X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FLinker.php;h=0b2d3a71b56dbc5cf43d8e2906ac9d8d422c2acd;hb=ca831d5f4535146dc1ddd19059d981f4deb01126;hp=6a869dd45f7bafe83acbcbcef85aed766d9c18a3;hpb=1a410d558a4d3bb8595072264e49cb05c55cfabf;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Linker.php b/includes/Linker.php index 6a869dd45f..0b2d3a71b5 100644 --- a/includes/Linker.php +++ b/includes/Linker.php @@ -20,6 +20,7 @@ * @file */ use MediaWiki\Linker\LinkTarget; +use MediaWiki\MediaWikiServices; /** * Some internal bits split of from Skin.php. These functions are used @@ -137,22 +138,30 @@ class Linker { * Return the CSS colour of a known link * * @since 1.16.3 - * @param Title $t + * @param LinkTarget $t * @param int $threshold User defined threshold * @return string CSS class */ - public static function getLinkColour( $t, $threshold ) { - $colour = ''; - if ( $t->isRedirect() ) { + public static function getLinkColour( LinkTarget $t, $threshold ) { + $linkCache = MediaWikiServices::getInstance()->getLinkCache(); + // Make sure the target is in the cache + $id = $linkCache->addLinkObj( $t ); + if ( $id == 0 ) { + // Doesn't exist + return ''; + } + + if ( $linkCache->getGoodLinkFieldObj( $t, 'redirect' ) ) { # Page is a redirect - $colour = 'mw-redirect'; - } elseif ( $threshold > 0 && $t->isContentPage() && - $t->exists() && $t->getLength() < $threshold + return 'mw-redirect'; + } elseif ( $threshold > 0 && MWNamespace::isContent( $t->getNamespace() ) + && $linkCache->getGoodLinkFieldObj( $t, 'length' ) < $threshold ) { # Page is a stub - $colour = 'stub'; + return 'stub'; } - return $colour; + + return ''; } /** @@ -210,55 +219,35 @@ class Linker { wfDeprecated( __METHOD__ . ' with parameter $query as string (should be array)', '1.20' ); $query = wfCgiToArray( $query ); } - $options = (array)$options; - - $dummy = new DummyLinker; // dummy linker instance for bc on the hooks - - $ret = null; - if ( !Hooks::run( 'LinkBegin', - [ $dummy, $target, &$html, &$customAttribs, &$query, &$options, &$ret ] ) - ) { - return $ret; - } - # Normalize the Title if it's a special page - $target = self::normaliseSpecialPage( $target ); - - # If we don't know whether the page exists, let's find out. - if ( !in_array( 'known', $options, true ) && !in_array( 'broken', $options, true ) ) { - if ( $target->isKnown() ) { - $options[] = 'known'; - } else { - $options[] = 'broken'; + $services = MediaWikiServices::getInstance(); + $options = (array)$options; + if ( $options ) { + // Custom options, create new LinkRenderer + if ( !isset( $options['stubThreshold'] ) ) { + $defaultLinkRenderer = $services->getLinkRenderer(); + $options['stubThreshold'] = $defaultLinkRenderer->getStubThreshold(); } + $linkRenderer = $services->getLinkRendererFactory() + ->createFromLegacyOptions( $options ); + } else { + $linkRenderer = $services->getLinkRenderer(); } - $oldquery = []; - if ( in_array( "forcearticlepath", $options, true ) && $query ) { - $oldquery = $query; - $query = []; - } - - # Note: we want the href attribute first, for prettiness. - $attribs = [ 'href' => self::linkUrl( $target, $query, $options ) ]; - if ( in_array( 'forcearticlepath', $options, true ) && $oldquery ) { - $attribs['href'] = wfAppendQuery( $attribs['href'], $oldquery ); - } - - $attribs = array_merge( - $attribs, - self::linkAttribs( $target, $customAttribs, $options ) - ); - if ( is_null( $html ) ) { - $html = self::linkText( $target ); - } - - $ret = null; - if ( Hooks::run( 'LinkEnd', [ $dummy, $target, $options, &$html, &$attribs, &$ret ] ) ) { - $ret = Html::rawElement( 'a', $attribs, $html ); + if ( $html !== null ) { + $text = new HtmlArmor( $html ); + } else { + $text = $html; // null + } + if ( in_array( 'known', $options, true ) ) { + return $linkRenderer->makeKnownLink( $target, $text, $customAttribs, $query ); + } elseif ( in_array( 'broken', $options, true ) ) { + return $linkRenderer->makeBrokenLink( $target, $text, $customAttribs, $query ); + } elseif ( in_array( 'noclasses', $options, true ) ) { + return $linkRenderer->makePreloadedLink( $target, $text, '', $customAttribs, $query ); + } else { + return $linkRenderer->makeLink( $target, $text, $customAttribs, $query ); } - - return $ret; } /** @@ -269,135 +258,11 @@ class Linker { */ public static function linkKnown( $target, $html = null, $customAttribs = [], - $query = [], $options = [ 'known', 'noclasses' ] + $query = [], $options = [ 'known' ] ) { return self::link( $target, $html, $customAttribs, $query, $options ); } - /** - * Returns the Url used to link to a Title - * - * @param LinkTarget $target - * @param array $query Query parameters - * @param array $options - * @return string - */ - private static function linkUrl( LinkTarget $target, $query, $options ) { - # We don't want to include fragments for broken links, because they - # generally make no sense. - if ( in_array( 'broken', $options, true ) && $target->hasFragment() ) { - $target = $target->createFragmentTarget( '' ); - } - - # If it's a broken link, add the appropriate query pieces, unless - # there's already an action specified, or unless 'edit' makes no sense - # (i.e., for a nonexistent special page). - if ( in_array( 'broken', $options, true ) && empty( $query['action'] ) - && $target->getNamespace() !== NS_SPECIAL ) { - $query['action'] = 'edit'; - $query['redlink'] = '1'; - } - - if ( in_array( 'http', $options, true ) ) { - $proto = PROTO_HTTP; - } elseif ( in_array( 'https', $options, true ) ) { - $proto = PROTO_HTTPS; - } else { - $proto = PROTO_RELATIVE; - } - - $title = Title::newFromLinkTarget( $target ); - $ret = $title->getLinkURL( $query, false, $proto ); - return $ret; - } - - /** - * Returns the array of attributes used when linking to the Title $target - * - * @param Title $target - * @param array $attribs - * @param array $options - * - * @return array - */ - private static function linkAttribs( $target, $attribs, $options ) { - global $wgUser; - $defaults = []; - - if ( !in_array( 'noclasses', $options, true ) ) { - # Now build the classes. - $classes = []; - - if ( in_array( 'broken', $options, true ) ) { - $classes[] = 'new'; - } - - if ( $target->isExternal() ) { - $classes[] = 'extiw'; - } - - if ( !in_array( 'broken', $options, true ) ) { # Avoid useless calls to LinkCache (see r50387) - $colour = self::getLinkColour( - $target, - isset( $options['stubThreshold'] ) ? $options['stubThreshold'] : $wgUser->getStubThreshold() - ); - if ( $colour !== '' ) { - $classes[] = $colour; # mw-redirect or stub - } - } - if ( $classes != [] ) { - $defaults['class'] = implode( ' ', $classes ); - } - } - - # Get a default title attribute. - if ( $target->getPrefixedText() == '' ) { - # A link like [[#Foo]]. This used to mean an empty title - # attribute, but that's silly. Just don't output a title. - } elseif ( in_array( 'known', $options, true ) ) { - $defaults['title'] = $target->getPrefixedText(); - } else { - // This ends up in parser cache! - $defaults['title'] = wfMessage( 'red-link-title', $target->getPrefixedText() ) - ->inContentLanguage() - ->text(); - } - - # Finally, merge the custom attribs with the default ones, and iterate - # over that, deleting all "false" attributes. - $ret = []; - $merged = Sanitizer::mergeAttributes( $defaults, $attribs ); - foreach ( $merged as $key => $val ) { - # A false value suppresses the attribute, and we don't want the - # href attribute to be overridden. - if ( $key != 'href' && $val !== false ) { - $ret[$key] = $val; - } - } - return $ret; - } - - /** - * Default text of the links to the Title $target - * - * @param Title $target - * - * @return string - */ - private static function linkText( $target ) { - if ( !$target instanceof Title ) { - wfWarn( __METHOD__ . ': Requires $target to be a Title object.' ); - return ''; - } - // If the target is just a fragment, with no title, we return the fragment - // text. Otherwise, we return the title text itself. - if ( $target->getPrefixedText() === '' && $target->hasFragment() ) { - return htmlspecialchars( $target->getFragment() ); - } - - return htmlspecialchars( $target->getPrefixedText() ); - } - /** * Make appropriate markup for a link to the current article. This is * currently rendered as the bold link text. The calling sequence is the @@ -940,7 +805,15 @@ class Linker { $redir = RepoGroup::singleton()->getLocalRepo()->checkRedirect( $title ); if ( $redir ) { - return self::linkKnown( $title, $encLabel, [], wfCgiToArray( $query ) ); + // We already know it's a redirect, so mark it + // accordingly + return self::link( + $title, + $encLabel, + [ 'class' => 'mw-redirect' ], + wfCgiToArray( $query ), + [ 'known', 'noclasses' ] + ); } $href = self::getUploadUrl( $title, $query ); @@ -950,7 +823,7 @@ class Linker { $encLabel . ''; } - return self::linkKnown( $title, $encLabel, [], wfCgiToArray( $query ) ); + return self::link( $title, $encLabel, [], wfCgiToArray( $query ), [ 'known', 'noclasses' ] ); } /** @@ -1084,7 +957,16 @@ class Linker { if ( !$title ) { $title = $wgTitle; } - $attribs['rel'] = Parser::getExternalLinkRel( $url, $title ); + $newRel = Parser::getExternalLinkRel( $url, $title ); + if ( !isset( $attribs['rel'] ) || $attribs['rel'] === '' ) { + $attribs['rel'] = $newRel; + } elseif ( $newRel !== '' ) { + // Merge the rel attributes. + $newRels = explode( ' ', $newRel ); + $oldRels = explode( ' ', $attribs['rel'] ); + $combined = array_unique( array_merge( $newRels, $oldRels ) ); + $attribs['rel'] = implode( ' ', $combined ); + } $link = ''; $success = Hooks::run( 'LinkerMakeExternalLink', [ &$url, &$text, &$link, &$attribs, $linktype ] ); @@ -1872,7 +1754,7 @@ class Linker { * work if $wgShowRollbackEditCount is disabled, so this can only function * as an additional check. * - * If the option noBrackets is set the rollback link wont be enclosed in [] + * If the option noBrackets is set the rollback link wont be enclosed in "[]". * * @since 1.16.3. $context added in 1.20. $options added in 1.21 * @@ -1996,11 +1878,14 @@ class Linker { $query = [ 'action' => 'rollback', 'from' => $rev->getUserText(), - 'token' => $context->getUser()->getEditToken( [ - $title->getPrefixedText(), - $rev->getUserText() - ] ), + 'token' => $context->getUser()->getEditToken( 'rollback' ), ]; + $attrs = [ + 'data-mw' => 'interface', + 'title' => $context->msg( 'tooltip-rollback' )->text(), + ]; + $options = [ 'known', 'noclasses' ]; + if ( $context->getRequest()->getBool( 'bot' ) ) { $query['bot'] = '1'; $query['hidediff'] = '1'; // bug 15999 @@ -2025,27 +1910,16 @@ class Linker { } if ( $editCount > $wgShowRollbackEditCount ) { - $editCount_output = $context->msg( 'rollbacklinkcount-morethan' ) + $html = $context->msg( 'rollbacklinkcount-morethan' ) ->numParams( $wgShowRollbackEditCount )->parse(); } else { - $editCount_output = $context->msg( 'rollbacklinkcount' )->numParams( $editCount )->parse(); + $html = $context->msg( 'rollbacklinkcount' )->numParams( $editCount )->parse(); } - return self::link( - $title, - $editCount_output, - [ 'title' => $context->msg( 'tooltip-rollback' )->text() ], - $query, - [ 'known', 'noclasses' ] - ); + return self::link( $title, $html, $attrs, $query, $options ); } else { - return self::link( - $title, - $context->msg( 'rollbacklink' )->escaped(), - [ 'title' => $context->msg( 'tooltip-rollback' )->text() ], - $query, - [ 'known', 'noclasses' ] - ); + $html = $context->msg( 'rollbacklink' )->escaped(); + return self::link( $title, $html, $attrs, $query, $options ); } }