Merge "Whitespace and typo fix"
[lhc/web/wiklou.git] / includes / resourceloader / ResourceLoaderStartUpModule.php
index 87b0cb5..3384631 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 class ResourceLoaderStartUpModule extends ResourceLoaderModule {
-       
+
        /* Protected Members */
 
        protected $modifiedTime = array();
@@ -33,27 +33,29 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
         * @return array
         */
        protected function getConfig( $context ) {
-               global $wgLoadScript, $wgScript, $wgStylePath, $wgScriptExtension, 
-                       $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, 
-                       $wgVariantArticlePath, $wgActionPaths, $wgUseAjax, $wgVersion, 
-                       $wgEnableAPI, $wgEnableWriteAPI, $wgDBname, $wgEnableMWSuggest, 
-                       $wgSitename, $wgFileExtensions, $wgExtensionAssetsPath;
-
-               // 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 ),
-               );
+               global $wgLoadScript, $wgScript, $wgStylePath, $wgScriptExtension,
+                       $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang,
+                       $wgVariantArticlePath, $wgActionPaths, $wgUseAjax, $wgVersion,
+                       $wgEnableAPI, $wgEnableWriteAPI, $wgDBname, $wgEnableMWSuggest,
+                       $wgSitename, $wgFileExtensions, $wgExtensionAssetsPath,
+                       $wgCookiePrefix, $wgResourceLoaderMaxQueryLength;
+
                $mainPage = Title::newMainPage();
-               
+
+               /**
+                * Namespace related preparation
+                * - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces.
+                * - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive.
+                */
+               $namespaceIds = $wgContLang->getNamespaceIds();
+               $caseSensitiveNamespaces = array();
+               foreach( MWNamespace::getCanonicalNamespaces() as $index => $name ) {
+                       $namespaceIds[$wgContLang->lc( $name )] = $index;
+                       if ( !MWNamespace::isCapitalized( $index ) ) {
+                               $caseSensitiveNamespaces[] = $index;
+                       }
+               }
+
                // Build list of variables
                $vars = array(
                        'wgLoadScript' => $wgLoadScript,
@@ -66,36 +68,43 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        'wgScriptExtension' => $wgScriptExtension,
                        'wgScript' => $wgScript,
                        'wgVariantArticlePath' => $wgVariantArticlePath,
-                       'wgActionPaths' => $wgActionPaths,
+                       // Force object to avoid "empty" associative array from
+                       // becoming [] instead of {} in JS (bug 34604)
+                       'wgActionPaths' => (object)$wgActionPaths,
                        'wgServer' => $wgServer,
                        'wgUserLanguage' => $context->getLanguage(),
                        'wgContentLanguage' => $wgContLang->getCode(),
                        'wgVersion' => $wgVersion,
                        'wgEnableAPI' => $wgEnableAPI,
                        'wgEnableWriteAPI' => $wgEnableWriteAPI,
-                       'wgSeparatorTransformTable' => $compactSeparatorTransTable,
-                       'wgDigitTransformTable' => $compactDigitTransTable,
-                       'wgMainPageTitle' => $mainPage ? $mainPage->getPrefixedText() : null,
+                       'wgDefaultDateFormat' => $wgContLang->getDefaultDateFormat(),
+                       'wgMonthNames' => $wgContLang->getMonthNamesArray(),
+                       'wgMonthNamesShort' => $wgContLang->getMonthAbbreviationsArray(),
+                       'wgMainPageTitle' => $mainPage->getPrefixedText(),
                        'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(),
-                       'wgNamespaceIds' => $wgContLang->getNamespaceIds(),
+                       'wgNamespaceIds' => $namespaceIds,
                        'wgSiteName' => $wgSitename,
                        'wgFileExtensions' => array_values( $wgFileExtensions ),
                        'wgDBname' => $wgDBname,
-                       // This sucks, it is only needed on Special:Upload, but I could 
+                       // This sucks, it is only needed on Special:Upload, but I could
                        // not find a way to add vars only for a certain module
                        'wgFileCanRotate' => BitmapHandler::canRotate(),
                        'wgAvailableSkins' => Skin::getSkinNames(),
                        'wgExtensionAssetsPath' => $wgExtensionAssetsPath,
+                       // MediaWiki sets cookies to have this prefix by default
+                       'wgCookiePrefix' => $wgCookiePrefix,
+                       'wgResourceLoaderMaxQueryLength' => $wgResourceLoaderMaxQueryLength,
+                       'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces,
                );
                if ( $wgUseAjax && $wgEnableMWSuggest ) {
                        $vars['wgMWSuggestTemplate'] = SearchEngine::getMWSuggestTemplate();
                }
-               
+
                wfRunHooks( 'ResourceLoaderGetConfigVars', array( &$vars ) );
-               
+
                return $vars;
        }
