Blog
May 14th, 2008
It's been fascinating to watch the outpouring of interest and creativity that's surrounded the recent release of Processing.js.
First things first, the project has been moved over to Github. This will help with the collaboration/patching process going forward.
A number of patches have already been provided by active users and have been merged into the main code base (which can be found in the project history).
Some of the changes that were made:
- Virtually all of the demos now work in Webkit (save for the text rendering ones) in addition to Firefox 3.
- Chris Davenport provided support for QUADS, QUAD_STRIP, TRIANGLE_FAN, and TRIANGLE_STRIP implementations in beginShape/vertex. Also endShape(CLOSE) support was added.
- Renato Formato provided a patch for handling curveVertex and curveTightness correctly.
- A patch from Felipe Gomes includes the addition of the LEFT/CENTER/RIGHT and mouseButton globals. The contextmenu is now prevented, as well, from right clicks. Additionally, a new init.js file was created (which is more robust than what was initially provided).
I've pulled together a quick round-up of the different, interesting, posts, demos, and projects that I've found, relating to Processing.js.
Getting Started
Will Larson has written a series of articles that detail how to best get started playing with Processing.js:
Additionally, the basic demos have been broken down and included in an interactive wiki.
Demos
A number of new demos have been created, at this point. Here's a couple that I thought were pretty interesting.
IDEs
There's been some significant effort towards creating an interactive development environment for Processing.js.
Press / Blogs
There was a bunch of feedback concerning the project release - overwhelmingly positive, as well. Some of my favorite responses thus far:
Wired: "We cover a lot of language and software developments here at Compiler, but this might be the most impressive thing we've ever seen."
Chris Blizzard: "Easy to drop in graphical interactive elements into other sites with the same transparency and zero-barrier to learning we’ve seen from the rest of the web. Think about how fast that stuff might spread on the web, how we might end up with people sharing and learning together and how much better the experience on the web might be in the end. That iterative process is one that needs starting points and what John has done is give us a great starting point. "
Andy Baio: "one of the most amazing hacks I've ever seen... could Processing.js be the beginning of the end for the closed-source culture of rich media tech?"
Also: Scott Hanselman, Kottke, Simon Willison, Peter Kirn, and Ajaxian.
It also made a bunch of social sites (with some interesting discussion taking place): Slashdot, Digg, Y Combinator News, Del.icio.us (2), and Reddit.
Tags: processing, visualization, javascript
10 Comments on 'Processing.js Aftermath'
May 8th, 2008
Demos below!
As a sort-of reverse birthday present I've decided to release one of my largest projects, in recent memory. This is the project that I've been alluding to for quite some time now:
I've ported the Processing visualization language to JavaScript, using the Canvas element.
I've been working on this project, off-and-on now, for the past 7 months - it's been a fun, and quite rewarding, challenge. The full scope of the project can be broken down into two portions:
The Processing Language
The first portion of the project was writing a parser to dynamically convert code written in the Processing language, to JavaScript. This involves a lot of gnarly regular expressions chewing up the code, spitting it out in a format that the browser understands.
It works "fairly well" (in that it's able to handle anything that the processing.org web site throws at it) but I'm sure its total scope is limited (until a proper parser is involved). I felt bad about tackling this using regular expressions until I found out that the original Processing code base did it in the same manner (they now use a real parser, naturally).
The language includes a number of interesting aspects, many of which are covered in the basic demos. Here's a brief selection of language features that are handled:
- Types and type casting - Type information is generally discarded, but becomes important in variable declaration and in casting (which is generally handled well).
- Classes - The full class system is supported (can be instantiated, etc. just fine).
- Method overloading and multiple constructors - Within classes you can have multiple method (or constructor) definitions - with the appropriate methods being called, based upon their signature length.
- Inheritance - Even classical-style inheritance is supported.
Note: There's one feature of Processing that's pretty much impossible to support: variable name overloading. In Processing you can have variables and functions that have the same name (e.g. float size = 0; float size(){}). In order to support this there would have to be considerable overhead - and it's generally not a good practice to begin with.
If you're curious as to what the language looks like, here's a basic example of inheritance:
class Spin
{
float x, y, speed;
float angle =
0.
0;
Spin
(float xpos, float ypos, float s
) {
x = xpos;
y = ypos;
speed = s;
}
void update
() {
angle += speed;
}
}
class SpinArm extends Spin {
SpinArm(float x, float y, float s) {
super(x, y, s);
}
void display() {
strokeWeight(1);
stroke(0);
pushMatrix();
translate(x, y);
angle += speed;
rotate(angle);
line(0, 0, 66, 0);
popMatrix();
}
}
The Processing API
The second portion of the project is the full 2d Processing API. This includes all sorts of different methods:
- Shapes drawing
- Canvas manipulation
- Pixel utilities
- Image drawing
- Math functions
- Keyboard and mouse access
- Objects (point, arrays, random number generators)
- Color manipulation
- Font selection and text drawing
- Buffers
Most of these are demonstrated in the basic demos.
There's pretty-good coverage of the Processing API: there's sure to be many gaps, but most of what I can throw at it works.
Download
The full source code is contained within a single file. It comes in at about 5000 lines, compresses down to less than 10kb.
How to Use
The API is quite simple - there's a single method "Processing". If you wish to only use the Processing API (not the language) you can interact with it like so:
var p = Processing(CanvasElement);
p.size(100, 100);
p.background(0);
p.fill(255);
p.ellipse(50, 50, 50, 50);
If you wish to have the full power of the language, as well, you would pass in your Processing code as the second argument.
Processing(CanvasElement, "size(100, 100); background(0);" +
"fill(255); ellipse(50, 50, 50, 50);");
That's really all there is to it. Information on the full Processing API can be found on the Processing.org web site.
Important: Browser Support
Before we get into the demos I want to outline what some of my goal was for this project. First, and foremost, I wanted to try and get the best Canvas-based demos out of a browser, as possible. This meant that I had to shoot directly for the latest, and greatest, browsers. I needed good Canvas API support and, importantly, I needed speed.
Because of this, for this first release, I've specifically targeted Firefox 3, the latest WebKit Nightly, and Opera 9.5. In other words: beta browsers.
A large part of the code base is sure to work in "older" browsers (Firefox 2, Safari 3, Opera 9, and IE with excanvas) - but that wasn't my target platform. I wanted something that would be capable of pushing the edge of what a browser is able to render - giving them something to strive for in their upcoming releases.
There were a couple of stumbling blocks that the above browsers hit:
- Image loading - Currently, only Firefox 3, Opera 9.5, and Safari 3.1 handle this reliably.
- Pixel processing - Loading pixel data from images, manipulating them, and putting them back on the canvas. Only Firefox 3, Opera 9.5, and WebKit Nightlies can handle this sufficiently.
- Font loading and text rendering - The specification for this is still in the works, currently only Firefox 3 has support for this.
Thus, anything outside of the above (images, pixel processing, and text) should work "ok" everywhere.
Demos
NOTE: I highly recommend that you use the latest Firefox 3 beta to view the demos. Most will work in the latest WebKit Nightly and a majority will work in Opera 9.5, but all will work in Firefox 3.
Note again: A lot of these demos will peg your CPU. As I mentioned above, I'm trying to squeeze the most out of the browser, as possible - be ready for it!
What would the release be without a ton of demos? In development I worked in a backwards manner. Instead of building the API up from the ground - I worked from the top, down, implementing enough of the API to get individual demos working. The result of this is two-fold: 1) It made for a very rewarding development process - and guaranteed working demos and 2) It means that there are still portions of the Processing API left unimplemented.
Regardless - enough of the API has been implemented to allow all of the demos, available on processing.org, to work as best as possible.
Here's the full break-down of demos that are available:
I've gone through and cherry-picked a bunch that I really liked - in case you're interested in seeing some really interesting ones. Wherever possible I specify what browsers the demos work in (if none is specified, then it should work in all).
All of the following demos were written by Casey Reas and Ben Fry unless otherwise stated.
All of the following demos were written by Casey Reas and Ben Fry unless otherwise stated.
I'm quite curious to see what people construct with this new API. I think it holds a lot of potential and I'm excited to see what comes of it! Enjoy!
Remember: You should be using Firefox 3, a WebKit Nightly (Safari 3.1 is missing some features), or Opera 9.5 - the above demos generally work best in those browsers.
Tags: programming, processing, javascript
220 Comments on 'Processing.js'
May 7th, 2008
The guys over at Ajaxian asked me to do answer a couple questions for them (on video) so I set about forming it into a mini-presentation. I discuss a couple things:
- What's happening in jQuery Core, jQuery UI, and the jQuery Project.
- What upcoming browser features I'm excited about.
- Some of what's coming in JavaScript 1.9.
- Some things that should change about Open Web development.
Video: What's Next in jQuery and JavaScript?

View Flash Version (on Vimeo.com) - Download .mp4 (80mb, Must be Logged In to Vimeo.com)
Update: I also have a small 320x240 video: Download .mov (16mb)
Let me know if you have any follow-up questions, I'll be happy to answer them. Additionally, this is the first time recording a presentation in my new office. I'm pleased with the result (even though the quality of the camera is quite poor). It was quite easy to get set up and perform, which is exciting - I may do some more, short, presentations if there's interest.
Tags: standards, jquery, javascript, browsers
27 Comments on 'What's Next in jQuery and JavaScript?'
May 6th, 2008
I'm going to do a new project release on Thursday, which should it be?
- Something small and fast.
- Something large and pretty.
Tags: javascript
82 Comments on 'Thursday Release'
May 5th, 2008
Shaun Inman wrote a quick post on what he's calling "CSS Qualified Selectors". The syntax that he's proposing looks something like this:
Which says "Find me all a elements that have an img element inside of them."
To those of you who are familiar with jQuery we've had a similar selector, :has(), for quite some time:
If you're totally bent on Shaun's syntax (don't care for :has, I would assume) here's the two-line plugin that'll give it to you in jQuery:
jQuery.parse.push(/^\s*(<)(\s*)(.*)$/);
jQuery.expr["<"] = jQuery.expr[":"].has;
Then the following will work as you would expect it to:
It's really nice having an extensible selector engine at your disposal.
Tags: selectors, javascript, jquery
27 Comments on 'Qualified Selectors in jQuery'
May 5th, 2008
Recently I was having a little bit of fun and decided to go about writing a pure JavaScript HTML parser. Some might remember my one project, env.js, which ported the native browser JavaScript features to the server-side (powered by Rhino). One thing that was lacking from that project was an HTML parser (it parsed strict XML only).
I've been toying with the ability to port env.js to other platforms (Spidermonkey derivatives and the ECMAScript 4 Reference Implementation) and if I were to do so I would need an HTML parser. Because of this fact it became easiest to just write an HTML parser in pure JavaScript.
I did some digging to see what people had previously built, but the landscape was pretty bleak. The only one that I could find was one made by Erik Arvidsson - a simple SAX-style HTML parser. Considering that this contained only the most basic parsing - and none of the actual, complicated, HTML logic there was still a lot of work left to be done.
(I also contemplated porting the HTML 5 parser, wholesale, but that seemed like a herculean effort.)
However, the result is one that I'm quite pleased with. It won't match the compliance of html5lib, nor the speed of a pure XML parser, but it's able to get the job done with little fuss - while still being highly portable.
htmlparser.js:
4 Libraries in One!
There were four pieces of functionality that I wanted to implement with this library:
A SAX-style API
Handles tag, text, and comments with callbacks. For example, let's say you wanted to implement a simple HTML to XML serialization scheme - you could do so using the following:
var results =
"";
HTMLParser("<p id=test>hello <i>world", {
start: function( tag, attrs, unary ) {
results += "<" + tag;
for ( var i = 0; i < attrs.length; i++ )
results += " " + attrs[i].name + '="' + attrs[i].escaped + '"';
results += (unary ? "/" : "") + ">";
},
end: function( tag ) {
results += "</" + tag + ">";
},
chars: function( text ) {
results += text;
},
comment: function( text ) {
results += "<!--" + text + "-->";
}
});
results == '<p id="test">hello <i>world</i></p>"
XML Serializer
Now, there's no need to worry about implementing the above, since it's included directly in the library, as well. Just feed in HTML and it spits back an XML string.
var results = HTMLtoXML("<p>Data: <input disabled>")
results == '<p>Data: <input disabled="disabled"/></p>'
DOM Builder
If you're using the HTML parser to inject into an existing DOM document (or within an existing DOM element) then htmlparser.js provides a simple method for handling that:
// The following is appended into the document body
HTMLtoDOM
("<p>Hello <b>World", document
)
// The follow is appended into the specified element
HTMLtoDOM("<p>Hello <b>World", document.getElementById("test"))
DOM Document Creator
This is a more-advanced version of the DOM builder - it includes logic for handling the overall structure of a web page, returning a new DOM document.
A couple points are enforced by this method:
- There will always be a html, head, body, and title element.
- There will only be one html, head, body, and title element (if the user specifies more, then will be moved to the appropriate locations and merged).
- link and base elements are forced into the head.
You would use the method like so:
var dom = HTMLtoDOM("<p>Data: <input disabled>");
dom.getElementsByTagName("body").length == 1
dom.getElementsByTagName("p").length == 1
While this library doesn't cover the full gamut of possible weirdness that HTML provides, it does handle a lot of the most obvious stuff. All of the following are accounted for:
- Unclosed Tags:
HTMLtoXML("<p><b>Hello") == '<p><b>Hello</b></p>'
- Empty Elements:
HTMLtoXML("<img src=test.jpg>") == '<img src="test.jpg"/>'
- Block vs. Inline Elements:
HTMLtoXML("<b>Hello <p>John") == '<b>Hello </b><p>John</p>'
- Self-closing Elements:
HTMLtoXML("<p>Hello<p>World") == '<p>Hello</p><p>World</p>'
- Attributes Without Values:
HTMLtoXML("<input disabled>") == '<input disabled="disabled"/>'
Note: It does not take into account where in the document an element should exist. Right now you can put block elements in a head or th inside a p and it'll happily accept them. It's not entirely clear how the logic should work for those, but it's something that I'm open to exploring.
You can test a lot of this out in the live demo.
While I doubt this will cover all weird HTML cases - it should handle most of the obvious ones - at least making HTML parsing in JavaScript feasible.
Tags: rhino, html, javascript, parsing
35 Comments on 'Pure JavaScript HTML Parser'
April 30th, 2008
I don't think there's a single JavaScript developer who isn't excited about the new Selectors API specification (and the upcoming implementations). I've been following the progress of the specification (and implementations) and have been asked to provide some feedback to the Web API working group. What follows is an email that I sent to the public-webapi mailing list.
I just wanted to quickly pull together some of my thoughts concerning querySelectorAll. I've been asked by a number of people to provide my feedback here. Please forgive me if I've missed some previous discussions on the subject matter.
There's three major points that I wanted to discuss:
DOMElement.querySelectorAll returning incorrect elements
This is the most critical issue. As it stands DOM Element-rooted queries are borderline useless to libraries - and users. Their default behavior is unexpected and confusing. Demonstrated with an example, using Dojo:
<div><p id="foo"><span></span></p></div>
<script src="http://o.aolcdn.com/dojo/1.1.0/dojo/dojo.xd.js"></script>
<script>
var foo = document.getElementById("foo");
// should return nothing
alert( dojo.query('div span', foo).length );
// will return the SPAN (booo!)
alert( foo.querySelectorAll('div span').length );
</script>
The demo can be run online here:
http://ejohn.org/files/bugs/qsa-root/dojo.html
This is due to the fact that element-rooted queries are handled by "finding all the elements that match the given selector -- rooted in the document -- then filtering by the ones that have the specified element as an ancestor." This is completely unacceptable. Not only is it not intuitive (finding elements that don't match the correct expression) but it goes against what every single JavaScript library provides. If there behavior were persisted then there would be serious ramifications for the usefulness of this function in the wild.
I asked some of the other library developers what their thoughts were and they agreed with my conclusion.
Andrew Dupont (creator of Prototype's selector engine):
My issue with this is that it violates principle of least surprise and bears no resemblance to the APIs in the wild.
Alex Russell (creator of Dojo's selector engine):
This is a spec bug.
Combinator-rooted Queries
I read about some prior discussion concerning this (especially in relation to DOMElement.querySelectorAll-style queries). This is an important part of most libraries, as it stands. Maciej's proposed solution of using :root to allow for front-leading combinators is perfectly acceptable to me (where :root is made equivalent to the element, not the document element).
// jQuery
$("#foo").find("> span");
// DOM
document.getElementById("foo").querySelectorAll(":root > span")
This is something that a library can easily detect and inject.
Error-handling
I'm perfectly fine with the proposed try/catch solution however there must be a way of easily determining what the invalid portion of the selector was. Currently the following occurs in Safari:
try {
document.querySelectorAll("div:foo");
} catch(e) {
alert(e); // "Error: SYNTAX_ERR: DOM Exception 12"
}
If there were extra properties to point to what the inappropriate selector was, that'd be fundamentally important. Probably the best solution (for both implementors and JavaScript library authors) would be to simply provide a character index, working something like the following:
var selector = "div:foo";
try {
document.querySelectorAll(selector);
} catch(e) {
alert(selector.slice(e.position)); // ":foo"
}
The resulting solution in most libraries would then look something like (of course different caching could take place, as well):
try {
results = document.querySelectorAll(selector);
} catch(e) {
results = filterQuery(
document.querySelectorAll( selector.slice(0, e.position) ),
selector.slice(e.position)
);
}
There will be some form of a performance hit here but I think, if done correctly, it'll be negligible (especially in comparison to the benefits that are being received).
I hope these proposed changes work well for the members of this group as they will greatly benefit general web developers - and especially library developers.
Tags: javascript, queryselectorall, libraries
15 Comments on 'Thoughts on querySelectorAll'
April 29th, 2008
A common concern of most Ajax applications has been around their resulting accessibility. While, arguably, it's possible to design some form of a usable web page without the use of JavaScript it should be possible - with the additional scripting information - to provide a better experience to users. It's at this point that the ARIA specification comes into play. A large set of interaction is defined within it which is able to help web applications communicate directly to a screen reader in an effective manner.
To get a feel for what this interaction looks like, take the example of ARIA Live Regions (more info). With this functionality it would be possible to keep a live-updated list of users and allow the screen reader to keep up-to-date.
Observe the following ARIA-marked-up HTML:
<b>Active Users:
</b>
<p id="users-desc">A list of the currently-connected users.
</p>
<ol aria-live="polite" aria-relevant="additions removals"
aria-describedby="users-desc" id="users">
<li>John
</li>
<li>Mary
</li>
<li>Ted
</li>
<li>Jane
</li>
</ol>
A couple settings are used to make this piece of HTML particularly interactive to the screen reader (the actual JavaScript that will update this list is left out - but needless to say nothing, in particular, is needed beyond simple DOM insertion and removal).
- aria-live="polite" How polite the live area is (as in, how likely is it to butt in to what the user is currently listening to/interacting with). The default is 'polite' - in that it waits until all forms of user interaction have been completed before describing the updates to the user.
- aria-relevant="additions removals" Only notify the user about new node additions and removals. Since we wish to provide the user with a live list of users we can expect them to be both transitioning online and offline - this will give us the appropriate level of updates to make this possible.
- aria-describedby="users-desc" A pointer to the element that describes the contents of the live area. If the user
wishes to know more about what the contents of the field represent this element can be read to them.
What's most important about all of this, though, is that ARIA isn't just a pipe dream of functionality: It's implemented, today, in Firefox 2 and even more-so in the upcoming Firefox 3.
The Google Reader team recently took advantage of this and added full ARIA support to their application. It's safe to say that Google Reader is not a trivial application by any stretch, allowing this to demonstrate the feasibility of ARIA within large-scale web application projects.
In the course of their implementation they built a tool, AxsJAX, which injects ARIA usability enhancements into many pages using a bookmarklet, greasemonkey, or Fire Vox (a Firefox screenreader). They started by seeding a number of Google applications with this drop-in accessibility support (along with a few others, including the XKCD web comic).
I continue to be impressed with what can be accomplished with ARIA - and seeing the work that Google has been putting forth by implementing this functionality in their applications has been incredibly enlightening and encouraging.
Tags: ajax, javascript, accessibility, mozilla, firefox, aria
11 Comments on 'Ajax Accessibility'
Next entries » ·
« Previous entries