Yehuda Katz is a member of the Ember.js, Ruby on Rails and jQuery Core Teams; his 9-to-5 home is at the startup he founded, Tilde Inc.. There he works on Skylight, the smart profiler for Rails, and does Ember.js consulting. He is best known for his open source work, which also includes Thor and Handlebars. He travels the world doing open source evangelism and web standards work.

Archive for the ‘JavaScript’ Category

jQuery Selector Refcardz

Bear Bibeault (my co-author on jQuery in Action) and I have put together a neat reference card for jQuery selectors that you can get from DZone.

Here’s a blurb they provided:

This reference card puts the power of jQuery selectors at your very fingertips. Written by Bear Bibeault and Yehuda Katz, co-authors of jQuery in Action (Manning Publications), jQuery selectors are one of the most important aspects of the jQuery library. These selectors use familiar CSS syntax to allow page authors to quickly and easily identify any set of page elements to operate upon with the jQuery library methods. Understanding jQuery selectors is the key to using the jQuery library most effectively.

RailsConf Slides

Hey guys,

My talks at RailsConf were a ton of fun. The first night I did talks on Merb and jQuery which were completely packed, and the first day of the conference I did a talk on DataMapper which seemed to be well received as well.

While it was nice to hear that so many people wanted to see the DataMapper talk that some people were turned away, it sucks that some people got turned away. Without further ado, go check out my Merb and DataMapper slides at Slideshare:

I’ll try and get up the jQuery slides shortly as well. Enjoy!

Almost There: 30% Off jQuery in Action!

As you might know, I’m putting the final touches on jQuery in Action, an introductory book on all things jQuery for Manning Publications. I’ve spent the last half a year diligently plugging away at it, along with my co-author Bear Bibeault, and we’re finally hitting the home stretch.

It’s taken a lot of time, and focus, and while it’s been a great experience, I’m also looking forward to being able to once again put my full energy into the various Open Source projects I’m involved in (including jQuery, of course). We’re reviewing typeset PDF’s of what looks to be just about ready to print — there’s light at the end of this tunnel!

The book is set to print in early to mid-January; as a final push before publication, Manning is offering 30% off until December 31st, with the code JQM30. Though the book is also available on Amazon.com, among other places, Manning is the only place you can also get the e-book, which at least for me, is really important.

Thanks to everyone who’s been there for me in this crazy busy time, and for everyone who’s had to grin and bear it while my focus was split. I’m almost done!

JSpec: BDD for JS

A couple of weeks ago I wrote a nice little piece of JS that implemented BDD-style testing in JS. It was originally 70 or so lines of code, and supported code like:

jspec.describe("Some stuff", function() {
  it("should rock", function() {
    7.should("==", 7);
  });
});

It was (and still is) a very simple piece of code, that only dumps the output to the Firebug console. Because should() was a simple method, I was able to delegate out to a pluggable jspec.matchers object, which is where I specified the “match” definition, and allowed the customization of a “failure message.” The original jspec had just two matchers (“==” and “include”), and allowed the creation of new ones by extending the jspec.matchers object (all JS, no magic).

When I tried to actually use it to test real-world code, though, some issues came up. First, functions were being dumped in full into the output, which was sucky. Secondly, the default describe syntax was sucking a bit for certain cases. And finally, I wanted you to be able to plug in any logger you wanted (for say, pretty HTML output). I added those new features, and am now releasing this quick and dirty code for people to look at.

Some examples

(which are included in the downloadable file)

jspec.describe("JSpec", function() {
  it("should support ==", function() {
    (1).should("==", 1);
    var arr = [];
    arr.should("==", arr);
    var obj = new Object;
    obj.should("==", obj);
    document.should("==", document);
  });

  it("should support include", function() {
    [1,2,3,4,5].should("include", 3);
    [1,2,3,4,5].should_not("include", 3);
    document.getElementsByTagName("div").should("include", document.getElementById("hello"))
  });
  
  it("should support exists", function() {
    document.should("exist");
  });
  
  jspec.matchers["have_tag_name"] = {
    describe: function(target, not) {
      return jspec.compress_lines(this) + " should " + (not ? "not " : "") + "have " + target + " as its tag name."
    },
    matches: function(target) {
      return (this.tagName && this.tagName == target) ? true : false;
    },
    failure_message: function(target, not) {
      return "Expected " + this.toString() + (not ? " not " : " ") + "to have " + target + " as its tag name," +
        " but was " + this.tagName;
    }
  };
  
  it("should support custom matchers", function() {
    document.getElementById("wrapper").should("have_tag_name", "DIV");
    document.getElementById("wrapper").should_not("have_tag_name", "SPAN");
    document.getElementById("wrapper").should("have_tag_name", "SPAN");          
  });
});

And the Output

In Firebug

JSpec
  - should support ==
    - 1 should equal 1 (PASS)
    - [] should equal [] (PASS)
    - [object Object] should equal [object Object] (PASS)
    - [object HTMLDocument] should equal [object HTMLDocument] (PASS)
  - should support include
    - 1,2,3,4,5 should include 3 (PASS)
    - 1,2,3,4,5 should not include 3 (FAIL)
      Expected [[1,2,3,4,5]] not to include 3
    - [object HTMLCollection] should include [object HTMLDivElement] (PASS)
  - should support exists
    - [object HTMLDocument] should exist. (PASS)
  - should support custom matchers
    - [object HTMLDivElement] should have DIV as its tag name. (PASS)
    - [object HTMLDivElement] should not have SPAN as its tag name. (PASS)
    - [object HTMLDivElement] should have SPAN as its tag name. (FAIL)
      Expected [object HTMLDivElement] to have SPAN as its tag name, but was DIV

Some caveats

  • Despite some work put in, I can’t figure out how to get jspec to recover gracefully from errors and continue on. This will work in a future release
  • I temporarily override the Object prototype (evil, I know) for the duration of the test. You will still be able to load in libraries that expect Object to work correctly, but you will not be able to test functions (such as prototype’s Object.extend) without accounting for the fact that Object.prototype has been extended.

Happy hunting (Download here)

Update

There is now a git repo for the project at git.caboo.se/jspec.git

Conferences, etc.

As some of you may know, I was at The Ajax Experience conference last week, along with the one-day mini-conference, jQueryCamp.

This was my third The Ajax Experience, and there were a lot of great people to see. Even more exciting though, was jQueryCamp, despite forgetting my t-shirt in Boston.. The accommodations were especially wonderful ;) (that’s code for… I crashed on John‘s couch. Thanks John!)..

I met most of my fellow core team members, which I’d really been looking forward to, along with a slew of jQuery geeks and gurus. Karl, Jörn, Bradley, Marc, Paul, Rey, Richard — just to name a few. I hope to post more about jQuery camp — the talks, etc. — when things get a bit calmer… if ever they do.

(As a side bonus, there were a few Merb folks around — what more could I ask for?!)

There was a pleasantly enthusiastic response to jQuery in Action; lots of people with comments, reading the Early Access version, and lots of people looking forward to it. I’m feeling good about it!

I’ll be at RubyConf in NC this weekend. There are a lot of people I’m looking forward to meeting there, and talks of some Merb hacking.

There’s nothing like putting faces to the IRC folks I talk to every day, the blogs I read, etc. There are also some old friends I’m looking forward to seeing again. Stephen Bristol, ReinH, Evan Phoenix, Jeremy McAnally, Ezra Zygmuntowicz, Dr Nic Williams, and so on. Leah (the wife) will be joining me at RubyConf too, so that’s always a bonus — and I know there are lots of people she’s looking forward to seeing too.

Do drop me a line, or comment, if you’ll be around. Would love to see everyone. Safe travels!

Give JavaScript 2 a Look

Last week, I attended a talk on JavaScript 2 by John Resig. John wrote jQuery, and is now the JS evangelist for Mozilla, which is pushing JS2 along with Adobe and Opera.

Before the talk, I was fairly ambivalent about the new language. In the abstract, it has the ability to inflict pain on us humble JS developers if the upgrade path is too problematic, and there are a whole load of language features that aren’t obviously interesting (again in the abstract).

John’s presentation was, in effect, a Keynote version of the recently released Ecmascript 4 Language Overview Whitepaper, which was released by Adobe, Mozilla, and Opera, three members of the ECMA working group.

The presentation was incredibly code-heavy, and very interesting. As it currently stands, the EcmaScript 4 draft attempts to provide a class structure to EcmaScript 3 (ES3), without breaking backwards-compatibility with ES3, similar to the way C++ added classes to C while preserving back-compatibility.

Since one of the major goals of ES4 is to remain compatible with ES3, existing code will continue to run, and be progressively enhanced by using new features in ES4. The new classical system will exist side-by-side with the old prototypal system, and the new strongly typed system will exist side-by-side with the old weakly typed system.

Here are some examples:

Strict typing in ES3

function(x, y) {
  if(x.constructor != Number) throw TypeError();
  if(y.constructor != String) throw TypeError();
  // code
}

Strict typing in ES4

function(x:Number, y:String) {
  // code
}

The former pattern is extremely common in ES3, so the new feature will simply provide a language-supported way to do what you’re already able to do with functions. That said, the type system has some interesting features:

  • Union types: var x:(int, string)
  • Nullability: var x:int! only accepts an int, which cannot be null
  • *: var x:* is equivalent to the ES3 var x

Remaining variables in functions in ES3

function(x, y) {
  var rest = [].slice.call(arguments, 2);
  // code
}

Remaining variables in functions in ES4

function(x, y, ...rest) {
  // code
}

Again, ES4 simply makes a pattern that is extremely common in existing use simpler and more error-proof. And again, nothing stops your ES3 code from continuing to work.

The classical system

ES4 provides a new classical system, including real Classes, Inheritance, and Interfaces. The classes can be defined as dynamic (similar to ES3 classes, in that properties can be added after the fact), or non-dynamic, which throws an error if a programmer attempts to add a new property. A quick example:

class Foo {
	var bar;
	var baz = 7;
}
var x = new Foo;
x.bat = 12 #=> throws Error

But with a dynamic class:

dynamic class Foo {
	var bar;
	var baz = 7;
}
var x = new Foo;
x.bat = 12 #=> sets x

So you can use dynamic classes to give more structure to existing “classes”, and non-dynamic classes to lock down created classes from further change.

Inheritence

Inheritance in ES3 is done via the prototype chain. You might do something like this:

var Foo = function() { }
var Bar = function() { }
Bar.prototype = new Foo();

In ES4, inheritence is more explicit:

class Foo {}
class Bar extends Foo {}

Non-overridable functions

You can prevent classes from being inherited from, or methods in classes from being overridden using the final keyword, as follows:

final class Foo {}
class Bar extends Foo {} #=> throws Error
class Foo {
	final function bar() { }
}

class Bar extends Foo {
	function bar() { } #=> throws Error
}

Summary

I touched on only a few of the new features in ES4. For the most part, these features could be implemented using ES3 (and there are a number of examples above), but the ES3 counterparts are often verbose and repetitive. I encourage people who are interested in the language to read through the white paper. It’s surprisingly readable for a language spec, and describes a fair bit of motivation.

For people who currently write a fair bit of JavaScript code, I hope you’ll see the new features in ES4 as encapsulations of current, common patterns, and solutions to problems that arise when attempting to develop large systems using JavaScript.

Finally, the current draft is certainly not perfect, but it is a solid core for the next revision of the language. If there’s something you don’t like, feel free to join the ES4 discussion list and raise your concerns. A healthy discussion with more developers will help move the process forward, and away from the back-room politics that is currently miring it.

jQuery in Action (w00t)

Some of you might know that I’m writing a jQuery book for Manning called jQuery in Action. It’s pretty awesome, and includes a bunch of labs and exercises that are unique to it. My coauthor is Bear Bibeault (pronounced Bee-Bo), who coauthored Ajax in Practice (and hilariously enough, Prototype and Scriptaculous in Action).

It’s intended for people who already know some JavaScript, but still have questions about jQuery. It’s thorough, while going beyond the typical API runthrough (there are excellent examples; in later chapters, especially Ajax, the examples run through the entire chapter and show you how to complete a fairly detailed, yet typical project using jQuery).

Anyhow, check it out. If you buy now, you get the early-access chapters, which is the equivalent of the PragProgs’ beta book stuff. We’ve already released betas of chapters 1-8 (of 9), so there’s a lot there.

Event Normalization in jQuery 1.1.3

A loooong time ago, I wrote a bunch of event normalization code as a plugin to jQuery. In essence, the goal was the get events as close as possible to the DOM specification while retaining a sane file-size and backwards compatibility with existing code.

I wanted to add support for:
* relatedTarget, which, on mouse movement, returns the element that the mouse was previously on when moving onto or off of an element
* “which” for key events, which would return a normalized keyCode
* metaKey, which would return the Apple key on OSX, and the ctrl key in Windows (allowing stuff like apple-B to render something bold in OSX, but ctrl-B to do the same in Windows… the expected behavior)
* And a biggie: “which” support for buttons (1 for left-click, 2 for middle-click, and 3 for right-click).

I originally had some more grandiose plans, like supporting offsetX across browsers and getting keyCode to be the same cross-browser on keypresses, but those ended up either requiring unacceptable dependencies or requiring lots of messy code to get working.

Today, jQuery merged relatedTarget, which (for keys and buttons), and metaKey into the core jQuery distribution, and we did it without adding a single byte to the current 20k cap on jQuery’s filesize. We also added a whole slew of new features, without sacrificing our current cap. I say it’s incredible, and thanks to the hard, tireless work of the jQuery Core Team. The speed improvements, which are the work of jQuery’s maintainer, John Resig, also happened, sort of unexpectedly, without busting the 20k.

Amazing.

Back to the event normalization, I think you’ll find that between the old normalization that was present since the early days (event.target and event.pageX/pageY), and this new code, you’ll be able to do all sorts of neat tricks without having to put much thought into browser compatibility issues.

Enjoy!

Call For Papers

Those of you who have been around for a while know that in September of last year I published the first issue of the Visual jQuery Magazine. In October, the magazine was also released in French.

The mag had interviews with important jQuery community members (like creator John Resig, plugin editor Dave Cardwell, etc.), articles on jQuery features and implementations, and even a piece or two on alternate Javascript libraries, complete with quality graphics and original art.

The positive response was incredible, and people really seemed to like it. Unfortunately, though I’d initially planned on making the magazine a monthly publication, things fell to the wayside as my schedule got progressively more hectic. Since Issue 1 I’ve found a new job (new then; about eight or nine months old now), moved across the country (NY to CA), and gotten a huge chunk of the way through writing my first book (stay tuned for details!). Clearly, things have been busy.

The lack of Issue 2 has been bugging me since Issue 1, and I’ve decided it’s time to make it happen (this, I admit, is also largely in part to my good friend Rey Bango’s recently renewed effort to push jQuery forward). Thankfully, the magazine’s lead designer and the team of French developers/translators have all expressed an interest in helping make Issue 2 happen, which makes this goal a lot more tangible.

Issue 1 was an experiment, and it went really well. Since it was a first though, it was very much “the Yehuda show.” I’d like Issue 2 to be more of a collaboration of contributors; there are a lot of jQuery topics to explore, and a lot of team member and users with fascinating tales to tell.

As such, I’m putting the word out there. I’m looking for contributions for Issue 2 of Visual jQuery Magazine. Articles can vary in length extensively, from brief three paragraph shorts, to three page features. They can be tutorials, feature articles, interviews and lots of other things I’m sure you’ll all think of. Just a few brief (and somewhat flexible) guidelines:

  • The article must be in magazine or newspaper format (if, in fact, your submission is a piece of writing — illustrations will also be considered). I’m extremely lax on this, but it should be something you could see being in a magazine.
  • The article must be about a topic that is timely and pertinent to the jQuery community, with broad appeal.
  • The article must not be an advertisement (but it may, obviously, feature a plugin you have written if it has broad appeal).
  • The article must be factually correct.
  • The magazine staff will edit your article for grammar, space, and style. You will receive an edited copy prior to publication for approval.
  • The magazine staff will add graphics and other visual elements as appropriate.
  • Please email a proposal or brief description of your submission before spending a chunk of time working on it; that way we can avoid running out of space and ensure that everything print-worthy gets in. Email submissions and letters to the editor to editor AT visualjquery DOT com.

    As I said from the beginning of this project, I think that the magazine has real potential to open up the jQuery world to new users, and hope that by pushing the envelope of community-produced content, we can keep jQuery moving forward in it’s current positive direction. I, for one, I’m really excited about it.

    jQuery on Rails: A (Still Very Alpha) Update

    I’ve made a number of updates to my preliminary release of jQuery on Rails:

    • It’s now in svn as part of a demo app, so you can see how it all fits together.
    • The new svn URL is http://jqueryjs.googlecode.com/svn/trunk/tools/rails_demo_app for the entire demo, or http://jqueryjs.googlecode.com/svn/trunk/tools/rails_demo_app/vendor/plugins/jquery_on_rails for just the plugin
    • I added a number of new JavaScript files to get copied when you install the plugin.
    • Your jQuery modules now need to be in app/public/javascripts/jquery_modules, which allows the core library files to be separate from your modules

    And the big news…

    I’ve written a few proof of concept helpers for jQuery on Rails that come with modules that are automatically installed in jquery_modules.

    So far, I wrote one for a tabbed interface and one for sortable tables.

    They both take the same settings as the underlying JavaScript libraries. For instance, you can set up the table sorter as follows:

    <% sortable_table :sort_class_asc => “ascending”, :sort_class_desc => “descending”, :striping_row_class => ["even", "odd"], :stripe_rows_on_start_up => true do %>
    <thead>
    <tr>
    <th>Col 1</th>
    <th>Col 2</th>
    </tr>
    </thead>
    <tbody>
    <tr>
    <td>jQuery 1.0</td>
    <td>$100</td>
    </tr>
    <tr>
    <td>jQuery 1.1</td>
    <td>$59</td>
    </tr>
    <tr>
    <td>jQuery 1.1.1</td>
    <td>$68</td>
    </tr>
    <tr>
    <td>jQuery 1.1.2</td>
    <td>$8</td>
    </tr>
    </tbody>
    <% end %>

    This corresponds to:

    tableSorter({sortClassAsc: ‘ascending’, sortClassDesc: ‘descending’, stripingRowClass: ['even', 'odd'], stipeRowOnStartup: true})

    You can check out both the tablesorter helper and the tabs helper in action by checking out the jQuery on Rails demo app.

    Archives

    Categories

    Meta