-       
+
        /**
         * Gets registration code for all modules
         *
@@ -105,20 +114,26 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
        public static function getModuleRegistrations( ResourceLoaderContext $context ) {
                global $wgCacheEpoch;
                wfProfileIn( __METHOD__ );
-               
+
                $out = '';
                $registrations = array();
                $resourceLoader = $context->getResourceLoader();
+
+               // Register sources
+               $out .= ResourceLoader::makeLoaderSourcesScript( $resourceLoader->getSources() );
+
+               // Register modules
                foreach ( $resourceLoader->getModuleNames() as $name ) {
                        $module = $resourceLoader->getModule( $name );
+                       $deps = $module->getDependencies();
+                       $group = $module->getGroup();
+                       $source = $module->getSource();
                        // Support module loader scripts
                        $loader = $module->getLoaderScript();
                        if ( $loader !== false ) {
-                               $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 );
+                               $version = wfTimestamp( TS_ISO_8601_BASIC,
+                                       $module->getModifiedTime( $context ) );
+                               $out .= ResourceLoader::makeCustomLoaderScript( $name, $version, $deps, $group, $source, $loader );
                        }
                        // Automatically register module
                        else {
@@ -126,72 +141,102 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                                // seem to do that, and custom implementations might forget. Coerce it to TS_UNIX
                                $moduleMtime = wfTimestamp( TS_UNIX, $module->getModifiedTime( $context ) );
                                $mtime = max( $moduleMtime, wfTimestamp( TS_UNIX, $wgCacheEpoch ) );
-                               // Modules without dependencies or a group pass two arguments (name, timestamp) to 
+                               // Modules without dependencies, a group or a foreign source pass two arguments (name, timestamp) to
                                // mw.loader.register()
-                               if ( !count( $module->getDependencies() && $module->getGroup() === null ) ) {
+                               if ( !count( $deps ) && $group === null && $source === 'local' ) {
                                        $registrations[] = array( $name, $mtime );
                                }
-                               // Modules with dependencies but no group pass three arguments 
+                               // Modules with dependencies but no group or foreign source pass three arguments
                                // (name, timestamp, dependencies) to mw.loader.register()
-                               else if ( $module->getGroup() === null ) {
-                                       $registrations[] = array(
-                                               $name, $mtime,  $module->getDependencies() );
+                               elseif ( $group === null && $source === 'local' ) {
+                                       $registrations[] = array( $name, $mtime, $deps );
+                               }
+                               // Modules with a group but no foreign source pass four arguments (name, timestamp, dependencies, group)
+                               // to mw.loader.register()
+                               elseif ( $source === 'local' ) {
+                                       $registrations[] = array( $name, $mtime, $deps, $group );
                                }
-                               // Modules with dependencies pass four arguments (name, timestamp, dependencies, group) 
+                               // Modules with a foreign source pass five arguments (name, timestamp, dependencies, group, source)
                                // to mw.loader.register()
                                else {
-                                       $registrations[] = array(
-                                               $name, $mtime,  $module->getDependencies(), $module->getGroup() );
+                                       $registrations[] = array( $name, $mtime, $deps, $group, $source );
                                }
                        }
                }
                $out .= ResourceLoader::makeLoaderRegisterScript( $registrations );
-               
+
                wfProfileOut( __METHOD__ );
                return $out;
        }
 
        /* Methods */
 
