X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FOutputPage.php;h=af2f2649bea90873706c0ce910066b894c616fbf;hb=a40a045f5f04a6287e90d46555956698abaa0025;hp=a957e549547c0117dbbd85f47352cc55e3c83b65;hpb=9a51d5c61cd4ee9b8a7ee15a779dc3a711b37ebf;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/OutputPage.php b/includes/OutputPage.php index a957e54954..af2f2649be 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -13,7 +13,7 @@ if ( !defined( 'MEDIAWIKI' ) ) { * * @todo FIXME: Another class handles sending the whole page to the client. * - * Some comments comes from a pairing session between Zak Greant and Ashar Voultoiz + * Some comments comes from a pairing session between Zak Greant and Antoine Musso * in November 2010. * * @todo document @@ -124,6 +124,7 @@ class OutputPage extends ContextSource { // @todo FIXME: Next variables probably comes from the resource loader var $mModules = array(), $mModuleScripts = array(), $mModuleStyles = array(), $mModuleMessages = array(); var $mResourceLoader; + var $mJsConfigVars = array(); /** @todo FIXME: Is this still used ?*/ var $mInlineMsg = array(); @@ -151,7 +152,10 @@ class OutputPage extends ContextSource { // Parser related. var $mContainsOldMagic = 0, $mContainsNewMagic = 0; - /// lazy initialised, use parserOptions() + /** + * lazy initialised, use parserOptions() + * @var ParserOptions + */ protected $mParserOptions = null; /** @@ -223,7 +227,7 @@ class OutputPage extends ContextSource { * Instead a new RequestContext should be created and it will implicitly create * a OutputPage tied to that context. */ - function __construct( RequestContext $context = null ) { + function __construct( IContextSource $context = null ) { if ( $context === null ) { # Extensions should use `new RequestContext` instead of `new OutputPage` now. wfDeprecated( __METHOD__ ); @@ -756,7 +760,11 @@ class OutputPage extends ContextSource { * @param $name string */ public function setHTMLTitle( $name ) { - $this->mHTMLtitle = $name; + if ( $name instanceof Message ) { + $this->mHTMLtitle = $name->setContext( $this->getContext() )->text(); + } else { + $this->mHTMLtitle = $name; + } } /** @@ -774,16 +782,20 @@ class OutputPage extends ContextSource { * This function automatically sets \ to the same content as \ but with all tags removed. * Bad tags that were escaped in \ will still be escaped in \, and good tags like \ will be dropped entirely. * - * @param $name string + * @param $name string|Message */ public function setPageTitle( $name ) { + if ( $name instanceof Message ) { + $name = $name->setContext( $this->getContext() )->text(); + } + # change "" to "<script>foo&bar</script>" # but leave "foobar" alone $nameWithTags = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags( $name ) ); $this->mPagetitle = $nameWithTags; # change "foo&bar" to "foo&bar" - $this->setHTMLTitle( wfMsg( 'pagetitle', Sanitizer::stripAllTags( $nameWithTags ) ) ); + $this->setHTMLTitle( $this->msg( 'pagetitle', Sanitizer::stripAllTags( $nameWithTags ) ) ); } /** @@ -1201,6 +1213,19 @@ class OutputPage extends ContextSource { $this->mBodytext .= $text; } + /** + * Shortcut for adding an Html::element via addHTML. + * + * @since 1.19 + * + * @param $element string + * @param $attribs array + * @param $contents string + */ + public function addElement( $element, $attribs = array(), $contents = '' ) { + $this->addHTML( Html::element( $element, $attribs, $contents ) ); + } + /** * Clear the body HTML */ @@ -1235,7 +1260,7 @@ class OutputPage extends ContextSource { */ public function parserOptions( $options = null ) { if ( !$this->mParserOptions ) { - $this->mParserOptions = new ParserOptions; + $this->mParserOptions = ParserOptions::newFromContext( $this->getContext() ); $this->mParserOptions->setEditSection( false ); } return wfSetVar( $this->mParserOptions, $options ); @@ -1301,7 +1326,7 @@ class OutputPage extends ContextSource { * @return Array (dbKey => array('time' => MW timestamp or null, 'sha1' => sha1 or '')) * @since 1.18 */ - public function getImageTimeKeys() { + public function getFileSearchOptions() { return $this->mImageTimeKeys; } @@ -1311,10 +1336,11 @@ class OutputPage extends ContextSource { * * @param $text String * @param $linestart Boolean: is this the start of a line? + * @param $interface Boolean: is this text in the user interface language? */ - public function addWikiText( $text, $linestart = true ) { + public function addWikiText( $text, $linestart = true, $interface = true ) { $title = $this->getTitle(); // Work arround E_STRICT - $this->addWikiTextTitle( $text, $title, $linestart ); + $this->addWikiTextTitle( $text, $title, $linestart, /*tidy*/false, $interface ); } /** @@ -1329,7 +1355,7 @@ class OutputPage extends ContextSource { } /** - * Add wikitext with a custom Title object and + * Add wikitext with a custom Title object and tidy enabled. * * @param $text String: wikitext * @param $title Title object @@ -1357,8 +1383,10 @@ class OutputPage extends ContextSource { * @param $title Title object * @param $linestart Boolean: is this the start of a line? * @param $tidy Boolean: whether to use tidy + * @param $interface Boolean: whether it is an interface message + * (for example disables conversion) */ - public function addWikiTextTitle( $text, &$title, $linestart, $tidy = false ) { + public function addWikiTextTitle( $text, &$title, $linestart, $tidy = false, $interface = false ) { global $wgParser; wfProfileIn( __METHOD__ ); @@ -1367,6 +1395,7 @@ class OutputPage extends ContextSource { $popts = $this->parserOptions(); $oldTidy = $popts->setTidy( $tidy ); + $popts->setInterfaceMessage( (bool) $interface ); $parserOutput = $wgParser->parse( $text, $title, $popts, @@ -1411,7 +1440,7 @@ class OutputPage extends ContextSource { } } // File versioning... - foreach ( (array)$parserOutput->getImageTimeKeys() as $dbk => $data ) { + foreach ( (array)$parserOutput->getFileSearchOptions() as $dbk => $data ) { $this->mImageTimeKeys[$dbk] = $data; } @@ -1459,7 +1488,8 @@ class OutputPage extends ContextSource { * @param $linestart Boolean: is this the start of a line? * @param $interface Boolean: use interface language ($wgLang instead of * $wgContLang) while parsing language sensitive magic - * words like GRAMMAR and PLURAL + * words like GRAMMAR and PLURAL. This also disables + * LanguageConverter. * @param $language Language object: target language object, will override * $interface * @return String: HTML @@ -1610,7 +1640,7 @@ class OutputPage extends ContextSource { $this->mVaryHeader[$header] = $option; } } - $this->mVaryHeader[$header] = array_unique( $this->mVaryHeader[$header] ); + $this->mVaryHeader[$header] = array_unique( (array)$this->mVaryHeader[$header] ); } /** @@ -1649,12 +1679,12 @@ class OutputPage extends ContextSource { * /w/index.php?title=Main_page&variant=zh-cn should never be served. */ function addAcceptLanguage() { - global $wgContLang; - if( !$this->getRequest()->getCheck( 'variant' ) && $wgContLang->hasVariants() ) { - $variants = $wgContLang->getVariants(); + $lang = $this->getTitle()->getPageLanguage(); + if( !$this->getRequest()->getCheck( 'variant' ) && $lang->hasVariants() ) { + $variants = $lang->getVariants(); $aloption = array(); foreach ( $variants as $variant ) { - if( $variant === $wgContLang->getCode() ) { + if( $variant === $lang->getCode() ) { continue; } else { $aloption[] = 'string-contains=' . $variant; @@ -1711,6 +1741,7 @@ class OutputPage extends ContextSource { } elseif ( $this->mPreventClickjacking && $wgEditPageFrameOptions ) { return $wgEditPageFrameOptions; } + return false; } /** @@ -1800,7 +1831,7 @@ class OutputPage extends ContextSource { * the object, let's actually output it: */ public function output() { - global $wgLanguageCode, $wgDebugRedirects, $wgMimeType; + global $wgLanguageCode, $wgDebugRedirects, $wgMimeType, $wgVaryOnXFP; if( $this->mDoNothing ) { return; @@ -1820,6 +1851,9 @@ class OutputPage extends ContextSource { } $this->mLastModified = wfTimestamp( TS_RFC2822 ); } + if ( $wgVaryOnXFP ) { + $this->addVaryHeader( 'X-Forwarded-Proto' ); + } $this->sendCacheControl(); $response->header( "Content-Type: text/html; charset=utf-8" ); @@ -1890,6 +1924,32 @@ class OutputPage extends ContextSource { throw new UserBlockedError( $this->getUser()->mBlock ); } + /** + * Prepare this object to display an error page; disable caching and + * indexing, clear the current text and redirect, set the page's title + * and optionally an custom HTML title (content of the tag). + * + * @param $pageTitle String|Message will be passed directly to setPageTitle() + * @param $htmlTitle String|Message will be passed directly to setHTMLTitle(); + * optional, if not passed the <title> attribute will be + * based on $pageTitle + */ + public function prepareErrorPage( $pageTitle, $htmlTitle = false ) { + if ( $this->getTitle() ) { + $this->mDebugtext .= 'Original title: ' . $this->getTitle()->getPrefixedText() . "\n"; + } + + $this->setPageTitle( $pageTitle ); + if ( $htmlTitle !== false ) { + $this->setHTMLTitle( $htmlTitle ); + } + $this->setRobotPolicy( 'noindex,nofollow' ); + $this->setArticleRelated( false ); + $this->enableClientCache( false ); + $this->mRedirect = ''; + $this->clearHTML(); + } + /** * Output a standard error page * @@ -1901,16 +1961,7 @@ class OutputPage extends ContextSource { * @param $params Array: message parameters; ignored if $msg is a Message object */ public function showErrorPage( $title, $msg, $params = array() ) { - if ( $this->getTitle() ) { - $this->mDebugtext .= 'Original title: ' . $this->getTitle()->getPrefixedText() . "\n"; - } - $this->setPageTitle( wfMsg( $title ) ); - $this->setHTMLTitle( wfMsg( 'errorpagetitle' ) ); - $this->setRobotPolicy( 'noindex,nofollow' ); - $this->setArticleRelated( false ); - $this->enableClientCache( false ); - $this->mRedirect = ''; - $this->mBodytext = ''; + $this->prepareErrorPage( $this->msg( $title ), $this->msg( 'errorpagetitle' ) ); if ( $msg instanceof Message ){ $this->addHTML( $msg->parse() ); @@ -1928,15 +1979,8 @@ class OutputPage extends ContextSource { * @param $action String: action that was denied or null if unknown */ public function showPermissionsErrorPage( $errors, $action = null ) { - $this->mDebugtext .= 'Original title: ' . - $this->getTitle()->getPrefixedText() . "\n"; - $this->setPageTitle( wfMsg( 'permissionserrors' ) ); - $this->setHTMLTitle( wfMsg( 'permissionserrors' ) ); - $this->setRobotPolicy( 'noindex,nofollow' ); - $this->setArticleRelated( false ); - $this->enableClientCache( false ); - $this->mRedirect = ''; - $this->mBodytext = ''; + $this->prepareErrorPage( $this->msg( 'permissionserrors' ) ); + $this->addWikiText( $this->formatPermissionsErrorMessage( $errors, $action ) ); } @@ -1947,11 +1991,7 @@ class OutputPage extends ContextSource { * @param $version Mixed: the version of MediaWiki needed to use the page */ public function versionRequired( $version ) { - $this->setPageTitle( wfMsg( 'versionrequired', $version ) ); - $this->setHTMLTitle( wfMsg( 'versionrequired', $version ) ); - $this->setRobotPolicy( 'noindex,nofollow' ); - $this->setArticleRelated( false ); - $this->mBodytext = ''; + $this->prepareErrorPage( $this->msg( 'versionrequired', $version ) ); $this->addWikiMsg( 'versionrequiredtext', $version ); $this->returnToMain(); @@ -1974,19 +2014,15 @@ class OutputPage extends ContextSource { throw new PermissionsError( 'read' ); } - $this->setPageTitle( wfMsg( 'loginreqtitle' ) ); - $this->setHtmlTitle( wfMsg( 'errorpagetitle' ) ); - $this->setRobotPolicy( 'noindex,nofollow' ); - $this->setArticleRelated( false ); + $this->prepareErrorPage( $this->msg( 'loginreqtitle' ), $this->msg( 'errorpagetitle' ) ); - $loginTitle = SpecialPage::getTitleFor( 'Userlogin' ); $loginLink = Linker::linkKnown( - $loginTitle, - wfMsgHtml( 'loginreqlink' ), + SpecialPage::getTitleFor( 'Userlogin' ), + $this->msg( 'loginreqlink' )->escaped(), array(), array( 'returnto' => $this->getTitle()->getPrefixedText() ) ); - $this->addHTML( wfMessage( 'loginreqpagetext' )->rawParams( $loginLink )->parse() . + $this->addHTML( $this->msg( 'loginreqpagetext' )->rawParams( $loginLink )->parse() . "\n<!--" . $this->getTitle()->getPrefixedUrl() . '-->' ); # Don't return to the main page if the user can't read it @@ -2006,14 +2042,14 @@ class OutputPage extends ContextSource { */ public function formatPermissionsErrorMessage( $errors, $action = null ) { if ( $action == null ) { - $text = wfMsgNoTrans( 'permissionserrorstext', count( $errors ) ) . "\n\n"; + $text = $this->msg( 'permissionserrorstext', count( $errors ) )->plain() . "\n\n"; } else { - $action_desc = wfMsgNoTrans( "action-$action" ); - $text = wfMsgNoTrans( + $action_desc = $this->msg( "action-$action" )->plain(); + $text = $this->msg( 'permissionserrorstext-withaction', count( $errors ), $action_desc - ) . "\n\n"; + )->plain() . "\n\n"; } if ( count( $errors ) > 1 ) { @@ -2021,13 +2057,13 @@ class OutputPage extends ContextSource { foreach( $errors as $error ) { $text .= '<li>'; - $text .= call_user_func_array( 'wfMsgNoTrans', $error ); + $text .= call_user_func_array( array( $this, 'msg' ), $error )->plain(); $text .= "</li>\n"; } $text .= '</ul>'; } else { $text .= "<div class=\"permissions-errors\">\n" . - call_user_func_array( 'wfMsgNoTrans', reset( $errors ) ) . + call_user_func_array( array( $this, 'msg' ), reset( $errors ) )->plain() . "\n</div>"; } @@ -2055,8 +2091,6 @@ class OutputPage extends ContextSource { * @param $action String: action that was denied or null if unknown */ public function readOnlyPage( $source = null, $protected = false, $reasons = array(), $action = null ) { - global $wgEnableInterwikiTranscluding, $wgEnableInterwikiTemplatesTracking; - $this->setRobotPolicy( 'noindex,nofollow' ); $this->setArticleRelated( false ); @@ -2069,12 +2103,12 @@ class OutputPage extends ContextSource { if ( !empty( $reasons ) ) { // Permissions error if( $source ) { - $this->setPageTitle( wfMsg( 'viewsource' ) ); + $this->setPageTitle( $this->msg( 'viewsource' ) ); $this->setSubtitle( - wfMsg( 'viewsourcefor', Linker::linkKnown( $this->getTitle() ) ) + $this->msg( 'viewsourcefor', Linker::linkKnown( $this->getTitle() ) )->text() ); } else { - $this->setPageTitle( wfMsg( 'badaccess' ) ); + $this->setPageTitle( $this->msg( 'badaccess' ) ); } $this->addWikiText( $this->formatPermissionsErrorMessage( $reasons, $action ) ); } else { @@ -2105,13 +2139,6 @@ class OutputPage extends ContextSource { $templates </div> " ); - if ( $wgEnableInterwikiTranscluding && $wgEnableInterwikiTemplatesTracking ) { - $distantTemplates = Linker::formatDistantTemplates( $article->getUsedDistantTemplates() ); - $this->addHTML( "<div class='distantTemplatesUsed'> -$distantTemplates -</div> -" ); - } } # If the title doesn't exist, it's fairly pointless to print a return @@ -2146,37 +2173,34 @@ $distantTemplates ? 'lag-warn-normal' : 'lag-warn-high'; $wrap = Html::rawElement( 'div', array( 'class' => "mw-{$message}" ), "\n$1\n" ); - $this->wrapWikiMsg( "$wrap\n", array( $message, $this->getContext()->getLang()->formatNum( $lag ) ) ); + $this->wrapWikiMsg( "$wrap\n", array( $message, $this->getLang()->formatNum( $lag ) ) ); } } public function showFatalError( $message ) { - $this->setPageTitle( wfMsg( 'internalerror' ) ); - $this->setRobotPolicy( 'noindex,nofollow' ); - $this->setArticleRelated( false ); - $this->enableClientCache( false ); - $this->mRedirect = ''; - $this->mBodytext = $message; + $this->prepareErrorPage( $this->msg( 'internalerror' ) ); + + $this->addHTML( $message ); } public function showUnexpectedValueError( $name, $val ) { - $this->showFatalError( wfMsg( 'unexpected', $name, $val ) ); + $this->showFatalError( $this->msg( 'unexpected', $name, $val )->text() ); } public function showFileCopyError( $old, $new ) { - $this->showFatalError( wfMsg( 'filecopyerror', $old, $new ) ); + $this->showFatalError( $this->msg( 'filecopyerror', $old, $new )->text() ); } public function showFileRenameError( $old, $new ) { - $this->showFatalError( wfMsg( 'filerenameerror', $old, $new ) ); + $this->showFatalError( $this->msg( 'filerenameerror', $old, $new )->text() ); } public function showFileDeleteError( $name ) { - $this->showFatalError( wfMsg( 'filedeleteerror', $name ) ); + $this->showFatalError( $this->msg( 'filedeleteerror', $name )->text() ); } public function showFileNotFoundError( $name ) { - $this->showFatalError( wfMsg( 'filenotfound', $name ) ); + $this->showFatalError( $this->msg( 'filenotfound', $name )->text() ); } /** @@ -2188,10 +2212,8 @@ $distantTemplates */ public function addReturnTo( $title, $query = array(), $text = null ) { $this->addLink( array( 'rel' => 'next', 'href' => $title->getFullURL() ) ); - $link = wfMsgHtml( - 'returnto', - Linker::link( $title, $text, array(), $query ) - ); + $link = $this->msg( 'returnto' )->rawParams( + Linker::link( $title, $text, array(), $query ) )->escaped(); $this->addHTML( "<p id=\"mw-returnto\">{$link}</p>\n" ); } @@ -2245,7 +2267,7 @@ $distantTemplates $ret = Html::htmlHeader( array( 'lang' => $this->getLang()->getCode(), 'dir' => $userdir, 'class' => 'client-nojs' ) ); if ( $this->getHTMLTitle() == '' ) { - $this->setHTMLTitle( wfMsg( 'pagetitle', $this->getPageTitle() ) ); + $this->setHTMLTitle( $this->msg( 'pagetitle', $this->getPageTitle() ) ); } $openHead = Html::openElement( 'head' ); @@ -2277,7 +2299,7 @@ $distantTemplates # Classes for LTR/RTL directionality support $bodyAttrs['class'] = "mediawiki $userdir sitedir-$sitedir"; - if ( $this->getContext()->getLang()->capitalizeAllNouns() ) { + if ( $this->getLang()->capitalizeAllNouns() ) { # A <body> class is probably not the best way to do this . . . $bodyAttrs['class'] .= ' capitalize-all-nouns'; } @@ -2296,8 +2318,7 @@ $distantTemplates * Add the default ResourceLoader modules to this object */ private function addDefaultModules() { - global $wgIncludeLegacyJavaScript, $wgUseAjax, - $wgAjaxWatch, $wgEnableMWSuggest, $wgUseAJAXCategories; + global $wgIncludeLegacyJavaScript, $wgUseAjax, $wgAjaxWatch, $wgEnableMWSuggest; // Add base resources $this->addModules( array( @@ -2333,16 +2354,6 @@ $distantTemplates if ( $this->isArticle() && $this->getUser()->getOption( 'editondblclick' ) ) { $this->addModules( 'mediawiki.action.view.dblClickEdit' ); } - - if ( $wgUseAJAXCategories ) { - global $wgAJAXCategoriesNamespaces; - - $title = $this->getTitle(); - - if( empty( $wgAJAXCategoriesNamespaces ) || in_array( $title->getNamespace(), $wgAJAXCategoriesNamespaces ) ) { - $this->addModules( 'mediawiki.page.ajaxCategories.init' ); - } - } } /** @@ -2366,23 +2377,7 @@ $distantTemplates * @return string html <script> and <style> tags */ protected function makeResourceLoaderLink( $modules, $only, $useESI = false, array $extraQuery = array() ) { - global $wgLoadScript, $wgResourceLoaderUseESI, - $wgResourceLoaderInlinePrivateModules; - $baseQuery = array( - 'lang' => $this->getContext()->getLang()->getCode(), - 'debug' => ResourceLoader::inDebugMode() ? 'true' : 'false', - 'skin' => $this->getSkin()->getSkinName(), - ) + $extraQuery; - if ( $only !== ResourceLoaderModule::TYPE_COMBINED ) { - $baseQuery['only'] = $only; - } - // Propagate printable and handheld parameters if present - if ( $this->isPrintable() ) { - $baseQuery['printable'] = 1; - } - if ( $this->getRequest()->getBool( 'handheld' ) ) { - $baseQuery['handheld'] = 1; - } + global $wgResourceLoaderUseESI, $wgResourceLoaderInlinePrivateModules; if ( !count( $modules ) ) { return ''; @@ -2428,14 +2423,26 @@ $distantTemplates $links = ''; foreach ( $groups as $group => $modules ) { - $query = $baseQuery; // Special handling for user-specific groups + $user = null; if ( ( $group === 'user' || $group === 'private' ) && $this->getUser()->isLoggedIn() ) { - $query['user'] = $this->getUser()->getName(); + $user = $this->getUser()->getName(); } // Create a fake request based on the one we are about to make so modules return // correct timestamp and emptiness data + $query = ResourceLoader::makeLoaderQuery( + array(), // modules; not determined yet + $this->getLang()->getCode(), + $this->getSkin()->getSkinName(), + $user, + null, // version; not determined yet + ResourceLoader::inDebugMode(), + $only === ResourceLoaderModule::TYPE_COMBINED ? null : $only, + $this->isPrintable(), + $this->getRequest()->getBool( 'handheld' ), + $extraQuery + ); $context = new ResourceLoaderContext( $resourceLoader, new FauxRequest( $query ) ); // Drop modules that know they're empty foreach ( $modules as $key => $module ) { @@ -2448,8 +2455,6 @@ $distantTemplates continue; } - $query['modules'] = ResourceLoader::makePackedModulesString( array_keys( $modules ) ); - // Support inlining of private modules if configured as such if ( $group === 'private' && $wgResourceLoaderInlinePrivateModules ) { if ( $only == ResourceLoaderModule::TYPE_STYLES ) { @@ -2471,6 +2476,7 @@ $distantTemplates // timestamp of these user-changable modules so we can ensure cache misses on change // This should NOT be done for the site group (bug 27564) because anons get that too // and we shouldn't be putting timestamps in Squid-cached HTML + $version = null; if ( $group === 'user' ) { // Get the maximum timestamp $timestamp = 1; @@ -2478,15 +2484,21 @@ $distantTemplates $timestamp = max( $timestamp, $module->getModifiedTime( $context ) ); } // Add a version parameter so cache will break when things change - $query['version'] = wfTimestamp( TS_ISO_8601_BASIC, $timestamp ); + $version = wfTimestamp( TS_ISO_8601_BASIC, $timestamp ); } - // Make queries uniform in order - ksort( $query ); - $url = wfAppendQuery( $wgLoadScript, $query ); - // Prevent the IE6 extension check from being triggered (bug 28840) - // by appending a character that's invalid in Windows extensions ('*') - $url .= '&*'; + $url = ResourceLoader::makeLoaderURL( + array_keys( $modules ), + $this->getLang()->getCode(), + $this->getSkin()->getSkinName(), + $user, + $version, + ResourceLoader::inDebugMode(), + $only === ResourceLoaderModule::TYPE_COMBINED ? null : $only, + $this->isPrintable(), + $this->getRequest()->getBool( 'handheld' ), + $extraQuery + ); if ( $useESI && $wgResourceLoaderUseESI ) { $esi = Xml::element( 'esi:include', array( 'src' => $url ) ); if ( $only == ResourceLoaderModule::TYPE_STYLES ) { @@ -2610,15 +2622,33 @@ $distantTemplates } /** - * Get an array containing global JS variables + * Add one or more variables to be set in mw.config in JavaScript. + * + * @param $key {String|Array} Key or array of key/value pars. + * @param $value {Mixed} Value of the configuration variable. + */ + public function addJsConfigVars( $keys, $value ) { + if ( is_array( $keys ) ) { + foreach ( $keys as $key => $value ) { + $this->mJsConfigVars[$key] = $value; + } + return; + } + + $this->mJsConfigVars[$keys] = $value; + } + + + /** + * Get an array containing the variables to be set in mw.config in JavaScript. * - * Do not add things here which can be evaluated in - * ResourceLoaderStartupScript - in other words, without state. - * You will only be adding bloat to the page and causing page caches to + * Do not add things here which can be evaluated in ResourceLoaderStartupScript + * - in other words, page-independent/site-wide variables (without state). + * You will only be adding bloat to the html page and causing page caches to * have to be purged on configuration changes. */ protected function getJSVars() { - global $wgUseAjax, $wgEnableMWSuggest, $wgContLang; + global $wgUseAjax, $wgEnableMWSuggest; $title = $this->getTitle(); $ns = $title->getNamespace(); @@ -2644,9 +2674,10 @@ $distantTemplates 'wgCategories' => $this->getCategories(), 'wgBreakFrames' => $this->getFrameOptions() == 'DENY', ); - if ( $wgContLang->hasVariants() ) { - $vars['wgUserVariant'] = $wgContLang->getPreferredVariant(); - } + $lang = $this->getTitle()->getPageLanguage(); + if ( $lang->hasVariants() ) { + $vars['wgUserVariant'] = $lang->getPreferredVariant(); + } foreach ( $title->getRestrictionTypes() as $type ) { $vars['wgRestriction' . ucfirst( $type )] = $title->getRestrictions( $type ); } @@ -2657,10 +2688,14 @@ $distantTemplates $vars['wgIsMainPage'] = true; } - // Allow extensions to add their custom variables to the global JS variables - wfRunHooks( 'MakeGlobalVariablesScript', array( &$vars ) ); + // Allow extensions to add their custom variables to the mw.config map. + // Use the 'ResourceLoaderGetConfigVars' hook if the variable is not + // page-dependant but site-wide (without state). + // Alternatively, you may want to use OutputPage->addJsConfigVars() instead. + wfRunHooks( 'MakeGlobalVariablesScript', array( &$vars, &$this ) ); - return $vars; + // Merge in variables from addJsConfigVars last + return array_merge( $vars, $this->mJsConfigVars ); } /** @@ -2697,7 +2732,7 @@ $distantTemplates global $wgUniversalEditButton, $wgFavicon, $wgAppleTouchIcon, $wgEnableAPI, $wgSitename, $wgVersion, $wgHtml5, $wgMimeType, $wgFeed, $wgOverrideSiteFeed, $wgAdvertisedFeedTypes, - $wgDisableLangConversion, $wgCanonicalLanguageLinks, $wgContLang, + $wgDisableLangConversion, $wgCanonicalLanguageLinks, $wgRightsPage, $wgRightsUrl; $tags = array(); @@ -2773,7 +2808,7 @@ $distantTemplates if ( $this->isArticleRelated() && $this->getTitle() && $this->getTitle()->quickUserCan( 'edit' ) && ( $this->getTitle()->exists() || $this->getTitle()->quickUserCan( 'create' ) ) ) { // Original UniversalEditButton - $msg = wfMsg( 'edit' ); + $msg = $this->msg( 'edit' )->text(); $tags[] = Html::element( 'link', array( 'rel' => 'alternate', 'type' => 'application/x-wiki', @@ -2806,7 +2841,7 @@ $distantTemplates 'rel' => 'search', 'type' => 'application/opensearchdescription+xml', 'href' => wfScript( 'opensearch_desc' ), - 'title' => wfMsgForContent( 'opensearch-desc' ), + 'title' => $this->msg( 'opensearch-desc' )->inContentLanguage()->text(), ) ); if ( $wgEnableAPI ) { @@ -2823,14 +2858,16 @@ $distantTemplates ) ); } + $lang = $this->getTitle()->getPageLanguage(); + # Language variants if ( !$wgDisableLangConversion && $wgCanonicalLanguageLinks - && $wgContLang->hasVariants() ) { + && $lang->hasVariants() ) { - $urlvar = $wgContLang->getURLVariant(); + $urlvar = $lang->getURLVariant(); if ( !$urlvar ) { - $variants = $wgContLang->getVariants(); + $variants = $lang->getVariants(); foreach ( $variants as $_v ) { $tags[] = Html::element( 'link', array( 'rel' => 'alternate', @@ -2879,7 +2916,7 @@ $distantTemplates $format, $link, # Used messages: 'page-rss-feed' and 'page-atom-feed' (for an easier grep) - wfMsg( "page-{$format}-feed", $this->getTitle()->getPrefixedText() ) + $this->msg( "page-{$format}-feed", $this->getTitle()->getPrefixedText() )->text() ); } @@ -2895,10 +2932,11 @@ $distantTemplates if ( $wgOverrideSiteFeed ) { foreach ( $wgOverrideSiteFeed as $type => $feedUrl ) { + // Note, this->feedLink escapes the url. $tags[] = $this->feedLink( $type, - htmlspecialchars( $feedUrl ), - wfMsg( "site-{$type}-feed", $wgSitename ) + $feedUrl, + $this->msg( "site-{$type}-feed", $wgSitename )->text() ); } } elseif ( $this->getTitle()->getPrefixedText() != $rctitle->getPrefixedText() ) { @@ -2906,7 +2944,7 @@ $distantTemplates $tags[] = $this->feedLink( $format, $rctitle->getLocalURL( "feed={$format}" ), - wfMsg( "site-{$format}-feed", $wgSitename ) # For grep: 'site-rss-feed', 'site-atom-feed'. + $this->msg( "site-{$format}-feed", $wgSitename )->text() # For grep: 'site-rss-feed', 'site-atom-feed'. ); } } @@ -2959,8 +2997,13 @@ $distantTemplates /** * Adds inline CSS styles * @param $style_css Mixed: inline CSS + * @param $flip String: Set to 'flip' to flip the CSS if needed */ - public function addInlineStyle( $style_css ){ + public function addInlineStyle( $style_css, $flip = 'noflip' ) { + if( $flip === 'flip' && $this->getLang()->isRTL() ) { + # If wanted, and the interface is right-to-left, flip the CSS + $style_css = CSSJanus::transform( $style_css, true, false ); + } $this->mInlineStyles .= Html::inlineStyle( $style_css ); } @@ -3045,6 +3088,9 @@ $distantTemplates return $ret; } + /** + * @return Array + */ public function buildCssLinksArray() { $links = array(); @@ -3161,16 +3207,11 @@ $distantTemplates * Like addWikiMsg() except the parameters are taken as an array * instead of a variable argument list. * - * $options is passed through to wfMsgExt(), see that function for details. - * * @param $name string * @param $args array - * @param $options array */ - public function addWikiMsgArray( $name, $args, $options = array() ) { - $options[] = 'parse'; - $text = wfMsgExt( $name, $options, $args ); - $this->addHTML( $text ); + public function addWikiMsgArray( $name, $args ) { + $this->addWikiText( $this->msg( $name, $args )->plain() ); } /**