From 177b1e264a717475b2571c9643dab79ba3cfea58 Mon Sep 17 00:00:00 2001 From: Alexandre Emsenhuber Date: Thu, 21 Aug 2008 14:09:57 +0000 Subject: [PATCH] Tweaks for skins: * Moved SkinTemplate::addStyle() and related stuff to OutputPage so that it can be used non-SkinTemplate skins and avoid duplication with the actual OutputPage::addStyle() (the two functions have the same format). * Non-SkinTemplate skins now also load their CSS with tags instead of @import. * Moved SkinTemplate::setupUserCss() to Skin. * Merged action=raw&gen=(js|css) for SkinTemplate and non-SkinTemplate skins, renamed functions to Skin::generateUserJs() and Skin::generateUserStyleSheet() and dropped a lot of cascading call which is a bit incomprehensible. --- includes/OutputPage.php | 184 +++++++++++++++++++----- includes/RawPage.php | 8 +- includes/Skin.php | 245 ++++++++++++++++++------------- includes/SkinTemplate.php | 295 +++++--------------------------------- skins/Chick.php | 13 +- skins/CologneBlue.php | 5 +- skins/Modern.php | 15 +- skins/MonoBook.php | 27 ++-- skins/MySkin.php | 9 +- skins/Simple.php | 11 +- skins/Standard.php | 23 +-- 11 files changed, 381 insertions(+), 454 deletions(-) diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 4640608cb8..f46524e819 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -35,6 +35,13 @@ class OutputPage { var $mSquidMaxage = 0; var $mRevisionId = null; + /** + * An array of stylesheet filenames (relative from skins path), with options + * for CSS media, IE conditions, and RTL/LTR direction. + * For internal use; add settings in the skin via $this->addStyle() + */ + var $styles = array(); + private $mIndexPolicy = 'index'; private $mFollowPolicy = 'follow'; @@ -65,18 +72,19 @@ class OutputPage { */ function setStatusCode( $statusCode ) { $this->mStatusCode = $statusCode; } - # To add an http-equiv meta tag, precede the name with "http:" - function addMeta( $name, $val ) { array_push( $this->mMetatags, array( $name, $val ) ); } + /** + * Add a new tag + * To add an http-equiv meta tag, precede the name with "http:" + * + * @param $name tag name + * @param $val tag value + */ + function addMeta( $name, $val ) { + array_push( $this->mMetatags, array( $name, $val ) ); + } + function addKeyword( $text ) { array_push( $this->mKeywords, $text ); } function addScript( $script ) { $this->mScripts .= "\t\t".$script; } - function addStyle( $style ) { - global $wgStylePath, $wgStyleVersion; - $this->addLink( - array( - 'rel' => 'stylesheet', - 'href' => $wgStylePath . '/' . $style . '?' . $wgStyleVersion, - 'type' => 'text/css' ) ); - } function addExtensionStyle( $url ) { $linkarr = array( 'rel' => 'stylesheet', 'href' => $url, 'type' => 'text/css' ); @@ -1382,15 +1390,19 @@ class OutputPage { /** * @return string The doctype, opening , and head element. */ - public function headElement() { + public function headElement( Skin $sk ) { global $wgDocType, $wgDTD, $wgContLanguageCode, $wgOutputEncoding, $wgMimeType; global $wgXhtmlDefaultNamespace, $wgXhtmlNamespaces; global $wgUser, $wgContLang, $wgUseTrackbacks, $wgTitle, $wgStyleVersion; + $this->addMeta( "http:Content-type", "$wgMimeType; charset={$wgOutputEncoding}" ); + $this->addStyle( 'common/wikiprintable.css', 'print' ); + $sk->setupUserCss( $this ); + + $ret = ''; + if( $wgMimeType == 'text/xml' || $wgMimeType == 'application/xhtml+xml' || $wgMimeType == 'application/xml' ) { - $ret = "\n"; - } else { - $ret = ''; + $ret .= "\n"; } $ret .= "\n"; @@ -1405,29 +1417,17 @@ class OutputPage { $ret .= "xmlns:{$tag}=\"{$ns}\" "; } $ret .= "xml:lang=\"$wgContLanguageCode\" lang=\"$wgContLanguageCode\" $rtl>\n"; - $ret .= "\n" . htmlspecialchars( $this->getHTMLTitle() ) . "\n"; - $this->addMeta( "http:Content-type", "$wgMimeType; charset={$wgOutputEncoding}" ); - - $ret .= $this->getHeadLinks(); - global $wgStylePath; - if( $this->isPrintable() ) { - $media = ''; - } else { - $media = "media='print'"; - } - $printsheet = htmlspecialchars( "$wgStylePath/common/wikiprintable.css?$wgStyleVersion" ); - $ret .= "\n"; - - $sk = $wgUser->getSkin(); - // Load order here is key - $ret .= $sk->getHeadScripts( $this->mAllowUserJs ); - $ret .= $this->mScripts; - $ret .= $sk->getSiteStyles(); - foreach( $this->mExtStyles as $tag ) { - $ret .= Xml::element( 'link', $tag ) . "\n"; + $ret .= "\n" . htmlspecialchars( $this->getHTMLTitle() ) . "\n\t\t"; + $ret .= implode( "\t\t", array( + $this->getHeadLinks(), + $this->buildCssLinks(), + $sk->getHeadScripts( $this->mAllowUserJs ), + $this->mScripts, + $this->getHeadItems(), + )); + if( $sk->usercss ){ + $ret .= ""; } - $ret .= $sk->getUserStyles(); - $ret .= $this->getHeadItems(); if ($wgUseTrackbacks && $this->isArticleRelated()) $ret .= $wgTitle->trackbackRDF(); @@ -1564,6 +1564,118 @@ class OutputPage { 'href' => $url ) ); } + /** + * Add a local or specified stylesheet, with the given media options. + * Meant primarily for internal use... + * + * @param $media -- to specify a media type, 'screen', 'printable', 'handheld' or any. + * @param $conditional -- for IE conditional comments, specifying an IE version + * @param $dir -- set to 'rtl' or 'ltr' for direction-specific sheets + */ + public function addStyle( $style, $media='', $condition='', $dir='' ) { + $options = array(); + if( $media ) + $options['media'] = $media; + if( $condition ) + $options['condition'] = $condition; + if( $dir ) + $options['dir'] = $dir; + $this->styles[$style] = $options; + } + + /** + * Build a set of s for the stylesheets specified in the $this->styles array. + * These will be applied to various media & IE conditionals. + */ + public function buildCssLinks() { + $links = array(); + foreach( $this->styles as $file => $options ) { + $link = $this->styleLink( $file, $options ); + if( $link ) + $links[] = $link; + } + + return implode( "\n\t\t", $links ); + } + + protected function styleLink( $style, $options ) { + global $wgRequest; + + if( isset( $options['dir'] ) ) { + global $wgContLang; + $siteDir = $wgContLang->isRTL() ? 'rtl' : 'ltr'; + if( $siteDir != $options['dir'] ) + return ''; + } + + if( isset( $options['media'] ) ) { + $media = $this->transformCssMedia( $options['media'] ); + if( is_null( $media ) ) { + return ''; + } + } else { + $media = ''; + } + + if( substr( $style, 0, 1 ) == '/' || + substr( $style, 0, 5 ) == 'http:' || + substr( $style, 0, 6 ) == 'https:' ) { + $url = $style; + } else { + global $wgStylePath, $wgStyleVersion; + $url = $wgStylePath . '/' . $style . '?' . $wgStyleVersion; + } + + $attribs = array( + 'rel' => 'stylesheet', + 'href' => $url, + 'type' => 'text/css' ); + if( $media ) { + $attribs['media'] = $media; + } + + $link = Xml::element( 'link', $attribs ); + + if( isset( $options['condition'] ) ) { + $condition = htmlspecialchars( $options['condition'] ); + $link = ""; + } + return $link; + } + + function transformCssMedia( $media ) { + global $wgRequest, $wgHandheldForIPhone; + + // Switch in on-screen display for media testing + $switches = array( + 'printable' => 'print', + 'handheld' => 'handheld', + ); + foreach( $switches as $switch => $targetMedia ) { + if( $wgRequest->getBool( $switch ) ) { + if( $media == $targetMedia ) { + $media = ''; + } elseif( $media == 'screen' ) { + return null; + } + } + } + + // Expand longer media queries as iPhone doesn't grok 'handheld' + if( $wgHandheldForIPhone ) { + $mediaAliases = array( + 'screen' => 'screen and (min-device-width: 481px)', + 'handheld' => 'handheld, only screen and (max-device-width: 480px)', + ); + + if( isset( $mediaAliases[$media] ) ) { + $media = $mediaAliases[$media]; + } + } + + return $media; + } + /** * Turn off regular page output and return an error reponse * for when rate limiting has triggered. diff --git a/includes/RawPage.php b/includes/RawPage.php index b1e2539a26..6d746caa86 100644 --- a/includes/RawPage.php +++ b/includes/RawPage.php @@ -163,11 +163,13 @@ class RawPage { global $wgUser, $wgOut, $wgRequest; if($this->mGen) { $sk = $wgUser->getSkin(); - $sk->initPage($wgOut); + if( !StubObject::isRealObject( $wgOut ) ) + $wgOut->_unstub( 2 ); + $sk->initPage( $wgOut ); if($this->mGen == 'css') { - return $sk->getUserStylesheet(); + return $sk->generateUserStylesheet(); } else if($this->mGen == 'js') { - return $sk->getUserJs(); + return $sk->generateUserJs(); } } else { return $this->getArticleText(); diff --git a/includes/Skin.php b/includes/Skin.php index 0cb732246f..9296d24318 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -171,7 +171,7 @@ class Skin extends Linker { return $q; } - function initPage( &$out ) { + function initPage( OutputPage $out ) { global $wgFavicon, $wgAppleTouchIcon; wfProfileIn( __METHOD__ ); @@ -223,7 +223,7 @@ class Skin extends Linker { $lb->execute(); } - function addMetadataLinks( &$out ) { + function addMetadataLinks( OutputPage $out ) { global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf; global $wgRightsPage, $wgRightsUrl; @@ -259,16 +259,25 @@ class Skin extends Linker { } } - function outputPage( &$out ) { - global $wgDebugComments; + function setMembers(){ + global $wgTitle, $wgUser; + $this->mTitle = $wgTitle; + $this->mUser = $wgUser; + $this->userpage = $wgUser->getUserPage()->getPrefixedText(); + $this->usercss = false; + } + function outputPage( OutputPage $out ) { + global $wgDebugComments; wfProfileIn( __METHOD__ ); + + $this->setMembers(); $this->initPage( $out ); // See self::afterContentHook() for documentation $afterContent = $this->afterContentHook(); - $out->out( $out->headElement() ); + $out->out( $out->headElement( $this ) ); $out->out( "\ngetBodyOptions(); @@ -336,7 +345,7 @@ class Skin extends Linker { 'wgScriptPath' => $wgScriptPath, 'wgScript' => $wgScript, 'wgVariantArticlePath' => $wgVariantArticlePath, - 'wgActionPaths' => $wgActionPaths, + 'wgActionPaths' => (object)$wgActionPaths, 'wgServer' => $wgServer, 'wgCanonicalNamespace' => $nsname, 'wgCanonicalSpecialPageName' => SpecialPage::resolveAlias( $wgTitle->getDBkey() ), @@ -390,26 +399,26 @@ class Skin extends Linker { function getHeadScripts( $allowUserJs ) { global $wgStylePath, $wgUser, $wgJsMimeType, $wgStyleVersion; - $r = self::makeGlobalVariablesScript( array( 'skinname' => $this->getSkinName() ) ); + $vars = self::makeGlobalVariablesScript( array( 'skinname' => $this->getSkinName() ) ); - $r .= "\n"; + $r = array( "" ); global $wgUseSiteJs; if ($wgUseSiteJs) { $jsCache = $wgUser->isLoggedIn() ? '&smaxage=0' : ''; - $r .= "\n"; + "\">"; } if( $allowUserJs && $wgUser->isLoggedIn() ) { $userpage = $wgUser->getUserPage(); $userjs = htmlspecialchars( self::makeUrl( $userpage->getPrefixedText().'/'.$this->getSkinName().'.js', 'action=raw&ctype='.$wgJsMimeType)); - $r .= '\n"; + $r[] = '"; } - return $r; + return $vars . "\t\t" . implode ( "\n\t\t", $r ); } /** @@ -437,46 +446,23 @@ class Skin extends Linker { } /** - * Get the site-specific stylesheet, SkinTemplate loads via RawPage.php (settings are cached that way) - */ - function getSiteStylesheet() { - global $wgStylePath, $wgContLang, $wgStyleVersion; - $sheet = $this->getStylesheet(); - $s = "@import \"$wgStylePath/common/shared.css?$wgStyleVersion\";\n"; - $s .= "@import \"$wgStylePath/common/oldshared.css?$wgStyleVersion\";\n"; - $s .= "@import \"$wgStylePath/$sheet?$wgStyleVersion\";\n"; - if( $wgContLang->isRTL() ) - $s .= "@import \"$wgStylePath/common/common_rtl.css?$wgStyleVersion\";\n"; - return "$s\n"; - } - - /** - * Get the user-specific stylesheet, SkinTemplate loads via RawPage.php (settings are cached that way) - */ - function getUserStylesheet() { - global $wgContLang, $wgSquidMaxage, $wgStyleVersion; - $query = "usemsgcache=yes&action=raw&ctype=text/css&smaxage=$wgSquidMaxage"; - $s = '@import "' . self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) . "\";\n"; - $s .= '@import "' . self::makeNSUrl( ucfirst( $this->getSkinName() . '.css' ), $query, NS_MEDIAWIKI ) . "\";\n"; - $s .= $this->doGetUserStyles(); - return "$s\n"; - } - - /** - * This returns MediaWiki:Common.js, and derived classes may add other JS. - * Despite its name, it does *not* return any custom user JS from user - * subpages. The returned script is sitewide and publicly cacheable and - * therefore must not include anything that varies according to user, - * interface language, etc. (although it may vary by skin). See - * makeGlobalVariablesScript for things that can vary per page view and are - * not cacheable. + * generated JavaScript action=raw&gen=js + * This returns MediaWiki:Common.js and MediaWiki:[Skinname].js concate- + * nated together. For some bizarre reason, it does *not* return any + * custom user JS from subpages. Huh? + * + * There's absolutely no reason to have separate Monobook/Common JSes. + * Any JS that cares can just check the skin variable generated at the + * top. For now Monobook.js will be maintained, but it should be consi- + * dered deprecated. * - * @return string Raw JavaScript to be returned + * @return string */ - public function getUserJs() { + public function generateUserJs() { + global $wgStylePath; + wfProfileIn( __METHOD__ ); - global $wgStylePath; $s = "/* generated javascript */\n"; $s .= "var skin = '" . Xml::escapeJsString( $this->getSkinName() ) . "';\n"; $s .= "var stylepath = '" . Xml::escapeJsString( $wgStylePath ) . "';"; @@ -485,57 +471,35 @@ class Skin extends Linker { if ( !wfEmptyMsg ( 'common.js', $commonJs ) ) { $s .= $commonJs; } + + $s .= "\n\n/* MediaWiki:".ucfirst( $this->getSkinName() ).".js */\n"; + // avoid inclusion of non defined user JavaScript (with custom skins only) + // by checking for default message content + $msgKey = ucfirst( $this->getSkinName() ).'.js'; + $userJS = wfMsgForContent($msgKey); + if ( !wfEmptyMsg( $msgKey, $userJS ) ) { + $s .= $userJS; + } + wfProfileOut( __METHOD__ ); return $s; } /** - * Return html code that include site stylesheets + * generate user stylesheet for action=raw&gen=css */ - function getSiteStyles() { - $s = "\n"; + public function generateUserStylesheet() { + wfProfileIn( __METHOD__ ); + $s = "/* generated user stylesheet */\n" . + $this->reallyGenerateUserStylesheet(); + wfProfileOut( __METHOD__ ); return $s; } /** - * Return html code that include User stylesheets + * Split for easier subclassing in SkinSimple, SkinStandard and SkinCologneBlue */ - function getUserStyles() { - $s = "\n"; - return $s; - } - - /** - * Some styles that are set by user through the user settings interface. - */ - function doGetUserStyles() { - global $wgUser, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss; - - $s = ''; - - if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { # logged in - if($wgTitle->isCssSubpage() && $this->userCanPreview( $wgRequest->getText( 'action' ) ) ) { - $s .= $wgRequest->getText('wpTextbox1'); - } else { - $userpage = $wgUser->getUserPage(); - $s.= '@import "'.self::makeUrl( - $userpage->getPrefixedText().'/'.$this->getSkinName().'.css', - 'action=raw&ctype=text/css').'";'."\n"; - } - } - - return $s . $this->reallyDoGetUserStyles(); - } - - function reallyDoGetUserStyles() { + protected function reallyGenerateUserStylesheet(){ global $wgUser; $s = ''; if (($undopt = $wgUser->getOption("underline")) < 2) { @@ -572,6 +536,81 @@ END; return $s; } + /** + * @private + */ + function setupUserCss( OutputPage $out ) { + global $wgRequest, $wgContLang, $wgUser; + global $wgAllowUserCss, $wgUseSiteCss, $wgSquidMaxage, $wgStylePath; + + wfProfileIn( __METHOD__ ); + + $this->setupSkinUserCss( $out ); + + $siteargs = array( + 'action' => 'raw', + 'maxage' => $wgSquidMaxage, + ); + if( $wgUser->isLoggedIn() ) { + // Ensure that logged-in users' generated CSS isn't clobbered + // by anons' publicly cacheable generated CSS. + $siteargs['smaxage'] = '0'; + $siteargs['ts'] = $wgUser->mTouched; + } + + // Add any extension CSS + foreach( $out->getExtStyle() as $tag ) { + $out->addStyle( $tag['href'] ); + } + + // If we use the site's dynamic CSS, throw that in, too + // Per-site custom styles + if( $wgUseSiteCss ) { + $query = wfArrayToCGI( array( + 'usemsgcache' => 'yes', + 'ctype' => 'text/css', + 'smaxage' => $wgSquidMaxage + ) + $siteargs ); + # Site settings must override extension css! (bug 15025) + $out->addStyle( self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI) ); + $out->addStyle( self::makeNSUrl( $this->getSkinName() . '.css', $query, NS_MEDIAWIKI ) ); + } + + // Per-user styles based on preferences + $siteargs['gen'] = 'css'; + if( ( $us = $wgRequest->getVal( 'useskin', '' ) ) !== '' ) { + $siteargs['useskin'] = $us; + } + $out->addStyle( self::makeUrl( '-', wfArrayToCGI( $siteargs ) ) ); + + // Per-user custom style pages + if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { + $action = $wgRequest->getVal('action'); + # If we're previewing the CSS page, use it + if( $this->mTitle->isCssSubpage() && $this->userCanPreview( $action ) ) { + $previewCss = $wgRequest->getText('wpTextbox1'); + // @FIXME: properly escape the cdata! + $this->usercss = "/**/"; + } else { + $out->addStyle( self::makeUrl($this->userpage .'/'.$this->getSkinName() .'.css', + 'action=raw&ctype=text/css') ); + } + } + + wfProfileOut( __METHOD__ ); + } + + /** + * Add skin specific stylesheets + * @param $out OutputPage + */ + function setupSkinUserCss( OutputPage $out ) { + $out->addStyle( 'common/shared.css' ); + $out->addStyle( 'common/oldshared.css' ); + $out->addStyle( $this->getStylesheet() ); + $out->addStyle( 'common/common_rtl.css', '', '', 'rtl' ); + } + function getBodyOptions() { global $wgUser, $wgTitle, $wgOut, $wgRequest, $wgContLang; @@ -646,11 +685,11 @@ END; $s .= "\n
\n
\n" . "\n\n"; - $shove = ($qb != 0); - $left = ($qb == 1 || $qb == 3); - if($wgContLang->isRTL()) $left = !$left; + $shove = ( $qb != 0 ); + $left = ( $qb == 1 || $qb == 3 ); + if( $wgContLang->isRTL() ) $left = !$left; - if ( !$shove ) { + if( !$shove ) { $s .= "'; } elseif( $left ) { @@ -733,7 +772,7 @@ END; # optional 'dmoz-like' category browser. Will be shown under the list # of categories an article belong to - if($wgUseCategoryBrowser) { + if( $wgUseCategoryBrowser ){ $s .= '

'; # get a big array of the parents tree @@ -756,7 +795,7 @@ END; * @param &skin Object: skin passed by reference * @return String separated by >, terminate with "\n" */ - function drawCategoryBrowser($tree, &$skin) { + function drawCategoryBrowser( $tree, &$skin ){ $return = ''; foreach ($tree as $element => $parent) { if (empty($parent)) { @@ -806,13 +845,13 @@ END; * * Returns an empty string by default, if not changed by any hook function. */ - protected function afterContentHook () { + protected function afterContentHook() { $data = ""; - if (wfRunHooks ('SkinAfterContent', array (&$data))) { + if( wfRunHooks( 'SkinAfterContent', array( &$data ) ) ){ // adding just some spaces shouldn't toggle the output // of the whole
, so we use trim() here - if (trim ($data) != "") { + if( trim( $data ) != '' ){ // Doing this here instead of in the skins to // ensure that the div has the same ID in all // skins @@ -821,15 +860,15 @@ END; "
\n"; } } else { - wfDebug ('Hook SkinAfterContent changed output processing.'); + wfDebug( "Hook SkinAfterContent changed output processing.\n" ); } return $data; } /** - * This gets called shortly before the \ tag. - * @return String HTML to be put before \ + * This gets called shortly before the tag. + * @return String HTML to be put before */ function afterContent() { $printfooter = "
\n" . $this->printFooter() . "
\n"; @@ -837,8 +876,8 @@ END; } /** - * This gets called shortly before the \ tag. - * @return String HTML-wrapped JS code to be put before \ + * This gets called shortly before the tag. + * @return String HTML-wrapped JS code to be put before */ function bottomScripts() { global $wgJsMimeType; @@ -860,7 +899,7 @@ END; } /** overloaded by derived classes */ - function doAfterContent() { } + function doAfterContent() { return ""; } function pageTitleLinks() { global $wgOut, $wgTitle, $wgUser, $wgRequest; diff --git a/includes/SkinTemplate.php b/includes/SkinTemplate.php index cdcbb3b124..9d766307e5 100644 --- a/includes/SkinTemplate.php +++ b/includes/SkinTemplate.php @@ -87,13 +87,6 @@ class SkinTemplate extends Skin { */ var $template; - /** - * An array of stylesheet filenames (relative from skins path), with options - * for CSS media, IE conditions, and RTL/LTR direction. - * For internal use; add settings in the skin via $this->addStyle() - */ - var $styles = array(); - /**#@-*/ /** @@ -101,16 +94,23 @@ class SkinTemplate extends Skin { * Child classes should override this to set the name, * style subdirectory, and template filler callback. * - * @param OutputPage $out + * @param $out OutputPage */ - function initPage( &$out ) { + function initPage( OutputPage $out ) { parent::initPage( $out ); $this->skinname = 'monobook'; $this->stylename = 'monobook'; $this->template = 'QuickTemplate'; + } - $this->addStyle( 'common/shared.css', 'screen' ); - $this->addStyle( 'common/commonPrint.css', 'print' ); + /** + * Add specific styles for this skin + * + * @param $out OutputPage + */ + function setupSkinUserCss( OutputPage $out ){ + $out->addStyle( 'common/shared.css', 'screen' ); + $out->addStyle( 'common/commonPrint.css', 'print' ); } /** @@ -118,9 +118,9 @@ class SkinTemplate extends Skin { * and eventually it spits out some HTML. Should have interface * roughly equivalent to PHPTAL 0.7. * - * @param string $callback (or file) - * @param string $repository subdirectory where we keep template files - * @param string $cache_dir + * @param $callback string (or file) + * @param $repository string: subdirectory where we keep template files + * @param $cache_dir string * @return object * @private */ @@ -131,11 +131,10 @@ class SkinTemplate extends Skin { /** * initialize various variables and generate the template * - * @param OutputPage $out - * @public + * @param $out OutputPage */ - function outputPage( &$out ) { - global $wgTitle, $wgArticle, $wgUser, $wgLang, $wgContLang, $wgOut; + function outputPage( OutputPage $out ) { + global $wgTitle, $wgArticle, $wgUser, $wgLang, $wgContLang; global $wgScript, $wgStylePath, $wgContLanguageCode; global $wgMimeType, $wgJsMimeType, $wgOutputEncoding, $wgRequest; global $wgXhtmlDefaultNamespace, $wgXhtmlNamespaces; @@ -153,9 +152,7 @@ class SkinTemplate extends Skin { wfProfileIn( __METHOD__."-init" ); $this->initPage( $out ); - $this->mTitle =& $wgTitle; - $this->mUser =& $wgUser; - + $this->setMembers(); $tpl = $this->setupTemplate( $this->template, 'skins' ); #if ( $wgUseDatabaseMessages ) { // uncomment this to fall back to GetText @@ -170,8 +167,6 @@ class SkinTemplate extends Skin { $this->iscontent = ($this->mTitle->getNamespace() != NS_SPECIAL ); $this->iseditable = ($this->iscontent and !($action == 'edit' or $action == 'submit')); $this->username = $wgUser->getName(); - $userPage = $wgUser->getUserPage(); - $this->userpage = $userPage->getPrefixedText(); if ( $wgUser->isLoggedIn() || $this->showIPinHeader() ) { $this->userpageUrlDetails = self::makeUrlDetails( $this->userpage ); @@ -181,16 +176,16 @@ class SkinTemplate extends Skin { $this->userpageUrlDetails = self::makeKnownUrlDetails( $this->userpage ); } - $this->usercss = $this->userjs = $this->userjsprev = false; - $this->setupUserCss( $out->getExtStyle() ); + $this->userjs = $this->userjsprev = false; + $this->setupUserCss( $out ); $this->setupUserJs( $out->isUserJsAllowed() ); $this->titletxt = $this->mTitle->getPrefixedText(); wfProfileOut( __METHOD__."-stuff" ); wfProfileIn( __METHOD__."-stuff2" ); - $tpl->set( 'title', $wgOut->getPageTitle() ); - $tpl->set( 'pagetitle', $wgOut->getHTMLTitle() ); - $tpl->set( 'displaytitle', $wgOut->mPageLinkTitle ); + $tpl->set( 'title', $out->getPageTitle() ); + $tpl->set( 'pagetitle', $out->getHTMLTitle() ); + $tpl->set( 'displaytitle', $out->mPageLinkTitle ); $tpl->set( 'pageclass', $this->getPageClasses( $this->mTitle ) ); $tpl->set( 'skinnameclass', ( "skin-" . Sanitizer::escapeClass( $this->getSkinName ( ) ) ) ); @@ -205,7 +200,7 @@ class SkinTemplate extends Skin { $tpl->set( 'articleid', $this->mTitle->getArticleId() ); $tpl->set( 'currevisionid', isset( $wgArticle ) ? $wgArticle->getLatest() : 0 ); - $tpl->set( 'isarticle', $wgOut->isArticle() ); + $tpl->set( 'isarticle', $out->isArticle() ); $tpl->setRef( "thispage", $this->thispage ); $subpagestr = $this->subPageSubtitle(); @@ -222,9 +217,9 @@ class SkinTemplate extends Skin { ); $tpl->set( 'catlinks', $this->getCategories()); - if( $wgOut->isSyndicated() ) { + if( $out->isSyndicated() ) { $feeds = array(); - foreach( $wgOut->getSyndicationLinks() as $format => $link ) { + foreach( $out->getSyndicationLinks() as $format => $link ) { $feeds[$format] = array( 'text' => wfMsg( "feed-$format" ), 'href' => $link ); @@ -245,14 +240,14 @@ class SkinTemplate extends Skin { $tpl->setRef( 'jsmimetype', $wgJsMimeType ); $tpl->setRef( 'charset', $wgOutputEncoding ); $tpl->set( 'headlinks', $out->getHeadLinks() ); - $tpl->set('headscripts', $out->getScript() ); + $tpl->set( 'headscripts', $out->getScript() ); + $tpl->set( 'csslinks', $out->buildCssLinks() ); $tpl->setRef( 'wgScript', $wgScript ); $tpl->setRef( 'skinname', $this->skinname ); $tpl->set( 'skinclass', get_class( $this ) ); $tpl->setRef( 'stylename', $this->stylename ); $tpl->set( 'printable', $wgRequest->getBool( 'printable' ) ); $tpl->set( 'handheld', $wgRequest->getBool( 'handheld' ) ); - $tpl->set( 'csslinks', $this->buildCssLinks() ); $tpl->setRef( 'loggedin', $this->loggedin ); $tpl->set('notspecialpage', $this->mTitle->getNamespace() != NS_SPECIAL); /* XXX currently unused, might get useful later @@ -310,7 +305,7 @@ class SkinTemplate extends Skin { ) ); # Disable Cache - $wgOut->setSquidMaxage(0); + $out->setSquidMaxage(0); } } else if (count($newtalks)) { $sep = str_replace("_", " ", wfMsgHtml("newtalkseperator")); @@ -321,7 +316,7 @@ class SkinTemplate extends Skin { } $parts = implode($sep, $msgs); $ntl = wfMsgHtml('youhavenewmessagesmulti', $parts); - $wgOut->setSquidMaxage(0); + $out->setSquidMaxage(0); } else { $ntl = ''; } @@ -331,7 +326,7 @@ class SkinTemplate extends Skin { $tpl->setRef( 'newtalk', $ntl ); $tpl->setRef( 'skin', $this ); $tpl->set( 'logo', $this->logoText() ); - if ( $wgOut->isArticle() and (!isset( $oldid ) or isset( $diff )) and + if ( $out->isArticle() and (!isset( $oldid ) or isset( $diff )) and $wgArticle and 0 != $wgArticle->getID() ) { if ( !$wgDisableCounters ) { @@ -413,7 +408,7 @@ class SkinTemplate extends Skin { $language_urls = array(); if ( !$wgHideInterlanguageLinks ) { - foreach( $wgOut->getLanguageLinks() as $l ) { + foreach( $out->getLanguageLinks() as $l ) { $tmp = explode( ':', $l, 2 ); $class = 'interwiki-' . $tmp[0]; unset($tmp); @@ -650,7 +645,7 @@ class SkinTemplate extends Skin { * @return array * @private */ - function buildContentActionUrls () { + function buildContentActionUrls() { global $wgContLang, $wgLang, $wgOut; wfProfileIn( __METHOD__ ); @@ -846,7 +841,7 @@ class SkinTemplate extends Skin { * @return array * @private */ - function buildNavUrls () { + function buildNavUrls() { global $wgUseTrackbacks, $wgTitle, $wgUser, $wgRequest; global $wgEnableUploads, $wgUploadNavigationUrl; @@ -961,74 +956,10 @@ class SkinTemplate extends Skin { * @return string * @private */ - function getNameSpaceKey () { + function getNameSpaceKey() { return $this->mTitle->getNamespaceKey(); } - /** - * @private - */ - function setupUserCss( $extCSS = array() ) { - global $wgRequest, $wgAllowUserCss, $wgUseSiteCss, $wgContLang, $wgSquidMaxage, $wgStylePath, $wgUser; - - wfProfileIn( __METHOD__ ); - - $siteargs = array( - 'action' => 'raw', - 'maxage' => $wgSquidMaxage, - ); - if( $this->loggedin ) { - // Ensure that logged-in users' generated CSS isn't clobbered - // by anons' publicly cacheable generated CSS. - $siteargs['smaxage'] = '0'; - $siteargs['ts'] = $wgUser->mTouched; - } - - // Add any extension CSS - foreach( $extCSS as $tag ) { - $this->addStyle( $tag['href'] ); - } - - // If we use the site's dynamic CSS, throw that in, too - // Per-site custom styles - if ( $wgUseSiteCss ) { - $query = wfArrayToCGI( array( - 'usemsgcache' => 'yes', - 'ctype' => 'text/css', - 'smaxage' => $wgSquidMaxage - ) + $siteargs ); - $this->addStyle( self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) ); - $this->addStyle( self::makeNSUrl( ucfirst( $this->skinname ) . '.css', $query, NS_MEDIAWIKI ), - 'screen' ); - } - - // Per-user styles based on preferences - $siteargs['gen'] = 'css'; - if( ( $us = $wgRequest->getVal( 'useskin', '' ) ) !== '' ) - $siteargs['useskin'] = $us; - $this->addStyle( self::makeUrl( '-', wfArrayToCGI( $siteargs ) ), 'screen' ); - - // Per-user custom style pages - if ( $wgAllowUserCss && $this->loggedin ) { - $action = $wgRequest->getVal('action'); - - # if we're previewing the CSS page, use it - if( $this->mTitle->isCssSubpage() && $this->userCanPreview( $action ) ) { - $previewCss = $wgRequest->getText('wpTextbox1'); - - /// @fixme properly escape the cdata! - $this->usercss = "/**/"; - } else { - $this->addStyle( self::makeUrl($this->userpage . '/'.$this->skinname.'.css', - 'action=raw&ctype=text/css'), 'screen' ); - } - } - - wfProfileOut( __METHOD__ ); - } - /** * @private */ @@ -1059,165 +990,9 @@ class SkinTemplate extends Skin { wfProfileIn( __METHOD__ ); $out = false; wfRunHooks( 'SkinTemplateSetupPageCss', array( &$out ) ); - wfProfileOut( __METHOD__ ); return $out; } - - /** - * returns css with user-specific options - */ - public function getUserStylesheet() { - wfProfileIn( __METHOD__ ); - - $s = "/* generated user stylesheet */\n"; - $s .= $this->reallyDoGetUserStyles(); - wfProfileOut( __METHOD__ ); - return $s; - } - - /** - * This returns MediaWiki:Common.js and MediaWiki:[Skinname].js concate- - * nated together. For some bizarre reason, it does *not* return any - * custom user JS from subpages. Huh? - * - * There's absolutely no reason to have separate Monobook/Common JSes. - * Any JS that cares can just check the skin variable generated at the - * top. For now Monobook.js will be maintained, but it should be consi- - * dered deprecated. - * - * @return string - */ - public function getUserJs() { - wfProfileIn( __METHOD__ ); - - $s = parent::getUserJs(); - $s .= "\n\n/* MediaWiki:".ucfirst($this->skinname).".js */\n"; - - // avoid inclusion of non defined user JavaScript (with custom skins only) - // by checking for default message content - $msgKey = ucfirst($this->skinname).'.js'; - $userJS = wfMsgForContent($msgKey); - if ( !wfEmptyMsg( $msgKey, $userJS ) ) { - $s .= $userJS; - } - - wfProfileOut( __METHOD__ ); - return $s; - } - - /** - * Add a local or specified stylesheet, with the given media options. - * Meant primarily for internal use... - * - * @param $media -- to specify a media type, 'screen', 'printable', 'handheld' or any. - * @param $conditional -- for IE conditional comments, specifying an IE version - * @param $dir -- set to 'rtl' or 'ltr' for direction-specific sheets - */ - public function addStyle( $style, $media='', $condition='', $dir='' ) { - $options = array(); - if( $media ) - $options['media'] = $media; - if( $condition ) - $options['condition'] = $condition; - if( $dir ) - $options['dir'] = $dir; - $this->styles[$style] = $options; - } - - /** - * Build a set of s for the stylesheets specified in the $this->styles array. - * These will be applied to various media & IE conditionals. - */ - protected function buildCssLinks() { - $links = array(); - foreach( $this->styles as $file => $options ) { - $link = $this->styleLink( $file, $options ); - if( $link ) - $links[] = $link; - } - - return implode( "\n\t\t", $links ); - } - - protected function styleLink( $style, $options ) { - global $wgRequest; - - if( isset( $options['dir'] ) ) { - global $wgContLang; - $siteDir = $wgContLang->isRTL() ? 'rtl' : 'ltr'; - if( $siteDir != $options['dir'] ) - return ''; - } - - if( isset( $options['media'] ) ) { - $media = $this->transformCssMedia( $options['media'] ); - if( is_null( $media ) ) { - return ''; - } - } else { - $media = ''; - } - - if( substr( $style, 0, 1 ) == '/' || - substr( $style, 0, 5 ) == 'http:' || - substr( $style, 0, 6 ) == 'https:' ) { - $url = $style; - } else { - global $wgStylePath, $wgStyleVersion; - $url = $wgStylePath . '/' . $style . '?' . $wgStyleVersion; - } - - $attribs = array( - 'rel' => 'stylesheet', - 'href' => $url, - 'type' => 'text/css' ); - if( $media ) { - $attribs['media'] = $media; - } - - $link = Xml::element( 'link', $attribs ); - - if( isset( $options['condition'] ) ) { - $condition = htmlspecialchars( $options['condition'] ); - $link = ""; - } - return $link; - } - - function transformCssMedia( $media ) { - global $wgRequest, $wgHandheldForIPhone; - - // Switch in on-screen display for media testing - $switches = array( - 'printable' => 'print', - 'handheld' => 'handheld', - ); - foreach( $switches as $switch => $targetMedia ) { - if( $wgRequest->getBool( $switch ) ) { - if( $media == $targetMedia ) { - $media = ''; - } elseif( $media == 'screen' ) { - return null; - } - } - } - - // Expand longer media queries as iPhone doesn't grok 'handheld' - if( $wgHandheldForIPhone ) { - $mediaAliases = array( - 'screen' => 'screen and (min-device-width: 481px)', - 'handheld' => 'handheld, only screen and (max-device-width: 480px)', - ); - - if( isset( $mediaAliases[$media] ) ) { - $media = $mediaAliases[$media]; - } - } - - return $media; - } - } /** diff --git a/skins/Chick.php b/skins/Chick.php index 1ad6c7e1a4..a95a72cea4 100644 --- a/skins/Chick.php +++ b/skins/Chick.php @@ -18,17 +18,20 @@ require_once( dirname(__FILE__) . '/MonoBook.php' ); * @ingroup Skins */ class SkinChick extends SkinTemplate { - function initPage( &$out ) { + function initPage( OutputPage $out ) { SkinTemplate::initPage( $out ); $this->skinname = 'chick'; $this->stylename = 'chick'; $this->template = 'MonoBookTemplate'; + } + function setupSkinUserCss( OutputPage $out ){ + parent::setupSkinUserCss( $out ); // Append to the default screen common & print styles... - $this->addStyle( 'chick/main.css', 'screen,handheld' ); - $this->addStyle( 'chick/IE50Fixes.css', 'screen,handheld', 'lt IE 5.5000' ); - $this->addStyle( 'chick/IE55Fixes.css', 'screen,handheld', 'IE 5.5000' ); - $this->addStyle( 'chick/IE60Fixes.css', 'screen,handheld', 'IE 6' ); + $out->addStyle( 'chick/main.css', 'screen,handheld' ); + $out->addStyle( 'chick/IE50Fixes.css', 'screen,handheld', 'lt IE 5.5000' ); + $out->addStyle( 'chick/IE55Fixes.css', 'screen,handheld', 'IE 5.5000' ); + $out->addStyle( 'chick/IE60Fixes.css', 'screen,handheld', 'IE 6' ); } } diff --git a/skins/CologneBlue.php b/skins/CologneBlue.php index 29addfc935..797396223e 100644 --- a/skins/CologneBlue.php +++ b/skins/CologneBlue.php @@ -96,9 +96,8 @@ class SkinCologneBlue extends Skin { return $s; } - function doGetUserStyles() { - global $wgOut; - $s = parent::doGetUserStyles(); + function reallyGenerateUserStylesheet() { + $s = parent::reallyGenerateUserStylesheet(); $qb = $this->qbSetting(); if ( 2 == $qb ) { # Right diff --git a/skins/Modern.php b/skins/Modern.php index d37086cc0e..d0e6066849 100644 --- a/skins/Modern.php +++ b/skins/Modern.php @@ -25,15 +25,18 @@ class SkinModern extends SkinTemplate { return "
Powered by MediaWiki $wgVersion
"; } - function initPage( &$out ) { - Skin::initPage( $out ); + function initPage( OutputPage $out ) { + parent::initPage( $out ); $this->skinname = 'modern'; $this->stylename = 'modern'; $this->template = 'ModernTemplate'; - - $this->addStyle( 'common/shared.css', 'screen' ); - $this->addStyle( 'modern/main.css', 'screen' ); - $this->addStyle( 'modern/print.css', 'print' ); + } + + function setupSkinUserCss( OutputPage $out ){ + // Do not call parent::setupSkinUserCss(), we have our own print style + $out->addStyle( 'common/shared.css', 'screen' ); + $out->addStyle( 'modern/main.css', 'screen' ); + $out->addStyle( 'modern/print.css', 'print' ); } } diff --git a/skins/MonoBook.php b/skins/MonoBook.php index 2c02d684a0..db77791260 100644 --- a/skins/MonoBook.php +++ b/skins/MonoBook.php @@ -20,27 +20,32 @@ if( !defined( 'MEDIAWIKI' ) ) */ class SkinMonoBook extends SkinTemplate { /** Using monobook. */ - function initPage( &$out ) { - global $wgHandheldStyle; - - SkinTemplate::initPage( $out ); + function initPage( OutputPage $out ) { + parent::initPage( $out ); $this->skinname = 'monobook'; $this->stylename = 'monobook'; $this->template = 'MonoBookTemplate'; + } + + function setupSkinUserCss( OutputPage $out ) { + global $wgHandheldStyle; + + parent::setupSkinUserCss( $out ); + // Append to the default screen common & print styles... - $this->addStyle( 'monobook/main.css', 'screen' ); + $out->addStyle( 'monobook/main.css', 'screen' ); if( $wgHandheldStyle ) { // Currently in testing... try 'chick/main.css' - $this->addStyle( $wgHandheldStyle, 'handheld' ); + $out->addStyle( $wgHandheldStyle, 'handheld' ); } - $this->addStyle( 'monobook/IE50Fixes.css', 'screen', 'lt IE 5.5000' ); - $this->addStyle( 'monobook/IE55Fixes.css', 'screen', 'IE 5.5000' ); - $this->addStyle( 'monobook/IE60Fixes.css', 'screen', 'IE 6' ); - $this->addStyle( 'monobook/IE70Fixes.css', 'screen', 'IE 7' ); + $out->addStyle( 'monobook/IE50Fixes.css', 'screen', 'lt IE 5.5000' ); + $out->addStyle( 'monobook/IE55Fixes.css', 'screen', 'IE 5.5000' ); + $out->addStyle( 'monobook/IE60Fixes.css', 'screen', 'IE 6' ); + $out->addStyle( 'monobook/IE70Fixes.css', 'screen', 'IE 7' ); - $this->addStyle( 'monobook/rtl.css', 'screen', '', 'rtl' ); + $out->addStyle( 'monobook/rtl.css', 'screen', '', 'rtl' ); } } diff --git a/skins/MySkin.php b/skins/MySkin.php index 90fb534904..460984540b 100644 --- a/skins/MySkin.php +++ b/skins/MySkin.php @@ -10,20 +10,15 @@ if( !defined( 'MEDIAWIKI' ) ) die( -1 ); -/** */ -require_once( dirname(__FILE__) . '/MonoBook.php' ); - /** * @todo document * @ingroup Skins */ class SkinMySkin extends SkinTemplate { - function initPage( &$out ) { - SkinTemplate::initPage( $out ); + function initPage( OutputPage $out ) { + parent::initPage( $out ); $this->skinname = 'myskin'; $this->stylename = 'myskin'; $this->template = 'MonoBookTemplate'; } } - - diff --git a/skins/Simple.php b/skins/Simple.php index d8af7ed632..b26f50d024 100644 --- a/skins/Simple.php +++ b/skins/Simple.php @@ -18,17 +18,20 @@ require_once( dirname(__FILE__) . '/MonoBook.php' ); * @ingroup Skins */ class SkinSimple extends SkinTemplate { - function initPage( &$out ) { + function initPage( OutputPage $out ) { SkinTemplate::initPage( $out ); $this->skinname = 'simple'; $this->stylename = 'simple'; $this->template = 'MonoBookTemplate'; - $this->addStyle( 'simple/main.css', 'screen' ); - $this->addStyle( 'simple/rtl.css', '', '', 'rtl' ); + } + + function setupSkinUserCss( OutputPage $out ){ + $out->addStyle( 'simple/main.css', 'screen' ); + $out->addStyle( 'simple/rtl.css', '', '', 'rtl' ); } - function reallyDoGetUserStyles() { + function reallyGenerateUserStylesheet() { global $wgUser; $s = ''; if (($undopt = $wgUser->getOption("underline")) != 2) { diff --git a/skins/Standard.php b/skins/Standard.php index 87a151faba..9b65de718e 100644 --- a/skins/Standard.php +++ b/skins/Standard.php @@ -33,27 +33,20 @@ class SkinStandard extends Skin { /** * */ - function getUserStyles() { - global $wgStylePath, $wgStyleVersion; - $s = ''; + function setupSkinUserCss( OutputPage $out ){ if ( 3 == $this->qbSetting() ) { # Floating left - $s .= "\n"; + $out->addStyle( 'common/quickbar.css' ); } else if ( 4 == $this->qbSetting() ) { # Floating right - $s .= "\n"; + $out->addStyle( 'common/quickbar-right.css' ); } - $s .= parent::getUserStyles(); - return $s; + parent::setupSkinUserCss( $out ); } /** * */ - function doGetUserStyles() { - global $wgStylePath; - - $s = parent::doGetUserStyles(); + function reallyGenerateUserStylesheet() { + $s = parent::reallyGenerateUserStylesheet(); $qb = $this->qbSetting(); if ( 2 == $qb ) { # Right @@ -273,7 +266,7 @@ class SkinStandard extends Skin { $id=User::idFromName($wgTitle->getText()); $ip=User::isIP($wgTitle->getText()); - if($id||$ip) { + if( $id || $ip ){ $s .= $sep . $this->userContribsLink(); } if( $this->showEmailUser( $id ) ) { @@ -302,5 +295,3 @@ class SkinStandard extends Skin { } - - -- 2.20.1
\n" . $this->logoText() . '