Say Hello to Envjs for QtScript

After I blogged about faking DOM APIs and the like, a few mentioned Envjs. Quoting the Envjs site:

Envjs is a simulated browser environment written in JavaScript.

Rather than faking, Envjs actually implements the APIs so that they work.
That's very cool. I just had to get this running on QtScript, and here's the result of two nights of hacking:

http://qt.gitorious.org/qt-labs/qtscript-browser-env

The README has the pertinent details; in short, you evaluate the Envjs implementation (env.js), call a function to register the native Envjs/QtScript handlers (for network & file access, asynchronous function execution, and a few more things), and presto -- instant browser environment.

Some simple examples

From examples/document.js in the repository:


document.write("<p>Hello, JavaScript in QtScript!</p>");
document.close();
console.log("p tag's innerHTML:", document.getElementsByTagName("p").item(0).innerHTML);
console.log("document.innerHTML:", document.innerHTML);

Output:


document:   HTMLDocument
p tag's innerHTML:   Hello, JavaScript in QtScript!
document.innerHTML:   <html><head/><body><p>Hello, JavaScript in QtScript!</p></body></html>

And, yay, prototype.js works:


var my_div = document.createElement('div');
my_div.addClassName('prototyped').hide();
document.body.appendChild(my_div);
console.log("document.innerHTML:", document.innerHTML);

Output:


document.innerHTML:   <html><head/><body><div class="prototyped"/></body></html>

(jQuery 1.5.1 unfortunately fails with the error Result of expression 'ajaxLocParts' [null] is not an object.)

Known limitations

I haven't really had the time to try it much, but one limitation is that responseXML of XMLHttpRequest doesn't work, so you're best off using JSON (with responseText and JSON.parse()). The reason responseXML doesn't work is that the Envjs DOM parser uses E4X, a language extension that's currently only supported by Mozilla's JS engines. (Feel free to vote for the relevant JavaScriptCore and V8 suggestions, though I really wouldn't hold my breath.)

QML integration?

Nothing yet, but a deep integration would be nice (no external dependencies, just start using the browser environment in your QML/JavaScript). Note that QML already has an XMLHttpRequest implementation of its own, and also implements a subset of the DOM API (for purposes of responseXML), but it is just that -- a subset. And it's not API we want to develop ourselves -- but it's good to have to enable richer JS integration. Maybe Envjs is a solution.

Overhead?

Well, Envjs version 1.2 is 680KB (unminified), so evaluating it isn't free. It's another tradeoff to consider. With V8, it would be possible to inject Envjs into the standard environment and serialize all of it, with the prospect of vastly reducing initialization time.

Contributions welcome

This project is open for merge requests. Not all of the native integration is implemented yet, and the XMLHttpRequest implementation could be improved. There's also the XML parsing issue (maybe an existing lightweight parser could be used instead of relying on E4X?).

Have fun!


Blog Topics:

Comments