+       /**
+        * @param $context ResourceLoaderContext
+        * @return string
+        */
        public function getScript( ResourceLoaderContext $context ) {
-               global $IP, $wgLoadScript;
+               global $IP, $wgLoadScript, $wgLegacyJavaScriptGlobals;
 
                $out = file_get_contents( "$IP/resources/startup.js" );
                if ( $context->getOnly() === 'scripts' ) {
-                       // Build load query for jquery and mediawiki modules
+
+                       // The core modules:
+                       $moduleNames = array( 'jquery', 'mediawiki' );
+                       wfRunHooks( 'ResourceLoaderGetStartupModules', array( &$moduleNames ) );
+
+                       // Get the latest version
+                       $loader = $context->getResourceLoader();
+                       $version = 0;
+                       foreach ( $moduleNames as $moduleName ) {
+                               $version = max( $version,
+                                       $loader->getModule( $moduleName )->getModifiedTime( $context )
+                               );
+                       }
+                       // Build load query for StartupModules
                        $query = array(
-                               'modules' => implode( '|', array( 'jquery', 'mediawiki' ) ),
+                               'modules' => ResourceLoader::makePackedModulesString( $moduleNames ),
                                'only' => 'scripts',
                                'lang' => $context->getLanguage(),
                                'skin' => $context->getSkin(),
                                'debug' => $context->getDebug() ? 'true' : 'false',
-                               'version' => wfTimestamp( TS_ISO_8601_BASIC, round( max(
-                                       $context->getResourceLoader()->getModule( 'jquery' )->getModifiedTime( $context ),
-                                       $context->getResourceLoader()->getModule( 'mediawiki' )->getModifiedTime( $context )
-                               ), -2 ) )
+                               'version' => wfTimestamp( TS_ISO_8601_BASIC, $version )
                        );
                        // Ensure uniform query order
                        ksort( $query );
-                       
+
                        // Startup function
                        $configuration = $this->getConfig( $context );
                        $registrations = self::getModuleRegistrations( $context );
-                       $out .= "var startUp = function() {\n" . 
-                               "\t$registrations\n" . 
-                               "\t" . Xml::encodeJsCall( 'mw.config.set', array( $configuration ) ) . 
+                       $registrations = str_replace( "\n", "\n\t", trim( $registrations ) ); // fix indentation
+                       $out .= "var startUp = function() {\n" .
+                               "\tmw.config = new " . Xml::encodeJsCall( 'mw.Map', array( $wgLegacyJavaScriptGlobals ) ) . "\n" .
+                               "\t$registrations\n" .
+                               "\t" . Xml::encodeJsCall( 'mw.config.set', array( $configuration ) ) .
                                "};\n";
-                       
+
                        // Conditional script injection
                        $scriptTag = Html::linkedScript( $wgLoadScript . '?' . wfArrayToCGI( $query ) );
-                       $out .= "if ( isCompatible() ) {\n" . 
-                               "\t" . Xml::encodeJsCall( 'document.write', array( $scriptTag ) ) . 
-                               "}\n" . 
+                       $out .= "if ( isCompatible() ) {\n" .
+                               "\t" . Xml::encodeJsCall( 'document.write', array( $scriptTag ) ) .
+                               "}\n" .
                                "delete isCompatible;";
                }
 
                return $out;
        }
 
+       /**
+        * @return bool
+        */
+       public function supportsURLLoading() {
+               return false;
+       }
+
+       /**
+        * @param $context ResourceLoaderContext
+        * @return array|mixed
+        */
        public function getModifiedTime( ResourceLoaderContext $context ) {
                global $IP, $wgCacheEpoch;
 
@@ -207,7 +252,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
 
                $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 
+               // infinite recursion - think carefully before making changes to this
                // code!
                $time = wfTimestamp( TS_UNIX, $wgCacheEpoch );
                foreach ( $loader->getModuleNames() as $name ) {
@@ -217,18 +262,11 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                return $this->modifiedTime[$hash] = $time;
        }
 
+       /* Methods */
+
        /**
-        * @param $context ResourceLoaderContext
-        * @return bool
+        * @return string
         */
-       public function getFlip( $context ) {
-               global $wgContLang;
-
-               return $wgContLang->getDir() !== $context->getDirection();
-       }
-       
-       /* Methods */
-       
        public function getGroup() {
                return 'startup';
        }