Blog
September 1st, 2009

I've been slowly working on a new JavaScript book that covers many of the specifics behind how and why JavaScript libraries are designed they way that they are - titled Secrets of the JavaScript Ninja. I'm still working on the book - I have four chapters left to write - and am hoping to have it completed this year.
Incidentally Manning Publishing is running a special (today only!) offering the ebook version of Secrets of the JavaScript Ninja for 50% off the normal price, if you use the coupon code pop0901. (Note: I've heard that it may also work for the ebook + paperback version of the book.)
A number of excerpts from the book can be found in the site archive. My Learning Advanced JavaScript interactive tutorial is also based upon the contents of the book.
Note: The book is not yet complete, nor has it gone through any proofreading or technical editing - there will be mistakes. Also, yes, I'm aware that the cover of the book has a samurai on it, not a ninja - I'm working with the publisher to rectify this.
I've also been asked if people should buy Pro JavaScript Techniques (my Apress book from 2006) or my upcoming one. I should note that the upcoming one is much more advanced than my previous one - covering much more complicated topics and more about cross-browser development. If you're looking for a good introductory book to JavaScript and the DOM I strongly recommend Nicholas Zakas' Professional JavaScript Developers book.
Tags: javascript, book, programming
63 Comments on '50% Off Secrets of the JavaScript Ninja'
August 19th, 2009

Unfortunately I'm short on time at the moment (trying to launch a project this week) but I have to say, at least, a few words about the hacker and artist _why.
At this moment, _why's online presence appears to be no more. All of his sites and code are gone. This includes, and is not limited to:
- http://twitter.com/_why
- http://github.com/why
- http://whytheluckystiff.net/
- http://poignantguide.net/
- http://hackety.org/
- http://shoooes.net/
- http://hacketyhack.net/
- http://tryruby.hobix.com/
Two conjectures are common at the moment: His account(s) were hacked and sites taken down or he simply decided to delete his online presence. I personally believe that he did this deliberately and with some amount of forethought.
One of the things that's made _why unique amongst programmers is that he has worked in virtual anonymity. Some people knew his name but it was never a focus of his online persona (and, at least, never actively associated with him as a person - I've seen sites that purport to identify him, but they're generally incorrect, and fringe, at best). Even live, giving talks or performing music, he still went by his pseudonym.
Reading through the original discovery thread you can see a full range of emotion regarding his disappearance; Anger, confusion, and sadness.
Personally, I feel a mixture of joy and amazement.
_why, the code he's written, the persona he projected, and the art he produced has been a long-time admiration of mine. Some only see _why's code or writing (Why's Poignant Guide to Ruby, for example - which can still be purchased on Lulu).
I tend to see _why more as an artist. He used a wide variety of mediums for his exploration: Written word, drawings, code, and even music.
Not many know that he released an album to go along with Why's Poignant Guide to Ruby. One of my favorite songs from the album is the one for the second chapter: This Book is Made (of Rabbits and Lemonade).
Nothing can capture the artistic ethos of _why better than the above song.
_why - even in his code - was eccentric, humorous, cute, and whimsical. He relished his ability to express his art and was extremely good at it, at the same time.
Underlying the layer of whimsy that permeated his work there was a more serious tone: expression, simplicity, and education. In all of his code, and writing, he was constantly trying to find ways to bring the art of hacking to more people - to younger people - to simplify the complexities that normally permeate development.
It's never completely clear from his writing, but I like to imagine _why with children. Either as a grade school teacher or with his own children. Finding ways to communicate with them, teach them, and encouraging their imagination and freedom of expression.
Due to his expressive nature I feel like I understand _why, even though I only managed to chat with him once, for a couple minutes, on IRC. I can especially appreciate his anonymity.
In my life I constantly try to keep my work and personal life separate. What _why did with his online persona has been a great inspiration to me. He was successful in having virtually no bleed-over of his personal life (with his family and friends) into his online persona, and likely vice-versa.
People get way too caught up in their work. I like to think that he was able to keep the products of his online persona separate from the rest of his life, treating them as completely distinct entities - the perfect, clear-cut, division between personal life, work, and play.
Seeing the complete deletion of his online persona doesn't terribly surprise me. Back in 2007 _why closed his main blog (RedHanded). That event truly shocked me, but it helped me to better understand him as a person. The blog, even though he had put years of work into it and people strongly identified him with it, was immaterial. It didn't feel like the right place to talk anymore so he moved on to another place, abandoning the old site.
If there's any analogy that I can make about _why, his online persona, and all the works that he's produced over the years it's to the Tibetan Buddhist tradition of the sand mandala.
Sand mandalas are incredibly intricate works of art that take many people many days to construct. They're very expressive, but fragile, works of art.
After a mandala has been constructed - and displayed - it is ceremoniously deconstructed - which is meant "to symbolize the Buddhist doctrinal belief in the transitory nature of material life."
_why's entire online presence and code was presented in the sand mandala that was '_why'. The person behind '_why' simply decided to move on and close that portion of his life.
I've seen a few people ask why he opted to remove his code - why didn't he take his work seriously? (Especially since others have grown to depend upon it.)
Looking at the cumulative work and art of _why it should become painfully obvious: The online presence of _why, and all the code, writing, music, and drawings that've been produced are a mere transitory portion of one person's life. He was constantly moving from project to project, blog to blog. Now he's truly moved on and we should feel joy in having gotten to know him, and his art, over the past couple years.
While this isn't a eulogy for a living person - I fully expect that he's happy and continuing to explore life with his friends and family - it's a eulogy to one portion of one man's life.
I wish I could better express what I feel for _why. Whenever I think of him I think of artistic expression, happiness, and the joy of exploration.
To _why: Thank you for bringing your code and art to us over the past couple years. It's been greatly appreciated, more than you can know. Please continue to enjoy your life and bring your joy and whimsy to others all over the world.
Tags: programming
64 Comments on 'Eulogy to _why'
July 1st, 2008
Like every web developer I've spent a lot of time using the Firebug extension to Firefox in my day-to-day development. I've found it interesting to see how my development methodologies have changed with access to that tool.
Unsurprisingly, my personal development style mirrors much of the general web dev public. But what I find most interesting is to try and track trends in web development that Firebug has single-handedly revolutionized.
Firebug Advances
Performance Profiling
Prior to Firebug there was only rudimentary analysis of JavaScript performance (using tricks like injecting timers and computing the difference). Firebug brought us the ability to analyze all function calls during a period of execution, see how they each affected each other and, probably most important, see the difference in the sub-millisecond range.
Previously none of these techniques were possible with pure-JavaScript techniques - having the ability to tap into the JavaScript engine (which Firebug does) is fundamentally important to getting good analysis.
You can see an immediate interest, by JavaScript library authors, in the performance of their code bases around the time of Firebug's introduction of profiling.
Console logging with object introspection
Logging statements has always been possible with JavaScript (and, most infamously, with the alert() function) however Firebug gave us something significant: The ability to click and introspect into logged objects. This includes the ability to click DOM nodes (and see their properties and methods) and even normal objects (like Arrays or Object literals).
Firebug has to maintain a lot references to point to where these objects exist - and it wouldn't be possible in pure-JavaScript without introducing an excessive number of memory leaks.
Current Styles / CSS Rules
There had existed some tools for examining the current CSS style values of a DOM element (such as its dimensions and positioning) but Firebug brought a whole new level of inspection: The ability to see which stylesheet rules were introducing specific styling on an element. Not to mention the ability to edit the rules in-line (along with disabling them outright).
This level of inspection completely overhauled Web Design - and has been able to detach many web designers from their IDE-of-choice into a more agnostic view of CSS design. Absolutely the biggest short-coming of this feature is its inability to work cross-browser (although, that argument can certainly be used for most Firebug features).
Network Performance
Firebug's network tab gave developers the ability to see - in very real terms - two things: 1) How long a resource was taking to load and 2) How the loading of that resource was blocking the loading of other resources. #2 is especially important, seeing that the execution of JavaScript blocks other actions from occurring can be an eye-opening experience to most developers. Or even seeing how a slow-loading stat tracking script can prevent the further display of the page.
XMLHttpRequest Inspection
While XMLHttpRequest use existed prior to the existence of Firebug it was horribly hard to debug - it was rarely obvious where errors were occurring - on the client-side? on the server-side? in the transmission? The ability to see how the requests occurred - and very importantly - how long they took (and even how frequently they occurred!) has done much to improve the overall quality of Ajax use on web pages.
JavaScript Debugging
I would've said that JavaScript Debugging was a piece of that equation, as well, however Venkman definitely lead the way, in that respect (and has been a de-facto debugger for quite some time).
I'd argue that these trends wouldn't be where they are right now if it weren't for Firebug - and that tools are the primary reason for a development strategy's success. As a corollary look at the relative success of web standards - I'd argue that adherence to HTML or CSS wouldn't be where it is today without the tools to verify a page's compliance.
How to Improve
The question now becomes: What are the next set of tools that Firebug can introduce that will revolutionize its respective areas of development?
I'd like to propose a couple, possible, areas of interest:
JavaScript Library Analysis
As it stands Firebug's JavaScript function analysis is, perhaps, too finely-grained to provide help in many instances - especially when the use of JavaScript libraries is at play. For example, when using jQuery, you're generally more concerned with finding out how fast, or slow, a particular method is - or a selector - not the performance of all the individual internal methods of jQuery.
I began some of this analysis with my Deep Profiling jQuery Apps experiment but that's really only a test. Smart integration of JavaScript library knowledge into Firebug can provide significant details about how your code should be performing.
Visual Performance Profiling
Application performance profiling is rather clumsy right now, we have a number of disparate resources (network performance, rendering performance, script performance) that we need to mentally merge to create a full picture of what's happening. To counter this I'd like to propose a way of visually viewing how components of a site affect its overall performance. Perhaps a way to break things down like this:
- Header: 300ms: 20ms Transmission + 20ms Parsing + 60ms CSS + 200ms JavaScript
- Google Ad: [BLOCKING RENDERING] 600ms: 20ms Transmission + 20ms Parsing + 20ms CSS + 240ms JavaScript + 300ms Frame Loading
- Sidebar: 400ms: 40ms Transmission + 40ms Parsing + 80ms CSS + 240ms JavaScript
The YSlow Firebug plugin already provides some level of analysis on your site - but it's much more holistic (giving you generic tips for files and pieces of code). Whereas a more specific approach would be greatly appreciated.
Ajax Improvements
We currently have the ability to view XMLHttpRequests as they occur, which is great, but some additions could be made that would serve to be quite helpful, such as:
- The ability to manipulate a request and re-submit it. If you're attempting to see how different inputs will affect your site, this would be a great way to play back requests or see how they can be best improved.
- Right now Firebug only lets you know the basic textual output that's coming from the server-side. Having it be able to tell you if incoming XML, JSON, or even HTML is syntactically correct (and even being able to navigate the resulting structures - as the browser would see them) would be a huge boon. As it stands it can be quite frustrating to receive a slightly-malformed response from a server and be stuck trying to figure out what's going wrong.
- Better JSON/JSONP integration is essential. There are a large number of Ajax requests being done through dynamic script tag injection - and those are completely unmonitored by Firebug's XMLHttpRequest tracking. Being able to see what requests and responses look like - and where errors may be occurring - would be immensely useful.
Rendering Performance Analysis
While we have fantastic tools for digging in to the performance of JavaScript - CSS is a complete unknown. How much overhead do our stylesheets provide? How many elements does this CSS rule affect? Does this rule cause a costly reflow to occur? and how many times? How long does it take to render a particular portion of a page? Would changing the structure of my page help to improved perceived rendering speed?
Virtually all of these questions are un-answered and we need a tool to help provide a solid response.
Security Analysis
Security is one area that has seen virtually no attention in the respect of user tools. Most developers have no idea how secure their web site is or how vulnerable it may be to attacks. There needs to be easily-accessible tools for testing:
- SQL Injection attacks
- XSS Injection
- Susceptibility to Spoofing (Data Encryption)
At the very least. The problem here is that while these tools will be incredibly useful for developers to improve their web sites - it'll also encourage malicious behavior. Although, arguably, those that wish to be malicious already have the tools to do so.
Standards Integration
Inline support for analyzing the standards-compliance of a page. Being able to see notes next to specific elements, attributes, CSS rules, etc. that show information on how they don't comply with particular standards - or even how they could be improved to match standards.
This includes inline strictness warnings for JavaScript (produced by the JavaScript engine).
I think that compliance should go a step further, as well, and look to provide information on Microformat and RDFa compliance - pointing out specific errors and helping sites to become better formatted.
Finally - RSS and Atom standards compliance. Notifying a developer that their site's RSS/Atom feed is malformed would allow them to immediately make a more compliant feed (a common area of mistakes).
Internet Explorer Support
The final, and perhaps most difficult, item that should occur would be a port of Firebug over to Internet Explorer. Both Safari and Opera have web developer tools integrated into their browsers - however Internet Explorer still consumes a majority market share and there's no good tools in sight. (I, personally, use CompanionJS but it's still a far cry from the full suite of utilities that Firebug provides - especially in the realm of DOM/CSS.)
This could probably be remedied if there was a really good pure-JavaScript Firebug (although the overhead associated with many of Firebug's features would lead to an astronomically-sized implementation). The current "Firebug Lite" is something of a joke - only vaguely functioning in modern browsers.
Not only do I want to see Firebug improve - it's imperative that Firebug continue to improve, for the sake of web developers everywhere. If it simply stalls and works into a stasis of bug fixes then web developers will be stuck with the current set of tools for quite some time. While other browsers are improving at a rapid pace, it'll still be quite some time before they are able to match the current feature-set of Firebug.
Since so much of web development ecosystem is currently linked to the health of a single tool advances have to be made now and they have to be made quickly in order for the web to flourish and survive as a development medium.
Tags: development, firefox, firebug, javascript, css, programming
41 Comments on 'Powering a Web Revolution'
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: javascript, processing, programming
220 Comments on 'Processing.js'
April 30th, 2008
Recently I put a lot of work into my office (as I frequently mentioned in my Twitter account) - revamping it, adding new furniture, hanging up art, and generally moving things around. I've received some questions about my set up so I've taken some pictures and detailed them here.
Desk
This is my primary work area in the apartment. I work off of a previous-generation Macbook Pro (Core 2 Duo, no Wireless N support) on a 24" LCD. I use the nice new Apple Keyboard - and swear by it. I like to position my desk to overlook the street (the bay window provides that nicely). I primarily drink water during the day and keep a gallon jug by the desk.
Whiteboard and Shelf
To the right of my desk is my whiteboard (primarily used as a rough to-do list). Note the stack of Pro JavaScript Techniques books on the shelf.
Second Shelf
The primary location of my technical books. The print is by Shepard Fairey.
Love-seat and Side Window
Couch, Shelves, Table
The primary seating area of the office. It's very important, for me, to have comfortable places to sit. Throughout the day I frequently change positions in the office (moving from desk to couches and vice versa). The shelf also serves as a location for my printer (an ever-reliable Brother Dual-sided laser printer), wireless base station (D-Link 802.11 B/G/N), Wii, and projector (BenQ 720p HD). The large painting was created by my brother Steven, as his Chirstmas present to me>. The owl print on the wall is from aestheticapparatus.com. The door is just a storage closet.
Projector Screen
Where the projector shines to. The result is surprisingly bright - very effective even during the day with all the sun coming in to the room. About 90" diagonal.
Tags: programming, work, office
16 Comments on 'My Work Area'
April 9th, 2008
A crude JavaScript implementation of the first stage of Super Mario Brothers has been making the rounds today. It's roughly playable but misses many key aspects (no mushrooms, no flag, no one-ups, etc.). However, that's not what's particularly interesting about the game.
Perhaps the most interesting part of the application is not within the game mechanics itself but in the fact that all of the game contents are embedded within the game script: This includes all game sprites and music.
This is an interesting feat and one that's possible to accomplish within your own code. Let's take a step through how this was done to understand how we can better use this within our own sites.
Music Embedding (base64)
Surprisingly, how the music is embedded within the application is, perhaps, the easiest to completely understand. The application makes use of data: URLs, encoding the Mario music MIDI files using base64.
We can see the result within the source file:
aSounds = [
// very small, very simple mario theme. Sequenced by Mike Martel.
"data:audio/mid;base64,TVRoZAAAAAYAAQAEAMBNVH...",
// game over. Sequenced by John N. Engelmann.
"data:audio/mid;base64,TVRoZAAAAAYAAQADAHhNVH..."
],
data: URLs work by encoding the entire contents of the specified files within the URL to the file itself. This can even be used for images (embedding PNGs, JPGs, GIFs, etc.). In this case it's being sent to an <embed/> element, which is capable of playing the midi file. We can spot the resulting injection code here:
playMusic = function(iSoundID, bLoop) {
if (!bMusic) return;
var oEmbed = dc("embed");
oEmbed.src = aSounds[iSoundID];
oEmbed.id = "sound_" + iSoundID;
if (bLoop) oEmbed.setAttribute("loop", "true");
oEmbed.setAttribute("autostart", "true");
oEmbed.style.position = "absolute";
oEmbed.style.left = -1000;
appChild(document.body, oEmbed);
},
Which simply creates an embed element, sets it to automatically start, and injects the data: url as the src. The result is an auto-playing MIDI file (assumedly a similar result could be achieved with another universal file format, such as WAV).
data: URLs are capable of playing in all browsers but Internet Explorer (they're being introduced in Internet Explorer 8). In the case of this application Internet Explorer users simply don't receive audio for the game.
Image Embedding (binary and ascii)
The second, interesting, portion of the application is the embedding of the various sprites used in the game. This includes the mario character, the blocks, pipes, and even the background images.
The application uses a number of interesting techniques in order to compress the size of the resulting images. Rather than using the data: url technique (which is completely applicable, in this case, to applications that can use them) the game, instead, uses the <canvas/> element (and regular div/spans for Internet Explorer). Because of this dual platform target the individual pixels of the sprites must be saved and retrieved.
In order to meet this target all of the individual pixels must be stored in a way that is space efficient, and yet, easy to access.
To start, all available colors must be mapped out and reduced. All sprites within the game have, at most, 4 colors (some have less). We can see this reduction process in the following graphic:
This reduction, and mapping into a binary grid, is a useful way to create a portable sprite (each sprite is reduced to the binary and associated colors). The next step is to convert the binary grid into an easily-transportable string, like the following:
The end result is a string representation of the entire sprite - which is quite small (byte-wise) while still being translatable back to its original representation.
Both of these encoding techniques can prove to be quite useful in your JavaScript code - especially if you're striving to encapsulate as much within the base code, itself, rather than in external files.
Tags: javascript, programming
19 Comments on 'Embedding and Encoding in JavaScript'
April 1st, 2008
NOTE: This was an April Fools joke for April 1st, 2008.
Over the past two years, seeing hundreds of thousands of people use jQuery, a major point has become apparent: jQuery simply isn't able to scale to handle the development needs of most power users. It lacks the clarity and power functionality that most developers need in order build applications in a collaborative environment.
For this reason I've put a lot of work into a new library (which sits on top of jQuery), called:
Classy Query
» View Source to Classy Query
If one thing has become apparent to me it's that users enjoy working with the typical Class-style of object creation and inheritance. Because of this I've constructed the entirety of Classy Query in an classical manner (you can inherit and override any piece of functionality that you desire).
Before we go too far, let's take a look at the type of clearly-defined code that you can now write with Classy Query:
<script src="jquery.js"></script>
<script src="classy.js"></script>
<script>
jQuery.Events.addEventListener(document, "ready", function(){
jQuery.querySelectorAll("div").forEach(function(elem){
jQuery.DOM.append(elem, " <b>More...</b>");
});
jQuery.querySelectorAll("div b").forEach(function(elem){
jQuery.Events.addEventListener(elem, "click", function(elem, event){
var next = jQuery.Traversal.nextSibling(elem);
var animation = jQuery.Effects.buildAnimation( next, {height: "toggle"});
amimation.start();
});
});
});
</script>
You can even sub-class functionality, creating your own pieces of encapsulation. All of the class and inheritance functionality is taken care of by the Simple JavaScript Inheritance code released last week.
jQuery.
DOM.
boldWrapInner = jQuery.
DOM.
wrapInner.
extend({
attach:
function(elem
){
this._super
(elem,
"<b></b>");
}
});
jQuery.querySelectorAll("div").forEach(function(elem){
jQuery.DOM.boldWrapInner(elem);
});
Additionally you can treat pieces of functionality as if they were attachable behaviors, like so:
jQuery.querySelectorAll("div").attach(new jQuery.DOM.boldWrapInner());
There's a number of core features encompassed in Classy Query that really help to transform the traditional jQuery experience into something much more usable.
Class creation
The full Simple JavaScript Inheritance API is included in Classy Query, allowing you to extend and create JavaScript 'classes', like so:
var Person = jQuery.
Class.
create({
init:
function(name){
this.
name =
name;
}
});
var ClassyDude = Person.extend({
sipWine: function(){
return "Has a beautiful bouquet.";
}
});
Inheritance
It's possible to inherit from any existing piece of Classy Query functionality, supporting a true 'programming in the large' mindset. You can inherit from, or completely override, existing methods with ease (especially since they're all classes).
jQuery.Effects.collapse = jQuery.Effects.buildAnimation.extend({
attach: function(elem){
this._super(elem, {height: "hide", width: "hide"});
}
});
Behaviors
Behaviors tend to encapsulate a portion of functionality which is applied against an element (such as making a table sortable or making an item draggable). Classy Query supports a technique to make this particular implementation trivial.
jQuery.querySelectorAll("div")
.attach(new jQuery.DOM.addClassName("current"));
No more 'this'
The 'this' keyword is confusing and frequently misused. To counter this all access to elements (within functions) is done by the first argument, rather than through 'this'.
jQuery.querySelectorAll("div").forEach(function(elem){
jQuery.DOM.addClassName(elem, "current");
});
Re-Structuring
The hierarchy of jQuery has been completely re-organized. Rather than having a single, flat, interface through which to access all methods functionality has been broken down into individual groupings of methods. These groupings tend to, also, coordinate with the jQuery Documentation for convenience.
Additionally, nearly all the method names have been re-named in order to provide a greater level of clarity to developers. Frequently it was found that the concise method names of jQuery provided too much confusion to developers just getting started with the library. The end result is a library that is easier to read and understand for developers.
The full list of categories and changed methods can be found in the following table:
| jQuery |
Classy Query |
| jQuery |
jQuery.querySelectorAll |
| each |
forEach |
| prepend |
jQuery.DOM.prepend |
| append |
jQuery.DOM.append |
| before |
jQuery.DOM.insertBefore |
| after |
jQuery.DOM.insertAfter |
| wrap |
jQuery.DOM.wrap |
| wrapInner |
jQuery.DOM.wrapInner |
| wrapAll |
jQuery.DOM.wrapAll |
| clone |
jQuery.DOM.clone |
| empty |
jQuery.DOM.empty |
| remove |
jQuery.DOM.remove |
| replaceWith |
jQuery.DOM.replaceWith |
| removeAttr |
jQuery.DOM.removeAttribute |
| addClass |
jQuery.DOM.addClassName |
| hasClass |
jQuery.DOM.hasClassName |
| removeClass |
jQuery.DOM.removeClassName |
| offset |
jQuery.DOM.getOffset |
| text |
jQuery.DOM.getText |
| text |
jQuery.DOM.setText |
| html |
jQuery.DOM.getHTML |
| html |
jQuery.DOM.setHTML |
| attr |
jQuery.DOM.getAttribute |
| attr |
jQuery.DOM.setAttribute |
| val |
jQuery.DOM.getValue |
| val |
jQuery.DOM.setValue |
| height |
jQuery.DOM.getHeight |
| height |
jQuery.DOM.setHeight |
| width |
jQuery.DOM.getWidth |
| width |
jQuery.DOM.setWidth |
| css |
jQuery.DOM.getCSS |
| css |
jQuery.DOM.setCSS |
| children |
jQuery.Traverse.getChildElements |
| find |
jQuery.Traverse.getDescendantElements |
| next |
jQuery.Traverse.getNextSiblingElements |
| nextAll |
jQuery.Traverse.getAllNextSiblingElements |
| parent |
jQuery.Traverse.getParentElements |
| parents |
jQuery.Traverse.getAncestorElements |
| prev |
jQuery.Traverse.getPreviousSiblingElements |
| prevAll |
jQuery.Traverse.getAllPreviousSiblingElements |
| siblings |
jQuery.Traverse.getSiblingElements |
| filter |
jQuery.Traverse.filterSelector |
| bind |
jQuery.Events.addEventListener |
| unbind |
jQuery.Events.removeEventListener |
| trigger |
jQuery.Events.triggerEvent |
| hover |
jQuery.Events.hover |
| toggle |
jQuery.Events.toggle |
| show |
jQuery.Effects.show |
| hide |
jQuery.Effects.hide |
| toggle |
jQuery.Effects.toggle |
| animate |
jQuery.Effects.buildAnimation |
| queue |
jQuery.Effects.queue |
| dequeue |
jQuery.Effects.dequeue |
| $.ajax |
jQuery.Ajax.request |
| load |
jQuery.Ajax.loadAndInsert |
| ajaxSetup |
jQuery.Ajax.setup |
| serialize |
jQuery.Ajax.getSerializedString |
| serializeArray |
jQuery.Ajax.getSerializedArray |
querySelector and querySelectorAll
Finally, rather than having a generic, catch-all, method as jQuery selector functionality is deferred to the new querySelector and querySelectorAll methods. These methods only support pure CSS 1-3 selectors (nothing extra) in an attempt to avoid any unpleasant situations when a browser's native querySelectorAll is implemented.
jQuery.
querySelectorAll("div").
forEach(function(elem
){
jQuery.
Effect.
hide( elem
);
});
jQuery.Effect.hide( jQuery.querySelector("#item") )
» View Source to Classy Query
I hope this particular library will be of use to the general jQuery-using population. I hope we can start to have an open dialog, moving forward, getting everyone to adopt a more standard approach to JavaScript development. There's no reason why we shouldn't be using this tried-and-true approach to application development. It's worked in an untold number of existing applications, it's bound to work here as well. Enjoy.
Tags: programming, jquery, javascript
65 Comments on 'Classy Query'
March 27th, 2008
Yesterday I gave a presentation for the local ACM of Northeastern University. I covered the basics of JavaScript - targeted to a Computer Science major (in the case of the students at NU, they learn Scheme and Java so I emphasized the subject matter to that audience). I did a fast run-through of the whole language, covering the main points, and move on to a quick inspection of jQuery and the DOM - closing with some Q&A. The subject matter of JavaScript 2 (and 1.6-1.8) came up a couple times so discussion of that was interspersed throughout. There were a bunch of jQuery users in the audience and it was great to get to hear their feedback.
JavaScript and jQuery for CS Majors
Also available in OGG Theora.
Here are the full slides, as well. I left in the slides where I typed out code, so that you can be able to reference it.
Tags: javascript, programming, presentation
16 Comments on 'JavaScript Talk at Northeastern'
·
« Previous entries