Reduce a bit the coupling between Skin and OutputPage:
authorAlexandre Emsenhuber <ialex@users.mediawiki.org>
Fri, 22 Jul 2011 10:45:07 +0000 (10:45 +0000)
committerAlexandre Emsenhuber <ialex@users.mediawiki.org>
Fri, 22 Jul 2011 10:45:07 +0000 (10:45 +0000)
* Removed Skin::setupUserCss() and merged it in OutputPage::buildCssLinks() and OutputPage::buildCssLinksArray(), also removed its call from ApiParse.php
* Moved Skin::userCanPreview() to OutputPage since two of the three calls to that function are made from there and the last one in SkinTemplate.php is in a somewhat deprecated function
* Removed the Skin parameter from OutputPage::buildCssLinks(), OutputPage::getHeadScripts(), OutputPage::getBottomScripts() and OutputPage::makeResourceLoaderLink() since we now have a context

Also made ApiParse.php call createContext() instead of create a new RequestContext manually and set its Title  so so that it does not rely on $wgRequest and $wgTitle to get that member objects

includes/OutputPage.php
includes/Skin.php
includes/SkinTemplate.php
includes/api/ApiParse.php

index 2ce48f4..aa80c2d 100644 (file)
@@ -2269,7 +2269,6 @@ $templates
                if ( $sk->commonPrintStylesheet() ) {
                        $this->addModuleStyles( 'mediawiki.legacy.wikiprintable' );
                }
-               $sk->setupUserCss( $this );
 
                $ret = Html::htmlHeader( array( 'lang' => $wgLang->getCode(), 'dir' => $userdir ) );
 
@@ -2286,9 +2285,9 @@ $templates
                $ret .= Html::element( 'title', null, $this->getHTMLTitle() ) . "\n";
 
                $ret .= implode( "\n", array(
-                       $this->getHeadLinks( $sk, true ),
-                       $this->buildCssLinks( $sk ),
-                       $this->getHeadScripts( $sk ),
+                       $this->getHeadLinks( null, true ),
+                       $this->buildCssLinks(),
+                       $this->getHeadScripts(),
                        $this->getHeadItems()
                ) );
 
@@ -2397,13 +2396,12 @@ $templates
 
        /**
         * TODO: Document
-        * @param $skin Skin
         * @param $modules Array/string with the module name
         * @param $only String ResourceLoaderModule TYPE_ class constant
         * @param $useESI boolean
         * @return string html <script> and <style> tags
         */
-       protected function makeResourceLoaderLink( Skin $skin, $modules, $only, $useESI = false ) {
+       protected function makeResourceLoaderLink( $modules, $only, $useESI = false ) {
                global $wgLoadScript, $wgResourceLoaderUseESI,
                        $wgResourceLoaderInlinePrivateModules;
                // Lazy-load ResourceLoader
@@ -2411,7 +2409,7 @@ $templates
                $baseQuery = array(
                        'lang' => $this->getContext()->getLang()->getCode(),
                        'debug' => ResourceLoader::inDebugMode() ? 'true' : 'false',
-                       'skin' => $skin->getSkinName(),
+                       'skin' => $this->getSkin()->getSkinName(),
                        'only' => $only,
                );
                // Propagate printable and handheld parameters if present
@@ -2436,7 +2434,7 @@ $templates
                                // Recursively call us for every item
                                $links = '';
                                foreach ( $modules as $name ) {
-                                       $links .= $this->makeResourceLoaderLink( $skin, $name, $only, $useESI );
+                                       $links .= $this->makeResourceLoaderLink( $name, $only, $useESI );
                                }
                                return $links;
                        }
@@ -2501,6 +2499,7 @@ $templates
                                                )
                                        );
                                }
+                               $links .= "\n";
                                continue;
                        }
                        // Special handling for the user group; because users might change their stuff
