* Format:
* {
* 'moduleName': {
+ * // At registry
* 'version': ############## (unix timestamp),
* 'dependencies': ['required.foo', 'bar.also', ...], (or) function () {}
* 'group': 'somegroup', (or) null,
* 'source': 'local', 'someforeignwiki', (or) null
* 'state': 'registered', 'loaded', 'loading', 'ready', 'error' or 'missing'
+ * 'skip': 'return !!window.Example', (or) null
+ *
+ * // Added during implementation
+ * 'skipped': true,
* 'script': ...,
* 'style': ...,
* 'messages': { 'key': 'value' },
/* Private methods */
function getMarker() {
- // Cached ?
- if ( $marker ) {
- return $marker;
- }
-
- $marker = $( 'meta[name="ResourceLoaderDynamicStyles"]' );
- if ( $marker.length ) {
- return $marker;
+ // Cached
+ if ( !$marker ) {
+ $marker = $( 'meta[name="ResourceLoaderDynamicStyles"]' );
+ if ( !$marker.length ) {
+ mw.log( 'No <meta name="ResourceLoaderDynamicStyles"> found, inserting dynamically' );
+ $marker = $( '<meta>' ).attr( 'name', 'ResourceLoaderDynamicStyles' ).appendTo( 'head' );
+ }
}
- mw.log( 'getMarker> No <meta name="ResourceLoaderDynamicStyles"> found, inserting dynamically.' );
- $marker = $( '<meta>' ).attr( 'name', 'ResourceLoaderDynamicStyles' ).appendTo( 'head' );
-
return $marker;
}
* @throws {Error} If any unregistered module or a dependency loop is encountered
*/
function sortDependencies( module, resolved, unresolved ) {
- var n, deps, len;
+ var n, deps, len, skip;
if ( registry[module] === undefined ) {
throw new Error( 'Unknown dependency: ' + module );
}
+
+ if ( registry[module].skip !== null ) {
+ /*jshint evil:true */
+ skip = new Function( registry[module].skip );
+ registry[module].skip = null;
+ if ( skip() ) {
+ registry[module].skipped = true;
+ registry[module].dependencies = [];
+ registry[module].state = 'ready';
+ handlePending( module );
+ return;
+ }
+ }
+
// Resolves dynamic loader function and replaces it with its own results
if ( $.isFunction( registry[module].dependencies ) ) {
registry[module].dependencies = registry[module].dependencies();
} catch ( e ) {
// A user-defined callback raised an exception.
// Swallow it to protect our state machine!
- log( 'Exception thrown by job.error', e );
+ log( 'Exception thrown by user callback', e );
}
}
}
crossDomain: true,
cache: true,
async: true
- } ).always( function () {
- if ( callback ) {
- callback();
- }
- } );
+ } ).always( callback );
} else {
/*jshint evil:true */
document.write( mw.html.element( 'script', { 'src': src }, '' ) );
* names on which this module depends, or a function that returns that array.
* @param {string} [group=null] Group which the module is in
* @param {string} [source='local'] Name of the source
+ * @param {string} [skip=null] Script body of the skip function
*/
- register: function ( module, version, dependencies, group, source ) {
+ register: function ( module, version, dependencies, group, source, skip ) {
var m;
// Allow multiple registration
if ( typeof module === 'object' ) {
dependencies: [],
group: typeof group === 'string' ? group : null,
source: typeof source === 'string' ? source : 'local',
- state: 'registered'
+ state: 'registered',
+ skip: typeof skip === 'string' ? skip : null
};
if ( typeof dependencies === 'string' ) {
// Allow dependencies to be given as a single module name