Index: trunk/phase3/includes/CoreParserFunctions.php |
— | — | @@ -211,5 +211,56 @@ |
212 | 212 | return ''; |
213 | 213 | } |
214 | 214 | } |
| 215 | + |
| 216 | + /** |
| 217 | + * Parser function to extension tag adaptor |
| 218 | + */ |
| 219 | + public static function tagObj( $parser, $frame, $args ) { |
| 220 | + $xpath = false; |
| 221 | + if ( !count( $args ) ) { |
| 222 | + return ''; |
| 223 | + } |
| 224 | + $tagName = strtolower( trim( $frame->expand( array_shift( $args ) ) ) ); |
| 225 | + $stripList = $parser->getStripList(); |
| 226 | + if ( !in_array( $tagName, $stripList ) ) { |
| 227 | + return '<span class="error">' . |
| 228 | + wfMsg( 'unknown_extension_tag', $tagName ) . |
| 229 | + '</span>'; |
| 230 | + } |
| 231 | + |
| 232 | + $lastNumberedNode = false; |
| 233 | + $attributes = array(); |
| 234 | + foreach ( $args as $arg ) { |
| 235 | + if ( !$xpath ) { |
| 236 | + $xpath = new DOMXPath( $arg->ownerDocument ); |
| 237 | + } |
| 238 | + $names = $xpath->query( 'name', $arg ); |
| 239 | + if ( $names->item( 0 )->hasAttributes() ) { |
| 240 | + $lastNumberedNode = $arg; |
| 241 | + } else { |
| 242 | + $name = $frame->expand( $names->item( 0 ), PPFrame::STRIP_COMMENTS ); |
| 243 | + if ( preg_match( '/^\d+$/', $name ) ) { |
| 244 | + // For = suppression syntax {{#tag|thing|1=2=3=4}} |
| 245 | + $lastNumberedNode = $arg; |
| 246 | + } else { |
| 247 | + $values = $xpath->query( 'value', $arg ); |
| 248 | + $attributes[$name] = trim( $frame->expand( $values->item( 0 ) ) ); |
| 249 | + } |
| 250 | + } |
| 251 | + } |
| 252 | + |
| 253 | + if ( !$lastNumberedNode ) { |
| 254 | + $inner = null; |
| 255 | + } else { |
| 256 | + $values = $xpath->query( 'value', $lastNumberedNode ); |
| 257 | + $inner = $frame->expand( $values->item( 0 ) ); |
| 258 | + } |
| 259 | + $params = array( |
| 260 | + 'name' => $tagName, |
| 261 | + 'inner' => $inner, |
| 262 | + 'attributes' => $attributes |
| 263 | + ); |
| 264 | + return $parser->extensionSubstitution( $params, $frame ); |
| 265 | + } |
215 | 266 | } |
216 | 267 | |
Index: trunk/phase3/includes/Parser.php |
— | — | @@ -166,6 +166,7 @@ |
167 | 167 | $this->setFunctionHook( 'special', array( 'CoreParserFunctions', 'special' ) ); |
168 | 168 | $this->setFunctionHook( 'defaultsort', array( 'CoreParserFunctions', 'defaultsort' ), SFH_NO_HASH ); |
169 | 169 | $this->setFunctionHook( 'filepath', array( 'CoreParserFunctions', 'filepath' ), SFH_NO_HASH ); |
| 170 | + $this->setFunctionHook( 'tag', array( 'CoreParserFunctions', 'tagObj' ), SFH_OBJECT_ARGS ); |
170 | 171 | |
171 | 172 | if ( $wgAllowDisplayTitle ) { |
172 | 173 | $this->setFunctionHook( 'displaytitle', array( 'CoreParserFunctions', 'displaytitle' ), SFH_NO_HASH ); |
— | — | @@ -3661,7 +3662,8 @@ |
3662 | 3663 | * |
3663 | 3664 | * @param array $params Associative array of parameters: |
3664 | 3665 | * name DOMNode for the tag name |
3665 | | - * attrText DOMNode for unparsed text where tag attributes are thought to be |
| 3666 | + * attr DOMNode for unparsed text where tag attributes are thought to be |
| 3667 | + * attributes Optional associative array of parsed attributes |
3666 | 3668 | * inner Contents of extension element |
3667 | 3669 | * noClose Original text did not have a close tag |
3668 | 3670 | * @param PPFrame $frame |
— | — | @@ -3671,15 +3673,18 @@ |
3672 | 3674 | static $n = 1; |
3673 | 3675 | |
3674 | 3676 | $name = $frame->expand( $params['name'] ); |
3675 | | - $attrText = is_null( $params['attr'] ) ? null : $frame->expand( $params['attr'] ); |
3676 | | - $content = is_null( $params['inner'] ) ? null : $frame->expand( $params['inner'] ); |
| 3677 | + $attrText = !isset( $params['attr'] ) ? null : $frame->expand( $params['attr'] ); |
| 3678 | + $content = !isset( $params['inner'] ) ? null : $frame->expand( $params['inner'] ); |
3677 | 3679 | |
3678 | 3680 | $marker = "{$this->mUniqPrefix}-$name-" . sprintf('%08X', $n++) . $this->mMarkerSuffix; |
3679 | 3681 | |
3680 | 3682 | if ( $this->ot['html'] ) { |
3681 | 3683 | $name = strtolower( $name ); |
3682 | 3684 | |
3683 | | - $params = Sanitizer::decodeTagAttributes( $attrText ); |
| 3685 | + $attributes = Sanitizer::decodeTagAttributes( $attrText ); |
| 3686 | + if ( isset( $params['attributes'] ) ) { |
| 3687 | + $attributes = $attributes + $params['attributes']; |
| 3688 | + } |
3684 | 3689 | switch ( $name ) { |
3685 | 3690 | case 'html': |
3686 | 3691 | if( $wgRawHtml ) { |
— | — | @@ -3693,15 +3698,15 @@ |
3694 | 3699 | break; |
3695 | 3700 | case 'math': |
3696 | 3701 | $output = $wgContLang->armourMath( |
3697 | | - MathRenderer::renderMath( $content, $params ) ); |
| 3702 | + MathRenderer::renderMath( $content, $attributes ) ); |
3698 | 3703 | break; |
3699 | 3704 | case 'gallery': |
3700 | | - $output = $this->renderImageGallery( $content, $params ); |
| 3705 | + $output = $this->renderImageGallery( $content, $attributes ); |
3701 | 3706 | break; |
3702 | 3707 | default: |
3703 | 3708 | if( isset( $this->mTagHooks[$name] ) ) { |
3704 | 3709 | $output = call_user_func_array( $this->mTagHooks[$name], |
3705 | | - array( $content, $params, $this ) ); |
| 3710 | + array( $content, $attributes, $this ) ); |
3706 | 3711 | } else { |
3707 | 3712 | throw new MWException( "Invalid call hook $name" ); |
3708 | 3713 | } |
Index: trunk/phase3/languages/messages/MessagesEn.php |
— | — | @@ -335,6 +335,7 @@ |
336 | 336 | 'special' => array( 0, 'special', ), |
337 | 337 | 'defaultsort' => array( 1, 'DEFAULTSORT:', 'DEFAULTSORTKEY:', 'DEFAULTCATEGORYSORT:' ), |
338 | 338 | 'filepath' => array( 0, 'FILEPATH:' ), |
| 339 | + 'tag' => array( 0, 'tag' ), |
339 | 340 | ); |
340 | 341 | |
341 | 342 | /** |
— | — | @@ -3115,4 +3116,7 @@ |
3116 | 3117 | 'signature' => '[[{{ns:user}}:$1|$2]]', # don't translate or duplicate this message to other languages |
3117 | 3118 | 'signature-anon' => '[[{{#special:Contributions}}/$1|$2]]', # don't translate or duplicate this message to other languages |
3118 | 3119 | |
| 3120 | +# CoreParserFunctions |
| 3121 | +'unknown_extension_tag' => 'Unknown extension tag "$1"', |
| 3122 | + |
3119 | 3123 | ); |