This weekend I took a big step in upping the ante for JavaScript as a Language. At some point last Friday evening I started coding and didn’t stop until sometime mid-Monday. The result is a good-enough browser/DOM environment, written in JavaScript, that runs on top of Rhino; capable of running jQuery, Prototype, and MochiKit (at the very least).
The implications of this are phenomenal, and I’m not the only one who’s interested in it what this could mean for server-side JS development. More on that in a minute, but first here’s some sample results from running jQuery:
jQuery
$ java -jar build/js.jar Rhino 1.6 release 6 2007 06 28 js> load('build/runtest/env.js'); js> window.location = 'test/index.html'; test/index.html js> load('dist/jquery.js'); // Add pretty printing to jQuery objects: js> jQuery.fn.toString = DOMNodeList.prototype.toString; js> $('span').remove(); [ <span#å°åŒ—Taibei>, <span#å°åŒ—>, <span#utf8class1>, <span#utf8class2>, <span#foo:bar>, <span#test.foo[5]bar> ] // Yes - UTF-8 is support in DOM documents! js> $('span') [ ] js> $('div').append('<span><b>hello!</b> world</span>'); [ <div#main>, <div#foo> ] js> $('span') [ <span>, <span> ] js> $('span').text() hello! worldhello! world
On a whim, I then plugged in Prototype and MochiKit, both of which appeared to work OK (I haven’t done any significant testing with them – so there’s probably gaps). Here’s some sample results:
Prototype
$ java -jar build/js.jar Rhino 1.6 release 6 2007 06 28 js> load('build/runtest/env.js'); js> window.location = 'test/index.html'; test/index.html js> load('prototype.js'); js> $$('div p') <p#firstp>,<p#ap>,<p#sndp>,<p#en>,<p#sap>,<p#first> js> Object.toJSON({foo:'bar',baz:true}); {'baz': true, 'foo': 'bar'} js> var fn = (function(name,msg){ print(name + ' ' + msg); }).curry('John'); js> fn('hello!'); John hello!
MochiKit
$ java -jar build/js.jar Rhino 1.6 release 6 2007 06 28 js> load('build/runtest/env.js'); js> window.location = 'test/index.html'; test/index.html js> load('Mochikit.js'); js> $$('div') <div#main>,<div#foo> js> document.body.innerHTML = ''; js> document.body.appendChild( P( 'test', A({href:'http://google.com/'}, 'link')) ); js> document.body.innerHTML <p>test<a href='http://google.com/'>link</a></p> js> $$('a') <a>
I just want to emphasize that these are un-modified copies of jQuery, Prototype, and MochiKit – all running perfectly in this un-natural environment.
When I came up with this idea for an environment, I was mulling over a couple ideas: Namely, better ways of automating tests and ways to bring JS-style DOM/HTML interaction to the server-side. Having a way to bring this popular idiom to established problem sets seemed like a lot of fun.
In short, the following (at the very least) can all get a big dose of JavaScript:
- Automated Testing
- Screen Scraping
- Web Application Development
Now, if you think I’m crazy, I’d like to show you a couple quick examples:
Automated Testing
$ java -jar build/js.jar Rhino 1.6 release 6 2007 06 28 js> load('build/runtest/env.js'); js> window.location = 'test/index.html'; test/index.html js> load('dist/jquery.js'); js> load('build/runtest/testrunner.js'); js> load('src/jquery/coreTest.js'); PASS (1) [core] Array.push() PASS (2) [core] Function.apply() PASS (3) [core] getElementById PASS (4) [core] getElementsByTagName PASS (5) [core] RegExp PASS (6) [core] jQuery ...
Oh yes, that’s right – the full jQuery test suite is now automated and capable of running in Rhino (passing all tests). jQuery served as my initial testbed for development, making sure that I was getting all of my code right. So if you import a copy of jQuery into this environment, it should work “just fine”.
By the way, you can try out the automated test suite by getting a copy of trunk/jquery out of SVN, then running make runtest – the results are just awesome.
Screen Scraping
This is one part that works pretty well right now – with the huge caveat that it only works on well-formed XML documents (oops!). I’ll be integrating an HTML parser into the code base so that we can make this functionality a little more resilient. In the meantime, here’s an example of the sort of scraping that you can do currently:
load("env.js"); window.location = "http://alistapart.com/"; window.onload = function(){ load("dist/jquery.js"); print("Newest A List Apart Posts:"); $("h4.title").each(function(){ print(" - " + this.textContent); }); };
And here’s another one that writes the results out to a file:
load("env.js"); window.location = "http://alistapart.com/"; window.onload = function(){ load("dist/jquery.js"); var str = "Newest A List Apart Posts:\n"; $("h4.title").each(function(){ str += " - " + this.textContent + "\n"; }); var out = new XMLHttpRequest(); out.open("PUT", "file:/tmp/alist.txt"); out.send( str ); };
Oh yeah, I went there – I made PUT and DELETE requests to local files perform the expected actions. I think the result is hilarious.
Web Application Development
This is still a work in progress, but some of the initial ideas are already at play here in this environment. When I have some time I plan on making a JavaScript-based web app framework out of this – which should be pretty cool.
Here’s some psuedo-code for how I think it could work:
window.onload = function(){ print("Content-type: text/html\n"); if ( location.href == "/" ) show_home(); print( document.innerHTML ); }; function show_home(){ document.load("index.html"); document.getElementById("time").innerHTML = (new Date()).toString(); }
Download!
Check out the code – there’s still huuuge gaps of functionality missing – I only implemented the bare minimum to get this environment working (and passing the jQuery test suite). So your mileage may vary.
Download: http://jqueryjs.googlecode.com/svn/trunk/jquery/build/runtest/env.js (Formatted)
NOTE (February 2009): The above code is quite out of date. If you’re interested in using it in your project I recommend that you visit the following Google group and download the code from the current working fork:
How to Use
To start with, you’ll need to have, at least, Rhino 1.6R6. You can download it from Mozilla FTP.
Now download the env.js script and put it in the same directory as the Rhino js.jar.
In order to use it from the command-line, you’ll wanna do something like this:
$ java -jar js.jar js> load('env.js'); js> window.location = 'some.html'; some.html js> // Your code here!
It’s important that you do window.location = “some file” before loading any DOM-dependent code (as the ‘document’ object doesn’t exist before the location request).
A full list of Rhino-shell-specific commands can be found in the Rhino Shell docs.
If you want to write executable scripts, the contents will look something like this:
load('env.js'); window.location = 'some.html'; window.onload = function(){ // Your code here };
Which can then run like so: java -jar js.jar myscript.js.
Feedback is very much welcome – I’ve only thought of a couple use-cases thus far, but I’m sure that the surface is just being scratched.
Yehuda Katz (July 9, 2007 at 11:08 pm)
Good stuff!
I’ve played with this code some, and I think it’ll be absolutely perfect for automating JavaScript tests. In fact, I think it’ll be game-changing in terms of the possibilities of automated unit tests for applications.
The key to making that happen, of course, is to build more env.js’s; one per environment you’ll want to test in. So an ie6-env.js, ie7-env.js, safari-env.js, etc.
It’ll be a little work, but this code is an excellent starting point for full test suites that make real JS continuous integration possible.
As a side note, there’s something incredibly pleasant about being able to use full-on Java classes dynamically as JS objects. I know it’s nothing new (Jython does the same), but actually playing with it made the possibilities more real to me.
Kudos!
Tzury Bar Yochay (July 10, 2007 at 1:41 am)
sub-zero, indeed. I always envy Dojo users for their ability of testing their code with Rhino… Now I can as well.
apart from this, your work, and the following wxJS + mod_js might suggest an old attempts revival to use java-script
see:
http://www.wxjavascript.net/
http://jerakeen.org/blog/2007/07/server-side-javascript-under-apache/
Though it is hard for me to think of giving up my love of lady Python…
Edwin Martin (July 10, 2007 at 2:52 am)
Great job! I already see a nice application here: agnostic portlets. Some portlets/widgets run in the browser (think Netvibes, iGoogle) and some on the server (like in most CMSes). With your framework, you could make portlets which can run in the browser or on the server. That way you can dynamically switch a portlet to the browser or to the server, whichever is best at that moment. You can run a portlet in the browser to be very dynamic or on the server when JavaScript is not available and for indexing by search engines.
zimo (July 10, 2007 at 4:49 am)
are you aware of mozrepl? seems you can already do this (well, the client side) using the real browser instead of emulation: http://dev.hyperstruct.net/mozlab/wiki/MozRepl
Dr Nic (July 10, 2007 at 7:09 am)
You are a machine.
John Resig (July 10, 2007 at 7:31 am)
@Tzury: When I looked through what Dojo had, it appeared as if they only have a small number of tests running in Rhino – and the tests are limited to tests that are pure JavaScript (no DOM, window, etc.). So even they could benefit from this addition.
I was, also, looking at the wxJS stuff earlier – I’ll have to check it out some more!
@Edwin: Great call – being able to confine widgets to an area where they can’t do any damage (but still produce results) would seem to be quite useful indeed.
@zimo: Nope – looks interesting though. It’s unfortunate that you have to have an instance of the browser running (and that it doesn’t run with other browsers). As Yehuda mentioned, I’d like to be able to layer on the different browser “quirks” to simulate the problems that you might experience in IE, Safari, etc. But yeah, if someone wants something that’s guaranteed to be bug free, MozRepl looks promising!
Jason Harwig (July 10, 2007 at 8:05 am)
Have you check out crosscheck? (http://www.thefrontside.net/crosscheck)
I’ve been using it with prototype.js to manipulate the DOM in unit tests in continuous integration. I have had some headaches with certain $$ calls not working, so I’m anxious to try this. One cool feature of crosscheck is it includes separate DOM API’s for IE6, and multiple mozilla versions.
David Ziegler (July 10, 2007 at 8:06 am)
You may also like know about HTML Unit:
http://htmlunit.sourceforge.net/
It is a (really excellent) browser simulator written in Java.
HtmlUnit uses Rhino to execute javascript, httpclient to
the the http stuff, and neckohtml to do HTML parsing.
The code is shockingly good, and I have had a lot of fun with
it.
John Resig (July 10, 2007 at 8:24 am)
@Jason & David: Great finds, guys – both Crosscheck and HTML Unit are very close to what I set out to achieve. I’m going to have to dig through their code to see if there’s anything that I can glean from them. It doesn’t appear as if XMLHttpRequest is supported by either of them, but I can’t be certain.
@David: Have you been able to run any JS libraries on top of HTML Unit? They say that their JavaScript support is limited – but I’m not entirely sure what that entails.
John Resig (July 10, 2007 at 9:18 am)
@Jason & David: I guess the most important differences (between Crosscheck, HTML Unit and my environment) are that my work is done purely in JavaScript – and that it’s not limited to the scope of testing. Although, considering how large Crosscheck is, I think they’ve got some serious ground on me, heh.
Mike parsons (July 10, 2007 at 9:23 am)
On the windows platform, I’ve used
var oHTMLDoc = new ActiveXObject(“htmlfile”);
quite effectively to do this same sort of thing.
I know it’s IE specific, but it’s a quick and dirty way to script the DOM.
Jason Harwig (July 10, 2007 at 9:23 am)
@John: Crosscheck does support XMLHttpRequest. Use crosscheck.Host.setResponse(url, params)
URL is the url that will be requested
PARAMS is a JSON object with contentType and responseText string attributes
When a new request is opened to a url that was set using setResponse, handler will be called with the params.
Rami Kayyali (July 10, 2007 at 9:45 am)
I’m not sure if I should be surprised or afraid.
Nicely done John.
JB Boisseau (July 10, 2007 at 10:25 am)
You had a nice week-end, indeed.
Charles Lowell (July 10, 2007 at 10:35 am)
@John: Our original implementation of crosscheck was in pure javascript, however, for performance reasons as well as limitations in rhino, we decided to switch to java in order to more faithfully represent the browser enviroment. However, one of our primary focuses is to mimick obscure browser idiosyncrasies, which might not be a requirement for you.
Also, the initial implementation was built rhino 1.5, and there are some compelling features of in the upcoming 1.6R6 release that are making us reevaluate whether or not to take the implementation back to javascript.
In either case, it might be useful to collaborate with others to create a seperate browser environment which can be shared by all for the greater good :)
Sean Graham (July 10, 2007 at 10:43 am)
I guess I’ll let it slide that you missed the film club this Sunday.. =)
Da Scritch (July 10, 2007 at 10:50 am)
This is absolutely fantastic but … When will we have a perfect DOM comptability between client browsers ?
I explain here in … french : http://dascritch.net/blog.php/2007/07/05/818-javascript-comme-un-dialecte
John Resig (July 10, 2007 at 10:50 am)
@Charles: That’s great to hear. I suspect that before 1.6R6 this implementation wouldn’t have been possible with pure JavaScript (mostly due to the lack of setters/getters).
Idiosyncrasies isn’t a huge issue at the moment – but it definitely will become one as time goes by. An ideal situation, for me, would be one where each “quirk” could be written in clean, commented, JavaScript and posted to a general web page for discussion and analysis. All of these quirks would then serve two purposes: 1) To help make for a more-realistic server-side environment and 2) to educate JavaScript web developers as to the nature of cross-browser issues (and hopefully how to work around them).
As far as collaboration goes, it’s certainly feasible – I’ve already been contacted by at least one other project who’s interested in working together. Let me know how you’d like to collaborate – you already have some significant ground on me, so I’m all ears.
Mikael Bergkvist (July 10, 2007 at 10:58 am)
All the widgets here, http://www.widgetplus.com , are database-driven serverside and coded entirely in javascript, in a serverside enviroment that mimicks the browsers DHTML model almost to the letter.
As a result, the applications can be made to run in any browser.
Dossy Shiobara (July 10, 2007 at 11:00 am)
I can’t wait to get this working inside of nsjsapi on AOLserver:
http://dossy.org/archives/000407.html
Thank you SO much for putting this together! Amazing work, as usual.
whoopee (July 10, 2007 at 11:18 am)
this is a great step forward. support like this will help developers get a true web “repl” environment for testing and integrating into other tools (emacs etc)
Uriel Katz (July 10, 2007 at 11:22 am)
i see that you used Java threads to do async XMLHttpRequest and do emulate setInterval,this isn’t the way JavaScript works,you made JavaScript to use more than one thread,this isn’t a way to really do testing since that part isn’t emulated correctly,JavaScript have only one thread.
John Resig (July 10, 2007 at 11:28 am)
@Uriel: You’re mis-understanding the problem slightly. A JavaScript runtime is single threaded (correct) – but various aspects that aren’t part of the ECMAScript spec (such as setTimeout, setInterval, and XMLHttpRequest) all rely on a threaded behavior. Incidentally, in browsers those threads take place outside of the single-threaded JavaScript runtime (which is then called based upon the external actions; such as a timer firing).
In this specific environment implementation the external threads COEXIST with the single JavaScript thread. There’s inherently nothing wrong with this, as this is what a browser would doing too, behind the scenes – but the result is just an amalgam of the two worlds.
Uriel Katz (July 10, 2007 at 11:35 am)
but in a browser one thread running will block all other threads,right?
how is this the same,here you can be running two threads,like in a real threaded environment.
John Resig (July 10, 2007 at 11:39 am)
@Uriel: Incorrect – you can’t run threads in a JavaScript runtime, so of course whatever you do will block. HOWEVER, you can run multiple threads in a browser – which is what this code is attempting to simulate. setTimeout, setInterval, and XMLHttpRequest are all non-blocking in a JavaScript runtime (which necessitates the use of threads in this browser-simulation environment).
Uriel Katz (July 10, 2007 at 12:00 pm)
for some reason pasting the JavaScript code didn’t work,here is a link to the test case: http://www.urielkatz.com/media/test.html
you can see in firefox(with firebug) that you will have a bunch of running 1 and then running 2 in the console,meaning that the threads run one after the other,as far as i understand.
Ian McKellar (July 10, 2007 at 12:06 pm)
Oh man, I’ve wanted this for so long!
Now we just need a way to transmit running JS state between the browser and the server…
John Resig (July 10, 2007 at 12:12 pm)
@Uriel: setTimeouts aren’t threads. Running code in a loop isn’t a thread. I’m talking about how timeouts are handled in the browser engine itself not in the JavaScript runtime these are two very different things. This library is a simulation of a browser engine, not a JavaScript runtime. As Bob already mentioned, XMLHttpRequest has to be done with a thread, there is simply no other way around it.
Let’s try to stay on the topic at hand: The server-side browser environment.
John Resig (July 10, 2007 at 12:14 pm)
@Ian: I’ve been thinking about that too – I don’t think I’ve found a silver-bullet solution for it yet. If you wanted to keep everything stateful, I think passing along code in script blocks might be an option, although, that doesn’t seem ideal.
Uriel Katz (July 10, 2007 at 12:19 pm)
there is no way in Java to do a http request in a true async way?
in C# for example you would to a BeginRequest and then a EndRequest,the request will be still non-blocking but will not run in a different thread,it will use the async api of the operation system.
Paul Colton (July 10, 2007 at 12:34 pm)
@John, I sent you an email. I’d like to chat with you about what Aptana is up to. Please contact me at paul at aptana dot com.
Neil Mix (July 10, 2007 at 1:21 pm)
John: sweet! I’ve been meaning to do this for a long time — you just saved me tons of work. ;) This is awesome.
Eric Blue (July 10, 2007 at 1:24 pm)
Pretty amazing stuff!
Juixe TechKnow (July 10, 2007 at 2:45 pm)
This sounds awesome! I am not only in awe in the end results and ideas but in how you must have just hacked at it non stop over the weekend. I participated in the iPhoneDevCamp this weekend and there were a ton of techies in the proverbial zone writing some great code, mmm, has there been a jquery dev camp?
John Resig (July 10, 2007 at 2:53 pm)
@Juixe: It was a lot of fun – it’s been a while since I was “in the zone”, it felt good. We’ve been talking about having a jQuery conf/hack day this fall, immediately following the Ajax Experience here in Boston. Hopefully we’ll be able to get a critical mass of people to come and participate.
John DeHope (July 10, 2007 at 3:19 pm)
Oh sorry now that I read the posts I realize I am not as amazingly prescient as I thought I was.
Mark Holton (July 10, 2007 at 3:44 pm)
John, this is really cool, many thanks. Count me as an adopter, as I will be giving this a spin, specifically with regards to Automated Testing. …really like that you built it on top of Rhino as that lends another reason to gain some familiarity with that.
Michael Mahemoff (July 11, 2007 at 7:21 am)
John,
I, for one, don’t think this is crazy :). I have been excited about the possibility of server-side JS (http://softwareas.com/phobos-server-side-js-redux) and I think you could use the above to build a very decent Rails-style framework out of it, only with cleaner Ajax support than any other language could ever hope for.
Steve Goguen (July 11, 2007 at 9:08 am)
John,
I was talking to Dossy and we were thinking Google and Mozilla should lock you and Steve Yegge into a room for a couple of months and broadcast it on Nerd TV. Dossy had a good name, “The Geek Life”.
Stephan Beal (July 11, 2007 at 1:50 pm)
Holy farging christ! This is fantastic! If it works with SpiderMonkey, consider me an adopter!
Kingsley (July 11, 2007 at 6:15 pm)
I left a comment on your JavaScript as a Language post about how much I’d love to use jQuery on the server side, and now you go do this – super sweet!
Michael Platzer (July 12, 2007 at 2:40 am)
hi john,
i just wanted to point to the thread on the helma-mailing-list regarding your script: http://www.nabble.com/Server-side-DOM-tf4059771s2589.html which might be interesting for you to read.
and also wanted to point to my reply to your comment: http://michi.knallgrau.at/blog/stories/4058536/#4062586
Gaetano Giunta (July 12, 2007 at 5:44 am)
Great work, indeed.
A (possibly silly) question: would it be feasible to just embed XHR and the equivalent of windows.settimeout in the rhino engine itself (or at least the rhino shell host object)?
When running scripts in WSH host, XHR is there, as well as a sleep() function which, while not as good as settimeout/setinterval, can be quite useful…
Steve Clay (July 16, 2007 at 12:52 pm)
This got me thinking about the possibility of using Rhino as a Javascript validator, for fishing out calls to non-standard objects/interfaces.
Maybe it would be better if your script was separated out based on where certain features are defined. E.g. env_dom0.js could set up the minimal DOM0 interfaces: window, document, forms, etc. then env_dom.js would add on W3C Core & HTML DOM interfaces, then env_html5.js for XMLHTTPRequest, innerHTML, and the like. In some cases you’d certainly lose the compactness of object literals.
Pete Hall (July 19, 2007 at 9:04 am)
This looks very cool, and I’m anxious to try it out – thanks for doing the initial leg work. However, after doing the
js> load(‘build/runtest/env.js’);
js> window.location = ‘test/index.html’;
(both paths exist)
If I then access the ‘document’ object in any way I get
js: “”, line 27: uncaught JavaScript runtime exception: ReferenceError: “document” is not defined.
Any ideas?
John Resig (July 21, 2007 at 12:15 am)
@Pete: Currently window.location is an asynchronous operation – so attempting to access document right away will cause an error to occur. Simply wrap the code that you wish to use with the document in a window.onload = function(){…};
Clem Gruen (July 23, 2007 at 1:58 am)
Wow, this is a killer method to fetch all those javascript scrambled email adresses out there.. , by reassembling the DOM you really get what a user sees, not what his browser fetches.. great work
Bermi Ferrer (July 26, 2007 at 6:06 pm)
Hey John this looks really promising.
In regard to parsing XHTML… and badly formatted atrocities, have a look at the xhtml_parser.js file on the WYMeditor project. I coded this Lexer/Parser for dealing with DesignMode content on WYM, and also another Parser for configuring WYM via CSS.
The JavaScript version of this Lexer/Parser is quite new, but I used a PHP one on the Akelos PHP Framework project and it is incredibly easy to maintain / add new rules.
I would be happy to help you on this :)
Mark (July 30, 2007 at 11:23 am)
This looks really cool, unfortunately I’m having some trouble getting it to work. I’m using the js.jar file from the jquery svn trunk (Rhino 1.6 release 6 2007 06 28).
ant runtest doesn’t throw any error, simply:
[echo] Running Automated Test Suite
[echo] Test Suite Finished
I suspect that I don’t have an XMLHttpRequest object to work with because in interactive mode I get:
js> var xhr = new XMLHttpRequest();
js: “”, line 2: uncaught JavaScript runtime exception: ReferenceError: “XMLHttpRequest” is not defined.
What class are you using to emulate this functionality? After a bit of googling, I hacked the one from e4xutils.jar into js.jar and used defineClass(“xmlhttp.XMLHttpRequest”), but this didn’t seem to help. I can get an xhr reference, but the behaviour doesn’t seem correct. I’m certain I’m missing something pretty obvious. Any help would be much appreciated!
Craig Castelaz (August 2, 2007 at 9:28 pm)
John,
This is beyond cool. I’ve shied away from JavaScript in the past because the development tools were so incomplete. Your env.js helps to fill-in a signficant gap. I’m particularly interested in playing with prototype, and env.js along with the Rhino shell looks like the perfect opportunity. Unfortunately, I receive an exception when I attempt the following:
js> load(‘env.js’);
js> window.location=’chap02/index.html’;
chap02/index.html
js> load(‘prototype.js’);
js: “prototype.js”, line 9: uncaught JavaScript runtime exception: ReferenceError: “document” is not defined.
I’m running on OS X 10.4.10 with JRE 1.5.0_07 and attempting to load prototype 1.5.1.1 inside Rhino Rhino 1.6 release 6 2007 07 26.
Any help you can give will be greatly appreciated. Thanks for all your efforts.
Craig
EmpapeCeatolo (August 26, 2007 at 1:36 pm)
Hello
Need sex with local girls click here aarens dating directory online services
http://aarensdatingdirectoryonlineservic.blogspot.com
http://aarensonlinedatingservices.blogspot.com
http://aarensonlinedatingservicesdirecto.blogspot.com
Bye
ErikH (August 27, 2007 at 11:41 pm)
In the env.js source file, all the functions that start with “get” or “set” seem to be messed up. Instead of, e.g., “getLastChild: function() { …”, they look like “get lastChild() { …”
NawnElona (September 2, 2007 at 4:51 pm)
Hi peoplel!
Sex with cute girls freeonlinedatingservicesatholida
http://freeonlinedatingservicesatholida.blogspot.com
http://freenonlineatingcervicesuldesac.blogspot.com
http://freeonlinedatingserviceseleeleha.blogspot.com
http://freeonlinedatingservicesinbowman.blogspot.com
SwessePax (September 11, 2007 at 5:22 am)
High definition porno movies
here
http://premonsw545.worddatingguide.info
[email protected] (September 24, 2007 at 5:58 pm)
cvrain twulr tsdbmhwe teqno wofsgeqva sovwinyr obvkdef
eokyere (September 25, 2007 at 9:08 pm)
wow! i don’t think i’m going to sleep tonight!
eokyere :)
Chris Esler (October 2, 2007 at 3:53 pm)
Got it to work with mootools. Just had to add an extra line at the bottom of your env.js due to Mootools requiring the variable ‘document’:
var document = window.document;
and it worked.
pretty cool.
slava (October 2, 2007 at 4:20 pm)
John,
Dig you ever get around to integrating an HTML parser for this project?
Alex (October 4, 2007 at 7:52 am)
Hi!
I’m a university student and we needed some compatibility with DOM when using Rhino, and your code has helped us a lot.
Right now I’m using it, the only thing is that the document.write method is not implemented, and I’m on it right now. Any helpful ideas from your bright mind?
Thanks
Sylvain Pointeau (October 18, 2007 at 2:41 am)
Hi,
It could be really wonderful if we could parse HTML and not only XML…
Would it be possible to do it ?
Cheers,
Sylvain
Sylvain Pointeau (October 23, 2007 at 4:35 am)
JQuery is wonderful and the idea to have it server side is really great. HTML was my problem few days ago but I know How to do…
doing my template in xhtml then transform them with xslt to produce validated HTML 4 document.
Many thanks for your great full work !!!