microtask
Version:
287 lines (242 loc) • 6.95 kB
JavaScript
;(function(){
/**
* Require the given path.
*
* @param {String} path
* @return {Object} exports
* @api public
*/
function require(p, parent, orig){
var path = require.resolve(p)
, mod = require.modules[path];
// lookup failed
if (null == path) {
orig = orig || p;
parent = parent || 'root';
throw new Error('failed to require "' + orig + '" from "' + parent + '"');
}
// perform real require()
// by invoking the module's
// registered function
if (!mod.exports) {
mod.exports = {};
mod.client = mod.component = true;
mod.call(this, mod, mod.exports, require.relative(path));
}
return mod.exports;
}
/**
* Registered modules.
*/
require.modules = {};
/**
* Registered aliases.
*/
require.aliases = {};
/**
* Resolve `path`.
*
* Lookup:
*
* - PATH/index.js
* - PATH.js
* - PATH
*
* @param {String} path
* @return {String} path or null
* @api private
*/
require.resolve = function(path){
var orig = path
, reg = path + '.js'
, regJSON = path + '.json'
, index = path + '/index.js'
, indexJSON = path + '/index.json';
return require.modules[reg] && reg
|| require.modules[regJSON] && regJSON
|| require.modules[index] && index
|| require.modules[indexJSON] && indexJSON
|| require.modules[orig] && orig
|| require.aliases[index];
};
/**
* Normalize `path` relative to the current path.
*
* @param {String} curr
* @param {String} path
* @return {String}
* @api private
*/
require.normalize = function(curr, path) {
var segs = [];
if ('.' != path.charAt(0)) return path;
curr = curr.split('/');
path = path.split('/');
for (var i = 0; i < path.length; ++i) {
if ('..' == path[i]) {
curr.pop();
} else if ('.' != path[i] && '' != path[i]) {
segs.push(path[i]);
}
}
return curr.concat(segs).join('/');
};
/**
* Register module at `path` with callback `fn`.
*
* @param {String} path
* @param {Function} fn
* @api private
*/
require.register = function(path, fn){
require.modules[path] = fn;
};
/**
* Alias a module definition.
*
* @param {String} from
* @param {String} to
* @api private
*/
require.alias = function(from, to){
var fn = require.modules[from];
if (!fn) throw new Error('failed to alias "' + from + '", it does not exist');
require.aliases[to] = from;
};
/**
* Return a require function relative to the `parent` path.
*
* @param {String} parent
* @return {Function}
* @api private
*/
require.relative = function(parent) {
var p = require.normalize(parent, '..');
/**
* lastIndexOf helper.
*/
function lastIndexOf(arr, obj){
var i = arr.length;
while (i--) {
if (arr[i] === obj) return i;
}
return -1;
}
/**
* The relative require() itself.
*/
function fn(path){
var orig = path;
path = fn.resolve(path);
return require(path, parent, orig);
}
/**
* Resolve relative to the parent.
*/
fn.resolve = function(path){
// resolve deps by returning
// the dep in the nearest "deps"
// directory
if ('.' != path.charAt(0)) {
var segs = parent.split('/');
var i = lastIndexOf(segs, 'deps') + 1;
if (!i) i = 0;
path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
return path;
}
return require.normalize(p, path);
};
/**
* Check if module is defined at `path`.
*/
fn.exists = function(path){
return !! require.modules[fn.resolve(path)];
};
return fn;
};require.register("microtask/index.js", function(module, exports, require){
;(function(root){
"use strict";
try {root = global;} catch(e){ try {root = window;} catch(e){} };
var defer, deferred, observer, queue = [];
// Find best candidate for deferring a task
if(root.process && typeof root.process.nextTick === 'function'){
// avoid buggy nodejs setImmediate in v0.10.x
if(root.setImmediate && root.process.versions.node.split('.')[1] > '10') defer = root.setImmediate;
else defer = root.process.nextTick;
} else if(root.vertx && typeof root.vertx.runOnLoop === 'function') defer = root.vertx.RunOnLoop;
else if(root.vertx && typeof root.vertx.runOnContext === 'function') defer = root.vertx.runOnContext;
else if((observer = root.MutationObserver || root.WebKitMutationObserver)) {
defer = (function(document, observer, drain) {
var el = document.createElement('div');
new observer(drain).observe(el, { attributes: true });
return function() { el.setAttribute('x', 'y'); };
}(document, observer, drain));
} // avoid buggy IE MessageChannel
else if(typeof root.setTimeout === 'function' && (root.ActiveXObject || !root.postMessage)) {
defer = function(f){ root.setTimeout(f,0); };
}
else if(root.MessageChannel && typeof root.MessageChannel === 'function') {
var fifo = [], channel = new root.MessageChannel();
channel.port1.onmessage = function () { (fifo.shift())(); };
defer = function (f){ fifo[fifo.length] = f; channel.port2.postMessage(0); };
}
else if(typeof root.setTimeout === 'function') defer = function(f){ root.setTimeout(f,0); };
else throw Error("no candidate for defer");
deferred = head;
/**
* Execute task on next event loop / tick
*
* Example:
* function myTask(a,b,c){
* console.log(a,b,c);
* }
* microtask(myTask,["hello","world","!"]);
* //
* doSomethingElse();
* // ...after next event tick ... => "Hello world!"
*
* @param {Function} task - the function to call
* @param {Array} args - array of arguments
* @param {Object} context - task context
* @throws {Error} - task error
* @api public
*/
function microtask(func,args,context){
if( typeof func !== 'function' )
throw Error("not a function");
deferred(func,args,context);
}
function head(func,args,context){
queue[queue.length] = [func,args,context];
deferred = tail;
defer(drain);
}
function tail(func,args,context){
queue[queue.length] = [func,args,context];
}
function drain(){
var q;
for(var i = 0; i < queue.length; i++){
q = queue[i];
try {
q[0].apply(q[2],q[1]);
} catch(e) {
defer(function() {
throw e;
});
}
}
deferred = head;
queue = [];
}
if(module && module.exports) module.exports = microtask;
else if(typeof define ==='function' && define.amd) define(microtask);
else root.microtask = microtask;
}(this));
});
if ("undefined" == typeof module) {
window.uTask = require("microtask");
} else {
module.exports = require("microtask");
}
})();