r95541 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r95540‎ | r95541 | r95542 >
Date:22:59, 25 August 2011
Author:yaron
Status:ok
Tags:
Comment:
Moved some global functions into MeanEditorEditPage class, removed some unnecessary use of hooks
Modified paths:
  • /trunk/extensions/MeanEditor/MeanEditor.php (modified) (history)
  • /trunk/extensions/MeanEditor/MeanEditorEditPage.body.php (modified) (history)

Diff [purge]

Index: trunk/extensions/MeanEditor/MeanEditorEditPage.body.php
@@ -128,7 +128,7 @@
129129 # MeanEditor: convert HTML to wikitext
130130 # The hidden box should tell us if the editor was in use (we got HTML in the POST)
131131 if ( !$this->firsttime && !($this->formtype == 'initial') && !$this->noVisualEditor ) {
132 - wfRunHooks('EditPage::html2wiki', array($this->mArticle, $wgUser, &$this, &$this->textbox1));
 132+ self::html2wiki( $this->mArticle, $wgUser, &$this, &$this->textbox1 );
133133 }
134134
135135 # MeanEditor: we could leave MeanEditor enabled, but I think it would be confusing
@@ -204,11 +204,11 @@
205205 # Also apply htmlspecialchars? See $encodedtext
206206 $html_text = $this->safeUnicodeOutput( $this->textbox1 );
207207 if (!($this->noVisualEditor || $this->userWantsTraditionalEditor)) {
208 - $this->noVisualEditor = wfRunHooks('EditPage::wiki2html', array($this->mArticle, $wgUser, &$this, &$html_text));
 208+ $this->noVisualEditor = self::wiki2html( $this->mArticle, $wgUser, &$this, &$html_text );
209209 }
210210 if (!$this->noVisualEditor && !$this->userWantsTraditionalEditor) {
211211 # TODO: Now that MediaWiki has showContentForm, there is no need for a separate hook
212 - $this->noVisualEditor = wfRunHooks('EditPage::showBox', array(&$this, $html_text, $rows, $cols, $ew));
 212+ $this->noVisualEditor = self::showBox( &$this, $html_text, $rows, $cols, $ew );
213213 }
214214 if (!$this->noVisualEditor && !$this->userWantsTraditionalEditor) {
215215 $wgOut->addHTML("<input type='hidden' value=\"0\" name=\"wpNoVisualEditor\" />\n");
@@ -293,4 +293,426 @@
294294 return $buttons;
295295 }
296296
 297+ function substitute_hashed_img_urls($text) {
 298+ while (preg_match('/\[\[Image:(.*?)\]\]/', $text, $matches)) {
 299+ $img = $matches[1];
 300+ $hash = md5($img);
 301+ $folder = substr($hash, 0, 1) .
 302+ '/' . substr($hash, 0, 2);
 303+ $tag = '<img alt="' . $img . '" src="' . $wgUploadPath .
 304+ '/' . $folder . '/' . $img . '" />';
 305+ $text = str_replace($matches[0], $tag, $text);
 306+ }
 307+ return $text;
 308+ }
 309+
 310+ function deny_visual_because_of($reason, &$edit_context) {
 311+ global $wgOut;
 312+ $wgOut->addHTML('<p class="visual_editing_denied errorbox">' . wfMsg('no_visual') . '<em class="visual_editing_denied_reason">'.$reason.'</em></p>');
 313+ # FIXME: Doesn't work. Why?
 314+ #$edit_context->editFormTextBeforeContent .= '<p class="visual_editing_denied errorbox">The visual editor can\'t be used for this page. Most likely, it contains advanced or unsopported features. If you can, try editing smaller paragraphs.<br /><br />Reason: <em class="visual_editing_denied_reason">'.$reason.'</em></p>';
 315+ # Maybe add a page to gather feedback
 316+ return true; # Show the standard textbox interface
 317+ }
 318+
 319+ # Return true to force traditional editing
 320+ function wiki2html($article, $user, &$edit_context, &$wiki_text) {
 321+ global $wgUploadPath, $wgArticlePath;
 322+ $meaneditor_page_src = str_replace('$1', '', $wgArticlePath);
 323+
 324+ # Detect code sections (lines beginning with whitespace)
 325+ if (preg_match('/^[ \t]/m',$wiki_text))
 326+ return deny_visual_because_of(wfMsg('reason_whitespace'), $edit_context);
 327+
 328+ # Detect custom tags: only <br />, super/sub-scripts and references are supported at the moment
 329+ # TODO: expand the safe list
 330+ # Especially problematic tags (do not even think about supporting them):
 331+ # <p> (would require special handling to disable normal paragraphing, confusing)
 332+ # <h*> (for headings not in TOC, strange closing tag)
 333+ # <b>,<i> (not to be confused with ''emphasis'' as <em>)
 334+ # <pre>, <nowiki> (if something gets implemented, better be the common leading spaces)
 335+ $wiki_text=str_replace('<br />','__TEMP__TEMP__br',$wiki_text);
 336+ $wiki_text=str_replace('<br>','__TEMP__TEMP__br',$wiki_text);
 337+ $wiki_text=str_replace('<references />','__TEMP__TEMP__allreferences',$wiki_text);
 338+ $wiki_text=str_replace('<ref>','__TEMP__TEMP__ref',$wiki_text);
 339+ $wiki_text=str_replace('</ref>','__TEMP__TEMP__cref',$wiki_text);
 340+ $wiki_text=str_replace('<sup>','__TEMP__TEMP__sup',$wiki_text);
 341+ $wiki_text=str_replace('</sup>','__TEMP__TEMP__csup',$wiki_text);
 342+ $wiki_text=str_replace('<sub>','__TEMP__TEMP__sub',$wiki_text);
 343+ $wiki_text=str_replace('</sub>','__TEMP__TEMP__csub',$wiki_text);
 344+ if (!((strpos($wiki_text, '<')===FALSE) && (strpos($wiki_text, '>')===FALSE)))
 345+ return deny_visual_because_of(wfMsg('reason_tag'), $edit_context);
 346+ $wiki_text=str_replace('__TEMP__TEMP__br','<br />', $wiki_text);
 347+ $wiki_text=str_replace('__TEMP__TEMP__allreferences','references_here',$wiki_text);
 348+ $wiki_text=str_replace('__TEMP__TEMP__sup','<sup>',$wiki_text);
 349+ $wiki_text=str_replace('__TEMP__TEMP__csup','</sup>',$wiki_text);
 350+ $wiki_text=str_replace('__TEMP__TEMP__sub','<sub>',$wiki_text);
 351+ $wiki_text=str_replace('__TEMP__TEMP__csub','</sub>',$wiki_text);
 352+ $wiki_text=str_replace('__TEMP__TEMP__ref','<ref>',$wiki_text);
 353+ $wiki_text=str_replace('__TEMP__TEMP__cref','</ref>',$wiki_text);
 354+
 355+ # This characters are problematic only at line beginning
 356+ $unwanted_chars_at_beginning = array(':', ';');
 357+ foreach ($unwanted_chars_at_beginning as $uc)
 358+ if (preg_match('/^'.$uc.'/m',$wiki_text))
 359+ return deny_visual_because_of(wfMsg('reason_indent', $uc), $edit_context);
 360+
 361+ # <hr>, from Parser.php... TODO: other regexps can be directly stolen from there
 362+ $wiki_text=preg_replace('/(^|\n)-----*/', '\\1<hr />', $wiki_text);
 363+
 364+ #Collapse multiple newlines
 365+ # TODO: Compare Wikipedia:Don't_use_line_breaks
 366+ $wiki_text=preg_replace("/\n\n+/","\n\n",$wiki_text);
 367+
 368+ $wiki_text=preg_replace('/^(.+?)$/m','<p>$1</p>',$wiki_text);
 369+
 370+ #$wiki_text=preg_replace('/\'\'\'(.*?)\'\'\'/','<strong>$1</strong>',$wiki_text);
 371+ #$wiki_text=preg_replace('/\'\'(.*?)\'\'/','<em>$1</em>',$wiki_text);
 372+ $obp = new Parser;
 373+ $obp->setTitle('');
 374+ $obp->mOptions = new ParserOptions;
 375+ $obp->clearState();
 376+ $wiki_text = $obp->doAllQuotes($wiki_text);
 377+
 378+ #Substitute ===
 379+ $wiki_text=preg_replace('/(?:<p>|)\s*===(.*?)===\s*(?:<\/p>|)/','<h3>\1</h3>',$wiki_text);
 380+
 381+ #Substitute ==
 382+ $wiki_text=preg_replace('/(?:<p>|)\s*==(.*?)==\s*(?:<\/p>|)/','<h2>\1</h2>',$wiki_text);
 383+
 384+ #Substitute [[Image:a]]
 385+ if (!$wgHashedUploadDirectory) {
 386+ $wiki_text=preg_replace('/\[\[Image:(.*?)\]\]/','<img alt="\1" src="' . $wgUploadPath . '/\1" />',$wiki_text);
 387+ } else {
 388+ $wiki_text = substitute_hashed_img_urls($wiki_text);
 389+ }
 390+
 391+ $wiki_text=preg_replace('/\[\[Image:(.*?)\]\]/','<img alt="\1" src="' . $wgUploadPath . '/\1" />',$wiki_text);
 392+
 393+ #Create [[a|b]] syntax for every link
 394+ #TODO: What to do for the [[word (detailed disambiguation)|]] 'pipe trick'?
 395+ $wiki_text=preg_replace('/\[\[([^|]*?)\]\]/','[[\1|\1]]',$wiki_text);
 396+
 397+ #Substitute [[ syntax (internal links)
 398+ if (preg_match('/\[\[([^|\]]*?):(.*?)\|(.*?)\]\]/',$wiki_text,$unwanted_matches))
 399+ return deny_visual_because_of(wfMsg('reason_special_link', $unwanted_matches[0]), $edit_context);
 400+ #Preserve #section links from the draconic feature detection
 401+ $wiki_text=preg_replace_callback('/\[\[(.*?)\|(.*?)\]\]/',
 402+ create_function('$matches', 'return "[[".str_replace("#","__TEMP_MEAN_hash",$matches[1])."|".str_replace("#","__TEMP_MEAN_hash",$matches[2])."]]";'),
 403+ $wiki_text);
 404+ $wiki_text=preg_replace_callback('/<a href="(.*?)">/',
 405+ create_function('$matches', 'return "<a href=\"".str_replace("#","__TEMP_MEAN_hash",$matches[1])."\">";'),
 406+ $wiki_text);
 407+ $wiki_text=preg_replace('/\[\[(.*?)\|(.*?)\]\]/','<a href="' . $meaneditor_page_src . '\1">\2</a>',$wiki_text);
 408+
 409+ #Create [a b] syntax for every link
 410+ #(must be here, so that internal links have already been replaced)
 411+ $wiki_text=preg_replace('/\[([^| ]*?)\]/','[\1 _autonumber_]',$wiki_text);
 412+
 413+ #Substitute [ syntax (external links)
 414+ $wiki_text=preg_replace('/\[(.*?) (.*?)\]/','<a href="\1">\2</a>',$wiki_text);
 415+
 416+ #Lists support
 417+ $wiki_text=preg_replace("/<p># (.*?)<\/p>/",'<ol><li>\1</li></ol>',$wiki_text);
 418+ $wiki_text=preg_replace("/<p>\* (.*?)<\/p>/",'<ul><li>\1</li></ul>',$wiki_text);
 419+ $wiki_text=preg_replace("/<\/ol>\n<ol>/","\n",$wiki_text);
 420+ $wiki_text=preg_replace("/<\/ul>\n<ul>/","\n",$wiki_text);
 421+
 422+ # Crude but safe detection of unsupported features
 423+ # In the future, this could be loosened a lot, should also detect harmless uses
 424+ # TODO: Compare with MediaWiki security policy, ensure no mediawiki code can create unsafe HTML in the editor
 425+
 426+ # Allow numbered entities, these occur far too often and should be innocous
 427+ $wiki_text=str_replace('&#','__TEMP__MEAN__nument',$wiki_text);
 428+
 429+ $unwanted_chars = array('[', ']', '|', '{', '}', '#', '*');
 430+ foreach ($unwanted_chars as $uc)
 431+ if (!($unwanted_match = strpos($wiki_text, $uc) === FALSE))
 432+ return deny_visual_because_of(wfMsg('reason_forbidden_char', $uc), $edit_context);
 433+
 434+ # Restore numbered entities
 435+ $wiki_text=str_replace('__TEMP__MEAN__nument','&#',$wiki_text);
 436+
 437+ #<ref> support
 438+ global $refs_div;
 439+ global $refs_num;
 440+ $refs_div='';
 441+ $refs_num=0;
 442+ $wiki_text=preg_replace_callback('/<ref>(.*?)<\/ref>/',
 443+ create_function('$matches', 'global $refs_div,$refs_num; $refs_num++; $refs_div=$refs_div."<p id=ref".$refs_num." class=\"ref\"> [".$refs_num."] ".
 444+ $matches[1]."</p>"; return "<a href=\"#ref".$refs_num."\"> [".$refs_num."] </a>";'),
 445+ $wiki_text);
 446+ $refs_div='<div class="ref">'.$refs_div."</div>";
 447+
 448+
 449+ # We saved #section links from the sacred detection fury, now restore them
 450+ $wiki_text=str_replace("__TEMP_MEAN_hash","#",$wiki_text);
 451+
 452+ $wiki_text=$wiki_text.$refs_div;
 453+
 454+ return false;
 455+ }
 456+
 457+ function html2wiki($article, $user, &$edit_context, &$html_text) {
 458+ global $wgArticlePath;
 459+ $meaneditor_page_src = str_replace('$1', '', $wgArticlePath);
 460+ $meaneditor_page_src_escaped = addcslashes($meaneditor_page_src, '/.');
 461+
 462+ $html_text=preg_replace('/(^|\n)<hr \/>*/', '\\1-----',$html_text);
 463+ $html_text=preg_replace('/<strong>(.*?)<\/strong>/','\'\'\'\1\'\'\'',$html_text);
 464+ $html_text=preg_replace('/<em>(.*?)<\/em>/','\'\'\1\'\'',$html_text);
 465+ $html_text=preg_replace('/<h2>(.*?)<\/h2>/',"==\\1==\n",$html_text);
 466+ $html_text=preg_replace('/<h3>(.*?)<\/h3>/',"===\\1===\n",$html_text);
 467+
 468+ $html_text=preg_replace_callback('/<a href="'.$meaneditor_page_src_escaped.'(.*?)">/',
 469+ create_function('$matches', 'return "<a href=\"'.$meaneditor_page_src.'" . rawurldecode($matches[1]). "\">";'), $html_text);
 470+ $html_text=preg_replace('/<a href="'.$meaneditor_page_src_escaped.'(.*?)">(.*?)<\/a>/','[[\1|\2]]',$html_text);
 471+
 472+ $html_text=preg_replace('/references_here/','<references />',$html_text);
 473+
 474+ #<ref> support:
 475+ # 1) Extract references block
 476+ global $html_refs;
 477+ $html_text=preg_replace_callback('/<div class="ref">(.*?)<\/div>/',
 478+ create_function('$matches', 'global $html_refs; $html_refs=$matches[1];
 479+ return "";'),
 480+ $html_text);
 481+ # 2) Put each reference in place
 482+ $html_text=preg_replace_callback('/<a href="#(.*?)">.*?<\/a>/',
 483+ create_function('$matches', 'global $html_refs; preg_match("/<p id=.".$matches[1].".*?> \[.*?\] (.*?)<\/p>/",$html_refs,$b);return "<ref>".$b[1]."</ref>";'),$html_text);
 484+
 485+ $html_text=preg_replace('/<p>/','',$html_text);
 486+ $html_text=preg_replace('/<\/p>/',"\n\n",$html_text);
 487+
 488+ $html_text=preg_replace('/<a href="(.*?)">(.*?)<\/a>/','[\1 \2]',$html_text);
 489+
 490+ $html_text=preg_replace_callback('/<img alt="(.*?)" src="(.*?)" \/>/',create_function('$matches',
 491+ 'return "[[Image:".$matches[1]."]]";'
 492+ ),$html_text);
 493+ $html_text=preg_replace_callback('/<img src="(.*?)" alt="(.*?)" \/>/',create_function('$matches',
 494+ 'return "[[Image:".$matches[2]."]]";'
 495+ ),$html_text);
 496+
 497+ # TODO: integrate lists with the previous paragraph? Check XHTML requirements
 498+ $html_text=preg_replace_callback('/<ol>(.*?)<\/ol>/',create_function('$matches',
 499+ '$matches[1]=str_replace("<li>","# ",$matches[1]);
 500+ return str_replace("</li>","\n",$matches[1])."\n";'),$html_text);
 501+ $html_text=preg_replace_callback('/<ul>(.*?)<\/ul>/',create_function('$matches',
 502+ '$matches[1]=str_replace("<li>","* ",$matches[1]);
 503+ return str_replace("</li>","\n",$matches[1])."\n";'),$html_text);
 504+
 505+ # Let's simplify [page] links which don't need [page|text] syntax
 506+ $html_text=preg_replace('/\[\[(.*?)\|\1\]\]/','[[\1]]',$html_text);
 507+ # The same for autonumbered external links
 508+ $html_text=preg_replace('/\[(.*?) _autonumber_\]/','[\1]',$html_text);
 509+
 510+ # Safe-guard against unwanted whitespace at the beginning of a line
 511+ # TODO: code sections
 512+ $html_text=preg_replace('/^[ \t]+/',"",$html_text);
 513+ $html_text=preg_replace('/\n[ \t]+/',"\n",$html_text);
 514+
 515+ # When editing sections, Wymeditor has the bad habit of adding two newlines
 516+ # TODO: Why? Anyway, redundant whitespace handling is already authoritarian
 517+ $html_text=preg_replace('/\n\n$/', '', $html_text);
 518+
 519+ return false;
 520+ }
 521+
 522+ function showBox(&$edit_context, $html_text, $rows, $cols, $ew) {
 523+ global $wgOut, $wgArticlePath, $wgStylePath, $wgUploadPath, $wgLang;
 524+ $wiki_path = str_replace('$1', '', $wgArticlePath);
 525+ $wgOut->addScriptFile('../../extensions/MeanEditor/wymeditor/jquery/jquery.js');
 526+ $wgOut->addScriptFile('../../extensions/MeanEditor/wymeditor/wymeditor/jquery.wymeditor.pack.js');
 527+ $wgOut->addScriptFile('../../extensions/MeanEditor/wymeditor/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js');
 528+ $wgOut->addExtensionStyle('../extensions/MeanEditor/fix_meaneditor.css');
 529+
 530+ # For now, it looks better in IE8 standards mode, even though IE support is very messy
 531+ #$wgOut->addMeta('X-UA-Compatible', 'IE=7');
 532+
 533+ $wgOut->addInlineScript('
 534+ Array.prototype.wym_remove = function(from, to) {
 535+ // From a suggestion at forum.wymeditor.org
 536+ this.splice(from, !to || 1 + to - from + (!(to < 0 ^ from >= 0) && (to < 0 || -1) * this.length));
 537+ return this.length;
 538+ };
 539+ jQuery(function() {
 540+ jQuery(\'.wymeditor\').wymeditor({
 541+ html: "'.addcslashes($html_text,"\"\n").'",
 542+ lang: "'.$wgLang->getCode().'",
 543+ iframeBasePath: "extensions/MeanEditor/iframe/",
 544+ dialogLinkHtml: "<body class=\'wym_dialog wym_dialog_link\'"
 545+ + " onload=\'WYMeditor.INIT_DIALOG(" + WYMeditor.INDEX + ")\'"
 546+ + ">"
 547+ + "<form>"
 548+ + "<fieldset>"
 549+ + "<input type=\'hidden\' class=\'wym_dialog_type\' value=\'"
 550+ + WYMeditor.DIALOG_LINK
 551+ + "\' />"
 552+ + "<legend>{Link}</legend>"
 553+ + "<div class=\'row\'>"
 554+ + "<label>{URL}</label>"
 555+ + "<input type=\'text\' class=\'wym_href\' value=\'\' size=\'40\' />"
 556+ + "</div>"
 557+ + "<div class=\'row row-indent\'>"
 558+ + "<input class=\'wym_submit\' type=\'button\'"
 559+ + " value=\'{Submit}\' />"
 560+ + "<input class=\'wym_cancel\' type=\'button\'"
 561+ + "value=\'{Cancel}\' />"
 562+ + "</div>"
 563+ + "</fieldset>"
 564+ + "</form>"
 565+ + "</body>",
 566+ dialogImageHtml: "<body class=\'wym_dialog wym_dialog_image\'"
 567+ + " onload=\'WYMeditor.INIT_DIALOG(" + WYMeditor.INDEX + ")\'"
 568+ + ">"
 569+ + "<script type=\'text/javascript\' src=\''.$wgStylePath.'/common/ajax.js\'></scr"+"ipt>"
 570+ + "<script type=\'text/javascript\'>function meaneditor_responder(e) {"
 571+ + " divwait=document.getElementById(\'meaneditor_ajax_wait\');"
 572+ + " if (divwait)"
 573+ + " divwait.style.display = \'none\';"
 574+ + " div=document.getElementById(\'meaneditor_ajax_table\');"
 575+ + " div.innerHTML=e.responseText;"
 576+ + "}</scr"+"ipt>"
 577+ + "<form>"
 578+ + "<fieldset>"
 579+ + "<input type=\'hidden\' class=\'wym_dialog_type\' value=\'"
 580+ + WYMeditor.DIALOG_IMAGE
 581+ + "\' />"
 582+ + "<legend>{Image}</legend>"
 583+ + "<div class=\'row\'>"
 584+ + "<label>{Title}</label>"
 585+ + "<input id=\'image_name\' type=\'text\' class=\'wym_src\' value=\'\' size=\'40\' />"
 586+ + "</div>"
 587+ + "<div class=\'row\'>"
 588+ + "<script>sajax_do_call(\'recent_images\',[0],meaneditor_responder,0);</scr"+"ipt>"
 589+ + "<p>' . wfMsg('recent_images_text',str_replace('$1','Special:Upload',$wgArticlePath)) . '</p>"
 590+ + "<div id=\'meaneditor_ajax_wait\' style=\'color: #999; margin-bottom: 1em;\'>' . wfMsg('livepreview-loading') . '</div>"
 591+ + "<div style=\'max-height: 115px; overflow: auto\'><table id=\'meaneditor_ajax_table\'></table></div>"
 592+ + "</div>"
 593+ + "<div class=\'row row-indent\'>"
 594+ + "<input class=\'wym_submit_meaneditor_image\' type=\'button\'"
 595+ + " value=\'{Submit}\' />"
 596+ + "<input class=\'wym_cancel\' type=\'button\'"
 597+ + "value=\'{Cancel}\' />"
 598+ + "</div>"
 599+ + "</fieldset>"
 600+ + "</form>"
 601+ + "</body>",
 602+
 603+ preInit: function(wym) {
 604+ // Remove unwanted buttons, code from a suggestion at forum.wymeditor.org
 605+ wym._options.toolsItems.wym_remove(6);
 606+ wym._options.toolsItems.wym_remove(6);
 607+ wym._options.toolsItems.wym_remove(11);
 608+ wym._options.toolsItems.wym_remove(12);
 609+ wym._options.toolsItems.wym_remove(12);
 610+ },
 611+ postInit: function(wym) {
 612+ var wikilink_button_html = "<li class=\'wym_tools_wikilink\'>"
 613+ + "<a name=\'Wikilink\' href=\'#\' "
 614+ + "style=\'background-image: url(extensions/MeanEditor/wikilink-icon.png)\'>"
 615+ + "Create Wikilink</a></li>";
 616+ var wikilink_dialog_html = "<body class=\'wym_dialog wym_dialog_wikilink\'"
 617+ + " onload=\'WYMeditor.INIT_DIALOG(" + WYMeditor.INDEX + ")\'"
 618+ + ">"
 619+ + "<form>"
 620+ + "<fieldset>"
 621+ + "<input type=\'hidden\' class=\'wym_dialog_type\' value=\'"
 622+ + "MeanEditor_dialog_wikilink"
 623+ + "\' />"
 624+ + "<legend>Wikilink</legend>"
 625+ + "<div class=\'row\'>"
 626+ + "<label>Page</label>"
 627+ + "<input type=\'text\' class=\'wym_wikititle\' value=\'\' size=\'40\' />"
 628+ + "</div>"
 629+ + "<div class=\'row row-indent\'>"
 630+ + "Tip: to link \"dog\" from \"dogs\", just select the first letters."
 631+ + "</div>"
 632+ + "<div class=\'row row-indent\'>"
 633+ + "<input class=\'wym_submit wym_submit_wikilink\' type=\'button\'"
 634+ + " value=\'{Submit}\' />"
 635+ + "<input class=\'wym_cancel\' type=\'button\'"
 636+ + "value=\'{Cancel}\' />"
 637+ + "</div></fieldset></form></body>";
 638+
 639+ jQuery(wym._box).find(wym._options.toolsSelector + wym._options.toolsListSelector)
 640+ .append(wikilink_button_html);
 641+ jQuery(wym._box).find(\'li.wym_tools_wikilink a\').click(function() {
 642+ wym.dialog(\'Wikilink\', wikilink_dialog_html);
 643+ return (false);
 644+ });
 645+
 646+ wym.resizable();
 647+ },
 648+ preInitDialog: function(wym, wdm) {
 649+ if (wdm.jQuery(wym._options.dialogTypeSelector).val() != \'MeanEditor_dialog_wikilink\')
 650+ return;
 651+
 652+ var selected = wym.selected();
 653+
 654+ // Copied from Link dialog handling
 655+ if(selected && selected.tagName && selected.tagName.toLowerCase != WYMeditor.A)
 656+ selected = jQuery(selected).parentsOrSelf(WYMeditor.A);
 657+ if(!selected && wym._selected_image)
 658+ selected = jQuery(wym._selected_image).parentsOrSelf(WYMeditor.A);
 659+
 660+ var wikipage;
 661+ wikipage = jQuery(selected).attr(WYMeditor.HREF);
 662+ if (wikipage) {
 663+ if (wikipage.indexOf(\'' . $wiki_path . '\') == -1) {
 664+ alert(\'This is an external link. If you want to convert it to a wikilink, remove the existing link first.\');
 665+ wikipage = \'[External link, do not edit here]\';
 666+ wdm.close();
 667+ }
 668+ else wikipage = wikipage.slice(' . strlen($wiki_path) . ');
 669+ } else if (wym._iframe.contentWindow.getSelection) {
 670+ wikipage = wym._iframe.contentWindow.getSelection().toString();
 671+ } else if (wym._iframe.contentWindow.document.selection && wym._iframe.contentWindow.document.selection.createRange) {
 672+ var range = wym._iframe.contentWindow.document.selection.createRange();
 673+ wikipage = range.text;
 674+ }
 675+ wdm.jQuery(\'.wym_wikititle\').val(wikipage);
 676+ },
 677+ postInitDialog: function(wym, wdw) {
 678+ var dbody = wdw.document.body;
 679+ wdw.jQuery(dbody).find(\'input.wym_submit_wikilink\').click(function() {
 680+ var wikipage = jQuery(dbody).find(\'.wym_wikititle\').val();
 681+ var sUrl = \'' . $wiki_path . '\' + wikipage;
 682+
 683+ // Copied from Link dialog handling
 684+ var sStamp = wym.uniqueStamp();
 685+ if(sUrl.length > 0) {
 686+ wym._exec(WYMeditor.CREATE_LINK, sStamp);
 687+ jQuery("a[@href=" + sStamp + "]", wym._doc.body)
 688+ .attr(WYMeditor.HREF, sUrl);
 689+ }
 690+ wdw.close();
 691+ });
 692+ wdw.jQuery(dbody).find(\'input.wym_submit_meaneditor_image\').click(function() {
 693+ var image_name = jQuery(dbody).find(wym._options.srcSelector).val();
 694+ var sUrl = \'' . $wgUploadPath . '/' . '\' + image_name;
 695+
 696+ // Copied from original dialog handling
 697+ var sStamp = wym.uniqueStamp();
 698+ if(sUrl.length > 0) {
 699+ wym._exec(WYMeditor.INSERT_IMAGE, sStamp);
 700+ jQuery("img[@src=" + sStamp + "]", wym._doc.body)
 701+ .attr(WYMeditor.SRC, sUrl)
 702+ .attr(WYMeditor.ALT, image_name);
 703+ }
 704+ wdw.close();
 705+ });
 706+ }
 707+
 708+ });
 709+ });
 710+');
 711+ $wgOut->addHTML( <<<END
 712+<textarea tabindex='1' accesskey="," name="wpTextbox1" id="wpTextbox1" class="wymeditor" rows='{$rows}'
 713+cols='{$cols}'{$ew}></textarea>
 714+END
 715+ );
 716+ return false;
 717+ }
 718+
297719 }
Index: trunk/extensions/MeanEditor/MeanEditor.php
@@ -17,447 +17,13 @@
1818
1919 $wgAutoloadClasses['MeanEditorEditPage'] = $meanEditorDir . '/MeanEditorEditPage.body.php';
2020
21 -$wgHooks['EditPage::wiki2html'][] = 'meaneditor_wiki2html';
22 -$wgHooks['EditPage::html2wiki'][] = 'meaneditor_html2wiki';
23 -$wgHooks['EditPage::showBox'][] = 'meaneditor_showBox';
2421 $wgHooks['CustomEditor'][] = 'meaneditor_customeditor';
2522 $wgHooks['EditPageBeforeEditChecks'][] = 'meaneditor_checkboxes';
2623 $wgHooks['EditPageBeforeEditToolbar'][] = 'meaneditor_disabletoolbar';
 24+$wgHooks['UserToggles'][] = 'toggle_visualeditor_preference';
2725
28 -function substitute_hashed_img_urls($text)
29 -{
30 - while (preg_match('/\[\[Image:(.*?)\]\]/', $text, $matches)) {
31 - $img = $matches[1];
32 - $hash = md5($img);
33 - $folder = substr($hash, 0, 1) .
34 - '/' . substr($hash, 0, 2);
35 - $tag = '<img alt="' . $img . '" src="' . $wgUploadPath .
36 - '/' . $folder . '/' . $img . '" />';
37 - $text = str_replace($matches[0], $tag, $text);
38 - }
39 - return $text;
40 -}
 26+$wgAjaxExportList[] = "recent_images";
4127
42 -function deny_visual_because_of($reason, &$edit_context)
43 -{
44 - global $wgOut;
45 - $wgOut->addHTML('<p class="visual_editing_denied errorbox">' . wfMsg('no_visual') . '<em class="visual_editing_denied_reason">'.$reason.'</em></p>');
46 - # FIXME: Doesn't work. Why?
47 - #$edit_context->editFormTextBeforeContent .= '<p class="visual_editing_denied errorbox">The visual editor can\'t be used for this page. Most likely, it contains advanced or unsopported features. If you can, try editing smaller paragraphs.<br /><br />Reason: <em class="visual_editing_denied_reason">'.$reason.'</em></p>';
48 - # Maybe add a page to gather feedback
49 - return true; # Show the standard textbox interface
50 -}
51 -
52 -# Return true to force traditional editing
53 -function meaneditor_wiki2html($article, $user, &$edit_context, &$wiki_text)
54 -{
55 - global $wgUploadPath, $wgArticlePath;
56 - $meaneditor_page_src = str_replace('$1', '', $wgArticlePath);
57 -
58 - # Detect code sections (lines beginning with whitespace)
59 - if (preg_match('/^[ \t]/m',$wiki_text))
60 - return deny_visual_because_of(wfMsg('reason_whitespace'), $edit_context);
61 -
62 - # Detect custom tags: only <br />, super/sub-scripts and references are supported at the moment
63 - # TODO: expand the safe list
64 - # Especially problematic tags (do not even think about supporting them):
65 - # <p> (would require special handling to disable normal paragraphing, confusing)
66 - # <h*> (for headings not in TOC, strange closing tag)
67 - # <b>,<i> (not to be confused with ''emphasis'' as <em>)
68 - # <pre>, <nowiki> (if something gets implemented, better be the common leading spaces)
69 - $wiki_text=str_replace('<br />','__TEMP__TEMP__br',$wiki_text);
70 - $wiki_text=str_replace('<br>','__TEMP__TEMP__br',$wiki_text);
71 - $wiki_text=str_replace('<references />','__TEMP__TEMP__allreferences',$wiki_text);
72 - $wiki_text=str_replace('<ref>','__TEMP__TEMP__ref',$wiki_text);
73 - $wiki_text=str_replace('</ref>','__TEMP__TEMP__cref',$wiki_text);
74 - $wiki_text=str_replace('<sup>','__TEMP__TEMP__sup',$wiki_text);
75 - $wiki_text=str_replace('</sup>','__TEMP__TEMP__csup',$wiki_text);
76 - $wiki_text=str_replace('<sub>','__TEMP__TEMP__sub',$wiki_text);
77 - $wiki_text=str_replace('</sub>','__TEMP__TEMP__csub',$wiki_text);
78 - if (!((strpos($wiki_text, '<')===FALSE) && (strpos($wiki_text, '>')===FALSE)))
79 - return deny_visual_because_of(wfMsg('reason_tag'), $edit_context);
80 - $wiki_text=str_replace('__TEMP__TEMP__br','<br />', $wiki_text);
81 - $wiki_text=str_replace('__TEMP__TEMP__allreferences','references_here',$wiki_text);
82 - $wiki_text=str_replace('__TEMP__TEMP__sup','<sup>',$wiki_text);
83 - $wiki_text=str_replace('__TEMP__TEMP__csup','</sup>',$wiki_text);
84 - $wiki_text=str_replace('__TEMP__TEMP__sub','<sub>',$wiki_text);
85 - $wiki_text=str_replace('__TEMP__TEMP__csub','</sub>',$wiki_text);
86 - $wiki_text=str_replace('__TEMP__TEMP__ref','<ref>',$wiki_text);
87 - $wiki_text=str_replace('__TEMP__TEMP__cref','</ref>',$wiki_text);
88 -
89 - # This characters are problematic only at line beginning
90 - $unwanted_chars_at_beginning = array(':', ';');
91 - foreach ($unwanted_chars_at_beginning as $uc)
92 - if (preg_match('/^'.$uc.'/m',$wiki_text))
93 - return deny_visual_because_of(wfMsg('reason_indent', $uc), $edit_context);
94 -
95 - # <hr>, from Parser.php... TODO: other regexps can be directly stolen from there
96 - $wiki_text=preg_replace('/(^|\n)-----*/', '\\1<hr />', $wiki_text);
97 -
98 - #Collapse multiple newlines
99 - # TODO: Compare Wikipedia:Don't_use_line_breaks
100 - $wiki_text=preg_replace("/\n\n+/","\n\n",$wiki_text);
101 -
102 - $wiki_text=preg_replace('/^(.+?)$/m','<p>$1</p>',$wiki_text);
103 -
104 - #$wiki_text=preg_replace('/\'\'\'(.*?)\'\'\'/','<strong>$1</strong>',$wiki_text);
105 - #$wiki_text=preg_replace('/\'\'(.*?)\'\'/','<em>$1</em>',$wiki_text);
106 - $obp = new Parser;
107 - $obp->setTitle('');
108 - $obp->mOptions = new ParserOptions;
109 - $obp->clearState();
110 - $wiki_text = $obp->doAllQuotes($wiki_text);
111 -
112 - #Substitute ===
113 - $wiki_text=preg_replace('/(?:<p>|)\s*===(.*?)===\s*(?:<\/p>|)/','<h3>\1</h3>',$wiki_text);
114 -
115 - #Substitute ==
116 - $wiki_text=preg_replace('/(?:<p>|)\s*==(.*?)==\s*(?:<\/p>|)/','<h2>\1</h2>',$wiki_text);
117 -
118 - #Substitute [[Image:a]]
119 - if (!$wgHashedUploadDirectory) {
120 - $wiki_text=preg_replace('/\[\[Image:(.*?)\]\]/','<img alt="\1" src="' . $wgUploadPath . '/\1" />',$wiki_text);
121 - } else {
122 - $wiki_text = substitute_hashed_img_urls($wiki_text);
123 - }
124 -
125 - $wiki_text=preg_replace('/\[\[Image:(.*?)\]\]/','<img alt="\1" src="' . $wgUploadPath . '/\1" />',$wiki_text);
126 -
127 - #Create [[a|b]] syntax for every link
128 - #TODO: What to do for the [[word (detailed disambiguation)|]] 'pipe trick'?
129 - $wiki_text=preg_replace('/\[\[([^|]*?)\]\]/','[[\1|\1]]',$wiki_text);
130 -
131 - #Substitute [[ syntax (internal links)
132 - if (preg_match('/\[\[([^|\]]*?):(.*?)\|(.*?)\]\]/',$wiki_text,$unwanted_matches))
133 - return deny_visual_because_of(wfMsg('reason_special_link', $unwanted_matches[0]), $edit_context);
134 - #Preserve #section links from the draconic feature detection
135 - $wiki_text=preg_replace_callback('/\[\[(.*?)\|(.*?)\]\]/',
136 - create_function('$matches', 'return "[[".str_replace("#","__TEMP_MEAN_hash",$matches[1])."|".str_replace("#","__TEMP_MEAN_hash",$matches[2])."]]";'),
137 - $wiki_text);
138 - $wiki_text=preg_replace_callback('/<a href="(.*?)">/',
139 - create_function('$matches', 'return "<a href=\"".str_replace("#","__TEMP_MEAN_hash",$matches[1])."\">";'),
140 - $wiki_text);
141 - $wiki_text=preg_replace('/\[\[(.*?)\|(.*?)\]\]/','<a href="' . $meaneditor_page_src . '\1">\2</a>',$wiki_text);
142 -
143 - #Create [a b] syntax for every link
144 - #(must be here, so that internal links have already been replaced)
145 - $wiki_text=preg_replace('/\[([^| ]*?)\]/','[\1 _autonumber_]',$wiki_text);
146 -
147 - #Substitute [ syntax (external links)
148 - $wiki_text=preg_replace('/\[(.*?) (.*?)\]/','<a href="\1">\2</a>',$wiki_text);
149 -
150 - #Lists support
151 - $wiki_text=preg_replace("/<p># (.*?)<\/p>/",'<ol><li>\1</li></ol>',$wiki_text);
152 - $wiki_text=preg_replace("/<p>\* (.*?)<\/p>/",'<ul><li>\1</li></ul>',$wiki_text);
153 - $wiki_text=preg_replace("/<\/ol>\n<ol>/","\n",$wiki_text);
154 - $wiki_text=preg_replace("/<\/ul>\n<ul>/","\n",$wiki_text);
155 -
156 -
157 - # Crude but safe detection of unsupported features
158 - # In the future, this could be loosened a lot, should also detect harmless uses
159 - # TODO: Compare with MediaWiki security policy, ensure no mediawiki code can create unsafe HTML in the editor
160 -
161 - # Allow numbered entities, these occur far too often and should be innocous
162 - $wiki_text=str_replace('&#','__TEMP__MEAN__nument',$wiki_text);
163 -
164 - $unwanted_chars = array('[', ']', '|', '{', '}', '#', '*');
165 - foreach ($unwanted_chars as $uc)
166 - if (!($unwanted_match = strpos($wiki_text, $uc) === FALSE))
167 - return deny_visual_because_of(wfMsg('reason_forbidden_char', $uc), $edit_context);
168 -
169 - # Restore numbered entities
170 - $wiki_text=str_replace('__TEMP__MEAN__nument','&#',$wiki_text);
171 -
172 - #<ref> support
173 - global $refs_div;
174 - global $refs_num;
175 - $refs_div='';
176 - $refs_num=0;
177 - $wiki_text=preg_replace_callback('/<ref>(.*?)<\/ref>/',
178 - create_function('$matches', 'global $refs_div,$refs_num; $refs_num++; $refs_div=$refs_div."<p id=ref".$refs_num." class=\"ref\"> [".$refs_num."] ".
179 - $matches[1]."</p>"; return "<a href=\"#ref".$refs_num."\"> [".$refs_num."] </a>";'),
180 - $wiki_text);
181 - $refs_div='<div class="ref">'.$refs_div."</div>";
182 -
183 -
184 - # We saved #section links from the sacred detection fury, now restore them
185 - $wiki_text=str_replace("__TEMP_MEAN_hash","#",$wiki_text);
186 -
187 - $wiki_text=$wiki_text.$refs_div;
188 -
189 - return false;
190 -}
191 -
192 -function meaneditor_html2wiki($article, $user, &$edit_context, &$html_text)
193 -{
194 - global $wgArticlePath;
195 - $meaneditor_page_src = str_replace('$1', '', $wgArticlePath);
196 - $meaneditor_page_src_escaped = addcslashes($meaneditor_page_src, '/.');
197 -
198 - $html_text=preg_replace('/(^|\n)<hr \/>*/', '\\1-----',$html_text);
199 - $html_text=preg_replace('/<strong>(.*?)<\/strong>/','\'\'\'\1\'\'\'',$html_text);
200 - $html_text=preg_replace('/<em>(.*?)<\/em>/','\'\'\1\'\'',$html_text);
201 - $html_text=preg_replace('/<h2>(.*?)<\/h2>/',"==\\1==\n",$html_text);
202 - $html_text=preg_replace('/<h3>(.*?)<\/h3>/',"===\\1===\n",$html_text);
203 -
204 - $html_text=preg_replace_callback('/<a href="'.$meaneditor_page_src_escaped.'(.*?)">/',
205 - create_function('$matches', 'return "<a href=\"'.$meaneditor_page_src.'" . rawurldecode($matches[1]). "\">";'), $html_text);
206 - $html_text=preg_replace('/<a href="'.$meaneditor_page_src_escaped.'(.*?)">(.*?)<\/a>/','[[\1|\2]]',$html_text);
207 -
208 - $html_text=preg_replace('/references_here/','<references />',$html_text);
209 -
210 -
211 - #<ref> support:
212 - # 1) Extract references block
213 - global $html_refs;
214 - $html_text=preg_replace_callback('/<div class="ref">(.*?)<\/div>/',
215 - create_function('$matches', 'global $html_refs; $html_refs=$matches[1];
216 - return "";'),
217 - $html_text);
218 - # 2) Put each reference in place
219 - $html_text=preg_replace_callback('/<a href="#(.*?)">.*?<\/a>/',
220 - create_function('$matches', 'global $html_refs; preg_match("/<p id=.".$matches[1].".*?> \[.*?\] (.*?)<\/p>/",$html_refs,$b);return "<ref>".$b[1]."</ref>";'),$html_text);
221 -
222 -
223 - $html_text=preg_replace('/<p>/','',$html_text);
224 - $html_text=preg_replace('/<\/p>/',"\n\n",$html_text);
225 -
226 -
227 - $html_text=preg_replace('/<a href="(.*?)">(.*?)<\/a>/','[\1 \2]',$html_text);
228 -
229 - $html_text=preg_replace_callback('/<img alt="(.*?)" src="(.*?)" \/>/',create_function('$matches',
230 - 'return "[[Image:".$matches[1]."]]";'
231 - ),$html_text);
232 - $html_text=preg_replace_callback('/<img src="(.*?)" alt="(.*?)" \/>/',create_function('$matches',
233 - 'return "[[Image:".$matches[2]."]]";'
234 - ),$html_text);
235 -
236 -
237 - # TODO: integrate lists with the previous paragraph? Check XHTML requirements
238 - $html_text=preg_replace_callback('/<ol>(.*?)<\/ol>/',create_function('$matches',
239 - '$matches[1]=str_replace("<li>","# ",$matches[1]);
240 - return str_replace("</li>","\n",$matches[1])."\n";'),$html_text);
241 - $html_text=preg_replace_callback('/<ul>(.*?)<\/ul>/',create_function('$matches',
242 - '$matches[1]=str_replace("<li>","* ",$matches[1]);
243 - return str_replace("</li>","\n",$matches[1])."\n";'),$html_text);
244 -
245 -
246 - # Let's simplify [page] links which don't need [page|text] syntax
247 - $html_text=preg_replace('/\[\[(.*?)\|\1\]\]/','[[\1]]',$html_text);
248 - # The same for autonumbered external links
249 - $html_text=preg_replace('/\[(.*?) _autonumber_\]/','[\1]',$html_text);
250 -
251 -
252 - # Safe-guard against unwanted whitespace at the beginning of a line
253 - # TODO: code sections
254 - $html_text=preg_replace('/^[ \t]+/',"",$html_text);
255 - $html_text=preg_replace('/\n[ \t]+/',"\n",$html_text);
256 -
257 - # When editing sections, Wymeditor has the bad habit of adding two newlines
258 - # TODO: Why? Anyway, redundant whitespace handling is already authoritarian
259 - $html_text=preg_replace('/\n\n$/', '', $html_text);
260 -
261 - return false;
262 -}
263 -
264 -function meaneditor_showBox(&$edit_context, $html_text, $rows, $cols, $ew)
265 -{
266 - global $wgOut, $wgArticlePath, $wgStylePath, $wgUploadPath, $wgLang;
267 - $wiki_path = str_replace('$1', '', $wgArticlePath);
268 - $wgOut->addScriptFile('../../extensions/MeanEditor/wymeditor/jquery/jquery.js');
269 - $wgOut->addScriptFile('../../extensions/MeanEditor/wymeditor/wymeditor/jquery.wymeditor.pack.js');
270 - $wgOut->addScriptFile('../../extensions/MeanEditor/wymeditor/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js');
271 - $wgOut->addExtensionStyle('../extensions/MeanEditor/fix_meaneditor.css');
272 -
273 - # For now, it looks better in IE8 standards mode, even though IE support is very messy
274 - #$wgOut->addMeta('X-UA-Compatible', 'IE=7');
275 -
276 - $wgOut->addInlineScript('
277 - Array.prototype.wym_remove = function(from, to) {
278 - // From a suggestion at forum.wymeditor.org
279 - this.splice(from, !to || 1 + to - from + (!(to < 0 ^ from >= 0) && (to < 0 || -1) * this.length));
280 - return this.length;
281 - };
282 - jQuery(function() {
283 - jQuery(\'.wymeditor\').wymeditor({
284 - html: "'.addcslashes($html_text,"\"\n").'",
285 - lang: "'.$wgLang->getCode().'",
286 - iframeBasePath: "extensions/MeanEditor/iframe/",
287 - dialogLinkHtml: "<body class=\'wym_dialog wym_dialog_link\'"
288 - + " onload=\'WYMeditor.INIT_DIALOG(" + WYMeditor.INDEX + ")\'"
289 - + ">"
290 - + "<form>"
291 - + "<fieldset>"
292 - + "<input type=\'hidden\' class=\'wym_dialog_type\' value=\'"
293 - + WYMeditor.DIALOG_LINK
294 - + "\' />"
295 - + "<legend>{Link}</legend>"
296 - + "<div class=\'row\'>"
297 - + "<label>{URL}</label>"
298 - + "<input type=\'text\' class=\'wym_href\' value=\'\' size=\'40\' />"
299 - + "</div>"
300 - + "<div class=\'row row-indent\'>"
301 - + "<input class=\'wym_submit\' type=\'button\'"
302 - + " value=\'{Submit}\' />"
303 - + "<input class=\'wym_cancel\' type=\'button\'"
304 - + "value=\'{Cancel}\' />"
305 - + "</div>"
306 - + "</fieldset>"
307 - + "</form>"
308 - + "</body>",
309 - dialogImageHtml: "<body class=\'wym_dialog wym_dialog_image\'"
310 - + " onload=\'WYMeditor.INIT_DIALOG(" + WYMeditor.INDEX + ")\'"
311 - + ">"
312 - + "<script type=\'text/javascript\' src=\''.$wgStylePath.'/common/ajax.js\'></scr"+"ipt>"
313 - + "<script type=\'text/javascript\'>function meaneditor_responder(e) {"
314 - + " divwait=document.getElementById(\'meaneditor_ajax_wait\');"
315 - + " if (divwait)"
316 - + " divwait.style.display = \'none\';"
317 - + " div=document.getElementById(\'meaneditor_ajax_table\');"
318 - + " div.innerHTML=e.responseText;"
319 - + "}</scr"+"ipt>"
320 - + "<form>"
321 - + "<fieldset>"
322 - + "<input type=\'hidden\' class=\'wym_dialog_type\' value=\'"
323 - + WYMeditor.DIALOG_IMAGE
324 - + "\' />"
325 - + "<legend>{Image}</legend>"
326 - + "<div class=\'row\'>"
327 - + "<label>{Title}</label>"
328 - + "<input id=\'image_name\' type=\'text\' class=\'wym_src\' value=\'\' size=\'40\' />"
329 - + "</div>"
330 - + "<div class=\'row\'>"
331 - + "<script>sajax_do_call(\'recent_images\',[0],meaneditor_responder,0);</scr"+"ipt>"
332 - + "<p>' . wfMsg('recent_images_text',str_replace('$1','Special:Upload',$wgArticlePath)) . '</p>"
333 - + "<div id=\'meaneditor_ajax_wait\' style=\'color: #999; margin-bottom: 1em;\'>' . wfMsg('livepreview-loading') . '</div>"
334 - + "<div style=\'max-height: 115px; overflow: auto\'><table id=\'meaneditor_ajax_table\'></table></div>"
335 - + "</div>"
336 - + "<div class=\'row row-indent\'>"
337 - + "<input class=\'wym_submit_meaneditor_image\' type=\'button\'"
338 - + " value=\'{Submit}\' />"
339 - + "<input class=\'wym_cancel\' type=\'button\'"
340 - + "value=\'{Cancel}\' />"
341 - + "</div>"
342 - + "</fieldset>"
343 - + "</form>"
344 - + "</body>",
345 -
346 - preInit: function(wym) {
347 - // Remove unwanted buttons, code from a suggestion at forum.wymeditor.org
348 - wym._options.toolsItems.wym_remove(6);
349 - wym._options.toolsItems.wym_remove(6);
350 - wym._options.toolsItems.wym_remove(11);
351 - wym._options.toolsItems.wym_remove(12);
352 - wym._options.toolsItems.wym_remove(12);
353 - },
354 - postInit: function(wym) {
355 - var wikilink_button_html = "<li class=\'wym_tools_wikilink\'>"
356 - + "<a name=\'Wikilink\' href=\'#\' "
357 - + "style=\'background-image: url(extensions/MeanEditor/wikilink-icon.png)\'>"
358 - + "Create Wikilink</a></li>";
359 - var wikilink_dialog_html = "<body class=\'wym_dialog wym_dialog_wikilink\'"
360 - + " onload=\'WYMeditor.INIT_DIALOG(" + WYMeditor.INDEX + ")\'"
361 - + ">"
362 - + "<form>"
363 - + "<fieldset>"
364 - + "<input type=\'hidden\' class=\'wym_dialog_type\' value=\'"
365 - + "MeanEditor_dialog_wikilink"
366 - + "\' />"
367 - + "<legend>Wikilink</legend>"
368 - + "<div class=\'row\'>"
369 - + "<label>Page</label>"
370 - + "<input type=\'text\' class=\'wym_wikititle\' value=\'\' size=\'40\' />"
371 - + "</div>"
372 - + "<div class=\'row row-indent\'>"
373 - + "Tip: to link \"dog\" from \"dogs\", just select the first letters."
374 - + "</div>"
375 - + "<div class=\'row row-indent\'>"
376 - + "<input class=\'wym_submit wym_submit_wikilink\' type=\'button\'"
377 - + " value=\'{Submit}\' />"
378 - + "<input class=\'wym_cancel\' type=\'button\'"
379 - + "value=\'{Cancel}\' />"
380 - + "</div></fieldset></form></body>";
381 -
382 - jQuery(wym._box).find(wym._options.toolsSelector + wym._options.toolsListSelector)
383 - .append(wikilink_button_html);
384 - jQuery(wym._box).find(\'li.wym_tools_wikilink a\').click(function() {
385 - wym.dialog(\'Wikilink\', wikilink_dialog_html);
386 - return (false);
387 - });
388 -
389 - wym.resizable();
390 - },
391 - preInitDialog: function(wym, wdm) {
392 - if (wdm.jQuery(wym._options.dialogTypeSelector).val() != \'MeanEditor_dialog_wikilink\')
393 - return;
394 -
395 - var selected = wym.selected();
396 -
397 - // Copied from Link dialog handling
398 - if(selected && selected.tagName && selected.tagName.toLowerCase != WYMeditor.A)
399 - selected = jQuery(selected).parentsOrSelf(WYMeditor.A);
400 - if(!selected && wym._selected_image)
401 - selected = jQuery(wym._selected_image).parentsOrSelf(WYMeditor.A);
402 -
403 - var wikipage;
404 - wikipage = jQuery(selected).attr(WYMeditor.HREF);
405 - if (wikipage) {
406 - if (wikipage.indexOf(\'' . $wiki_path . '\') == -1) {
407 - alert(\'This is an external link. If you want to convert it to a wikilink, remove the existing link first.\');
408 - wikipage = \'[External link, do not edit here]\';
409 - wdm.close();
410 - }
411 - else wikipage = wikipage.slice(' . strlen($wiki_path) . ');
412 - } else if (wym._iframe.contentWindow.getSelection) {
413 - wikipage = wym._iframe.contentWindow.getSelection().toString();
414 - } else if (wym._iframe.contentWindow.document.selection && wym._iframe.contentWindow.document.selection.createRange) {
415 - var range = wym._iframe.contentWindow.document.selection.createRange();
416 - wikipage = range.text;
417 - }
418 - wdm.jQuery(\'.wym_wikititle\').val(wikipage);
419 - },
420 - postInitDialog: function(wym, wdw) {
421 - var dbody = wdw.document.body;
422 - wdw.jQuery(dbody).find(\'input.wym_submit_wikilink\').click(function() {
423 - var wikipage = jQuery(dbody).find(\'.wym_wikititle\').val();
424 - var sUrl = \'' . $wiki_path . '\' + wikipage;
425 -
426 - // Copied from Link dialog handling
427 - var sStamp = wym.uniqueStamp();
428 - if(sUrl.length > 0) {
429 - wym._exec(WYMeditor.CREATE_LINK, sStamp);
430 - jQuery("a[@href=" + sStamp + "]", wym._doc.body)
431 - .attr(WYMeditor.HREF, sUrl);
432 - }
433 - wdw.close();
434 - });
435 - wdw.jQuery(dbody).find(\'input.wym_submit_meaneditor_image\').click(function() {
436 - var image_name = jQuery(dbody).find(wym._options.srcSelector).val();
437 - var sUrl = \'' . $wgUploadPath . '/' . '\' + image_name;
438 -
439 - // Copied from original dialog handling
440 - var sStamp = wym.uniqueStamp();
441 - if(sUrl.length > 0) {
442 - wym._exec(WYMeditor.INSERT_IMAGE, sStamp);
443 - jQuery("img[@src=" + sStamp + "]", wym._doc.body)
444 - .attr(WYMeditor.SRC, sUrl)
445 - .attr(WYMeditor.ALT, image_name);
446 - }
447 - wdw.close();
448 - });
449 - }
450 -
451 - });
452 - });
453 - ');
454 - $wgOut->addHTML( <<<END
455 -<textarea tabindex='1' accesskey="," name="wpTextbox1" id="wpTextbox1" class="wymeditor" rows='{$rows}'
456 -cols='{$cols}'{$ew}></textarea>
457 -END
458 - );
459 - return false;
460 -}
461 -
46228 function recent_images($rsargs)
46329 {
46430 global $wgUploadPath, $wgDBprefix;
@@ -477,7 +43,6 @@
47844 return '<tr><td colspan="2"><strong>' . wfMsgWikiHtml('no_recent_images') . '</strong>' . ($u->isLoggedIn() ? '' : wfMsgWikiHtml('try_login')) . '</td></tr>';
47945 } else return $return_text;
48046 }
481 -$wgAjaxExportList[] = "recent_images";
48247
48348 function toggle_visualeditor_preference(&$toggles)
48449 {
@@ -493,9 +58,6 @@
49459 return false;
49560 }
49661
497 -$wgHooks['UserToggles'][] = 'toggle_visualeditor_preference';
498 -
499 -
50062 # Regular Editpage hooks
50163 function meaneditor_checkboxes(&$editpage, &$checkboxes, &$tabindex)
50264 {

Follow-up revisions

RevisionCommit summaryAuthorDate
r95543Fixes to r95541, for static methodsyaron23:06, 25 August 2011

Status & tagging log