Created
July 1, 2011 00:02
-
-
Save westonruter/1057588 to your computer and use it in GitHub Desktop.
User script to add browser support for setImmediate() API. Try on IE10 demo: http://ie.microsoft.com/testdrive/Performance/setImmediateSorting/Default.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Support for setImmediate() API | |
// @description Adapted from David Baron's setZeroTimeout() as suggested by Jeff Walden <http://dbaron.org/log/20100309-faster-timeouts>. Try on <http://ie.microsoft.com/testdrive/Performance/setImmediateSorting/Default.html> | |
// @author Weston Ruter (@westonruter) at X-Team <http://x-team.com/> | |
// @namespace http://weston.ruter.net/ | |
// @include * | |
// ==/UserScript== | |
(function(window){ | |
// Abort if we already have an implementation | |
if( | |
window.setImmediate || | |
window.WebkitSetImmediate || | |
window.MozSetImmediate || | |
window.OSetImmediate || | |
window.msSetImmediate | |
){ | |
return; | |
} | |
/** | |
* In user scripts, we can't add new methods to window due to the security | |
* sandbox (this can be skirted via Greasemonkey's unsafeWindow, but this is | |
* not available in Chrome). So we create a function expression which gets | |
* injected into the DOM as an Immediately-Invoked Function Expression (IIFE) | |
* inside of an inline script. | |
*/ | |
var injectedSetImmediateCode = function(window){ | |
/** | |
* Begin code from David Baron's setZeroTimeout(): http://dbaron.org/log/20100309-faster-timeouts | |
*/ | |
// Like setTimeout, but only takes a function argument. There's | |
// no time argument (always zero) and no arguments (you have to | |
// use a closure). | |
function setZeroTimeout(fn) { | |
timeouts.push(fn); | |
window.postMessage(messageName, "*"); | |
} | |
var timeouts = []; | |
var messageName = "set-immediate-message"; // was "zero-timeout-message" | |
function handleMessage(event) { | |
if (event.source == window && event.data == messageName) { | |
event.stopPropagation(); | |
if (timeouts.length > 0) { | |
var fn = timeouts.shift(); | |
fn(); | |
} | |
} | |
} | |
window.addEventListener("message", handleMessage, true); | |
/** | |
* Now use setZeroTimeout as setImmediate, using all vendor-prefixed names | |
*/ | |
window.WebkitSetImmediate = setZeroTimeout; | |
window.MozSetImmediate = setZeroTimeout; | |
window.OSetImmediate = setZeroTimeout; | |
window.msSetImmediate = setZeroTimeout; | |
} | |
/** | |
* Now inject the Immediately-Invoked Function Expression (IIFE) into the page | |
* Again, we can't just assign it to the window object due to the user script | |
* security sandbox. | |
*/ | |
var script = document.createElement('script'); | |
script.text = '(' + injectedSetImmediateCode.toString() + ')(window);'; | |
document.documentElement.insertBefore(script, document.documentElement.firstChild); | |
script.parentNode.removeChild(script); //cleanup | |
})(window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also check out my full implimentation of setImmediate (with clearImmediate) at https://github.com/NobleJS/setImmediate
I was thinking about overriding the knows vendor specific prefixed versions. I'm glad to see that you have done so. Good job!
Donavon