@@ -2553,12 +2552,11 @@ $templates
         * JS stuff to put in the <head>. This is the startup module, config
         * vars and modules marked with position 'top'
         *
-        * @param $sk Skin object to use
         * @return String: HTML fragment
         */
-       function getHeadScripts( Skin $sk ) {
+       function getHeadScripts() {
                // Startup - this will immediately load jquery and mediawiki modules
-               $scripts = $this->makeResourceLoaderLink( $sk, 'startup', ResourceLoaderModule::TYPE_SCRIPTS, true );
+               $scripts = $this->makeResourceLoaderLink( 'startup', ResourceLoaderModule::TYPE_SCRIPTS, true );
 
                // Load config before anything else
                $scripts .= Html::inlineScript(
@@ -2569,8 +2567,8 @@ $templates
 
                // Script and Messages "only" requests marked for top inclusion
                // Messages should go first
-               $scripts .= $this->makeResourceLoaderLink( $sk, $this->getModuleMessages( true, 'top' ), ResourceLoaderModule::TYPE_MESSAGES );
-               $scripts .= $this->makeResourceLoaderLink( $sk, $this->getModuleScripts( true, 'top' ), ResourceLoaderModule::TYPE_SCRIPTS );
+               $scripts .= $this->makeResourceLoaderLink( $this->getModuleMessages( true, 'top' ), ResourceLoaderModule::TYPE_MESSAGES );
+               $scripts .= $this->makeResourceLoaderLink( $this->getModuleScripts( true, 'top' ), ResourceLoaderModule::TYPE_SCRIPTS );
 
                // Modules requests - let the client calculate dependencies and batch requests as it likes
                // Only load modules that have marked themselves for loading at the top
@@ -2590,17 +2588,15 @@ $templates
         * JS stuff to put at the bottom of the <body>: modules marked with position 'bottom',
         * legacy scripts ($this->mScripts), user preferences, site JS and user JS
         *
-        * @param $sk Skin
-        *
         * @return string
         */
-       function getBottomScripts( Skin $sk ) {
+       function getBottomScripts() {
                global $wgUseSiteJs, $wgAllowUserJs;
 
                // Script and Messages "only" requests marked for bottom inclusion
                // Messages should go first
-               $scripts = $this->makeResourceLoaderLink( $sk, $this->getModuleMessages( true, 'bottom' ), ResourceLoaderModule::TYPE_MESSAGES );
-               $scripts .= $this->makeResourceLoaderLink( $sk, $this->getModuleScripts( true, 'bottom' ), ResourceLoaderModule::TYPE_SCRIPTS );
+               $scripts = $this->makeResourceLoaderLink( $this->getModuleMessages( true, 'bottom' ), ResourceLoaderModule::TYPE_MESSAGES );
+               $scripts .= $this->makeResourceLoaderLink( $this->getModuleScripts( true, 'bottom' ), ResourceLoaderModule::TYPE_SCRIPTS );
 
                // Modules requests - let the client calculate dependencies and batch requests as it likes
                // Only load modules that have marked themselves for loading at the bottom
@@ -2620,7 +2616,7 @@ $templates
 
                // Add site JS if enabled
                if ( $wgUseSiteJs ) {
-                       $scripts .= $this->makeResourceLoaderLink( $sk, 'site', ResourceLoaderModule::TYPE_SCRIPTS );
+                       $scripts .= $this->makeResourceLoaderLink( 'site', ResourceLoaderModule::TYPE_SCRIPTS );
                        if( $this->getUser()->isLoggedIn() ){
                                $userScripts[] = 'user.groups';
                        }
@@ -2628,7 +2624,7 @@ $templates
 
                // Add user JS if enabled
                if ( $wgAllowUserJs && $this->getUser()->isLoggedIn() ) {
-                       if( $this->getTitle() && $this->getTitle()->isJsSubpage() && $sk->userCanPreview() ) {
+                       if( $this->getTitle() && $this->getTitle()->isJsSubpage() && $this->userCanPreview() ) {
                                # XXX: additional security check/prompt?
                                $scripts .= Html::inlineScript( "\n" . $this->getRequest()->getText( 'wpTextbox1' ) . "\n" ) . "\n";
                        } else {
@@ -2637,7 +2633,7 @@ $templates
                                $userScripts[] = 'user';
                        }
                }
-               $scripts .= $this->makeResourceLoaderLink( $sk, $userScripts, ResourceLoaderModule::TYPE_SCRIPTS );
+               $scripts .= $this->makeResourceLoaderLink( $userScripts, ResourceLoaderModule::TYPE_SCRIPTS );
 
                return $scripts;
        }
@@ -2697,12 +2693,36 @@ $templates
        }
 
        /**
-        * @param $sk Skin
+        * To make it harder for someone to slip a user a fake
+        * user-JavaScript or user-CSS preview, a random token
+        * is associated with the login session. If it's not
+        * passed back with the preview request, we won't render
+        * the code.
+        *
+        * @return bool
+        */
+       public function userCanPreview() {
+               if ( $this->getRequest()->getVal( 'action' ) != 'submit'
+                       || !$this->getRequest()->wasPosted()
+                       || !$this->getUser()->matchEditToken(
+                               $this->getRequest()->getVal( 'wpEditToken' ) )
+               ) {
+                       return false;
+               }
+               if ( !$this->getTitle()->isJsSubpage() && !$this->getTitle()->isCssSubpage() ) {
+                       return false;
+               }
+
+               return !count( $this->getTitle()->getUserPermissionsErrors( 'edit', $this->getUser() ) );
+       }
+
+       /**
+        * @param $unused Unused
         * @param $addContentType bool
         *
         * @return string HTML tag links to be put in the header.
         */
-       public function getHeadLinks( Skin $sk, $addContentType = false ) {
+       public function getHeadLinks( $unused = null, $addContentType = false ) {
                global $wgUniversalEditButton, $wgFavicon, $wgAppleTouchIcon, $wgEnableAPI,
                        $wgSitename, $wgVersion, $wgHtml5, $wgMimeType,
                        $wgFeed, $wgOverrideSiteFeed, $wgAdvertisedFeedTypes,
@@ -2974,17 +2994,46 @@ $templates
        /**
         * Build a set of <link>s for the stylesheets specified in the $this->styles array.
         * These will be applied to various media & IE conditionals.
-        * @param $sk Skin object
         *
         * @return string
         */
-       public function buildCssLinks( $sk ) {
-               $ret = '';
+       public function buildCssLinks() {
+               global $wgUseSiteCss, $wgAllowUserCss, $wgAllowUserCssPrefs;
+
+               $this->getSkin()->setupSkinUserCss( $this );
+
                // Add ResourceLoader styles
                // Split the styles into four groups
                $styles = array( 'other' => array(), 'user' => array(), 'site' => array(), 'private' => array(), 'noscript' => array() );
                $resourceLoader = $this->getResourceLoader();
-               foreach ( $this->getModuleStyles() as $name ) {
+
+               $moduleStyles = $this->getModuleStyles();
+
+               // Per-site custom styles
+               if ( $wgUseSiteCss ) {
+                       $moduleStyles[] = 'site';
+                       $moduleStyles[] = 'noscript';
+                       if( $this->getUser()->isLoggedIn() ){
+                               $moduleStyles[] = 'user.groups';
+                       }
+               }
+
+               // Per-user custom styles
+               if ( $wgAllowUserCss ) {
+                       if ( $this->getTitle()->isCssSubpage() && $this->userCanPreview() ) {
+                               // @todo FIXME: Properly escape the cdata!
+                               $out->addInlineStyle( $this->getRequest()->getText( 'wpTextbox1' ) );
+                       } else {
+                               $moduleStyles[] = 'user';
+                       }
+               }
+
+               // Per-user preference styles
+               if ( $wgAllowUserCssPrefs ) {
+                       $moduleStyles[] = 'user.options';
+               }
+
+               foreach ( $moduleStyles as $name ) {
                        $group = $resourceLoader->getModule( $name )->getGroup();
                        // Modules in groups named "other" or anything different than "user", "site" or "private"
                        // will be placed in the "other" group
@@ -2995,7 +3044,7 @@ $templates
                // dynamically added styles to override statically added styles from other modules. So the order
                // has to be other, dynamic, site, private, user
                // Add statically added styles for other modules
-               $ret .= $this->makeResourceLoaderLink( $sk, $styles['other'], ResourceLoaderModule::TYPE_STYLES );
+               $ret = $this->makeResourceLoaderLink( $styles['other'], ResourceLoaderModule::TYPE_STYLES );
                // Add normal styles added through addStyle()/addInlineStyle() here
                $ret .= implode( "\n", $this->buildCssLinksArray() ) . $this->mInlineStyles;
                // Add marker tag to mark the place where the client-side loader should inject dynamic styles
@@ -3006,7 +3055,7 @@ $templates
                // 'private' at present only contains user.options, so put that before 'user'
                // Any future private modules will likely have a similar user-specific character
                foreach ( array( 'site', 'noscript', 'private', 'user' ) as $group ) {
-                       $ret .= $this->makeResourceLoaderLink( $sk, $styles[$group],
+                       $ret .= $this->makeResourceLoaderLink( $styles[$group],
                                        ResourceLoaderModule::TYPE_STYLES
                        );
                }
@@ -3015,6 +3064,13 @@ $templates
 
        public function buildCssLinksArray() {
                $links = array();
+
+               // Add any extension CSS
+               foreach ( $this->mExtStyles as $url ) {
+                       $this->addStyle( $url );
+               }
+               $this->mExtStyles = array();
+
                foreach( $this->styles as $file => $options ) {
                        $link = $this->styleLink( $file, $options );
                        if( $link ) {
index b0858c6..ae98951 100644 (file)
@@ -307,30 +307,6 @@ abstract class Skin extends ContextSource {
                }
        }
 
-       /**
-        * To make it harder for someone to slip a user a fake
-        * user-JavaScript or user-CSS preview, a random token
-        * is associated with the login session. If it's not
-        * passed back with the preview request, we won't render
-        * the code.
-        *
-        * @return bool
-        */
-       public function userCanPreview() {
-               if ( $this->getRequest()->getVal( 'action' ) != 'submit'
-                       || !$this->getRequest()->wasPosted()
-                       || !$this->getUser()->matchEditToken(
-                               $this->getRequest()->getVal( 'wpEditToken' ) )
-               ) {
-                       return false;
-               }
-               if ( !$this->getTitle()->isJsSubpage() && !$this->getTitle()->isCssSubpage() ) {
-                       return false;
-               }
-
-               return !count( $this->getTitle()->getUserPermissionsErrors( 'edit', $this->getUser() ) );
-       }
-
        /**
         * Generated JavaScript action=raw&gen=js
         * This used to load MediaWiki:Common.js and the skin-specific style
@@ -356,48 +332,6 @@ abstract class Skin extends ContextSource {
                return '';
        }
 
-       /**
-        * @private
-        * @todo document
-        * @param $out OutputPage
-        */
-       function setupUserCss( OutputPage $out ) {
-               global $wgUseSiteCss, $wgAllowUserCss, $wgAllowUserCssPrefs;
-
-               wfProfileIn( __METHOD__ );
-
-               $this->setupSkinUserCss( $out );
-               // Add any extension CSS
-               foreach ( $out->getExtStyle() as $url ) {
-                       $out->addStyle( $url );
-               }
-
-               // Per-site custom styles
-               if ( $wgUseSiteCss ) {
-                       $out->addModuleStyles( array( 'site', 'noscript' ) );
-                       if( $this->getUser()->isLoggedIn() ){
-                               $out->addModuleStyles( 'user.groups' );
-                       }
-               }
-
-               // Per-user custom styles
-               if ( $wgAllowUserCss ) {
-                       if ( $this->getTitle()->isCssSubpage() && $this->userCanPreview() ) {
-                               // @todo FIXME: Properly escape the cdata!
-                               $out->addInlineStyle( $this->getRequest()->getText( 'wpTextbox1' ) );
-                       } else {
-                               $out->addModuleStyles( 'user' );
-                       }
-               }
-
-               // Per-user preference styles
-               if ( $wgAllowUserCssPrefs ) {
-                       $out->addModuleStyles( 'user.options' );
-               }
-
-               wfProfileOut( __METHOD__ );
-       }
-
        /**
         * Get the query to generate a dynamic stylesheet
         *
@@ -695,7 +629,7 @@ abstract class Skin extends ContextSource {
                // TODO and the suckage continues. This function is really just a wrapper around
                // OutputPage::getBottomScripts() which takes a Skin param. This should be cleaned
                // up at some point
-               $bottomScriptText = $out->getBottomScripts( $this );
+               $bottomScriptText = $out->getBottomScripts();
                wfRunHooks( 'SkinAfterBottomScripts', array( $this, &$bottomScriptText ) );
 
                return $bottomScriptText;
index aa04445..18fab0c 100644 (file)
@@ -208,8 +208,8 @@ class SkinTemplate extends Skin {
                        $tpl->setRef( 'xhtmldefaultnamespace', $wgXhtmlDefaultNamespace );
                        $tpl->set( 'xhtmlnamespaces', $wgXhtmlNamespaces );
                        $tpl->set( 'html5version', $wgHtml5Version );
-                       $tpl->set( 'headlinks', $out->getHeadLinks( $this ) );
-                       $tpl->set( 'csslinks', $out->buildCssLinks( $this ) );
+                       $tpl->set( 'headlinks', $out->getHeadLinks() );
+                       $tpl->set( 'csslinks', $out->buildCssLinks() );
 
                        if( $wgUseTrackbacks && $out->isArticleRelated() ) {
                                $tpl->set( 'trackbackhtml', $out->getTitle()->trackbackRDF() );
@@ -1278,7 +1278,7 @@ class SkinTemplate extends Skin {
                wfProfileIn( __METHOD__ );
 
                if( $allowUserJs && $this->loggedin ) {
-                       if( $this->getTitle()->isJsSubpage() and $this->userCanPreview() ) {
+                       if( $this->getTitle()->isJsSubpage() and $this->getOutput()->userCanPreview() ) {
                                # XXX: additional security check/prompt?
                                $this->userjsprev = '/*<![CDATA[*/ ' . $wgRequest->getText( 'wpTextbox1' ) . ' /*]]>*/';
                        } else {
index 8311bd6..6450917 100644 (file)
@@ -253,16 +253,16 @@ class ApiParse extends ApiBase {
                }
 
                if ( isset( $prop['headitems'] ) || isset( $prop['headhtml'] ) ) {
-                       $context = new RequestContext;
+                       $context = $this->createContext();
+                       $context->setTitle( $titleObj );
                        $context->getOutput()->addParserOutputNoText( $p_result );
 
                        if ( isset( $prop['headitems'] ) ) {
                                $headItems = $this->formatHeadItems( $p_result->getHeadItems() );
 
-                               $context->getSkin()->setupUserCss( $context->getOutput() );
                                $css = $this->formatCss( $context->getOutput()->buildCssLinksArray() );
 
-                               $scripts = array( $context->getOutput()->getHeadScripts( $context->getSkin() ) );
+                               $scripts = array( $context->getOutput()->getHeadScripts() );
 
                                $result_array['headitems'] = array_merge( $headItems, $css, $scripts );
                        }