Projects


Bringing the Browser to the Server

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)

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.

Tags: rhino, java, ecmascript, firefox, mozilla, javascript

Course Visualization

Using the excellent TouchGraph library, I created a visualization of RIT classes which students tend to take together.

As a threshold, I limited the results to the top 95% of all associated courses (the most associated courses occuring together 1452 times, out of over 30,000 schedules). I played with setting the threshold to courses which occur together a certain percentage of the time, but the results were rather lacking. In the current view you can see Labs and Classes highly associated with one another, along with courses that students of different concentrations or year levels might take together. It's a rather neat find.

Links

Tags: graph, java, visualization

Pirate Barrel

Created for Software Engineering, this project was a game designed for grade school students to learn math. I feel as if the game turned out rather well, included is the code for the project, but I'm not entirely sure if it will compile properly, or not.

Downloads

Tags: gui, java, school

Javadoc to Java Convertor (jd2j)

This is a simple Perl script which takes the URL of a given Javadoc file and returns what the basic Java code would look like. A great utility for first year Computer Science students to use.

URL of Javadoc:

You will most likely be asked to download a file, simply save it as the name of the java program that you are downloading. (e.g. If the page is ../Thread.html save it as Thread.java)

Bonus: Want a quick template for your next Java file? Enter the following in the above box: "/Filename.java" (without the quotes) and it'll create a pre-made Filename class with a constructor, along with the proper Javadoc + CVS comments.

Note: Should you encounter any problems while using this utility, please feel free to contact me.

Tags: convertor, java, perl, scrape

Current Projects

jQuery JavaScript Library

jQuery

Comprehensive DOM, Event, Animation, and Ajax JavaScript Library.

Recent Projects

Pro JavaScript Techniques

JavaScript Book

The best techniques for professional JavaScript. Published by Apress.