X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2FResourceLoaderModule.php;h=b13557a223430cbc52419613d1b80e0e652b442f;hb=9898419dfd0aac8f2d5c64d34a6451f6ba3a84f5;hp=8e0464310c4d86f491ea70198fabcf1e78da83cb;hpb=016fbe7a81aaf51a4c37e3f69ff7bc81f0037834;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/ResourceLoaderModule.php b/includes/ResourceLoaderModule.php index 8e0464310c..b13557a223 100644 --- a/includes/ResourceLoaderModule.php +++ b/includes/ResourceLoaderModule.php @@ -217,7 +217,10 @@ abstract class ResourceLoaderModule { * @param $context ResourceLoaderContext object * @return int UNIX timestamp */ - public abstract function getModifiedTime( ResourceLoaderContext $context ); + public function getModifiedTime( ResourceLoaderContext $context ) { + // 0 would mean now + return 1; + } } /** @@ -276,44 +279,51 @@ class ResourceLoaderFileModule extends ResourceLoaderModule { * 'messages' => array( 'message1', 'message2' ... ), * 'group' => 'stuff', * ) + * + * @param $basePath String: base path to prepend to all paths in $options */ - public function __construct( $options = array() ) { + public function __construct( $options = array(), $basePath = null ) { foreach ( $options as $option => $value ) { switch ( $option ) { case 'scripts': - $this->scripts = (array)$value; + case 'debugScripts': + case 'languageScripts': + case 'skinScripts': + case 'loaders': + $this->{$option} = (array)$value; + // Automatically prefix script paths + if ( is_string( $basePath ) ) { + foreach ( $this->{$option} as $key => $value ) { + $this->{$option}[$key] = $basePath . $value; + } + } break; case 'styles': - $this->styles = (array)$value; + case 'skinStyles': + $this->{$option} = (array)$value; + // Automatically prefix style paths + if ( is_string( $basePath ) ) { + foreach ( $this->{$option} as $key => $value ) { + if ( is_array( $value ) ) { + $this->{$option}[$basePath . $key] = $value; + unset( $this->{$option}[$key] ); + } else { + $this->{$option}[$key] = $basePath . $value; + } + } + } break; + case 'dependencies': case 'messages': - $this->messages = (array)$value; + $this->{$option} = (array)$value; break; case 'group': $this->group = (string)$value; break; - case 'dependencies': - $this->dependencies = (array)$value; - break; - case 'debugScripts': - $this->debugScripts = (array)$value; - break; - case 'languageScripts': - $this->languageScripts = (array)$value; - break; - case 'skinScripts': - $this->skinScripts = (array)$value; - break; - case 'skinStyles': - $this->skinStyles = (array)$value; - break; - case 'loaders': - $this->loaders = (array)$value; - break; } } } - + /** * Add script files to this module. In order to be valid, a module * must contain at least one script file. @@ -469,7 +479,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule { // Collect referenced files $files = array(); - foreach ( $styles as $media => $style ) { + foreach ( $styles as $style ) { // Extract and store the list of referenced files $files = array_merge( $files, CSSMin::getLocalFileReferences( $style ) ); } @@ -485,12 +495,6 @@ class ResourceLoaderFileModule extends ResourceLoaderModule { 'md_deps' => $encFiles, ) ); - - // Save into memcached - global $wgMemc; - - $key = wfMemcKey( 'resourceloader', 'module_deps', $this->getName(), $context->getSkin() ); - $wgMemc->set( $key, $encFiles ); } return $styles; @@ -535,13 +539,13 @@ class ResourceLoaderFileModule extends ResourceLoaderModule { // Sort of nasty way we can get a flat list of files depended on by all styles $styles = array(); - foreach ( self::organizeFilesByOption( $this->styles, 'media', 'all' ) as $media => $styleFiles ) { + foreach ( self::organizeFilesByOption( $this->styles, 'media', 'all' ) as $styleFiles ) { $styles = array_merge( $styles, $styleFiles ); } $skinFiles = (array) self::getSkinFiles( $context->getSkin(), self::organizeFilesByOption( $this->skinStyles, 'media', 'all' ) ); - foreach ( $skinFiles as $media => $styleFiles ) { + foreach ( $skinFiles as $styleFiles ) { $styles = array_merge( $styles, $styleFiles ); } @@ -581,7 +585,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule { * Get the primary CSS for this module. This is pulled from the CSS * files added through addStyles() * - * @return String: JS + * @return Array */ protected function getPrimaryStyles() { return self::concatStyles( $this->styles ); @@ -690,7 +694,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule { * Get the contents of a set of CSS files, remap then and concatenate * them, with newlines in between. Each file is used only once. * - * @param $files Array of file names + * @param $styles Array of file names * @return Array: list of concatenated and remapped contents of $files keyed by media type */ protected static function concatStyles( $styles ) { @@ -725,18 +729,21 @@ class ResourceLoaderFileModule extends ResourceLoaderModule { * @return string Remapped CSS */ protected static function remapStyle( $file ) { - global $wgUseDataURLs, $wgScriptPath; + global $wgScriptPath; return CSSMin::remap( file_get_contents( self::remapFilename( $file ) ), dirname( $file ), $wgScriptPath . '/' . dirname( $file ), - $wgUseDataURLs + true ); } } /** * Abstraction for resource loader modules which pull from wiki pages + * + * This can only be used for wiki pages in the MediaWiki and User namespaces, because of it's dependence on the + * functionality of Title::isValidCssJsSubpage. */ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule { @@ -766,13 +773,11 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule { /* Methods */ public function getScript( ResourceLoaderContext $context ) { - global $wgCanonicalNamespaceNames; - $scripts = ''; foreach ( $this->getPages( $context ) as $page => $options ) { if ( $options['type'] === 'script' ) { if ( $script = $this->getContent( $page, $options['ns'] ) ) { - $ns = $wgCanonicalNamespaceNames[$options['ns']]; + $ns = MWNamespace::getCanonicalName( $options['ns'] ); $scripts .= "/*$ns:$page */\n$script\n"; } } @@ -781,7 +786,6 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule { } public function getStyles( ResourceLoaderContext $context ) { - global $wgCanonicalNamespaceNames; $styles = array(); foreach ( $this->getPages( $context ) as $page => $options ) { @@ -791,7 +795,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule { if ( !isset( $styles[$media] ) ) { $styles[$media] = ''; } - $ns = $wgCanonicalNamespaceNames[$options['ns']]; + $ns = MWNamespace::getCanonicalName( $options['ns'] ); $styles[$media] .= "/* $ns:$page */\n$style\n"; } } @@ -819,7 +823,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule { __METHOD__ ); if ( $latest ) { - $modifiedTime = wfTimestamp( TS_UNIX, $modifiedTime ); + $modifiedTime = wfTimestamp( TS_UNIX, $latest ); } } @@ -912,28 +916,34 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule { } } - public function getScript( ResourceLoaderContext $context ) { + /** + * Fetch the context's user options, or if it doesn't match current user, + * the default options. + * + * @param $context ResourceLoaderContext + * @return array + */ + protected function contextUserOptions( ResourceLoaderContext $context ) { global $wgUser; // Verify identity -- this is a private module if ( $context->getUser() === $wgUser->getName() ) { - $options = FormatJson::encode( $wgUser->getOptions() ); + return $wgUser->getOptions(); } else { - $options = FormatJson::encode( User::getDefaultOptions() ); + return User::getDefaultOptions(); } - return "mediaWiki.user.options.set( $options );"; + } + + public function getScript( ResourceLoaderContext $context ) { + $encOptions = FormatJson::encode( $this->contextUserOptions( $context ) ); + return "mediaWiki.user.options.set( $encOptions );"; } public function getStyles( ResourceLoaderContext $context ) { - global $wgUser, $wgAllowUserCssPrefs; + global $wgAllowUserCssPrefs; if ( $wgAllowUserCssPrefs ) { - // Verify identity -- this is a private module - if ( $context->getUser() === $wgUser->getName() ) { - $options = FormatJson::encode( $wgUser->getOptions() ); - } else { - $options = FormatJson::encode( User::getDefaultOptions() ); - } + $options = $this->contextUserOptions( $context ); // Build CSS rules $rules = array(); @@ -941,10 +951,10 @@ class ResourceLoaderUserOptionsModule extends ResourceLoaderModule { $rules[] = "a { text-decoration: " . ( $options['underline'] ? 'underline' : 'none' ) . "; }"; } if ( $options['highlightbroken'] ) { - $rules[] = "a.new, #quickbar a.new { color: #CC2200; }\n"; + $rules[] = "a.new, #quickbar a.new { color: #ba0000; }\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.new:after, #quickbar a.new:after { content: '?'; color: #ba0000; }"; $rules[] = "a.stub:after, #quickbar a.stub:after { content: '!'; color: #772233; }"; } if ( $options['justify'] ) { @@ -1031,13 +1041,13 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule { 'wgNamespaceIds' => $wgContLang->getNamespaceIds(), 'wgSiteName' => $wgSitename, 'wgFileExtensions' => $wgFileExtensions, + 'wgDBname' => $wgDBname, ); if ( $wgContLang->hasVariants() ) { $vars['wgUserVariant'] = $wgContLang->getPreferredVariant(); } if ( $wgUseAjax && $wgEnableMWSuggest ) { $vars['wgMWSuggestTemplate'] = SearchEngine::getMWSuggestTemplate(); - $vars['wgDBname'] = $wgDBname; } return $vars; @@ -1050,6 +1060,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule { * @return String: JavaScript code for registering all modules with the client loader */ public static function getModuleRegistrations( ResourceLoaderContext $context ) { + global $wgCacheEpoch; wfProfileIn( __METHOD__ ); $out = ''; @@ -1057,29 +1068,30 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule { foreach ( $context->getResourceLoader()->getModules() as $name => $module ) { // Support module loader scripts if ( ( $loader = $module->getLoaderScript() ) !== false ) { - $deps = FormatJson::encode( $module->getDependencies() ); - $group = FormatJson::encode( $module->getGroup() ); - $version = wfTimestamp( TS_ISO_8601, round( $module->getModifiedTime( $context ), -2 ) ); + $deps = $module->getDependencies(); + $group = $module->getGroup(); + $version = wfTimestamp( TS_ISO_8601_BASIC, round( $module->getModifiedTime( $context ), -2 ) ); $out .= ResourceLoader::makeCustomLoaderScript( $name, $version, $deps, $group, $loader ); } // Automatically register module else { + $mtime = max( $module->getModifiedTime( $context ), wfTimestamp( TS_UNIX, $wgCacheEpoch ) ); // Modules without dependencies or a group pass two arguments (name, timestamp) to // mediaWiki.loader.register() if ( !count( $module->getDependencies() && $module->getGroup() === null ) ) { - $registrations[] = array( $name, $module->getModifiedTime( $context ) ); + $registrations[] = array( $name, $mtime ); } // Modules with dependencies but no group pass three arguments (name, timestamp, dependencies) // to mediaWiki.loader.register() else if ( $module->getGroup() === null ) { $registrations[] = array( - $name, $module->getModifiedTime( $context ), $module->getDependencies() ); + $name, $mtime, $module->getDependencies() ); } // Modules with dependencies pass four arguments (name, timestamp, dependencies, group) // to mediaWiki.loader.register() else { $registrations[] = array( - $name, $module->getModifiedTime( $context ), $module->getDependencies(), $module->getGroup() ); + $name, $mtime, $module->getDependencies(), $module->getGroup() ); } } } @@ -1103,7 +1115,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule { 'lang' => $context->getLanguage(), 'skin' => $context->getSkin(), 'debug' => $context->getDebug() ? 'true' : 'false', - 'version' => wfTimestamp( TS_ISO_8601, round( max( + 'version' => wfTimestamp( TS_ISO_8601_BASIC, round( max( $context->getResourceLoader()->getModule( 'jquery' )->getModifiedTime( $context ), $context->getResourceLoader()->getModule( 'mediawiki' )->getModifiedTime( $context ) ), -2 ) ) @@ -1114,18 +1126,18 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule { // Startup function $configuration = FormatJson::encode( $this->getConfig( $context ) ); $registrations = self::getModuleRegistrations( $context ); - $out .= "window.startUp = function() {\n\t$registrations\n\tmediaWiki.config.set( $configuration );\n};"; + $out .= "var startUp = function() {\n\t$registrations\n\tmediaWiki.config.set( $configuration );\n};"; // Conditional script injection $scriptTag = Xml::escapeJsString( Html::linkedScript( $wgLoadScript . '?' . wfArrayToCGI( $query ) ) ); - $out .= "if ( isCompatible() ) {\n\tdocument.write( '$scriptTag' );\n}\ndelete window['isCompatible'];"; + $out .= "if ( isCompatible() ) {\n\tdocument.write( '$scriptTag' );\n}\ndelete isCompatible;"; } return $out; } public function getModifiedTime( ResourceLoaderContext $context ) { - global $IP; + global $IP, $wgCacheEpoch; $hash = $context->getHash(); if ( isset( $this->modifiedTime[$hash] ) ) { @@ -1135,7 +1147,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule { // ATTENTION!: Because of the line above, this is not going to cause infinite recursion - think carefully // before making changes to this code! - $time = 1; // wfTimestamp() treats 0 as 'now', so that's not a suitable choice + $time = wfTimestamp( TS_UNIX, $wgCacheEpoch ); foreach ( $context->getResourceLoader()->getModules() as $module ) { $time = max( $time, $module->getModifiedTime( $context ) ); }