X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2FOutputPage.php;h=fd527d257dc33b256d5ac37f08e5d00dc33f0290;hb=fb80a53b1ba3c0c5dc9b01b2a058b716a046461d;hp=93f245fb4b441cf9369da78ac655a0e4502155bb;hpb=ce8f81837c17729d9d6794f3097ee81458ac9ea3;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 93f245fb4b..fd527d257d 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -23,8 +23,9 @@ class OutputPage { var $mLastModified = '', $mETag = false; var $mCategoryLinks = array(), $mCategories = array(), $mLanguageLinks = array(); - var $mScripts = '', $mLinkColours, $mPageLinkTitle = '', $mHeadItems = array(); + var $mScripts = '', $mInlineStyles = '', $mLinkColours, $mPageLinkTitle = '', $mHeadItems = array(); var $mModules = array(), $mModuleScripts = array(), $mModuleStyles = array(), $mModuleMessages = array(); + var $mResourceLoader; var $mInlineMsg = array(); var $mTemplateIds = array(); @@ -47,6 +48,7 @@ class OutputPage { var $mPageTitleActionText = ''; var $mParseWarnings = array(); var $mSquidMaxage = 0; + var $mPreventClickjacking = true; var $mRevisionId = null; protected $mTitle = null; @@ -562,11 +564,6 @@ class OutputPage { $nameWithTags = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags( $name ) ); $this->mPagetitle = $nameWithTags; - $taction = $this->getPageTitleActionText(); - if( !empty( $taction ) ) { - $name .= ' - '.$taction; - } - # change "foo&bar" to "foo&bar" $this->setHTMLTitle( wfMsg( 'pagetitle', Sanitizer::stripAllTags( $nameWithTags ) ) ); } @@ -1003,14 +1000,6 @@ class OutputPage { $this->mDebugtext .= $text; } - /** - * @deprecated use parserOptions() instead - */ - public function setParserOptions( $options ) { - wfDeprecated( __METHOD__ ); - return $this->parserOptions( $options ); - } - /** * Get/set the ParserOptions object to use for wikitext parsing * @@ -1121,43 +1110,6 @@ class OutputPage { wfProfileOut( __METHOD__ ); } - /** - * Add wikitext to the buffer, assuming that this is the primary text for a page view - * Saves the text into the parser cache if possible. - * - * @param $text String: wikitext - * @param $article Article object - * @param $cache Boolean - * @deprecated Use Article::outputWikitext - */ - public function addPrimaryWikiText( $text, $article, $cache = true ) { - global $wgParser; - - wfDeprecated( __METHOD__ ); - - $popts = $this->parserOptions(); - $popts->setTidy( true ); - $parserOutput = $wgParser->parse( - $text, $article->mTitle, - $popts, true, true, $this->mRevisionId - ); - $popts->setTidy( false ); - if ( $cache && $article && $parserOutput->isCacheable() ) { - $parserCache = ParserCache::singleton(); - $parserCache->save( $parserOutput, $article, $popts ); - } - - $this->addParserOutput( $parserOutput ); - } - - /** - * @deprecated use addWikiTextTidy() - */ - public function addSecondaryWikiText( $text, $linestart = true ) { - wfDeprecated( __METHOD__ ); - $this->addWikiTextTitleTidy( $text, $this->getTitle(), $linestart ); - } - /** * Add a ParserOutput object, but without Html * @@ -1230,24 +1182,37 @@ class OutputPage { * @param $interface Boolean: use interface language ($wgLang instead of * $wgContLang) while parsing language sensitive magic * words like GRAMMAR and PLURAL + * @param $language Language object: target language object, will override + * $interface * @return String: HTML */ - public function parse( $text, $linestart = true, $interface = false ) { + public function parse( $text, $linestart = true, $interface = false, $language = null ) { global $wgParser; + if( is_null( $this->getTitle() ) ) { throw new MWException( 'Empty $mTitle in ' . __METHOD__ ); } + $popts = $this->parserOptions(); if ( $interface ) { $popts->setInterfaceMessage( true ); } + if ( $language !== null ) { + $oldLang = $popts->setTargetLanguage( $language ); + } + $parserOutput = $wgParser->parse( $text, $this->getTitle(), $popts, $linestart, true, $this->mRevisionId ); + if ( $interface ) { $popts->setInterfaceMessage( false ); } + if ( $language !== null ) { + $popts->setTargetLanguage( $oldLang ); + } + return $parserOutput->getText(); } @@ -1272,24 +1237,6 @@ class OutputPage { return $parsed; } - /** - * @deprecated - * - * @param $article Article - * @return Boolean: true if successful, else false. - */ - public function tryParserCache( &$article ) { - wfDeprecated( __METHOD__ ); - $parserOutput = ParserCache::singleton()->get( $article, $article->getParserOptions() ); - - if ( $parserOutput !== false ) { - $this->addParserOutput( $parserOutput ); - return true; - } else { - return false; - } - } - /** * Set the value of the "s-maxage" part of the "Cache-control" HTTP header * @@ -1429,13 +1376,58 @@ class OutputPage { if( $variant === $wgContLang->getCode() ) { continue; } else { - $aloption[] = "string-contains=$variant"; + $aloption[] = 'string-contains=' . $variant; + + // IE and some other browsers use another form of language code + // in their Accept-Language header, like "zh-CN" or "zh-TW". + // We should handle these too. + $ievariant = explode( '-', $variant ); + if ( count( $ievariant ) == 2 ) { + $ievariant[1] = strtoupper( $ievariant[1] ); + $ievariant = implode( '-', $ievariant ); + $aloption[] = 'string-contains=' . $ievariant; + } } } $this->addVaryHeader( 'Accept-Language', $aloption ); } } + /** + * Set a flag which will cause an X-Frame-Options header appropriate for + * edit pages to be sent. The header value is controlled by + * $wgEditPageFrameOptions. + * + * This is the default for special pages. If you display a CSRF-protected + * form on an ordinary view page, then you need to call this function. + */ + public function preventClickjacking( $enable = true ) { + $this->mPreventClickjacking = $enable; + } + + /** + * Turn off frame-breaking. Alias for $this->preventClickjacking(false). + * This can be called from pages which do not contain any CSRF-protected + * HTML form. + */ + public function allowClickjacking() { + $this->mPreventClickjacking = false; + } + + /** + * Get the X-Frame-Options header value (without the name part), or false + * if there isn't one. This is used by Skin to determine whether to enable + * JavaScript frame-breaking, for clients that don't support X-Frame-Options. + */ + public function getFrameOptions() { + global $wgBreakFrames, $wgEditPageFrameOptions; + if ( $wgBreakFrames ) { + return 'DENY'; + } elseif ( $this->mPreventClickjacking && $wgEditPageFrameOptions ) { + return $wgEditPageFrameOptions; + } + } + /** * Send cache control HTTP headers */ @@ -1572,7 +1564,6 @@ class OutputPage { global $wgLanguageCode, $wgDebugRedirects, $wgMimeType; global $wgUseAjax, $wgAjaxWatch; global $wgEnableMWSuggest, $wgUniversalEditButton; - global $wgArticle; if( $this->mDoNothing ) { return; @@ -1609,10 +1600,10 @@ class OutputPage { } $sk = $wgUser->getSkin(); - + // Add base resources - $this->addModules( array( 'mediawiki.legacy.wikibits' ) ); - + $this->addModules( array( 'mediawiki.legacy.wikibits', 'mediawiki.util' ) ); + // Add various resources if required if ( $wgUseAjax ) { $this->addModules( 'mediawiki.legacy.ajax' ); @@ -1620,7 +1611,7 @@ class OutputPage { wfRunHooks( 'AjaxAddScript', array( &$this ) ); if( $wgAjaxWatch && $wgUser->isLoggedIn() ) { - $this->addModules( 'mediawiki.legacy.ajaxwatch' ); + $this->addModules( 'mediawiki.action.watch.ajax' ); } if ( $wgEnableMWSuggest && !$wgUser->getOption( 'disablesuggest', false ) ) { @@ -1629,11 +1620,11 @@ class OutputPage { } if( $wgUser->getBoolOption( 'editsectiononrightclick' ) ) { - $this->addModules( 'mediawiki.legacy.rightclickedit' ); + $this->addModules( 'mediawiki.action.view.rightClickEdit' ); } if( $wgUniversalEditButton ) { - if( isset( $wgArticle ) && $this->getTitle() && $this->getTitle()->quickUserCan( 'edit' ) + if( $this->isArticleRelated() && $this->getTitle() && $this->getTitle()->quickUserCan( 'edit' ) && ( $this->getTitle()->exists() || $this->getTitle()->quickUserCan( 'create' ) ) ) { // Original UniversalEditButton $msg = wfMsg( 'edit' ); @@ -1659,6 +1650,12 @@ class OutputPage { $wgRequest->response()->header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" ); $wgRequest->response()->header( 'Content-language: ' . $wgLanguageCode ); + // Prevent framing, if requested + $frameOptions = $this->getFrameOptions(); + if ( $frameOptions ) { + $wgRequest->response()->header( "X-Frame-Options: $frameOptions" ); + } + if ( $this->mArticleBodyOnly ) { $this->out( $this->mBodytext ); } else { @@ -1695,32 +1692,6 @@ class OutputPage { print $outs; } - /** - * @todo document - */ - public static function setEncodings() { - global $wgInputEncoding, $wgOutputEncoding; - - $wgInputEncoding = strtolower( $wgInputEncoding ); - - if ( empty( $_SERVER['HTTP_ACCEPT_CHARSET'] ) ) { - $wgOutputEncoding = strtolower( $wgOutputEncoding ); - return; - } - $wgOutputEncoding = $wgInputEncoding; - } - - /** - * @deprecated use wfReportTime() instead. - * - * @return String - */ - public function reportTime() { - wfDeprecated( __METHOD__ ); - $time = wfReportTime(); - return $time; - } - /** * Produce a "user is blocked" page. * @@ -1811,9 +1782,7 @@ class OutputPage { $this->mRedirect = ''; $this->mBodytext = ''; - array_unshift( $params, 'parse' ); - array_unshift( $params, $msg ); - $this->addHTML( call_user_func_array( 'wfMsgExt', $params ) ); + $this->addWikiMsgArray( $msg, $params ); $this->returnToMain(); } @@ -1898,7 +1867,7 @@ class OutputPage { $this->setPageTitle( wfMsg( 'loginreqtitle' ) ); $this->setHtmlTitle( wfMsg( 'errorpagetitle' ) ); $this->setRobotPolicy( 'noindex,nofollow' ); - $this->setArticleFlag( false ); + $this->setArticleRelated( false ); $loginTitle = SpecialPage::getTitleFor( 'Userlogin' ); $loginLink = $skin->link( @@ -2044,7 +2013,6 @@ class OutputPage { * @return none */ public function addPasswordSecurity( $passwordId, $retypeId ) { - $this->includeJQuery(); $data = array( 'password' => '#' . $passwordId, 'retype' => '#' . $retypeId, @@ -2059,53 +2027,6 @@ class OutputPage { $this->addModules( 'mediawiki.legacy.password' ); } - /** @deprecated */ - public function errorpage( $title, $msg ) { - wfDeprecated( __METHOD__ ); - throw new ErrorPageError( $title, $msg ); - } - - /** @deprecated */ - public function databaseError( $fname, $sql, $error, $errno ) { - throw new MWException( "OutputPage::databaseError is obsolete\n" ); - } - - /** @deprecated */ - public function fatalError( $message ) { - wfDeprecated( __METHOD__ ); - throw new FatalError( $message ); - } - - /** @deprecated */ - public function unexpectedValueError( $name, $val ) { - wfDeprecated( __METHOD__ ); - throw new FatalError( wfMsg( 'unexpected', $name, $val ) ); - } - - /** @deprecated */ - public function fileCopyError( $old, $new ) { - wfDeprecated( __METHOD__ ); - throw new FatalError( wfMsg( 'filecopyerror', $old, $new ) ); - } - - /** @deprecated */ - public function fileRenameError( $old, $new ) { - wfDeprecated( __METHOD__ ); - throw new FatalError( wfMsg( 'filerenameerror', $old, $new ) ); - } - - /** @deprecated */ - public function fileDeleteError( $name ) { - wfDeprecated( __METHOD__ ); - throw new FatalError( wfMsg( 'filedeleteerror', $name ) ); - } - - /** @deprecated */ - public function fileNotFoundError( $name ) { - wfDeprecated( __METHOD__ ); - throw new FatalError( wfMsg( 'filenotfound', $name ) ); - } - public function showFatalError( $message ) { $this->setPageTitle( wfMsg( 'internalerror' ) ); $this->setRobotPolicy( 'noindex,nofollow' ); @@ -2226,12 +2147,9 @@ class OutputPage { $ret .= implode( "\n", array( $this->getHeadLinks( $sk ), - $this->buildCssLinks(), - $this->getHeadItems(), + $this->buildCssLinks( $sk ), + $this->getHeadItems() ) ); - if ( $sk->usercss ) { - $ret .= Html::inlineStyle( $sk->usercss ); - } if ( $wgUseTrackbacks && $this->isArticleRelated() ) { $ret .= $this->getTitle()->trackbackRDF(); @@ -2275,29 +2193,144 @@ class OutputPage { $bodyAttrs['class'] .= ' ' . Sanitizer::escapeClass( 'page-' . $this->getTitle()->getPrefixedText() ); $bodyAttrs['class'] .= ' skin-' . Sanitizer::escapeClass( $wgUser->getSkin()->getSkinName() ); + $sk->addToBodyAttributes( $this, $bodyAttrs ); // Allow skins to add body attributes they need + wfRunHooks( 'OutputPageBodyAttributes', array( $this, $sk, &$bodyAttrs ) ); + $ret .= Html::openElement( 'body', $bodyAttrs ) . "\n"; return $ret; } - - static function makeResourceLoaderLink( $skin, $modules, $only ) { - global $wgUser, $wgLang, $wgRequest, $wgLoadScript; + + /** + * Get a ResourceLoader object associated with this OutputPage + */ + public function getResourceLoader() { + if ( is_null( $this->mResourceLoader ) ) { + $this->mResourceLoader = new ResourceLoader(); + } + return $this->mResourceLoader; + } + + /** + * TODO: Document + * @param $skin Skin + * @param $modules Array/string with the module name + * @param $only string May be styles, messages or scripts + * @param $useESI boolean + * @return string html