# HG changeset patch
# User Dan
# Date 1234819045 18000
# Node ID 7152ca0a0ce9e03f437af279a1ffa06fe9c4a96c
# Parent 45e887f2328217874c219c92ad93d2280ae31d5f
Major redesign of rendering pipeline that separates pages saved with MCE from pages saved with the plaintext editor (full description in long commit message)
- Pages are now stored with an extra metadata field called page_format which is "wikitext" or "xhtml"
- New $flags parameter + RENDER_* constants added that control RenderMan::render() behavior
- Several other changes:
* Added a sprite API for Javascript and made editor use sprites when possible
* Removed a number of config options from the default install schema, replaced with second parameter to getConfig() calls
* MessageBox in editor mostly replaced with miniPrompt
* A few bugfixes related to password changes (registration didn't even work)
* Rewrote the bitfield compression algorithm used to serialize allowed MIME types
* Fixed some typos in language files and strings
* Fixed a Text_Wiki bug in Heading parser
diff -r 45e887f23282 -r 7152ca0a0ce9 ajax.php
--- a/ajax.php Mon Feb 16 16:04:54 2009 -0500
+++ b/ajax.php Mon Feb 16 16:17:25 2009 -0500
@@ -37,7 +37,7 @@
if ( $src = $page->fetch_source() )
{
$allowed = true;
- $q = $db->sql_query('SELECT author, time_id, page_text, edit_summary FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\'
+ $q = $db->sql_query('SELECT author, time_id, page_text, edit_summary, page_format FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\'
AND page_id = \'' . $db->escape($paths->page_id) . '\'
AND namespace = \'' . $db->escape($paths->namespace) . '\'
AND is_draft = 1;');
@@ -76,6 +76,21 @@
'have_draft' => false
);
+ $return['page_format'] = $paths->cpage['page_format'];
+ if ( $return['page_format'] == 'xhtml' )
+ {
+ // gently process headings to make tinymce format them correctly
+ if ( preg_match_all('/^ *?(={1,6}) *(.+?) *\\1 *$/m', $return['src'], $matches) )
+ {
+ foreach ( $matches[0] as $i => $match )
+ {
+ $hi = strlen($matches[1][$i]);
+ $heading = "$1
');
- text = text.replace(/'''(.+?)'''/g, '$1');
- text = text.replace(/''(.+?)''/g, '$1');
- text = text.replace(/\[(http|ftp|irc|mailto):([^ \]])+ ([^\]]+?)\]/g, '$4');
- return text;
+ return DN_AjaxGetTransformedText(text, 'xhtml');
+}
+
+function DN_XHTMLToWikitext(text)
+{
+ return DN_AjaxGetTransformedText(text, 'wikitext');
}
-// Inverse of the previous function
-function DN_XHTMLToWikitext(text)
+// AJAX to the server to transform text
+function DN_AjaxGetTransformedText(text, to)
{
- text = text.replace(/(.+?)<\/h3>/g, '=== $1 ===');
- text = text.replace(/<(b|strong)>(.+?)<\/(b|strong)>/g, "'''$2'''");
- text = text.replace(/<(i|em)>(.+?)<\/(i|em)>/g, "''$2''");
- text = text.replace(/(.+?)<\/a>/g, '[$1 $2]');
- text = text.replace(/<\/?p>/g, '');
+ // get an XHR instance
+ var ajax = ajaxMakeXHR();
+
+ var uri = stdAjaxPrefix + '&_mode=transform&to=' + to;
+ var parms = 'text=' + ajaxEscape(text);
+ try
+ {
+ ajax.open('POST', uri, false);
+ ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ // Setting Content-length in Safari triggers a warning
+ if ( !is_Safari )
+ {
+ ajax.setRequestHeader("Content-length", parms.length);
+ }
+ ajax.send(parms);
+ // async request, so if status != 200 at this point then we're screwed
+ if ( ajax.readyState == 4 && ajax.status == 200 )
+ {
+ var response = String(ajax.responseText + '');
+ if ( !check_json_response(response) )
+ {
+ handle_invalid_json(response);
+ return text;
+ }
+ response = parseJSON(response);
+ if ( response.mode == 'error' )
+ {
+ alert(response.error);
+ return text;
+ }
+ return response.text;
+ }
+ }
+ catch(e)
+ {
+ console.warn('DN_AjaxGetTransformedText: XHR failed');
+ }
return text;
}
diff -r 45e887f23282 -r 7152ca0a0ce9 includes/clientside/static/editor.js
--- a/includes/clientside/static/editor.js Mon Feb 16 16:04:54 2009 -0500
+++ b/includes/clientside/static/editor.js Mon Feb 16 16:17:25 2009 -0500
@@ -5,6 +5,7 @@
var AutosaveTimeoutObj = null;
var editor_img_path = cdnPath + '/images/editor';
var editor_save_lock = false;
+var editor_wikitext_transform_enable = true;
window.ajaxEditor = function(revid)
{
@@ -12,7 +13,7 @@
return true;
if ( editor_open )
return true;
- load_component(['l10n', 'template-compiler', 'messagebox']);
+ load_component(['l10n', 'template-compiler', 'messagebox', 'fadefilter', 'flyin']);
selectButtonMinor('edit');
selectButtonMajor('article');
setAjaxLoading();
@@ -124,29 +125,34 @@
var span_mce = document.createElement('span');
span_wiki.id = 'enano_edit_btn_pt';
span_mce.id = 'enano_edit_btn_mce';
- if ( readCookie('enano_editor_mode') == 'tinymce' )
+
+ // to-wikitext button
+ var a = document.createElement('a');
+ a.href = '#';
+ a.className = 'abutton image abutton_green';
+ a.appendChild(gen_sprite(scriptPath + '/images/editor/sprite.png', 16, 16, 0, 96));
+ a.appendChild(document.createTextNode(' ' + $lang.get('editor_btn_wikitext')));
+ span_wiki.appendChild(a);
+ toggler.appendChild(span_wiki);
+
+ // to-HTML button
+ var a = document.createElement('a');
+ a.href = '#';
+ a.className = 'abutton image abutton_blue';
+ a.appendChild(gen_sprite(scriptPath + '/images/editor/sprite.png', 16, 16, 0, 112));
+ a.appendChild(document.createTextNode(' ' + $lang.get('editor_btn_graphical')));
+ span_mce.appendChild(a);
+ toggler.appendChild(span_mce);
+
+ if ( response.page_format == 'xhtml' )
{
// Current selection is TinyMCE - make span_wiki have the link and span_mce be plaintext
- var a = document.createElement('a');
- a.href = '#';
- a.appendChild(document.createTextNode($lang.get('editor_btn_wikitext')));
- span_wiki.appendChild(a);
- toggler.appendChild(span_wiki);
- toggler.appendChild(document.createTextNode(' | '));
- span_mce.appendChild(document.createTextNode($lang.get('editor_btn_graphical')));
- toggler.appendChild(span_mce);
+ span_mce.style.display = 'none';
}
else
{
// Current selection is wikitext - set span_wiki to plaintext and span_mce to link
- span_wiki.appendChild(document.createTextNode($lang.get('editor_btn_wikitext')));
- toggler.appendChild(span_wiki);
- toggler.appendChild(document.createTextNode(' | '));
- var a = document.createElement('a');
- a.href = '#';
- a.appendChild(document.createTextNode($lang.get('editor_btn_graphical')));
- span_mce.appendChild(a);
- toggler.appendChild(span_mce);
+ span_wiki.style.display = 'none';
}
}
@@ -223,6 +229,7 @@
button.assign_vars({
TITLE: $lang.get('editor_btn_closeviewer'),
IMAGE: editor_img_path + '/discard.gif',
+ SPRITE: gen_sprite_html(editor_img_path + '/sprite.png', 16, 16, 0, 16),
FLAGS: 'href="#" onclick="ajaxReset(true); return false;"'
});
toolbar += button.run();
@@ -343,6 +350,7 @@
button.assign_vars({
TITLE: $lang.get('editor_btn_save'),
IMAGE: editor_img_path + '/save.gif',
+ SPRITE: gen_sprite_html(editor_img_path + '/sprite.png', 16, 16, 0, 64),
FLAGS: 'href="#" onclick="ajaxEditorSave(); return false;"'
});
toolbar += button.run();
@@ -351,6 +359,7 @@
button.assign_vars({
TITLE: $lang.get('editor_btn_preview'),
IMAGE: editor_img_path + '/preview.gif',
+ SPRITE: gen_sprite_html(editor_img_path + '/sprite.png', 16, 16, 0, 32),
FLAGS: 'href="#" onclick="ajaxEditorGenPreview(); return false;"'
});
toolbar += button.run();
@@ -359,6 +368,7 @@
button.assign_vars({
TITLE: $lang.get('editor_btn_revert'),
IMAGE: editor_img_path + '/revert.gif',
+ SPRITE: gen_sprite_html(editor_img_path + '/sprite.png', 16, 16, 0, 48),
FLAGS: 'href="#" onclick="ajaxEditorRevertToLatest(); return false;"'
});
toolbar += button.run();
@@ -367,6 +377,7 @@
button.assign_vars({
TITLE: $lang.get('editor_btn_diff'),
IMAGE: editor_img_path + '/diff.gif',
+ SPRITE: gen_sprite_html(editor_img_path + '/sprite.png', 16, 16, 0, 0),
FLAGS: 'href="#" onclick="ajaxEditorShowDiffs(); return false;"'
});
toolbar += button.run();
@@ -375,6 +386,7 @@
button.assign_vars({
TITLE: $lang.get('editor_btn_cancel'),
IMAGE: editor_img_path + '/discard.gif',
+ SPRITE: gen_sprite_html(editor_img_path + '/sprite.png', 16, 16, 0, 16),
FLAGS: 'href="#" onclick="ajaxEditorCancel(); return false;"'
});
toolbar += button.run();
@@ -389,6 +401,7 @@
button.assign_vars({
TITLE: $lang.get('editor_btn_savedraft'),
IMAGE: editor_img_path + '/savedraft.gif',
+ SPRITE: false,
FLAGS: 'href="#" onclick="ajaxPerformAutosave(); return false;" id="ajax_edit_savedraft_btn"'
});
toolbar += button.run();
@@ -467,29 +480,23 @@
$dynano('ajaxEditArea').setContent(content);
// If the editor preference is tinymce, switch the editor to TinyMCE now
- if ( readCookie('enano_editor_mode') == 'tinymce' && allow_wysiwyg )
+ if ( response.page_format == 'xhtml' && allow_wysiwyg )
{
- $dynano('ajaxEditArea').switchToMCE();
+ $dynano('ajaxEditArea').switchToMCE(false);
}
if ( allow_wysiwyg )
{
- if ( readCookie('enano_editor_mode') == 'tinymce' )
- {
- var a = document.getElementById('enano_edit_btn_pt').getElementsByTagName('a')[0];
- a.onclick = function() {
- ajaxSetEditorPlain();
- return false;
- };
- }
- else
- {
- var a = document.getElementById('enano_edit_btn_mce').getElementsByTagName('a')[0];
- a.onclick = function() {
- ajaxSetEditorMCE();
- return false;
- };
- }
+ var a = document.getElementById('enano_edit_btn_pt').getElementsByTagName('a')[0];
+ a.onclick = function() {
+ ajaxSetEditorPlain();
+ return false;
+ };
+ var a = document.getElementById('enano_edit_btn_mce').getElementsByTagName('a')[0];
+ a.onclick = function() {
+ ajaxSetEditorMCE();
+ return false;
+ };
}
// if we're using the modal window, fade it in
@@ -563,6 +570,7 @@
minor_edit: is_minor,
time: timestamp,
draft: ( is_draft == true ),
+ format: ( $dynano('ajaxEditArea').isMCE() ) ? 'xhtml' : 'wikitext',
used_draft: used_draft
};
@@ -597,12 +605,14 @@
// This will only be used if there was a lower-level error.
if ( response.mode == 'error' )
{
+ editor_save_lock = false;
new MessageBox(MB_OK | MB_ICONSTOP, $lang.get('editor_err_server'), response.error);
return false;
}
// This will be used if the PageProcessor generated errors (usually security/permissions related)
if ( response.mode == 'errors' )
{
+ editor_save_lock = false;
// This will be true if the user entered a captcha code incorrectly, thus
// invalidating the code and requiring a new image to be generated.
if ( response.new_captcha )
@@ -625,6 +635,7 @@
// If someone else got to the page first, warn the user
if ( response.mode == 'obsolete' )
{
+ editor_save_lock = false;
// Update the local timestamp to allow override
$dynano('ajaxEditArea').object._edTimestamp = response.time;
new MessageBox(MB_OK | MB_ICONEXCLAMATION, $lang.get('editor_err_obsolete_title'), $lang.get('editor_err_obsolete_body', { author: response.author, timestamp: response.date_string, page_url: makeUrl(title, false, true) }));
@@ -668,6 +679,7 @@
editor_open = false;
editor_save_lock = false;
enableUnload();
+ $dynano('ajaxEditArea').destroyMCE(false);
changeOpac(0, 'ajaxEditContainer');
ajaxGet(stdAjaxPrefix + '&_mode=getpage&noheaders', function(ajax)
{
@@ -751,11 +763,34 @@
window.ajaxEditorRevertToLatest = function()
{
- var mb = new MessageBox(MB_YESNO | MB_ICONQUESTION, $lang.get('editor_msg_revert_confirm_title'), $lang.get('editor_msg_revert_confirm_body'));
- mb.onclick['Yes'] = function()
- {
- setTimeout('ajaxEditorRevertToLatestReal();', 750);
- }
+ miniPromptMessage({
+ title: $lang.get('editor_msg_revert_confirm_title'),
+ message: $lang.get('editor_msg_revert_confirm_body'),
+ buttons: [
+ {
+ text: $lang.get('editor_btn_revert_confirm'),
+ color: 'red',
+ sprite: [ editor_img_path + '/sprite.png', 16, 16, 0, 48 ],
+ style: {
+ fontWeight: 'bold'
+ },
+ onclick: function()
+ {
+ ajaxEditorRevertToLatestReal();
+ miniPromptDestroy(this);
+ return false;
+ }
+ },
+ {
+ text: $lang.get('etc_cancel'),
+ onclick: function()
+ {
+ miniPromptDestroy(this);
+ return false;
+ }
+ }
+ ]
+ });
}
window.ajaxEditorRevertToLatestReal = function()
@@ -789,7 +824,11 @@
return false;
}
- $dynano('ajaxEditArea').setContent(response.src);
+ setTimeout(function()
+ {
+ editor_convert_if_needed(response.page_format);
+ $dynano('ajaxEditArea').setContent(response.src);
+ }, aclDisableTransitionFX ? 10 : 750);
}
}, true);
}
@@ -818,73 +857,135 @@
window.ajaxEditorCancel = function()
{
- var mb = new MessageBox(MB_YESNO | MB_ICONQUESTION, $lang.get('editor_msg_cancel_confirm_title'), $lang.get('editor_msg_cancel_confirm_body'));
- mb.onclick['Yes'] = function()
- {
- setAjaxLoading();
- ajaxEditorDestroyModalWindow();
- editor_open = false;
- enableUnload();
- setTimeout('ajaxReset();', 750);
- }
+ miniPromptMessage({
+ title: $lang.get('editor_msg_cancel_confirm_title'),
+ message: $lang.get('editor_msg_cancel_confirm_body'),
+ buttons: [
+ {
+ text: $lang.get('editor_btn_cancel_confirm'),
+ color: 'red',
+ sprite: [ editor_img_path + '/sprite.png', 16, 16, 0, 16 ],
+ style: {
+ fontWeight: 'bold'
+ },
+ onclick: function()
+ {
+ setAjaxLoading();
+ ajaxEditorDestroyModalWindow();
+ editor_open = false;
+ enableUnload();
+ $dynano('ajaxEditArea').destroyMCE(false);
+ ajaxReset();
+ miniPromptDestroy(this);
+ return false;
+ }
+ },
+ {
+ text: $lang.get('editor_btn_cancel_cancel'),
+ onclick: function()
+ {
+ miniPromptDestroy(this);
+ return false;
+ }
+ }
+ ]
+ });
}
-window.ajaxSetEditorMCE = function()
+window.ajaxSetEditorMCE = function(confirmed)
{
if ( editor_loading )
return false;
+ if ( !confirmed )
+ {
+ miniPromptMessage({
+ title: $lang.get('editor_msg_convert_confirm_title'),
+ message: $lang.get('editor_msg_convert_confirm_body'),
+ buttons: [
+ {
+ color: 'blue',
+ text: $lang.get('editor_btn_graphical'),
+ style: {
+ fontWeight: 'bold'
+ },
+ sprite: [ editor_img_path + '/sprite.png', 16, 16, 0, 112 ],
+ onclick: function()
+ {
+ ajaxSetEditorMCE(true);
+ miniPromptDestroy(this);
+ return false;
+ }
+ },
+ {
+ text: $lang.get('etc_cancel'),
+ onclick: function()
+ {
+ miniPromptDestroy(this);
+ return false;
+ }
+ }
+ ]
+ });
+ return false;
+ }
+
// Clear out existing buttons
var span_wiki = $dynano('enano_edit_btn_pt').object;
var span_mce = $dynano('enano_edit_btn_mce').object;
- span_wiki.removeChild(span_wiki.firstChild);
- span_mce.removeChild(span_mce.firstChild);
-
- // Rebuild control
- var a = document.createElement('a');
- a.href = '#';
- a.onclick = function() {
- ajaxSetEditorPlain();
- return false;
- };
- a.appendChild(document.createTextNode($lang.get('editor_btn_wikitext')));
- span_wiki.appendChild(a);
- span_mce.appendChild(document.createTextNode($lang.get('editor_btn_graphical')));
+ span_wiki.style.display = 'inline';
+ span_mce.style.display = 'none';
// Swap editor
- $dynano('ajaxEditArea').switchToMCE();
-
- // Remember the setting
- createCookie('enano_editor_mode', 'tinymce', 365);
+ $dynano('ajaxEditArea').switchToMCE(true);
}
-window.ajaxSetEditorPlain = function()
+window.ajaxSetEditorPlain = function(confirmed)
{
if ( editor_loading )
return false;
+ if ( !confirmed )
+ {
+ miniPromptMessage({
+ title: $lang.get('editor_msg_convert_confirm_title'),
+ message: $lang.get('editor_msg_convert_confirm_body'),
+ buttons: [
+ {
+ color: 'green',
+ text: $lang.get('editor_btn_wikitext'),
+ style: {
+ fontWeight: 'bold'
+ },
+ sprite: [ editor_img_path + '/sprite.png', 16, 16, 0, 96 ],
+ onclick: function()
+ {
+ ajaxSetEditorPlain(true);
+ miniPromptDestroy(this);
+ return false;
+ }
+ },
+ {
+ text: $lang.get('etc_cancel'),
+ onclick: function()
+ {
+ miniPromptDestroy(this);
+ return false;
+ }
+ }
+ ]
+ });
+ return false;
+ }
+
// Clear out existing buttons
var span_wiki = $dynano('enano_edit_btn_pt').object;
var span_mce = $dynano('enano_edit_btn_mce').object;
- span_wiki.removeChild(span_wiki.firstChild);
- span_mce.removeChild(span_mce.firstChild);
-
- // Rebuild control
- span_wiki.appendChild(document.createTextNode($lang.get('editor_btn_wikitext')));
- var a = document.createElement('a');
- a.href = '#';
- a.onclick = function() {
- ajaxSetEditorMCE();
- return false;
- };
- a.appendChild(document.createTextNode($lang.get('editor_btn_graphical')));
- span_mce.appendChild(a);
+ span_wiki.style.display = 'none';
+ span_mce.style.display = 'inline';
// Swap editor
- $dynano('ajaxEditArea').destroyMCE();
-
- // Remember the setting
- createCookie('enano_editor_mode', 'text', 365);
+ $dynano('ajaxEditArea').destroyMCE(true);
}
var editor_loading = false;
@@ -1003,6 +1104,8 @@
return false;
}
+ editor_convert_if_needed(response.page_format);
+
$dynano('ajaxEditArea').setContent(response.src);
$dynano('ajaxEditArea').object.used_draft = true;
@@ -1018,3 +1121,54 @@
}, true);
}
+window.editor_convert_if_needed = function(targetformat, noticetitle, noticebody)
+{
+ // Do we need to change the format?
+ var need_to_mce = ( targetformat == 'xhtml' && !$dynano('ajaxEditArea').isMCE() );
+ var need_to_wkt = ( targetformat == 'wikitext' && $dynano('ajaxEditArea').isMCE() );
+ if ( need_to_mce )
+ {
+ $dynano('ajaxEditArea').setContent('');
+ $dynano('ajaxEditArea').switchToMCE(false);
+
+ // Clear out existing buttons
+ var span_wiki = $dynano('enano_edit_btn_pt').object;
+ var span_mce = $dynano('enano_edit_btn_mce').object;
+ span_wiki.style.display = 'inline';
+ span_mce.style.display = 'none';
+ }
+ else if ( need_to_wkt )
+ {
+ $dynano('ajaxEditArea').setContent('');
+ $dynano('ajaxEditArea').destroyMCE(false);
+
+ // Clear out existing buttons
+ var span_wiki = $dynano('enano_edit_btn_pt').object;
+ var span_mce = $dynano('enano_edit_btn_mce').object;
+ span_wiki.style.display = 'none';
+ span_mce.style.display = 'inline';
+ }
+ if ( need_to_mce || need_to_wkt )
+ {
+ // explain the conversion
+ if ( !noticetitle )
+ noticetitle = 'editor_msg_convert_draft_load_title';
+ if ( !noticebody )
+ noticebody = 'editor_msg_convert_draft_load_body';
+
+ miniPromptMessage({
+ title: $lang.get(noticetitle),
+ message: $lang.get(noticebody),
+ buttons: [
+ {
+ text: $lang.get('etc_ok'),
+ onclick: function()
+ {
+ miniPromptDestroy(this);
+ return false;
+ }
+ }
+ ]
+ });
+ }
+}
diff -r 45e887f23282 -r 7152ca0a0ce9 includes/clientside/static/functions.js
--- a/includes/clientside/static/functions.js Mon Feb 16 16:04:54 2009 -0500
+++ b/includes/clientside/static/functions.js Mon Feb 16 16:17:25 2009 -0500
@@ -104,6 +104,8 @@
// The user allowed the editor to be closed. Reset flags and knock out the on-close confirmation.
editor_open = false;
enableUnload();
+ // destroy the MCE instance so it can be recreated later
+ $dynano('ajaxEditArea').destroyMCE(false);
}
var ajax = ajaxMakeXHR();
if ( !ajax )
@@ -136,6 +138,8 @@
// The user allowed the editor to be closed. Reset flags and knock out the on-close confirmation.
editor_open = false;
enableUnload();
+ // destroy the MCE instance so it can be recreated later
+ $dynano('ajaxEditArea').destroyMCE(false);
}
var ajax = ajaxMakeXHR();
if ( !ajax )
@@ -448,17 +452,67 @@
}
}
+/**
+ * Return a DOMElement that uses a sprite image.
+ * @param string Path to sprite image
+ * @param int Width of resulting image
+ * @param int Height of resulting image
+ * @param int X offset
+ * @param int Y offset
+ * @return object HTMLImageElement
+ */
+
+function gen_sprite(path, width, height, xpos, ypos)
+{
+ var image = document.createElement('img');
+ image.src = scriptPath + '/images/spacer.gif';
+ image.width = String(width);
+ image.height = String(height);
+ image.style.backgroundImage = 'url(' + path + ')';
+ image.style.backgroundRepeat = 'no-repeat';
+ xpos = ( xpos == 0 ) ? '0' : '-' + String(xpos);
+ ypos = ( ypos == 0 ) ? '0' : '-' + String(ypos);
+ image.style.backgroundPosition = ypos + 'px ' + xpos + 'px';
+
+ return image;
+}
+
+/**
+ * The same as gen_sprite but generates HTML instead of a DOMElement.
+ * @param string Path to sprite image
+ * @param int Width of resulting image
+ * @param int Height of resulting image
+ * @param int X offset
+ * @param int Y offset
+ * @return object HTMLImageElement
+ */
+
+function gen_sprite_html(path, width, height, xpos, ypos)
+{
+ var html = '';
+
+ return html;
+}
+
function findParentForm(o)
{
return get_parent_form(o);
}
-function domObjChangeOpac(opacity, id) {
- var object = id.style;
- object.opacity = (opacity / 100);
- object.MozOpacity = (opacity / 100);
- object.KhtmlOpacity = (opacity / 100);
- object.filter = "alpha(opacity=" + opacity + ")";
+function domObjChangeOpac(opacity, id)
+{
+ if ( !id )
+ return false;
+
+ var object = id.style;
+ object.opacity = (opacity / 100);
+ object.MozOpacity = (opacity / 100);
+ object.KhtmlOpacity = (opacity / 100);
+ object.filter = "alpha(opacity=" + opacity + ")";
}
function getScrollOffset(el)
diff -r 45e887f23282 -r 7152ca0a0ce9 includes/clientside/static/messagebox.js
--- a/includes/clientside/static/messagebox.js Mon Feb 16 16:04:54 2009 -0500
+++ b/includes/clientside/static/messagebox.js Mon Feb 16 16:17:25 2009 -0500
@@ -524,9 +524,17 @@
button.input.style[j] = button.style[j];
}
}
- if ( button.image )
+ if ( button.sprite )
{
- button.input.className += ' abutton_img';
+ var sprite = gen_sprite(button.sprite[0], button.sprite[1], button.sprite[2], button.sprite[3], button.sprite[4]);
+ sprite.style.position = 'relative';
+ sprite.style.top = '3px';
+ button.input.insertBefore(sprite, button.input.firstChild);
+ insertAfter(button.input, document.createTextNode(' '), sprite);
+ }
+ else if ( button.image )
+ {
+ button.input.className += ' icon';
button.input.style.backgroundImage = 'url(' + button.image + ')';
}
button.input.onclick = function(e)
@@ -572,7 +580,7 @@
style: {
fontWeight: 'bold'
},
- image: cdnPath + '/images/icons/abort.png',
+ sprite: [ cdnPath + '/images/icons/abortretryignore-sprite.png', 16, 16, 0, 0 ],
onclick: function() {
miniPromptDestroy(this);
}
@@ -580,7 +588,7 @@
{
text: 'Retry',
color: 'blue',
- image: cdnPath + '/images/icons/retry.png',
+ sprite: [ cdnPath + '/images/icons/abortretryignore-sprite.png', 16, 16, 0, 16 ],
onclick: function() {
miniPromptDestroy(this);
}
@@ -588,7 +596,7 @@
{
text: 'Ignore',
color: 'green',
- image: cdnPath + '/images/icons/ignore.png',
+ sprite: [ cdnPath + '/images/icons/abortretryignore-sprite.png', 16, 16, 0, 32 ],
onclick: function() {
miniPromptDestroy(this);
}
diff -r 45e887f23282 -r 7152ca0a0ce9 includes/clientside/static/template-compiler.js
--- a/includes/clientside/static/template-compiler.js Mon Feb 16 16:04:54 2009 -0500
+++ b/includes/clientside/static/template-compiler.js Mon Feb 16 16:17:25 2009 -0500
@@ -55,6 +55,8 @@
code = "'" + code + "'";
code = code.replace(/\{([A-z0-9_-]+)\}/ig, "' + this.tpl_strings['$1'] + '");
code = code.replace(/\{lang:([a-z0-9_]+)\}/g, "' + $lang.get('$1') + '");
+ code = code.replace(/\([\w\W]*?)|s', $text, $matches) )
+ return $text;
+
+ foreach ( $matches[0] as $i => $match )
+ {
+ $tag =& $matches[1][$i];
+ $attribs =& $matches[2][$i];
+ $inner =& $matches[3][$i];
+
+ $attribs = self::reverse_process_hint_attribs($attribs);
+ switch($tag)
+ {
+ case 'smiley':
+ case 'internallink':
+ case 'imagelink':
+ if ( isset($attribs['code']) )
+ {
+ $text = str_replace($match, $attribs['code'], $text);
+ }
+ else if ( isset($attribs['src']) )
+ {
+ $text = str_replace($match, $attribs['src'], $text);
+ }
+ break;
+ }
+ }
+
+ return $text;
+ }
+
+ public static function reverse_process_hint_attribs($attribs)
+ {
+ $return = array();
+ if ( !preg_match_all('/([a-z0-9_-]+)="([^"]+?)"/', $attribs, $matches) )
+ return array();
+
+ foreach ( $matches[0] as $i => $match )
+ {
+ $name =& $matches[1][$i];
+ $value =& $matches[2][$i];
+
+ $value = base64_decode($value);
+
+ $return[$name] = $value;
+ }
+
+ return $return;
+ }
+
+ /**
+ * Escapes a string so that it's safe to use as an attribute in a parser hint.
+ * @param string
+ * @return string
+ */
+
+ public static function escape_parser_hint_attrib($text)
+ {
+ return base64_encode($text);
+ }
+
+ public static function reverse_process_headings($text)
+ {
+ if ( !preg_match_all('|^
':
+ case '
':
+ case '':
+ $stack_height--;
+ $spaces = substr($spaces, 1);
+
+ if ( $stack_height == 0 )
+ {
+ // rotate
+ $text = str_replace_once("{$old_current_list}{$tag}", trim($current_list), $text);
+ $current_list = '';
+ $old_current_list = '';
+ }
+ $just_terminated = true;
+ break;
+ case '':
+ $stack_height++;
+ $just_terminated = false;
+ if ( $stack_height > 1 )
+ $spaces .= $marker;
+
+ $marker = ( $tag == 'ol' ) ? '#' : '*';
+ if ( $stack_height > 1 )
+ $current_list .= "\n";
+
+ break;
+ case '
'.htmlspecialchars($text).'
';
$nw = preg_match_all('#' . htmlspecialchars(print_r($bt, true)) . '
';
exit();
}
diff -r 45e887f23282 -r 7152ca0a0ce9 includes/search.php
--- a/includes/search.php Mon Feb 16 16:04:54 2009 -0500
+++ b/includes/search.php Mon Feb 16 16:17:25 2009 -0500
@@ -256,7 +256,7 @@
// Is this search term present in the page's title? If so, give extra points
preg_match("/^ns=$ns_list;pid=(.+)$/", $match, $piecesparts);
$pathskey = $paths->nslist[ $piecesparts[1] ] . sanitize_page_id($piecesparts[2]);
- if ( isset($paths->pages[$pathskey]) )
+ if ( isPage($pathskey) )
{
$test_func = ( $case_sensitive ) ? 'strstr' : 'stristr';
if ( $test_func($paths->pages[$pathskey]['name'], $row['word']) || $test_func($paths->pages[$pathskey]['urlname_nons'], $row['word']) )
@@ -298,7 +298,7 @@
// Is this search term present in the page's title? If so, give extra points
preg_match("/^ns=$ns_list;pid=(.+)$/", $pages, $piecesparts);
$pathskey = $paths->nslist[ $piecesparts[1] ] . sanitize_page_id($piecesparts[2]);
- if ( isset($paths->pages[$pathskey]) )
+ if ( isPage($pathskey) )
{
$test_func = ( $case_sensitive ) ? 'strstr' : 'stristr';
if ( $test_func($paths->pages[$pathskey]['name'], $row['word']) || $test_func($paths->pages[$pathskey]['urlname_nons'], $row['word']) )
@@ -397,7 +397,7 @@
// Is this search term present in the page's title? If so, give extra points
preg_match("/^ns=$ns_list;pid=(.+)$/", $id, $piecesparts);
$pathskey = $paths->nslist[ $piecesparts[1] ] . sanitize_page_id($piecesparts[2]);
- if ( isset($paths->pages[$pathskey]) )
+ if ( isPage($pathskey) )
{
$test_func = ( $case_sensitive ) ? 'strstr' : 'stristr';
foreach ( array_merge($query_phrase['any'], $query_phrase['req']) as $term )
diff -r 45e887f23282 -r 7152ca0a0ce9 includes/sessions.php
--- a/includes/sessions.php Mon Feb 16 16:04:54 2009 -0500
+++ b/includes/sessions.php Mon Feb 16 16:17:25 2009 -0500
@@ -716,13 +716,17 @@
$this->sql('SELECT password,\'\' AS password_salt,old_encryption,user_id,user_level,temp_password,temp_password_time FROM '.table_prefix."users\n"
. " WHERE " . ENANO_SQLFUNC_LOWERCASE . "(username) = '$username_db';");
}
- if($db->numrows() < 1)
+ if ( $db->numrows() < 1 )
{
// This wasn't logged in <1.0.2, dunno how it slipped through
- if($level > USER_LEVEL_MEMBER)
- $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')');
+ if ( $level > USER_LEVEL_MEMBER )
+ $this->sql('INSERT INTO ' . table_prefix . "logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES\n"
+ . ' (\'security\', \'admin_auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', '
+ . '\''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')');
else
- $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')');
+ $this->sql('INSERT INTO ' . table_prefix . "logs(log_type,action,time_id,date_string,author,edit_summary) VALUES\n"
+ . ' (\'security\', \'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', '
+ . '\''.$db->escape($_SERVER['REMOTE_ADDR']).'\')');
// Do we also need to increment the lockout countdown?
if ( @$policy != 'disable' && !defined('IN_ENANO_INSTALL') )
@@ -783,7 +787,7 @@
$success = true;
}
}
- else if ( $row['old_encryption'] == 2 || defined('ENANO_UPGRADE_USE_AES_PASSWORDS') )
+ else if ( $row['old_encryption'] == 2 || ( defined('ENANO_UPGRADE_USE_AES_PASSWORDS') ) )
{
// Our password field uses the 1.0RC1-1.1.5 encryption format
$real_pass = $aes->decrypt($row['password'], $this->private_key);
@@ -920,7 +924,7 @@
$salt = '';
for ( $i = 0; $i < 32; $i++ )
{
- $salt .= chr(mt_rand(32, 127));
+ $salt .= chr(mt_rand(32, 126));
}
// Session key
@@ -946,7 +950,7 @@
{
// Stash it in a cookie
// For now, make the cookie last forever, we can change this in 1.1.x
- setcookie( 'sid', $session_key, time()+15552000, scriptPath.'/', null, ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ) );
+ setcookie( 'sid', $session_key, time()+15552000, scriptPath.'/', null, $GLOBALS['is_https']);
$_COOKIE['sid'] = $session_key;
}
// $keyhash is stored in the database, this is for compatibility with the older DB structure
@@ -1354,10 +1358,6 @@
if($this->user_logged_in)
{
$aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
- // See if we can get rid of the cached decrypted session key
- $key_bin = hex2bin($this->sid);
- $key_hash = sha1($key_bin . '::' . $this->private_key);
- aes_decrypt_cache_destroy($key_hash);
// Completely destroy our session
if($this->auth_level > USER_LEVEL_CHPREF)
{
@@ -1811,8 +1811,6 @@
}
}
- $password = $aes->encrypt($password, $this->private_key, ENC_HEX);
-
// Require the account to be activated?
switch(getConfig('account_activation'))
{
@@ -1836,7 +1834,7 @@
$actkey = sha1 ( microtime() . mt_rand() );
// We good, create the user
- $this->sql('INSERT INTO '.table_prefix.'users ( username, password, email, real_name, theme, style, reg_time, account_active, activation_key, user_level, user_coppa, user_registration_ip ) VALUES ( \''.$username.'\', \''.$password.'\', \''.$email.'\', \''.$real_name.'\', \''.$template->default_theme.'\', \''.$template->default_style.'\', '.time().', '.$active.', \''.$actkey.'\', '.USER_LEVEL_CHPREF.', ' . $coppa_col . ', \'' . $ip . '\' );');
+ $this->sql('INSERT INTO '.table_prefix.'users ( username, email, real_name, theme, style, reg_time, account_active, activation_key, user_level, user_coppa, user_registration_ip ) VALUES ( \''.$username.'\', \''.$email.'\', \''.$real_name.'\', \''.$template->default_theme.'\', \''.$template->default_style.'\', '.time().', '.$active.', \''.$actkey.'\', '.USER_LEVEL_CHPREF.', ' . $coppa_col . ', \'' . $ip . '\' );');
// Get user ID and create users_extra entry
$q = $this->sql('SELECT user_id FROM '.table_prefix."users WHERE username='$username';");
@@ -1848,6 +1846,9 @@
$this->sql('INSERT INTO '.table_prefix.'users_extra(user_id) VALUES(' . $user_id . ');');
}
+ // Set the password
+ $this->set_password($user_id, $password);
+
// Config option added, 1.1.5
if ( getConfig('userpage_grant_acl', '1') == '1' )
{
@@ -1879,8 +1880,8 @@
// Require the account to be activated?
if ( $coppa )
{
- $this->admin_activation_request($username);
- $this->send_coppa_mail($username,$email);
+ $this->admin_activation_request($user_orig);
+ $this->send_coppa_mail($user_orig, $email);
}
else
{
@@ -1890,27 +1891,28 @@
default:
break;
case 'user':
- $a = $this->send_activation_mail($username);
+ $a = $this->send_activation_mail($user_orig);
if(!$a)
{
- $this->admin_activation_request($username);
+ $this->admin_activation_request($user_orig);
return $lang->get('user_reg_err_actmail_failed') . ' ' . $a;
}
break;
case 'admin':
- $this->admin_activation_request($username);
+ $this->admin_activation_request($user_orig);
break;
}
}
// Leave some data behind for the hook
- $code = $plugins->setHook('user_registered'); // , Array('username'=>$username));
+ $code = $plugins->setHook('user_registered');
foreach ( $code as $cmd )
{
eval($cmd);
}
- // $this->register_session($username, $password);
+ // Uncomment to automatically log the user in (WARNING: commented out for a reason - doesn't consider activation and other things)
+ // $this->register_session($user_orig, $password);
return 'success';
}
@@ -1924,9 +1926,6 @@
{
global $db, $session, $paths, $template, $plugins; // Common objects
global $lang;
- $q = $this->sql('SELECT username,email FROM '.table_prefix.'users WHERE user_id=2 OR user_level=' . USER_LEVEL_ADMIN . ' ORDER BY user_id ASC;');
- $un = $db->fetchrow();
- $admin_user = $un['username'];
$q = $this->sql('SELECT username,activation_key,account_active,email FROM '.table_prefix.'users WHERE username=\''.$db->escape($u).'\';');
$r = $db->fetchrow();
if ( empty($r['email']) )
@@ -1935,16 +1934,24 @@
$aklink = makeUrlComplete('Special', 'ActivateAccount/'.str_replace(' ', '_', $u).'/'. ( ( is_string($actkey) ) ? $actkey : $r['activation_key'] ) );
$message = $lang->get('user_reg_activation_email', array(
'activation_link' => $aklink,
- 'admin_user' => $admin_user,
'username' => $u
));
- if(getConfig('smtp_enabled') == '1')
+ if ( getConfig('smtp_enabled') == '1' )
{
$result = smtp_send_email($r['email'], $lang->get('user_reg_activation_email_subject'), preg_replace("#(?get('user_reg_activation_email_subject'), preg_replace("#(?" : '';
( $inc == 5 ) ? $inc = 0 : null;
$url = makeUrlNS('Special', 'TagCloud/' . htmlspecialchars($word));
- $popstring = ( $popularity == 1 ) ? $lang->get('pagetools_tagcloug_tip_popularity_one') : $lang->get('pagetools_tagcloug_tip_popularity_plural', array('popularity' => $popularity));
+ $popstring = ( $popularity == 1 ) ? $lang->get('pagetools_tagcloud_tip_popularity_one') : $lang->get('pagetools_tagcloud_tip_popularity_plural', array('popularity' => $popularity));
$html[] = "$word"; // $newline";
}
}
diff -r 45e887f23282 -r 7152ca0a0ce9 includes/template.php
--- a/includes/template.php Mon Feb 16 16:04:54 2009 -0500
+++ b/includes/template.php Mon Feb 16 16:17:25 2009 -0500
@@ -436,7 +436,7 @@
require(ENANO_ROOT . "/themes/{$this->theme}/theme.cfg");
- if ( $local_page_exists && isset($paths->pages[$local_page]) )
+ if ( $local_page_exists && isPage($local_page) )
{
$local_cdata =& $paths->pages[$local_page];
}
@@ -603,7 +603,7 @@
// Page toolbar
// Comments button
- if ( $perms->get_permissions('read') && getConfig('enable_comments')=='1' && $local_cdata['comments_on'] == 1 )
+ if ( $perms->get_permissions('read') && getConfig('enable_comments', '1')=='1' && $local_cdata['comments_on'] == 1 )
{
$e = $db->sql_query('SELECT approved FROM '.table_prefix.'comments WHERE page_id=\''.$local_page_id.'\' AND namespace=\''.$local_namespace.'\';');
@@ -1151,7 +1151,7 @@
var disable_redirect = ' . ( isset($_GET['redirect']) && $_GET['redirect'] == 'no' ? 'true' : 'false' ) . ';
var pref_disable_js_fx = ' . ( @$session->user_extra['disable_js_fx'] == 1 ? 'true' : 'false' ) . ';
var csrf_token = "' . $session->csrf_token . '";
- var editNotice = \'' . ( (getConfig('wiki_edit_notice')=='1') ? str_replace("\n", "\\\n", RenderMan::render(getConfig('wiki_edit_notice_text'))) : '' ) . '\';
+ var editNotice = \'' . ( (getConfig('wiki_edit_notice', '0')=='1') ? str_replace("\n", "\\\n", RenderMan::render(getConfig('wiki_edit_notice_text'))) : '' ) . '\';
var prot = ' . ( ($protected) ? 'true' : 'false' ) .'; // No, hacking this var won\'t work, it\'s re-checked on the server
var ENANO_SPECIAL_CREATEPAGE = \''. makeUrl($paths->nslist['Special'].'CreatePage') .'\';
var ENANO_CREATEPAGE_PARAMS = \'_do=&pagename='. $urlname_clean .'&namespace=' . $local_namespace . '\';
@@ -2405,7 +2405,7 @@
eval($cmd);
}
- if(count($ob) > 0 || getConfig('powered_btn') == '1') $sb_links = '
', $ob).'
', $ob).'
get('acpup_field_max_size'); ?> - +