Last commit contained errors. Revert most of it, keep only the tweaks to link()...
authorAryeh Gregor <simetrical@users.mediawiki.org>
Sun, 3 Aug 2008 17:05:17 +0000 (17:05 +0000)
committerAryeh Gregor <simetrical@users.mediawiki.org>
Sun, 3 Aug 2008 17:05:17 +0000 (17:05 +0000)
includes/GlobalFunctions.php
includes/Linker.php
includes/Xml.php
maintenance/parserTests.txt

index c5d5f1f..c0d7fe9 100644 (file)
@@ -1055,34 +1055,6 @@ function wfArrayToCGI( $array1, $array2 = NULL )
        return $cgi;
 }
 
-/**
- * This is the logical opposite of wfArrayToCGI(): it accepts a query string as
- * its argument and returns the same string in array form.  This allows compa-
- * tibility with legacy functions that accept raw query strings instead of nice
- * arrays.  Of course, keys and values are urldecode()d.  Don't try passing in-
- * valid query strings, or it will explode.
- *
- * @param $query string Query string
- * @return array Array version of input
- */
-function wfCgiToArray( $query ) {
-       if( isset( $query[0] ) and $query[0] == '?' ) {
-               $query = substr( $query, 1 );
-       }
-       $bits = explode( '&', $query );
-       $ret = array();
-       foreach( $bits as $bit ) {
-               if( $bit === '' ) {
-                       continue;
-               }
-               list( $key, $value ) = explode( '=', $bit );
-               $key = urldecode( $key );
-               $value = urldecode( $value );
-               $ret[$key] = $value;
-       }
-       return $ret;
-}
-
 /**
  * Append a query string to an existing URL, which may or may not already
  * have query string parameters already. If so, they will be combined.
index c80c286..4e4b5f5 100644 (file)
@@ -235,7 +235,7 @@ class Linker {
 
                if( !in_array( 'noclasses', $options ) ) {
                        wfProfileIn( __METHOD__ . '-getClasses' );
-                       # Now build the classes.
+                       # Build the classes.
                        $classes = array();
 
                        if( in_array( 'broken', $options ) ) {
@@ -401,17 +401,58 @@ class Linker {
                global $wgUser;
                wfProfileIn( __METHOD__ );
 
-               $query = wfCgiToArray( $query );
-               list( $inside, $trail ) = Linker::splitTrail( $trail );
-               if( $text === '' ) {
-                       $text = $this->linkText( $nt );
-               }
+               if ( $nt->isExternal() ) {
+                       $u = $nt->getFullURL();
+                       $link = $nt->getPrefixedURL();
+                       if ( '' == $text ) { $text = $nt->getPrefixedText(); }
+                       $style = $this->getInterwikiLinkAttributes( $link, $text, 'extiw' );
+
+                       $inside = '';
+                       if ( '' != $trail ) {
+                               $m = array();
+                               if ( preg_match( '/^([a-z]+)(.*)$$/sD', $trail, $m ) ) {
+                                       $inside = $m[1];
+                                       $trail = $m[2];
+                               }
+                       }
+                       $t = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>";
+
+                       wfProfileOut( __METHOD__ );
+                       return $t;
+               } elseif ( $nt->isAlwaysKnown() ) {
+                       # Image links, special page links and self-links with fragments are always known.
+                       $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
+               } else {
+                       wfProfileIn( __METHOD__.'-immediate' );
 
-               $ret = $this->link( $nt, "$prefix$text$inside", array(), $query,
-                       'noclasses' ) . $trail;
+                       # Handles links to special pages which do not exist in the database:
+                       if( $nt->getNamespace() == NS_SPECIAL ) {
+                               if( SpecialPage::exists( $nt->getDBkey() ) ) {
+                                       $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
+                               } else {
+                                       $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
+                               }
+                               wfProfileOut( __METHOD__.'-immediate' );
+                               wfProfileOut( __METHOD__ );
+                               return $retVal;
+                       }
 
+                       # Work out link colour immediately
+                       $aid = $nt->getArticleID() ;
+                       if ( 0 == $aid ) {
+                               $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
+                       } else {
+                               $colour = '';
+                               if ( $nt->isContentPage() ) {
+                                       $threshold = $wgUser->getOption('stubthreshold');
+                                       $colour = $this->getLinkColour( $nt, $threshold );
+                               }
+                               $retVal = $this->makeColouredLinkObj( $nt, $colour, $text, $query, $trail, $prefix );
+                       }
+                       wfProfileOut( __METHOD__.'-immediate' );
+               }
                wfProfileOut( __METHOD__ );
-               return $ret;
+               return $retVal;
        }
 
        /**
@@ -431,21 +472,31 @@ class Linker {
        function makeKnownLinkObj( Title $title, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '', $style = '' ) {
                wfProfileIn( __METHOD__ );
 
+               $nt = $this->normaliseSpecialPage( $title );
+
+               $u = $nt->escapeLocalURL( $query );
+               if ( $nt->getFragment() != '' ) {
+                       if( $nt->getPrefixedDbkey() == '' ) {
+                               $u = '';
+                               if ( '' == $text ) {
+                                       $text = htmlspecialchars( $nt->getFragment() );
+                               }
+                       }
+                       $u .= $nt->getFragmentForURL();
+               }
                if ( $text == '' ) {
-                       $text = $this->linkText( $title );
+                       $text = htmlspecialchars( $nt->getPrefixedText() );
+               }
+               if ( $style == '' ) {
+                       $style = $this->getInternalLinkAttributesObj( $nt, $text );
                }
-               $attribs = Sanitizer::mergeAttributes(
-                       Xml::explodeAttributes( $aprops ),
-                       Xml::explodeAttributes( $style )
-               );
-               $query = wfCgiToArray( $query );
-               list( $inside, $trail ) = Linker::splitTrail( $trail );
 
-               $ret = $this->link( $title, "$prefix$text$inside", $attribs, $query,
-                       array( 'known', 'noclasses' ) ) . $trail;
+               if ( $aprops !== '' ) $aprops = " $aprops";
 
+               list( $inside, $trail ) = Linker::splitTrail( $trail );
+               $r = "<a href=\"{$u}\"{$style}{$aprops}>{$prefix}{$text}{$inside}</a>{$trail}";
                wfProfileOut( __METHOD__ );
-               return $ret;
+               return $r;
        }
 
        /**
@@ -461,15 +512,32 @@ class Linker {
        function makeBrokenLinkObj( Title $title, $text = '', $query = '', $trail = '', $prefix = '' ) {
                wfProfileIn( __METHOD__ );
 
-               list( $inside, $trail ) = Linker::splitTrail( $trail );
-               if( $text === '' ) {
-                       $text = $this->linkText( $title );
-               }
                $nt = $this->normaliseSpecialPage( $title );
 
+               if( $nt->getNamespace() == NS_SPECIAL ) {
+                       $q = $query;
+               } else if ( '' == $query ) {
+                       $q = 'action=edit&redlink=1';
+               } else {
+                       $q = 'action=edit&redlink=1&'.$query;
+               }
+               $u = $nt->escapeLocalURL( $q );
+               if( $nt->getFragmentForURL() !== '' ) {
+                       # Might seem pointless to have a fragment on a redlink, but let's
+                       # be obedient.
+                       $u .= $nt->getFragmentForURL();
+               }
+
+               $titleText = $nt->getPrefixedText();
+               if ( '' == $text ) {
+                       $text = htmlspecialchars( $titleText );
+               }
+               $titleAttr = wfMsg( 'red-link-title', $titleText );
+               $style = $this->getInternalLinkAttributesObj( $nt, $text, 'new', $titleAttr );
+               list( $inside, $trail ) = Linker::splitTrail( $trail );
+
                wfRunHooks( 'BrokenLink', array( &$this, $nt, $query, &$u, &$style, &$prefix, &$text, &$inside, &$trail ) );
-               $s = $this->link( $title, "$prefix$text$inside", array(),
-                       wfCgiToArray( $query ), array( 'broken', 'noclasses' ) ) . $trail;
+               $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
 
                wfProfileOut( __METHOD__ );
                return $s;
index b5daf18..7db9ee8 100644 (file)
@@ -54,31 +54,6 @@ class Xml {
                }
        }
 
-       /**
-        * Given a string of attributes for an element, return an array of key =>
-        * value pairs.  Can be used for backward compatibility with old functions
-        * that accept attributes as strings instead of arrays.  Does not validate
-        * the string, so watch out for GIGO.
-        *
-        * @param $attribs string
-        * @return array
-        */
-       public static function explodeAttributes( $attribs ) {
-               $matches = array();
-               preg_match_all( '/([^\s=\'"]+)\s*=\s*(?:\'([^\']*)\'|"([^"]*)")/',
-                       $attribs, $matches );
-               $ret = array();
-               for( $i = 0; $i < count( $matches[0] ); ++$i ) {
-                       if( $matches[2][$i] !== '' ) {
-                               $val = $matches[2][$i];
-                       } else {
-                               $val = $matches[3][$i];
-                       }
-                       $ret[$matches[1][$i]] = html_entity_decode( $val );
-               }
-               return $ret;
-       }
-
        /**
         * Format an XML element as with self::element(), but run text through the
         * UtfNormal::cleanUp() validator first to ensure that no invalid UTF-8
@@ -707,4 +682,4 @@ class XmlSelect {
                return Xml::tags( 'select', $this->attributes, implode( "\n", $this->options ) );
        }
 
-}
+}
\ No newline at end of file
index 9379668..51df7e3 100644 (file)
@@ -3339,7 +3339,7 @@ Link to category
 !! input
 [[:Category:MediaWiki User's Guide]]
 !! result
-<p><a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User&#39;s Guide">Category:MediaWiki User's Guide</a>
+<p><a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">Category:MediaWiki User's Guide</a>
 </p>
 !! end
 
@@ -3350,7 +3350,7 @@ cat
 !! input
 [[Category:MediaWiki User's Guide]]
 !! result
-<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User&#039;s Guide">MediaWiki User's Guide</a>
+<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">MediaWiki User's Guide</a>
 !! end
 
 !! test
@@ -6625,7 +6625,7 @@ language=sr cat
 !! input
 [[:Category:МедиаWики Усер'с Гуиде]]
 !! result
-<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User&#039;s Guide">MediaWiki User's Guide</a>
+<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">MediaWiki User's Guide</a>
 !! end