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