JavaScriptMinifier: Remove support for unused $statementsOnOwnLine flag
[lhc/web/wiklou.git] / includes / Linker.php
index 4aae3ba..48be3bf 100644 (file)
@@ -76,7 +76,7 @@ class Linker {
         * @since 1.18 Method exists since 1.16 as non-static, made static in 1.18.
         * @deprecated since 1.28, use MediaWiki\Linker\LinkRenderer instead
         *
-        * @param Title $target Can currently only be a Title, but this may
+        * @param LinkTarget $target Can currently only be a LinkTarget, but this may
         *   change to support Images, literal URLs, etc.
         * @param string $html The HTML contents of the <a> element, i.e.,
         *   the link text.  This is raw HTML and will not be escaped.  If null,
@@ -107,8 +107,8 @@ class Linker {
        public static function link(
                $target, $html = null, $customAttribs = [], $query = [], $options = []
        ) {
-               if ( !$target instanceof Title ) {
-                       wfWarn( __METHOD__ . ': Requires $target to be a Title object.', 2 );
+               if ( !$target instanceof LinkTarget ) {
+                       wfWarn( __METHOD__ . ': Requires $target to be a LinkTarget object.', 2 );
                        return "<!-- ERROR -->$html";
                }
 
@@ -154,6 +154,11 @@ class Linker {
         * @since 1.16.3
         * @deprecated since 1.28, use MediaWiki\Linker\LinkRenderer instead
         * @see Linker::link
+        * @param Title $target
+        * @param string $html
+        * @param array $customAttribs
+        * @param array $query
+        * @param string|array $options
         * @return string
         */
        public static function linkKnown(
@@ -887,10 +892,26 @@ class Linker {
         */
        public static function userLink( $userId, $userName, $altUserName = false ) {
                $classes = 'mw-userlink';
+               $page = null;
                if ( $userId == 0 ) {
-                       $page = SpecialPage::getTitleFor( 'Contributions', $userName );
-                       if ( $altUserName === false ) {
-                               $altUserName = IP::prettifyIP( $userName );
+                       $pos = strpos( $userName, '>' );
+                       if ( $pos !== false ) {
+                               $iw = explode( ':', substr( $userName, 0, $pos ) );
+                               $firstIw = array_shift( $iw );
+                               $interwikiLookup = MediaWikiServices::getInstance()->getInterwikiLookup();
+                               if ( $interwikiLookup->isValidInterwiki( $firstIw ) ) {
+                                       $title = MWNamespace::getCanonicalName( NS_USER ) . ':' . substr( $userName, $pos + 1 );
+                                       if ( $iw ) {
+                                               $title = join( ':', $iw ) . ':' . $title;
+                                       }
+                                       $page = Title::makeTitle( NS_MAIN, $title, '', $firstIw );
+                               }
+                               $classes .= ' mw-extuserlink';
+                       } else {
+                               $page = SpecialPage::getTitleFor( 'Contributions', $userName );
+                               if ( $altUserName === false ) {
+                                       $altUserName = IP::prettifyIP( $userName );
+                               }
                        }
                        $classes .= ' mw-anonuserlink'; // Separate link class for anons (T45179)
                } else {
@@ -898,11 +919,12 @@ class Linker {
                }
 
                // Wrap the output with <bdi> tags for directionality isolation
-               return self::link(
-                       $page,
-                       '<bdi>' . htmlspecialchars( $altUserName !== false ? $altUserName : $userName ) . '</bdi>',
-                       [ 'class' => $classes ]
-               );
+               $linkText =
+                       '<bdi>' . htmlspecialchars( $altUserName !== false ? $altUserName : $userName ) . '</bdi>';
+
+               return $page
+                       ? self::link( $page, $linkText, [ 'class' => $classes ] )
+                       : Html::rawElement( 'span', [ 'class' => $classes ], $linkText );
        }
 
        /**
@@ -926,6 +948,11 @@ class Linker {
                $blockable = !( $flags & self::TOOL_LINKS_NOBLOCK );
                $addEmailLink = $flags & self::TOOL_LINKS_EMAIL && $userId;
 
+               if ( $userId == 0 && strpos( $userText, '>' ) !== false ) {
+                       // No tools for an external user
+                       return '';
+               }
+
                $items = [];
                if ( $talkable ) {
                        $items[] = self::userTalkLink( $userId, $userText );
@@ -1165,9 +1192,9 @@ class Linker {
                                                $section = str_replace( '[[', '', $section );
                                                $section = str_replace( ']]', '', $section );
 
-                                               $section = Sanitizer::normalizeSectionNameWhitespace( $section ); # T24784
+                                               $section = substr( Parser::guessSectionNameFromStrippedText( $section ), 1 );
                                                if ( $local ) {
-                                                       $sectionTitle = Title::newFromText( '#' . $section );
+                                                       $sectionTitle = Title::makeTitleSafe( NS_MAIN, '', $section );
                                                } else {
                                                        $sectionTitle = Title::makeTitleSafe( $title->getNamespace(),
                                                                $title->getDBkey(), $section );
@@ -1286,9 +1313,7 @@ class Linker {
                                                        if ( $target->getText() == '' && !$target->isExternal()
                                                                && !$local && $title
                                                        ) {
-                                                               $newTarget = clone $title;
-                                                               $newTarget->setFragment( '#' . $target->getFragment() );
-                                                               $target = $newTarget;
+                                                               $target = $title->createFragmentTarget( $target->getFragment() );
                                                        }
 
                                                        $thelink = Linker::makeCommentLink( $target, $linkText . $inside, $wikiId ) . $trail;
@@ -1316,7 +1341,7 @@ class Linker {
         *
         * @note This is only public for technical reasons. It's not intended for use outside Linker.
         *
-        * @param Title $title
+        * @param LinkTarget $linkTarget
         * @param string $text
         * @param string|null $wikiId Id of the wiki to link to (if not the local wiki),
         *  as used by WikiMap.
@@ -1325,23 +1350,23 @@ class Linker {
         * @return string HTML link
         */
        public static function makeCommentLink(
-               Title $title, $text, $wikiId = null, $options = []
+               LinkTarget $linkTarget, $text, $wikiId = null, $options = []
        ) {
-               if ( $wikiId !== null && !$title->isExternal() ) {
+               if ( $wikiId !== null && !$linkTarget->isExternal() ) {
                        $link = self::makeExternalLink(
                                WikiMap::getForeignURL(
                                        $wikiId,
-                                       $title->getNamespace() === 0
-                                               ? $title->getDBkey()
-                                               : MWNamespace::getCanonicalName( $title->getNamespace() ) . ':'
-                                                       . $title->getDBkey(),
-                                       $title->getFragment()
+                                       $linkTarget->getNamespace() === 0
+                                               ? $linkTarget->getDBkey()
+                                               : MWNamespace::getCanonicalName( $linkTarget->getNamespace() ) . ':'
+                                                       . $linkTarget->getDBkey(),
+                                       $linkTarget->getFragment()
                                ),
                                $text,
                                /* escape = */ false // Already escaped
                        );
                } else {
-                       $link = self::link( $title, $text, [], [], $options );
+                       $link = self::link( $linkTarget, $text, [], [], $options );
                }
 
                return $link;
@@ -1350,7 +1375,7 @@ class Linker {
        /**
         * @param Title $contextTitle
         * @param string $target
-        * @param string $text
+        * @param string &$text
         * @return string
         */
        public static function normalizeSubpageLink( $contextTitle, $target, &$text ) {
@@ -1534,10 +1559,16 @@ class Linker {
                if ( $sectionIndex !== false ) {
                        $classes .= " tocsection-$sectionIndex";
                }
-               return "\n<li class=\"$classes\"><a href=\"#" .
-                       $anchor . '"><span class="tocnumber">' .
-                       $tocnumber . '</span> <span class="toctext">' .
-                       $tocline . '</span></a>';
+
+               // \n<li class="$classes"><a href="#$anchor"><span class="tocnumber">
+               // $tocnumber</span> <span class="toctext">$tocline</span></a>
+               return "\n" . Html::openElement( 'li', [ 'class' => $classes ] )
+                       . Html::rawElement( 'a',
+                               [ 'href' => "#$anchor" ],
+                               Html::element( 'span', [ 'class' => 'tocnumber' ], $tocnumber )
+                                       . ' '
+                                       . Html::rawElement( 'span', [ 'class' => 'toctext' ], $tocline )
+                       );
        }
 
        /**
@@ -1608,23 +1639,27 @@ class Linker {
         *   a space and ending with '>'
         *   This *must* be at least '>' for no attribs
         * @param string $anchor The anchor to give the headline (the bit after the #)
-        * @param string $html Html for the text of the header
+        * @param string $html HTML for the text of the header
         * @param string $link HTML to add for the section edit link
-        * @param bool|string $legacyAnchor A second, optional anchor to give for
+        * @param string|bool $fallbackAnchor A second, optional anchor to give for
         *   backward compatibility (false to omit)
         *
         * @return string HTML headline
         */
        public static function makeHeadline( $level, $attribs, $anchor, $html,
-               $link, $legacyAnchor = false
+               $link, $fallbackAnchor = false
        ) {
+               $anchorEscaped = htmlspecialchars( $anchor );
+               $fallback = '';
+               if ( $fallbackAnchor !== false && $fallbackAnchor !== $anchor ) {
+                       $fallbackAnchor = htmlspecialchars( $fallbackAnchor );
+                       $fallback = "<span id=\"$fallbackAnchor\"></span>";
+               }
                $ret = "<h$level$attribs"
-                       . "<span class=\"mw-headline\" id=\"$anchor\">$html</span>"
+                       . "$fallback<span class=\"mw-headline\" id=\"$anchorEscaped\">$html</span>"
                        . $link
                        . "</h$level>";
-               if ( $legacyAnchor !== false ) {
-                       $ret = "<div id=\"$legacyAnchor\"></div>$ret";
-               }
+
                return $ret;
        }