Managing Asynchronous Assertions

10 Nov 2011 | By Alex Young | Comments | Tags frameworks tutorials lmaf testing

Let’s Make a Framework is an ongoing series about building a JavaScript framework from the ground up.

These articles are tagged with lmaf. The project we’re creating is called Turing. Documentation is available at turingjs.com.

The biggest problem I’ve had when writing tests for Turing is checking when asynchronous callbacks complete. For example, when testing the resource loading feature, I wrote tests with this pattern:

'test queue loading with no local scripts': function() {
  $t.require([
    'https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'
  ]).on('complete', function() {
    assert.ok(true);
    assert.done();
  }).on('loaded', function(item) {
    if (item.src === 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js') {
      assert.ok(jQuery, 'jQuery should be set');
    }
  });
}  

What happens if loaded never fires? Well, the test would still pass. That’s a consequence of the assertion never being run.

One solution is to wrap the assert module with counters that count how many assertions have been called. Then at the start of a test we can write assert.expect(2); to say ‘raise an error if anything other than two assertions are run’.

That’s fine, but at this point Turing’s test framework always runs tests asynchronously. If the assert module kept a counter, other tests would increment that value too. The number of assertions would be the total number for all of the current suite’s tests, rather than the current test.

Counting Assertions

The initial solution I came up with was to wrap every assertion method with a function that incremented a counter. Tests take this pattern:

'test queue loading with no local scripts': function() {
  var assertExpect = mixinExpect(assert);
  assertExpect.expect(2);

  $t.require([
    'https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'
  ]).on('complete', function() {
    assertExpect.ok(true);
    assertExpect.done();
  }).on('loaded', function(item) {
    if (item.src === 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js') {
      assertExpect.ok(jQuery, 'jQuery should be set');
    }
  });
}

Each test gets its own instance of the assert module.

The code to do this is slightly clumsy, because I aliased the old methods using a __ prefix:

function mixinExpect(m) {
  var m2 = {}, method;

  for (method in m) {
    if (m.hasOwnProperty(method)) {
      m2['__' + method] = m[method];
      (function(methodName) {
        m2[methodName] = function() {
          m2.mixinExpectAssertionCount++;
          m2['__' + methodName].apply(m2, arguments);
        };
      }(method));
    }
  }

  m2.expect = function(count) {
    m2.mixinExpectAssertionCount = 0;
    m2.mixinExpectExpected = count;
  };

  m2.done = function() {
    if (m2.mixinExpectAssertionCount !== m2.mixinExpectExpected) {
      throw('Expected assertion count was not found, expected: ' + m2.mixinExpectExpected + ', got: ' + m2.mixinExpectAssertionCount); 
    }
  };

  return m2;
}

It does the job, but is there a more elegant way that doesn’t require changing the assert module?

Expectations

I got this idea when I reviewed Tim Caswell’s Step library:

'test queue loading with no local scripts': function() {
  var expect = new Expect();
  expect.add('jQuery was set');
  expect.add('loaded fired');

  $t.require([
    'https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'
  ]).on('complete', function() {
    assert.ok(true);
    expect.fulfill('loaded fired');
    expect.done();
  }).on('loaded', function(item) {
    if (item.src === 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js') {
      expect.fulfill('jQuery was set');
      assert.ok(jQuery, 'jQuery should be set');
    }
  });
}

Each test creates an instance of Expect and adds a list of expectations. As the expectations are fulfilled, it marks down this fact, then at the end of the test when expect.done() is called it can see if any expectations were unfulfilled.

I made a quick implementation and it’s only a few lines of code:

function Expect() {
  this.expectations = {};
}

Expect.prototype = {
  add: function(expectation) {
    this.expectations[expectation] = false;
  },

  fulfill: function(expectation) {
    this.expectations[expectation] = true;
  },

  done: function() {
    for (var expectation in this.expectations) {
      if (!this.expectations[expectation]) {
        throw('Expected assertion was fulfilled , expected: ' + expectation); 
      }
    }
  }
};

Conclusion

Working with asynchronous tests can quickly get confusing — sometimes tests appear to be passing but aren’t actually running as expected. The CommonJS Unit Testing spec actually says the following:

The assertions defined above will not be to everyone’s taste style wise (or infact behaviour wise.) Authors are free to define their own assertion methods in new modules as desired.

So adding a assert.expect method to your own assertion module implementations is perfectly acceptable.

This week’s code can be found in the ajax tests in commit dc3b41f.

Node Roundup: 0.6, Moment.js, Cupboard

09 Nov 2011 | By Alex Young | Comments | Tags node modules

You can send your node modules and articles in for review through our contact form or @dailyjs.

Node 0.6.0

Node 0.6.0 is out! The benchmarks look promising, the Windows support is now getting pretty serious, so get it installed before the next version comes out!

In order to support Windows we reworked much of the core architecture. There was some fear that our work would degrade performance on UNIX systems but this was not the case. […] We consider this a good intermediate stage for the Windows port. There is still work to be done.

The API changes are actually quite gentle, and have been well-documented in Node API changes between v0.4 and v0.6. Don’t fret, your code will probably run fine.

Moment.js

Moment.js (GitHub: timrwood / moment, License: MIT, npm: moment) by Tim Wood might be the best date library I’ve seen so far. Like any good date wrangling citizen, it manipulates dates without changing the Date prototype, and it works in both Node and browsers. It even has a friendly chainable API:

var moment = require('moment');
moment().add('hours', 1).fromNow();

In fact, it works a little bit like jQuery, behaving differently based on the arguments to moment():

// JavaScript Date object
var day = new Date(2011, 11, 9)
  , dayWrapper = moment(day); 

// Unix time stamp
day = moment(1318781876406);

// String, parsed with Date.parse
day = moment('Dec 31, 1999');

More API options are available, read the full documentation here: Moment.js documentation

Cupboard

Cupboard (npm: cupboard) by Craig Condon is command line tool for managing multiple git/npm projects. Projects are accessible through the cdb command, and commands can be issued against multiple projects.

Cupboard comes with templates to get projects “in the cupboard” as quickly as possible. For example, this will add npm and git functions to a project like “publish”:

cbd init git+npm

There’s a list of templates and command documentation in the project’s README.

jQuery Roundup: 1.7, Doubletake, ThemeRoller for Mobile

08 Nov 2011 | By Alex Young | Comments | Tags jquery plugins mobile

Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

jQuery 1.7 Release

jQuery 1.7 is out. The official blog post has great coverage of this release, with some intriguing statistics on delegated event performance:

To optimize the code for the most commonly used forms of selectors, we examined a cross-section of code from Google Code Search… By parsing those simple selectors in JavaScript at the time the event was attached, we were able to outperform even the browser’s native-code implementations of matchesSelector during event delivery.

Doubletake

Doubletake (License: WTFPL) by Graham Bird changes the src of image elements based on the browser’s width. To control which images are requested, “breakpoints” are used to correctly match the file name:

$('#container').doubletake({
  'breakpoints': [480,960],
  'pattern': '/images/foobar.jpg?width=([0-9]+)'
});

Graham’s example includes the use of Sencha Src to automatically resize images.

ThemeRoller for Mobile

ThemeRoller for Mobile has been released, which is a version of jQuery UI’s ThemeRoller for jQuery Mobile.

It also includes Adobe Kuler support for easily creating a colour palette for your apps.

Although themes can be shared, the links to shared themes are only saved for 30 days to “keep our server from getting stuffed with themes”.

Code Review: Tim Caswell's Step

07 Nov 2011 | By Alex Young | Comments | Tags code-review node events

Code Review is a series on DailyJS where I take a look at an open source project to see how it’s built. Along the way we’ll learn patterns and techniques by JavaScript masters. If you’re looking for tips to write better apps, or just want to see how they’re structured in established projects, then this is the tutorial series for you.

Step (GitHub: creationix / step, License: MIT, npm: step) by Tim Caswell is a flow control library for Node that helps manage parallel and serial execution, as well as assisting with error handling.

Usage

Serial usage works by passing this as the callback argument to asynchronous functions, or by simply returning a value for synchronous code. Tim’s example neatly illustrates this:

Step(
  function readSelf() {
    // `this` will be the next callback
    fs.readFile(__filename, this);
  },
  function capitalize(err, text) {
    // This code is synchronous
    if (err) throw err;
    return text.toUpperCase();
  },
  function showIt(err, newText) {
    if (err) throw err;
    console.log(newText);
  }
);

Just like Node’s libraries, the callback signature is err, arguments.... Step will catch exceptions and pass them as err.

Parallel functions are also supported:

Step(
  // Loads two files in parallel
  function loadStuff() {
    fs.readFile(__filename, this.parallel());
    fs.readFile("/etc/passwd", this.parallel());
  },
  // Show the result when done
  function showStuff(err, code, users) {
    if (err) throw err;
    console.log(code);
    console.log(users);
  }
);

By using this.parallel(), Step will keep track of the number of callbacks so it can call them in the right order.

Structure

Step comes with a detailed README, a package.json file, a single file for the main library, and tests split into files that address each main feature of the library.

The CommonJS module support is conditional, so this library should be usable outside Node:

// Hook into commonJS module systems
if (typeof module !== 'undefined' && "exports" in module) {
  module.exports = Step;
}

The basic structure of the main Step function is easy to follow:

function Step() {
  var steps = Array.prototype.slice.call(arguments),
      pending, counter, results, lock;

  // Define the main callback that's given as `this` to the steps.
  function next() {
    // ...
  }

  // Add a special callback generator `this.parallel()` that groups stuff.
  next.parallel = function () {
    // ...
  };

  // Generates a callback generator for grouped results
  next.group = function () {
    // ...
  };

  // Start the engine an pass nothing to the first step.
  next();
}

The next function is called at the end of Step which starts everything running. This function also gets the parallel and group calls that can be accessed from this in your callbacks.

Execution Management

The core of the library is the next function. Let’s walk through each main part of it.

Counters and return values are used to determine what should run next. The counter is used by parallel and group. These values are set up when next is called:

  // Define the main callback that's given as `this` to the steps.
  function next() {
    counter = pending = 0;

The array of functions passed to Step is executed in order by calling shift on the array. If there are no steps, then any errors are thrown, else execution is complete:

    // Check if there are no steps left
    if (steps.length === 0) {
      // Throw uncaught errors
      if (arguments[0]) {
        throw arguments[0];
      }
      return;
    }

    // Get the next step to execute
    var fn = steps.shift();
    results = [];

Each “step” is called using apply so this in the supplied functions will be next:

    // Run the step in a try..catch block so exceptions don't get out of hand.
    try {
      lock = true;
      var result = fn.apply(next, arguments);
    } catch (e) {
      // Pass any exceptions on through the next callback
      next(e);
    }

Errors are caught and passed to the next step. The lock variable is used by the parallel and grouping functionality. The return value of the passed-in step function is saved. Next the return value will be used to determine if a synchronous return has been used, and if so next is called again with the result:

    if (counter > 0 && pending == 0) {
      // If parallel() was called, and all parallel branches executed
      // syncronously, go on to the next step immediately.
      next.apply(null, results);
    } else if (result !== undefined) {
      // If a syncronous return is used, pass it to the callback
      next(undefined, result);
    }
    lock = false;

Parallel Execution

The parallel method returns a function that wraps around callbacks to maintain counters, and execute the next step. An array of results is used to capture the return values of parallel functions:

next.parallel = function () {
  var index = 1 + counter++;
  pending++;

  return function () {
    pending--;
    // Compress the error from any result to the first argument
    if (arguments[0]) {
      results[0] = arguments[0];
    }
    // Send the other results as arguments
    results[index] = arguments[1];
    if (!lock && pending === 0) {
      // When all parallel branches done, call the callback
      next.apply(null, results);
    }
  };
};

Bonus: Step.fn

I also found the undocumented Step.fn method that creates function factories out of step calls. It’s used like this:

var myfn = Step.fn(
  function (name) {
    fs.readFile(name, 'utf8', this);
  },
  function capitalize(err, text) {
    if (err) throw err;
    return text.toUpperCase();
  }
);

var selfText = fs.readFileSync(__filename, 'utf8');

expect('result');
myfn(__filename, function (err, result) {
  fulfill('result');
  if (err) throw err;
  assert.equal(selfText.toUpperCase(), result, "It should work");
});

This is from Tim’s tests.

Testing

The tests are written using the basic CommonJS assert module, with an expect function defined in test/helper.js.

The expect function is used to define an expectation that must be satisfied by calling fulfill with the expected values. The unit tests set up these expectations at the top level, then satisfy them within potentially asynchronous callbacks.

For example:

expect('one');
expect('two');
Step(
  // Loads two files in parallel
  function loadStuff() {
    fulfill('one');

Conclusion

Step’s actually been around for a while, but Tim has been actively working on it. It’s a small library but solves a common problem found when writing heavily asynchronous Node apps. Over 35 libraries depend on Step according to NPM, which goes to show how popular it is.

Writing Modular JavaScript, Fake Private, Boulderdash, Shopify Fund

04 Nov 2011 | By Alex Young | Comments | Tags amd language games

Writing Modular JavaScript

I’ve mentioned the Asynchronous Module Definition spec on DailyJS before, but for a thorough writeup of this specification take a look at Writing Modular JavaScript With AMD, CommonJS and ES Harmony by Addy Osmani. It includes comparisons with script loaders, how to write modules (with code examples), and related topics like creating classes with getters and setters.

There are risks here such as specifications changing and a potential failure at the cross-browser level (IE9 for example will take a while to die) so your best bets until we have both spec finalization and coverage are AMD (for in-browser modules) and CJS (for those on the server).

The document has been technically reviewed by Andrée Hansson, and includes links to other reference material on ES Harmony and ES.Next.

“No Fake Private”

There’s a huge discussion going on at this gist: minimalist-classes.js, and I was particularly intrigued by some of Brendan Eich’s comments:

If we are doing private, it’ll use private name objects. No fake private. Enumerability has nothing to do with it.

It’s certainly a heated debate, but it’s interesting nonetheless.

JavaScript Boulderdash

Back in the 8-bit era I had a ZX Spectrum, and I seem to remember enjoying Boulder Dash. Jake Gordon is a Commodore 64 fan, and he’s created a simple version of this game that can actually play all of the original levels. In JavaScript Boulderdash, he explains how this Canvas-powered game works, with detailed coverage on the game loop and asset loading.

This is the first of a series of posts which can be followed on Jake’s amazingly cool blog, Code inComplete.

Shopify Fund

The Shopify Fund is a one million dollar fund for building apps on Shopify’s platform:

If you have an idea for an app or utility, tell us about it. We’ll evaluate it, and if we decide to support your project, we’ll provide an advance in the neighborhood of $5,000 – $10,000 on future sales in the App Store.

If you’re itching to go independent with server-side JavaScript apps and are looking for opportunities, it’s worth checking this out.

Asynchronous Resource Loading Part 6

03 Nov 2011 | By Alex Young | Comments | Tags frameworks tutorials lmaf network

Let’s Make a Framework is an ongoing series about building a JavaScript framework from the ground up.

These articles are tagged with lmaf. The project we’re creating is called Turing. Documentation is available at turingjs.com.

Previous parts of Asynchronous Resource Loading:

Handling Remote Scripts

In a world where XMLHttpRequest can load remote scripts, asynchronous script loading would be relatively easy. However, as CDNs are so popular loading third-party scripts is a common occurrence.

This tutorial takes the most basic technique for remote script loading, script insertion, and demonstrates how to combine it with XMLHttpRequest preloading.

Queueing and Preloading

Last week’s tutorial showed how to load remote scripts using an event-based queueing system. This must be modified to work with script insertion. Fortunately, keeping this process event-based gives rise to a simple algorithm:

  1. Preload all local scripts
  2. Once preloading is complete, emit an execute-next event
  3. If the script is preloaded, execute it. Afterwards, emit an execute-next event
  4. If the script is remote, fetch and execute it. Once execution is complete, emit an execute-next event

That gives rise to the following methods:

  • fetchExecute(item, fn): Fetch and execute a remote script, then call the callback
  • execute(item, fn): Execute a preloaded script, then call the callback
  • preloadAll: Preload every script possible. If no scripts are local, then emit execute-next

The callbacks for fetchExecute and execute should emit execute-next. In fact, it should probably just be one callback.

Testing

The tests are similar to the previous tests, but with the addition of a remote script:

'test queue loading with remote in the middle': function() {
  var assertExpect = mixinExpect(assert);
  assertExpect.expect(9);

  $t.require([
    '/load-me.js?test12=12',
    'https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js',
    '/load-me.js?test13=13'
  ]).on('complete', function() {
    assertExpect.ok(true);
    assertExpect.done();
  }).on('loaded', function(item) {
    if (item.src === 'https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js') {
      assertExpect.equal(typeof test13, 'undefined', 'test13 should not be set when remote is loaded');
      assertExpect.ok(window.swfobject, 'swfobject should be set');
    }

    if (item.src === '/load-me.js?test12=12') {
      assertExpect.ok(!window.swfobject, 'swfobject should not be set when test12 is loaded');
      assertExpect.equal(typeof test13, 'undefined', 'test13 should not be set when test12 is loaded');
      assertExpect.equal(test12, 12, 'test12 should be set when test12 is loaded');
    }

    if (item.src === '/load-me.js?test13=13') {
      assertExpect.ok(window.swfobject);
      assertExpect.equal(test13, 13);
      assertExpect.equal(test12, 12);
    }
  });
}

I’ve used the Google CDN for this test, and picked an arbitrary script to load. Execution is tested by checking a global variable that we know the remote script will set.

Implementation

A counter is required to check how many scripts require preloaded, then it gets decrement as each preload completes. I’ve called this this.preloadCount in Queue, and the preload event handler has been changed to emit preload-complete when preloading finishes.

The only edge case is preloadAll must emit something when there are no local scripts.

preloadAll: function() {
  var i, g, group, item, self = this;
  for (g = 0; g < this.groupKeys.length; g++) {
    group = this.groups[this.groupKeys[g]];
    
    for (i = 0; i < group.length; i++ ) {
      item = group[i];

      if (item.preload) {
        this.preloadCount++;
        (function(groupItem) {
          requireWithXMLHttpRequest(groupItem.src, {}, function(script) {
            self.emit('preloaded', groupItem, script);
          })
        }(item));
      }
    }
  }

  if (this.preloadCount === 0) {
    this.emit('execute-next');
  }
}

The preload event handler looks simpler than it did before:

installEventHandlers: function() {
  var self = this;

  this.on('preloaded', function(groupItem, options) {
    var group = self.groups[groupItem.group];
    groupItem.preloaded = true;
    groupItem.scriptOptions = options;
    self.preloadCount--;

    if (self.preloadCount === 0) {
      self.emit('preload-complete');
    }
  });

  this.on('preload-complete', function() {
    this.emit('execute-next');
  });

This neatly encapsulates preloading and executing code, making the distinction easier to follow. The next handler is the key one which manages execution:

this.on('execute-next', function() {
  var groupItem = self.nextItem();

  function completeCallback() {
    groupItem.loaded = true;
    self.emit('loaded', groupItem);
    self.emit('execute-next');
  }

  if (groupItem) {
    if (groupItem.preload) {
      self.execute(groupItem, completeCallback);
    } else {
      self.fetchExecute(groupItem, completeCallback);
    }
  } else {
    self.emit('complete');
  }
});

The key method here is really nextItem which finds an item waiting to be executed, or “fetch executed”:

nextItem: function() {
  var group, i, j, item;

  for (i = 0; i < this.groupKeys.length; i++) {
    group = this.groups[this.groupKeys[i]];
    for (j = 0; j < group.length; j++) {
      item = group[j];
      if (!item.loaded) {
        return item;
      }
    }
  }
}

The execute code is retained from last week, but the group completion handling code has been removed:

fetchExecute: function(item, fn) {
  var self = this;
  requireWithScriptInsertion(item.src, { async: true, defer: true }, function() {
    fn();
  });
},

execute: function(item, fn) {
  if (item && item.scriptOptions) {
    script = createScript(item.scriptOptions);
    insertScript(script);
    appendTo.removeChild(script);
  }

  fn();
}

Both methods call the callback, which was set by the execute-next handler. By using the same callback, completeCallback, we remove the possibility of creating a mistake in the completion behaviour — it would be easy to forget to set groupItem.loaded in one of the callbacks for example.

Conclusion

Although this doesn’t use any preloading techniques for remote scripts, it extends the event-based approach and better encapsulates execution and preloading. I think you’ll agree that creating remote script loaders is not at all trivial, despite support from the HTML specifications.

If you want to read more about the gruesome details of script loading, the comments on ControlJS Part 1 are extremely interesting, because it shows some of the thinking that went into LABjs. It also demonstrates an alternative HTML-oriented approach that removes some of the headaches of doing everything purely in JavaScript.

This code can be found in commit a4642e1.

References

Node Roundup: cheerio, dbmon, HTML Sourcery

02 Nov 2011 | By Alex Young | Comments | Tags node modules html dom templating database

You can send your node modules and articles in for review through our contact form or @dailyjs.

cheerio

cheerio (License: MIT, npm: cheerio) by Matt Mueller is an implementation of the core of jQuery designed specifically for server-side use. The author has removed all of the browser support code, and created a simplified version of the DOM designed for speed:

The goal of JSDOM is to provide an identical DOM environment as what we see in the browser. I never really needed all this, I just wanted a simple, familiar way to do HTML manipulation.
Usage looks just like jQuery for the most part:

$('.apple').attr('id', 'favorite').html()
// <li class = "apple" id = "favorite">Apple</li>

Cheerio also includes a test suite, and Matt has provided instructions on how to run them.

dbmon

dbmon (License: MIT, npm: dbmon) by Francesco Strappini is an interesting library for monitoring changes to databases. Francesco’s example uses postgres and the pg module:

var pg = require('pg')
  , cli = new pg.Client('tcp://postgres@localhost/template1')
  , dbmon = require('dbmon');

cli.connect();

var channel = dbmon.channel({
    driver: 'postgresql'
  , driverOpts: {
      postgresql: {
        cli: cli
      }
    }
  , table: 'testtable'
  , monitor: 'all'
  , keyfld: {
      name: 'id'
    , type: 'integer'
    }
});

There’s also a file system driver based on inotifywait. The documentation includes examples on how to create generic TCP-based transports.

HTML Sourcery

html-sourcery (License: GPL, npm: html-sourcery) by Matt Baker is a library for building HTML:

src = require('html-sourcery');

console.log(src.compile(src.doctype(5), { title: 'HTML SOURCERY', dumbledore: true }, src.html([
  src.head([
    src.meta({ charset: 'utf-8' }),
    src.title(function(params) { return params.title; })
  ]),
  src.body([
    src.h1(function(params) { return params.title; }),
    src.div({ class: 'container' }, [
      src.p('A pure-Javascript library for conjuring up HTML, meant for use with node. Observe:')
// More available in the README

It reminds me of Ruby’s Builder library, and the author addresses the distinction between a templating language and a templating library:

HTML Sourcery isn’t a templating language: it’s a templating library, and that makes all the difference. Source files are just .js files, and you can require away at will.

jQuery Roundup: 1.7 RC2, jQote2, jquery.factory, Native Fullscreen

01 Nov 2011 | By Alex Young | Comments | Tags jquery plugins fullscreen templating

Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

jQuery 1.7 RC2

jQuery 1.7 RC2 is out, with a Halloween-themed announcement:

In RC2, we fixed a tricky problem that sometimes caused Internet Explorer 8 to go full-zombie when jQuery was loaded. Appropriately enough, the crash was related to creating a detached <body> element that we were using to perform feature detection. IE8 seems frightened to a crashy death when it sees a detached body. If you still see any problems with IE8 crashes, please let us know.

It sounds like IE8 is the new IE7 (which was the new IE6)!

jQote2

jQote2 (GitHub: aefxx / jQote2, License: MIT) by aefxx is a template plugin that works a little bit like .tmpl.

The author has written jQote2 API documentation. I picked out the Fibonacci example because it demonstrates some interesting features of this plugin. Given this HTML:

<ul id="fibonacci">
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

<script type="text/x-jqote-template" id="template">
    <![CDATA[
    <%= ( ( this.n == 0 ) ?
            0 : ( this.n == 1 || this.n == 2 ) ?
                1 : parseInt($.jqote(fn, {n: this.n-1})) +
                        parseInt($.jqote(fn, {n: this.n-2})) ) %>
    ]]>
</script>

… and this JavaScript:

$(function() {
  var lambda = $.jqotec('#template');

  $('#fibonacci li').each(function(i) {
    $(this).text($.jqote(lambda, {n: i}));
  });
});

then an unordered list displaying the Fibonacci sequence will be displayed for the number of list elements in the template.

Despite having some advanced features, this plugin performs well when compared to other templating plugins. The benchmarks compare Srender, mustache.js, Underscore, jQote2, Tempest, and nano, with Underscore and jQote2 coming out on top.

jquery.factory

jquery.factory by iwyg is a class constructor library. Objects can be created using the factory function that has the following signature:

var MyClass = $.factory(ParentClass, constructorFunction, prototypeObject);

It comes with documentation and unit tests. It doesn’t yet offer much that goes beyond prototypal inheritance, but the author only published it two days ago so perhaps there’s more to come.

Native Fullscreen

In Native Fullscreen JavaScript API, John Dyer writes about the history and current state of browser full screen support, complete with a demo and jQuery plugin.

The API is still heavily in flux especially since the W3C joined in this week. I spent some time working through the differences to implement FullScreen in MediaElement.js HTML5 video player, and it’s working great in Safari 5.1+, Chrome 15+, or Firefox Nightly.

The resulting code can be used like this:

if (fullScreenApi.supportsFullScreen) {
  myButton.addEventListener('click', function() {
    fullScreenApi.requestFullScreen(someElement);
  }, true);
}

Five Common JavaScript Misunderstandings

31 Oct 2011 | By Alex Young | Comments | Tags language essays

Over the last few years more people have been drawn to JavaScript thanks to libraries like jQuery and innovative server-side projects like Node. However, JavaScript is deceptively easy to learn for existing developers, and there are a few frustratingly awkward pitfalls for newcomers. I’ve quietly been keeping notes on some of these pitfalls, and have selected a few of my favourites in this post.

Too Many Callbacks!

New Node developers like to complain about callbacks. Deeply nested callbacks don’t read particularly well, but this isn’t necessarily JavaScript’s fault. One way to mitigate this is through flow control techniques, and chainable APIs are probably the most popular technique in this area. For example, consider jQuery where the API feels very “flat”:

$('#foo')
  .slideUp(300)
  .delay(800)
  .fadeIn(400);

If you’re knee-deep in callbacks, check to see if the library you’re using has an alternative chainable API. A lot of popular libraries do, like Underscore.js.

Chainable APIs work by returning this from their methods. It can be quite hard to make some APIs work this way, but masking the underlying complexity is often worth it.

There are plenty of flow control libraries available through npm that solve this (and similar) style problems.

Inheritance

Experienced classical object-oriented developers often get frustrated with JavaScript’s prototypes and recreate traditional class and inheritance patterns. I think the lack of OO-related keywords is the main reason for this. However, there’s no need to shy away from prototypes, and prototypal inheritance is surprisingly easy to learn:

var user;

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log('Hello', this.name);
};

// Admin inherits from Person

function Admin(name) {
  this.name = name;
}

Admin.prototype = new Person;

user = new Admin('alex');

// This method was defined on Person
user.greet();

The key line is Admin.prototype = new Person;. I only really understood this when I started to think about prototype chains: Inheritance and the prototype chain.

Scope and Callbacks in Loops

I’ve fallen foul of this a few times over the years. When looping over a set of values, people often mistakenly think an anonymous function will capture the current state of the variables in the loop:

var assert = require('assert')
  , names = ['alex', 'molly', 'yuka']
  , name
  , i;

for (i = 0; i < names.length; i++) {
  name = names[i];

  if (name === 'alex') {
    setTimeout(function() {
      assert.equal(name, 'alex');
    }, 10);
  }
}

The callback will execute in the future, at which point the name will have changed because it hasn’t been bound the way it seems like it should. This will work as expected:

var assert = require('assert')
  , names = ['alex', 'molly', 'yuka'];

names.forEach(function(name) {
  if (name === 'alex') {
    setTimeout(function() {
      assert.equal(name, 'alex');
    }, 10);
  }
});

People often use for instead of an iterator when performance is desired, but in certain cases callback-based iteration might be more readable.

this in Nested Functions

What’s the value of this in a nested function?

var user;

function Person(name) {
  this.name = name;
}

Person.prototype.nested = function() {
  console.log(this);

  (function() {
    console.log(this);
  })();
};

user = new Person('alex');
user.nested();

The first console.log will show { name: 'alex' }, but the second will show the global object (window in client-side code). This is why a lot of code sets var self = this at the start of a method.

Future Reserved Words

The ECMA standards define Future Reserved Words that include commonly used words like class, extends, and super. It’s probably a good idea to avoid using these words; check with the specifications if you’re unsure of a particular word.

References

KickJS, Stage3D vs WebGL Performance, Large Commercial Node App

28 Oct 2011 | By Alex Young | Comments | Tags node webgl frameworks libraries games

KickJS

KickJS (GitHub: mortennobel / KickJS, License: New BSD) by Morten Nobel-Jørgensen is a new WebGL game engine. It looks like the author has only been working on it for about a month, but there’s already a snake game example and an interesting shader editor example.

The KickJS API documentation seems fairly complete, and provides an overview of the main functionality. It looks like games are constructed based on KICK.scene.Component objects, and events based on these components. There’s also WebGL abstraction which reminds me a little bit of three.js — there’s a camera class, and classes for lots of other things like textures, materials, lighting, and meshes.

Stage3D vs WebGL Performance

In Stage3D vs WebGL Performance, Felix Turner compares Flash 11’s Stage3D API with WebGL. Two demos of equivalent code are compared, and both can run so you can see how they perform on your own hardware. It’s interesting to see how the code compares, because Felix has used three.js and the API doesn’t seem too different to Stage3D.

The post has a good discussion as well, with contributions from three.js’s author.

Large Commercial Node App

Sam Fresco who works at an agency called Clock sent me some interesting PR about a project built with Node called Eat Out that his company has developed for The Times and Sunday Times. I searched high and low to actually try this project, but when I found Sam’s blog post I realised it’s only accessible to Times subscribers until 2012, when it should be released to a wider audience. More details are available in his blog post: There’s Never Been A Better Time To Eat Out.

Clock’s technical blog also has posts on working with Node, including one on deploying Node apps.

Why do I bring this up? Well, it’s always interesting to hear about large commercial projects that use Node, and also because it helps answer the dreaded boss/client question: “what popular sites use Node, anyway?”

Asynchronous Resource Loading Part 5

27 Oct 2011 | By Alex Young | Comments | Tags frameworks tutorials lmaf network

Let’s Make a Framework is an ongoing series about building a JavaScript framework from the ground up.

These articles are tagged with lmaf. The project we’re creating is called Turing. Documentation is available at turingjs.com.

Previous parts:

Creating a Preloading API

Last week I fleshed out turing.request so it can handle preloading with XMLHttpRequest. It’s time to look at how to build an API that will allow scripts to load based on the required order.

I thought a lot about this and decided that an array is a good way to model dependencies between scripts. Given this array:

[
  'framework.js',
  ['plugin.js', 'plugin2.js'],
  'app.js']
]

then the following actions should occur:

  • framework.js is downloaded and executed
  • plugin.js and plugin2.js are downloaded asynchronously, but only executed when framework.js is ready
  • Finally, app.js is executed

These scripts can be loaded at any time, as long as they’re executed in the specified order. If the scripts are local, they can be preloaded with XMLHttpRequest.

Preloading Test

To break this down into something implementable, I created a test first:

'test async queue loading': function() {
  $t.require([
    '/load-me.js?test9=9',
    ['/load-me.js?test4=4', '/load-me.js?test5=5'],
    ['/load-me.js?test6=6', '/load-me.js?test7=7'],
    '/load-me.js?test8=8'
  ]).on('complete', function() {
    assert.ok(true);
  }).on('loaded', function(item) {
    if (item.src === '/load-me.js?test9=9') {
      assert.equal(typeof test4, 'undefined');
    }

    if (item.src === '/load-me.js?test4=4') {
      assert.equal(test9, 9);
      assert.equal(test4, 4);
      assert.equal(typeof test6, 'undefined');
      assert.equal(typeof test8, 'undefined');
    }

    if (item.src === '/load-me.js?test6=6') {
      assert.equal(test9, 9);
      assert.equal(test4, 4);
      assert.equal(test6, 6);
      assert.equal(typeof test8, 'undefined');
    }
  });

I originally wrote this with a callback like the old require signature implied, but I realised that different types of callbacks are required, so it felt natural to use something based on events.

Using this event-based approach should make it easier to build internally, but also makes a pretty rich API.

Modifying require

To work with this new signature (and event-based API), last week’s require implementation will have to be updated. Recall that a setTimeout method was used to delay loading until the head part of the document is ready. That makes returning a value — and thus chaining off require — impossible.

To get around this, I extracted the setTimeout part and made it into a method:

function runWhenReady(fn) {
  setTimeout(function() {
    if ('item' in appendTo) {
      if (!appendTo[0]) {
        return setTimeout(arguments.callee, 25);
      }

      appendTo = appendTo[0];
    }

    fn();
  });
}

When an array is passed to require we can safely assume queuing is necessary. The old method signature is still available. In the case when an array has been passed, a Queue object can be returned to enable chaining:

turing.require = function(scriptSrc, options, fn) {
  options = options || {};
  fn = fn || function() {};

  if (turing.isArray(scriptSrc)) {
    return new Queue(scriptSrc);
  }

  runWhenReady(function() {
    // Last week's code follows

The Queue Class

The Queue class is based on turing.events.Emitter which is a simple event management class, created in Let’s Make a Framework: Custom Events. The basic algorithm works like this:

  1. Queue.prototype.parseQueue: Iterate over each item in the array to work out which scripts require preloading, and group them together based on the array groupings. Single script items will be added to a group that contains one item, so the array of arrays becomes normalised into something easy to manage.
  2. Queue.prototype.enqueue: Whenever parseQueue finds a script, call enqueue to add it to a sequentially indexed object.
  3. runQueue: Iterate over each group and preload each local script using XMLHttpRequest. Add an event emitter to the XMLHttpRequest callback to signal a preload event has completed.
  4. preload event: When this event is fired, mark the group item as ‘preloaded’ and start executing scripts if the whole group has finished preloading.
  5. complete event: This event is fired when all items have executed.

I’ll explain these methods and events below.

Initialization Queue and Maintaining the Chain

To allow the on methods to be called after turing.require, Queue has to use runWhenReady itself, and proxy calls to turing.events.Emitter and return this:

function Queue(sources) {
  this.sources = sources;
  this.events = new turing.events.Emitter();
  this.queue = [];
  this.currentGroup = 0;
  this.groups = {};
  this.groupKeys = [];
  this.parseQueue(this.sources, false, 0);

  this.installEventHandlers();
  this.pointer = 0;

  var self = this;
  runWhenReady(function() {
    self.runQueue();
  });
}

Queue.prototype = {
  on: function() {
    this.events.on.apply(this.events, arguments);
    return this;
  },

  emit: function() {
    this.events.emit.apply(this.events, arguments);
    return this;
  },

  // ...

Parsing the Queue

The array of script sources must be parsed into something that’s easy to execute sequentially. The enqueue method helps sort items into groups, and flags if they’re suitable for preloading:

enqueue: function(source, async) {
  var preload = isSameOrigin(source),
      options;

  options = {
    src: source,
    preload: preload,
    async: async,
    group: this.currentGroup
  };

  if (!this.groups[this.currentGroup]) {
    this.groups[this.currentGroup] = [];
    this.groupKeys.push(this.currentGroup);
  }

  this.groups[this.currentGroup].push(options);
},

The actual job of queuing is fairly simple, but care must be taken to increment the currentGroup counter as groups are added:

parseQueue: function(sources, async, level) {
  var i, source;
  for (i = 0; i < sources.length; i++) {
    source = sources[i];
    if (turing.isArray(source)) {
      this.currentGroup++;
      this.parseQueue(source, true, level + 1);
    } else {
      if (level === 0) {
        this.currentGroup++;
      }
      this.enqueue(source, async);
    }
  }
},

The reason the level variable is used is to differentiate between grouped items and single scripts.

Running the Queue

Each script item is iterated over in sequence, and XMLHttpRequest is used to preload scripts:

runQueue: function() {
  var i, g, group, item, self = this;

  for (g = 0; g < this.groupKeys.length; g++) {
    group = this.groups[this.groupKeys[g]];
    
    for (i = 0; i < group.length; i++ ) {
      item = group[i];

      if (item.preload) {
        (function(groupItem) {
          requireWithXMLHttpRequest(groupItem.src, {}, function(script) {
            self.emit('preloaded', groupItem, script);
          })
        }(item));
      }
    }
  }
}

The anonymous function wrapper helps keep the right item around (because I’ve used for loops instead of a callback-based iterator).

As each request comes back and preloaded is fired, the event handler will check to see if the entire group has been loaded, and if so, execute each item.

Conclusion

When I had the idea to use events to manage script loading, I thought I was onto something and the code would be very simple. However, the Queue class I wrote for this tutorial ended up becoming quite complex, and it only handles local scripts at this stage.

I’ll attempt to add support for remote preloading as well (where available), and also add support for script tag insertion as a last resort.

This week’s code is in commit 74a0f7f. If you’ve got any feedback, post a comment (or fork) and I’ll see if I can incorporate it.

Node Roundup: 0.5.10 and 0.6, MCMS, EventStream, RSS Tutorial

26 Oct 2011 | By Alex Young | Comments | Tags node modules events cms

You can send your node modules and articles in for review through our contact form or @dailyjs.

0.5.10 and 0.6

Node 0.5.10 has been released. This version changes the build system, adds performance improvements, and it looks like there’s been a lot of documentation improvements.

Node 0.6 was also formally announced on the official Node blog:

The API changes between v0.4.12 and v0.5.10 are 99% cosmetic, minor, and easy to fix. Most people are able to migrate their code in 10 minutes. Don’t fear.

Sounds good to me!

MCMS

MCMS (npm: mcms, License: MIT) by Oleg Podsechin is a content management system built with Common Node. Actually, Common Node is just part of the story:

By being built on top of the CommonJS Filesystem/A and JSGI 0.3 specs, it runs on multiple server side JavaScript platforms, such as Node.js (via Common Node) and RingoJS.

Oleg has provided installation instructions for both Node and RingoJS.

MCMS is more like a static site generator than a traditional CMS, and serves as an interesting example of how to build something using Common Node while still being able to deploy to other CommonJS-compatible environments.

EventStream

Streams are like Arrays, but laid out in time, rather than in memory.

EventStream (npm: event-stream) by Dominic Tarr is a library for manipulating “through streams”, which is the author’s terms for streams that are both readable and writable:

// pretty.js

if (!module.parent) {
  var es = require('event-stream');

  es.connect(                          // connect streams together with `pipe`
    process.openStdin(),               // open stdin
    es.split(),                        // split stream to break on newlines
    es.map(function(data, callback) { // turn this async function into a stream
      callback(null
        , inspect(JSON.parse(data)))   // render it nicely
    }),
    process.stdout                     // pipe it to stdout!
  );
}

// On the terminal:
// curl -sS registry.npmjs.org/event-stream | node pretty.js

The library provides many interesting ways to enhance native objects and functions with streams. The author has even created a list of compatible Node modules, which includes popular modules like sax-js and request.

RSS with NodeJS and Socket.IO

French-speaking readers may appreciate RSS with NodeJS Socket.IO and Express which is a full tutorial on how to build an RSS reader with Express and Socket.IO. I had a go at reading it with Google Translate, and I was able to follow it (for the most part).

jQuery Roundup: 1.7 RC1, $.Callbacks, jquery.rss, sessionTimeout

25 Oct 2011 | By Alex Young | Comments | Tags jquery plugins rss events

Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

jQuery 1.7 RC1

jQuery 1.7 RC1 has been released. Meanwhile, the jQuery Standards Team has been created, which aims to represent jQuery users to standards bodies such as the W3C and TC39.

The jQuery Standards Team is driven by jQuery team members Yehuda Katz and Paul Irish who some of you may know. Yeuhda and Paul have extenstively worked with standards bodies and browser vendors in a number of capacities over the years.

Demystifying jQuery 1.7’s $.Callbacks

In Demystifying jQuery 1.7’s $.Callbacks, Addy Osmani explains the origins of $.Callbacks and provides detailed examples on how to use it.

The general idea behind pub/sub (the Observer pattern) is the promotion of loose coupling in applications. Rather than single objects calling on the methods of other objects, an object instead subscribes to a specific task or activity of another object and is notified when it occurs.

Looking at the source in in jQuery 1.7 is interesting because $.Callbacks is now used in several places. For example, the new deferred.js is built with it, and ajax.js is as well.

I was trying to compare Node’s EventEmitter with $.Callbacks and discovered Comparison Between Different Observer Pattern Implementations by Miller Medeiros, which is an interesting post on this subject.

jquery.rss

jquery.rss (License: MIT) by Sascha Depold and DaWanda GmbH is an RSS reading and transformation library. It uses the Google Feed API to download feeds straight from the browser. It comes complete with support for simple templates and filtering:

$("#rss-feeds").rss("http://feeds.feedburner.com/premiumpixels", {
  // how many entries do you want? default: 4
  limit: 10,

  // will request the API via https; default: false
  ssl: true,

  // template for the html transformation
  // default: "<ul>{entry}<li><a href='{url}'>[{author}@{date}] {title}</a><br/>{shortBodyPlain}</li>{/entry}</ul>"
  template: "<div class='feed-container'>{entry}<p>{title}</p>{/entry}</div>",

  // additional token definition for in-template-usage
  // default: {}
  tokens: {
    foo: 'bar',
    bar: function(entry, tokens) { return entry.title }
  }
});

sessionTimeout

sessionTimeout (Source: jquery.sessionTimeout.1.0.js) is a simple plugin for handling session timeouts in the browser. It will poll a URL, and show a jQuery UI dialog when the time limit has been reached.

$.sessionTimeout({
  message :     'Your session is about to expire.'
, keepAliveUrl: '/sessions/alive'
, redirUrl:     '/sessions/timed-out'
, logoutUrl:    '/sessions/destroy'
, warnAfter:    900000
, redirAfter:   1200000
})

Backbone.js Screencasts, XDate, JavaScript BigInteger Library

24 Oct 2011 | By Alex Young | Comments | Tags libraries time date screencasts backbone.js maths

Backbone.js Screencasts

Backbone.js Screencasts is a commercial set of Backbone.js tutorials from 30 Cubits that costs $9 (until November 9th, then $18 thereafter) for 106 minutes of videos. The videos cover the core Backbone.js functionality like views, routers, events, models, collections, and also how to use other JavaScript techniques alongside your Backbone.js code.

There’s a preview of the content on Vimeo here: Backbone.js Quickly – Preview.

XDate

XDate (GitHub: arshaw / xdate, License: dual MIT and GPL) by Adam Shaw is a wrapper around Date that provides improved date parsing, formatting, and manipulation. XDate format strings really help with formatting dates, which I find myself doing a lot lately in Node or single page applications.

Here’s an example of XDate’s formatting method:

new XDate(2011, 0, 1, 6, 0).toString('d/M/yy h(:mm)TT');

Another useful feature of this library is the set of XDate diffing methods. They provide a friendly API around date subtraction.

Most of XDate’s methods return an XDate, so it’s chainable too:

d1 = new XDate();
d2 = d1.clone()
       .setUTCMode(true)
       .setDate(1)
       .addMonths(1)
       .addYears(2);

JavaScript BigInteger Library

The JavaScript BigInteger Library (GitHub: silentmatt / javascript-biginteger, License: MIT) by Matthew Crumley is a BigInteger library for JavaScript. The author has written detailed blog posts on how the library works and the algorithms behind it:

If you look at the source, you’ll probably notice that I’m actually using base 10000000, not base 10. I’m using decimal in these examples because it makes things clearer but everything works pretty much exactly the same way in any base. Using a larger base just makes things more efficient because you get 7 digits in each array entry.

Matthew created this library to support his Google Chrome Scientific Calculator.

WebGL X-Wing, JS Test Runner, Lists.js

21 Oct 2011 | By Alex Young | Comments | Tags webgl html testing

WebGL X-Wing

It’s not impossible! I used to bullseye womp rats in my T-16 back home, they’re not much bigger than two meters.

WebGL X-Wing is a simple game demo where an X-wing is piloted through the Death Star trench run. It’s created by @oosmoxiecode, and the author has a whole load of other WebGL demos here: OutsideOfSociety WebGL demos.

JS Test Runner

JS Test Runner (License: Apache License 2.0) by Christopher Hunt runs tests in a browser simulator (PhantomJS), and works well with JUnit so it’s easy to integrate with Maven’s Surefire plugin. The author notes that the project doesn’t depend on Maven, but should work well with anything that can run JUnit tests.

If you’re used to working with Eclipse then JS Test Runner should fit into your workflow very well.

Sample usage of JS Test Runner looks like this:

import org.codehaus.jstestrunner.junit.JSTestSuiteRunner;
import org.junit.runner.RunWith;

/**
 * Run all JS tests associated with this project.
 */
@RunWith(JSTestSuiteRunner.class)
public class SuiteUT {
}

Lists.js

Lists.js (GitHub: javve / list, License: MIT) by Jonny Strömberg is a small library for adding extra filtering options to HTML lists. It’s native JavaScript rather than framework-dependent, so the API is a simple class:

new List('list', { valueNames: [ 'name', 'city' ] });

There are some interesting Lists.js examples which include references to LucasArts games — proof, if any is needed, that the author is a man of impeccable taste.

Asynchronous Resource Loading Part 4

20 Oct 2011 | By Alex Young | Comments | Tags frameworks tutorials lmaf network

Let’s Make a Framework is an ongoing series about building a JavaScript framework from the ground up.

These articles are tagged with lmaf. The project we’re creating is called Turing. Documentation is available at turingjs.com.

Previous parts:

Loading with XMLHttpRequest

In last week’s tutorial I hinted at a technique script loading libraries use to preload local scripts using XMLHttpRequest. By requesting scripts this way, the contents can be placed into a queue then executed through a script element’s .text property when required. This allows libraries like LABjs to schedule execution based on the user’s requirements.

Now we’re starting to go beyond script insertion and into the realms of preloading and scheduling. With that in mind, I’ve redesigned the code for this module to be easier to test.

Designing for Testability

Production-ready script loaders will dynamically decide on the best strategy for preloading a given script. That makes them easy to use, but potentially makes them hard to test. I want to write tests like this:

$t.require('/load-me.js?test0=0', { transport: 'scriptInsertion' }, function() {
  assert.equal(window.test0, 0);
});

$t.require('/load-me.js?test3=3', { transport: 'XMLHttpRequest' }, function() {
  assert.equal(window.test3, 3);
});

Given a server-side test harness — which I’ve already written in test/functional/ajax.js — we should be able to specify which method is used to load a script, and get the expected results.

The transport option in the previous example allows us to control which loading strategy is used. The scriptInsertion transport is what we created in the previous tutorials. The new one is XMLHttpRequest, which gives us more potential for preloading and scheduling scripts.

Implementation

To build this, I’ve broken the problem up into several functions:

  • isSameOrigin determines if a given src is local or remote, so we don’t get same origin errors in the browser
  • createScript creates a new script tag and applies an Object of options
  • insertScript inserts the script tag into the document
  • requireWithScriptInsertion loads scripts using insertion
  • requireWithXMLHttpRequest loads scripts using XMLHttpRequest

A lot of this code was originally in require, but when I realised I was doing the same thing in the XMLHttpRequest loader I decided to break it up.

This method loads the script using our built-in XMLHttpRequest support:

  /**
   * Loads scripts using XMLHttpRequest.
   *
   * @param {String} The script path
   * @param {Object} A configuration object
   * @param {Function} A callback
   */
  function requireWithXMLHttpRequest(scriptSrc, options, fn) {
    if (!isSameOrigin(scriptSrc)) {
      throw('Scripts loaded with XMLHttpRequest must be from the same origin');
    }

    if (!turing.get) {
      throw('Loading scripts with XMLHttpRequest requires turing.net to be loaded');
    }

    turing
      .get(scriptSrc)
      .end(function(res) {
        // Here's where the magic happens.  This callback is what will get scheduled in future versions.
        options.text = res.responseText;
        
        var script = createScript(options);
        insertScript(script);
        appendTo.removeChild(script);
        fn();
      });
  }

Which means the public method, require, now has to decide which transport to use:

/**
 * Non-blocking script loading.
 *
 * @param {String} The script path
 * @param {Object} A configuration object.  Options: {Boolean} `defer`, {Boolean} `async`
 * @param {Function} A callback
 */
turing.require = function(scriptSrc, options, fn) {
  options = options || {};
  fn = fn || function() {};

  setTimeout(function() {
    if ('item' in appendTo) {
      if (!appendTo[0]) {
        return setTimeout(arguments.callee, 25);
      }

      appendTo = appendTo[0];
    }

    switch (options.transport) {
      case 'XMLHttpRequest':
        return requireWithXMLHttpRequest(scriptSrc, options, fn);

      case 'scriptInsertion':
        return requireWithScriptInsertion(scriptSrc, options, fn);

      default:
        return requireWithScriptInsertion(scriptSrc, options, fn);
    }
  });
};

Conclusion

I’ve tested this in IE 6, 7, Firefox, Chrome, and Safari. A future version of this module will have to decide which loading method to use by default, depending on the scheduling requirements (which we have yet to start work on).

There are actually more script loading techniques to look at before I can get to scheduling. As I’ve said before, if you’re interested in this area take a look at RequireJS and LABjs to jump ahead.

This week’s code can be found in commit 649f882.

Node Roundup: hotcode, fbgraph, browser

19 Oct 2011 | By Alex Young | Comments | Tags node modules scraping facebook social

You can send your node modules and articles in for review through our contact form or @dailyjs.

hotcode

hotcode (License: MIT, npm: hotcode) by Mathias Pettersson is a small Express app that watches for changes on a given path, then reloads an associated app when files change.

To use it, follow the instructions in the project’s README file. When hotcode is run it’ll print out a link to some JavaScript (it should be http://127.0.0.1:8080/static/injected.js) — this will need to be added to your project to get automatic reloading in the browser.

Projects can be configured in ~/.hotcode so the path doesn’t need to be entered each time hotcode is started. This can be set per-domain as well.

One of the interesting things about hotcode is it can be run against practically any app in any language. If you’re sick of having to restart your app and refresh the browser every time you make a change, then you’re going to love this.

fbgraph

fbgraph (GitHub: criso / fbgraph, License: MIT, npm: fbgraph) by Cristiano Oliveira provides consistent access to the Facebook graph API. According to the author:

All calls will return json. Facebook sometimes decides to just return a string or true or redirects directly to an image.

Given suitable configuration options, people can be authorised using getOauthUrl:

var graph = require('fbgraph')
  , authUrl = graph.getOauthUrl({
      'client_id':    conf.client_id
    , 'redirect_uri': conf.redirect_uri
  });

Once the Facebook dialog has been displayed, graph.authorize is called to complete the process and get the access token.

API calls are made with graph.get or graph.post, so most of the API is oriented around HTTP methods:

graph.get('zuck', function(err, res) {
  console.log(res); // { id: '4', name: 'Mark Zuckerberg'... }
});

graph.post(userId + '/feed', wallPost, function(err, res) {
  // returns the post id
  console.log(res); // { id: xxxxx}
});

This is a clean, well-documented, and well-tested Facebook library, which is surprisingly refreshing.

browser

browser (License: MIT, npm: browser) by Shin Suzuki is an event-based library for browsing and scraping URLs, whilst maintaining cookies. Requests are built up using the library’s object, and then triggered with .run():

var $b = require('browser');
$b.browse('https://example.com/');
$b.run();

Building up a sequence of events is possible with the after method:

var $b = require('browser');

$b.browse('https://example.com/sign-in');

$b.browse('https://example.com/account')
  .after(); // browse after previously registered function

$b.run();

Event callbacks can also be registered:

$b.on('end', function(err, res) {
});

Now load up jsdom and you’ll be able to scrape faster than you can say “deep-linking lawsuit”!

jQuery Roundup: 1.7 Beta 2, Counter, Templator

18 Oct 2011 | By Alex Young | Comments | Tags jquery plugins templates

Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

jQuery 1.7 Beta 2

jQuery 1.7 Beta 2 is out. It’s worth skimming over the whole change log in the announcement to check for things that may affect your scripts. This release includes a lot of IE fixes and improvements, for example:

  • #6485 — Solution for HTML5 issues in IE
  • #10267 — IE8 and window is(':visible') crashes
  • #10429 — IE7 – invalid procedure call or argument when calling .removeAttr('contenteditable');
  • #9033 — (Deferred) try { } finally { } error in IE8
  • #6170jQuery(window).scroll(); causes IE* to scroll to 0,0
  • #6319 — Regression: stopPropagation inside change handlers in IE is incorrectly applied to keydown event
  • #6593 — IE8: DOM 0 event handler called twice when a separate handler is attached via jQuery
  • #6667 — submit event doesn’t delegate in IE* under certain conditions
  • #6942jQuery.event.fix causes unnecessary reflows in IE when handling key events
  • #7161 — Submit event on a form element not unbound properly in IE
  • #7444 — Submitting form with “Enter” instead of button click on IE8 or IE7 triggers live submit event twice
  • #8157 — Focusing an already focused text field will prevent the change event from firing in IE
  • #8866 — IE8 input[type=file] delegated change event files only on blur
  • #9593 — Delegated submit event is not instanceof jQuery.Event in IE
  • #9570 — Selector $('form[name=".."]') returns zero elements in IE8 under some conditions

There are 68 fixes and improvements altogether; 15 are for IE support.

jQuery Word and Character Counter

Counter (License: MIT) by Wilkins Fernandez is a word and character counting plugin that works a little bit like Twitter. $(selector).counter(); will add a character counter to a textarea. It supports lots of options — it’s possible to enforce the word or character limit by preventing more text from being entered, or to simply count forever:

// This will simply print the character count forever
$(selector).counter({
  goal: 'sky'
});

$(selector).counter({
  type: 'word'
, goal: 'sky'
});

The thing I’ve always found challenging about word counting algorithms is supporting other languages. A naive word count implementation is likely to get Japanese and Chinese word counts wrong. It would be interesting to see this supported here (or your favourite JavaScript algorithm for doing this in the comments).

Templator

Templator (License: AOL) by Nijiko Yonskai is a template manager, and currently supports a wide range of template languages. It depends on jQuery, and includes support for mustache.js, jSmart, TrimPath Template, YAJET, and more (look at Template/lib/ to see what template languages are supported).

It also comes with a caching system:

var Template = new Templator({
    language: 'jSmart', // Supported Languages: jSmart, EJS, Moustache, Trimpath, YAJET, JST, or Empty
    cache: {
        enabled: false,
        life: 32000,
        tick: 1000
    }
});

And has a chainable API:

var Template = new Templator({ language: 'yajet' })
   .storeElement('tmpl', '.tmpl', { foo: 'Hello', bar: 'World!' })
   .partialElement({ partial: '.partial' }, {}, 'tmpl')
   .on('.this')
   .render('tmpl');

It can also be used in a rudimentary fashion without a template language:

var Template = new Templator({ language: '' });
Template.renderRaw('Hello {name}!', { name: 'World' });

Code Review: Oliver Caldwell's EventEmitter

17 Oct 2011 | By Alex Young | Comments | Tags code-review node events

Code Review is a series on DailyJS where I take a look at an open source project to see how it’s built. Along the way we’ll learn patterns and techniques by JavaScript masters. If you’re looking for tips to write better apps, or just want to see how they’re structured in established projects, then this is the tutorial series for you.

After a previous Code Review of EventEmitter2 by hij1nx in Code Review: EventEmitter2, Oliver Caldwell asked me to take a look at his EventEmitter (GitHub: Wolfy87 / EventEmitter, License: MIT and GPL).

This library places special focus on browser support, supporting all major browsers and even IE 5+. A minimised version is also supplied to further support client-side developers.

Usage

This EventEmitter implementation is used the same way as Node’s:

// Initialise the EventEmitter
var ee = new EventEmitter();

function myListener() {
}

// Add the listener
ee.addListener('event', myListener);

// Emit the event
ee.emit('event');

// Remove the listener
ee.removeListener('event', myListener);

Structure

As with most browser-based libraries, I expected to see a self-executing anonymous function. However, in this implementation the author has opted to wrap everything in a regular function, declaring methods inside the function’s scope:

function EventEmitter() {
  var listeners = {},
      instance = this;

  instance.Event = function(type, listener, scope, once) {
  };

  instance.eachListener = function(type, callback) {
  };

  // Etc.
}

The Event class is used to encapsulate an event, and instantiated Event objects are pushed onto arrays indexed by type on listeners.

This style of encapsulation reminds me of how TJ Holowaychuk likes to model his runtime objects (the Request and Response classes in Express for example). Also, it demonstrates high-level object oriented principles without resorting to creating classical-OO-style classes in JavaScript.

Implementation

Like the other EventEmitter libraries, listeners are stored in an Object. The newListener event has been retained, which I thought shows good attention to detail. Most of the core methods are extremely short, which I like to see. For example, emit is implemented like this:

instance.emit = function(type, args) {
  instance.eachListener(type, function(currentListener) {
    return currentListener.fire(args);
  });

  // Return the instance to allow chaining
  return instance;
};

Extracting eachListener seems like a good idea. Rather than having a lot of loops throughout the code, eachListener gets reused by removeListener and emit, making these methods more readable.

The code is also clearly commented, and the build process is included as part of the Makefile.

Performance

The last time I looked at serious JavaScript loop benchmarks, optimised for loops performed extremely well, which I suspect is why EventEmitter and EventEmitter2 don’t use the callback-based iterators Oliver has used. He hasn’t included benchmarks so I can’t easily say how well this implementation performs, but I did find this code easier to follow than the other EventEmitters that I’ve looked at.

Tests

Oliver has included QUnit tests, which do the job admirably:

test('Emitting events', function() {
  var ee = new EventEmitter();

  ee.addListener('emittingTest', function() {
    // Listener
    ok(true, 'First called');
  });

  ee.addListener('emittingTest', function() {
    // Another listener for the same event
    ok(true, 'Second called');
  });

  ee.addListener('differentEvent', function() {
    // Another listener for the same event
    ok(false, 'Wrong event called');
  });

  ee.emit('emittingTest');
});

I think these tests could benefit from being able to assert on how many assertions are expected before the test completes, like assert.expect in nodeunit.

Conclusion

Yet another EventEmitter implementation, but this one still manages to differentiate itself from the others I’ve looked at. I liked the way the author has explored readability rather than purely performance; it offers a hackable alternative that might suit certain projects. And the code uses OO concepts without feeling too heavy handed.

Check it out yourselves on GitHub: Wolfy87 / EventEmitter

Milkshake, An Introduction to WebGL, MapsGL

14 Oct 2011 | By Alex Young | Comments | Tags webgl animation google opera

Milkshake

Milkshake (GitHub: gattis / milkshake, License: LGPL) by Matt Gattis is a WebGL audio visualiser that uses SoundCloud’s API to play audio. It’ll play lots of tracks and cycle through tonnes of visualisations based on MilkDrop.

I particularly like the way the visualiser presets are JSON files, and how everything is client-side — this thing can be uploaded to GitHub Pages or Dropbox and shared easily.

The choice of tracks really made me want to get some Girl Talk out (Feed the Animals is a great way to start the weekend!)

An Introduction to WebGL

In An Introduction to WebGL, Luz Caballero explains the basics behind WebGL, including: browser support, the rendering pipeline, WebGL libraries, and example code using PhiloGL.

MapsGL

MapsGL from Google is a new way to view Google Maps using WebGL. To use it, load up Google Maps in the latest Chrome or Firefox 8+ and look for the “What to try something new?” button on the bottom left-hand-side:

MapsGL uses new technology called WebGL (Web-based Graphics Library) to enhance the Google Maps experience. WebGL brings 3D graphics to your browser without the need to install additional software. This allows us to provide seamless transitions between various levels of imagery and different map views.

I really like the 45 degree view mode, but I could only get it working around Rome for some reason. It’s also slightly weird that when MapsGL is enabled the Google Earth option still requires a plugin. However, it does feel extremely slick, particularly zooming right in which automatically transitions to street view mode.