r61913 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r61912‎ | r61913 | r61914 >
Date:07:10, 3 February 2010
Author:tstarling
Status:resolved (Comments)
Tags:
Comment:
* Fix for r57997 and bug 21222: move math, gallery, pre and nowiki to a new module called CoreTagHooks, analogous to CoreParserFunctions.
* Extended the return interface for tag hooks in a way analogous to the one for parser functions, allowing <nowiki> and <html> to specify that they want to be in the nowiki replacement array instead of the general replacement array.
* Removed ParserOptions::setUseTeX() and related. If <math> is going to be registered in firstCallInit(), then it needs to be stable across multiple parser calls and not change based on parser options. Only one extension caller.

In parserTests.inc:
* Fixed parser test failures due to $wgMathDirectory not being properly set up. The math directory of the host wiki was being used, leading to a parser test failure if it was not writable.
* Fixed message cache hack from r15502. Made parser tests not fail in the case where a tested message is overwritten by the local wiki. All tests now pass on my installation.
Modified paths:
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/parser/CoreTagHooks.php (added) (history)
  • /trunk/phase3/includes/parser/Parser.php (modified) (history)
  • /trunk/phase3/includes/parser/ParserOptions.php (modified) (history)
  • /trunk/phase3/maintenance/parserTests.inc (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/parserTests.inc
@@ -442,11 +442,6 @@
443443 $user = new User();
444444 $options = ParserOptions::newFromUser( $user );
445445
446 - if ( isset( $opts['math'] ) ) {
447 - # XXX this should probably be done by the ParserOptions
448 - $options->setUseTex(true);
449 - }
450 -
451446 $m = array();
452447 if (isset( $opts['title'] ) ) {
453448 $titleText = $opts['title'];
@@ -641,7 +636,8 @@
642637 'wgNoFollowDomainExceptions' => array(),
643638 'wgThumbnailScriptPath' => false,
644639 'wgUseImageResize' => false,
645 - 'wgUseTeX' => false,
 640+ 'wgUseTeX' => isset( $opts['math'] ),
 641+ 'wgMathDirectory' => $this->uploadDir . '/math',
646642 'wgLocaltimezone' => 'UTC',
647643 'wgAllowExternalImages' => true,
648644 'wgUseTidy' => false,
@@ -689,8 +685,6 @@
690686 $GLOBALS['wgMemc'] = new FakeMemCachedClient;
691687 $GLOBALS['wgOut'] = new OutputPage;
692688
693 - //$GLOBALS['wgMessageCache'] = new MessageCache( new BagOStuff(), false, 0, $GLOBALS['wgDBname'] );
694 -
695689 MagicWord::clearCache();
696690
697691 global $wgUser;
@@ -848,6 +842,10 @@
849843
850844 # Reinitialise the LocalisationCache to match the database state
851845 Language::getLocalisationCache()->unloadAll();
 846+
 847+ # Make a new message cache
 848+ global $wgMessageCache, $wgMemc;
 849+ $wgMessageCache = new MessageCache( $wgMemc, true, 3600, '' );
852850 }
853851
854852 /**
@@ -954,6 +952,8 @@
955953 "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg",
956954
957955 "$dir/0/09/Bad.jpg",
 956+
 957+ "$dir/math/f/a/5/fa50b8b616463173474302ca3e63586b.png",
958958 )
959959 );
960960
@@ -969,8 +969,11 @@
970970
971971 "$dir/0/09/",
972972 "$dir/0/",
973 -
974973 "$dir/thumb",
 974+ "$dir/math/f/a/5",
 975+ "$dir/math/f/a",
 976+ "$dir/math/f",
 977+ "$dir/math",
975978 "$dir",
976979 )
977980 );
@@ -1122,7 +1125,6 @@
11231126 * @param int $line the input line number, for reporting errors
11241127 */
11251128 private function addArticle($name, $text, $line) {
1126 - global $wgMessageCache;
11271129 $this->setupGlobals();
11281130 $title = Title::newFromText( $name );
11291131 if ( is_null($title) ) {
Index: trunk/phase3/includes/parser/Parser.php
@@ -129,7 +129,7 @@
130130 $this->mFunctionHooks = array();
131131 $this->mFunctionTagHooks = array();
132132 $this->mFunctionSynonyms = array( 0 => array(), 1 => array() );
133 - $this->mDefaultStripList = $this->mStripList = array( 'nowiki', 'gallery' );
 133+ $this->mDefaultStripList = $this->mStripList = array();
134134 $this->mUrlProtocols = wfUrlProtocols();
135135 $this->mExtLinkBracketedRegex = '/\[(\b(' . wfUrlProtocols() . ')'.
136136 '[^][<>"\\x00-\\x20\\x7F]+) *([^\]\\x0a\\x0d]*?)\]/S';
@@ -172,8 +172,8 @@
173173
174174 wfProfileIn( __METHOD__ );
175175
176 - $this->setHook( 'pre', array( $this, 'renderPreTag' ) );
177176 CoreParserFunctions::register( $this );
 177+ CoreTagHooks::register( $this );
178178 $this->initialiseVariables();
179179
180180 wfRunHooks( 'ParserFirstCallInit', array( &$this ) );
@@ -614,15 +614,7 @@
615615 * Get a list of strippable XML-like elements
616616 */
617617 function getStripList() {
618 - global $wgRawHtml;
619 - $elements = $this->mStripList;
620 - if( $wgRawHtml ) {
621 - $elements[] = 'html';
622 - }
623 - if( $this->mOptions->getUseTeX() ) {
624 - $elements[] = 'math';
625 - }
626 - return $elements;
 618+ return $this->mStripList;
627619 }
628620
629621 /**
@@ -3282,59 +3274,48 @@
32833275 $name = $frame->expand( $params['name'] );
32843276 $attrText = !isset( $params['attr'] ) ? null : $frame->expand( $params['attr'] );
32853277 $content = !isset( $params['inner'] ) ? null : $frame->expand( $params['inner'] );
3286 -
32873278 $marker = "{$this->mUniqPrefix}-$name-" . sprintf('%08X', $this->mMarkerIndex++) . self::MARKER_SUFFIX;
32883279
32893280 $isFunctionTag = isset( $this->mFunctionTagHooks[strtolower($name)] ) &&
32903281 ( $this->ot['html'] || $this->ot['pre'] );
 3282+ if ( $isFunctionTag ) {
 3283+ $markerType = 'none';
 3284+ } else {
 3285+ $markerType = 'general';
 3286+ }
32913287 if ( $this->ot['html'] || $isFunctionTag ) {
32923288 $name = strtolower( $name );
32933289 $attributes = Sanitizer::decodeTagAttributes( $attrText );
32943290 if ( isset( $params['attributes'] ) ) {
32953291 $attributes = $attributes + $params['attributes'];
32963292 }
3297 - switch ( $name ) {
3298 - case 'html':
3299 - if( $wgRawHtml ) {
3300 - $output = $content;
3301 - break;
3302 - } else {
3303 - throw new MWException( '<html> extension tag encountered unexpectedly' );
3304 - }
3305 - case 'nowiki':
3306 - $content = strtr($content, array('-{' => '-&#123;', '}-' => '&#125;-'));
3307 - $output = Xml::escapeTagsOnly( $content );
3308 - break;
3309 - case 'gallery':
3310 - $output = $this->renderImageGallery( $content, $attributes );
3311 - break;
3312 - case 'math':
3313 - if ( $this->mOptions->getUseTeX() ) {
3314 - $output = $wgContLang->armourMath(
3315 - MathRenderer::renderMath( $content, $attributes ) );
3316 - break;
3317 - }
3318 - /* else let a tag hook handle it (bug 21222) */
3319 - default:
3320 - if( isset( $this->mTagHooks[$name] ) ) {
3321 - # Workaround for PHP bug 35229 and similar
3322 - if ( !is_callable( $this->mTagHooks[$name] ) ) {
3323 - throw new MWException( "Tag hook for $name is not callable\n" );
3324 - }
3325 - $output = call_user_func_array( $this->mTagHooks[$name],
3326 - array( $content, $attributes, $this, $frame ) );
3327 - } elseif( isset( $this->mFunctionTagHooks[$name] ) ) {
3328 - list( $callback, $flags ) = $this->mFunctionTagHooks[$name];
3329 - if( !is_callable( $callback ) )
3330 - throw new MWException( "Tag hook for $name is not callable\n" );
33313293
3332 - $output = call_user_func_array( $callback,
3333 - array( &$this, $frame, $content, $attributes ) );
3334 - } else {
3335 - $output = '<span class="error">Invalid tag extension name: ' .
3336 - htmlspecialchars( $name ) . '</span>';
3337 - }
 3294+ if( isset( $this->mTagHooks[$name] ) ) {
 3295+ # Workaround for PHP bug 35229 and similar
 3296+ if ( !is_callable( $this->mTagHooks[$name] ) ) {
 3297+ throw new MWException( "Tag hook for $name is not callable\n" );
 3298+ }
 3299+ $output = call_user_func_array( $this->mTagHooks[$name],
 3300+ array( $content, $attributes, $this, $frame ) );
 3301+ } elseif( isset( $this->mFunctionTagHooks[$name] ) ) {
 3302+ list( $callback, $flags ) = $this->mFunctionTagHooks[$name];
 3303+ if( !is_callable( $callback ) )
 3304+ throw new MWException( "Tag hook for $name is not callable\n" );
 3305+
 3306+ $output = call_user_func_array( $callback,
 3307+ array( &$this, $frame, $content, $attributes ) );
 3308+ } else {
 3309+ $output = '<span class="error">Invalid tag extension name: ' .
 3310+ htmlspecialchars( $name ) . '</span>';
33383311 }
 3312+
 3313+ if ( is_array( $output ) ) {
 3314+ // Extract flags to local scope (to override $markerType)
 3315+ $flags = $output;
 3316+ $output = $flags[0];
 3317+ unset( $flags[0] );
 3318+ extract( $flags );
 3319+ }
33393320 } else {
33403321 if ( is_null( $attrText ) ) {
33413322 $attrText = '';
@@ -3353,12 +3334,14 @@
33543335 }
33553336 }
33563337
3357 - if( $isFunctionTag ) {
 3338+ if( $markerType === 'none' ) {
33583339 return $output;
3359 - } elseif ( $name === 'html' || $name === 'nowiki' ) {
 3340+ } elseif ( $markerType === 'nowiki' ) {
33603341 $this->mStripState->nowiki->setPair( $marker, $output );
3361 - } else {
 3342+ } elseif ( $markerType === 'general' ) {
33623343 $this->mStripState->general->setPair( $marker, $output );
 3344+ } else {
 3345+ throw new MWException( __METHOD__.': invalid marker type' );
33633346 }
33643347 return $marker;
33653348 }
@@ -4342,19 +4325,6 @@
43434326 }
43444327
43454328 /**
4346 - * Tag hook handler for 'pre'.
4347 - */
4348 - function renderPreTag( $text, $attribs ) {
4349 - // Backwards-compatibility hack
4350 - $content = StringUtils::delimiterReplace( '<nowiki>', '</nowiki>', '$1', $text, 'i' );
4351 -
4352 - $attribs = Sanitizer::validateTagAttributes( $attribs, 'pre' );
4353 - return Xml::openElement( 'pre', $attribs ) .
4354 - Xml::escapeTagsOnly( $content ) .
4355 - '</pre>';
4356 - }
4357 -
4358 - /**
43594329 * Renders an image gallery from a text with one line per image.
43604330 * text labels may be given by using |-style alternative text. E.g.
43614331 * Image:one.jpg|The number "1"
Index: trunk/phase3/includes/parser/CoreTagHooks.php
@@ -0,0 +1,49 @@
 2+<?php
 3+
 4+class CoreTagHooks {
 5+ static function register( $parser ) {
 6+ global $wgRawHtml, $wgUseTeX;
 7+ $parser->setHook( 'pre', array( __CLASS__, 'pre' ) );
 8+ $parser->setHook( 'nowiki', array( __CLASS__, 'nowiki' ) );
 9+ $parser->setHook( 'gallery', array( __CLASS__, 'gallery' ) );
 10+ if ( $wgRawHtml ) {
 11+ $parser->setHook( 'html', array( __CLASS__, 'html' ) );
 12+ }
 13+ if ( $wgUseTeX ) {
 14+ $parser->setHook( 'math', array( __CLASS__, 'math' ) );
 15+ }
 16+ }
 17+
 18+ static function pre( $text, $attribs, $parser ) {
 19+ // Backwards-compatibility hack
 20+ $content = StringUtils::delimiterReplace( '<nowiki>', '</nowiki>', '$1', $text, 'i' );
 21+
 22+ $attribs = Sanitizer::validateTagAttributes( $attribs, 'pre' );
 23+ return Xml::openElement( 'pre', $attribs ) .
 24+ Xml::escapeTagsOnly( $content ) .
 25+ '</pre>';
 26+ }
 27+
 28+ static function html( $content, $attributes, $parser ) {
 29+ global $wgRawHtml;
 30+ if( $wgRawHtml ) {
 31+ return array( $content, 'markerType' => 'nowiki' );
 32+ } else {
 33+ throw new MWException( '<html> extension tag encountered unexpectedly' );
 34+ }
 35+ }
 36+
 37+ static function nowiki( $content, $attributes, $parser ) {
 38+ $content = strtr( $content, array( '-{' => '-&#123;', '}-' => '&#125;-' ) );
 39+ return array( Xml::escapeTagsOnly( $content ), 'markerType' => 'nowiki' );
 40+ }
 41+
 42+ static function math( $content, $attributes, $parser ) {
 43+ global $wgContLang;
 44+ return $output = $wgContLang->armourMath( MathRenderer::renderMath( $content, $attributes ) );
 45+ }
 46+
 47+ static function gallery( $content, $attributes, $parser ) {
 48+ return $parser->renderImageGallery( $content, $attributes );
 49+ }
 50+}
Property changes on: trunk/phase3/includes/parser/CoreTagHooks.php
___________________________________________________________________
Added: svn:eol-style
151 + native
Index: trunk/phase3/includes/parser/ParserOptions.php
@@ -7,7 +7,6 @@
88 */
99 class ParserOptions {
1010 # All variables are supposed to be private in theory, although in practise this is not the case.
11 - var $mUseTeX; # Use texvc to expand <math> tags
1211 var $mUseDynamicDates; # Use DateFormatter to format dates
1312 var $mInterwikiMagic; # Interlanguage links are removed and returned in an array
1413 var $mAllowExternalImages; # Allow external images inline
@@ -36,7 +35,6 @@
3736 var $mIsSectionPreview; # Parsing the page for a "preview" operation on a single section
3837 var $mIsPrintable; # Parsing the printable version of the page
3938
40 - function getUseTeX() { return $this->mUseTeX; }
4139 function getUseDynamicDates() { return $this->mUseDynamicDates; }
4240 function getInterwikiMagic() { return $this->mInterwikiMagic; }
4341 function getAllowExternalImages() { return $this->mAllowExternalImages; }
@@ -81,7 +79,6 @@
8280 return $this->mTimestamp;
8381 }
8482
85 - function setUseTeX( $x ) { return wfSetVar( $this->mUseTeX, $x ); }
8683 function setUseDynamicDates( $x ) { return wfSetVar( $this->mUseDynamicDates, $x ); }
8784 function setInterwikiMagic( $x ) { return wfSetVar( $this->mInterwikiMagic, $x ); }
8885 function setAllowExternalImages( $x ) { return wfSetVar( $this->mAllowExternalImages, $x ); }
@@ -122,7 +119,7 @@
123120
124121 /** Get user options */
125122 function initialiseFromUser( $userInput ) {
126 - global $wgUseTeX, $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages;
 123+ global $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages;
127124 global $wgAllowExternalImagesFrom, $wgEnableImageWhitelist, $wgAllowSpecialInclusion, $wgMaxArticleSize;
128125 global $wgMaxPPNodeCount, $wgMaxTemplateDepth, $wgMaxPPExpandDepth, $wgCleanSignatures;
129126 global $wgExternalLinkTarget;
@@ -142,7 +139,6 @@
143140
144141 $this->mUser = $user;
145142
146 - $this->mUseTeX = $wgUseTeX;
147143 $this->mUseDynamicDates = $wgUseDynamicDates;
148144 $this->mInterwikiMagic = $wgInterwikiMagic;
149145 $this->mAllowExternalImages = $wgAllowExternalImages;
Index: trunk/phase3/includes/AutoLoader.php
@@ -436,6 +436,7 @@
437437 # includes/parser
438438 'CoreLinkFunctions' => 'includes/parser/CoreLinkFunctions.php',
439439 'CoreParserFunctions' => 'includes/parser/CoreParserFunctions.php',
 440+ 'CoreTagHooks' => 'includes/parser/CoreTagHooks.php',
440441 'DateFormatter' => 'includes/parser/DateFormatter.php',
441442 'LinkHolderArray' => 'includes/parser/LinkHolderArray.php',
442443 'LinkMarkerReplacer' => 'includes/parser/Parser_LinkHooks.php',

Follow-up revisions

RevisionCommit summaryAuthorDate
r61914Fix for r61913, setUseTeX() removed.tstarling07:13, 3 February 2010
r62726Fixed unnecessary assignment (from r61913)tstarling23:21, 19 February 2010
r68812(Bug 22675) Fix DynamicPageList (3rd party) to work with mediawiki post r61913...bawolff03:44, 1 July 2010

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r15502* Quick hack for extension testing: parser test doesn't create new message...brion18:06, 10 July 2006
r57997(bug 21222) Free <math> tag if not using it. Patch by Platonides.demon11:40, 22 October 2009

Comments

#Comment by P.Copp (talk | contribs)   18:13, 19 February 2010
-		} elseif ( $name === 'html' || $name === 'nowiki' ) {
+		} elseif ( $markerType === 'nowiki' ) {

Note, that this changes the marker type for <nowiki>-tags from 'nowiki' to 'general' for the output types OT_PREPROCESS and OT_WIKI. At first glance this doesn't seem to hurt, since both preSaveTransform() and preprocess() always do unstripBoth(), but perhaps this should be documented in a comment, so people don't get confused when their extensions happen to rely on the old behavior.

+		return $output = $wgContLang->armourMath( MathRenderer::renderMath( $content, $attributes ) );

The assignment to $output seems unnecessary here.

#Comment by Tim Starling (talk | contribs)   23:29, 19 February 2010

The only extension that calls unstripNoWiki() or unstripGeneral() is SemanticForms. It looks like the only thing that's affected is substing a parser function like #arraymap when the delimiter contains <nowiki>. I'm not sure if that's worth fixing.

CoreTagHooks::math() is fixed in r62726.

Status & tagging log