Mozilla

JavaScript Articles

Sort by:

View:

  1. Coordinate Conversion Made Easy – the power of GeometryUtils

    In a previous post we introduced the GeometryUtils interface and the getBoxQuads() API for retrieving the CSS box geometry of a DOM node. GeometryUtils also takes care of another important problem: converting coordinates reliably from one DOM node to another. For example, you might want to find the bounding-box of one element relative to another element, or you might want to convert event coordinates from the viewport to some arbitrary element.

    Existing APIs

    Until now, simple cases could be handled using getBoundingClientRect() and some math, but complex cases (e.g. involving CSS transforms) were almost impossible to handle using standard APIs. The nonstandard APIs webkitConvertPointToPage and webkitConvertPageToPoint are a big improvement, but apart from not being standardized, they’re not as powerful as they need to be. In particular it’s more convenient and more robust to provide an API for directly converting coordinates from one element to another.[1]

    New APIs

    GeometryUtils introduces three new methods for coordinate conversion:

    • to.convertPointFromNode(point, from) converts a a point relative to the top-left of the first border-box of “from” to a point relative to the top-left of the first border-box of “to”. The point is a DOMPointInit, which means you can pass a DOMPoint or a JS object such as {x:0, y:0}.
    • to.convertRectFromNode(rect, from) converts a a DOMRect relative to the top-left of the first border-box of “from” to a DOMQuad relative to the top-left of the first border-box of “to” by converting the vertices of the DOMRect. It converts to a DOMQuad to ensure that the result is accurate even if it needs to be rotated or skewed by CSS transforms.
    • to.convertQuadFromNode(quad, from) converts a DOMQuad from “from” to “to”. It’s just like convertRectFromNode except for taking a DOMQuad.

    As with getBoxQuads, a node can be an Element, TextNode or Document; when a Document is used, the coordinates are relative to the document’s viewport.

    Example:

    <div id="d" style="position:absolute; transform:rotate(45deg); left:100px; top:100px; width:100px; height:100px;"></div>
    <div id="e" style="position:absolute; left:100px; top:100px; width:100px; height:100px;"></div>
    var p1 = document.convertPointFromNode({
        x:0, y:0
      }, document.getElementById("e")
    );
    // p1.x == 100, p1.y == 100
     
    var p2 = document.convertPointFromNode({
        x:0, y:0
      }, document.getElementById("d")
    );
    // p2.x == 150, p2.y == 150 - 50*sqrt(2) (approx)
     
    p2 = document.getElementById("e").convertPointFromNode({
        x:0, y:0
      }, document.getElementById("d")
    );
    // p2.x == 50, p2.y == 50 - 50*sqrt(2) (approx)
     
    var q1 = document.convertRectFromNode(
      new DOMRect(0, 0, 50, 50), 
      document.getElementById("e")
    );
    // q1.p1.x == 100, q1.p1.y == 100
    // q1.p2.x == 150, q1.p2.y == 100
    // q1.p3.x == 150, q1.p3.y == 150
    // q1.p4.x == 100, q1.p4.y == 150
     
    var q2 = document.convertQuadFromNode(
      new DOMQuad({
        x:60, y:50
      }, {
        x:90, y:50
      }, {
        x:100, y:100
      }, {
        x:50, y:100
      }), 
      document.getElementById("e")
    );
    // q2.p1.x == 100, q2.p1.y == 100
    // q2.p2.x == 150, q2.p2.y == 100
    // q2.p3.x == 140, q2.p3.y == 150
    // q2.p4.x == 110, q2.p4.y == 150
    p1
    p2

    Sometimes it’s useful to convert to or from an element’s CSS content-box, padding-box or margin-box. This is supported via an optional ConvertCoordinateOptions dictionary with the following options:

    • fromBox: one of "content", "padding", "border" or "margin", selecting which CSS box of the first fragment of the from node the input point(s) are relative to.
    • toBox: selects which CSS box of the first fragment of the to node the returned point(s) are relative to.

    As a special case, this makes it easy to convert points between different
    CSS box types of the same element. For example, to convert a point from an
    element’s border-box to be relative to its content-box, use
    element.convertPointFromNode(point, element, {toBox:"content"}).

    Example:

    <div id="e" style="position:absolute; padding:20px; left:100px; top:100px; width:60px; height:60px;"></div>
    var p1 = document.convertPointFromNode({
        x:0, y:0
      }, document.getElementById("e"), 
      {fromBox:"content"}
    );
    // p1.x == 120, p1.y == 120
     
    p1 = document.getElementById("e").convertPointFromNode({
        x:120, y:120
      }, document,
      {toBox:"content"}
    );
    // p1.x == 0, p1.y == 0
     
    p1 = document.getElementById("e").convertPointFromNode({
        x:0, y:0
      }, document.getElementById("e"), 
      {fromBox:"content"}
    );
    // p1.x == 20, p1.y == 20
     
    p1 = document.getElementById("e").convertPointFromNode({
        x:20, y:20
      }, document.getElementById("e"), 
      {toBox:"content"}
    );
    // p1.x == 0, p1.y == 0
    p1
    e content-box
    e border-box

    These APIs are available in Firefox nightly builds and should be released in Firefox 31. Firefox is the first browser to implement these APIs.

    Footnote

    [1] Consider the following example:

    <div style="transform:scale(0)">
      <div id="a">...<>
      <div id="b">...<>
    </div>

    In this case, converting a point relative to a to be relative to b by converting first to page coordinates and then back to b doesn’t work, because the scale(0) maps every point in a to a single point in the page.

  2. Rormix – Discover Emerging Music Videos with Firefox OS

    Rormix is a platform for discovering emerging music videos. Music videos are tagged by genre and similar commercial artists, making it easy to discover new music videos.

    The Rormix app was made using PhoneGap and released on iOS and Android. Development took just over a month from the first line of code, to the app submissions in the app stores. The Firefox OS port took one developer just one day!

    Listed below are a few things we learnt along the way:

    What screen sizes am I developing for?

    When you develop an open web app you can install it in the actual desktop browser, the Android Firefox browser or Firefox OS devices.

    If you want to support all of them in one app, responsive designs are a must (you can also select just the platform you want to support). The current crop of Firefox OS phones have a resolution of 320×480. They have a pixel density of 1 so no special graphics need to be produced.

    Back Button?

    iOS devices don’t have a back button, Android devices have a hardware back button, so where does Firefox OS stand? It has a software back button that you can optionally hide or show when building the manifest for the app. The back button can be hidden at the bottom of the screen however it can be hard to press.

    I recommend that you build a back button into your app and hide the default one to make the app easier to navigate.

    //jQuery example
    $('.backbutton').click(function(){
        history.go(-1);
    });

    Stateful design

    As a back button has a presence in Firefox OS you need to build a stateful application in order to go back in state when the user presses the back button.
    A simple way to implement this is using one of the various JS frameworks that use fragment identifiers to load different states (e.g. Sammy JS).

    //jQuery example
     
    //Sammy app
    var app;
     
    $(function(){
     
        app = Sammy(function() {
            this.get('#/', function() {
                //Load default content
            });
            this.get('#/trending', function() {
                //Get trending content
            });
            this.get('#/fresh', function() {
                //Get fresh content
            });
        });
    });
     
    //Load the default content on app load
    app.run('#/');
     
     
    //Go to fresh content
    $('.freshbutton').click(function(){
        app.setLocation('#/fresh');
    });

    Creating a menu

    The trick with making menus for Firefox OS is to use CSS3 transforms for speed, but also making them simple enough to limit the redraw cycle when the menu comes into play. Firefox OS phones have the same width in reference pixels as all iPhones (at the time of writing), and the same pixel height as iPhones previous to the iPhone 5, so if you have a design that works for iOS then you’re all set.

    Adding some Firefox OS flavour

    There are a set of design guidelines that give you an idea of the colour scheme etc of the Firefox OS platform. They also detail how to make the icon for your app, the fonts used etc.

    Submitting your app

    When you have finished building your app you have a choice of how to submit it. You can package it up in a zip file:

    zip -r package.zip *

    You can send this zip to the Marketplace or you can host it yourself.

    The other option is to simply host the code as a web page (rather than zip it), and with a little extra JS prompt the user to download the app to their phone.

    Aside: Using PhoneGap / Cordova and HTML5

    Building web apps allows you to quickly and easily build cross platform apps. Even better, with responsive designs it can all be in one project. Advancing tools and workflows (Sass and Yeoman for example) makes developing apps even easier.

    PhoneGap / Cordova supports Firefox OS from version 3.4 (more information in Building Cordova apps for Firefox OS). The biggest advantage of using PhoneGap is that you only need to support a single codebase for all your apps. We all know some browsers have niggles, and PhoneGap has a built in merge mechanism that allows you to put platform specific code aside from the main code and it will merge them when building the app.

    PhoneGap also has a bunch of libraries for accessing native properties of the phone (native dialogue boxes for example) and this code is the same across all platforms, minimising duplicate code.

    The best thing about PhoneGap is the ability for you to create your own plugins, harnessing the power of mobile devices in a really easy way, effortlessly switching between JS and native mobile code.

    Contact:
    @pixelcodeUK

  3. Introducing the getBoxQuads API

    Web developers often need to determine where an element has been placed in the page, or more generally, where it is relative to another element. Existing APIs for doing this have significant limitations. The new GeometryUtils interface and its supporting interfaces DOMPoint, DOMRect and DOMQuad provide Web-standard APIs to address these problems. Firefox is the first browser to implement these APIs; they are available in Firefox 31 Nightly builds.

    Current best standardized APIs for retrieving element geometry

    Currently the best standardized DOM APIs for retrieving element geometry are element.getBoundingClientRect() and element.getClientRects(). These return the border-box rectangle(s) for an element relative to the viewport of the containing document. These APIs are supported cross-browser but have several limitations:

    • When complex CSS transforms are present, they return the smallest axis-aligned rectangle enclosing the transformed border-box. This loses information.
    • There is no way to obtain the coordinates of the content-box, padding-box or border-box. In simple cases you can add or subtract computed style values from the results of getBoundingClientRect()/getClientRects() but this is clumsy and difficult to get right. For example, when a <span> breaks into several fragments, its left border is only added to one of the fragments — either the first or the last, depending on the directionality of the text.
    • There is no way to obtain box geometry relative to another element.

    Introducing getBoxQuads()

    The GeometryUtils.getBoxQuads() method, implemented on Document, Element and TextNode, solves these problems. It returns a list of DOMQuads, one for each CSS fragment of the object (normally this list would just have a single
    DOMQuad).

    Example:

    <div id="d" 
      style="position:absolute; left:100px; top:100px; width:100px; height:100px;">
    </div>
    var quads = document.getElementById("d").getBoxQuads();
    // quads.length == 1
    // quads[0].p1.x == 100
    // quads[0].p1.y == 100
    // quads[0].p3.x == 200
    // quads[0].p3.y == 200
    p1
    p2
    p3
    p4

    Using bounds

    A DOMQuad is a collection of four DOMPoints defining the corners of an arbitrary quadrilateral. Returning DOMQuads lets getBoxQuads() return accurate information even when arbitrary 2D or 3D transforms are present. It has a handy bounds attribute returning a DOMRectReadOnly for those cases where you just want an axis-aligned bounding rectangle.

    For example:

    <div id="d" 
      style="transform:rotate(45deg); position:absolute; left:100px; top:100px; width:100px; height:100px;">
    </div>
    var quads = document.getElementById("d").getBoxQuads();
    // quads[0].p1.x == 150
    // quads[0].p1.y == 150 - 50*sqrt(2) (approx)
    // quads[0].p3.x == 150
    // quads[0].p3.y == 150 + 50*sqrt(2) (approx)
    // quads[0].bounds.width == 100*sqrt(2) (approx)
    p1
    p2
    p3
    p4
    bounds

    Passing in options

    By default getBoxQuads() returns border-boxes relative to the node’s document viewport, but this can be customized by passing in an optional
    options dictionary with the following (optional) members:

    • box: one of "content", "padding", "border" or "margin", selecting which CSS box type to return.
    • relativeTo: a Document, Element or TextNode; getBoxQuads() returns coordinates relative to the top-left of the border-box of that node (the border-box of the first fragment, if there’s more than one fragment). For documents, the origin of the document’s viewport is used.

    Example:

    <div id="d" 
      style="position:absolute; left:100px; top:100px; width:150px; height:150px;">
        <div id="e" 
          style="position:absolute; padding:20px; left:0; top:0; width:100px; height:100px;">
        </div>
    </div>
    var quads = document.getElementById("e").getBoxQuads({
      relativeTo:document.getElementById("d")
    });
    // quads[0].p1.x == 0
    // quads[0].p1.y == 0
     
    quads = document.getElementById("e").getBoxQuads({
      relativeTo:document.getElementById("d"), 
      box:"content"
    });
    // quads[0].p1.x == 20
    // quads[0].p1.y == 20
    d
    e content-box
    e border-box

    The relativeTo node need not be an ancestor of the node receiving getBoxQuads(). The nodes can even be in different documents, although they must be in the same toplevel browsing context (i.e. browser tab).

    Scratching the surface

    If you’ve read this far, you’re probably observant enough to have noticed additional methods in GeometryUtils — methods for coordinate conversion. These will be covered in a future blog post.

  4. Introducing the Canvas Debugger in Firefox Developer Tools

    The Canvas Debugger is a new tool we’ll be demoing at the Game Developers Conference in San Francisco. It’s a tool for debugging animation frames rendered on a Canvas element. Whether you’re creating a visualization, animation or debugging a game, this tool will help you understand and optimize your animation loop. It will let you debug either a WebGL or 2D Canvas context.

    Canvas Debugger Screenshot

    You can debug an animation using a traditional debugger, like our own JavaScript Debugger in Firefox’ Developer Tools. However, this can be difficult as it becomes a manual search for all of the various canvas methods you may wish to step through. The Canvas Debugger is designed to let you view the rendering calls from the perspective of the animation loop itself, giving you a much better overview of what’s happening.

    How it works

    The Canvas Debugger works by creating a snapshot of everything that happens while rendering a frame. It records all canvas context method calls. Each frame snapshot contains a list of context method calls and the associated JavaScript stack. By inspecting this stack, a developer can trace the call back to the higher level function invoked by the app or engine that caused something to be drawn.

    Certain types of Canvas context functions are highlighted to make them easier to spot in the snapshot. Quickly scrolling through the list, a developer can easily spot draw calls or redundant operations.

    Canvas Debugger Call Highlighting Detail

    Each draw call has an associated screenshot arranged in a timeline at the bottom of the screen as a “film-strip” view. You can “scrub” through this film-strip using a slider to quickly locate a draw call associated with a particular bit of rendering. You can also click a thumbnail to be taken directly to the associated draw call in the animation frame snapshot.

    Canvas Debugger Timeline Picture

    The thumbnail film-strip gives you get a quick overview of the drawing process. You can easily see how the scene is composed to get the final rendering.

    Stepping Around

    You might notice a familiar row of buttons in the attached screenshot. They’ve been borrowed from the JavaScript Debugger and provide the developer a means to navigate through the animation snapshot. These buttons may change their icons at final release, but for now, we’ll describe them as they currently look.

    Canvas Debugger Buttons image

    • “Resume” – Jump to the next draw call.
    • “Step Over” – Goes over the current context call.
    • “Step Out” – Jumps out of the animation frame (typically to the next requestAnimationFrame call).
    • “Step In” – Goes to the next non-context call in the JavaScript debugger

    Jumping to the JavaScript debugger by “stepping in” on a snapshot function call, or via a function’s stack, allows you to add a breakpoint and instantly pause if the animation is still running. Much convenience!

    Future Work

    We’re not done. We have some enhancements to make this tool even better.

    • Add the ability to inspect the context’s state at each method call. Highlight the differences in state between calls.
    • Measure Time spent in each draw call. This will readily show expensive canvas operations.
    • Make it easier to know which programs and shaders are currently in use at each draw call, allowing you to jump to the Shader Editor and tinkering with shaders in real time. Better linkage to the Shader Editor in general.
    • Inspecting Hit Regions by either drawing individual regions separately, colored differently by id, or showing the hit region id of a pixel when hovering over the preview panel using the mouse.

    And we’re just getting started. The Canvas Debugger should be landing in Firefox Nightly any day now. Watch this space for news of its landing and more updates.

  5. Flambe Provides Support For Firefox OS

    Flambe is a performant cross-platform open source game engine based on the Haxe programming language. Games are compiled to HTML5 or Flash and can be optimized for desktop or mobile browsers. The HTML5 Renderer uses WebGL, but provides fallback to the Canvas tag and functions nicely even on low-end phones. Flash Rendering uses Stage 3D and native Android and iOS apps are packaged using Adobe AIR.

    Flambe provides many other features, including:

    • simple asset loading
    • scene management
    • touch support
    • complete physics library
    • accelerometer access

    It has been used to create many of the Nickelodeon games available at nick.com/games and m.nick.com/games. To see other game examples, and some of the other well-known brands making use of the engine, have a look at the Flambe Showcase.

    In the last few weeks, the developers of the Flambe engine have been working to add support for Firefox OS. With the 4.0.0 release of Flambe, it is now possible to take Flambe games and package them into publication-ready Firefox OS applications, complete with manifest.

    Firefox Marketplace Games

    To get an idea of what is possible with the Flambe engine on the Firefox OS platform, take a look at two games that were submitted recently to the Firefox Marketplace. The first — The Firefly Game written by Mark Knol — features a firefly that must navigate through a flock of hungry birds. The game’s use of physics, sound and touch are very effective.
    firefly

    The second game, entitled Shoot’em Down, tests the player’s ability to dodge fire while shooting down as many enemy aircraft as possible. The game was written by Bruno Garcia, who is the main developer of the Flambe engine. The source for this game is available as one of the engine’s demo apps.
    shootemup

    Building a Firefox OS App using Flambe

    Before you can begin writing games using the Flambe engine, you will need to install and setup a few pieces of software:

    1. Haxe. Auto installers are available for OSX, Windows and Linux on the download page.
    2. Node.js for building projects. Version 0.8 or greater is required
    3. A Java runtime.

    Once those prerequisites are met, you can run the following command to install Flambe:

    # Linux and Mac may require sudo
    npm install -g flambe 
    flambe update

    This will install Flambe and you can begin writing apps with the engine.

    Create a Project

    To create a new project, run the following command.

    flambe new

    This will create a directory named whatever you supplied for ProjectName. In this directory you will have several files and other directories for configuring and coding your project. By default the new command creates a very simple project that illustrates loading and animating an image.

    A YAML (flambe.yaml) file within the project directory defines several characteristics of the project for build purposes. This file contains tags for developer, name and version of the app, and other project meta-data, such as description. In addition it contains the main class name that will be fired as the entry point to your application. This tag needs to be set to a fully qualified Haxe Class name. I.e., if you use a package name in your Haxe source file, you need to prepend the package name in this tag like this: packagename.Classname. (The default example uses urgame.Main.) You can also set the orientation for your app within the YAML file.

    Of specific note for Firefox OS developers, a section of the YAML file contains a partial manifest.webapp that can be altered. This data is merged into a complete manifest.webapp when the project is built.

    The main project folder also contains a directory for assets (images, sounds, animations, and particle effects files). The icons folder contains the icons that will be used with your app. The src folder contains the Haxe source code for your application.

    Build the Project

    Flambe provides a build method to compile your code to the appropriate output. To build the app run:

    flambe build <output>

    Where output is html, flash, android, ios, or firefox. Optionally you can add the –debug option to the build command, producing output more suitable for debugging. For Firefox OS this will produce non-minified JavaScript files. The build process will add a build directory to your application. Inside of the build directory a firefox directory will be created containing your Firefox OS app.

    Debug the Project

    You can debug your application in the Firefox App Manager. See Using the App Manager for details on installing and debugging using the App Manager. Within the App Manager you can add the built app using the Add Packaged App button and selecting the ProjectName/build/firefox directory. Debugging for other platforms is described in the Flambe documentation.
    appmanager
    The -debug option can provide additional insight for debugging and performance tuning. In addition to being able to step through the generated JavaScript, Flambe creates a source map that allows you to look look through the original Haxe files while debugging.
    debugsession
    To see the original Haxe files in the debugger, select the Debugger options icon in the far right corner of the debugger and choose Show Original Sources.
    sourcemap
    Also, when using the -debug option you can use a shortcut key (Ctrl + O) to initiate a view of your app that illustrates overdraw — this measures the number of times a pixel is being drawn in a frame. The brighter the pixel the more times it is being drawn. By reducing the amount of overdraw, you should be able to improve the performance of your game.
    overdraw

    A Bit about Haxe and Flambe

    Haxe is an object-oriented, class-based programing language that can be compiled to many other languages. In Flambe, your source code needs to be written using Haxe-specific syntax. Developers familiar with Java, C++ or JavaScript will find learning the language relatively straightforward. The Haxe website contains a reference guide that nicely documents the language. For editing, there are many options available for working with Haxe. I am using Sublime with the Haxe plugin.

    Flambe offers some additional classes that need to be used when building your app. To get a better understanding of these classes, let’s walk through the simple app that is created when you run the flambe new command. The Main.hx file created in the source directory contains the Haxe source code for the Main Class. It looks like this:

    package urgame;
     
    import flambe.Entity;
    import flambe.System;
    import flambe.asset.AssetPack;
    import flambe.asset.Manifest;
    import flambe.display.FillSprite;
    import flambe.display.ImageSprite;
     
    class Main
    {
      private static function main ()
      {
        // Wind up all platform-specific stuff
        System.init();
     
        // Load up the compiled pack in the assets directory named "bootstrap"
        var manifest = Manifest.fromAssets("bootstrap");
        var loader = System.loadAssetPack(manifest);
        loader.get(onSuccess);
      }
     
      private static function onSuccess (pack :AssetPack)
      {
        // Add a solid color background
        var background = new FillSprite(0x202020, System.stage.width, System.stage.height);
        System.root.addChild(new Entity().add(background));
     
        // Add a plane that moves along the screen
        var plane = new ImageSprite(pack.getTexture("plane"));
        plane.x._ = 30;
        plane.y.animateTo(200, 6);
        System.root.addChild(new Entity().add(plane));
      }
    }

    Haxe Packages and Classes

    The package keyword provides a way for classes and other Haxe data types to be grouped and addressed by other pieces of code, organized by directory. The import keyword is used to include classes and other Haxe types within the file you are working with. For example, import flambe.asset.Manifest will import the Manifest class, while import flambe.asset.* will import all types defined in the asset package. If you try to use a class that you have not imported into your code and run the build command, you will receive an error message stating that the particular class could not be found. All of the Flambe packages are documented on the Flambe website.

    Flambe Subsystem Setup and Entry point

    The main function is similar to other languages and acts as the entry point into your app. Flambe applications must have one main function and only one per application. In the main function the System.init() function is called to setup all the subsystems that will be needed by your code and the Flambe engine.

    Flambe Asset Management

    Flambe uses a dynamic asset management system that allows images, sound files, etc. to be loaded very simply. In this particular instance the fromAssets function defined in the Manifest class examines the bootstrap folder located in the assets directory to create a manifest of all the available files. The loadAssetPack System function creates an instance of the AssetPack based on this manifest. One of the functions of AssetPack is get, which takes a function parameter to call when the asset pack is loaded into memory. In the default example, the only asset is an image named plane.png.

    Flambe Entities and Components

    Flambe uses an abstract concept of Entities and Components to describe and manipulate game objects. An Entity is essentially just a game object with no defining characteristics. Components are characteristics that are attached to entities. For example an image component may be attached to an entity. Entities are also hierarchal and can be nested. For example, entity A can be created and an image could be attached to it. Entity B could then be created with a different image. Entity A could then be attached to the System root (top level Entity) and Entity B could then be attached to Entity A or the System root. The entity nest order is used for rendering order, which can be used to make sure smaller visible objects are not obscured by other game objects.

    Creating Entities and Components in the Sample App

    The onSuccess function in the default sample is called by the loader instance after the AssetPack is loaded. The function first creates an instance of a FillSprite Component, which is a rectangle defined by the size of the display viewport width and height. This rectangle is colored using the hex value defined in the first parameter. To actually have the FillSprite show up on the screen you first have to create an Entity and add the Component to it. The new Entity().add(background) method first creates the Entity and then adds the FillSprite Component. The entire viewport hierarchy starts at the System.root, so the addChild command adds this new Entity to the root. Note this is the first Entity added and it will be the first rendered. In this example this entity represents a dark background.

    Next the plane image is created. This is done by passing the loaded plane image to the ImageSprite Component constructor. Note that the AssetPack class’s getTexture method is being used to retrieve the loaded plane image. The AssetPack class contains methods for retrieving other types of Assets as well. For example, to retrieve and play a sound you would use pack.getSound("bounce").play();.

    Flambe Animated Data Types

    Flambe wraps many of the default Haxe data types in classes and introduces a few more. One of these is the AnimatedFloat class. This class essentially wraps a float and provides some utility functions that allow the float to be altered in a specific way. For example, one of the functions of the AnimatedFloat class is named animateTo, which takes parameters to specify the final float value and the time in which the animation will occur. Many components within the Flambe system use AnimatedFloats for property values. The plane that is loaded in the default application is an instance of the ImageSprite Component. Its x and y placement values are actually AnimatedFloats. AnimatedFloat values can be set directly but special syntax has to be used (value._).

    In the example, the x value for the ImageSprite is set to 30 using this syntax: plane.x._ = 30;. The y value for the ImageSprite is then animated to 200 over a 6 second period. The x and y values for an ImageSprite represent the upper left corner of the image when placed into the viewport. You can alter this using the centerAnchor function of the ImageSprite class. After this call, the x and y values will be in reference to the center of the image. While the default example does not do this, it could be done by calling plane.centerAnchor();. The final line of code just creates a new Entity, adds the plane Component to the Entity and then adds the new Entity to the root. Note that this is the second Entity added to the root and it will render after the background is rendered.

    Flambe Event Model

    Another area of Flambe that is important to understand is its event model. Flambe uses a signal system where the subsystems, Components and Entities have available signal properties that can be connected to in order to listen for a specific signal event. For example, resizing the screen fires a signal. This event can be hooked up using the following code.

    System.stage.resize.connect(function onResize() {
      //do something 
    });

    This is a very nice feature when dealing with other components within apps. For example, to do something when a user either clicks on or touches an ImageSprite within your app you would use the following code:

    //ImageSprite Component has pointerDown signal property
    myBasketBallEntity.get(ImageSprite).pointerDown.connect(function (event) {
        bounceBall();
    });

    In this case the pointerDown signal is fired when a user either uses a mouse down or touch gesture.

    Demo Apps

    The Flambe repository also contains many demo apps that can be used to further learn the mechanics and APIs for the engine. These demos have been tested on Firefox OS and perform very well. Pictured below are several screenshots taken on a Geeksphone Keon running Firefox OS.
    colla

    Of particular note in the demos are the physics and particles demos. The physics demo uses the Nape Haxe library and allows for some very cool environments. The Nape website contains documentation for all the packages available. To use this library you need to run the following command:

    haxelib install nape

    The particle demo illustrates using particle descriptions defined in a PEX file within a Flambe-based game. PEX files can be defined using a particle editor, like Particle Designer.

    Wrapping Up

    If you are a current Flambe game developer with one or more existing games, why not use the new version of the engine to compile and package them for Firefox OS? If you are a Firefox OS developer and are looking for a great way to develop new games for the platform, Flambe offers an excellent means for developing engaging, performant games for Firefox OS–and many other platforms besides!

    And, if you are interested in contributing to Flambe, we’d love to hear from you as well.

  6. The Making of the Time Out Firefox OS app

    A rash start into adventure

    So we told our client that yes, of course, we would do their Firefox OS app. We didn’t know much about FFOS at the time. But, hey, we had just completed refactoring their native iOS and Android apps. Web applications were our core business all along. So what was to be feared?

    More than we thought, it turned out. Some of the dragons along the way we fought and defeated ourselves. At times we feared that we wouldn’t be able to rescue the princess in time (i.e. before MWC 2013). But whenever we got really lost in detail forest, the brave knights from Mozilla came to our rescue. In the end, it all turned out well and the team lived happily ever after.

    But here’s the full story:

    Mission & challenge

    Just like their iOS and Android apps, Time Out‘s new Firefox OS app was supposed to allow browsing their rich content on bars, restaurants, things to do and more by category, area, proximity or keyword search, patient zero being Barcelona. We would need to show results as illustrated lists as well as visually on a map and have a decent detail view, complete with ratings, access details, phone button and social tools.

    But most importantly, and in addition to what the native apps did, this app was supposed to do all of that even when offline.

    Oh, and there needed to be a presentable, working prototype in four weeks time.

    Cross-platform reusability of the code as a mobile website or as the base of HTML5 apps on other mobile platforms was clearly prio 2 but still to be kept in mind.

    The princess was clearly in danger. So we arrested everyone on the floor that could possibly be of help and locked them into a room to get the basics sorted out. It quickly emerged that the main architectural challenges were that

    • we had a lot of things to store on the phone, including the app itself, a full street-level map of Barcelona, and Time Out’s information on every venue in town (text, images, position & meta info),
    • at least some of this would need to be loaded from within the app; once initially and synchronizable later,
    • the app would need to remain interactively usable during these potentially lengthy downloads, so they’d need to be asynchronous,
    • whenever the browser location changed, this would be interrupted

    In effect, all the different functionalities would have to live within one single HTML document.

    One document plus hash tags

    For dynamically rendering, changing and moving content around as required in a one-page-does-all scenario, JavaScript alone didn’t seem like a wise choice. We’d been warned that Firefox OS was going to roll out on a mix of devices including the very low cost class, so it was clear that fancy transitions of entire full-screen contents couldn’t be orchestrated through JS loops if they were to happen smoothly.

    On the plus side, there was no need for JS-based presentation mechanics. With Firefox OS not bringing any graveyard of half-dead legacy versions to cater to, we could (finally!) rely on HTML5 and CSS3 alone and without fallbacks. Even beyond FFOS, the quick update cycles in the mobile environment didn’t seem to block the path for taking a pure CSS3 approach further to more platforms later.

    That much being clear, which better place to look for best practice examples than Mozilla Hacks? After some digging, Thomas found Hacking Firefox OS in which Luca Greco describes the use of fragment identifiers (aka hashtags) appended to the URL to switch and transition content via CSS alone, which we happily adopted.

    Another valuable source of ideas was a list of GAIA building blocks on Mozilla’s website, which has since been replaced by the even more useful Building Firefox OS site.

    In effect, we ended up thinking in terms of screens. Each physically a <div>, whose visibility and transitions are governed by :target CSS selectors that draw on the browser location’s hashtag. Luckily, there’s also the onHashChange event that we could additionally listen to in order to handle the app-level aspects of such screen changes in JavaScript.

    Our main HTML and CSS structure hence looked like this:

    And a menu

    We modeled the drawer menu very similarily, just that it sits in a <nav> element on the same level as the <section> container holding all the screens. Its activation and deactivation works by catching the menu icon clicks, then actively changing the screen container’s data-state attribute from JS, which triggers the corresponding CSS3 slide-in / slide-out transition (of the screen container, revealing the menu beneath).

    This served as our “Hello, World!” test for CSS3-based UI performance on low-end devices, plus as a test case for combining presentation-level CSS3 automation with app-level explicit status handling. We took down a “yes” for both.

    UI

    By the time we had put together a dummy around these concepts, the first design mockups from Time Out came in so that we could start to implement the front end and think about connecting it to the data sources.

    For presentation, we tried hard to keep the HTML and CSS to the absolute minimum. Mozilla’s GAIA examples being a very valuable source of ideas once more.

    Again, targeting Firefox OS alone allowed us to break free of the backwards compatibility hell that we were still living in, desktop-wise. No one would ask us Will it display well in IE8? or worse things. We could finally use real <section>, <nav>, <header>, and <menu> tags instead of an army of different classes of <div>. What a relief!

    The clear, rectangular, flat and minimalistic design we got from Time Out also did its part to keep the UI HTML simple and clean. After we were done with creating and styling the UI for 15 screens, our HTML had only ~250 lines. We later improved that to 150 while extending the functionality, but that’s a different story.

    Speaking of styling, not everything that had looked good on desktop Firefox even in its responsive design view displayed equally well on actual mobile devices. Some things that we fought with and won:

    Scale: The app looked quite different when viewed on the reference device (a TurkCell branded ZTE device that Mozilla had sent us for testing) and on our brand new Nexus 4s:

    After a lot of experimenting, tearing some hair and looking around how others had addressed graceful, proportional scaling for a consistent look & feel across resolutions, we stumbled upon this magic incantation:

    <meta name="viewport" content="user-scalable=no, initial-scale=1,
    maximum-scale=1, width=device-width" />

    What it does, to quote an article at Opera, is to tell the browser that there is “No scaling needed, thank you very much. Just make the viewport as many pixels wide as the device screen width”. It also prevents accidental scaling while the map is zoomed. There is more information on the topic at MDN.

    Then there are things that necessarily get pixelated when scaled up to high resolutions, such as the API based venue images. Not a lot we could do about that. But we could at least make the icons and logo in the app’s chrome look nice in any resolution by transforming them to SVG.

    Another issue on mobile devices was that users have to touch the content in order to scroll it, so we wanted to prevent the automatic highlighting that comes with that:

    li, a, span, button, div
    {
        outline:none;
        -moz-tap-highlight-color: transparent;
        -moz-user-select: none;
        -moz-user-focus:ignore
    }

    We’ve since been warned that suppressing the default highlighting can be an issue in terms of accessibility, so you might wanted to consider this carefully.

    Connecting to the live data sources

    So now we had the app’s presentational base structure and the UI HTML / CSS in place. It all looked nice with dummy data, but it was still dead.

    Trouble with bringing it to life was that Time Out was in the middle of a big project to replace its legacy API with a modern Graffiti based service and thus had little bandwidth for catering to our project’s specific needs. The new scheme was still prototypical and quickly evolving, so we couldn’t build against it.

    The legacy construct already comprised a proxy that wrapped the raw API into something more suitable for consumption by their iOS and Android apps, but after close examination we found that we better re-re-wrap that on the fly in PHP for a couple of purposes:

    • Adding CORS support to avoid XSS issues, with the API and the app living in different subdomains of timeout.com,
    • stripping API output down to what the FFOS app really needed, which we could see would reduce bandwidth and increase speed by magnitude,
    • laying the foundation for harvesting of API based data for offline use, which we already knew we’d need to do later

    As an alternative to server-side CORS support, one could also think of using the SystemXHR API. It is a mighty and potentially dangerous tool however. We also wanted to avoid any needless dependency on FFOS-only APIs.

    So while the approach wasn’t exactly future proof, it helped us a lot to get to results quickly, because the endpoints that the app was calling were entirely of our own choice and making, so that we could adapt them as needed without time loss in communication.

    Populating content elements

    For all things dynamic and API-driven, we used the same approach at making it visible in the app:

    • Have a simple, minimalistic, empty, hidden, singleton HTML template,
    • clone that template (N-fold for repeated elements),
    • ID and fill the clone(s) with API based content.
    • For super simple elements, such as <li>s, save the cloning and whip up the HTML on the fly while filling.

    As an example, let’s consider the filters for finding venues. Cuisine is a suitable filter for restaurants, but certainly not for museums. Same is true for filter values. There are vegetarian restaurants in Barcelona, but certainly no vegetarian bars. So the filter names and lists of possible values need to be asked of the API after the venue type is selected.

    In the UI, the collapsible category filter for bars & pubs looks like this:

    The template for one filter is a direct child of the one and only

    <div id="templateContainer">

    which serves as our central template repository for everything cloned and filled at runtime and whose only interesting property is being invisible. Inside it, the template for search filters is:

    <div id="filterBoxTemplate">
      <span></span>
      <ul></ul>
    </div>

    So for each filter that we get for any given category, all we had to do was to clone, label, and then fill this template:

    $('#filterBoxTemplate').clone().attr('id', filterItem.id).appendTo(
    '#categoryResultScreen .filter-container');
    ...
    $("#" + filterItem.id).children('.filter-button').html(
    filterItem.name);

    As you certainly guessed, we then had to to call the API once again for each filter in order to learn about its possible values, which were then rendered into <li> elements within the filter‘s <ul> on the fly:

    $("#" + filterId).children('.filter_options').html(
    '<li><span>Loading ...</span></li>');
    
    apiClient.call(filterItem.api_method, function (filterOptions)
    {
      ...
      $.each(filterOptions, function(key, option)
      {
        var entry = $('<li filterId="' + option.id + '"><span>'
          + option.name + '</span></li>');
    
        if (selectedOptionId && selectedOptionId == filterOptionId)
        {
          entry.addClass('filter-selected');
        }
    
        $("#" + filterId).children('.filter_options').append(entry);
      });
    ...
    });

    DOM based caching

    To save bandwidth and increase responsiveness in on-line use, we took this simple approach a little further and consciously stored more application level information in the DOM than needed for the current display if that information was likely needed in the next step. This way, we’d have easy and quick local access to it without calling – and waiting for – the API again.

    The technical way we did so was a funny hack. Let’s look at the transition from the search result list to the venue detail view to illustrate:

    As for the filters above, the screen class for the detailView has an init() method that populates the DOM structure based on API input as encapsulated on the application level. The trick now is, while rendering the search result list, to register anonymous click handlers for each of its rows, which – JavaScript passing magic – contain a copy of, rather than a reference to, the venue objects used to render the rows themselves:

    renderItems: function (itemArray)
    {
      ...
    
      $.each(itemArray, function(key, itemData)
      {        
        var item = screen.dom.resultRowTemplate.clone().attr('id', 
          itemData.uid).addClass('venueinfo').click(function()
        {
          $('#mapScreen').hide();
          screen.showDetails(itemData);
        });
    
        $('.result-name', item).text(itemData.name);
        $('.result-type-label', item).text(itemData.section);
        $('.result-type', item).text(itemData.subSection);
    
        ...
    
        listContainer.append(item);
      });
    },
    
    ...
    
    showDetails: function (venue)
    {
      require(['screen/detailView'], function (detailView)
      {
        detailView.init(venue);
      });
    },

    In effect, there’s a copy of the data for rendering each venue’s detail view stored in the DOM. But neither in hidden elements nor in custom attributes of the node object, but rather conveniently in each of the anonymous pass-by-value-based click event handlers for the result list rows, with the added benefit that they don’t need to be explicitly read again but actively feed themselves into the venue details screen as soon a row receives a touch event.

    And dummy feeds

    Finishing the app before MWC 2013 was pretty much a race against time, both for us and for Time Out’s API folks, who had an entirely different and equally – if not more so – sportive thing to do. Therefore they had very limited time for adding to the (legacy) API that we were building against. For one data feed, this meant that we had to resort to including static JSON files into the app’s manifest and distribution; then use relative, self-referencing URLs as fake API endpoints. The illustrated list of top venues on the app’s main screen was driven this way.

    Not exactly nice, but much better than throwing static content into the HTML! Also, it kept the display code already fit for switching to the dynamic data source that eventually materialized later, and compatible with our offline data caching strategy.

    As the lack of live data on top venues then extended right to their teaser images, we made the latter physically part of the JSON dummy feed. In Base64 :) But even the low-end reference device did a graceful job of handling this huge load of ASCII garbage.

    State preservation

    We had a whopping 5M of local storage to spam, and different plans already (as well as much higher needs) for storing the map and application data for offline use. So what to do with this liberal and easily accessed storage location? We thought we could at least preserve the current application state here, so you’d find the app exactly as you left it when you returned to it.

    Map

    A city guide is the very showcase of an app that’s not only geo aware but geo centric. Maps fit for quick rendering and interaction in both online and offline use were naturally a paramount requirement.

    After looking around what was available, we decided to go with Leaflet, a free, easy to integrate, mobile friendly JavaScript library. It proved to be really flexible with respect to both behaviour and map sources.

    With its support for pinching, panning and graceful touch handling plus a clean and easy API, Leaflet made us arrive at a well-usable, decent-looking map with moderate effort and little pain:

    For a different project, we later rendered the OSM vector data for most of Europe into terabytes of PNG tiles in cloud storage using on-demand cloud power. Which we’d recommend as an approach if there’s a good reason not to rely on 3rd party hosted apps, as long as you don’t try this at home; Moving the tiles may well be slower and more costly than their generation.

    But as time was tight before the initial release of this app, we just – legally and cautiously(!) – scraped ready-to use OSM tiles off MapQuest.com.

    The packaging of the tiles for offline use was rather easy for Barcelona because about 1000 map tiles are sufficient to cover the whole city area up to street level (zoom level 16). So we could add each tile as a single line into the manifest.appache file. The resulting, fully automatic, browser-based download on first use was only 10M.

    This left us with a lot of lines like

    /mobile/maps/barcelona/15/16575/12234.png
    /mobile/maps/barcelona/15/16575/12235.png
    ...

    in the manifest and wishing for a $GENERATE clause as for DNS zone files.

    As convenient as it may seem to throw all your offline dependencies’ locations into a single file and just expect them to be available as a consequence, there are significant drawbacks to this approach. The article Application Cache is a Douchebag by Jake Archibald summarizes them and some help is given at Html5Rocks by Eric Bidleman.

    We found at the time that the degree of control over the current download state, and the process of resuming the app cache load in case that the initial time users spent in our app didn’t suffice for that to complete was rather tiresome.

    For Barcelona, we resorted to marking the cache state as dirty in Local Storage and clearing that flag only after we received the updateready event of the window.applicationCache object but in the later generalization to more cities, we moved the map away from the app cache altogether.

    Offline storage

    The first step towards offline-readiness was obviously to know if the device was online or offline, so we’d be able to switch the data source between live and local.

    This sounds easier than it was. Even with cross-platform considerations aside, neither the online state property (window.navigator.onLine), the events fired on the <body> element for state changes (“online” and “offline”, again on the <body>), nor the navigator.connection object that was supposed to have the on/offline state plus bandwidth and more, really turned out reliable enough.

    Standardization is still ongoing around all of the above, and some implementations are labeled as experimental for a good reason :)

    We ultimately ended up writing a NetworkStateService class that uses all of the above as hints, but ultimately and very pragmatically convinces itself with regular HEAD requests to a known live URL that no event went missing and the state is correct.

    That settled, we still needed to make the app work in offline mode. In terms of storage opportunities, we were looking at:

    Storage Capacity Updates Access Typical use
    App / app cache, i.e. everything listed in the file that the value of appcache_path in the app‘s webapp.manifest points to, and which is and therefore downloaded onto the device when the app is installed. <= 50M. On other platforms (e.g. iOS/Safari), user interaction required from 10M+. Recommendation from Moziila was to stay <2M. Hard. Requires user interaction / consent, and only wholesale update of entire app possible. By (relative) path HTML, JS, CSS, static assets such as UI icons
    LocalStorage 5M on UTF8-platforms such as FFOS, 2.5M in UTF16, e.g. on Chrome. Details here Anytime from app By name Key-value storage of app status, user input, or entire data of modest apps
    Device Storage (often SD card) Limited only by hardware Anytime from app (unless mounted as UDB drive when cionnected to desktop computer) By path, through Device Storage API Big things
    FileSystem API Bad idea
    Database Unlimited on FFOS. Mileage on other platforms varies Anytime from app Quick and by arbitrary properties Databases :)

    Some aspects of where to store the data for offline operation were decided upon easily, others not so much:

    • the app, i.e. the HTML, JS, CSS, and UI images would go into the app cache
    • state would be maintained in Local Storage
    • map tiles again in the app cache. Which was a rather dumb decision, as we learned later. Barcelona up to zoom level 16 was 10M, but later cities were different. London was >200M and even reduced to max. zoom 15 still worth 61M. So we moved that to Device Storage and added an actively managed download process for later releases.
    • The venue information, i.e. all the names, locations, images, reviews, details, showtimes etc. of the places that Time Out shows in Barcelona. Seeing that we needed lots of space, efficient and arbitrary access plus dynamic updates, this had to to go into the Database. But how?

    The state of affairs across the different mobile HTML5 platforms was confusing at best, with Firefox OS already supporting IndexedDB, but Safari and Chrome (considering earlier versions up to Android 2.x) still relying on a swamp of similar but different sqlite / WebSQL variations.

    So we cried for help and received it, as always when we had reached out to the Mozilla team. This time in the form of a pointer to pouchDB, a JS-based DB layer that at the same time wraps away the different native DB storage engines behind a CouchDB-like interface and adds super easy on-demand synchronization to a remote CouchDB-hosted master DB out there.

    Back last year it still was in pre-alpha state but very usable already. There were some drawbacks, such as the need for adding a shim for WebSql based platforms. Which in turn meant we couldn’t rely on storage being 8 bit clean, so that we had to base64 our binaries, most of all the venue images. Not exactly pouchDB’s fault, but still blowing up the size.

    Harvesting

    The DB platform being chosen, we next had to think how we’d harvest all the venue data from Time Out’s API into the DB. There were a couple of endpoints at our disposal. The most promising for this task was proximity search with no category or other restrictions applied, as we thought it would let us harvest a given city square by square.

    Trouble with distance metrics however being that they produce circles rather than squares. So step 1 of our thinking would miss venues in the corners of our theoretical grid

    while extending the radius to (half the) the grid’s diagonal, would produce redundant hits and necessitate deduplication.

    In the end, we simply searched by proximity to a city center location, paginating through the result indefinitely, so that we could be sure to to encounter every venue, and only once:

    Technically, we built the harvester in PHP as an extension to the CORS-enabled, result-reducing API proxy for live operation that was already in place. It fed the venue information in to the master CouchDB co-hosted there.

    Time left before MWC 2013 getting tight, we didn’t spend much time on a sophisticated data organization and just pushed the venue information into the DB as one table per category, one row per venue, indexed by location.

    This allowed us to support category based and area / proximity based (map and list) browsing. We developed an idea how offline keyword search might be made possible, but it never came to that. So the app simply removes the search icon when it goes offline, and puts it back when it has live connectivity again.

    Overall, the app now

    • supported live operation out of box,
    • checked its synchronization state to the remote master DB on startup,
    • asked, if needed, permission to make the big (initial or update) download,
    • supported all use cases but keyword search when offline.

    The involved components and their interactions are summarized in this diagram:

    Organizing vs. Optimizing the code

    For the development of the app, we maintained the code in a well-structured and extensive source tree, with e.g. each JavaScript class residing in a file of its own. Part of the source tree is shown below:

    This was, however, not ideal for deployment of the app, especially as a hosted Firefox OS app or mobile web site, where download would be the faster, the fewer and smaller files we had.

    Here, Require.js came to our rescue.

    It provides a very elegant way of smart and asynchronous requirement handling (AMD), but more importantly for our purpose, comes with an optimizer that minifies and combines the JS and CSS source into one file each:

    To enable asynchronous dependency management, modules and their requirements must be made known to the AMD API through declarations, essentially of a function that returns the constructor for the class you’re defining.

    Applied to the search result screen of our application, this looks like this:

    define
    (
      // new class being definied
      'screensSearchResultScreen',
    
      // its dependencies
      ['screens/abstractResultScreen', 'app/applicationController'],
    
      // its anonymous constructor
      function (AbstractResultScreen, ApplicationController)
      {
        var SearchResultScreen = $.extend(true, {}, AbstractResultScreen,
        {
          // properties and methods
          dom:
          {
            resultRowTemplate: $('#searchResultRowTemplate'),
            list: $('#search-result-screen-inner-list'),
            ...
          }
          ...
        }
        ...
    
        return SearchResultScreen;
      }
    );

    For executing the optimization step in the build & deployment process, we used Rhino, Mozilla’s Java-based JavaScript engine:

    java -classpath ./lib/js.jar:./lib/compiler.jar   
      org.mozilla.javascript.tools.shell.Main ./lib/r.js -o /tmp/timeout-webapp/
      $1_config.js

    CSS bundling and minification is supported, too, and requires just another call with a different config.

    Outcome

    Four weeks had been a very tight timeline to start with, and we had completely underestimated the intricacies of taking HTML5 to a mobile and offline-enabled context, and wrapping up the result as a Marketplace-ready Firefox OS app.

    Debugging capabilities in Firefox OS, especially on the devices themselves, were still at an early stage (compared to clicking about:app-manager today). So the lights in our Cologne office remained lit until pretty late then.

    Having built the app with a clear separation between functionality and presentation also turned out a wise choice when a week before T0 new mock-ups for most of the front end came in :)

    But it was great and exciting fun, we learned a lot in the process, and ended up with some very useful shiny new tools in our box. Often based on pointers from the super helpful team at Mozilla.

    Truth be told, we had started into the project with mixed expectations as to how close to the native app experience we could get. We came back fully convinced and eager for more.

    In the end, we made the deadline and as a fellow hacker you can probably imagine our relief. The app finally even received its 70 seconds of fame, when Jay Sullivan shortly demoed it at Mozilla’s MWC 2013 press conference as a showcase for HTML5′s and Firefox OS’s offline readiness (Time Out piece at 7:50). We were so proud!

    If you want to play with it, you can find the app in the marketplace or go ahead try it online (no offline mode then).

    Since then, the Time Out Firefox OS app has continued to evolve, and we as a team have used the chance to continue to play with and build apps for FFOS. To some degree, the reusable part of this has become a framework in the meantime, but that’s a story for another day..

    We’d like to thank everyone who helped us along the way, especially Taylor Wescoatt, Sophie Lewis and Dave Cook from Time Out, Desigan Chinniah and Harald Kirschner from Mozilla, who were always there when we needed help, and of course Robert Nyman, who patiently coached us through writing this up.

  7. Ember.JS – What it is and why we need to care about it

    This is a guest post by Sourav Lahoti and his thoughts about Ember.js

    Developers increasingly turn to client-side frameworks to simplify development, and there’s a big need for good ones in this area. We see a lot of players in this field, but for lots of functionality and moving parts, very few stand out in particular — Ember.js is one of them.

    So what is Ember.js? Ember.js is a MVC (Model–View–Controller) JavaScript framework which is maintained by the Ember Core Team (including Tom Dale, Yehuda Katz, and others). It helps developers create ambitious single-page web applications that don’t sacrifice what makes the web great: URI semantics, RESTful architecture, and the write-once, run-anywhere trio of HTML, CSS, and JavaScript.

    Why do we need to care

    Ember.js is tightly coupled with the technologies that make up the web today. It doesn’t attempt to abstract that away. Ember.js brings a clean and consistent application development model. If one needs to migrate from HTML to any other technology, Ember.js framework will evolve along with the current trends in web front end technology.

    It makes it very easy to create your own “component” and “template views” that are easy to understand, create and update. Coupled with its consistent way of managing bindings and computed properties, Ember.js does indeed offer much of the boilerplate code that a web framework needs.

    The core concept

    There are some nominal terms that you will find very common when you use ember.js and they form the basics of Ember.js:

    Routes
    A Route object basically represents the state of the application and corresponds to a url.
    Models
    Every route has an associated Model object, containing the data associated with the current state of the application.
    Controllers
    Controllers are used to decorate models with display logic.

    A controller typically inherits from ObjectController if the template is associated with a single model record, or an ArrayController if the template is associated with a list of records.

    Views
    Views are used to add sophisticated handling of user events to templates or to add reusable behavior to a template.
    Components
    Components are a specialized view for creating custom elements that can be easily reused in templates.

    Hands-on with Ember.js

    Data Binding:

    <script type=”text/x-handlebars”>
      <p>
        <label>Insert your name:</label>
        {{input type=”text” value=name}}
      </p>
     
      <p><strong>Echo: {{name}}</strong></p>
    </script>
    App = Ember.Application.create();

    Final result when the user interacts with the web app

    Ember.js does support data binding as we can see in the above example. What we type into the input is bound to name, as is the text after Echo: . When you change the text in one place, it automatically updates everywhere.

    But how does this happen? Ember.js uses Handlebars for two-way data binding. Templates written in handlebars get and set data from their controller. Every time we type something in our input, the name property of our controller is updated. Then, automatically, the template is updated because the bound data changed.

    A simple Visiting card demo using Handlebars

    We can create our own elements by using Handlebars.

    HTML

    <script type="text/x-handlebars">
     
      {{v-card myname=name street-address=address locality=city zip=zipCode email=email}}
     
      <h2 class="subheader">Enter Your information:</h2>
     
      <label>Enter Your Name:</label>
      {{input type="text" value=name}}
     
      <label>Enter Your Address:</label>
      {{input type="text" value=address}}
     
      <label>Enter Your City:</label>
      {{input type="text" value=city}}
     
      <label>Enter Your Zip Code:</label>
      {{input type="text" value=zipCode}}
     
      <label>Enter Your Email address:</label>
      {{input type="text" value=email}}
     
    </script>
     
    <script type="text/x-handlebars" data-template-name="components/v-card">
     
      <ul class="vcard">
        <li class="myname">{{myname}}</li>
        <li class="street-address">{{street-address}}</li>
        <li class="locality">{{locality}}</li>
        <li><span class="state">{{usState}}</span>, <span class="zip">{{zip}}</span></li>
        <li class="email">{{email}}</li>
      </ul>
     
    </script>

    CSS

    .vcard {
      border: 1px solid #dcdcdc;
      max-width: 12em;
      padding: 0.5em;
    }
     
    .vcard li {
      list-style: none;
    }
     
    .vcard .name {
      font-weight: bold;
    }
     
    .vcard .email {
      font-family: monospace;
    }
     
    label {
      display: block;
      margin-top: 0.5em;
    }

    JavaScript

    App = Ember.Application.create();
     
    App.ApplicationController = Ember.Controller.extend({
        name: 'Sourav',
        address: '123 M.G Road.',
        city: 'Kolkata',
        zipCode: '712248',
        email: 'me@me.com'
    });

    The component is defined by opening a new <script type="text/x-handlebars">, and setting its template name using the data-template-name attribute to be components/[NAME].

    We should note that the web components specification requires the name to have a dash in it in order to separate it from existing HTML tags.

    There is much more to it, I have just touched the surface. For more information, feel free to check out the Ember.js Guides.

  8. JavaScriptOO.com, to find what meets your JavaScript needs

    The JavaScript Renaissance

    We all know the major players in JavaScript projects. MV* frameworks like AngularJS, Backbone, and Ember.js are inspiring a whole new breed of client applications. Utility libraries like underscore and lodash simplify constructs once reserved for academic exercise. And of course, the monolithic namespace jQuery is everywhere. The large teams and growing communities behind these projects (a little corporate backing never hurts) are moving forward and providing very solid platforms for developers to build upon. However, they are merely a precursor for the renaissance that is happening in the world of JavaScript right now.

    Enter the micro-libraries, the drop-in replacements, and the “I-Had-No-Idea-JS-Could-Do-That” projects. Thanks to tooling like Grunt, bower, and npm, testing suites like Jasmine and QUnit, and of course the social coding site github; dozens of peer-reviewed and test-driven JavaScript libraries are sprouting up every day. Fresh approaches on everything from the core JavaScript functionality to abstractions of the ridiculously complex are in abundance and expanding the very foundation of the web.

    VerbalExpression lets you write regular expressions in English; Knwl.js is a natural language processor; 140medley is an entire framework in 821 bytes. Want a DOM selector engine other than sizzle? Try micro-selector, nut, zest, qwery, Sly, or Satisfy. Need a templating engine? Try T-Lite, Grips, gloomy, Transparency, dust, hogan.js, Tempo, Plates, Mold, shorttag, doT.js, t.js, Milk, or at least 10 others. Dates got you down? Check out Date-Utils, moment.js, datejs, an.hour.ago, time.js. Route with Pilot, filter images with CamanJS, write games in Crafty, or make a presentation with RevealJS or impress.js.

    Of course, along with this prolific creativity in the JS universe comes some serious overload. A bit of natural selection will eventually get the best of these projects on your radar, but if you want to see the really exciting bits of evolution occurring you have to watch. Constantly.

    JavaScriptOO.com

    Watching constantly is exactly what I do with JavaScriptOO.com. I watch, I lurk, I read, and eventually I find something that really inspires me.

    The elevator pitch for the site is that it is a directory of JavaScript libraries with examples, CDN links, statistics, and sometimes videos about each library.

    Behind the scenes, after sifting through github, twitter, hacker news, pineapple, and an endless stream of sites and finding something exciting, I begin the slow process of adding a library to the site. Slow is a relative term, but for me, in this context, it means anywhere from 30 minutes to a few days. Adding a library to the site is a purposefully manual process that requires I actually spend some time with the library, writing an example for it, categorizing it as best I can, and sometimes even creating a video about it.

    This slow process is a huge bottleneck for updates on JSOO, and boy, do I hear about it. However, it also keeps the site from becoming just a directory of github links and it keeps the single curator excited about maintaining the site.

    Examples and submitting your library

    There are currently 401 405 409 examples on the site… almost one for every day it has been online. There are 79 libraries in the “Needed Examples” section where visitors can submit a gist or fiddle for that library and are encouraged to “include your Twitter handle or any other marketing you may like to, but keep it simple”. Lastly, there is a section for submitting your own library. Not all libraries submitted are added to the site, but they are given immediate priority, and if they are a fit, added to the queue. There is no editorial, no blog, no opinion at all other than hoping every visitor feels like this:

    Beyond the very manual process of adding a library, the site is also a chance for me to experiment with all sorts of tech and see in real time how it performs under a moderate load. Originally launched as a .NET application most of what you see today is running node.js under iisnode using Express w/ Jade templates (moving to doT.js as I write), a gulpjs build process, a homegrown CMS using AngularJS and VB.NET (gasp!), and a Lucene.NET search application in C#.

  9. Gap between asm.js and native performance gets even narrower with float32 optimizations

    asm.js is a simple subset of JavaScript that is very easy to optimize, suitable for use as a compiler target from languages like C and C++. Earlier this year Firefox could run asm.js code at about half of native speed – that is, C++ code compiled by emscripten could run at about half the speed that the same C++ code could run when compiled natively – and we thought that through improvements in both emscripten (which generates asm.js code from C++) and JS engines (that run that asm.js code), it would be possible to get much closer to native speed.

    Since then many speedups have arrived, lots of them small and specific, but there were also a few large features as well. For example, Firefox has recently gained the ability to optimize some floating-point operations so that they are performed using 32-bit floats instead of 64-bit doubles, which provides substantial speedups in some cases as shown in that link. That optimization work was generic and applied to any JavaScript code that happens to be optimizable in that way. Following that work and the speedups it achieved, there was no reason not to add float32 to the asm.js type system so that asm.js code can benefit from it specifically.

    The work to implement that in both emscripten and SpiderMonkey has recently completed, and here are the performance numbers:

    asm1.5b

    Run times are normalized to clang, so lower is better. The red bars (firefox-f32) represent Firefox running on emscripten-generated code using float32. As the graph shows, Firefox with float32 optimizations can run all those benchmarks at around 1.5x slower than native, or better. That’s a big improvement from earlier this year, when as mentioned before things were closer to 2x slower than native. You can also see the specific improvement thanks to float32 optimizations by comparing to the orange bar (firefox) next to it – in floating-point heavy benchmarks like skinning, linpack and box2d, the speedup is very noticeable.

    Another thing to note about those numbers is that not just one native compiler is shown, but two, both clang and gcc. In a few benchmarks, the difference between clang and gcc is significant, showing that while we often talk about “times slower than native speed”, “native speed” is a somewhat loose term, since there are differences between native compilers.

    In fact, on some benchmarks, like box2d, fasta and copy, asm.js is as close or closer to clang than clang is to gcc. There is even one case where asm.js beats clang by a slight amount, on box2d (gcc also beats clang on that benchmark, by a larger amount, so probably clang’s backend codegen just happens to be a little unlucky there).

    Overall, what this shows is that “native speed” is not a single number, but a range. It looks like asm.js on Firefox is very close to that range – that is, while it’s on average slower than clang and gcc, the amount it is slower by is not far off from how much native compilers differ amongst themselves.

    Note that float32 code generation is off by default in emscripten. This is intentional, as while it can both improve performance as well as ensure the proper C++ float semantics, it also increases code size – due to adding Math.fround calls – which can be detrimental in some cases, especially in JavaScript engines not yet supporting Math.fround.

    There are some ways to work around that issue, such as the outlining option which reduces maximum function size. We have some other ideas on ways to improve code generation in emscripten as well, so we’ll be experimenting with those for a while as well as following when Math.fround gets supported in browsers (so far Firefox and Safari do). Hopefully in the not so far future we can enable float32 optimizations by default in emscripten.

    Summary

    In summary, the graph above shows asm.js performance getting yet closer to native speed. While for the reasons just mentioned I don’t recommend that people build with float32 optimizations quite yet – hopefully soon though! – it’s an exciting increase in performance. And even the current performance numbers – 1.5x slower than native, or better – are not the limit of what can be achieved, as there are still big improvements either under way or in planning, both in emscripten and in JavaScript engines.

  10. Ember Inspector on a Firefox near you

    … or Cross-Browser Add-ons for Fun or Profit

    Browser add-ons are clearly an important web browser feature, at least on the desktop platform, and for a long time Firefox was the browser add-on authors’ preferred target. When Google launched Chrome, this trend on the desktop browsers domain was pretty clear, so their browser provides an add-on api as well.

    Most of the Web DevTools we are used to are now directly integrated into our browser, but they were add-ons not so long time ago, and it’s not strange that new web developer tools are born as add-ons.

    Web DevTools (integrated or add-ons) can motivate web developers to change their browser, and then web developers can push web users to change theirs. So, long story short, it would be interesting and useful to create cross-browser add-ons, especially web devtools add-ons (e.g. to preserve the web neutrality).

    With this goal in mind, I chose Ember Inspector as the target for my cross-browser devtool add-ons experiment, based on the following reasons:

    • It belongs to an emerging and interesting web devtools family (web framework devtools)
    • It’s a pretty complex / real world Chrome extension
    • It’s mostly written in the same web framework by its own community
    • Even if it is a Chrome extension, it’s a webapp built from the app sources using grunt
    • Its JavaScript code is organized into modules and Chrome-specific code is mostly isolated in just a couple of those
    • Plan & Run Porting Effort

      Looking into the ember-extension git repository, we see that the add-on is built from its sources using grunt:

      Ember Extension: chrome grunt build process

      The extension communicates between the developer tools panel, the page and the main extension code via message passing:

      Ember Extension: High Level View

      Using this knowledge, planning the port to Firefox was surprisingly easy:

      • Create new Firefox add-on specific code (register a devtool panel, control the inspected tab)
      • Polyfill the communication channel between the ember_debug module (that is injected into the inspected tab) and the devtool ember app (that is running in the devtools panel)
      • Polyfill the missing non-standard inspect function, which open the DOM Inspector on a DOM Element selected by a defined Ember View id
      • Minor tweaks (isolate remaining Chrome and Firefox specific code, fix CSS -webkit prefixed rules)

      In my opinion this port was particularly pleasant to plan thanks to two main design choices:

      • Modular JavaScript sources which helps to keep browser specific code encapsulated into replaceable modules
      • Devtool panel and code injected into the target tab collaborate exchanging simple JSON messages and the protocol (defined by this add-on) is totally browser agnostic

      Most of the JavaScript modules which compose this extension were already browser independent, so the first step was to bootstrap a simple Firefox Add-on and register a new devtool panel.

      Create a new panel into the DevTools is really simple, and there’s some useful docs about the topic in the Tools/DevToolsAPI page (work in progress).

      Register / unregister devtool panel

      From https://github.com/tildeio/ember-extension/blob/master/dist_firefox/lib/main.js

      Devtool panel definition

      From https://github.com/tildeio/ember-extension/blob/master/dist_firefox/lib/devtool-panel.js#L26

      Then, moving to the second step, adapt the code used to create the message channels between the devtool panel and injected code running in the target tab, using content scripts and the low level content worker from the Mozilla Add-on SDK, which are well documented on the official guide and API reference:

      EmberInspector - Workers, Content Scripts and Adapters

      DevTool Panel Workers

      From https://github.com/tildeio/ember-extension/blob/master/dist_firefox/lib/devtool-panel.js

      Inject ember_debug

      From https://github.com/tildeio/ember-extension/blob/master/dist_firefox/lib/devtool-panel.js

      Finally hook browser specific code needed to activate the DOM Inspector on a defined DOM Element:

      Inspect DOM element request handler

      From https://github.com/tildeio/ember-extension/blob/master/dist_firefox/lib/devtool-panel.js#L178

      Evaluate its features and dive into the exchanged messages

      At this point one could wonder: how much useful is a tool like this?, Do I really need it? etc.

      I must admit that I’ve started and completed this port without being an experienced EmberJS developer, but to be able to check if all the original features were working correctly on Firefox and to really understand how this browser add-on helps EmberJS developers during app development/debugging phases (its most important use cases), I’ve started to experiment with EmberJS and I have to say that EmberJS is a very pleasant framework to work with and Ember Inspector is a really important tool to put into our tool belts.

      I’m pretty sure that every medium or large sized JavaScript framework need this kind of DevTool; clearly it will never be an integrated one, because it’s framework-specific and we will get used to this new family of DevTool Add-ons from now on.

      List Ember View, Model Components and Routes

      The first use case is being able to immediately visualize Routes, Views/Components, Models and Controllers our EmberJS app instantiate for us, without too much webconsole acrobatics.

      So its immediately available (and evident) when we open its panel on an EmberJS Apps active in the current browser tab:

      Ember Inspector - ViewTree

      Using these tables we can then inspect all the properties (even computed ones) defined by us or inherited from the ember classes in the actual object hierarchy.

      Using an approach very similar to the Mozilla Remote Debugging Protocol from the integrated DevTools infrastructure (e.g. even when we use devtools locally, they exchange JSON messages over a pipe), the ember_debug component injected into the target tab sends the info it needs about the instantiated EmberJS objects to the devtool panel component, each identified by internally generated reference IDs (similar to the grips concept from the Mozilla Remote Debugging Protocol.

      Ember Extension - JSON messages

      Logging the exchanged messages, we can learn more about the protocol.

      Receive updates about EmberJS view tree info (EmberDebug -> DevtoolPanel):

      Request inspect object (DevtoolPanel -> EmberDebug):

      Receive updates about the requested Object info (DevtoolPanel -> EmberDebug):

      Reach every EmberJS object in the hierarchy from the webconsole

      A less evident but really useful feature is “sendToConsole”, to be able to reach any object/property that we can inspect from the webconsole, from the tables described above.

      When we click the >$E link, which is accessible in the right split panel:

      Ember Inspector - sendToConsole

      The ember devtool panel asks to ember_debug to put the defined object/property into a variable accessible globally in the target tab and named $E, then we can switch to the webconsole and interact with it freely:

      Ember Inspector - sendToConsole

      Request send object to console (DevtoolPanel -> EmberDebug):

      Much more

      These are only some of the feature already present in the Ember Inspector and more features are coming in its upcoming versions (e.g. log and inspect Ember Promises).

      If you already use EmberJS or if you are thinking about trying it, I suggest you to give Ember Inspector a try (on both Firefox or Chrome, if you prefer), it will turn inspecting your EmberJS webapp into a fast and easy task.

      Integrate XPI building into the grunt-based build process

      The last challenge in the road to a Firefox add-on fully integrated into the ember-extension build workflow was xpi building for an add-on based on the Mozilla Add-on SDK integrated into the grunt build process:

      Chrome crx extensions are simply ZIP files, as are Firefox XPI add-ons, but Firefox add-ons based on the Mozilla Add-on SDK needs to be built using the cfx tool from the Add-on SDK package.

      If we want more cross-browser add-ons, we have to help developers to build cross-browser extensions using the same approach used by ember-extension: a webapp built using grunt which will run into a browser add-on (which provides glue code specific to the various browsers supported).

      So I decided to move the grunt plugin that I’ve put together to integrate Add-on SDK common and custom tasks (e.g. download a defined Add-on SDK release, build an XPI, run cfx with custom parameters) into a separate project (and npm package), because it could help to make this task simpler and less annoying.

      Ember Extension: Firefox and Chrome Add-ons grunt build

      Build and run Ember Inspector Firefox Add-on using grunt:

      Following are some interesting fragments from grunt-mozilla-addon-sdk integration into ember-extension (which are briefly documented in the grunt-mozilla-addon-sdk repo README):

      Integrate grunt plugin into npm dependencies: package.json

      Define and use grunt shortcut tasks: Gruntfile.js

      Configure grunt-mozilla-addon-sdk tasks options

      Conclusion

      Especially thanks to the help from the EmberJS/EmberInspector community and its maintainers, Ember Inspector Firefox add-on is officially merged and integrated in the automated build process, so now we can use it on Firefox and Chrome to inspect our EmberJS apps!

      Stable:

      Latest Build

      In this article we’ve briefly dissected an interesting pattern to develop cross-browser devtools add-ons, and introduced a grunt plugin that simplifies integration of Add-on SDK tools into projects built using grunt: https://npmjs.org/package/grunt-mozilla-addon-sdk

      Thanks to the same web first approach Mozilla is pushing in the Apps domain creating cross-browser add-ons is definitely simpler than what we thought, and we all win :-)

      Happy Cross-Browser Extending,
      Luca