Fixing dump tests for non-wikitext in NS_MAIN.
[lhc/web/wiklou.git] / includes / Linker.php
index 3a4f7c3..0f45165 100644 (file)
@@ -188,6 +188,8 @@ class Linker {
         *       cons.
         *     'forcearticlepath': Use the article path always, even with a querystring.
         *       Has compatibility issues on some setups, so avoid wherever possible.
+        *     'http': Force a full URL with http:// as the scheme.
+        *     'https': Force a full URL with https:// as the scheme.
         * @return string HTML <a> attribute
         */
        public static function link(
@@ -294,7 +296,16 @@ class Linker {
                        $query['action'] = 'edit';
                        $query['redlink'] = '1';
                }
-               $ret = $target->getLinkURL( $query );
+
+               if ( in_array( 'http', $options ) ) {
+                       $proto = PROTO_HTTP;
+               } elseif ( in_array( 'https', $options ) ) {
+                       $proto = PROTO_HTTPS;
+               } else {
+                       $proto = PROTO_RELATIVE;
+               }
+
+               $ret = $target->getLinkURL( $query, false, $proto );
                wfProfileOut( __METHOD__ );
                return $ret;
        }
@@ -345,7 +356,7 @@ class Linker {
                } elseif ( in_array( 'known', $options ) ) {
                        $defaults['title'] = $target->getPrefixedText();
                } else {
-                       $defaults['title'] = wfMsg( 'red-link-title', $target->getPrefixedText() );
+                       $defaults['title'] = wfMessage( 'red-link-title', $target->getPrefixedText() )->text();
                }
 
                # Finally, merge the custom attribs with the default ones, and iterate
@@ -437,6 +448,7 @@ class Linker {
         * @param $context IContextSource context to use to get the messages
         * @param $namespace int Namespace number
         * @param $title string Text of the title, without the namespace part
+        * @return string
         */
        public static function getInvalidTitleDescription( IContextSource $context, $namespace, $title ) {
                global $wgContLang;
@@ -536,6 +548,7 @@ class Linker {
         *          valign          Vertical alignment (baseline, sub, super, top, text-top, middle,
         *                          bottom, text-bottom)
         *          alt             Alternate text for image (i.e. alt attribute). Plain text.
+        *          class           HTML for image classes. Plain text.
         *          caption         HTML for image caption.
         *          link-url        URL to link to
         *          link-title      Title object to link to
@@ -580,6 +593,9 @@ class Linker {
                if ( !isset( $fp['title'] ) ) {
                        $fp['title'] = '';
                }
+               if ( !isset( $fp['class'] ) ) {
+                       $fp['class'] = '';
+               }
 
                $prefix = $postfix = '';
 
@@ -660,11 +676,15 @@ class Linker {
                if ( !$thumb ) {
                        $s = self::makeBrokenImageLinkObj( $title, $fp['title'], '', '', '', $time == true );
                } else {
+                       self::processResponsiveImages( $file, $thumb, $hp );
                        $params = array(
                                'alt' => $fp['alt'],
                                'title' => $fp['title'],
-                               'valign' => isset( $fp['valign'] ) ? $fp['valign'] : false ,
-                               'img-class' => isset( $fp['border'] ) ? 'thumbborder' : false );
+                               'valign' => isset( $fp['valign'] ) ? $fp['valign'] : false,
+                               'img-class' => $fp['class'] );
+                       if ( isset( $fp['border'] ) ) {
+                               $params['img-class'] .= ( $params['img-class'] !== '' ) ? ' thumbborder' : 'thumbborder';
+                       }
                        $params = self::getImageLinkMTOParams( $fp, $query, $parser ) + $params;
 
                        $s = $thumb->toHtml( $params );
@@ -777,6 +797,7 @@ class Linker {
                        $hp['width'] = isset( $fp['upright'] ) ? 130 : 180;
                }
                $thumb = false;
+               $noscale = false;
 
                if ( !$exists ) {
                        $outerWidth = $hp['width'] + 2;
@@ -795,6 +816,7 @@ class Linker {
                        } elseif ( isset( $fp['framed'] ) ) {
                                // Use image dimensions, don't scale
                                $thumb = $file->getUnscaledThumb( $hp );
+                               $noscale = true;
                        } else {
                                # Do not present an image bigger than the source, for bitmap-style images
                                # This is a hack to maintain compatibility with arbitrary pre-1.10 behaviour
@@ -825,13 +847,17 @@ class Linker {
                        $s .= self::makeBrokenImageLinkObj( $title, $fp['title'], '', '', '', $time == true );
                        $zoomIcon = '';
                } elseif ( !$thumb ) {
-                       $s .= htmlspecialchars( wfMsg( 'thumbnail_error', '' ) );
+                       $s .= wfMessage( 'thumbnail_error', '' )->escaped();
                        $zoomIcon = '';
                } else {
+                       if ( !$noscale ) {
+                               self::processResponsiveImages( $file, $thumb, $hp );
+                       }
                        $params = array(
                                'alt' => $fp['alt'],
                                'title' => $fp['title'],
-                               'img-class' => 'thumbimage' );
+                               'img-class' => ( isset( $fp['class'] ) && $fp['class'] !== '' ) ? $fp['class'] . ' thumbimage' : 'thumbimage'
+                       );
                        $params = self::getImageLinkMTOParams( $fp, $query ) + $params;
                        $s .= $thumb->toHtml( $params );
                        if ( isset( $fp['framed'] ) ) {
@@ -841,7 +867,7 @@ class Linker {
                                        Html::rawElement( 'a', array(
                                                'href' => $url,
                                                'class' => 'internal',
-                                               'title' => wfMsg( 'thumbnail-more' ) ),
+                                               'title' => wfMessage( 'thumbnail-more' )->text() ),
                                                Html::element( 'img', array(
                                                        'src' => $wgStylePath . '/common/images/magnify-clip' . ( $wgContLang->isRTL() ? '-rtl' : '' ) . '.png',
                                                        'width' => 15,
@@ -853,35 +879,66 @@ class Linker {
                return str_replace( "\n", ' ', $s );
        }
 
+       /**
+        * Process responsive images: add 1.5x and 2x subimages to the thumbnail, where
+        * applicable.
+        *
+        * @param File $file
+        * @param MediaOutput $thumb
+        * @param array $hp image parameters
+        */
+       protected static function processResponsiveImages( $file, $thumb, $hp ) {
+               global $wgResponsiveImages;
+               if ( $wgResponsiveImages ) {
+                       $hp15 = $hp;
+                       $hp15['width'] = round( $hp['width'] * 1.5 );
+                       $hp20 = $hp;
+                       $hp20['width'] = $hp['width'] * 2;
+                       if ( isset( $hp['height'] ) ) {
+                               $hp15['height'] = round( $hp['height'] * 1.5 );
+                               $hp20['height'] = $hp['height'] * 2;
+                       }
+
+                       $thumb15 = $file->transform( $hp15 );
+                       $thumb20 = $file->transform( $hp20 );
+                       if ( $thumb15->url !== $thumb->url ) {
+                               $thumb->responsiveUrls['1.5'] = $thumb15->url;
+                       }
+                       if ( $thumb20->url !== $thumb->url ) {
+                               $thumb->responsiveUrls['2'] = $thumb20->url;
+                       }
+               }
+       }
+
        /**
         * Make a "broken" link to an image
         *
         * @param $title Title object
-        * @param $html String: link label in htmlescaped text form
+        * @param $label String: link label (plain text)
         * @param $query String: query string
-        * @param $trail String: link trail (HTML fragment)
-        * @param $prefix String: link prefix (HTML fragment)
+        * @param $unused1 Unused parameter kept for b/c
+        * @param $unused2 Unused parameter kept for b/c
         * @param $time Boolean: a file of a certain timestamp was requested
         * @return String
         */
-       public static function makeBrokenImageLinkObj( $title, $html = '', $query = '', $trail = '', $prefix = '', $time = false ) {
+       public static function makeBrokenImageLinkObj( $title, $label = '', $query = '', $unused1 = '', $unused2 = '', $time = false ) {
                global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl;
                if ( ! $title instanceof Title ) {
-                       return "<!-- ERROR -->{$prefix}{$html}{$trail}";
+                       return "<!-- ERROR -->" . htmlspecialchars( $label );
                }
                wfProfileIn( __METHOD__ );
+               if ( $label == '' ) {
+                       $label = $title->getPrefixedText();
+               }
+               $encLabel = htmlspecialchars( $label );
                $currentExists = $time ? ( wfFindFile( $title ) != false ) : false;
 
-               list( $inside, $trail ) = self::splitTrail( $trail );
-               if ( $html == '' )
-                       $html = htmlspecialchars( $title->getPrefixedText() );
-
                if ( ( $wgUploadMissingFileUrl || $wgUploadNavigationUrl || $wgEnableUploads ) && !$currentExists ) {
                        $redir = RepoGroup::singleton()->getLocalRepo()->checkRedirect( $title );
 
                        if ( $redir ) {
                                wfProfileOut( __METHOD__ );
-                               return self::linkKnown( $title, "$prefix$html$inside", array(), wfCgiToArray( $query ) ) . $trail;
+                               return self::linkKnown( $title, $encLabel, array(), wfCgiToArray( $query ) );
                        }
 
                        $href = self::getUploadUrl( $title, $query );
@@ -889,10 +946,10 @@ class Linker {
                        wfProfileOut( __METHOD__ );
                        return '<a href="' . htmlspecialchars( $href ) . '" class="new" title="' .
                                htmlspecialchars( $title->getPrefixedText(), ENT_QUOTES ) . '">' .
-                               "$prefix$html$inside</a>$trail";
+                               $encLabel . '</a>';
                } else {
                        wfProfileOut( __METHOD__ );
-                       return self::linkKnown( $title, "$prefix$html$inside", array(), wfCgiToArray( $query ) ) . $trail;
+                       return self::linkKnown( $title, $encLabel, array(), wfCgiToArray( $query ) );
                }
        }
 
@@ -971,7 +1028,7 @@ class Linker {
                        $key = strtolower( $name );
                }
 
-               return self::linkKnown( SpecialPage::getTitleFor( $name ) , wfMsg( $key ) );
+               return self::linkKnown( SpecialPage::getTitleFor( $name ) , wfMessage( $key )->text() );
        }
 
        /**
@@ -1063,7 +1120,7 @@ class Linker {
                        }
                        $contribsPage = SpecialPage::getTitleFor( 'Contributions', $userText );
 
-                       $items[] = self::link( $contribsPage, wfMsgHtml( 'contribslink' ), $attribs );
+                       $items[] = self::link( $contribsPage, wfMessage( 'contribslink' )->escaped(), $attribs );
                }
                if ( $blockable && $wgUser->isAllowed( 'block' ) ) {
                        $items[] = self::blockLink( $userId, $userText );
@@ -1104,7 +1161,7 @@ class Linker {
         */
        public static function userTalkLink( $userId, $userText ) {
                $userTalkPage = Title::makeTitle( NS_USER_TALK, $userText );
-               $userTalkLink = self::link( $userTalkPage, wfMsgHtml( 'talkpagelinktext' ) );
+               $userTalkLink = self::link( $userTalkPage, wfMessage( 'talkpagelinktext' )->escaped() );
                return $userTalkLink;
        }
 
@@ -1115,7 +1172,7 @@ class Linker {
         */
        public static function blockLink( $userId, $userText ) {
                $blockPage = SpecialPage::getTitleFor( 'Block', $userText );
-               $blockLink = self::link( $blockPage, wfMsgHtml( 'blocklink' ) );
+               $blockLink = self::link( $blockPage, wfMessage( 'blocklink' )->escaped() );
                return $blockLink;
        }
 
@@ -1126,7 +1183,7 @@ class Linker {
         */
        public static function emailLink( $userId, $userText ) {
                $emailPage = SpecialPage::getTitleFor( 'Emailuser', $userText );
-               $emailLink = self::link( $emailPage, wfMsgHtml( 'emaillink' ) );
+               $emailLink = self::link( $emailPage, wfMessage( 'emaillink' )->escaped() );
                return $emailLink;
        }
 
@@ -1138,12 +1195,12 @@ class Linker {
         */
        public static function revUserLink( $rev, $isPublic = false ) {
                if ( $rev->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
-                       $link = wfMsgHtml( 'rev-deleted-user' );
+                       $link = wfMessage( 'rev-deleted-user' )->escaped();
                } elseif ( $rev->userCan( Revision::DELETED_USER ) ) {
                        $link = self::userLink( $rev->getUser( Revision::FOR_THIS_USER ),
                                $rev->getUserText( Revision::FOR_THIS_USER ) );
                } else {
-                       $link = wfMsgHtml( 'rev-deleted-user' );
+                       $link = wfMessage( 'rev-deleted-user' )->escaped();
                }
                if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
                        return '<span class="history-deleted">' . $link . '</span>';
@@ -1159,7 +1216,7 @@ class Linker {
         */
        public static function revUserTools( $rev, $isPublic = false ) {
                if ( $rev->isDeleted( Revision::DELETED_USER ) && $isPublic ) {
-                       $link = wfMsgHtml( 'rev-deleted-user' );
+                       $link = wfMessage( 'rev-deleted-user' )->escaped();
                } elseif ( $rev->userCan( Revision::DELETED_USER ) ) {
                        $userId = $rev->getUser( Revision::FOR_THIS_USER );
                        $userText = $rev->getUserText( Revision::FOR_THIS_USER );
@@ -1167,7 +1224,7 @@ class Linker {
                                . wfMessage( 'word-separator' )->plain()
                                . self::userToolLinks( $userId, $userText );
                } else {
-                       $link = wfMsgHtml( 'rev-deleted-user' );
+                       $link = wfMessage( 'rev-deleted-user' )->escaped();
                }
                if ( $rev->isDeleted( Revision::DELETED_USER ) ) {
                        return ' <span class="history-deleted">' . $link . '</span>';
@@ -1281,11 +1338,11 @@ class Linker {
                        }
                        if ( $pre ) {
                                # written summary $presep autocomment (summary /* section */)
-                               $pre .= wfMsgExt( 'autocomment-prefix', array( 'escapenoentities', 'content' ) );
+                               $pre .= wfMessage( 'autocomment-prefix' )->inContentLanguage()->escaped();
                        }
                        if ( $post ) {
                                # autocomment $postsep written summary (/* section */ summary)
-                               $auto .= wfMsgExt( 'colon-separator', array( 'escapenoentities', 'content' ) );
+                               $auto .= wfMessage( 'colon-separator' )->inContentLanguage()->escaped();
                        }
                        $auto = '<span class="autocomment">' . $auto . '</span>';
                        $comment = $pre . $link . $wgLang->getDirMark() . '<span dir="auto">' . $auto . $post . '</span>';
@@ -1507,12 +1564,12 @@ class Linker {
                        return "";
                }
                if ( $rev->isDeleted( Revision::DELETED_COMMENT ) && $isPublic ) {
-                       $block = " <span class=\"comment\">" . wfMsgHtml( 'rev-deleted-comment' ) . "</span>";
+                       $block = " <span class=\"comment\">" . wfMessage( 'rev-deleted-comment' )->escaped() . "</span>";
                } elseif ( $rev->userCan( Revision::DELETED_COMMENT ) ) {
                        $block = self::commentBlock( $rev->getComment( Revision::FOR_THIS_USER ),
                                $rev->getTitle(), $local );
                } else {
-                       $block = " <span class=\"comment\">" . wfMsgHtml( 'rev-deleted-comment' ) . "</span>";
+                       $block = " <span class=\"comment\">" . wfMessage( 'rev-deleted-comment' )->escaped() . "</span>";
                }
                if ( $rev->isDeleted( Revision::DELETED_COMMENT ) ) {
                        return " <span class=\"history-deleted\">$block</span>";
@@ -1526,13 +1583,11 @@ class Linker {
         */
        public static function formatRevisionSize( $size ) {
                if ( $size == 0 ) {
-                       $stxt = wfMsgExt( 'historyempty', 'parsemag' );
+                       $stxt = wfMessage( 'historyempty' )->escaped();
                } else {
-                       global $wgLang;
-                       $stxt = wfMsgExt( 'nbytes', 'parsemag', $wgLang->formatNum( $size ) );
+                       $stxt = wfMessage( 'nbytes' )->numParams( $size )->escaped();
                        $stxt = wfMessage( 'parentheses' )->rawParams( $stxt )->escaped();
                }
-               $stxt = htmlspecialchars( $stxt );
                return "<span class=\"history-size\">$stxt</span>";
        }
 
@@ -1584,11 +1639,13 @@ class Linker {
         * Wraps the TOC in a table and provides the hide/collapse javascript.
         *
         * @param $toc String: html of the Table Of Contents
-        * @param $lang mixed: Language code for the toc title
+        * @param $lang String|Language|false: Language for the toc title, defaults to user language
         * @return String: full html of the TOC
         */
        public static function tocList( $toc, $lang = false ) {
-               $title = wfMsgExt( 'toc', array( 'language' => $lang, 'escape' ) );
+               $lang = wfGetLangObj( $lang );
+               $title = wfMessage( 'toc' )->inLanguage( $lang )->escaped();
+
                return
                   '<table id="toc" class="toc"><tr><td>'
                 . '<div id="toctitle"><h2>' . $title . "</h2></div>\n"
@@ -1803,11 +1860,14 @@ class Linker {
                        # Construct the HTML
                        $outText = '<div class="mw-templatesUsedExplanation">';
                        if ( $preview ) {
-                               $outText .= wfMsgExt( 'templatesusedpreview', array( 'parse' ), count( $templates ) );
+                               $outText .= wfMessage( 'templatesusedpreview' )->numParams( count( $templates ) )
+                                       ->parseAsBlock();
                        } elseif ( $section ) {
-                               $outText .= wfMsgExt( 'templatesusedsection', array( 'parse' ), count( $templates ) );
+                               $outText .= wfMessage( 'templatesusedsection' )->numParams( count( $templates ) )
+                                       ->parseAsBlock();
                        } else {
-                               $outText .= wfMsgExt( 'templatesused', array( 'parse' ), count( $templates ) );
+                               $outText .= wfMessage( 'templatesused' )->numParams( count( $templates ) )
+                                       ->parseAsBlock();
                        }
                        $outText .= "</div><ul>\n";
 
@@ -1815,23 +1875,23 @@ class Linker {
                        foreach ( $templates as $titleObj ) {
                                $r = $titleObj->getRestrictions( 'edit' );
                                if ( in_array( 'sysop', $r ) ) {
-                                       $protected = wfMsgExt( 'template-protected', array( 'parseinline' ) );
+                                       $protected = wfMessage( 'template-protected' )->parse();
                                } elseif ( in_array( 'autoconfirmed', $r ) ) {
-                                       $protected = wfMsgExt( 'template-semiprotected', array( 'parseinline' ) );
+                                       $protected = wfMessage( 'template-semiprotected' )->parse();
                                } else {
                                        $protected = '';
                                }
                                if ( $titleObj->quickUserCan( 'edit' ) ) {
                                        $editLink = self::link(
                                                $titleObj,
-                                               wfMsg( 'editlink' ),
+                                               wfMessage( 'editlink' )->text(),
                                                array(),
                                                array( 'action' => 'edit' )
                                        );
                                } else {
                                        $editLink = self::link(
                                                $titleObj,
-                                               wfMsg( 'viewsourcelink' ),
+                                               wfMessage( 'viewsourcelink' )->text(),
                                                array(),
                                                array( 'action' => 'edit' )
                                        );
@@ -1852,14 +1912,13 @@ class Linker {
         * @return String: HTML output
         */
        public static function formatHiddenCategories( $hiddencats ) {
-               global $wgLang;
                wfProfileIn( __METHOD__ );
 
                $outText = '';
                if ( count( $hiddencats ) > 0 ) {
                        # Construct the HTML
                        $outText = '<div class="mw-hiddenCategoriesExplanation">';
-                       $outText .= wfMsgExt( 'hiddencategories', array( 'parse' ), $wgLang->formatnum( count( $hiddencats ) ) );
+                       $outText .= wfMessage( 'hiddencategories' )->numParams( count( $hiddencats ) )->parseAsBlock();
                        $outText .= "</div><ul>\n";
 
                        foreach ( $hiddencats as $titleObj ) {
@@ -2019,7 +2078,8 @@ class Linker {
         */
        public static function revDeleteLink( $query = array(), $restricted = false, $delete = true ) {
                $sp = SpecialPage::getTitleFor( 'Revisiondelete' );
-               $html = $delete ? wfMsgHtml( 'rev-delundel' ) : wfMsgHtml( 'rev-showdeleted' );
+               $msgKey = $delete ? 'rev-delundel' : 'rev-showdeleted';
+               $html = wfMessage( $msgKey )->escaped();
                $tag = $restricted ? 'strong' : 'span';
                $link = self::link( $sp, $html, array(), $query, array( 'known', 'noclasses' ) );
                return Xml::tags( $tag, array( 'class' => 'mw-revdelundel-link' ), wfMessage( 'parentheses' )->rawParams( $link )->escaped() );
@@ -2034,8 +2094,10 @@ class Linker {
         * of appearance with CSS
         */
        public static function revDeleteLinkDisabled( $delete = true ) {
-               $html = $delete ? wfMsgHtml( 'rev-delundel' ) : wfMsgHtml( 'rev-showdeleted' );
-               return Xml::tags( 'span', array( 'class' => 'mw-revdelundel-link' ), wfMessage( 'parentheses' )->rawParams( $html )->escaped() );
+               $msgKey = $delete ? 'rev-delundel' : 'rev-showdeleted';
+               $html = wfMessage( $msgKey )->escaped();
+               $htmlParentheses = wfMessage( 'parentheses' )->rawParams( $html )->escaped();
+               return Xml::tags( 'span', array( 'class' => 'mw-revdelundel-link' ), $htmlParentheses );
        }
 
        /* Deprecated methods */