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;
 | |
| }());
 |