Merge "Skin: Make skins aware of their registered skin name"
[lhc/web/wiklou.git] / resources / src / mediawiki / mediawiki.js
index fc930ca..a661ae5 100644 (file)
                 * @param {Function} callback
                 */
                trackUnsubscribe: function ( callback ) {
-                       trackHandlers = $.grep( trackHandlers, function ( fns ) {
+                       trackHandlers = trackHandlers.filter( function ( fns ) {
                                if ( fns[ 1 ] === callback ) {
                                        trackCallbacks.remove( fns[ 0 ] );
                                        // Ensure the tuple is removed to avoid holding on to closures
                                                registry[ module ].dependencies = [ registry[ module ].dependencies ];
                                        }
                                }
-                               if ( $.inArray( module, resolved ) !== -1 ) {
+                               if ( resolved.indexOf( module ) !== -1 ) {
                                        // Module already resolved; nothing to do
                                        return;
                                }
                                // Tracks down dependencies
                                deps = registry[ module ].dependencies;
                                for ( i = 0; i < deps.length; i++ ) {
-                                       if ( $.inArray( deps[ i ], resolved ) === -1 ) {
+                                       if ( resolved.indexOf( deps[ i ] ) === -1 ) {
                                                if ( unresolved.has( deps[ i ] ) ) {
                                                        throw new Error( mw.format(
                                                                'Circular reference detected: $1 -> $2',
                                registry[ module ].state = 'executing';
 
                                runScript = function () {
-                                       var script, markModuleReady, nestedAddScript, implicitDependencies, implicitWait;
+                                       var script, markModuleReady, nestedAddScript;
 
                                        script = registry[ module ].script;
                                        markModuleReady = function () {
                                                } );
                                        };
 
-                                       implicitDependencies = [];
-
-                                       if ( module === 'user' ) {
-                                               // Implicit dependency on the site module. Not real dependency because
-                                               // it should run after 'site' regardless of whether it succeeds or fails.
-                                               implicitDependencies.push( 'site' );
-                                       }
-
-                                       implicitWait = implicitDependencies.length ?
-                                               mw.loader.using( implicitDependencies ) :
-                                               $.Deferred().resolve();
-
-                                       implicitWait.always( function () {
-                                               try {
-                                                       if ( Array.isArray( script ) ) {
-                                                               nestedAddScript( script, markModuleReady, 0 );
-                                                       } else if ( typeof script === 'function' ) {
-                                                               // Pass jQuery twice so that the signature of the closure which wraps
-                                                               // the script can bind both '$' and 'jQuery'.
-                                                               script( $, $, mw.loader.require, registry[ module ].module );
-                                                               markModuleReady();
-
-                                                       } else if ( typeof script === 'string' ) {
-                                                               // Site and user modules are legacy scripts that run in the global scope.
-                                                               // This is transported as a string instead of a function to avoid needing
-                                                               // to use string manipulation to undo the function wrapper.
-                                                               $.globalEval( script );
-                                                               markModuleReady();
+                                       try {
+                                               if ( Array.isArray( script ) ) {
+                                                       nestedAddScript( script, markModuleReady, 0 );
+                                               } else if ( typeof script === 'function' ) {
+                                                       // Pass jQuery twice so that the signature of the closure which wraps
+                                                       // the script can bind both '$' and 'jQuery'.
+                                                       script( $, $, mw.loader.require, registry[ module ].module );
+                                                       markModuleReady();
+
+                                               } else if ( typeof script === 'string' ) {
+                                                       // Site and user modules are legacy scripts that run in the global scope.
+                                                       // This is transported as a string instead of a function to avoid needing
+                                                       // to use string manipulation to undo the function wrapper.
+                                                       $.globalEval( script );
+                                                       markModuleReady();
 
-                                                       } else {
-                                                               // Module without script
-                                                               markModuleReady();
-                                                       }
-                                               } catch ( e ) {
-                                                       // Use mw.track instead of mw.log because these errors are common in production mode
-                                                       // (e.g. undefined variable), and mw.log is only enabled in debug mode.
-                                                       registry[ module ].state = 'error';
-                                                       mw.track( 'resourceloader.exception', { exception: e, module: module, source: 'module-execute' } );
-                                                       handlePending( module );
+                                               } else {
+                                                       // Module without script
+                                                       markModuleReady();
                                                }
-                                       } );
+                                       } catch ( e ) {
+                                               // Use mw.track instead of mw.log because these errors are common in production mode
+                                               // (e.g. undefined variable), and mw.log is only enabled in debug mode.
+                                               registry[ module ].state = 'error';
+                                               mw.track( 'resourceloader.exception', { exception: e, module: module, source: 'module-execute' } );
+                                               handlePending( module );
+                                       }
                                };
 
                                // Add localizations to message system
                                                // cssHandlesRegistered ensures we don't take off too soon, e.g. when
                                                // one of the cssHandles is fired while we're still creating more handles.
                                                if ( cssHandlesRegistered && pending === 0 && runScript ) {
-                                                       runScript();
+                                                       if ( module === 'user' ) {
+                                                               // Implicit dependency on the site module. Not real dependency because
+                                                               // it should run after 'site' regardless of whether it succeeds or fails.
+                                                               mw.loader.using( [ 'site' ] ).always( runScript );
+                                                       } else {
+                                                               runScript();
+                                                       }
                                                        runScript = undefined; // Revoke
                                                }
                                        };
                                if ( ready !== undefined || error !== undefined ) {
                                        jobs.push( {
                                                // Narrow down the list to modules that are worth waiting for
-                                               dependencies: $.grep( dependencies, function ( module ) {
+                                               dependencies: dependencies.filter( function ( module ) {
                                                        var state = mw.loader.getState( module );
                                                        return state === 'registered' || state === 'loaded' || state === 'loading' || state === 'executing';
                                                } ),
                                        } );
                                }
 
-                               $.each( dependencies, function ( idx, module ) {
+                               dependencies.forEach( function ( module ) {
                                        var state = mw.loader.getState( module );
                                        // Only queue modules that are still in the initial 'registered' state
                                        // (not ones already loading, ready or error).
-                                       if ( state === 'registered' && $.inArray( module, queue ) === -1 ) {
+                                       if ( state === 'registered' && queue.indexOf( module ) === -1 ) {
                                                // Private modules must be embedded in the page. Don't bother queuing
                                                // these as the server will deny them anyway (T101806).
                                                if ( registry[ module ].group === 'private' ) {
                                        a = [];
 
                                for ( key in o ) {
-                                       if ( hasOwn.call( o, key ) ) {
-                                               a.push( key );
-                                       }
+                                       a.push( key );
                                }
                                a.sort();
                                for ( key = 0; key < a.length; key++ ) {
                         * @param {string} sourceLoadScript URL of load.php
                         */
                        function doRequest( moduleMap, currReqBase, sourceLoadScript ) {
-                               var query = $.extend(
-                                       { modules: buildModulesString( moduleMap ) },
-                                       currReqBase
-                               );
+                               // Optimisation: Inherit (Object.create), not copy ($.extend)
+                               var query = Object.create( currReqBase );
+                               query.modules = buildModulesString( moduleMap );
                                query = sortQuery( query );
                                addScript( sourceLoadScript + '?' + $.param( query ) );
                        }
                                                // modules for this group from this source.
                                                modules = splits[ source ][ group ];
 
-                                               currReqBase = $.extend( {
-                                                       version: getCombinedVersion( modules )
-                                               }, reqBase );
+                                               // Optimisation: Inherit (Object.create), not copy ($.extend)
+                                               currReqBase = Object.create( reqBase );
+                                               currReqBase.version = getCombinedVersion( modules );
+
                                                // For user modules append a user name to the query string.
                                                if ( group === 'user' && mw.config.get( 'wgUserName' ) !== null ) {
                                                        currReqBase.user = mw.config.get( 'wgUserName' );
                        function splitModuleKey( key ) {
                                var index = key.indexOf( '@' );
                                if ( index === -1 ) {
-                                       return { name: key };
+                                       return {
+                                               name: key,
+                                               version: ''
+                                       };
                                }
                                return {
                                        name: key.slice( 0, index ),
                                                // Only load modules which are registered
                                                if ( hasOwn.call( registry, queue[ q ] ) && registry[ queue[ q ] ].state === 'registered' ) {
                                                        // Prevent duplicate entries
-                                                       if ( $.inArray( queue[ q ], batch ) === -1 ) {
+                                                       if ( batch.indexOf( queue[ q ] ) === -1 ) {
                                                                batch.push( queue[ q ] );
                                                                // Mark registered modules as loading
                                                                registry[ queue[ q ] ].state = 'loading';
                                        if ( mw.loader.store.enabled ) {
                                                implementations = [];
                                                sourceModules = [];
-                                               batch = $.grep( batch, function ( module ) {
+                                               batch = batch.filter( function ( module ) {
                                                        var implementation = mw.loader.store.get( module );
                                                        if ( implementation ) {
                                                                implementations.push( implementation );
 
                                                        mw.track( 'resourceloader.exception', { exception: err, source: 'store-eval' } );
                                                        // Re-add the failed ones that are still pending back to the batch
-                                                       failed = $.grep( sourceModules, function ( module ) {
+                                                       failed = sourceModules.filter( function ( module ) {
                                                                return registry[ module ].state === 'loading';
                                                        } );
                                                        batchRequest( failed );
                                        registry[ name ].messages = messages || null;
                                        registry[ name ].templates = templates || null;
                                        // The module may already have been marked as erroneous
-                                       if ( $.inArray( registry[ name ].state, [ 'error', 'missing' ] ) === -1 ) {
+                                       if ( registry[ name ].state !== 'error' && registry[ name ].state !== 'missing' ) {
                                                registry[ name ].state = 'loaded';
                                                if ( allReady( registry[ name ].dependencies ) ) {
                                                        execute( name );
                                        }
 
                                        // Filter out top-level modules that are unknown or failed to load before.
-                                       filtered = $.grep( modules, function ( module ) {
+                                       filtered = modules.filter( function ( module ) {
                                                var state = mw.loader.getState( module );
                                                return state !== 'error' && state !== 'missing';
                                        } );
                                                mw.loader.register( module );
                                        }
                                        registry[ module ].state = state;
-                                       if ( $.inArray( state, [ 'ready', 'error', 'missing' ] ) !== -1 ) {
+                                       if ( state === 'ready' || state === 'error' || state === 'missing' ) {
                                                // Make sure pending modules depending on this one get executed if their
                                                // dependencies are now fulfilled!
                                                handlePending( module );
                                 *  in the registry.
                                 */
                                getVersion: function ( module ) {
-                                       if ( !hasOwn.call( registry, module ) || registry[ module ].version === undefined ) {
-                                               return null;
-                                       }
-                                       return registry[ module ].version;
+                                       return hasOwn.call( registry, module ) ? registry[ module ].version : null;
                                },
 
                                /**
                                 *  in the registry.
                                 */
                                getState: function ( module ) {
-                                       if ( !hasOwn.call( registry, module ) || registry[ module ].state === undefined ) {
-                                               return null;
-                                       }
-                                       return registry[ module ].state;
+                                       return hasOwn.call( registry, module ) ? registry[ module ].state : null;
                                },
 
                                /**
                                                        // Module failed to load
                                                        descriptor.state !== 'ready' ||
                                                        // Unversioned, private, or site-/user-specific
-                                                       ( !descriptor.version || $.inArray( descriptor.group, [ 'private', 'user' ] ) !== -1 ) ||
+                                                       !descriptor.version ||
+                                                       descriptor.group === 'private' ||
+                                                       descriptor.group === 'user' ||
                                                        // Partial descriptor
                                                        // (e.g. skipped module, or style module with state=ready)
-                                                       $.inArray( undefined, [ descriptor.script, descriptor.style,
-                                                               descriptor.messages, descriptor.templates ] ) !== -1
+                                                       [ descriptor.script, descriptor.style, descriptor.messages,
+                                                               descriptor.templates ].indexOf( undefined ) !== -1
                                                ) {
                                                        // Decline to store
                                                        return false;
        $( function () {
                var loading, modules;
 
-               modules = $.grep( mw.loader.getModuleNames(), function ( module ) {
+               modules = mw.loader.getModuleNames().filter( function ( module ) {
                        return mw.loader.getState( module ) === 'loading';
                } );
                // We only need a callback, not any actual module. First try a single using()