Reduce a bit the coupling between Skin and OutputPage:
* 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
This commit is contained in:
parent
1159d6cdf1
commit
e78acdc3f1
4 changed files with 92 additions and 102 deletions
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue