Node Roundup: BinaryJS, Advice, Buildify, MaDGe

01 Aug 2012 | By Alex Young | Comments | Tags node modules graphics binary websockets
You can send in your Node projects for review through our contact form or @dailyjs.

BinaryJS

BinaryJS (GitHub: binaryjs / binaryjs, License: MIT, npm: binaryjs) by Eric Zhang uses WebSocket to stream binary data. The streams can be bidirectional, and is binary end-to-end. This basically gives browsers something closer to TCP sockets, and allows multimedia data to be streamed.

The client-side portion works with Chrome, Firefox, Internet Explorer 10, and Safari’s nightly builds. The authors are working on supporting older browsers (presumably through Flash).

BinaryJS employs BinaryPack a modified version of the MessagePack protocol. The Node.js server uses a modified version of the ws library enhanced to pass through the status of the socket buffer so adherence to Node.js Stream API is possible.

Advice Functional Mixin

Advice (License: MIT, npm: advice) by Martin Angers is inspired by Angus Croll’s functional mixin example. It can be used to modify an object with after, before, and around methods:

var myObj = { fn: function() {} }
  , withAdvice = require('advice');

withAdvice.call(myObj)
myObj.before(fn, function() {
  // Things that should happen before fn
});

// the 'before' method will now run automatically
myObj.fn();

The author has kindly included thorough Mocha tests as well.

Buildify

Buildify (License: MIT, npm: buildify) by Charles Davison is a build script API:

var buildify = require('buildify');

buildify()
  .load('base.js')
  .concat(['part1.js', 'part2.js'])
  .wrap('../lib/template.js', { version: '1.0' })
  .save('../distribution/output.js')
  .uglify()
  .save('../distribution/output.min.js');

MaDGe

MaDGe (License: MIT, npm: madge) by Patrik Henningsson generates graphs based on CommonJS or AMD dependencies. It can generate various output including text-based lists in the console, and PNGs using Graphviz. There are lots of commnad-line options, which can be loaded from a JSON file.

This example shows the result of using MaDGe with Express:

MaDGe/Express

jQuery Roundup: Flex, jquery-binddata, jquery.notification

31 Jul 2012 | By Alex Young | Comments | Tags jquery plugins ui databinding notifications
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

Flex

jQuery Flex

Flex (GitHub: jasonenglish / jquery-flex, License: MIT) by Jason English displays an animated grid with expanding panels.

The author has based the effect on a design originally implemented with Flash. He was compelled to write the plugin after he found a discussion on Stack Overflow that suggested creating the effect with JavaScript would be impossible.

jquery-binddata

jquery-binddata is a new plugin created by “jdavidw13” that helps bind form fields to simple JavaScript data models. If you’re used to working with MVC frameworks and want to carry across some of the related data binding techniques to a smaller jQuery project, then this plugin might do the trick.

The basic usage is to provide the plugin with an object to bind and a form element:

var data = { field: 'value' };
$('form').binddata(data);

QUnit tests have been included, and the plugin is currently only about 200 lines long.

jquery.notification

jquery.notification (License: MIT) by Mikhail Davydov is a wrapper around the WebKit Notifications API. I’ve seen quite a few of these plugins, but I don’t think I’ve actually seen them used effectively in the wild.

If you’re looking for such a thing, the plugin looks like this:

var notification = $.notification(options, function(isNotificationsAllowed) {
  if (isNotificationsAllowed) {
    notification.show();
  }
});

Rivets.js, BackboneMVC, Unitools, Moog Source

30 Jul 2012 | By Alex Young | Comments | Tags backbone.js mvc unicode library audio

Rivets.js

Rivets.js (GitHub: mikeric / rivets, License: MIT) by Michael Richards is a data binding library that can be used with frameworks like Backbone.js. It has an adapter option that can be set up to support event-based models. Data formatting is supported, so data types like monetary values or dates can be displayed consistently.

Data attributes are used to describe the data bindings in HTML templates. There are built-in bindings like data-html for innerHTML, but tag attributes are also supported, so to write modelInstance.url to an image’s src attribute data-src could be used.

Rivets.js embraces a pipe-inspired syntax for certain operations. For example, rendering a collection could automatically sort the results like this:

<ul data-html="model.tags | sort | tagList"></ul>

BackboneMVC

BackboneMVC (GitHub: chance-an / backbone-mvc, License: LGPL) by Changsi An adds a controller to Backbone. Controllers are singletons, which means the same instance will always be returned. I suspect this might fit well if you’re wrapping classes with AMD and loading them with RequireJS.

Methods on controllers can be executed by Backbone.Router, so it works very much like Rails (the author states the project is inspired by CakePHP). The beforeFilter and afterRender hooks are executed based on a jQuery Deferred object, but false can be returned as well.

Unitools

Unitools is a collection of Unicode web-related tools for creating all manner of useful and ludicrous text effects.

It includes the Twitter favourite upside down mapping (”sɾʎlıɐp ɯoɹɟ ollǝɥ”), Zalgo, and tools for escaping and working with raw Unicode values.

Moog Google Doodle Open Sourced

I noticed the Moog Google Doodle has been released under the Apache 2.0 license here: bob-moog-google-doodle (HN discussion). I was coincidentally recently working on some web audio stuff, so it’s useful to have something like this to refer to.

TiddlyWiki5, Backbone.Notifier, MVC Jungle

27 Jul 2012 | By Alex Young | Comments | Tags apps mvc backbone.js libraries

TiddlyWiki5

TiddlyWiki5 (GitHub: Jermolene / TiddlyWiki5, npm: tiddlywikigithub) by Jeremy Ruston is a reboot of the venerable TiddlyWiki. As reboots go I’d say this was more along the lines of Batman Begins than The Amazing Spider-Man. It can run entirely in a browser, or as a Node application.

TiddlyWiki is designed to fit around your brain, giving you a better way of managing data compared to traditional documents and emails. The fundamental idea is that information is more useful and reusable if we cut it up into the smallest semantically meaningful chunks.

The project is currently tentatively released as an alpha, and you can keep track of future updates on the TiddlyWikiDev Google Group and @TiddlyWiki on Twitter.

Backbone.Notifier

Backbone.Notifier (License: MIT, GitHub: ewebdev / backbone.notifier) by Eyal Weiss is a notification library designed to work with Backbone.js. Features include dialogs, modal display, and CSS3-based effects.

The Backbone.Notifier class works like the other Backbone classes:

var notifier = new Backbone.Notifier(options);
nofitier.notity('What did one snowman say to the other snowman?');

Instances of Backbone.Notifier can be chained, and the class is event-based, which means it’s quite easy to create wizards by chaining together multiple dialogs.

Journey Through The JavaScript MVC Jungle

Journey Through The JavaScript MVC Jungle is a detailed article by Addy Osmani that introduces MVC frameworks and his TodoMVC collection of demos. There are also some handy descriptions of when to use each framework:

Use KnockoutJS: I want something that will help me build simple Web applications and websites. I don’t expect there to be a great deal of code involved and so code organisation won’t be much of a concern.

Backbone.js: Hacker's Guide Part 2

26 Jul 2012 | By Alex Young | Comments | Tags mvc tutorials backbone.js code-review

Last week we looked at Backbone.js’s internals, covering configuration, server support, events, and models. I actually really enjoy looking at projects this way, it’s one of the best ways to learn new programming techniques. So let’s continue dissecting Backbone by taking a look at Backbone.Collection.

Constructor

Backbone.Collection is a constructor function that accepts an array of models and an options object.

As an aside, notice that void 0 is used in this code. To understand why, recall that the void operator returns undefined. Since ECMAScript 5, the undefined property isn’t writable, so it’s safe to use it. However, in earlier versions it was writable, which meant malicious code could technically take advantage of this fact by assigning a value to the undefined property of the global object. The void operator expects an expression, so void 0 is considered the idiomatic way of safely obtaining undefined.

The constructor calls the reset method, which removes existing models and adds new ones. This is similar to instantiating a collection with no models, and then manually calling add on each one.

Inheritance and Mixins

The Collection class inherits from Backbone.Events. Events are used both publicly and internally. There’s a toJSON method that iterates over each model and calls the model’s toJSON method. This brings up an interesting point: collections use methods from Underscore.js, but Collection doesn’t inherit from Underscore. Why not? Well, certain methods are manually assigned to Collection.prototype, while others are rewritten in ways that make sense in Backbone. For example, the pluck method works on model attributes, and sort uses the boundComparator which has a slightly different API to Array.prototype.sort.

Adding and Removing Items

Collections are basically an array of models with events, wrapped with convenient Underscore-like iterator methods. The add method is always called however models are added, which means it’s a good place to do housekeeping like preventing invalid models and duplicates from being inserted into the collection. Models are also indexed by id, and all model events are bound to _onModelEvent. This method dynamically adds new models, removes deleted ones, and updates models with changes.

If the collection requires sorting, the add method will call sort once all models have been processed. And, if the silent option isn’t set, an add event will be triggered for each model that was successfully added.

It naturally follows that the remove method has a fair amount of work to do, given the complexity of add. The indexed ids must be deleted, and _removeReference is called to remove the model’s reference back to the collection.

Deleting items in JavaScript is interesting, because we actually have the delete keyword to do this for us. However, delete is only used for properties, so the authors have used the Array.prototype.splice technique to delete models from the array. The add and remove methods also update the length property, which allows the collection to behave in an Array-like manner, and helps support the mixed-in Underscore methods.

Now take a look at the simplicity of the where method. It basically loops over each model, comparing an attributes object. This is simple because the filter method is taken directly from Underscore.

Chainable API

Another bit of sugar is the support for Underscore’s chain method. This works by calling the original method with the current array of models and returning the result. In case you haven’t seen it before, the chainable API looks like this:

var collection = new Backbone.Collection([
  { name: 'Tim', age: 5 },
  { name: 'Ida', age: 26 },
  { name: 'Rob', age: 55 }
]);

collection.chain()
  .filter(function(item) { return item.get('age') > 10; })
  .map(function(item) { return item.get('name'); })
  .value();

// Will return ['Ida', 'Rob']

Some of the Backbone-specific method will return this, which means they can be chained as well:

var collection = new Backbone.Collection();

collection
    .add({ name: 'John', age: 23 })
    .add({ name: 'Harry', age: 33 })
    .add({ name: 'Steve', age: 41 });

collection.pluck('name');
// ['John', 'Harry', 'Steve']

Conclusion

I’ve been using Backbone for a while, and I’ve never really thought about how the Backbone.Collection methods can be chained. Sometimes it’s difficult to tell what’s possible though – once you’re in an Underscore chain you can’t use methods like pluck because Backbone’s models use the get method to access attributes, so you’ll end up with an array of undefined values.

Next week I’ll continue looking at Backbone by investing the formidable routing and history APIs.

Node Roundup: Node 0.9.0, ttycast, Simba

25 Jul 2012 | By Alex Young | Comments | Tags node modules terminal config
You can send in your Node projects for review through our contact form or @dailyjs.

Node 0.9.0

Node 0.9.0 is out, and this marks the first in the 0.9 series of unstable releases. In the recent commits there’s been an interesting discussion about uncaughtException:

So if uncaughtException may be removed in the future, does that mean every node.js process will have at least 1 domain?

Node 0.8.3 is the latest addition to the stable line, and this release adds a lot of fixes:

  • net: fix net.Server.listen({fd:x}) error reporting (Ben Noordhuis)
  • net: fix bogus errno reporting (Ben Noordhuis)
  • build: fix add-on loading on freebsd (Ben Noordhuis)
  • build: fix spurious mksnapshot crashes for good (Ben Noordhuis)
  • domain: Fix memory leak on error (isaacs)
  • events: Fix memory leak from removeAllListeners (Nathan Rajlich)
  • zlib: Fix memory leak in Unzip class. (isaacs)
  • crypto: Fix memory leak in DecipherUpdate() (Ben Noordhuis)

ttycast

ttycast

ttycast (GitHub: dtinth / ttycast, License: MIT, npm: ttycast) by Thai Pangsakulyanont is a terminal-to-web broadcasting utility built with ttyrec, Connect, and Socket.IO.

Once ttyrec and ttycast are installed, activity within a terminal can be viewed through a browser. The author has written up some tips on how to do this over SSH.

I tried it out, but I had a problem running it due to a Connect version issue. I’ve let the author know through GitHub so hopefully it’ll work out of the box fairly soon.

Simba

Simba (License: MIT, npm: simba) by Charles Bourasseau is a configuration management module:

simba
  .add('db')
  .children() 
    .add('host', 'localhost')
    .add('port')
    .add('username')
    .add('password')
  .end();

console.log(simba.get('db').get('host')); // 'localhost'

There is full documentation available for Simba that explains some of the underlying concepts and each API method.

jQuery Roundup: noty, jquery.tocify.js, Routie

24 Jul 2012 | By Alex Young | Comments | Tags jquery plugins routing ui navigation
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

noty

noty

noty (GitHub: needim / noty, License: MIT) by Nedim Arabacı is a plugin for displaying notifications. It supports alerts with the usual set of levels, and also allows a prompt to be displayed. A “noty” can be created using a function that accepts an options object:

var noty = noty({ text: 'noty - a jquery notification library!' });

An existing container can be populated using the familiar jQuery syntax:

$('.custom_container').noty({ text: 'noty - a jquery notification library!' });

Notifications can be queued, allowing a large amount of alerts to be handled sensibly. This plugin also supports themes through CSS or a JavaScript file.

jquery.tocify.js

jquery.tocify.js (GitHub: gfranko / jquery.tocify.js, License: MIT) by Greg Franko is a table of contents plugin that works with jQuery UI’s ThemeRoller and jQuery’s animation effects. It also supports history.pushState, so pressing the back button will work as expected.

Given a suitable container div, running $('#toc').tocify(); will generate a table of contents based on the headers on the page.

Routie

Routie (GitHub: jgallen23 / routie, License: MIT) by Greg Allen is a lightweight hash routing library. It’s not specifically dependent on jQuery, and the author has packaged it nicely with a makefile and build instructions. Routes can be defined as follows:

routie('users', function() {
  //this gets called when hash == #users
});

routie({
  'users': function() {
  },
  'about': function() {
  }
});

It also works with regular expressions to allow parameters to be accessed. Notice how parameters are mapped to the function arguments:

routie('users/:name', function(name) {
});

The project includes tests written with Mocha and Chai.

JS101: A Brief Lesson on Scope

23 Jul 2012 | By Alex Young | Comments | Tags js101 tutorials language beginner

JavaScript is a language that demands a rigorous understanding of its scoping rules. One reason for this is JavaScript looks deceptively like other languages, but subtle differences in the rules that govern identifier visibility make it unexpectedly difficult to master.

Here’s some computer science so you can impress your friends and wayward wizards: scope refers to the visibility of a given identifier within a program. Sometimes we talk about function scope and block scope. I’ve already covered function scope in this series, but JavaScript doesn’t have block scope. In this context, block refers to control structures like if statements and for loops – a block of statements grouped by curly braces.

Declaring Variables and Functions

Variables can be defined with the var statement, and are initialised to undefined:

var a; // undefined
var b = 'hello';

The scoping of these statements is dependent on where they’re declared. If var statements don’t appear inside a function, they’re globally accessible:

var a = 1;

function sum(b) {
  return a + b;
}

Missing var

Problems start to occur when a var statement is forgotten:

function example() {
  a = 1;
  b = 1;
  return a + b;
}

These variables are not local to the example function, they’re actually global. If a or b already existed, then their values will be overwritten.

Accidentally leaving out a var statement is surprisingly easy, and could potentially cause irritating bugs. Tools like JSLint will attempt to use static analysis to find such errors.

Variable Declaration Styles

Some people like to group var statements together:

var a = 1,
    b = 2,
    c = 3;

What would happen if a comma was missed by mistake?

function example() {
  var a = 1
      b = 2,
      c = 3;
}

example();

console.log(typeof a);
console.log(typeof b);
console.log(typeof c);

Running this will show that while a is undefined and therefore local to example, the other variables are global.

The reason some developers place commas before lists of variable declarations is to make it easier to see if a comma has been forgotten:

var a = 1
  , b = 2
  , c = 3
  ;

However, the Google JavaScript Style Guide recommends using a var statement on every line, to avoid the problem altogether.

No Block Scope

Variables and functions are visible within the current function, regardless of blocks. This is amazingly confusing because it prevents us from using control structures to declare functions and variables in a dynamic way.

Defining variables in blocks may confuse programmers who work with other languages:

function example() {
  // Do not do this
  for (var i = 0; i < 3; i++) {
    var a = 1;
    // Do stuff with `a`
  }
}

Since there is no block scope, the previous example should be written like this:

function example() {
  var i, a;
  for (i = 0; i < 3; i++) {
    a = 1;
    // Do stuff with `a`
  }
}

Hoisting

Have you ever noticed how some things appear to be in scope even though their definition appears later in the file? The colloquial term for this is hoisting:

function example() {
  console.log(a);
  var a = 1;
}

example();

Running this will log undefined rather than 1. The term hoisting isn’t in the ECMAScript 3 or 5 standards, but the behaviour is documented in 10.5 Declaration Binding Instantiation, in the line that starts For eachVariableDeclaration_ and VariableDeclarationNoIn d in code, in source text order do_. The reason the value is undefined rather than 1 is also explained by the specification:

A variable with an Initialiser is assigned the value of its AssignmentExpression when the VariableStatement is executed, not when the variable is created.

Confusing Closures

The following example defines three functions and assigns them as methods to an object. Each method is then called after the loop has finished.

function example() {
  var o = {}, i = 0;
  for (i = 0; i < 3; i++) {
    o[i] = function() { console.log(i); };
  }
  o[0]();
  o[1]();
  o[2]();
}

example();

The output will be 3 each time, because the closure is bound to the function scope, not the (non-existent) block scope. Intermediate JavaScript programmers often make this mistake.

Conclusion

If understanding JavaScript’s scoping rules was a video game, then the levels would be as follows:

  • Title Screen: Press [Start] to begin (I always press the other buttons to see if it starts anyway)
  • Level 1: Function scope
  • Level 2: No block scope
  • Level 3: Missing var
  • Level 4: Hoisting
  • Level 5: Closures

The scoping story isn’t complete, and worth noting is the fact that ECMAScript extensions can subtly alter scoping behaviour for certain things. If you’re interested in going beyond this 101 introduction level article, then try reading Angus Croll’s Function Declarations vs. Function Expressions to see how some of these scoping rules play out, and Dmitry Soshnikov’s post on ECMAScript’s lexical environments.

References

Enyo, Miso, Dancer.js

20 Jul 2012 | By Alex Young | Comments | Tags libraries frameworks webgl audio

Enyo 2.0

Enyo 2 (GitHub: enyojs, License: Apache 2.0) from HP was released this week. There’s a post all about the release on the Enyo blog:

Enyo 2 boasts an amazing community of developers, a broad set of cross-platform UI widgets, and a powerful layout library for building apps that work across all form factors from phones to desktops.

They’re also promising more updates, with some great hyperbole about the future of web apps:

We see a web-centric future in which there aren’t iOS apps, Android apps, Mac apps and Windows apps - there are just apps: apps that let you access your content and get stuff done, wherever you happen to be, on whatever device is handy.

Miso Dataset

Miso Dataset Example

Miso Dataset (GitHub: misoproject / dataset, License: MIT/GPL, npm: miso.dataset) is a client-side library for managing data. There’s an example called Exploring government spending that uses D3 and Backbone.js alongside Miso Dataset to generate an interactive chart that reminds me of the images David McCandless creates.

Dataset provides tools for working with data in a web-friendly, event-based manner. Data can be loaded using techniques like jsonp, and then manipulated in a similar way to Backbone’s models (Dataset also has an event-based syncing system). It comes with extensible classes for parsing and displaying data, and it also plays well with Node.

There are Dataset tutorials, and a Quick Start guide for the perplexed.

Dataset is actually part of a wider project called Miso by the Guardian Interactive team and Bocoup.

Thanks to @flywheeltech for sending this in.

dancer.js

dancer.js (GitHub: jsantell / dancer.js, License: MIT) by Jordan Santell is an audio API designed for making visualisations. It can work with the HTML5 Audio or use a Flash fallback. It actually includes stuff like an FFT class from DSP.js, so it allows interesting effects to be created while working at a relatively high level.

Backbone.js: Hacker's Guide

19 Jul 2012 | By Alex Young | Comments | Tags mvc tutorials backbone.js code-review

There’s no denying the popularity and impact that Backbone.js (License: MIT, GitHub: documentcloud / backbone) by Jeremy Ashkenas and DocumentCloud has made. Although the documentation and examples are excellent, I thought it would be interesting to review the code on a more technical level. Hopefully this will give readers a deeper understanding of Backbone, and as the MVC series progresses these code reviews should prove useful in accurately comparing the many competing frameworks.

Follow me on a guided tour through Backbone’s source to really learn how it works and what it provides.

Namespace and Conflict Management

Like most client-side projects, Backbone.js wraps everything in an immediately-invoked function expression:

(function(){
  // Backbone.js
}).call(this);

Several things happen during this configuration stage. A Backbone “namespace” is created, and multiple versions of Backbone on the same page are supported through the noConflict mode:

var root = this;
var previousBackbone = root.Backbone;

Backbone.noConflict = function() {
  root.Backbone = previousBackbone;
  return this;
};

Multiple versions of Backbone can be used on the same page by calling noConflict like this:

var Backbone19 = Backbone.noConflict();
// Backbone19 refers to the most recently loaded version,
// and `window.Backbone` will be restored to the previously
// loaded version

This initial configuration code also supports CommonJS modules so Backbone can be used in Node projects:

var Backbone;
if (typeof exports !== 'undefined') {
  Backbone = exports;
} else {
  Backbone = root.Backbone = {};
}

The existence of Underscore.js (also by DocumentCloud) and a jQuery-like library is checked as well.

Server Support

During configuration, Backbone sets a variable to denote if extended HTTP methods are supported by the server. Another setting controls if the server understands the correct MIME type for JSON:

Backbone.emulateHTTP = false;
Backbone.emulateJSON = false;

The Backbone.sync method that uses these values is actually an integral part of Backbone.js. A jQuery-like ajax method is assumed, so HTTP parameters are organised based on jQuery’s API. Searching through the code for calls to the sync method show it’s used whenever a model is saved, fetched, or deleted (destroyed).

What if jQuery’s ajax API isn’t appropriate for your project? Well, it seems like the sync method is the right place to override for changing how models are persisted, and this is confirmed by Backbone’s documentation:

The sync function may be overriden globally as Backbone.sync, or at a finer-grained level, by adding a sync function to a Backbone collection or to an individual model.

There’s no fancy plugin API for adding a persistence layer – simply override Backbone.sync with the same function signature:

Backbone.sync = function(method, model, options) {
};

The default methodMap is useful for working out what the method argument does:

var methodMap = {
  'create': 'POST',
  'update': 'PUT',
  'delete': 'DELETE',
  'read':   'GET'
};

Events

Backbone has a built-in module for handling events. It’s a simple object with the following methods:

  • on: function(events, callback, context) , aliased to bind
  • off: function(events, callback, context) {, aliased to unbind
  • trigger: function(events) {

Each of these methods returns this, so it’s a chainable object. The comments recommend using Underscore.js to add Backbone.Events to any object:

//     var object = {};
//     _.extend(object, Backbone.Events);
//     object.on('expand', function(){ alert('expanded'); });
//     object.trigger('expand');

This won’t overwrite the existing object, it appends the methods instead. That means it’s easy to add event support to other objects in your project.

Model

Backbone.Model is where things start to get serious. Models use a constructor function that sets up various internal properties for managing things like attributes and whether or not the model has been saved yet. Underscore.js is used to add the methods from Backbone.Events, and then the public model API is defined. This contains most of the frequently used Backbone methods.

Notice that Backbone.Model is actually quite transparent: there aren’t any private methods defined inside the constructor.

The set method supports two different signatures, making it easy to support a single attribute or multiple attributes:

// Handle both `"key", value` and `{key: value}` -style arguments.
if (_.isObject(key) || key == null) {
  attrs = key;
  options = value;
} else {
  attrs = {};
  attrs[key] = value;
}

The save method does something similar. Notice how the authors ensure an object is always set for options:

options || (options = {});

In terms of expressing the programmer’s intent, this seems better than options = options || {}.

The set method triggers validations and prevents the method from progressing if a validation fails:

if (!this._validate(attrs, options)) return false;

Next each attribute is iterated over. If the attribute has changed, according to Underscore’s isEqual method, then the change is recorded. Once the list of changes have been built, the change method is called.

The change method calls trigger for each change. This allows for changes to any attribute to be listened on specifically, allowing the UI to be updated appropriately. For example, let’s say I had a blogPost model instance:

blogPost.on('change:title', function() {
  // Update the HTML for the page title
});

blogPost.set('title', 'All Work and No Play Makes Blank a Blank Blank');

Other methods also trigger change events: unset, clear, and fetch. Since we don’t always care if these cause a change event, a silent option is supported that will be passed from these methods to set. It’s actually quite interesting how each of these methods is implemented by reusing set:

// Clear all attributes on the model, firing `"change"` unless you choose
// to silence it.
clear: function(options) {
  options = _.extend({}, options, {unset: true});
  return this.set(_.clone(this.attributes), options);
},

The fetch method will trigger a sync operation that will retrieve the latest values from the server (or suitable persistence layer if it’s been overridden).

The save method ensures only valid attributes and models are persisted, and calls set if required:

if (options.wait) {
  if (!this._validate(attrs, options)) return false;
  current = _.clone(this.attributes);
}

// Regular saves `set` attributes before persisting to the server.
var silentOptions = _.extend({}, options, {silent: true});
if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) {
  return false;
}

// Do not persist invalid models.
if (!attrs && !this.isValid()) return false;

The sync method is called to persist the changes to the server. isNew is used to determine if the model should be created or updated. The isNew state is determined by whether an id attribute exists or not. This could be easily overridden if a given persistence layer works a different way. Notice that Backbone internally references this attribute as this.id and doesn’t map it to the value set with idAttribute in isNew.

A parse placeholder method is called whenever models are fetched, or saved. There are examples of people using this to parse other data formats like XML.

Conclusion

After looking at the Backbone.js setup and model code, we’ve already learned quite a lot:

  • Any persistence scheme can be supported by overriding the sync method
  • Models are event-based
  • change events can drive the UI whenever models change
  • Models know when to create or update objects
  • Reusing Backbone’s models, events, and Underscore methods is useful for organising project architecture

Although the Backbone models don’t have a plugin layer, the authors have kept the design open and allowed for just the right hooks to support lots of HTTP services and data types outside the built-in RESTful JSON oriented design.

Backbone relies heavily on Underscore.js, which means applications built with it can build on both of these libraries to create (potentially) well-designed and reusable code.

Node Roundup: Markdox, node-authenticate, node-codein

You can send in your Node projects for review through our contact form or @dailyjs.

Markdox

Markdox (License: MIT, npm: markdox) by Charles Bourasseau is a documentation generator based on Dox (which TJ changed to output JSON only) that produces Markdown. It can be used in the shell, or programatically.

This is a straightforward way of generating API documentation that works with services that support Markdown, like GitHub.

authenticate-pam

authenticate-pam (License: MIT, npm: authenticate-pam) by Damian Kaczmarek is an asynchronous PAM authentication addon. It uses libpam to authenticate users with a simple, idiomatic Node API:

var pam = require('authenticate-pam');
pam.authenticate('myusername', 'mysecretpassword', function(err) {
  if (err) {
    console.log(err);
  } else {
    console.log('Authenticated!');
  }
});

node-codein

node-codein (License: MIT, npm: node-codein) by “ketamynx” is a Windows-friendly Node interface based on WebKit Inspector. It can display objects graphically as trees, and can also execute code.

Although it looks like a debugger interface, it seems like the author intends for it to be used as a friendly alternative to the REPL.

jQuery Roundup: trunk8, tcsst, MaxImage

17 Jul 2012 | By Alex Young | Comments | Tags jquery plugins galleries testing truncation
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

trunk8

trunk8 (GitHub: rviscomi / trunk8) by Rick Viscomi is a text truncation plugin. Truncating text in browsers is actually quite awkward to do well, and I haven’t yet found a plugin that does it particularly well when a certain number of vertical lines is required. However, this one appears to do that through the lines option, and it also does a lot more: tooltips can be created, character count is supported, and the internal calculations are cached so it should perform very well.

The author has attempted to address performance using several familiar client-side hacks, so if speed is an issue this might be a good choice. The author hasn’t included unit tests or benchmarks, so it might take a bit of jsPerf to really see how efficient it is.

tcsst

tcsst by Paul Battley is a CSS testing script for jQuery. The author wrote it because “life’s too short to click around”. It’s basically a simple test runner with a CSS-specific flavour: tests are defined in terms of CSS selectors:

tcsst(function(tc){
  tc.test('top of paragraph should be at a multiple of line-height', 'p',
    function(test, element){
      var lineHeight = parseInt($('body').css('line-height'), 10);
      var diff = $(element).offset().top % lineHeight;
      test.assert((0 == diff), 'Off by ' + diff + 'px');
    });
});

It’s an interesting concept, and I think there’s a lot of room for time-saving assertions that are tailored for CSS.

MaxImage 2.0

MaxImage 2.0 (GitHub: akv2 / MaxImage, License: MIT/GPL) by Aaron Vanderzwan is a fullscreen background slideshow plugin. There’s a demo of MaxImage that shows it being used with the jQuery Cycle and Easing plugins.

This plugin actually checks if the browser supports background-size, so it should look good in modern browsers. It also pre-loads images.

JSON Extensions

16 Jul 2012 | By Alex Young | Comments | Tags json essays

JSON is typically used as a data interchange format. We use it for communicating with services over HTTP, and for configuration files. People are starting to take it beyond Douglas Crockford’s original definition to add more features. Let’s take a look at some of these extensions to JSON.

JSON Schema

JSON Schema is a JSON-based format for defining the structure of JSON data. Although the JSON Schema specification has expired, it crops up now and then in the open source community in the form of data validation modules. The idea of writing a portable JSON schema once, and then a module or framework automatically providing validation in a user interface is definitely attractive, although such projects aren’t wildly popular so far.

JSON5

JSON5 (GitHub: aseemk / json5, License: MIT, npm: json5) by Aseem Kishore brings ECMAScript 5-inspired enhancements to JSON. The main changes are as follows:

  • Keys don’t need to be quoted and can be any valid identifier
  • Strings can be single-quoted
  • Multi-line strings are supported
  • Objects and arrays can have trailing commas
  • Inline and block comments are allowed
  • Numbers can be hex or start with a decimal point

The author’s implementation is available for Node, but it’ll run in most browsers (including IE6), and it has a test suite as well.

eson

Another tweaked version of JSON is TJ Holowaychuk’s eson. The main change here is TJ’s parser allows functions to extend any JSON file’s behaviour. It’s a little bit like middleware for JSON: a function can be run over each key and value, allowing data values to be transformed.

The example in the documentation is supporting { "interval": "15 minutes" } instead of writing the millisecond value.

Conclusion

Looking at these deviations in JSON illustrates what authors are trying to get out of the JSON standard. Some want to relax the schema rules, others want more extensible parsers. What surprised me most about JSON in the last few years is the failure of JSON Schema to catch on. Perhaps it’s lacking a killer app?

Kinesis, Lo-Dash, Backbone-Super

13 Jul 2012 | By Alex Young | Comments | Tags kinect games windows css testing backbone.js

Kinesis

Kinesis

When I was growing up I knew a good microswitch when I saw one. I ended up with a formidable collection of joysticks for gaming, but they’re nothing compared to the extremes the arcade fighting stick mod community go to. Why am I boring you with my knowledge of awesome buttons? Well, the developers behind Kinesis want to bring Kinect hacking to a wider audience through their new JavaScript APIs.

Right now the SDK requires an invitation to download (really?), but there are some videos of Kinesis demos available now.

In the meantime I’ll be standing in a corner with my Sanwa-modded Hori arcade stick playing some real video games.

Lo-Dash

I saw TJ Holowaychuk mention Lo-Dash (GitHub: bestiejs / lodash, License: MIT) on Twitter:

A drop-in replacement for Underscore.js, from the devs behind jsPerf.com, that delivers performance improvements, bug fixes, and additional features.

There are, of course, benchmarks:

Lo-Dash’s performance is gained by avoiding slower native methods, instead opting for simplified non-ES5 compliant methods optimized for common usage, and by leveraging function compilation to reduce the number of overall function calls.

John-David Dalton has posted a video about the project to Vimeo: Lo-Dash’s origin and why it’s a better utility belt.

Backbone-Super

Backbone-Super by Lukas Olson adds a super method to Backbone.Model using John Resig’s Inheritance script. Rather than using Backbone.Model.prototype.set.call as per the Backbone.js documentation, _super can be called instead:

var Note = Backbone.Model.extend({
  set: function(attributes, options) {
    this._super(attributes, options);
  }
});

MVC: Primer

12 Jul 2012 | By Alex Young | Comments | Tags mvc tutorials

I recently attended a talk by Addy Osmani at the London Ajax Group (great meetup by the way) in which Addy discussed client-side MVC. The slides are available here: Digesting JavaScript MVC – Pattern Abuse Or Evolution?

Since then I’ve been thinking a lot about client-side MVC. Rather than simply mentioning frameworks like Backbone.js as part of regular roundup style posts, I thought it might be useful to dig a little deeper into the client-side MVC phenomenon.

The Elephant in the Room

We’re stuck with the term “MVC”. It’s not an accurate way to describe what frameworks like Backbone.js do, but to avoid confusing matters I’ll stick with it for now. Some libraries and frameworks seek to differentiate themselves by using more accurate terms like MVVM (Model-View-View Model).

Terminology aside, most client-side developers are probably in a position where they think they need something like Backbone.js, but aren’t entirely sure what it does, how it does it, and what else is out there. Furthermore, is it worth investing time learning Backbone.js only for someone to replace it with something more cutting edge? The field is definitely changing fast – as single page applications are now commonplace, their associated techniques are cropping up on traditional websites. It’s clear that client-side development requires more investment in the architectural side of development. Organising code with mature techniques lifted from the classic Design Patterns: Elements of Reusable Object-Oriented Software is just the beginning.

Choice

The choice of frameworks is bewildering. TodoMVC provides implementations of a to-do app in more frameworks than anyone has time to learn. Choosing the right framework for a given project is only the start of the problem, however. The real issue is learning how to use the framework correctly. It’s very easy to write “anti-patterns” with something like Backbone.js, and quickly get into a spaghetti code mess.

Choosing the right framework and using it well comes down to knowing what you need. If you’re in the position of thinking you might need a client-side MVC framework, but you’re not sure why, then my advice is to get your hands dirty. Take a look at how these frameworks are built, and what they provide. Eventually you’ll see similarities between them, and see how to apply their features to your own projects.

Forget Models and Controllers

Forget terms like models and controllers for a moment, and consider these frameworks at a higher level.

Backbone.js: Helps represent and manipulate data with JavaScript. The data originates from a server or can be generated by the browser – Backbone.js is good at synchronising data with RESTful services. Events fire when data changes, triggering code that can update the interface. It also provides some tools for generating (rendering) reusable templates based on events – however, these “views” are more of a convention than sophisticated API. URLs can be dynamically updated by the browser using the HTML5 History API.

Knockout: Uses data bindings to automatically update the interface based on changes to data. Doesn’t provide client-side routing or data synchronisation with a server.

These two frameworks are very different: Knockout focuses on automatic data binding to keep the UI in sync, and offers tools to write reusable view-oriented code to do this. Conversely, Backbone.js requires the user to manually wire up events between the interface and data, and instead makes it easier to integrate with RESTful services and create modern single page application using the routing API.

If I was writing a single page application backed by a RESTful service, I may opt for Backbone.js. However, if I was writing a more traditional web app with complex data-driven templates, then Knockout might be a better fit.

So, Which MVC Framework Should I Use?

Set aside hyperbole and stop worrying about which framework implements MVC correctly. Instead, look at each framework in relation to your project and requirements at a high level.

In the upcoming weeks I plan to further demystify MVC frameworks by exploring the patterns and anti-patterns. I’d also like to look at some of these frameworks in more depth in some upcoming code review style posts.

Node Roundup: 0.6.20, New npm Site, Raspberry/ARM, Engines Removal, nodist

11 Jul 2012 | By Alex Young | Comments | Tags node modules
You can send in your Node projects for review through our contact form or @dailyjs.

Node 0.6.20

Node 0.6.20 has been released. The 0.6 series is now in “maintenance mode”, so this release tidies a few things and updates npm, there isn’t anything application-breaking as far as I can tell.

Node 0.8.2 was also released. There are bug fixes and incremental improvements, I’ve updated to it for all my development work and it seems fine so far.

New npm Site

new.npmjs.org

The new npm site is available at new.npmjs.org. The new design is based on nodejs.org – the navigation, icons, and typography have been reused, which makes a welcome change from the old hacker-friendly monospaced font design.

Signing in to the new site allows account credentials to be edited, including social network handles. Avatars are supported through Gravatar. And… packages have their own pages, no more hash URLs! Take a look at the Express npm page to see what I mean. It even displays documentation.

The source for the new site is open source and can be downloaded at GitHub: isaacs / npm-www. This is actually quite enlightening, because Isaac has written a readme with an extremely detailed design philosophy.

Ridiculous speed: This site should be surprisingly fast. Towards that end, things are cached and served from memory whenever possible, and ETagged for browser-cacheablility.

No lib folder: If you would put it in lib/, then it belongs in a separate module.

Considering who this comes from this could form the start of a guide to idiomatic Node web applications, which is something I feel is sorely lacking in the community.

There aren’t currently any tests, outside of the project’s dependencies. However, even if you’re a die-hard TDD advocate I still think there’s a lot to be learned from taking a deeper look at this project.

From the Groups: Raspberry Pi, Engines

Trying to build Node for a Raspberry Pi? There’s a discussion about ARM support on nodejs-dev:

Every time there’s a new version of node I have to go in and modify config files specifically for ARM and it seems that nodejs just doesn’t run very well on it.

Apparently building for ARM requires V8 to be compiled as a shared library:

The current problem is with V8 + gyp. If you compile v8 from svn as a shared library, node should then compile alright.

– AJ ONeal

I also noticed an interesting discussion about removing “engines” from package.json:

Engines is advisory. It prints a warning. Set engineStrict in your package.json, or --engine-strict config, to make it strict. (If the package.json field is abused, it will be removed eventually. I don’t suspect this is going to be an issue.)

There’s a commit related to this here: Make ‘engines’ field advisory.

nodist

nodist (License: MIT, npm: nodist) by Marcel Klehr is a Node version manager for Windows. Once Node has been installed with the standard Windows installer, other versions can be installed using nodist’s command-line interface:

nodist + v0.8.1

Typing nodist --help will display documentation for each command and examples.

jQuery Roundup: New Sizzle, HubInfo, Select2

10 Jul 2012 | By Alex Young | Comments | Tags jquery plugins selectorengines
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

The New Sizzle

In The New Sizzle, Timmy Wilson explains how jQuery’s revised CSS selector engine works. Timmy has compared it to other selector engines, and shows how the new implementation differs to the previous version.

The part about extensibility is promising:

… there are a couple changes that make Sizzle even more extensible. Now with the parser compiling a function of functions, you can receive more information when creating your custom selector. Sizzle.compile is exposed so you can cache your selectors before they get used. While compiling is still very fast without caching, you can make sure that step is skipped before the selection is ever run.

HubInfo

HubInfo (GitHub: jgallen23 / hubinfo, License: MIT) by Greg Allen displays a GitHub repository widget. It comes bundled with CSS, so it’s easy to get something looking good straight away with a small amount of JavaScript:

$('#hubInfo').hubInfo({ 
  user: 'alexyoung'
, repo: 'dailyjs'
});

The hubInfo method returns an object that will fire a render event. The project’s documentation shows this being used to add a Twitter share button.

Select2

Select2 (GitHub: ivaynberg / select2, License: Apache 2.0) by Igor Vaynberg is a select box replacement that features a similar style to the popular Chosen library. Unlike Chosen, the author has made Select2 work better with large data sets – results can be paginated, and infinite scrolling is supported.

There’s an active community of Select2 users at the Select2 Google Group, and there’s lots of demos and documentation on the project’s homepage.

JS101: The Function Constructor

09 Jul 2012 | By Alex Young | Comments | Tags js101 tutorials language beginner

Last week we took a cursory glance at functions, and this week we’ll look at the Function object itself.

Creating Functions with the Function Constructor

Functions can be instantiated with zero or more arguments. The last argument is always the function body:

var sum = new Function('a', 'b', 'return a + b');
sum(1, 1);
// 2

The length property will return the number of arguments:

sum.length
// 2

This property is not writeable. The function body will have access to arguments, so supporting variable arguments is still possible:

The behaviour of a function when invoked on a number of arguments other than the number specified by its length property depends on the function.

Other properties include call, apply, and bind. There’s also a toString method, which will return a string containing the function’s body. It won’t be exactly the same as the source supplied to the Function constructor.

Scope

To all intents and purposes, functions created this way are indistinguishable from any other function. There is a difference, however, and that lies in the scope binding. The Global Environment is passed as the scope for the new function, which isn’t necessarily intuitive. This isn’t a bug and is covered by the specification, but it’s worth being aware of the behaviour.

For example, this will fail because a isn’t in scope for the Function instances:

function container() {
  var a = 1
    , b = 1
    , sum = new Function('return a + b')
    , sum2 = new Function('sum()');
  sum();
  sum2();
}

container();

The amazing thing is, an eval would have access to a and b because entering eval code sets up the lexical and variable environments the usual way.

This difference is useful, because new Function offers a way to execute arbitrary code without providing access to local (perhaps considered “internal”) variables. jQuery’s JSON parser uses this distinction to parse JSON:

if (rvalidchars.test( data.replace( rvalidescape, "" )
    .replace( rvalidtokens, "]" )
    .replace( rvalidbraces, "")) ) {

  return ( new Function( "return " + data ) )();
}

In this way we can see eval and new Function are related, but not entirely the same. However, some well-known JavaScript professionals strongly warn against using both:

eval has aliases. Do not use the Function constructor. Do not pass strings to setTimeout or setInterval.

Metaprogramming

The Function constructor is occasionally used for metaprogramming. It’s used to generate new methods in the Mongoose MongoDB module for Node:

MongooseBuffer.prototype[method] = new Function(
  'var ret = Buffer.prototype.'+method+'.apply(this, arguments);' +
  'this._markModified();' +
  'return ret;'
)

In this case, it would be trivial to refactor out the Function constructor.

There are more specific cases where the Function constructor is used for more devious metaprogramming. The Jade template language compiles templates into functions. Dojo also has a few places relating to templates where it’s used as well.

Conclusion

The Function constructor has some scope behaviour that takes a bit of getting used to, but it’s exploited by a very specific class of libraries. In general, most code doesn’t really need to use new Function.

References

Bootstrap Tour, DOM Utils, asEvented

06 Jul 2012 | By Alex Young | Comments | Tags backbone.js dom events

Bootstrap Tour

Bootstrap Tour (GitHub: pushly / bootstrap-tour, License: Apache 2.0) from Push.ly is a small library for building interactive product tours with Twitter Bootstrap. Tours are instances of Tour, and can contain a reference to an element to anchor to along with a title and descriptive text:

var tour = new Tour();

tour.addStep({
  element: 'selector'
, title: 'Popup Title'
, content: 'Descriptive text'
});

Steps will be displayed using popovers, and the tour can be ended at any time. Steps can also contain a path option so tours can span several pages.

DOM Utils

Utils (License: MIT) by Matt McDonald is a modular DOM library designed to degrade gracefully and work in a wide range of browsers. It contains a lot of the utility functions we find ourselves needing when working without a larger framework, for example:

  • Utils.is.arrayLike: Is a given object array-like?
  • Utils.node.prepend: An insertBefore wrapper method
  • Utils.select.byClassName: Returns an array of node-like objects that match the class name

Some methods will return null in browsers that don’t support the underlying DOM API calls. This is documented thoroughly, with a suggestion on how to proceed:

Warning: this property will return null if the host environment is detected to be unsuitable; an if block or a similar construct should be used for detection.

Rather than falling over to less efficient methods, this library prefers to make the developer determine how to proceed.

Utils can be downloaded by selecting the required modules: Utils Download.

asEvented

asEvented (License: MIT, npm: asEvented) by Michal Kuklis is a small event emitter module that works in Node and browsers. It works using a mixin style rather than through inheritance:

function Model() {
  this.id = 0;
}

asEvented.call(Model.prototype);

This gives Model methods for dealing with events, like trigger and bind.

The project has already received a few contributions, and it includes qunit tests that are easy to run in a browser.

Chrome Apps: JavaScript Desktop Development

05 Jul 2012 | By Alex Young | Comments | Tags google chrome talks videos

Evolution of Chrome Apps

June was a month of tech conferences, but it was Google I/O that really stole the thunder of E3 and Apple’s WWDC. People are understandably excited about the Nexus 7, Jelly Bean, and Chrome for iOS, but what was there for us JavaScript hackers? All of the Google I/O sessions are available for viewing, and one that caught my eye was The Next Evolution of Chrome Apps.

I saw this video referenced on Twitter by TJ Holowaychuk, and given that his JavaScript aesthetics align with mine I wanted to know why he was talking about it. It turns out there’s a lot to like about the future direction of Chrome apps and Chromebooks from a JavaScript developer’s perspective. Offline is now being taken extremely seriously – partly because existing APIs are being adapted to cope with intermittent connections, but also because Chrome apps will be integrated with the OS (whether it’s Google Chrome OS, Mac OS, Linux, or Windows). This addresses a key usability problem people have with offline web apps: how are they launched? Rather than digging around in bookmarks or Chrome’s Apps page, we’ll now be able to launch them from the OS.

After seeing this talk, here’s my hyperbolic claim: Google is going to revolutionise desktop development. Watch the talk to see if you agree.

The part of the talk that stole the show was the Arduino demo. The new APIs allow applications to access OS-level features: networking, bluetooth, and even serial IO. Mihai Parparita (Chrome Apps Tech Lead, Google Reader) demonstrated an Arduino board that controlled a motor with a potentiometer, and a Chromebook (on the latest Canary build) was able to read and write data to it.

I’ve summarised the talk below, but if you’re desperate to see sample code then take a look at the GoogleChrome GitHub account and developer.chrome.com/apps.

Breaking out of the Browser

In Breaking out of the Browser, system-level integration is discussed:

  • Launch apps from outside the browser
  • First-class OS windows – rather than just using the DOM, windows can be created that work with native controls and shortcuts (including cmd/alt-tab)
  • Full window frame without browser chrome
  • Links open in browsers, not the app

The Bizarro World Window Demo demonstrates this. This is all done with JavaScript.

Offline by Default

The Offline by Default section deals with how new packaged apps are better able to cope with offline mode or intermittent connectivity.

  • The interface and application logic are entirely local
  • There’s an enforced separation of data and UI to help prevent apps from getting into a broken state
  • An application should work without ever having connected to the network
  • Older APIs have been updated to perform better during poor connectivity
  • The fact apps launch from outside the browser helps people realise they work outside the browser and will function offline

There’s a demo of a diff tool that works differently offline. When the connection is lost, it immediately displays an offline notice and only allows local files to be opened. When it’s offline remote files can be opened instead.

New APIs

The new APIs are mainly concerned with OS-level integration.

  • System APIs: interacting with the hardware (USB/bluetooth) or OS (TCP)
  • Shared data APIs: interoperating with other apps (photos/contacts/calendar) accessed safely from multiple apps
  • (Google) Web service APIs that run well under poor network conditions: analytics, ads
  • Raw sockets, which Google employees have been using to create things like IRC clients

There’s a demo showing an Arduino board interacting with a Chromebook.

Programming Model

Of course, to facilitate all of these changes the programming model has changed somewhat:

  • Applications use a “background page” with a main event
  • The application life cycle is event-based
  • System-level signals are accessible through an event-based API
  • The APIs have bindings to more languages – Dart is mentioned, but I’m not sure what else they’ll ship with
  • Background applications can be created
  • Apps should be single page with no navigation – basically designed like desktop applications instead of web applications

There’s a bigger emphasis on the difference between extensions and apps. Extensions are now seen as something that modifies the browser itself, while apps are more like desktop applications. Some apps on the Chrome Web Store currently use extension-level functionality, but these will have to be changed to become extensions instead. I’m not sure if a package app can be distributed with an extension, because I’m sure there are some cases where the boundary is blurred – how does 1Password or LastPass fit into this model?

Security Model

The Security Model reviews Chrome’s existing sandbox approach, but also details some new features:

  • Storage isolation ensures applications can’t modify data they shouldn’t have access to
  • Applications can be restricted using a new permission system
  • There’s a new <browser> element that allows apps to render a page in a similar way to an iframe, but without the security issues

Systems Applications Working Group

It certainly seems like these changes will open up new possibilities for developers interested in targeting Chrome and Chromebooks, but doesn’t this mean we’re investing in vendor-specific technology that we can’t use elsewhere? Well, Erik and Mihai addressed this by announcing that Google is working with Mozilla, Samsung, and Intel on the System Applications Working Group:

The mission of the System Applications Working Group is to define an runtime environment, security model, and associated APIs for building Web applications that integrate with a host operating system.

They’re also in the early stages of looking at adapting this technology for mobile platforms.