MediaWiki
REL1_21
|
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 $target = $context->getRequest()->getVal( 'target', 'desktop' ); 00118 00119 // Register sources 00120 $out .= ResourceLoader::makeLoaderSourcesScript( $resourceLoader->getSources() ); 00121 00122 // Register modules 00123 foreach ( $resourceLoader->getModuleNames() as $name ) { 00124 $module = $resourceLoader->getModule( $name ); 00125 $moduleTargets = $module->getTargets(); 00126 if ( !in_array( $target, $moduleTargets ) ) { 00127 continue; 00128 } 00129 $deps = $module->getDependencies(); 00130 $group = $module->getGroup(); 00131 $source = $module->getSource(); 00132 // Support module loader scripts 00133 $loader = $module->getLoaderScript(); 00134 if ( $loader !== false ) { 00135 $version = wfTimestamp( TS_ISO_8601_BASIC, 00136 $module->getModifiedTime( $context ) ); 00137 $out .= ResourceLoader::makeCustomLoaderScript( $name, $version, $deps, $group, $source, $loader ); 00138 continue; 00139 } 00140 00141 // Automatically register module 00142 // getModifiedTime() is supposed to return a UNIX timestamp, but it doesn't always 00143 // seem to do that, and custom implementations might forget. Coerce it to TS_UNIX 00144 $moduleMtime = wfTimestamp( TS_UNIX, $module->getModifiedTime( $context ) ); 00145 $mtime = max( $moduleMtime, wfTimestamp( TS_UNIX, $wgCacheEpoch ) ); 00146 // Modules without dependencies, a group or a foreign source pass two arguments (name, timestamp) to 00147 // mw.loader.register() 00148 if ( !count( $deps ) && $group === null && $source === 'local' ) { 00149 $registrations[] = array( $name, $mtime ); 00150 } 00151 // Modules with dependencies but no group or foreign source pass three arguments 00152 // (name, timestamp, dependencies) to mw.loader.register() 00153 elseif ( $group === null && $source === 'local' ) { 00154 $registrations[] = array( $name, $mtime, $deps ); 00155 } 00156 // Modules with a group but no foreign source pass four arguments (name, timestamp, dependencies, group) 00157 // to mw.loader.register() 00158 elseif ( $source === 'local' ) { 00159 $registrations[] = array( $name, $mtime, $deps, $group ); 00160 } 00161 // Modules with a foreign source pass five arguments (name, timestamp, dependencies, group, source) 00162 // to mw.loader.register() 00163 else { 00164 $registrations[] = array( $name, $mtime, $deps, $group, $source ); 00165 } 00166 } 00167 $out .= ResourceLoader::makeLoaderRegisterScript( $registrations ); 00168 00169 wfProfileOut( __METHOD__ ); 00170 return $out; 00171 } 00172 00173 /* Methods */ 00174 00178 public function isRaw() { 00179 return true; 00180 } 00181 00186 public function getScript( ResourceLoaderContext $context ) { 00187 global $IP, $wgLoadScript, $wgLegacyJavaScriptGlobals; 00188 00189 $out = file_get_contents( "$IP/resources/startup.js" ); 00190 if ( $context->getOnly() === 'scripts' ) { 00191 00192 // The core modules: 00193 $moduleNames = array( 'jquery', 'mediawiki' ); 00194 wfRunHooks( 'ResourceLoaderGetStartupModules', array( &$moduleNames ) ); 00195 00196 // Get the latest version 00197 $loader = $context->getResourceLoader(); 00198 $version = 0; 00199 foreach ( $moduleNames as $moduleName ) { 00200 $version = max( $version, 00201 $loader->getModule( $moduleName )->getModifiedTime( $context ) 00202 ); 00203 } 00204 // Build load query for StartupModules 00205 $query = array( 00206 'modules' => ResourceLoader::makePackedModulesString( $moduleNames ), 00207 'only' => 'scripts', 00208 'lang' => $context->getLanguage(), 00209 'skin' => $context->getSkin(), 00210 'debug' => $context->getDebug() ? 'true' : 'false', 00211 'version' => wfTimestamp( TS_ISO_8601_BASIC, $version ) 00212 ); 00213 // Ensure uniform query order 00214 ksort( $query ); 00215 00216 // Startup function 00217 $configuration = $this->getConfig( $context ); 00218 $registrations = self::getModuleRegistrations( $context ); 00219 $registrations = str_replace( "\n", "\n\t", trim( $registrations ) ); // fix indentation 00220 $out .= "var startUp = function() {\n" . 00221 "\tmw.config = new " . Xml::encodeJsCall( 'mw.Map', array( $wgLegacyJavaScriptGlobals ) ) . "\n" . 00222 "\t$registrations\n" . 00223 "\t" . Xml::encodeJsCall( 'mw.config.set', array( $configuration ) ) . 00224 "};\n"; 00225 00226 // Conditional script injection 00227 $scriptTag = Html::linkedScript( $wgLoadScript . '?' . wfArrayToCgi( $query ) ); 00228 $out .= "if ( isCompatible() ) {\n" . 00229 "\t" . Xml::encodeJsCall( 'document.write', array( $scriptTag ) ) . 00230 "}\n" . 00231 "delete isCompatible;"; 00232 } 00233 00234 return $out; 00235 } 00236 00240 public function supportsURLLoading() { 00241 return false; 00242 } 00243 00248 public function getModifiedTime( ResourceLoaderContext $context ) { 00249 global $IP, $wgCacheEpoch; 00250 00251 $hash = $context->getHash(); 00252 if ( isset( $this->modifiedTime[$hash] ) ) { 00253 return $this->modifiedTime[$hash]; 00254 } 00255 00256 // Call preloadModuleInfo() on ALL modules as we're about 00257 // to call getModifiedTime() on all of them 00258 $loader = $context->getResourceLoader(); 00259 $loader->preloadModuleInfo( $loader->getModuleNames(), $context ); 00260 00261 $this->modifiedTime[$hash] = filemtime( "$IP/resources/startup.js" ); 00262 // ATTENTION!: Because of the line above, this is not going to cause 00263 // infinite recursion - think carefully before making changes to this 00264 // code! 00265 $time = wfTimestamp( TS_UNIX, $wgCacheEpoch ); 00266 foreach ( $loader->getModuleNames() as $name ) { 00267 $module = $loader->getModule( $name ); 00268 $time = max( $time, $module->getModifiedTime( $context ) ); 00269 } 00270 return $this->modifiedTime[$hash] = $time; 00271 } 00272 00273 /* Methods */ 00274 00278 public function getGroup() { 00279 return 'startup'; 00280 } 00281 }