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;
}
/**
// 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"
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
return $this->request;
}
- public function getServer() {
- return $this->server;
- }
-
public function getModules() {
return $this->modules;
}
return $this->skin;
}
+ public function getUser() {
+ return $this->skin;
+ }
+
public function getDebug() {
return $this->debug;
}
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 ) );
}
}
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.
* @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.
* @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.
*
* @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.
* 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
* combination of language, skin and debug mode flag. This is typically
/* 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 */
-
- 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;
- }
+ /* Methods */
+
+ 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 {
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" );
// 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
);
// 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
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() {
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(); }
}
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 '';
- }
+ }
}
/**
* @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
'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 ) );
-
+
return self::makeVariablesScript( $vars );
}
* @return string
*/
public function generateUserJs( $skinName = null ) {
- global $wgStylePath;
-
- wfProfileIn( __METHOD__ );
-
- 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;
+
+ // Stub - see ResourceLoaderSiteModule, CologneBlue, Simple and Standard skins override this
+
+ return '';
}
/**
* Generate user stylesheet for action=raw&gen=css
*/
public function generateUserStylesheet() {
- wfProfileIn( __METHOD__ );
-
- $s = "/* generated user stylesheet */\n" .
- $this->reallyGenerateUserStylesheet();
-
- wfProfileOut( __METHOD__ );
- return $s;
+
+ // Stub - see ResourceLoaderUserModule, CologneBlue, Simple and Standard skins override this
+
+ return '';
}
/**
* Anything in here won't be generated if $wgAllowUserCssPrefs is false.
*/
protected function reallyGenerateUserStylesheet() {
- global $wgUser;
-
- $s = '';
-
- 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;
+
+ // Stub - see ResourceLoaderUserModule, CologneBlue, Simple and Standard skins override this
+
+ return '';
}
/**
*/
function setupUserCss( OutputPage $out ) {
global $wgRequest, $wgUser;
- global $wgAllowUserCss, $wgUseSiteCss, $wgSquidMaxage;
+ global $wgUseSiteCss, $wgAllowUserCss, $wgAllowUserCssPrefs, $wgSquidMaxage;
wfProfileIn( __METHOD__ );
$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__ );
}
}
// Respond to resource loading request
-ResourceLoader::respond( new ResourceLoaderContext( $wgRequest, $wgServer . $wgScriptPath . '/load.php' ) );
+ResourceLoader::respond( new ResourceLoaderContext( $wgRequest ) );
wfProfileOut( 'load.php' );
wfLogProfilingData();
'site' => new ResourceLoaderSiteModule,
'startup' => new ResourceLoaderStartUpModule,
+ 'user' => new ResourceLoaderUserModule,
+ 'user.preferences' => new ResourceLoaderUserPreferencesModule,
/* Skins */
'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',
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;