Activate your free membership today | Log-in

Friday, May 9th, 2008

Processing.js: Port of the Processing language to JavaScript and Canvas

Category: JavaScript, Canvas

Processing.js

John Resig has completed 7 months of work to produce a port of Processing, the “programming language and integrated development environment (IDE) built for the electronic arts and visual design communities”, which aims to teach the basics of computer programming in a visual context, and to serve as the foundation for electronic sketchbooks. One of the stated aims of Processing is to act as a tool to get non-programmers started with programming, through the instant gratification of visual feedback.”

Processing.js uses Canvas and obviously JavaScript to get the job down in the browser.

John talks about the two pieces of the puzzle:

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.

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.

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

Congratulations to John, and I look forward to seeing some fantastic visualizations in the browser thanks to this work.

Posted by Dion Almaer at 12:54 am
4 Comments

++++-
4.3 rating from 14 votes

Thursday, May 8th, 2008

Ajax Pioneer Week: Alex Russell of Dojo

Category: JavaScript, Dojo, Interview

Last, but never least, is Alex Russell of the Dojo Toolkit and SitePen. In Alex’s five minutes of video footage for our JavaOne talk, he explained how Dojo enables you to built fantastic, responsive applications for everyone. The everyone piece revolves around accessibility too, which is core to Dojo thanks to work from Becky Gibson and others on the team.

The Dojo grid and charting packages are very rich these days, and continue to get better. Alex also noted in a separate discussion how there are subtle advantages to the charting package such as being able to print the darn things out nicely. Other flashier products may not allow that minor feature.


Previously on Ajax Pioneer Week…

Posted by Dion Almaer at 11:51 am
1 Comment

+++--
3.7 rating from 20 votes

Growl for Windows and a Web Notification API

Category: JavaScript, Gears

I have talked before about the desire for a Notification API on the Web. As a Mac user, I would love to see Growl from JavaScript, and there have been libraries written from as far back as protoGrowl.

The difference is between a JavaScript API that does notifications on the desktop, versus trying to get little custom notifications inside the browser window itself. I am talking about the former.

Brian Dunnington has developed Growl for Windows, and with his latest version, he allows you to talk to the system via JavaScript.

You can check out the growl.js library.

What was interesting was the implementation side, and the paths Brian went down to get this working. I asked him for his thoughts, and he wrote up the following:

One of the biggest new features in the latest version of Growl for Windows (v1.2 alpha) is the ability to receive notifications from websites running in your browser. i spent quite a bit of time working out the best way to handle this functionality and thought i would share my thought process.

since Growl can already receive notifications over the network, i figured that it would be easiset to build the Web-based notification system on top of that. Growl receives network notifications using a simple protocol over UDP. ok - first hurdle: browsers and javascript dont do UDP, so i figured i would have to go with some kind of add-on. i wanted the solution to work cross-browser, so Firefox extensions and ActiveX plug-ins were ruled out. i also wanted the solution to work for the broadest range of people, so i didnt want to write a custom add-on (a la Gears). i knew that Flash and Silverlight both had networking support, but neither can do UDP, so they were both quickly ruled out.

that left Java as the only other widely-installed cross-browser extension at my disposal. Java obviously has robust networking support, including UDP, so i headed down that path. the biggest problem now was that i have never created a Java applet, nor even written a line of Java code. but the syntax was familiar enough, and i was able to find some good sample code on the net that i was able to mash into a tiny applet that could send UDP packets. it actually worked brilliantly, and i was quite happy with myself for solving the problem so easily.

but of course, it was not that easy. there is that little restriction known as the 'same-origin policy'. running the applet on my localhost worked great, but as soon as i ran it from any other location, i would get a secuirty exception. i tried all kinds of combinations of values for the CODE and CODEBASE attributes, including file:// urls and even encoding the applet code as a data: uri, but i was thwarted at every turn (as so i should have been - the entire reason the restriction is in place is to prevent what i was trying to do). right before i gave up on the applet idea, i had the realization that if i could serve the applet up from the local host, then it would be able to communicate with the local host later. but configuring and installing a simple web server just to serve up an applet seemed like overkill. alas, the Java idea was a dead end.

