X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FOutputPage.php;h=3bb217560a20c9b24a35d31cefc40bd3e4af02bf;hb=6f5b29ff4e6fdf21b5a8cacaf10d6aceaee26a7d;hp=fbd80c955f40b28d34d119b041178346a7bd2d78;hpb=185b81f769f32e59088d3ce7ded63272b95dd062;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/OutputPage.php b/includes/OutputPage.php index fbd80c955f..3bb217560a 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -122,6 +122,9 @@ class OutputPage extends ContextSource { /** @var array */ protected $mCategories = array(); + /** @var array */ + protected $mIndicators = array(); + /** @var array Array of Interwiki Prefixed (non DB key) Titles (e.g. 'fr:Test page') */ private $mLanguageLinks = array(); @@ -179,14 +182,12 @@ class OutputPage extends ContextSource { protected $mFeedLinksAppendQuery = null; - /** @var array - * What level of 'untrustworthiness' is allowed in CSS/JS modules loaded on this page? + /** + * @var int + * The level of 'untrustworthiness' allowed for modules loaded on this page. * @see ResourceLoaderModule::$origin - * ResourceLoaderModule::ORIGIN_ALL is assumed unless overridden; */ - protected $mAllowedModules = array( - ResourceLoaderModule::TYPE_COMBINED => ResourceLoaderModule::ORIGIN_ALL, - ); + protected $mAllowedModuleOrigin = ResourceLoaderModule::ORIGIN_ALL; /** @var bool Whether output is disabled. If this is true, the 'output' method will do nothing. */ protected $mDoNothing = false; @@ -1332,48 +1333,91 @@ class OutputPage extends ContextSource { } /** - * Do not allow scripts which can be modified by wiki users to load on this page; - * only allow scripts bundled with, or generated by, the software. + * Add an array of indicators, with their identifiers as array keys and HTML contents as values. + * + * In case of duplicate keys, existing values are overwritten. + * + * @param array $indicators + * @since 1.25 + */ + public function setIndicators( array $indicators ) { + $this->mIndicators = $indicators + $this->mIndicators; + // Keep ordered by key + ksort( $this->mIndicators ); + } + + /** + * Get the indicators associated with this page. + * + * The array will be internally ordered by item keys. + * + * @return array Keys: identifiers, values: HTML contents + * @since 1.25 + */ + public function getIndicators() { + return $this->mIndicators; + } + + /** + * Restrict the page to loading modules bundled the software. + * + * Disallows the queue to contain any modules which can be modified by wiki + * users to load on this page. */ public function disallowUserJs() { - $this->reduceAllowedModules( - ResourceLoaderModule::TYPE_SCRIPTS, - ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL - ); + $this->reduceAllowedModuleOrigin( ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL ); } /** - * Show what level of JavaScript / CSS untrustworthiness is allowed on this page + * Get the level of JavaScript / CSS untrustworthiness allowed on this page. + * * @see ResourceLoaderModule::$origin - * @param string $type ResourceLoaderModule TYPE_ constant + * @param string $type Unused: Module origin allowance used to be fragmented by + * ResourceLoaderModule TYPE_ constants. * @return int ResourceLoaderModule ORIGIN_ class constant */ - public function getAllowedModules( $type ) { - if ( $type == ResourceLoaderModule::TYPE_COMBINED ) { - return min( array_values( $this->mAllowedModules ) ); - } else { - return isset( $this->mAllowedModules[$type] ) - ? $this->mAllowedModules[$type] - : ResourceLoaderModule::ORIGIN_ALL; - } + public function getAllowedModules( $type = null ) { + return $this->mAllowedModuleOrigin; } /** * Set the highest level of CSS/JS untrustworthiness allowed + * + * @deprecated since 1.24 Raising level of allowed untrusted content is no longer supported. + * Use reduceAllowedModuleOrigin() instead. + * * @param string $type ResourceLoaderModule TYPE_ constant - * @param int $level ResourceLoaderModule class constant + * @param int $level ResourceLoaderModule ORIGIN_ constant */ public function setAllowedModules( $type, $level ) { - $this->mAllowedModules[$type] = $level; + wfDeprecated( __METHOD__, '1.24' ); + $this->reduceAllowedModuleOrigin( $level ); } /** - * As for setAllowedModules(), but don't inadvertently make the page more accessible - * @param string $type - * @param int $level ResourceLoaderModule class constant + * Limit the highest level of CSS/JS untrustworthiness allowed. + * + * @deprecated since 1.24 Module allowance is no longer fragmented by content type. + * Use reduceAllowedModuleOrigin() instead. + * + * @param string $type ResourceLoaderModule TYPE_ constant + * @param int $level ResourceLoaderModule ORIGIN_ class constant */ public function reduceAllowedModules( $type, $level ) { - $this->mAllowedModules[$type] = min( $this->getAllowedModules( $type ), $level ); + wfDeprecated( __METHOD__, '1.24' ); + $this->reduceAllowedModuleOrigin( $level ); + } + + /** + * Limit the highest level of CSS/JS untrustworthiness allowed. + * + * If passed the same or a higher level than the current level of untrustworthiness set, the + * level will remain unchanged. + * + * @param int $level ResourceLoaderModule class constant + */ + public function reduceAllowedModuleOrigin( $level ) { + $this->mAllowedModuleOrigin = min( $this->mAllowedModuleOrigin, $level ); } /** @@ -1626,6 +1670,7 @@ class OutputPage extends ContextSource { public function addParserOutputMetadata( $parserOutput ) { $this->mLanguageLinks += $parserOutput->getLanguageLinks(); $this->addCategoryLinks( $parserOutput->getCategories() ); + $this->setIndicators( $parserOutput->getIndicators() ); $this->mNewSectionLink = $parserOutput->getNewSection(); $this->mHideNewSectionLink = $parserOutput->getHideNewSection(); @@ -2070,8 +2115,6 @@ class OutputPage extends ContextSource { * the object, let's actually output it: */ public function output() { - global $wgLanguageCode; - if ( $this->mDoNothing ) { return; } @@ -2125,7 +2168,7 @@ class OutputPage extends ContextSource { ob_start(); $response->header( 'Content-type: ' . $config->get( 'MimeType' ) . '; charset=UTF-8' ); - $response->header( 'Content-language: ' . $wgLanguageCode ); + $response->header( 'Content-language: ' . $config->get( 'LanguageCode' ) ); // Avoid Internet Explorer "compatibility view" in IE 8-10, so that // jQuery etc. can work correctly. @@ -2399,90 +2442,32 @@ class OutputPage extends ContextSource { } /** - * Display a page stating that the Wiki is in read-only mode, - * and optionally show the source of the page that the user - * was trying to edit. Should only be called (for this - * purpose) after wfReadOnly() has returned true. - * - * For historical reasons, this function is _also_ used to - * show the error message when a user tries to edit a page - * they are not allowed to edit. (Unless it's because they're - * blocked, then we show blockedPage() instead.) In this - * case, the second parameter should be set to true and a list - * of reasons supplied as the third parameter. + * Display a page stating that the Wiki is in read-only mode. + * Should only be called after wfReadOnly() has returned true. * - * @todo Needs to be split into multiple functions. + * Historically, this function was used to show the source of the page that the user + * was trying to edit and _also_ permissions error messages. The relevant code was + * moved into EditPage in 1.19 (r102024 / d83c2a431c2a) and removed here in 1.25. * - * @param string $source Source code to show (or null). - * @param bool $protected Is this a permissions error? - * @param array $reasons List of reasons for this error, as returned by - * Title::getUserPermissionsErrors(). - * @param string $action Action that was denied or null if unknown + * @deprecated since 1.25; throw the exception directly * @throws ReadOnlyError */ - public function readOnlyPage( $source = null, $protected = false, - array $reasons = array(), $action = null - ) { - $this->setRobotPolicy( 'noindex,nofollow' ); - $this->setArticleRelated( false ); - - // If no reason is given, just supply a default "I can't let you do - // that, Dave" message. Should only occur if called by legacy code. - if ( $protected && empty( $reasons ) ) { - $reasons[] = array( 'badaccess-group0' ); - } - - if ( !empty( $reasons ) ) { - // Permissions error - if ( $source ) { - $this->setPageTitle( $this->msg( 'viewsource-title', $this->getTitle()->getPrefixedText() ) ); - $this->addBacklinkSubtitle( $this->getTitle() ); - } else { - $this->setPageTitle( $this->msg( 'badaccess' ) ); - } - $this->addWikiText( $this->formatPermissionsErrorMessage( $reasons, $action ) ); - } else { - // Wiki is read only - throw new ReadOnlyError; - } - - // Show source, if supplied - if ( is_string( $source ) ) { - $this->addWikiMsg( 'viewsourcetext' ); - - $pageLang = $this->getTitle()->getPageLanguage(); - $params = array( - 'id' => 'wpTextbox1', - 'name' => 'wpTextbox1', - 'cols' => $this->getUser()->getOption( 'cols' ), - 'rows' => $this->getUser()->getOption( 'rows' ), - 'readonly' => 'readonly', - 'lang' => $pageLang->getHtmlCode(), - 'dir' => $pageLang->getDir(), - ); - $this->addHTML( Html::element( 'textarea', $params, $source ) ); - - // Show templates used by this article - $templates = Linker::formatTemplates( $this->getTitle()->getTemplateLinksFrom() ); - $this->addHTML( "
-$templates -
-" ); + public function readOnlyPage() { + if ( func_num_args() > 0 ) { + throw new MWException( __METHOD__ . ' no longer accepts arguments since 1.25.' ); } - # If the title doesn't exist, it's fairly pointless to print a return - # link to it. After all, you just tried editing it and couldn't, so - # what's there to do there? - if ( $this->getTitle()->exists() ) { - $this->returnToMain( null, $this->getTitle() ); - } + throw new ReadOnlyError; } /** * Turn off regular page output and return an error response * for when rate limiting has triggered. + * + * @deprecated since 1.25; throw the exception directly */ public function rateLimited() { + wfDeprecated( __METHOD__, '1.25' ); throw new ThrottledError; } @@ -2587,6 +2572,8 @@ $templates public function headElement( Skin $sk, $includeStyle = true ) { global $wgContLang; + $section = new ProfileSection( __METHOD__ ); + $userdir = $this->getLanguage()->getDir(); $sitedir = $wgContLang->getDir(); @@ -2769,7 +2756,9 @@ $templates ); $context = new ResourceLoaderContext( $resourceLoader, new FauxRequest( $query ) ); - // Extract modules that know they're empty + // Extract modules that know they're empty and see if we have one or more + // raw modules + $isRaw = false; foreach ( $grpModules as $key => $module ) { // Inline empty modules: since they're empty, just mark them as 'ready' (bug 46857) // If we're only getting the styles, we don't need to do anything for empty modules. @@ -2779,6 +2768,8 @@ $templates $links['states'][$key] = 'ready'; } } + + $isRaw |= $module->isRaw(); } // If there are no non-empty modules, skip this group @@ -2797,7 +2788,9 @@ $templates ); } else { $links['html'] .= Html::inlineScript( - $resourceLoader->makeModuleResponse( $context, $grpModules ) + ResourceLoader::makeLoaderConditionalScript( + $resourceLoader->makeModuleResponse( $context, $grpModules ) + ) ); } $links['html'] .= "\n"; @@ -2843,6 +2836,17 @@ $templates ); } else { $link = Html::linkedScript( $url ); + if ( $context->getOnly() === 'scripts' && !$context->getRaw() && !$isRaw ) { + // Wrap only=script requests in a conditional as browsers not supported + // by the startup module would unconditionally execute this module. + // Otherwise users will get "ReferenceError: mw is undefined" or + // "jQuery is undefined" from e.g. a "site" module. + $link = Html::inlineScript( + ResourceLoader::makeLoaderConditionalScript( + Xml::encodeJsCall( 'document.write', array( $link ) ) + ) + ); + } // For modules requested directly in the html via or