Skip to content

Instantly share code, notes, and snippets.

@westonruter
Created July 1, 2011 00:02
Show Gist options
  • Save westonruter/1057588 to your computer and use it in GitHub Desktop.
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
// ==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);
@donavon
Copy link

donavon commented Jul 1, 2011

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment