Major refactoring of site and user CSS, creating ResourceLoaderUserModule and ResourceLoaderUserPreferenceModule. Also moved as much of the global variables being generated in Skin::makeGlobalVaiablesScript into the ResourceLoaderStartupModule - which will make configuration changes effective site-wide in 5 minutes instead of whenever all pages are purged from cache - what remains embedded in the HTML is article and user specific - two things we don't know by the time we request the startup module. Also, fixed issue where debug=false was being interpreted to be equivilant to debug=true. Finally, finished integrating the introduction of $wgLoadScript, thus fixing overlooked issues in r72763.

This commit is contained in:
Trevor Parscal 2010-09-11 03:26:15 +00:00
parent af26088bd9
commit a99f9ec28b
7 changed files with 279 additions and 295 deletions

View file

@ -2283,19 +2283,33 @@ class OutputPage {
static function makeResourceLoaderLink( $skin, $modules, $only ) {
global $wgUser, $wgLang, $wgRequest, $wgLoadScript;
// TODO: Should this be a static function of ResourceLoader instead?
// TODO: Divide off modules starting with "user", and add the user parameter to them
$query = array(
'modules' => implode( '|', array_unique( (array) $modules ) ),
'lang' => $wgLang->getCode(),
'debug' => $wgRequest->getBool( 'debug' ) && $wgRequest->getVal( 'debug' ) !== 'false',
'skin' => $wgUser->getSkin()->getSkinName(),
'only' => $only,
);
// Automatically select style/script elements
if ( $only === 'styles' ) {
return Html::linkedStyle( wfAppendQuery( $wgLoadScript, $query ) );
} else {
return Html::linkedScript( wfAppendQuery( $wgLoadScript, $query ) );
$moduleGroups = array( null => array(), 'user' => array() );
foreach ( (array) $modules as $module ) {
$moduleGroups[strpos( $module, 'user' ) === 0 ? 'user' : null][] = $module;
}
$links = '';
foreach ( $moduleGroups as $group => $modules ) {
if ( count( $modules ) ) {
$query['modules'] = implode( '|', array_unique( (array) $modules ) );
if ( $group === 'user' ) {
$query['user'] = $wgUser->getName();
}
// Automatically select style/script elements
if ( $only === 'styles' ) {
$links .= Html::linkedStyle( wfAppendQuery( $wgLoadScript, $query ) );
} else {
$links .= Html::linkedScript( wfAppendQuery( $wgLoadScript, $query ) );
}
}
}
return $links;
}
/**
@ -2313,8 +2327,8 @@ class OutputPage {
// Statup - this will immediately load jquery and mediawiki modules
$scripts = self::makeResourceLoaderLink( $sk, 'startup', 'scripts' );
// Configuration -- this could be merged together with the load and go, but makeGlobalVariablesScript returns a
// whole script tag -- grumble grumble
// Configuration -- This could be merged together with the load and go, but makeGlobalVariablesScript returns a
// whole script tag -- grumble grumble...
$scripts .= Skin::makeGlobalVariablesScript( $sk->getSkinName() ) . "\n";
// Script and Messages "only"

View file

@ -31,23 +31,24 @@ class ResourceLoaderContext {
protected $language;
protected $direction;
protected $skin;
protected $user;
protected $debug;
protected $only;
protected $hash;
/* Methods */
public function __construct( WebRequest $request, $server ) {
public function __construct( WebRequest $request ) {
global $wgLang, $wgDefaultSkin;
$this->request = $request;
$this->server = $server;
// Interperet request
$this->modules = explode( '|', $request->getVal( 'modules' ) );
$this->language = $request->getVal( 'lang' );
$this->direction = $request->getVal( 'dir' );
$this->skin = $request->getVal( 'skin' );
$this->debug = $request->getVal( 'debug' ) === 'true' || $request->getBool( 'debug' );
$this->user = $request->getVal( 'user' );
$this->debug = $request->getBool( 'debug' ) && $request->getVal( 'debug' ) === 'true';
$this->only = $request->getVal( 'only' );
// Fallback on system defaults
@ -68,10 +69,6 @@ class ResourceLoaderContext {
return $this->request;
}
public function getServer() {
return $this->server;
}
public function getModules() {
return $this->modules;
}
@ -88,6 +85,10 @@ class ResourceLoaderContext {
return $this->skin;
}
public function getUser() {
return $this->skin;
}
public function getDebug() {
return $this->debug;
}
@ -111,6 +112,6 @@ class ResourceLoaderContext {
public function getHash() {
return isset( $this->hash ) ?
$this->hash : $this->hash =
implode( '|', array( $this->language, $this->skin, $this->debug, $this->only ) );
implode( '|', array( $this->language, $this->skin, $this->user, $this->debug, $this->only ) );
}
}

View file

@ -81,8 +81,6 @@ abstract class ResourceLoaderModule {
return $context->getDirection() === 'rtl';
}
/* Abstract Methods */
/**
* Get all JS for this module for a given language and skin.
* Includes all relevant JS except loader scripts.
@ -90,7 +88,10 @@ abstract class ResourceLoaderModule {
* @param $context ResourceLoaderContext object
* @return String: JS
*/
public abstract function getScript( ResourceLoaderContext $context );
public function getScript( ResourceLoaderContext $context ) {
// Stub, override expected
return '';
}
/**
* Get all CSS for this module for a given skin.
@ -98,7 +99,10 @@ abstract class ResourceLoaderModule {
* @param $context ResourceLoaderContext object
* @return array: strings of CSS keyed by media type
*/
public abstract function getStyles( ResourceLoaderContext $context );
public function getStyles( ResourceLoaderContext $context ) {
// Stub, override expected
return '';
}
/**
* Get the messages needed for this module.
@ -107,14 +111,20 @@ abstract class ResourceLoaderModule {
*
* @return array of message keys. Keys may occur more than once
*/
public abstract function getMessages();
public function getMessages() {
// Stub, override expected
return array();
}
/**
* Get the loader JS for this module, if set.
*
* @return Mixed: loader JS (string) or false if no custom loader set
*/
public abstract function getLoaderScript();
public function getLoaderScript() {
// Stub, override expected
return '';
}
/**
* Get a list of modules this module depends on.
@ -131,7 +141,12 @@ abstract class ResourceLoaderModule {
* loader script, see getLoaderScript()
* @return Array of module names (strings)
*/
public abstract function getDependencies();
public function getDependencies() {
// Stub, override expected
return array();
}
/* Abstract Methods */
/**
* Get this module's last modification timestamp for a given
@ -682,58 +697,65 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
/* Protected Members */
// In-object cache for modified time
protected $modifiedTime = null;
protected $modifiedTime = array();
/* Abstract Protected Methods */
abstract protected function getPages( ResourceLoaderContext $context );
/* Protected Methods */
/* Methods */
protected function getStyleCode( array $styles ) {
foreach ( $styles as $media => $messages ) {
foreach ( $messages as $i => $message ) {
$style = wfMsgExt( $message, 'content' );
if ( !wfEmptyMsg( $message, $style ) ) {
$styles[$media][$i] = $style;
}
public function getScript( ResourceLoaderContext $context ) {
$scripts = '';
foreach ( $this->getPages( $context ) as $page => $options ) {
if ( $options['type'] === 'script' ) {
$script = wfMsgExt( $page, 'content' );
$scripts .= "/* MediaWiki:$page */\n" . ( !wfEmptyMsg( $page, $script ) ? $script : '' ) . "\n";
}
}
foreach ( $styles as $media => $messages ) {
$styles[$media] = implode( "\n", $messages );
return $scripts;
}
public function getStyles( ResourceLoaderContext $context ) {
$styles = array();
foreach ( $this->getPages( $context ) as $page => $options ) {
if ( $options['type'] === 'style' ) {
$media = isset( $options['media'] ) ? $options['media'] : 'all';
$style = wfMsgExt( $page, 'content' );
if ( !isset( $styles[$media] ) ) {
$styles[$media] = '';
}
$styles[$media] .= "/* MediaWiki:$page */\n" . ( !wfEmptyMsg( $page, $style ) ? $style : '' ) . "\n";
}
}
return $styles;
}
/* Methods */
public function getModifiedTime( ResourceLoaderContext $context ) {
if ( isset( $this->modifiedTime[$context->getHash()] ) ) {
return $this->modifiedTime[$context->getHash()];
$hash = $context->getHash();
if ( isset( $this->modifiedTime[$hash] ) ) {
return $this->modifiedTime[$hash];
}
$pages = $this->getPages( $context );
foreach ( $pages as $i => $page ) {
$pages[$i] = Title::makeTitle( NS_MEDIAWIKI, $page );
$titles = array();
foreach ( $this->getPages( $context ) as $page => $options ) {
$titles[] = Title::makeTitle( NS_MEDIAWIKI, $page );
}
// Do batch existence check
// TODO: This would work better if page_touched were loaded by this as well
$lb = new LinkBatch( $pages );
$lb = new LinkBatch( $titles );
$lb->execute();
$this->modifiedTime = 1; // wfTimestamp() interprets 0 as "now"
foreach ( $pages as $page ) {
if ( $page->exists() ) {
$this->modifiedTime = max( $this->modifiedTime, wfTimestamp( TS_UNIX, $page->getTouched() ) );
$modifiedTime = 1; // wfTimestamp() interprets 0 as "now"
foreach ( $titles as $title ) {
if ( $title->exists() ) {
$modifiedTime = max( $modifiedTime, wfTimestamp( TS_UNIX, $title->getTouched() ) );
}
}
return $this->modifiedTime;
return $this->modifiedTime[$hash] = $modifiedTime;
}
public function getMessages() { return array(); }
public function getLoaderScript() { return ''; }
public function getDependencies() { return array(); }
}
/**
* Custom module for site customizations
* Module for site customizations
*/
class ResourceLoaderSiteModule extends ResourceLoaderWikiModule {
@ -742,49 +764,172 @@ class ResourceLoaderSiteModule extends ResourceLoaderWikiModule {
protected function getPages( ResourceLoaderContext $context ) {
global $wgHandheldStyle;
// HACK: We duplicate the message names from generateUserJs() and generateUserCss here and weird things (i.e.
// mtime moving backwards) can happen when a MediaWiki:Something.js page is deleted
$pages = array(
'Common.js',
'Common.css',
ucfirst( $context->getSkin() ) . '.js',
ucfirst( $context->getSkin() ) . '.css',
'Print.css',
'Common.js' => array( 'type' => 'script' ),
'Common.css' => array( 'type' => 'style' ),
ucfirst( $context->getSkin() ) . '.js' => array( 'type' => 'script' ),
ucfirst( $context->getSkin() ) . '.css' => array( 'type' => 'style' ),
'Print.css' => array( 'type' => 'style', 'media' => 'print' ),
);
if ( $wgHandheldStyle ) {
$pages[] = 'Handheld.css';
$pages['Handheld.css'] = array( 'type' => 'style', 'media' => 'handheld' );
}
return $pages;
}
}
/**
* Module for user customizations
*/
class ResourceLoaderUserModule extends ResourceLoaderWikiModule {
/* Protected Methods */
protected function getPages( ResourceLoaderContext $context ) {
global $wgAllowUserCss;
if ( $context->getUser() && $wgAllowUserCss ) {
$user = User::newFromName( $context->getUser() );
$userPage = $user->getUserPage()->getPrefixedText();
return array(
"$userPage/common.css" => array( 'type' => 'style' ),
"$userPage/" . $context->getSkin() . '.css' => array( 'type' => 'style' ),
);
}
return array();
}
}
/**
* Module for user preference customizations
*/
class ResourceLoaderUserPreferencesModule extends ResourceLoaderModule {
/* Protected Members */
protected $modifiedTime = array();
/* Methods */
public function getScript( ResourceLoaderContext $context ) {
return Skin::newFromKey( $context->getSkin() )->generateUserJs();
public function getModifiedTime( ResourceLoaderContext $context ) {
$hash = $context->getHash();
if ( isset( $this->modifiedTime[$hash] ) ) {
return $this->modifiedTime[$hash];
}
$user = User::newFromName( $context->getUser() );
return $this->modifiedTime[$hash] = $user->getTouched();
}
public function getStyles( ResourceLoaderContext $context ) {
global $wgHandheldStyle;
$styles = array(
'all' => array( 'Common.css', $context->getSkin() . '.css' ),
'print' => array( 'Print.css' ),
);
if ( $wgHandheldStyle ) {
$sources['handheld'] = array( 'Handheld.css' );
global $wgAllowUserCssPrefs;
if ( $wgAllowUserCssPrefs ) {
$user = User::newFromName( $context->getUser() );
$rules = array();
if ( ( $underline = $user->getOption( 'underline' ) ) < 2 ) {
$rules[] = "a { text-decoration: " . ( $underline ? 'underline' : 'none' ) . "; }";
}
if ( $user->getOption( 'highlightbroken' ) ) {
$rules[] = "a.new, #quickbar a.new { color: #CC2200; }\n";
} else {
$rules[] = "a.new, #quickbar a.new, a.stub, #quickbar a.stub { color: inherit; }";
$rules[] = "a.new:after, #quickbar a.new:after { content: '?'; color: #CC2200; }";
$rules[] = "a.stub:after, #quickbar a.stub:after { content: '!'; color: #772233; }";
}
if ( $user->getOption( 'justify' ) ) {
$rules[] = "#article, #bodyContent, #mw_content { text-align: justify; }\n";
}
if ( !$user->getOption( 'showtoc' ) ) {
$rules[] = "#toc { display: none; }\n";
}
if ( !$user->getOption( 'editsection' ) ) {
$rules[] = ".editsection { display: none; }\n";
}
if ( ( $fontstyle = $user->getOption( 'editfont' ) ) !== 'default' ) {
$rules[] = "textarea { font-family: $fontstyle; }\n";
}
return array( 'all' => implode( "\n", $rules ) );
}
return $this->getStyleCode( $styles );
return array();
}
public function getFlip( $context ) {
global $wgContLang;
return $wgContLang->getDir() !== $context->getDirection();
}
}
class ResourceLoaderStartUpModule extends ResourceLoaderModule {
/* Protected Members */
protected $modifiedTime = null;
protected $modifiedTime = array();
/* Protected Methods */
protected function getConfig( $context ) {
global $wgLoadScript, $wgScript, $wgStylePath, $wgScriptExtension, $wgArticlePath, $wgScriptPath, $wgServer,
$wgContLang, $wgBreakFrames, $wgVariantArticlePath, $wgActionPaths, $wgUseAjax, $wgAjaxWatch, $wgVersion,
$wgEnableAPI, $wgEnableWriteAPI, $wgDBname, $wgEnableMWSuggest, $wgSitename, $wgFileExtensions;
// Pre-process information
$separatorTransTable = $wgContLang->separatorTransformTable();
$separatorTransTable = $separatorTransTable ? $separatorTransTable : array();
$compactSeparatorTransTable = array(
implode( "\t", array_keys( $separatorTransTable ) ),
implode( "\t", $separatorTransTable ),
);
$digitTransTable = $wgContLang->digitTransformTable();
$digitTransTable = $digitTransTable ? $digitTransTable : array();
$compactDigitTransTable = array(
implode( "\t", array_keys( $digitTransTable ) ),
implode( "\t", $digitTransTable ),
);
$mainPage = Title::newMainPage();
// Build list of variables
$vars = array(
'wgLoadScript' => $wgLoadScript,
'debug' => $context->getDebug(),
'skin' => $context->getSkin(),
'stylepath' => $wgStylePath,
'wgUrlProtocols' => wfUrlProtocols(),
'wgArticlePath' => $wgArticlePath,
'wgScriptPath' => $wgScriptPath,
'wgScriptExtension' => $wgScriptExtension,
'wgScript' => $wgScript,
'wgVariantArticlePath' => $wgVariantArticlePath,
'wgActionPaths' => $wgActionPaths,
'wgServer' => $wgServer,
'wgUserLanguage' => $context->getLanguage(),
'wgContentLanguage' => $wgContLang->getCode(),
'wgBreakFrames' => $wgBreakFrames,
'wgVersion' => $wgVersion,
'wgEnableAPI' => $wgEnableAPI,
'wgEnableWriteAPI' => $wgEnableWriteAPI,
'wgSeparatorTransformTable' => $compactSeparatorTransTable,
'wgDigitTransformTable' => $compactDigitTransTable,
'wgMainPageTitle' => $mainPage ? $mainPage->getPrefixedText() : null,
'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(),
'wgNamespaceIds' => $wgContLang->getNamespaceIds(),
'wgSiteName' => $wgSitename,
'wgFileExtensions' => $wgFileExtensions,
);
if ( $wgContLang->hasVariants() ) {
$vars['wgUserVariant'] = $wgContLang->getPreferredVariant();
}
if ( $wgUseAjax && $wgEnableMWSuggest ) {
$vars['wgMWSuggestTemplate'] = SearchEngine::getMWSuggestTemplate();
$vars['wgDBname'] = $wgDBname;
$vars['wgSearchNamespaces'] = SearchEngine::userNamespaces( $wgUser );
}
return $vars;
}
/* Methods */
public function getScript( ResourceLoaderContext $context ) {
global $IP;
global $IP, $wgStylePath, $wgLoadScript;
$scripts = file_get_contents( "$IP/resources/startup.js" );
@ -792,9 +937,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
// Get all module registrations
$registration = ResourceLoader::getModuleRegistrations( $context );
// Build configuration
$config = FormatJson::encode(
array( 'server' => $context->getServer(), 'debug' => $context->getDebug() )
);
$config = FormatJson::encode( $this->getConfig( $context ) );
// Add a well-known start-up function
$scripts .= "window.startUp = function() { $registration mediaWiki.config.set( $config ); };";
// Build load query for jquery and mediawiki modules
@ -814,7 +957,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
);
// Build HTML code for loading jquery and mediawiki modules
$loadScript = Html::linkedScript( $context->getServer() . "?$query" );
$loadScript = Html::linkedScript( "$wgLoadScript?$query" );
// Add code to add jquery and mediawiki loading code; only if the current client is compatible
$scripts .= "if ( isCompatible() ) { document.write( '$loadScript' ); }";
// Delete the compatible function - it's not needed anymore
@ -827,14 +970,15 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
public function getModifiedTime( ResourceLoaderContext $context ) {
global $IP;
if ( !is_null( $this->modifiedTime ) ) {
return $this->modifiedTime;
$hash = $context->getHash();
if ( isset( $this->modifiedTime[$hash] ) ) {
return $this->modifiedTime[$hash];
}
// HACK getHighestModifiedTime() calls this function, so protect against infinite recursion
$this->modifiedTime = filemtime( "$IP/resources/startup.js" );
$this->modifiedTime = ResourceLoader::getHighestModifiedTime( $context );
return $this->modifiedTime;
$this->modifiedTime[$hash] = filemtime( "$IP/resources/startup.js" );
// ATTENTION!: Because of the line above, this is not going to cause infinite recursion - think carefully
// before making changes to this code!
$this->modifiedTime[$hash] = ResourceLoader::getHighestModifiedTime( $context );
return $this->modifiedTime[$hash];
}
public function getClientMaxage() {
@ -845,14 +989,9 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
return 300; // 5 minutes
}
public function getStyles( ResourceLoaderContext $context ) { return array(); }
public function getFlip( $context ) {
global $wgContLang;
return $wgContLang->getDir() !== $context->getDirection();
}
public function getMessages() { return array(); }
public function getLoaderScript() { return ''; }
public function getDependencies() { return array(); }
}

View file

@ -357,7 +357,7 @@ class Skin extends Linker {
static function makeVariablesScript( $data ) {
if ( $data ) {
return Html::inlineScript( 'mediaWiki.config.set(' . json_encode( $data ) . ');' );
return Html::inlineScript( 'mediaWiki.config.set(' . FormatJson::encode( $data ) . ');' );
} else {
return '';
}
@ -368,50 +368,16 @@ class Skin extends Linker {
* @param $skinName string Name of the skin
* The odd calling convention is for backwards compatibility
* @todo FIXME: Make this not depend on $wgTitle!
*
* Do not add things here which can be evaluated in ResourceLoaderStartupScript - in other words, without state.
* You will only be adding bloat to the page and causing page caches to have to be purged on configuration changes.
*/
static function makeGlobalVariablesScript( $skinName ) {
if ( is_array( $skinName ) ) {
# Weird back-compat stuff.
$skinName = $skinName['skinname'];
}
global $wgScript, $wgTitle, $wgStylePath, $wgUser, $wgScriptExtension;
global $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, $wgLang;
global $wgOut, $wgArticle;
global $wgBreakFrames, $wgRequest, $wgVariantArticlePath, $wgActionPaths;
global $wgUseAjax, $wgAjaxWatch;
global $wgVersion, $wgEnableAPI, $wgEnableWriteAPI;
global $wgRestrictionTypes;
global $wgDBname, $wgEnableMWSuggest;
global $wgSitename;
global $wgTitle, $wgUser, $wgRequest, $wgArticle, $wgOut, $wgRestrictionTypes;
$ns = $wgTitle->getNamespace();
$nsname = MWNamespace::exists( $ns ) ? MWNamespace::getCanonicalName( $ns ) : $wgTitle->getNsText();
$separatorTransTable = $wgContLang->separatorTransformTable();
$separatorTransTable = $separatorTransTable ? $separatorTransTable : array();
$compactSeparatorTransTable = array(
implode( "\t", array_keys( $separatorTransTable ) ),
implode( "\t", $separatorTransTable ),
);
$digitTransTable = $wgContLang->digitTransformTable();
$digitTransTable = $digitTransTable ? $digitTransTable : array();
$compactDigitTransTable = array(
implode( "\t", array_keys( $digitTransTable ) ),
implode( "\t", $digitTransTable ),
);
$mainPage = Title::newMainPage();
$vars = array(
'skin' => $skinName,
'stylepath' => $wgStylePath,
'wgUrlProtocols' => wfUrlProtocols(),
'wgArticlePath' => $wgArticlePath,
'wgScriptPath' => $wgScriptPath,
'wgScriptExtension' => $wgScriptExtension,
'wgScript' => $wgScript,
'wgVariantArticlePath' => $wgVariantArticlePath,
'wgActionPaths' => (object)$wgActionPaths,
'wgServer' => $wgServer,
'wgCanonicalNamespace' => $nsname,
'wgCanonicalSpecialPageName' => $ns == NS_SPECIAL ?
SpecialPage::resolveAlias( $wgTitle->getDBkey() ) : false, # bug 21115
@ -423,53 +389,13 @@ class Skin extends Linker {
'wgIsArticle' => $wgOut->isArticle(),
'wgUserName' => $wgUser->isAnon() ? null : $wgUser->getName(),
'wgUserGroups' => $wgUser->getEffectiveGroups(),
'wgUserLanguage' => $wgLang->getCode(),
'wgContentLanguage' => $wgContLang->getCode(),
'wgBreakFrames' => $wgBreakFrames,
'wgCurRevisionId' => isset( $wgArticle ) ? $wgArticle->getLatest() : 0,
'wgVersion' => $wgVersion,
'wgEnableAPI' => $wgEnableAPI,
'wgEnableWriteAPI' => $wgEnableWriteAPI,
'wgSeparatorTransformTable' => $compactSeparatorTransTable,
'wgDigitTransformTable' => $compactDigitTransTable,
'wgMainPageTitle' => $mainPage ? $mainPage->getPrefixedText() : null,
'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(),
'wgNamespaceIds' => $wgContLang->getNamespaceIds(),
'wgSiteName' => $wgSitename,
'wgCategories' => $wgOut->getCategories(),
);
if ( $wgContLang->hasVariants() ) {
$vars['wgUserVariant'] = $wgContLang->getPreferredVariant();
}
// if on upload page output the extension list & js_upload
if ( SpecialPage::resolveAlias( $wgTitle->getDBkey() ) == 'Upload' ) {
global $wgFileExtensions;
$vars['wgFileExtensions'] = $wgFileExtensions;
}
if ( $wgUseAjax && $wgEnableMWSuggest && !$wgUser->getOption( 'disablesuggest', false ) ) {
$vars['wgMWSuggestTemplate'] = SearchEngine::getMWSuggestTemplate();
$vars['wgDBname'] = $wgDBname;
$vars['wgSearchNamespaces'] = SearchEngine::userNamespaces( $wgUser );
$vars['wgMWSuggestMessages'] = array( wfMsg( 'search-mwsuggest-enabled' ), wfMsg( 'search-mwsuggest-disabled' ) );
}
foreach ( $wgRestrictionTypes as $type ) {
$vars['wgRestriction' . ucfirst( $type )] = $wgTitle->getRestrictions( $type );
}
if ( $wgOut->isArticleRelated() && $wgUseAjax && $wgAjaxWatch && $wgUser->isLoggedIn() ) {
$msgs = (object)array();
foreach ( array( 'watch', 'unwatch', 'watching', 'unwatching',
'tooltip-ca-watch', 'tooltip-ca-unwatch' ) as $msgName ) {
$msgs-> { $msgName . 'Msg' } = wfMsg( $msgName );
}
$vars['wgAjaxWatch'] = $msgs;
}
// Allow extensions to add their custom variables to the global JS variables
wfRunHooks( 'MakeGlobalVariablesScript', array( &$vars ) );
@ -521,51 +447,20 @@ class Skin extends Linker {
* @return string
*/
public function generateUserJs( $skinName = null ) {
global $wgStylePath;
wfProfileIn( __METHOD__ );
// Stub - see ResourceLoaderSiteModule, CologneBlue, Simple and Standard skins override this
if ( !$skinName ) {
$skinName = $this->getSkinName();
}
$s = "/* generated javascript */\n";
$s .= "var skin = '" . Xml::escapeJsString( $skinName ) . "';\n";
$s .= "var stylepath = '" . Xml::escapeJsString( $wgStylePath ) . "';";
$s .= "\n\n/* MediaWiki:Common.js */\n";
$commonJs = wfMsgExt( 'common.js', 'content' );
if ( !wfEmptyMsg( 'common.js', $commonJs ) ) {
$s .= $commonJs;
}
$s .= "\n\n/* MediaWiki:" . ucfirst( $skinName ) . ".js */\n";
// avoid inclusion of non defined user JavaScript (with custom skins only)
// by checking for default message content
$msgKey = ucfirst( $skinName ) . '.js';
$userJS = wfMsgExt( $msgKey, 'content' );
if ( !wfEmptyMsg( $msgKey, $userJS ) ) {
$s .= $userJS;
}
wfProfileOut( __METHOD__ );
return $s;
return '';
}
/**
* Generate user stylesheet for action=raw&gen=css
*/
public function generateUserStylesheet() {
wfProfileIn( __METHOD__ );
$s = "/* generated user stylesheet */\n" .
$this->reallyGenerateUserStylesheet();
// Stub - see ResourceLoaderUserModule, CologneBlue, Simple and Standard skins override this
wfProfileOut( __METHOD__ );
return $s;
return '';
}
/**
@ -573,53 +468,10 @@ class Skin extends Linker {
* Anything in here won't be generated if $wgAllowUserCssPrefs is false.
*/
protected function reallyGenerateUserStylesheet() {
global $wgUser;
$s = '';
// Stub - see ResourceLoaderUserModule, CologneBlue, Simple and Standard skins override this
if ( ( $undopt = $wgUser->getOption( 'underline' ) ) < 2 ) {
$underline = $undopt ? 'underline' : 'none';
$s .= "a { text-decoration: $underline; }\n";
}
if ( $wgUser->getOption( 'highlightbroken' ) ) {
$s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
} else {
$s .= <<<CSS
a.new, #quickbar a.new,
a.stub, #quickbar a.stub {
color: inherit;
}
a.new:after, #quickbar a.new:after {
content: "?";
color: #CC2200;
}
a.stub:after, #quickbar a.stub:after {
content: "!";
color: #772233;
}
CSS;
}
if ( $wgUser->getOption( 'justify' ) ) {
$s .= "#article, #bodyContent, #mw_content { text-align: justify; }\n";
}
if ( !$wgUser->getOption( 'showtoc' ) ) {
$s .= "#toc { display: none; }\n";
}
if ( !$wgUser->getOption( 'editsection' ) ) {
$s .= ".editsection { display: none; }\n";
}
$fontstyle = $wgUser->getOption( 'editfont' );
if ( $fontstyle !== 'default' ) {
$s .= "textarea { font-family: $fontstyle; }\n";
}
return $s;
return '';
}
/**
@ -627,7 +479,7 @@ CSS;
*/
function setupUserCss( OutputPage $out ) {
global $wgRequest, $wgUser;
global $wgAllowUserCss, $wgUseSiteCss, $wgSquidMaxage;
global $wgUseSiteCss, $wgAllowUserCss, $wgAllowUserCssPrefs, $wgSquidMaxage;
wfProfileIn( __METHOD__ );
@ -643,51 +495,26 @@ CSS;
$out->addStyle( $url );
}
// If we use the site's dynamic CSS, throw that in, too
// Per-site custom styles
if ( $wgUseSiteCss ) {
$out->addModuleStyles( 'site' );
}
global $wgAllowUserCssPrefs;
if ( $wgAllowUserCssPrefs ) {
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;
}
// 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 ) ) {
// Per-user custom styles
if ( $wgAllowUserCss ) {
if ( $this->mTitle->isCssSubpage() && $this->userCanPreview( $wgRequest->getVal( 'action' ) ) ) {
// @FIXME: properly escape the cdata!
$out->addInlineStyle( $wgRequest->getText( 'wpTextbox1' ) );
} else {
$names = array( 'common', $this->getSkinName() );
foreach ( $names as $name ) {
$out->addStyle( self::makeUrl(
$this->userpage . '/' . $name . '.css',
'action=raw&ctype=text/css' )
);
}
$out->addModuleStyles( 'user' );
}
}
// Per-user preference styles
if ( $wgAllowUserCssPrefs ) {
$out->addModuleStyles( 'user.preferences' );
}
wfProfileOut( __METHOD__ );
}

View file

@ -45,7 +45,7 @@ if ( $wgRequest->isPathInfoBad() ) {
}
// Respond to resource loading request
ResourceLoader::respond( new ResourceLoaderContext( $wgRequest, $wgServer . $wgScriptPath . '/load.php' ) );
ResourceLoader::respond( new ResourceLoaderContext( $wgRequest ) );
wfProfileOut( 'load.php' );
wfLogProfilingData();

View file

@ -6,6 +6,8 @@ ResourceLoader::register( array(
'site' => new ResourceLoaderSiteModule,
'startup' => new ResourceLoaderStartUpModule,
'user' => new ResourceLoaderUserModule,
'user.preferences' => new ResourceLoaderUserPreferencesModule,
/* Skins */
@ -356,6 +358,7 @@ ResourceLoader::register( array(
'mediawiki.legacy.mwsuggest' => new ResourceLoaderFileModule( array(
'scripts' => 'skins/common/mwsuggest.js',
'dependencies' => 'mediawiki.legacy.wikibits',
'messages' => array( 'search-mwsuggest-enabled', 'search-mwsuggest-disabled' ),
) ),
'mediawiki.legacy.password' => new ResourceLoaderFileModule( array(
'scripts' => 'skins/common/password.js',

View file

@ -469,7 +469,7 @@ window.mediaWiki = new ( function( $ ) {
var html = '';
for ( var r = 0; r < requests.length; r++ ) {
// Build out the HTML
var src = mediaWiki.config.get( 'server' ) + '?' + $.param( requests[r] );
var src = mediaWiki.config.get( 'wgLoadScript' ) + '?' + $.param( requests[r] );
html += '<script type="text/javascript" src="' + src + '"></script>';
}
return html;