MediaWiki
REL1_20
|
00001 <?php 00025 class ResourceLoaderStartUpModule extends ResourceLoaderModule { 00026 00027 /* Protected Members */ 00028 00029 protected $modifiedTime = array(); 00030 00031 /* Protected Methods */ 00032 00037 protected function getConfig( $context ) { 00038 global $wgLoadScript, $wgScript, $wgStylePath, $wgScriptExtension, 00039 $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, 00040 $wgVariantArticlePath, $wgActionPaths, $wgVersion, 00041 $wgEnableAPI, $wgEnableWriteAPI, $wgDBname, 00042 $wgSitename, $wgFileExtensions, $wgExtensionAssetsPath, 00043 $wgCookiePrefix, $wgResourceLoaderMaxQueryLength; 00044 00045 $mainPage = Title::newMainPage(); 00046 00052 $namespaceIds = $wgContLang->getNamespaceIds(); 00053 $caseSensitiveNamespaces = array(); 00054 foreach( MWNamespace::getCanonicalNamespaces() as $index => $name ) { 00055 $namespaceIds[$wgContLang->lc( $name )] = $index; 00056 if ( !MWNamespace::isCapitalized( $index ) ) { 00057 $caseSensitiveNamespaces[] = $index; 00058 } 00059 } 00060 00061 // Build list of variables 00062 $vars = array( 00063 'wgLoadScript' => $wgLoadScript, 00064 'debug' => $context->getDebug(), 00065 'skin' => $context->getSkin(), 00066 'stylepath' => $wgStylePath, 00067 'wgUrlProtocols' => wfUrlProtocols(), 00068 'wgArticlePath' => $wgArticlePath, 00069 'wgScriptPath' => $wgScriptPath, 00070 'wgScriptExtension' => $wgScriptExtension, 00071 'wgScript' => $wgScript, 00072 'wgVariantArticlePath' => $wgVariantArticlePath, 00073 // Force object to avoid "empty" associative array from 00074 // becoming [] instead of {} in JS (bug 34604) 00075 'wgActionPaths' => (object)$wgActionPaths, 00076 'wgServer' => $wgServer, 00077 'wgUserLanguage' => $context->getLanguage(), 00078 'wgContentLanguage' => $wgContLang->getCode(), 00079 'wgVersion' => $wgVersion, 00080 'wgEnableAPI' => $wgEnableAPI, 00081 'wgEnableWriteAPI' => $wgEnableWriteAPI, 00082 'wgMainPageTitle' => $mainPage->getPrefixedText(), 00083 'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(), 00084 'wgNamespaceIds' => $namespaceIds, 00085 'wgSiteName' => $wgSitename, 00086 'wgFileExtensions' => array_values( $wgFileExtensions ), 00087 'wgDBname' => $wgDBname, 00088 // This sucks, it is only needed on Special:Upload, but I could 00089 // not find a way to add vars only for a certain module 00090 'wgFileCanRotate' => BitmapHandler::canRotate(), 00091 'wgAvailableSkins' => Skin::getSkinNames(), 00092 'wgExtensionAssetsPath' => $wgExtensionAssetsPath, 00093 // MediaWiki sets cookies to have this prefix by default 00094 'wgCookiePrefix' => $wgCookiePrefix, 00095 'wgResourceLoaderMaxQueryLength' => $wgResourceLoaderMaxQueryLength, 00096 'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces, 00097 ); 00098 00099 wfRunHooks( 'ResourceLoaderGetConfigVars', array( &$vars ) ); 00100 00101 return $vars; 00102 } 00103 00110 public static function getModuleRegistrations( ResourceLoaderContext $context ) { 00111 global $wgCacheEpoch; 00112 wfProfileIn( __METHOD__ ); 00113 00114 $out = ''; 00115 $registrations = array(); 00116 $resourceLoader = $context->getResourceLoader(); 00117 00118 // Register sources 00119 $out .= ResourceLoader::makeLoaderSourcesScript( $resourceLoader->getSources() ); 00120 00121 // Register modules 00122 foreach ( $resourceLoader->getModuleNames() as $name ) { 00123 $module = $resourceLoader->getModule( $name ); 00124 $deps = $module->getDependencies(); 00125 $group = $module->getGroup(); 00126 $source = $module->getSource(); 00127 // Support module loader scripts 00128 $loader = $module->getLoaderScript(); 00129 if ( $loader !== false ) { 00130 $version = wfTimestamp( TS_ISO_8601_BASIC, 00131 $module->getModifiedTime( $context ) ); 00132 $out .= ResourceLoader::makeCustomLoaderScript( $name, $version, $deps, $group, $source, $loader ); 00133 } 00134 // Automatically register module 00135 else { 00136 // getModifiedTime() is supposed to return a UNIX timestamp, but it doesn't always 00137 // seem to do that, and custom implementations might forget. Coerce it to TS_UNIX 00138 $moduleMtime = wfTimestamp( TS_UNIX, $module->getModifiedTime( $context ) ); 00139 $mtime = max( $moduleMtime, wfTimestamp( TS_UNIX, $wgCacheEpoch ) ); 00140 // Modules without dependencies, a group or a foreign source pass two arguments (name, timestamp) to 00141 // mw.loader.register() 00142 if ( !count( $deps ) && $group === null && $source === 'local' ) { 00143 $registrations[] = array( $name, $mtime ); 00144 } 00145 // Modules with dependencies but no group or foreign source pass three arguments 00146 // (name, timestamp, dependencies) to mw.loader.register() 00147 elseif ( $group === null && $source === 'local' ) { 00148 $registrations[] = array( $name, $mtime, $deps ); 00149 } 00150 // Modules with a group but no foreign source pass four arguments (name, timestamp, dependencies, group) 00151 // to mw.loader.register() 00152 elseif ( $source === 'local' ) { 00153 $registrations[] = array( $name, $mtime, $deps, $group ); 00154 } 00155 // Modules with a foreign source pass five arguments (name, timestamp, dependencies, group, source) 00156 // to mw.loader.register() 00157 else { 00158 $registrations[] = array( $name, $mtime, $deps, $group, $source ); 00159 } 00160 } 00161 } 00162 $out .= ResourceLoader::makeLoaderRegisterScript( $registrations ); 00163 00164 wfProfileOut( __METHOD__ ); 00165 return $out; 00166 } 00167 00168 /* Methods */ 00169 00173 public function isRaw() { 00174 return true; 00175 } 00176 00181 public function getScript( ResourceLoaderContext $context ) { 00182 global $IP, $wgLoadScript, $wgLegacyJavaScriptGlobals; 00183 00184 $out = file_get_contents( "$IP/resources/startup.js" ); 00185 if ( $context->getOnly() === 'scripts' ) { 00186 00187 // The core modules: 00188 $moduleNames = array( 'jquery', 'mediawiki' ); 00189 wfRunHooks( 'ResourceLoaderGetStartupModules', array( &$moduleNames ) ); 00190 00191 // Get the latest version 00192 $loader = $context->getResourceLoader(); 00193 $version = 0; 00194 foreach ( $moduleNames as $moduleName ) { 00195 $version = max( $version, 00196 $loader->getModule( $moduleName )->getModifiedTime( $context ) 00197 ); 00198 } 00199 // Build load query for StartupModules 00200 $query = array( 00201 'modules' => ResourceLoader::makePackedModulesString( $moduleNames ), 00202 'only' => 'scripts', 00203 'lang' => $context->getLanguage(), 00204 'skin' => $context->getSkin(), 00205 'debug' => $context->getDebug() ? 'true' : 'false', 00206 'version' => wfTimestamp( TS_ISO_8601_BASIC, $version ) 00207 ); 00208 // Ensure uniform query order 00209 ksort( $query ); 00210 00211 // Startup function 00212 $configuration = $this->getConfig( $context ); 00213 $registrations = self::getModuleRegistrations( $context ); 00214 $registrations = str_replace( "\n", "\n\t", trim( $registrations ) ); // fix indentation 00215 $out .= "var startUp = function() {\n" . 00216 "\tmw.config = new " . Xml::encodeJsCall( 'mw.Map', array( $wgLegacyJavaScriptGlobals ) ) . "\n" . 00217 "\t$registrations\n" . 00218 "\t" . Xml::encodeJsCall( 'mw.config.set', array( $configuration ) ) . 00219 "};\n"; 00220 00221 // Conditional script injection 00222 $scriptTag = Html::linkedScript( $wgLoadScript . '?' . wfArrayToCGI( $query ) ); 00223 $out .= "if ( isCompatible() ) {\n" . 00224 "\t" . Xml::encodeJsCall( 'document.write', array( $scriptTag ) ) . 00225 "}\n" . 00226 "delete isCompatible;"; 00227 } 00228 00229 return $out; 00230 } 00231 00235 public function supportsURLLoading() { 00236 return false; 00237 } 00238 00243 public function getModifiedTime( ResourceLoaderContext $context ) { 00244 global $IP, $wgCacheEpoch; 00245 00246 $hash = $context->getHash(); 00247 if ( isset( $this->modifiedTime[$hash] ) ) { 00248 return $this->modifiedTime[$hash]; 00249 } 00250 00251 // Call preloadModuleInfo() on ALL modules as we're about 00252 // to call getModifiedTime() on all of them 00253 $loader = $context->getResourceLoader(); 00254 $loader->preloadModuleInfo( $loader->getModuleNames(), $context ); 00255 00256 $this->modifiedTime[$hash] = filemtime( "$IP/resources/startup.js" ); 00257 // ATTENTION!: Because of the line above, this is not going to cause 00258 // infinite recursion - think carefully before making changes to this 00259 // code! 00260 $time = wfTimestamp( TS_UNIX, $wgCacheEpoch ); 00261 foreach ( $loader->getModuleNames() as $name ) { 00262 $module = $loader->getModule( $name ); 00263 $time = max( $time, $module->getModifiedTime( $context ) ); 00264 } 00265 return $this->modifiedTime[$hash] = $time; 00266 } 00267 00268 /* Methods */ 00269 00273 public function getGroup() { 00274 return 'startup'; 00275 } 00276 }