Monday, September 24, 2007

Simulating include() in workers

Gears has an outstanding bug to create an include() method for workers. Once implemented, you should be able to do something like:

google.gears.workerPool.include("dojo.js");
google.gears.workerPool.include("mylib.js");

// Use libs here


One of the reasons that we have prioritized other things over this new API in Gears was that we knew you could emulate it using HttpRequest and eval().

Well, this turns out to be tricky in IE. In Firefox, you can just do:

var global = self;
function include(url, callback) {
var req = google.gears.factory.create("beta.httprequest", "1.0");
req.onreadystatechange = function() {
if (req.readyState == 4) {
// DOESN'T WORK IN IE :(
global.eval(req.responseText);
}
}

req.open("GET", "dojo.js");
req.send(null);
}

include("dojo.js", function() {
include("mylib.js", function() {
// Use libs here
});
});


But the eval line does not work in IE. In IE, eval() always runs in the calling scope, no matter where you get the function. The way people typically get around this in IE is to use the execScript method, but since that is a method on window, not a built-in part of JScript, it is not available in workers.

Luckily, the Gears timer implementation includes the script form of setTimeout and setInterval, so you can use it to workaround this problem. Here is the code that works in both IE and Firefox:

function include(url, callback) {
var req = google.gears.factory.create("beta.httprequest", "1.0");
req.onreadystatechange = function() {
if (req.readyState == 4) {
include.callback = callback;

// Hack to workaround the fact that global.eval() doesn't work in IE.
google.gears.factory.create("beta.timer", "1.0").setTimeout(
req.responseText + "\ninclude.callback()", 0);
}
}

req.open("GET", "dojo.js");
req.send(null);
}

include("dojo.js", function() {
include("mylib.js", function() {
// Use libs here
});
});


This is a dirty, dirty hack, and the lack of a synchronous form of include() remains an annoying problem. But until we get the include() implemented in Gears, this seems to be a workaround.

1 comment:

Idriss said...

i just read your archived post from 2002 about pop-up windows. i wanna have your children.