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 &lt;a&gt; 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

Reply via email to