72 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
var callable, byObserver;
 | 
						|
 | 
						|
callable = function (fn) {
 | 
						|
	if (typeof fn !== 'function') throw new TypeError(fn + " is not a function");
 | 
						|
	return fn;
 | 
						|
};
 | 
						|
 | 
						|
byObserver = function (Observer) {
 | 
						|
	var node = document.createTextNode(''), queue, currentQueue, i = 0;
 | 
						|
	new Observer(function () {
 | 
						|
		var callback;
 | 
						|
		if (!queue) {
 | 
						|
			if (!currentQueue) return;
 | 
						|
			queue = currentQueue;
 | 
						|
		} else if (currentQueue) {
 | 
						|
			queue = currentQueue.concat(queue);
 | 
						|
		}
 | 
						|
		currentQueue = queue;
 | 
						|
		queue = null;
 | 
						|
		if (typeof currentQueue === 'function') {
 | 
						|
			callback = currentQueue;
 | 
						|
			currentQueue = null;
 | 
						|
			callback();
 | 
						|
			return;
 | 
						|
		}
 | 
						|
		node.data = (i = ++i % 2); // Invoke other batch, to handle leftover callbacks in case of crash
 | 
						|
		while (currentQueue) {
 | 
						|
			callback = currentQueue.shift();
 | 
						|
			if (!currentQueue.length) currentQueue = null;
 | 
						|
			callback();
 | 
						|
		}
 | 
						|
	}).observe(node, { characterData: true });
 | 
						|
	return function (fn) {
 | 
						|
		callable(fn);
 | 
						|
		if (queue) {
 | 
						|
			if (typeof queue === 'function') queue = [queue, fn];
 | 
						|
			else queue.push(fn);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
		queue = fn;
 | 
						|
		node.data = (i = ++i % 2);
 | 
						|
	};
 | 
						|
};
 | 
						|
 | 
						|
module.exports = (function () {
 | 
						|
	// Node.js
 | 
						|
	if ((typeof process === 'object') && process && (typeof process.nextTick === 'function')) {
 | 
						|
		return process.nextTick;
 | 
						|
	}
 | 
						|
 | 
						|
	// MutationObserver
 | 
						|
	if ((typeof document === 'object') && document) {
 | 
						|
		if (typeof MutationObserver === 'function') return byObserver(MutationObserver);
 | 
						|
		if (typeof WebKitMutationObserver === 'function') return byObserver(WebKitMutationObserver);
 | 
						|
	}
 | 
						|
 | 
						|
	// W3C Draft
 | 
						|
	// http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html
 | 
						|
	if (typeof setImmediate === 'function') {
 | 
						|
		return function (cb) { setImmediate(callable(cb)); };
 | 
						|
	}
 | 
						|
 | 
						|
	// Wide available standard
 | 
						|
	if ((typeof setTimeout === 'function') || (typeof setTimeout === 'object')) {
 | 
						|
		return function (cb) { setTimeout(callable(cb), 0); };
 | 
						|
	}
 | 
						|
 | 
						|
	return null;
 | 
						|
}());
 |