Merge "jquery.tablesorter: Fix pre-JS selector to match wikitext-generated sortable...
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 22 May 2019 17:11:17 +0000 (17:11 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 22 May 2019 17:11:17 +0000 (17:11 +0000)
1  2 
includes/skins/Skin.php
resources/src/jquery.tablesorter.styles/jquery.tablesorter.styles.less

diff --combined includes/skins/Skin.php
@@@ -55,8 -55,7 +55,8 @@@ abstract class Skin extends ContextSour
         * @return array Associative array of strings
         */
        static function getSkinNames() {
 -              return SkinFactory::getDefaultInstance()->getSkinNames();
 +              $skinFactory = MediaWikiServices::getInstance()->getSkinFactory();
 +              return $skinFactory->getSkinNames();
        }
  
        /**
         */
        public function getDefaultModules() {
                $out = $this->getOutput();
 -              $config = $this->getConfig();
                $user = $this->getUser();
  
                // Modules declared in the $modules literal are loaded
                // Preload jquery.tablesorter for mediawiki.page.ready
                if ( strpos( $out->getHTML(), 'sortable' ) !== false ) {
                        $modules['content'][] = 'jquery.tablesorter';
+                       $modules['styles']['content'][] = 'jquery.tablesorter.styles';
                }
  
                // Preload jquery.makeCollapsible for mediawiki.page.ready
        function getCategoryLinks() {
                $out = $this->getOutput();
                $allCats = $out->getCategoryLinks();
 +              $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
  
                if ( $allCats === [] ) {
                        return '';
                if ( !empty( $allCats['normal'] ) ) {
                        $t = $embed . implode( $pop . $embed, $allCats['normal'] ) . $pop;
  
 -                      $msg = $this->msg( 'pagecategories' )->numParams( count( $allCats['normal'] ) )->escaped();
 +                      $msg = $this->msg( 'pagecategories' )->numParams( count( $allCats['normal'] ) );
                        $linkPage = $this->msg( 'pagecategorieslink' )->inContentLanguage()->text();
                        $title = Title::newFromText( $linkPage );
 -                      $link = $title ? Linker::link( $title, $msg ) : $msg;
 +                      $link = $title ? $linkRenderer->makeLink( $title, $msg->text() ) : $msg->escaped();
                        $s .= '<div id="mw-normal-catlinks" class="mw-normal-catlinks">' .
                                $link . $colon . '<ul>' . $t . '</ul></div>';
                }
         */
        function drawCategoryBrowser( $tree ) {
                $return = '';
 +              $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
  
                foreach ( $tree as $element => $parent ) {
                        if ( empty( $parent ) ) {
  
                        # add our current element to the list
                        $eltitle = Title::newFromText( $element );
 -                      $return .= Linker::link( $eltitle, htmlspecialchars( $eltitle->getText() ) );
 +                      $return .= $linkRenderer->makeLink( $eltitle, $eltitle->getText() );
                }
  
                return $return;
        function getUndeleteLink() {
                $action = $this->getRequest()->getVal( 'action', 'view' );
                $title = $this->getTitle();
 +              $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
  
                if ( ( !$title->exists() || $action == 'history' ) &&
                        $title->quickUserCan( 'deletedhistory', $this->getUser() )
                                }
  
                                return $this->msg( $msg )->rawParams(
 -                                      Linker::linkKnown(
 +                                      $linkRenderer->makeKnownLink(
                                                SpecialPage::getTitleFor( 'Undelete', $this->getTitle()->getPrefixedDBkey() ),
 -                                              $this->msg( 'restorelink' )->numParams( $n )->escaped() )
 +                                              $this->msg( 'restorelink' )->numParams( $n )->text() )
                                        )->escaped();
                        }
                }
         * @return string
         */
        function subPageSubtitle( $out = null ) {
 +              $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
                if ( $out === null ) {
                        $out = $this->getOutput();
                }
                        return $subpages;
                }
  
 -              if ( $out->isArticle() && MWNamespace::hasSubpages( $title->getNamespace() ) ) {
 +              if (
 +                      $out->isArticle() && MediaWikiServices::getInstance()->getNamespaceInfo()->
 +                              hasSubpages( $title->getNamespace() )
 +              ) {
                        $ptext = $title->getPrefixedText();
                        if ( strpos( $ptext, '/' ) !== false ) {
                                $links = explode( '/', $ptext );
                                        $linkObj = Title::newFromText( $growinglink );
  
                                        if ( is_object( $linkObj ) && $linkObj->isKnown() ) {
 -                                              $getlink = Linker::linkKnown(
 -                                                      $linkObj,
 -                                                      htmlspecialchars( $display )
 +                                              $getlink = $linkRenderer->makeKnownLink(
 +                                                      $linkObj, $display
                                                );
  
                                                $c++;
         * @return string
         */
        function getCopyright( $type = 'detect' ) {
 +              $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
                if ( $type == 'detect' ) {
                        if ( !$this->isRevisionCurrent()
                                && !$this->msg( 'history_copyright' )->inContentLanguage()->isDisabled()
  
                if ( $config->get( 'RightsPage' ) ) {
                        $title = Title::newFromText( $config->get( 'RightsPage' ) );
 -                      $link = Linker::linkKnown( $title, $config->get( 'RightsText' ) );
 +                      $link = $linkRenderer->makeKnownLink(
 +                              $title, new HtmlArmor( $config->get( 'RightsText' ) )
 +                      );
                } elseif ( $config->get( 'RightsUrl' ) ) {
                        $link = Linker::makeExternalLink( $config->get( 'RightsUrl' ), $config->get( 'RightsText' ) );
                } elseif ( $config->get( 'RightsText' ) ) {
                $url2 = htmlspecialchars(
                        "$resourceBasePath/resources/assets/poweredby_mediawiki_176x62.png"
                );
 -              $text = '<a href="//www.mediawiki.org/"><img src="' . $url1
 +              $text = '<a href="https://www.mediawiki.org/"><img src="' . $url1
                        . '" srcset="' . $url1_5 . ' 1.5x, ' . $url2 . ' 2x" '
                        . 'height="31" width="88" alt="Powered by MediaWiki" /></a>';
                Hooks::run( 'SkinGetPoweredBy', [ &$text, $this ] );
         * @return string
         */
        function mainPageLink() {
 -              $s = Linker::linkKnown(
 +              $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
 +              $s = $linkRenderer->makeKnownLink(
                        Title::newMainPage(),
 -                      $this->msg( 'mainpage' )->escaped()
 +                      $this->msg( 'mainpage' )->text()
                );
  
                return $s;
         */
        public function footerLink( $desc, $page ) {
                $title = $this->footerLinkTitle( $desc, $page );
 +              $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
                if ( !$title ) {
                        return '';
                }
  
 -              return Linker::linkKnown(
 +              return $linkRenderer->makeKnownLink(
                        $title,
 -                      $this->msg( $desc )->escaped()
 +                      $this->msg( $desc )->text()
                );
        }
  
                $user = $this->getUser();
                $newtalks = $user->getNewMessageLinks();
                $out = $this->getOutput();
 +              $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
  
                // Allow extensions to disable or modify the new messages alert
                if ( !Hooks::run( 'GetNewMessagesAlert', [ &$newMessagesAlert, $newtalks, $user, $out ] ) ) {
                        // 999 signifies "more than one revision". We don't know how many, and even if we did,
                        // the number of revisions or authors is not necessarily the same as the number of
                        // "messages".
 -                      $newMessagesLink = Linker::linkKnown(
 +                      $newMessagesLink = $linkRenderer->makeKnownLink(
                                $uTalkTitle,
 -                              $this->msg( 'newmessageslinkplural' )->params( $plural )->escaped(),
 +                              $this->msg( 'newmessageslinkplural' )->params( $plural )->text(),
                                [],
                                $uTalkTitle->isRedirect() ? [ 'redirect' => 'no' ] : []
                        );
  
 -                      $newMessagesDiffLink = Linker::linkKnown(
 +                      $newMessagesDiffLink = $linkRenderer->makeKnownLink(
                                $uTalkTitle,
 -                              $this->msg( 'newmessagesdifflinkplural' )->params( $plural )->escaped(),
 +                              $this->msg( 'newmessagesdifflinkplural' )->params( $plural )->text(),
                                [],
                                $lastSeenRev !== null
                                        ? [ 'oldid' => $lastSeenRev->getId(), 'diff' => 'cur' ]
         *   should fall back to the next notice in its sequence
         */
        private function getCachedNotice( $name ) {
 -              $needParse = false;
                $config = $this->getConfig();
  
                if ( $name === 'default' ) {
  
                $links = [
                        'editsection' => [
 -                              'text' => $this->msg( 'editsection' )->inLanguage( $lang )->escaped(),
 +                              'text' => $this->msg( 'editsection' )->inLanguage( $lang )->text(),
                                'targetTitle' => $nt,
                                'attribs' => $attribs,
 -                              'query' => [ 'action' => 'edit', 'section' => $section ],
 -                              'options' => [ 'noclasses', 'known' ]
 +                              'query' => [ 'action' => 'edit', 'section' => $section ]
                        ]
                ];
  
  
                $result = '<span class="mw-editsection"><span class="mw-editsection-bracket">[</span>';
  
 +              $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
                $linksHtml = [];
                foreach ( $links as $k => $linkDetails ) {
 -                      $linksHtml[] = Linker::link(
 +                      $linksHtml[] = $linkRenderer->makeKnownLink(
                                $linkDetails['targetTitle'],
                                $linkDetails['text'],
                                $linkDetails['attribs'],
 -                              $linkDetails['query'],
 -                              $linkDetails['options']
 +                              $linkDetails['query']
                        );
                }
  
@@@ -1,10 -1,14 +1,16 @@@
  @import 'mediawiki.mixins';
  
 +/* stylelint-disable selector-class-pattern */
 +
  /* Table Sorting */
  
- .client-js .sortable:not( .jquery-tablesorter ) > thead > :last-of-type > th:not( .unsortable ),
+ // Reserve space for table sortable controls
+ // This selector is not perfect as it will not correctly handle cases with
+ // merged header cells, so ensure it is removed after the JS has run by using
+ // the :not( .jquery-tablesorter ) selector.
+ // It will still prevent a visible jump in the majority of simpler cases.
+ // The second selector in this rule is for after the JS has run.
+ .client-js .sortable:not( .jquery-tablesorter ) > * > tr:first-child > th:not( .unsortable ),
  .jquery-tablesorter th.headerSort {
        .background-image-svg( 'images/sort_both.svg', 'images/sort_both.png' );
        cursor: pointer;