so, it was back to the drawing board. what did the browser have access to that could bridge the gap? i decided to try a custom protocol handler, similar to the Itunes Music Store (itms://). a couple of simple registry entries and i had my growl:// protocol working. i had a helper process that sat in the background and everytime a growl:// url link was clicked, the browser would pass it off to my handler, along with the original url. i decided that i could pass any information as a JSON-encoded string in that url information. again, it worked great and seemed to be a good solution, but that made me sure that it must have a drawback. turns out the drawback in this case was that there was no way for the browser to know if the protocol handler was installed on the user's machine - if the protocol handler was installed, the browser passed it off nicely and all was good, but if the protocol was not installed, Firefox would present a dialog saying something like 'firefox doesnt know how to open the address because the protocol is not known' (IE and Safari both just returned a 404-type page). since i wanted websites to be able to use the communication feature if the user had Growl installed, but not mess up the experience if they didnt, this was a deal breaker.

i was starting to run out of ideas at this point, but i remembered the idea of serving up the Java applet locally. while i was pondering the details of that solution, i thought 'if i am going to have a local server to serve up the applet, why not skip the applet and just communicate with the local server?'. so i implemented a very simple webserver that runs when Growl is running that can be accessed at something like http://localhost:9889. the idea of using the url to pass JSON was repurposed and soon i was able to pass JSON-encoded Javascript objects to the local server, which code then parse the data and handle it in real application code. i couldnt use ajax to communicate with the local server (same-origin policy strikes again), so i decided to use the hidden iframe technique. i wrote a small js library to abstract everything out, so now you can write code in Javascript that almost mimics the code you would write if you included the Growl libraries in you application code:

JAVASCRIPT:
  1.  
  2. Growl.NotificationType someKindOfNotification = new Growl.NotificationType("some kind of notification", true);
  3. Growl.register("Website Name", [someKindOfNotification]);
  4. Growl.notify(someKindOfNotification, 'Notification from the web', 'this is the description', Growl.Priority.VeryLow, false);
  5.  

of course, receiving notifications from websites opens up the possiblity of spam and other noise, so applications that register from the web have their notifications disabled by default (thus requiring the user to explicity grant the notifications they wish to receive). but that is another topic for another day.

Ed: I decided to make today, "Extend the browser through APIs Day"

Posted by Dion Almaer at 11:38 am
6 Comments

++++-
4.3 rating from 8 votes

Location APIs: The Discussions

Category: JavaScript, Gears

The Gears community is discussing a Geo Location API, which Aaron Boodman mentioned "was recently proposed to the W3C WebAPI group."

Aza Raskin just posted today about Geolocation in Firefox and Beyond which covers his thoughts on an API.

I thought it would be fun to look at the proposed APIs:

Gears Examples

JAVASCRIPT:
  1.  
  2. var geo = google.gears.factory.create('beta.geolocation');
  3.  
  4. // Get the position.
  5. geo.getCurrentPosition(function(position) {
  6.   updateMap(position.latitude, position.longitude);
  7. });
  8.  
  9. // Watch the position over time.
  10. var watchId = geo.watchPosition(function(position) {
  11.   updateMap(position.latitude, position.longitude, position.accuracy);
  12. });
  13.  
  14. geo.clearWatch(watchId);
  15.  
  16. // Only get the position if the last known position is more than a minute old.
  17. var now = new Date().getTime();
  18. var threshold = now - 60000;
  19.  
  20. if (geo.lastPosition &&
  21.     geo.lastPosition.timestamp.getTime()> threshold) {
  22.   updateMap2(geo.lastPosition);
  23. } else {
  24.   loc.getCurrentPosition(function(position) {
  25.     updateMap2(position);
  26.   });
  27. }
  28.  

Aza Examples

JAVASCRIPT:
  1.  
  2. var geolocator = new navigator.GeolocationRequest();
  3. geolocator.request(function(location) {
  4.   alert( location.latitude + ', '+ location.longitude + ", " + location.accuracy );
  5. });
  6.  
  7. var geolocator = new navigator.GeolocationRequest();
  8. geolocator.request({
  9.   success: function(location) { /* We've got the location! */ },
  10.   error: function(err){ /* There was an error getting location. */ },
  11.   accuracy: "neighborhood"
  12. });
  13.  

There is also a lot of talk around privacy and accuracy, and Apple has their own location manager too.

I hope that we can unify some of this, and give the browsers a geo location API soon. One simple JavaScript abstraction will enable a lot of great apps.

Posted by Dion Almaer at 8:09 am
2 Comments

++++-
4.3 rating from 7 votes

Wednesday, May 7th, 2008

The seven rules of pragmatic progressive enhancement

Category: Usability, JavaScript, Tutorial, Unobtrusive JS

I've been talking about progressive enhancement here before and got a lot of flak in comments about it. It seemed that there was a general misunderstanding of progressive enhancement and unobtrusive scripting as a "passing fad" or "backward facing rather than being innovative".

I was asked by a design agency in London to go there and give a brown bag presentation (during lunch break) on the matter and took this as an opportunity to write up reasons and examples for progressive enhancement concentrating more on the why than on the how.

The gist would be to say: enhancing a product progressively means you'll always deliver a working product - as you have no idea how your product can fail in certain environments, you plan for it to fail. This ties in nicely with the agile manifesto - you always deliver software that works.

In my talk I came up with seven "rules" of pragmatic progressive enhancement:

  1. Separate as much as possible
  2. Build on things that work
  3. Generate dependent markup
  4. Test for everything before you apply it
  5. Explore the environment
  6. Load on demand
  7. Modularize code

I've taken these ideas and backed them up with benefits you get by following them and code examples in a full article: Pragmatic Progressive Enhancement.

The article is licensed with Creative Commons and uses YUI in the example scripts, feel free to translate, remix and create examples using other libraries.

You can also read the slides on slideshare:

Pending the quality of the recording, there'll also be a video available sooner or later.

Posted by Chris Heilmann at 5:58 pm
3 Comments

++++-
4 rating from 8 votes

Ajax Pioneer Week: John Resig of jQuery

Category: JavaScript, Interview, Presentation, jQuery

John Resig got in front of the camera, and the projector, as he gives us his thoughts on the state, and future of Ajax.

He starts out by discussing jQuery Core, and the features in the near term (1.2.4), short term (1.3) and beyond. He then delves into the UI side of the house with jQuery UI 1.5. He segues from jQuery to the future of browsers and JavaScript in general.


Previously on Ajax Pioneer Week...

Posted by Dion Almaer at 1:14 pm
2 Comments

+++--
3.4 rating from 38 votes

Lazily load functionality via Unobtrusive Scripts

Category: JavaScript, Prototype

David Kees has written about Using Prototype to Load Javascript Files, which is an implementation of the general technique of loading functionality via scripts based on the availability of DOM elements.

He started using the technique to scratch an itch:

The calendar on this site only appears on pages that show blog-related information. That calendar is enhanced with Javascript allowing you to change the month displayed by the calendar without reloading the rest of the page. So, in order to ensure that these enhancements would be available everywhere the calendar is, I figured I had two options:

  1. Code the inclusion of the Javascript file into every page which requires it. While a good solution, and one that has worked well in the past, sometimes it can be difficult to remember or realize that you've forgotten to include the file when you add new pages that require it.
  2. Find a way to automatically include the file when it's needed. This would avoid the need to remember the need to include it when adding new pages that require it, but would result in a little more Javascript going on when the page loads.

Here is an example implementation:

JAVASCRIPT:
  1.  
  2. document.observe("dom:loaded", function() {
  3.         var calendar = $("calendar");
  4.         if(calendar) {
  5.                 var script = new Element("script", { type: "text/javascript", src: "/path/to/calendar.js" });
  6.                 document.observe("calendar:loaded", function() { new Calendar(calendar); });
  7.                 $$("head")[0].insert(script);
  8.         }
  9. });
  10.  

Posted by Dion Almaer at 1:02 pm
14 Comments

++++-
4 rating from 9 votes

Monday, May 5th, 2008

HTML Parser in JavaScript

Category: HTML, JavaScript

John must have had some downtime on Sunday afternoon, as he implemented an HTML parser in JavaScript. The library, that you can play with via this demo, lets you attack HTML in a few ways:

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:

JAVASCRIPT:
  1.  
  2. var results = "";
  3.  
  4. HTMLParser("<p id=test>hello <i>world", {
  5.   start: function( tag, attrs, unary ) {
  6.     results += "<" + tag;
  7.  
  8.     for ( var i = 0; i <attrs.length; i++ )
  9.       results += " " + attrs[i].name + '="' + attrs[i].escaped + '"';
  10.  
  11.     results += (unary ? "/" : "") + ">";
  12.   },
  13.   end: function( tag ) {
  14.     results += "";
  15.   },
  16.   chars: function( text ) {
  17.     results += text;
  18.   },
  19.   comment: function( text ) {
  20.     results += "<!--" + text + "-->";
  21.   }
  22. });
  23.  
  24. 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.

JAVASCRIPT:
  1.  
  2. var results = HTMLtoXML("<p>Data: <input disabled/>")
  3. results == "</p><p>Data: <input disabled="disabled"/></p>"
  4.  

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:

JAVASCRIPT:
  1.  
  2. // The following is appended into the document body
  3. HTMLtoDOM("<p>Hello <b>World", document)
  4.  
  5. // The follow is appended into the specified element
  6. HTMLtoDOM("<p>Hello <b>World", document.getElementById("test"))
  7.  

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:

JAVASCRIPT:
  1.  
  2. var dom = HTMLtoDOM("<p>Data: <input disabled/>");
  3. dom.getElementsByTagName("body").length == 1
  4. dom.getElementsByTagName("p").length == 1
  5.  

One place that you could use this API would be on the server-side. For example, using Aptana Jaxer. Although, you could also interface directly to Java, or just use the Mozilla utilities directly.

Posted by Dion Almaer at 10:51 am
6 Comments

+++--
3 rating from 21 votes

Compression using Canvas and PNG

Category: JavaScript, Canvas

The image above is the 124 kilobyte Prototype library embedded in a 30 kilobyte 8 bit PNG image file.

Jacob Seidelin had some fun this weekend it appears and created a script that can read in JavaScript code from images. To do this, he used the canvas getImageData() method.

Here are the detailed steps:

The first step was to find the best image format for the job, that means the one that gives the best compression while still being lossless. Here on the intertubes, we don't get a lot of image format choices and since JPEG is lossy, we're down to GIF and PNG.
For PNG we have two options, 24 bit and 8 bit. Using 24 bit RGB colors, we can store 3 bytes of data per pixel while 8 bit indexed colors only gives us 1 byte per pixel.
A quick test in Photoshop tells us that a 100x100 image with random 24 bit colored noise compresses down to about 20 KB while a 300x100 image with random 8 bit monochromatic noise compressed down to just 5 KB. A regular 8 bit GIF comes in a bit heavier than the 8 bit PNG, so we go with the PNG option.

Now we need to convert our Javascript file into color data and stuff it in a PNG file. For this purpose, I crafted this quick and dirty PHP script, which reads the Javascript file, creates a PNG image file and simply lets each pixel have a value 0-255 corresponding to the ascii value of the character in the script.

I ran into a problem here, since the image is created as a truecolor image and we need it to be 8 bit indexed and PHP won't make an exact conversion. I guess there are ways to create a palletted image from scratch in PHP/GD, but I haven't looked into that yet. The solution for now is to simply run the generated image through something like Photoshop and convert it to 8 bit there.

So now we have the Javascript all nice and packed up in a compressed PNG file and now we need to get it out again in the client. Using the canvas element, we simply paint the picture using drawImage() and then read all the pixel data using getImageData(). This data is given to us as a large array of values, where each pixels takes up 4 elements (RGBA), so we just take every 4 value and tack them all together into an eval()-ready string. And we're done.

And the reading function is here.

NOTE: This is for fun, and isn't meant to be used in the real world. That being said, see it at work in the mario game.

Posted by Dion Almaer at 10:28 am
19 Comments

++++-
4.8 rating from 26 votes

Friday, May 2nd, 2008

We are JavaScript library authors. Hear us roar!

Category: JavaScript, Browsers, CSS

John Resig "doesn't think there's a single JavaScript developer who isn't excited about the new Selectors API specification (and the upcoming implementations)."

He was asked to provide feedback on the API, and he sent them an email with just that.

He had three concerns:

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:

HTML:
  1.  
  2.   <div><p id="foo"><span></span></p></div>
  3.   <script src="http://o.aolcdn.com/dojo/1.1.0/dojo/dojo.xd.js"></script>
  4.   var foo = document.getElementById("foo");
  5.   // should return nothing
  6.   alert( dojo.query('div span', foo).length );
  7.   // will return the SPAN (booo!)
  8.   alert( foo.querySelectorAll('div span').length );
  9.   </script>
  10.  

He then asked other library authors if they agreed:

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).

JAVASCRIPT:
  1.  
  2.   // jQuery
  3.   $("#foo").find("> span");
  4.  
  5.   // DOM
  6.   document.getElementById("foo").querySelectorAll(":root> span")
  7.  

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: