http://www.mediawiki.org/wiki/Special:Code/MediaWiki/58717
Revision: 58717 Author: daniel Date: 2009-11-07 16:46:34 +0000 (Sat, 07 Nov 2009) Log Message: ----------- adding support for <a> tags as a parser tag hook, in order to support rdfa output Modified Paths: -------------- trunk/phase3/includes/Linker.php trunk/phase3/includes/Sanitizer.php trunk/phase3/includes/parser/Parser.php Modified: trunk/phase3/includes/Linker.php =================================================================== --- trunk/phase3/includes/Linker.php 2009-11-07 15:59:45 UTC (rev 58716) +++ trunk/phase3/includes/Linker.php 2009-11-07 16:46:34 UTC (rev 58717) @@ -760,7 +760,10 @@ * hook play with them, *then* expand it all at once. */ function makeExternalLink( $url, $text, $escape = true, $linktype = '', $attribs = array() ) { - $attribsText = $this->getExternalLinkAttributes( 'external ' . $linktype ); + if ( isset( $attribs[ 'class' ] ) ) $class = $attribs[ 'class' ]; # yet another hack :( + else $class = 'external ' . $linktype; + + $attribsText = $this->getExternalLinkAttributes( $class ); $url = htmlspecialchars( $url ); if( $escape ) { $text = htmlspecialchars( $text ); Modified: trunk/phase3/includes/Sanitizer.php =================================================================== --- trunk/phase3/includes/Sanitizer.php 2009-11-07 15:59:45 UTC (rev 58716) +++ trunk/phase3/includes/Sanitizer.php 2009-11-07 16:46:34 UTC (rev 58717) @@ -610,6 +610,8 @@ */ static function validateAttributes( $attribs, $whitelist ) { $whitelist = array_flip( $whitelist ); + $hrefExp = '/^(' . wfUrlProtocols() . ')[^\s]+$/'; + $out = array(); foreach( $attribs as $attribute => $value ) { if( !isset( $whitelist[$attribute] ) ) { @@ -641,6 +643,15 @@ } } + # NOTE: even though elements using href/src are not allowed directly, supply + # validation code that can be used by tag hook handlers, etc + if ( $attribute === 'href' || $attribute === 'src' ) { + if ( !preg_match( $hrefExp, $value ) ) { + continue; //drop any href or src attributes not using an allowed protocol. + //NOTE: this also drops all relative URLs + } + } + // If this attribute was previously set, override it. // Output should only have one attribute of each name. $out[$attribute] = $value; @@ -1279,6 +1290,9 @@ 'td' => array_merge( $common, $tablecell, $tablealign ), 'th' => array_merge( $common, $tablecell, $tablealign ), + # 12.2 # NOTE: <a> is not allowed directly, but the attrib whitelist is used from the Parser object + 'a' => array_merge( $common, array( 'href', 'rel', 'rev' ) ), # rel/rev esp. for RDFa + # 13.2 # Not usually allowed, but may be used for extension-style hooks # such as <math> when it is rasterized Modified: trunk/phase3/includes/parser/Parser.php =================================================================== --- trunk/phase3/includes/parser/Parser.php 2009-11-07 15:59:45 UTC (rev 58716) +++ trunk/phase3/includes/parser/Parser.php 2009-11-07 16:46:34 UTC (rev 58717) @@ -129,7 +129,7 @@ $this->mFunctionHooks = array(); $this->mFunctionTagHooks = array(); $this->mFunctionSynonyms = array( 0 => array(), 1 => array() ); - $this->mDefaultStripList = $this->mStripList = array( 'nowiki', 'gallery' ); + $this->mDefaultStripList = $this->mStripList = array( 'nowiki', 'gallery', 'a' ); $this->mUrlProtocols = wfUrlProtocols(); $this->mExtLinkBracketedRegex = '/\[(\b(' . wfUrlProtocols() . ')'. '[^][<>"\\x00-\\x20\\x7F]+) *([^\]\\x0a\\x0d]*?)\]/S'; @@ -3284,6 +3284,9 @@ case 'gallery': $output = $this->renderImageGallery( $content, $attributes ); break; + case 'a': + $output = $this->renderHyperlink( $content, $attributes, $frame ); + break; case 'math': if ( $this->mOptions->getUseTeX() ) { $output = $wgContLang->armourMath( @@ -4333,6 +4336,35 @@ } /** + * Tag hook handler for 'a'. Renders a HTML <a> tag, allowing most attributes, filtering href against + * allowed protocols and spam blacklist. + **/ + function renderHyperlink( $text, $params, $frame = false ) { + foreach ( $params as $name => $value ) { + $params[ $name ] = $this->replaceVariables( $value, $frame ); + } + + $whitelist = Sanitizer::attributeWhitelist( 'a' ); + $params = Sanitizer::validateAttributes( $params, $whitelist ); + + $content = $this->recursiveTagParse( trim( $text ), $frame ); + + if ( isset( $params[ 'href' ] ) ) { + $href = $params[ 'href' ]; + $this->mOutput->addExternalLink( $href ); + unset( $params[ 'href' ] ); + } else { + # Non-link <a> tag + return Xml::openElement( 'a', $params ) . $content . Xml::closeElement( 'a' ); + } + + $sk = $this->mOptions->getSkin(); + $html = $sk->makeExternalLink( $href, $content, false, '', $params ); + + return $html; + } + + /** * Renders an image gallery from a text with one line per image. * text labels may be given by using |-style alternative text. E.g. * Image:one.jpg|The number "1" _______________________________________________ MediaWiki-CVS mailing list MediaWiki-CVS@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs