Monday, April 6, 2015

Agile, how to embrace the change

The agile manifesto gives us a better way for developing software, putting:

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan

This overview tells a lot from a project perspective, but what about developers perspective ? how is it possible to adapt to continuous changes?
Writing a good piece of code, fully tested, requires a lot of time and effort. Throwing it into the bin is not only a waste, it is also very bad for the morale.

Luckily enough there are a few tricks that can solve most of the problems. Not a big deal, just common sense, but still thing worth to be said:

Automation, automation, automation

Ok, you are writing a piece of software and you already know that you are going to rewrite part of it, probably more than once. Automate all tedious tasks, most of the time is it a pretty good investment, especially at the beginning of the project.
I can safely assume you can automate:

  • building
  • testing
  • releasing
  • deploying 
All this can take a bit to set up, the key part is that you can reuse them across many projects.

Divide and conquer

The common mistake in approaching the design of a software is looking at it as a single entity. The best approach instead is to split it into simple and configurable libraries/modules, they can be assembled at the last minutes to get what you want.
This approach minimizes the waste and enforces the separation of concerns. And it is also a overall win in maintainability.
A good library should solve a common problem, always. A very specific problem does not deserve to be taken into consideration. What happen if your beautifully crafted, business specific library, needs to be thrown away because of requirements change ?
Instead make the business requirement a configurable option of your generic library.
There is also a huge bonus: generic libraries can be easily reused across many projects.

Documentation

Writing a good documentation improves the thing that matter most: your code should be reused more than once. A good documentation should contain purpose, a design explanation, installation instruction, API and some examples. These are particularly important.
In this case documentation is more important than working software. Bugs can be fixed, a missing/outdated documentation means your library can't be used by anyone, even you after a month.

The open source power

A fully documented and tested generic library is a big investment, and it is often valuable enough for other people as well. Why don't share it with others ?
It can enrich the ecosystem of the platform that you are using. You can also get valuable feedback.

This method, applied: a true story

The first example it comes to my mind is several years old. I was working in a company where one of the most successful product was a solution for building on line catalogs.
When I got hired my first task was the third attempt to build this software. The first two attempts were way too vertical on the previous customers to be reused for the next ones.
The main problem was embedding specific customer requirement in the project, for example the design of the product page was something every customer wanted to be different.

The business input was: "I want a catalog product", way too generic and misleading from the developer point of view. There were though, a certain amount of loosely couple, common functionalities. The real point here was to identify these functionalities and build all of them as separate product.
This is a classic case in which a developer should not do what is being told, he should use his expertise to build a system that fulfil the requirements.
The product page, for example, was never a part of the product but I developed a system to build a page with subcomponent, all of them configurable.

After a few attempt we managed to have a very flexible collection of products for building catalog applications. By the time I left the company this was used several times ...

Bottom line

It is possible to be agile, to foresee and to adapt, after all is our job.


Wednesday, February 25, 2015

High performance animations (a few tricks)

The web browser is capable of very smooth animations, but there are a few gotchas. Here is what you should know.

jQuery

With jQuery animations went mainstream. But jQuery.animate is possibly the less efficient way for animating elements nowadays:
It can be still useful on old browsers or in specific cases. Better not using it on mobile browsers.

CSS transitions and animations

Native animations runs usually faster than JS ones. So it is quite obvious to use them when possible. There are plenty of tutorial on how to use them so google for it!

Composite layer css properties

When you change a CSS property you trigger some operations in the browser. These are:

  • recalculating sizes and positions (layout)
  • redrawing elements on the screen (paint)
  • composite all elements together (composite)

The topmost operations triggers the ones below. Furthermore the more elements are involved the worst the animation is , performance wise.
You can visualize and debug this process in the useful timeline panel (inside Chrome developer tools).
The trick here is to use css properties that triggers only the composite step. These are opacity
and transform. This is article contains what you need to know.
Sadly it is not enough to use these for getting the performance jump, you should also trigger the creation of a new composite layer using these CSS rules:

.will-change{
    transform: translate3d(0, 0, 0); 
    perspective: 1000;
    backface-visibility: hidden;
}

For a better support you can add these browser prefixes:

.will-change{
    -webkit-transform: translate3d(0, 0, 0); /*old chrome and safari*/
    -o-transform: translate3d(0, 0, 0); /*old opera*/
    -moz-transform: translate3d(0, 0, 0); /*old FF*/
    -ms-transform: translate3d(0, 0, 0); /*IE9*/
    transform: translate3d(0, 0, 0);
    -webkit-perspective: 1000;
    -o-perspective: 1000; /*old opera*/
    perspective: 1000;
    -webkit-backface-visibility: hidden;
    -o-backface-visibility: hidden; /*old opera*/
    backface-visibility: hidden;
}

Doing this opacity and transform are managed by the GPU if possible.
This can be a bit awkward and for this reason browser vendors have created a new css rules: will-change.
This will make the browser know that an element is going to change and to put it inside a compositing layer (this is not yet widely available so sadly, for now, it is better to stick with the hack).

Request Animation Frame


The way js animations work is changing a numeric CSS property over time. The only way to schedule an event in js was setTimeout (and its brother setInterval). As I mentioned they are still used by jQuery.
A while ago browser vendors introduced "requestAnimationFrame". It is a much better way to do it as it execute a piece of code right before the page refresh (approximately 60 times a second).
This is a polyfill for any browser (in the worst case it uses setTimeout).

If your animation depends on user interactions it can be a good idea to throttle the changes to the CSS using requestAnimationFrame. In this example I am using a queue with a simple policy that returns only the last function discarding the others.

function lastOne(q){
    return q.length ? [q.pop()] : [];
}

function getRenderingQueue(policy){
    var queue = [];
    var isRunning = false;
    policy = policy || function (q){return q;};

    var render = function (){
        var f;
        queue = policy(queue);
        isRunning = false;
        while (f = queue.shift()){
            f();
        }
    };
    return {
        empty: function (){
            queue = [];
        },
        push: function (func){
            queue.push(func);
            if (!isRunning){
                isRunning = true;
                window.requestAnimationFrame(render);
            }
        }
    }
}


var renderingQueue = getRenderingQueue(lastOne);

renderingQueue.push(function (){
    //changing a piece of CSS
});


Depending on your application you can decide using a different policy.

This is it, I'll soon put this in context.

Friday, January 30, 2015

urlwalker.js, a context aware router for express

Urlwalker.js is a router middleware for Connect/Express.js.

It is not a substitute of the default Express.js router but it works together with the latter, trying to get an object from a fragment of URL (It literally walks it segment by segment, hence the name). You can then use this object as model in the function called by the default Express.js router.
This process is called URL traversal. This concept is not by any means original: I took the inspiration from other web frameworks such as Zope and Pyramid.

Confused ? Let's make a step behind

URL, model and view

Using REST principles it seems to be natural mapping a URLs to a hierarchy of objects:

  • http://www.example.com/roald_dahl/the_chocolate_factory

This URL represents a relation between two objects: the author (roald_dahl) and one of his books (the_chocolate_factory). The last is the model used by the function. Let's put this thing together using express.js:
app.get("/:author/:book", function (req, res){
    // getting the book object
    // doing something with the object
    // return the result
});
The original "Expressjs" way to get the model is to do it directly inside the function (like the previous example) or (better) using app.param. But it is not flexible enough for managing a deeply arbitrary nested structure.
Furthermore I believe it can be useful to split the URL in two different parts. The first part is for getting an object and the second one to transform the object:

  • http://www.example.com/roald_dahl/the_chocolate_factory/index.json
  • http://www.example.com/roald_dahl/the_chocolate_factory/index.html

Both of these URLS point to the same object but return a different representations of that object.
Urlwalker.js follows this convention.

How to use it


The middleware is initialized with a function and a "root" object.

var traversal = require('urlwalkerjs').traversal;
var traversal_middleware = traversal(function (obj, segment, cb){
    return cb({ ... new obj ... })
    // or
    return cb(); // end of traversing
},root_object);

Then you can use it as a normal middleware and add the regular routing:

app.use(traversal_middleware);

app.get('index.json', function(req, res) {
  res.send(req.context);
});

The routing process starts with an object. I call it the "root object" and it is the second argument passed to the middleware. It can be anything, even undefined.
The function (the first argument of the middleware) is invoked for any URL segment. The first time is invoked with the first segment and the root object. It returns an object. The second time is called with the second segment and the object returned previously. The process is repeated until it can't find a match. Then it returns the last object in "req.context" and pass the control to the next middleware.
For this URL:

  • http://www.example.com/roald_dahl/the_chocolate_factory/index.json

The function is invoked twice:

  • from the root object and the segment "roald_dahl" I get an author object
  • from the author object and "the_chocolate_factory" I get a book object

Then the express.js function is called with the book object inside req.context.
For clarifying the process I have added an example here.

An example with occamsrazor.js


Defining this function with such a complex behaviour can be difficult and not very flexible.
For this reason you can use occamsrazor.js for adding dinamically new behaviours to the function (see example 2).
So it becomes:

var getObject = occamsrazor();
var has_authors = occamsrazor.validator().has("authors");
var has_books = occamsrazor.validator().has("books");

getObject.add(null, function (obj, id, cb){
    return cb(); // this will match if no one else match
});

getObject.add(has_authors, function (obj, id, cb){
    return cb(obj.authors[id]);
});

getObject.add(has_books, function (obj, id, cb){
    return cb(obj.books[id]);
});

var traversal_middleware = traversal(getObject, data);
app.use(traversal_middleware);
app.get('index.json', function(req, res) {
  res.send(req.context);
});

At the beginning it might seem a bit cumbersome until you realize you can easily extend the behaviour so easily:

var has_year = occamsrazor.validator().has("year");

getObject.add(has_year, function (obj, id, cb){
    return cb(obj.year[id]);
});

Plugin all the things

But why stops here? why can't we get the view with a similar mechanism  (example 3) ? Let's replace the Express.js routing completely with this:

...
var view = require('urlwalkerjs').view;
var getView = occamsrazor();

var view_middleware = view(getView);

getView.add(null, function (url, method, context, req, res, next){
    next(); // this will match if no one else match
});

getView.add(["/index", "GET", has_books], function (url, method, context, req, res, next){
  res.send('this is the author name: ' + req.context.name);
});

getView.add(["/index", "GET", has_authors], function (url, method, context, req, res, next){
  res.send('these are the authors available: ' + Object.keys(req.context.authors));
});

getView.add(["/index", "GET", has_title], function (url, method, context, req, res, next){
  res.send('Book: ' + req.context.title + " - " + req.context.year);
});

app.use(view_middleware);

A plugin architecture is very helpful, even though you don't need plugins at all. It allows you to apply the open/close principle and extend your application safely.

Thursday, January 15, 2015

Why I have stopped using requirejs (and you should too)

I have used requirejs extensively and I have written many posts about it. I think it is very ingenious and well designed.
It tries to solve more than one problem at the same time (in a very elegant way) but nowadays these problems are not so important and they have better solutions.

Loading scripts asynchronously

This was one of the main selling point of requirejs in the past. Now it is not necessary anymore. It is much better moving (back) the script tags on the top and use the async attribute as described by this great article. The async attribute now is very well supported !

Loading dependencies

Requirejs can dinamically load dependencies when they are required. But often you want to have the control. Sometime is better to include a library when you load the page (bundling more than a library together, for having them saved in the cache) and sometime you want to load it on demand. In case it is very easy do something like:

var script = document.createElement('script');
script.src = "http://www.example.com/script.js";
document.head.appendChild(script);

Isolate dependencies

Requirejs is even able to run 2 different versions of the same library. But is a feature rarely used and to be honest in 99.9 % of the cases using the module pattern is more than enough.

The only issue

The only issue of having all these asynchronous bundles (using the async attribute) is managing the execution order. You can use a tiny library like this one:

(function (w){

var go = {}, wait = {};
w.later = function (dep, func){
    if (go[dep]) func();
    else {
        wait[dep] = wait[dep] || [];
        wait[dep].push(func);
    }
}

w.later.go = function (dep){
    var funcs =  wait[dep] || [], l = funcs.length;
    delete wait[dep];
    go[dep] = true;
    for (var i = 0; i < l; i++){
        try{
            funcs[i]();
        }
        catch (e){
            console && console.error(e);
        }
    }
}
}(window));

This could be the only JS to be loaded synchronously. For maximum performances you can also minify it and inline in the HTML.
Then you can manage the dependencies at execution time:

later('foo', function (){
   // waiting for the bundle named foo (it is an arbitrary string)
});

You only need to put this instruction at the end of the bundle "foo":

later.go("foo");

There are still valid use cases for requirejs but I suggest to keep your build process lean, tweak performances by hand, use the async attribute and the module pattern.
Simpler and more performant !

Edited: and what about "defer"?

This article suggests to use async and defer together for improving performances on older browsers. I suggest to not do that, unless you know what your script is doing. This is because of this bug. The bug is even worst of what it seems, if you inject a script tag inside a DEFERred script the execution will stop waiting for the injected script to be downloaded and executed. So be careful!


Tuesday, January 6, 2015

Less Sass and (mo)Rework

I apologize for the pun. In this blog post I'd like to give my opinion about css preprocessors.

Sass and Less

Sass and Less are the most popular CSS preprocessors. I think CSS preprocessors are powerful tools but often they are not going to help you writing better CSS. Most of their powerful features can be abused to make the wrong choices in term of code reuse. This is because they don't promote reusability of the produced css rules.
There are still (a few) acceptable use cases: producing css demos, bulding very repetitive css rules as responsive grids and things like that.

But in the hands of inexperienced developers, they produce a mess: in my experience a bad less/sass is much worst than a bad css.

Writing proper css

Writing CSS is not too bad. The real challenge is to keep it maintainable. In this challenge Sass and Less are not helping. What is useful is design the css for the reuse, following these simple principles for example:
  • Naming is particularly important. With a namespace you can avoid conflicts. You can also separate rules in "general rules", "module rules", "exceptions". For this one you can adhere or find inspiration in SMACSS.
  • Avoid at any cost working with specificity. Use namespacing instead! So don't use selectors as ".my-module .my-special-class" but ".my-module-special-class"
  • a rule, a feature. Any rule should just contains a single functionality. This functionality can be a single rule or a combination of rules. CSS frameworks (like Bootstrap) are full of examples.

Enter reworkcss (and Myth.io)

Actually there are a couple of things that are really useful in CSS preprocessors. They can address automatically browsers prefixes, they can let you use variables and calculations (server side).
My favourite tool for doing this is rework. Although it is not a CSS preprocessor but a css parser. It produce an AST (that is a js object), you can change this object and write back the css.
It has a plugin system so it is very easy to create custom extensions.
You always start and end with a syntactically valid css (selector {property: value;}). You don't have to change syntax, syntax highlighters keeps working fine and the result can be easily used together with other static analysis tools.
You can roll out your own plugin for doing complex operations that are not possible at all with Sass/Less.
There are already a lot of plugins like one for using variables, another one for addressing browser prefixes etc.

grunt-css-annotator

This grunt plugin is an example of using rework. It scans some webpage (using PhantomJS) and adds an annotation in a comment if a css selector is used in those pages.
There is also an option to remove rules with specific annotations. It can be useful if you want to do spring cleaning in your css and this is only an example of the power of rework!

Myth.io

Myth.io is a CSS preprocessors built using a collection of useful rework plugins. It is designed for polyfilling some of the CSS features of tomorrow, like variables and calculations. But you can also extend it with other custom plugins!

EDIT: I have used myth.io for a serious project. It was mostly a pleasant experience but there is a severe limitation in the use of css variables! https://github.com/segmentio/myth/issues/10 .

Thursday, April 17, 2014

A trip into Clojure, lesson learned

In my current job I had the chance to learn and use Clojure (this is the experience reported by a former collegue). Having worked with Python and Javascript I had consided myself well skilled in functional programming. But working with a more opinionated functional programming language was an eye opener. The benefits? robustness, better code reuse, a more organic workflow.

My main takeaway is that I can apply the lesson learned to Python and Javascript (and many others) as well. Let's see how.

Languages

Many languages enforce a specific point of view. Java for example with its pervasive object orientation enforce to model problems in objects. Python tries to please everyone with a solid OO implementation and a good deal of functional constructs. Javascript is similar (but with a different OO implementation).
Clojure, from this point of view, is more like Java: it enforces a specific way to model problems: a functional model.

Functions

Of course functions are first class citizen in a functional language so they can be stored in variables, passed as argument etc.
This allows a lot of useful programming patterns. These are just few examples:

  • Passing a callback: in event oriented programming (like events in browser or node.js) it's useful to pass a specific callback to run after an event
  • Decorator: you wrap a function in another function (useful for access control, memoization etc.). In Python there is a programming feature called "decorator" that makes easier to use this pattern.
  • Lazyness and partials: a function retuning not the actual result but another function that return the result. Useful to defer the actual task and if you need only a part of the result.

A brilliant example of what functional programming allows are wsgi middlewares (in the Python world) and Connect middlewares (in the node.js/Javascript world). As a matter of fact you can find a similar pattern in Clojure ring.

No objects - nothing enforce a local state

While the classic OO tries to encapsulate logic and state in the same entity (objects) a functional language keeps the two things well separated. This seems to be weird if you are used to OO but it has a lot of sense.
It is easy and more predictable to test the code because you are sure there is no mutation of the local state during the method calls. Any function has arguments and output: there is no side effect based on value of "this". Actually in Clojure you can have side effects (mutating atoms for example) but this is an exception, not the rule. And this is clearly explicit.

Types and common interface

Standard maps/lists offer a common and simple interface to a lot of generic functions. In the classic OO every object has a different interface requiring specific code to interact with.

In Javascript there are fantastic libraries like underscore, lodash to interact with standard arrays, objects (intended as maps in this case). You can also use hash maps and sets (Ecmascript 6). If you use  field descriptor you can access getters and setters using the usual semantic.

If you use Python, you should use more list an dict and less custom objects. Python can help you to keep the interface simpler using field descriptors and operators overloading. There are a lot of functional built in (like zip, map, filter, list comprehensions ...) and the fantastic itertools library.

(Im)Mutability

An immutable object cannot be changed. Any change creates a new object.
Mutable objects are a dangerous source of bugs. It's very easy to change an object passed as argument or by another function call without realizing that you are changing permanently the original object. This is a classic python gotcha.
It's not only a newbie's mistake: I have spotted the same nasty bug in Backbone.js.

In this case Clojure shines because everything is immutable by default.
If you use Python, you should never mutate an object/dictionary/list passed as argument. If you really need to do that, clone it before. Remember that list comprehensions, slice operator, and many built-ins return a brand new object and are safe. But it is better to check the doc because for example the "sort" method mutate the original list and the "sorted" built-in no.

The same advice is valid for Javascript too. Check the usual underscore and lodash for  clone and deepClone method. Remember that some array method returns a brand new array. This is a shallow clone but sometimes is good enough. A fantastic option is to use mori a library to use Clojure(script) data type and sequences in Javascript.

Lazyness

Working with sequences in Clojure is amazing because any operation is deferred. This is memory and computational efficient. This is not a new thing if you use Python generators, itertools or the new Javascript iterators and the for-of statement (ES 6). You can also use the Clojure sequence library with the aforementioned Mori library.

Development process

The functional approach (in my personal opinion) allows to develop in a more gradual way. While in the OO you have better results deciding the object model upfront, this is a bit complex in the long run. Some changes will require to move methods around the class hierarchy, create common base classes. And this kind of refactoring often invalidates a lot of unit tests too. So you often ends with small patches and code duplication.
The evolution of a functional program can be a bit chaotic but changes are more granular and it's easier to reuse code without doing a lot of impact.


This is the lesson learned: be more functional!

P.S. This is a nice book if you want to improve your Functional Javascript skills

Sunday, March 23, 2014

When scripts should run?

A quick walkthrough on when executing a script in the browser.

A lot of examples on the internet show to wrap the code inside the jQuery "ready" event handler. It is not always the case. As a matter of fact you can execute a script in three different fashions:
  • immediately
  • in the ready event handler
  • in the load event handler
  • under another event handler (but this is a different story though)

Immediately

You can execute a script immediately if your script doesn't rely on the DOM, or rely on a fragment of DOM that is already been loaded (because is placed before your script).
I think this is often the preferred case.

JQuery ready

The jQuery ready event handler uses the  domcontentloaded event but is guaranteed to be executed right away if this event is already been fired.
"The handler passed to .ready() is guaranteed to be executed after the DOM is ready"
You should execute your script here if it runs before the fragment of DOM targeted by the script. Given this, if you are loading synchronously you should definitely put the script at the bottom of the HTML and just execute it immediately.

On load

There are rare cases when you need the CSS and images loaded before executing the script. A suggestion: avoid it if you can! For example you could (and definitely should) add the width and height attribute on any img and you can use a bit of inline css styling (in some edge case).
In the few cases you really need this you can use the load event handler.

Asynchronous loading

If you use requirejs you really don't have a clue on when your script is executed. Luckily enough executing it immediately or inside a jQuery ready event is always safe. It's not so using the load event.
Your script could be loaded after the load event is already been fired. For this reason is a good idea to check it and, in case, executing the script immediately.

function mycode(){
   ...
}

if (document.readyState == "complete"){
    mycode();
}
else {
    $(document).load(mycode);
}

Ajax fragments

When you load or create a new fragment of html sometimes you need to run the some code against the new fragment. This can be avoided the vast majority of time using event delegation adding your event handlers to a wrapper node (or to the document itself). If you really need to manage this I suggest to generate a custom event to manage these cases. For example:

// loading a fragment
var $result = $("#result")
$result.load("ajax/test.html", function (){
    ...
    $result.trigger('nodeloaded');
    ...
});

...
// trigger on the document ready 
// for the whole document
$(document).ready(function (evt){
    $(document).trigger('nodeloaded');    
});

...

// manage the event
$(document).on("nodeloaded", function (evt){
    $('.your-class', evt.target).yourplugin();
});

You can find something similar used in jquery mobile.


Sunday, January 26, 2014

Requirejs: edge cases


I have already written about requirejs in this post.
In this new post I'm going to explain something you should know using require in complex environments.

You definitely should use the optimizer

Not using the optimizer in a production environment is highly discouraged.

To explain why, it can be useful thinking about how requirejs works:
All the modules together form a dependency tree. The process of loading this tree is not completely parallel because requirejs is aware of specific dependencies only after loading a module.
Requirejs optimizes this process executing a module only once and caching its result.
The optimizer simply merges a group of modules in a single file and this makes the process much faster.

Inline scripts

Sometimes you'll need to add online scripts to the HTML. Doing this you should consider that your module could be not loaded yet. To fix this problem you can "require" your bundle as a dependency before running the code:

require(["app"], function (){ // app is the name of the bundle
    require(["yourdependency"], function (){
        //inline script
    });
});

But there is another problem!
Many examples shows to put your requirejs configuration inside the first module.
Sometimes you'll need a specific configuration to load your module (for example the baseUrl). But the configuration could not be available in your inline scripts (it's async!).

There is a trick for this: requirejs allows to load the configuration in a synchronous way. You just need to define a global object "require" with the configuration right before loading requirejs script.

<script>
var require = {
    "baseUrl": "http://example.com/js/lib",
    "paths": {
      "app": "main/app"
    },
    "shim": {
        ...
    }
};
</script>
<script data-main="scripts/main.js" src="scripts/require.js"></script>

Mixing synchronous and asynchronous scripts

Performance wise all the scripts should be loaded asynchronously but real world applications need some compromise.
A typical case is using the infamous document.write that wipes out the page when executed asynchronously.

In this slideshow @slicknet explains why loading scripts in different positions.

But mixing synchronous and asynchronous script can be tricky. How can do it safely?

First of all be careful where you load the requirejs script in the page. Many libraries check for the presence of the "define" global variable to be loaded asynchronously (using the UMD pattern):

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['b'], factory);
    } else {
        // Browser globals
        root.amdWeb = factory(root.b);
    }
}(this, function (b) {
    //use b in some fashion.

    // Just return a value to define the module export.
    // This example returns an object, but the module
    // can return a function as the exported value.
    return {};
}));


Jquery for example is AMD compatible so, if you load requirejs before jquery, this will behave in a different way.
My suggestion is to concatenate all the synchronous files of your application in a single script, putting requirejs in the last position.

Second problem: what happen if you are requiring a module and, in this particular page, this module is already loaded synchronously ?
Requirejs will download the module again, this time as a module. This is not ideal so you need to trick requirejs prepending to our main module something like this:

define('jquery', [], function() { // jquery is loaded synchronously before this code
    return jQuery;
});

With the previous code requirejs will use the global jquery instead of requiring a new jquery module to the server.
I am not advocating to load jQuery syncronously. This is just an example!
Another issue: the optimizer will include all the scripts that in your particular case are synchronous.
You need to exclude these files from the optimization (this is an example using the grunt-contrib-requirejs task):

    requirejs: {
      dev: {
        options: {
        "appDir": "www",
        "baseUrl": "js/lib",
        ... other options ...
        "modules": [
            {
                "name": "app",
                "exclude": [
                    "jquery",
                    ... other exclusions ...
                ]
            },
            ... other bundles ...
          ]      
        }
      },

Loading dynamically

In some case you'll want to download a different group of modules in a more dynamic way. Based on a certain configurations or user event (like in this example)
For doing this you can create one or more different bundles (with the optimizer).
You need to remember to exclude from the bundles the resource that should be already loaded in the page (use the previous option).

Scripts not bundled

In some case you don't want to include your file in a bundle because is served by a CDN or directly from your application (for example socket.io). The requirejs optimizator uses the "empty:" option to manage this:

    requirejs: {
      compile: {
        options: {
          mainConfigFile: "static/js/main.js",
          baseUrl: "static/js",
          name: "main",
          paths: {
            'socketio': 'empty:',
            'backboneio': 'empty:'
          },
          out: "static/js/main-built.js"
        }
      }
    }

Requirejs is a very good choice to manage scripts loading and dependencies. I hope to have brought light in some of the dark spots of using this in a complex environment.

Friday, October 18, 2013

Reusable javascript modules with Bower

In a previous post I have used require.js to download javascript files and optimize them.
Here I'll introduce a useful tool to manage your javascript and css assets. But first of all let's talk about modules definition in Javascript.

Universal module definition

At the moment there is no standard way to define a module (we are waiting for EcmaScript6) but you can easily define your module in a way compatible with AMD, UMD and regular script import. Just pick one of these snippets. I recommend to use one of those because declaring object in the global namespace is not a good practice and libraries like requirejs can help to load and optimize your scripts.

Bower

Bower is a package manager designed for the web. You can install it using:

npm install -g bower

And then start downloading your first package (jquery for example):

bower install jquery

You'll find jquery in the jquery folder inside the "bower_components" folder. Bower packages are versioned so you could (and should) specify what version install.
bower install jquery#1.10.2
If this package has some dependencies (other bower packages of course) those will be installed in the same "bower_components" folder. For those who are using node.js: be aware that it is quite different from how npm works! In this case all the dependencies are resolved and flatten in the same folder.

Bower package

A bower package, in fact, is a simple folder with a bower.json file:
{
  "name": "mypackage",
  "version": "0.0.1",
  "main": [
     "script.js",
     "style.css"
  ],
  "homepage": "https://github.com/User/myproject",
  "authors": [
    "Donald Duck "<donald.duck@gmail.com>";
  ],
  "description": "an example package",
  "keywords": [
    "js",
    "css",
  ],
  "license": "private",
  "private": true,
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "lodash": "~1.3.1",
  }
}
Let's see the most important fields:

name: the name of the package

version: the version of the package. It should be the same of the tag on git.

main: these are the main files of your project. For example a jquery repository has a lot of stuff (unbuilded file, test, fixtures etc.) but the main file is just jquery.js.

dependencies: an array of bower packages needed to run this one. You should always specific the version using this syntax.

Bower repository

The published packages are just git tags with a bower.json. The bower command  anyway uses a central repository to store the metadata (name, url of repository, keywords etc.). This repository is on https://bower.herokuapp.com/. If you have a public project you can publish on the central repository using:
bower register mypackage https://github.com/user/mypackage.git
The versions available will be taken from the available tags on you repo.

Running your own repository

Let's say you are working on a project and you don't want to share every package you are working on.
You can easily set up your own bower registry and configure bower to use it. You can do this putting a ".bowerrc" in your working directory (or in your home):
{
    "registry": {
        "search": ["http://bower.myserver.com", "https://bower.herokuapp.com/"],
        "register": "http://bower.myserver.com"
    }
}

This instructs bower to download packages from your server or the official one (the first has the priority), and to register the packages on your server only.

Automate everything !

Using grunt-bower-task you can create a build step that install all the dependencies required by your bower.json and copy all the files defined in "main" in a folder. If you use require.js you can also use grunt-bower-requirejs to build  the require.js configuration automatically.

I think this is enough to start working with bower. Enjoy!




Thursday, July 25, 2013

Server side modules with Architect

After my last notes on a client side modular architecture using require.js I'll talk about server side modules using Architect.

Modules

In my opinion every application (not only the bigger ones) needs to be divided into interdependent modules. This helps a lot when you deal with testing and enhancing your application.
In node.js applications, you will see and use this pattern very often:

//import a module
var Database = require('./db');

// initialize a module using some options 
var db = new Database('http://my.db.connection');

// initializing a module injecting a dependency 
var usermanager = require('./usermanager')(db);

But what if you want to use this module in other applications ? In this case you should make an npm independent package for each module, of course. And, in the main application you would initialize each package in the proper order. This is repeatitive and tedious furthermore, when the number of the packages starts to get bigger, initializing each module in the proper order can be an issue.

From modules to plugins

Architect uses a simple declarative syntax to explain the interconnections between packages. It also starts the system in the correct order initializing each package just once.
I recommend to read the documentation on github. It's very clear and detailed.

Express.js and Architect

I have set up a simple express.js/architect boilerplate to show how to use Architect to make an extensible express.js application.


I hope this will be useful ...

P.S.
A friend of mine suggest me to use a git subtree for each package. Nice idea!


Thursday, July 18, 2013

Client side modules with require.js


In this post I will show you how to use Require.js to split a project into simple and manageable modules.

UMD and AMD

I really didn't want to dive into differences of these 2 module systems but I think it's very important to realize of what module system we are talking about.

UMD is the module system used by node.js. You define modules doing this (foobar.js):

module.exports = {
    foo: 'bar'
};

And load a module doing this:

var foobar = require('./foobar');
console.log(foobar.foo); // prints bar

You can use UMD in the browser using browserify.
If you usually work with Javascript in the browser you will notice two issues:
  • the exports object would be overwritten every time by differents modules
  • it uses a synchronous approach
As a matter of fact it cannot work in the browser without a build step (and this is the browserify's task).

AMD instead is designed from the ground up to work in the browser.

Saying this I am not advocating one of these systems. They are both very useful even though they use different approaches.

I started by explaining UMD because, unfortunately, both systems use a function called "require".
Now that you can't be fooled anymore by this let's go on.

What is an AMD module

An AMD module must be contained in a single file and is encapsulated by the global function define.
"define" takes two parameters: an array of dependencies and the actual module code.

//module3.js
define(['module1', 'module2'], function(module1, module2) {
    'use strict';

    var namespace = {};
    
    return namespace;
});

In this example I have defined a module called "module3". This module needs module1 and module2 to run.
The return value of define will be returned if another module requires module3.
module1 and module2 are resolved loading with AJAX module1.js and module2.js (both AMD modules).
The job of require.js is basically to resolve the dependency tree and to make sure that every module would be run just once.

A module has a pair of interesting properties:

  • It is loaded the first time is required by another module.
  • not a single variable is added to the global namespace. For this reason you can even use different versions of the same library if you need to

Bootstrap and configuration

After defining modules you will need to bootstrap your application (configure and load the first module). For doing this you will define in your page a script tag with require.js and the url of the bootstrap script (main.js).

<script data-main="/js/main" src="js/vendor/require.js"></script>

After loading require.js it will load the "main.js" bootstrap using ajax. From this point every script will be loaded asynchronously and the DOMContentLoaded event (the jquery ready event) will be fired independently from the script loading.

Main.js is made of 2 part. The first one is require.js configuration:

require.config({
  baseUrl: "js/",
  paths: {
    jquery: 'vendor/jquery-1.9.1',
    underscore: 'vendor/underscore',
    backbone: 'vendor/backbone',
  },
  shim: {
      underscore: {
          exports: "_"
      },
      backbone: {
          deps: ['underscore', 'jquery'],
          exports: 'Backbone'
      },
      'jquery.bootstrap': {
          deps: ['jquery'],
          exports: '$'
      }
    }
});

Here are the most important parameters:
baseUrl: this is the path used to resolve modules.. So if you require "module1" this will be loaded from "js/module1.js".

paths is very useful to define script that are in some other paths. When you require "jquery" will be loaded the script "js/vendor/jquery-1.9.1.js".

Shims

Until now I assumed that every script is an AMD module but this is not always true.
require.js shim option allows to wrap automatically a non AMD script into an AMD define.

"deps" are dependencies to be injected and "exports" is the value to be returned:

For example your backbone.js will become:

define(['underscore', 'jquery'], function (_, $){

..actual backbone.js source ...

return Backbone;

});

The trick works even when you have to add attributes to an existing object (like defining a jquery plugin):

define(['jquery'], function ($){

$.fn.myJqueryPlugin = function (){
};

return $;

});

This is the case of Twitter bootstrap.

require

The second part of main.js is the actual bootstrap. It loads and execute the first module.

require([
  // Load our app module and pass it to our definition function
  'app',
], function(App){
  // The "app" dependency is passed in as "App"
  App.start();
});
The app module will start a chain of loading that will load the entire application's scripts.

The useful text plugin

The text plugin allows you to add text files as dependencies and this is very useful for client side templating.
Just add "text" in the path config:

require.config({
  ...
  paths: {
     ...
    text: 'vendor/text'

and you can load your templates:

define(['underscore', "text!templates/template.html"], function (_, template_html){
    var template = _.template(template_html);
    ...
});

You can also write your own plugin as described here.

Script optimization

Using a lot of modules have an obvious drawback: the time spent to load these modules in the browser.
Require.js comes with a useful tool for optimizing scripts: r.js. It analizes, concatenates and minifies all the dependencies in one single script.

I warmly recommend to use a build step to make this operation automatically.

I use grunt and a grunt plugin to automate everything.

Installing grunt and the require.js optimizer plugin

Grunt is structured in 2 different modules: "grunt-cli" and "grunt" and a series of plugins. "grunt-cli" can be installed globally:

npm install -g grunt-cli
grunt and the plugins should be installed locally pinning a release version. This system allows to use different versions and plugins for each project.
npm install grunt --save-dev

npm install grunt-contrib-requirejs --save-dev

The save-dev option adds the modules in the package.json under the "devDependencies" key and using the latest release.
...
  "devDependencies": {
    "grunt": "~0.4.1",
    "grunt-contrib-requirejs": "~0.4.1"
  },
...

You can also do this manually and launch "npm install".

Grunt configuration

Grunt needs a configuration file called Gruntfile.js this is an example from a past project of mine:

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    requirejs: {
      compile: {
        options: {
          mainConfigFile: "static/js/main.js",
          baseUrl: "static/js",
          name: "main",
          paths: {
            'socketio': 'empty:',
            'backboneio': 'empty:'
          },
          out: "static/js/main-built.js"
        }
      }
    }
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  // Default task(s).
  grunt.registerTask('default', ['requirejs']);

};

In the "requirejs" configuration I have:
mainConfigFile: the path of the bootstrap script
baseUrl: the same as configured in the main.js configuration
name: the name of the main script
paths: in this section I added a pair of script to not be included in the optimized script. These 2 files are served directly by my node module. You can also do the same for script served through a CDN or an external service.
out: the output file

"registerTask" allows me to launch the whole optimization step with the "grunt" command (using no options).

At the end of the task I can load my new optimized script using:

<script data-main="/js/main-built" src="js/vendor/require.js"></script>
I think this is all. Stay tuned for the next!

Edit: If you liked this you'll probably be interested in this other blog post on require.js edge cases.

Monday, July 1, 2013

Writing a real time single page application - server side

In the first part I highlighted how to take care of the frontend of a real time web app. Now I'll explain how to face the backend. As usual I will not dive into details, follow the links if you search in depth explanations.

Server side

I wrote the server side of my application using node.js and a very lightweight framework called express.js
The most important feature of this framework is the middleware system.
This is a middleware:

function middleware(req, res, next){
...
}

A middleware is a sort of russian doll. You can put a middleware inside another middleware (the "next" argument).

A middleware can basically:
  • call the next middleware in the chain ( next() )
  • call the output function ( res() )
  • change the input (req)
  • overwrite the output function (res)

You can use a middleware for:
  • authenticate and get user informations
  • route to a specific middleware using the URL (req.url) and the method (req.method)
  • add a specific header to the HTTP response
  • etc.

Using middlewares is very common because it allows to build simpler and reusable components.

Express.js gives you already a lot of middlewares but I used passportjs to get a complete solution for authentication.
In this example I will store users into couchdb using nano

var config = require('./config'), // I used a config.json to store configuration parameters
    db_url = config.db_protocol + "://" + config.db_user + ":" + config.db_password + "@" + config.db_url;
    nano = require('nano')(db_url), 
    setupAuth = require('./auth'),
    MemoryStore = express.session.MemoryStore,
    sessionStore = new MemoryStore(), // nano will store user id in this session
    passport = setupAuth(userdb);

var app = express(),
    server = http.createServer(app);
    
// configure Express
app.configure(function() {
    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs');
    app.use(express.logger());
    app.use(express.cookieParser());
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.session({ store: sessionStore, secret: config.session_secret, key: config.session_key }))
    // Initialize Passport!  Also use passport.session() middleware, to support
    // persistent login sessions (recommended).
    app.use(flash());
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
    app.use(express.static(__dirname + '/' + config.static_dir));
});

var ensureAuthenticated = function(req, res, next) {
    if (req.isAuthenticated()) {
        return next();
    }
    res.redirect('/login');
};

// I check if a user is authenticated before accessing this URL
app.get('/', ensureAuthenticated, function(req, res){
  res.render('index', { user: req.user});
});

// login
app.get('/login', function(req, res){
    res.render('login', { user: req.user });
});

app.post('/login', 
    passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
function(req, res) {
    res.redirect('/');
});

app.get('/logout', function(req, res){
  req.logout();
  res.redirect('/login');
});

server.listen(config.http_port);

The auth module contains functions used by passport:

var passport = require('passport'),
    LocalStrategy = require('passport-local').Strategy,
    crypto = require('crypto');


module.exports = function (userdb){
    var getUserFromId = function(id, done) {
        userdb.get(id, { revs_info: false }, function(err, body) {
            if (!err){
                return done(null, body);
            }
            else {
                return done(null, false, { message: 'Invalid credentials' });
            }
        });
    };

    passport.getUserFromId = getUserFromId;
    
    passport.serializeUser(function(user, done) {
        done(null, user._id);
    });
        
    passport.deserializeUser(getUserFromId);

    passport.use(new LocalStrategy(
        function(username, password, done) {
            var shasum = crypto.createHash('sha1').update(password),
                key = [username, shasum.digest('hex')]

            // this view's keys are [username, password]
            // the password is hashed of course
            userdb.view("user", "login", { keys: [key] }, function (err, body){
                if (!err) {
                    if (body.rows.length){
                        // logged in !!!
                        return done(null, body.rows[0].value);
                    }
                    else {
                        return done(null, false, { message: 'Invalid credentials' });
                    }
                }
                else {
                    console.error(err);
                    return done(null, false, { message: 'Db error, try later' });
                }
            });        

        })
    );

    
    return passport;
};

This example is explained in the passport documentation.
If you are careful you will notice that the getUserFromId function is called every time to get the complete object from the database (couchdb in this case).
This is not very optimal and it's better to cache users for some time. I used this nice memoization module:

    var memoize = require('memoizee');
    
    // cache this function for optimal performance (2 minutes)
    // https://npmjs.org/package/memoizee
    getUserFromId = memoize(getUserFromId, { maxAge: 120000,  async: true});

Backbone.io in the server

At this point I will define a backbone.io backend (as explained here: https://github.com/scttnlsn/backbone.io)

var items_backend = backboneio.createBackend();

A backend is very similar to an express.js middleware.

var backendMiddleware1 = function(req, res, next) {
   ...
};

items_backend.use(backendMiddleware1);
items_backend.use(backendMiddleware2);

Once defined, I will connect the backend.

var io = backboneio.listen(server, {items: items_backend});

The io object which is returned by the listen method is a socket.io object.

When a websocket is connected for the first time it makes a basic handshake. This phase can be used to perform the passport authentication.

var cookie = require('cookie'),
    cookiesig = require('cookie-signature');
// socket io authorization
io.set('authorization', function (data, accept) {
    if (data.headers.cookie) {
        data.cookie = cookie.parse(data.headers.cookie);

        // cookies are signed for better security:
        //
        // s:name:signature
        //
        // s: is a prefix for signed cookies
        // name is the cookie name
        // signature is an hmac of the value
        // doing this the client cannot change the cookie value
        // without invalidate the cookie
        if (data.cookie[session_key].indexOf('s:') === 0){
            data.sessionID = cookiesig.unsign(data.cookie[session_key].slice(2), session_secret);
        }
        else {
            data.sessionID = data.cookie[session_key];
        }
        
        // (literally) get the session data from the session store
        sessionStore.get(data.sessionID, function (err, session) {
            
            if (err || !session) {
                // if we cannot grab a session, turn down the connection
                accept('Cannot get sessionid', false);
            } else {
                // save the session data and accept the connection
                data.session = session;
                if("passport" in session && "user" in session.passport){
                    passport.getUserFromId(session.passport.user, function (err, user, message){
                        if(err || !user){
                            accept('Cannot find user', false);
                        }
                        else {
                            try{
                                data.user = user;

                                accept(null, true);
                            }
                            catch (e){
                                accept('Error: ' + e.toString(), false);
                            }

                        }
                        
                    });
                }
                else {
                    accept('Session does not contain userid', false);
                }
            }
        });
    } else {
       return accept('No cookie transmitted.', false);
    }
});

The tricky part here is to extract the session from the (signed) cookie. The passport and sessionStore objects are the same defined before for normal authentication.
The backend authentication middleware can get the object through req.socket.handshake object:

var authMiddleware = function(req, res, next) {
    var user = req.socket.handshake.user;

    if (!req.user){
        next(new Error('Unauthorized'));
    }
    else {
        req.user = user;
        next();
    }

};

Backend events and channels

When a backend changes something backbone.io automatically broadcasts the change to every node connected (and triggers the events I talked before).
You often need to notify only a subset of clients. For this reason you can define channels. Every changes will be notified to clients connected to a certain channel.
The channel can be defined client side but I added a useful feature to define channel server side, during the handshake.

There is also another case where you need to detect whether couchdb has been changed by another application.
In this case I recommend you to use my fork of backbone.io  because it supports channels.

Database and flow control with promises

The last piece of the application is talking to the database. In my application I used couchdb but it is really not important which database will you use.
In the first paragraph I have underlined that a single resource operation could cause many operations in the backend. For this reason is very important using a smarter way to control the flow. I have chosen promises.

Promises are a standard pattern to manage asynchronous tasks. I used this library: https://github.com/kriskowal/q
The advantage of promises is to avoid the "pyramid of doom" of nested callbacks:

step1(function (value1) {
    step2(value1, function(value2) {
        step3(value2, function(value3) {
            step4(value3, function(value4) {
                // Do something with value4
            });
        });
    });
});

And transform that in something more manageable:

Q.fcall(step1)
.then(step2)
.then(step3)
.then(step4)
.then(function (value4) {
    // Do something with value4
}, function (error) {
    // Handle any error from step1 through step4
})
.done();

With promises, managing errors is very easy.
This is an example using nano:

var getUser = function (id) {
    var deferred = Q.defer();

    userdb.get(id, {}, function(err, body) {
        if (err) {
            deferred.reject(new Error('Not found'));
        }
        else {
            deferred.resolve(body);
        }
    });
    return deferred.promise;
};

var getGroup = function (user) {
    var deferred = Q.defer();

    userdb.get(user.groupid, {}, function(err, body) {
        if (err) {
            deferred.reject(new Error('Not found'));
        }
        else {
            deferred.resolve(body);
        }
    });
    return deferred.promise;
};

function getGroupFromUserId(id, callback){
    getUser(id)
    .then(getGroup)
    .then(function (group){
        callback(group);
    })
    .done();
}

Backbone.io and databases

Backbone.io has some ready to use backend and it is quite easy to write your own following the examples (I added the couchdb backend).

The end?

This ends this whirlwind tour. I hope someone will find this useful.

Friday, June 28, 2013

Writing a real time single page application - client side

Introduction

In this two parts guide I will explain how to use backbone.js, node.js and socket.io (and many others libraries) to write a single page/real time application.
The guide's goal is to explain a system and I will not dive into details of every component, for this reason I suggest you to follow the links to get more informations.
The topic is quite hot, so let's get started !

First step: defining resources

This part is the most boring but it is very important.
In my application I should model every client server exchange using REST principles  (even though I will eventually use websockets instead of HTTP protocol).

Following these principles I need to define resources.
A resource is a well defined piece of information

Every resource should:
  • have an id (the URL)
  • be atomic (every exchange will be stateless)
A very important detail here is that resources don't need to match exactly with backend models (database schemas). For example a resource can be the result of a join between tables.

I will leave to node.js backend to manage the differences between the actual db models and resources.
The backend can update more than one model in a reliable way (and, in case, rolling back changes) while it's not so reliable do this directly from the client.

From this point when I talk about models in the client I am talking about an HTTP resources.

Client side

For the front end I will use backbone.js. This library's task is basically to organize homogeneous models (they are resources!) into collections and keep these data synchronized with the UI (view) and the backend.
This is a model:

var Item = Backbone.Model.extend({
    defaults: {
       "name": "",
       "description": "",
    },
    validate: function(attrs, options) {
        // return a string is attributes are wrong
    }
});

This is a simple collection:

var Items = Backbone.Collection.extend({
    model: Item,
    initialize: function (){
        //...
    }
});

This collection contains a group of Items.
A backbone collection usually has an url attribute that is used to download data from the server. So I'll rewrite the last collection:

var Items = Backbone.Collection.extend({
    url: "/items"
    model: Item,
    initialize: function (){
        //...
    }
});

Backbone.js uses AJAX by default to download and update collections. It uses the standard HTTP methods: GET POST PUT DELETE (optionally PATCH if supported).
If the collection's url is "/items" the single model urls will be "/items/model_id".

Backbone.IO

One of the nicest feature of Backbone.js is that you can use different ways to save your data (overwriting the Backbone.sync function).
In this example I will use backbone.io. This component sends data to the backend using a websocket or another available socket like transport (it uses socket.io under the hood).

Backbone.io.connect();

var Items = Backbone.Collection.extend({
    backend: 'items',
    model: Item,
    initialize: function (){
        this.bindBackend();        
        //...
    }
});

Backbone.io.connect is used to initialize websockets. I replaced the url attribute with a backend identifier.
I have also launched "bindBackend". This method connect backbone.io events to the collection events. So when the server broadcasts that something is changed the collection triggers the event and views are refreshed.

Views

Backbone.js main feature is to be unopinionated. Views, for example, are mostly boilerplate code. For this reason, you often need to build a more high level framework on top of it.
It is usually a good idea to use something like Marionette.
Anyway I tried to build something simpler. This is a model's view:

var ModelView = Backbone.View.extend({
    initialize: function (){
        this.initialEvents();
    },
    initialEvents: function (){
        if (this.model){
          this.listenTo(this.model, "change", this.render);
        }
    },
    serialize: function (){
        var attrs = _.clone(this.model.attributes);
        attrs.id = attrs[this.model.idAttribute];
        return attrs;
    },
    render: function (){
        this.preRender();
        this.$el.html(this.template(this.serialize()));
        this.postRender();
        return this;
    },
    preRender: function (){
        // this runs before the rendering
    },
    postRender: function (){
        // this runs after the rendering
    }
});

I also build a collection's view:

var CollectionView = Backbone.View.extend({
    contentSelector: '.append-item-here',
    // this is the class where I append the model views
    viewOptions: {},
    initialize: function (){
        this.children = {}; // this will contain the models views
        this.initialEvents();
    },
    initialEvents: function (){
        if (this.collection){
          this.listenTo(this.collection, "add", this.addChildView);
          this.listenTo(this.collection, "remove", this.removeChildView);
          this.listenTo(this.collection, "reset", this.render);
          this.listenTo(this.collection, "sort", this.render);
        }
    },   
    render: function (){
        var that = this;
        this.preRender();

        // I remove the old models views
        _.each(this.children, function (view){
            view.remove();
        });

        this.children = {};

        // I rebuild the models views
        this.collection.chain()
        .each(function(item, index){
            // every model view have a reference to its collection view
            var options = _.extend({index: index, parentView: that}, that.viewOptions);
            that.addChildView(item, that.collection, options);
        });

        this.postRender();
        return this;
    },
    // I can use this to filter some view if it is necessary
    filterView: function (model){
        return true;
    },
    addChildView: function (item, collection, options){
        // add a view to this.children trying to respect the sorting order
        var index;
        if (!this.filterView(item)){
            return;
        }
        options.model = item;
        if (options && options.index){
            index = options.index;
        }
        else {
            index = collection.chain().filter(this.filterView, this).indexOf(item).value();
            if (index === -1){
                index = 0;
            }
        }

        var view = new this.itemView(options);
        view.render();

        this.children[item.cid] = view;
        this.addToView(view, index);
        
    },
    removeChildView: function (item, collection, options){
        this.children[item.cid].remove();
        delete this.children[item.cid];
    },

    addToView: function (view, index){
        // append a model view to the collection view in the correct sorting order
        var $el = this.$el.find(this.contentSelector),
            $children = $el.children();
        if (index >= $children.length ){
            $el.append(view.el);
        }
        else {
            $children.eq(index).before(view.el);
        }
    },
    preRender: function (){
        // this runs before the rendering
    },
    postRender: function (){
        // this runs after the rendering
    }

});

Extending these base views I can write a very simple item view:

var ItemView = ModelView.extend({
    template: _.template(html_item),
    tagName: 'div',
    events: {
        //...
    }
});

and, of course, a very simple collection view:

var ItemsView =  CollectionView.extend({
    itemView: ItemView,
    el: $("#items"),
    events: {
        //...
    }
});

You should notice that I am using the underscore template engine (_.template).

Routing and bootstrapping

Backbone uses a router object to keep the state of your application. The state is represented by the current URL.

var Router = Backbone.Router.extend({

    routes: {
        "item/:id":        "changeitem",  // #item/id
    },
    changeitem: function(id) {
        // this is called when the URL is changed
    }
});

Like others backbone primitives you can react to an URL change handling an event (inside a view for example):

var ItemsView =  CollectionView.extend({
    itemView: ItemView,
    el: $("#items"),
    initialize: function (){
        this.listenTo(router, 'route:changeitem', this.update);
    },
    update: function (){
        // ...
    },
    events: {
        //...
    }
});

When every component is in place you can instance it and bootstrap the application.

var router = new Router(); // router instance
 
var items = new Items(); // collection instance
var itemsView = new ItemsView({collection: items}); // collection view instance
    
Backbone.history.start(); // this initialize the router

items.fetch(); // this loads initially the collection from the server

The fetch method is not your best option if you want to load models for the first time. It's better to load models inline.


I hope everything is clear. Next part: the server side!

Friday, April 26, 2013

Objects in HTML5 canvas (part 3: interacting with images)

This article is the third of a series of simple recipes that explains how to interact with objects in HTML5 canvas.
  • part 1 (Drawing shapes)
  • part 2 (Interacing with objects)
In this part we will solve the last problem: how to interact with objects with irregular shapes.

The simple answer is that you don't have to. You can wrap any image inside a rectangular box and detect where the image is transparent.

Introducing offscreen canvas

An offscreen canvas is a canvas outside the DOM. It's very useful for 2 reasons:
  • you can do complex drawing once and reuse the result with just an instruction
  • you can use it to check where an image is transparent

Let's draw

First of all I start with an images array (I used inline images, but you can use images urls):

var objs = [
    {name:'firefox',
     src:'data:image/png;base64,iVBORw0KGgoAAAA.....',
     x:30,
     y:50,
     angle:Math.PI/2,
     },
    {name:'opera',
     src:'data:image/png;base64,iVBORw0KGgoAAAA...',
     x:40,
     y:30,
     angle:Math.PI/4,
     },
    {name:'chrome',
     src:'data:image/png;base64,iVBORw0...',
     x:60,
     y:100,
     angle:-Math.PI/4,
     }
];

Then I draw each image inside an offscreen canvas and, then the offscreen canvas in the main canvas:

var i, obj;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (i = 0;i < objs.length;i++){
    obj = objs[i];
    (function (obj){
        var img = new Image();   // Creating a new img element
        img.onload = function(){
            // It's very important to wait until the image loads!!!
            // otherwise I have no clue of the real size of the image 
            ctx.save();

            ctx.translate(obj.x, obj.y);
            ctx.rotate(obj.angle);
            obj.width = img.width;
            obj.height = img.height;
            //I attach the offscreen canvas to the object
            obj.canvas = document.createElement("canvas");
            obj.canvas.width = img.width;
            obj.canvas.height = img.height;
            obj.ctx = obj.canvas.getContext('2d');
            // I draw the image on a off-screen canvas
            obj.ctx.drawImage(img, 0 , 0);
            // I draw the off-screen canvas on the main canvas
            ctx.drawImage(obj.canvas, -img.width/2 , -img.height/2);
            
            ctx.restore();
        };
        img.src = obj.src; // Set source path
    }(objs[i]));
}

Pay attention! I have applied transformations on the main canvas and not on each  off-screen canvases.

Detecting mouse clicks

Let's finish detecting on which shape a user is pointing. As usual I check each object in reverse order and transform pointer coordinates. Then I must retrieve the image from the offscreen canvas and test the color on the resulting coordinates. If the alpha value is opaque the pointer is on the image.

    // I get a single pixel
    imageData = obj.ctx.getImageData(p.x+(obj.width/2), p.y+(obj.height/2), 1, 1);
    // imageData contains r,g,b,a
    if(imageData.data[3] > 50){ // 50 is the threeshold
        log.innerHTML = 'clicked on ' + obj.name;
        return;
    }            

I have taken a pixel from the canvas using getImageData. This function returns  an array that include 4 values for each pixel (just one in my case).
The values are Red, Green, Blue and Alpha (transparency) and they have values between 0 and 255.
I set a threeshold of 50 on alpha.
This is the whole code:

canvas.addEventListener('click', function (evt){
    var rect = canvas.getBoundingClientRect(),
        posx = evt.clientX - rect.left,
        posy = evt.clientY - rect.top,
        i = objs.length,
        obj,p;
        for (; i > 0; i--){
            obj = objs[i-1];
            // translate coordinates
            p = new Point(posx, posy);
            p.translate(-obj.x, -obj.y);
            p.rotate(-obj.angle);

            imageData = obj.ctx.getImageData(p.x+(obj.width/2), p.y+(obj.height/2), 1, 1);

            if(imageData.data[3] > 50){
                log.innerHTML = 'clicked on ' + obj.name;
                return;
            }            
            
        }
        log.innerHTML = '';

}, false);


And this is the results:
  Your browser doesn't support canvas!


I hope this is helpful!