Mozilla

Articles

Sort by:

View:

  1. Trainspotting: Firefox 38

    Trainspotting is a series of articles highlighting features in the latest version of Firefox, that are live now in production code, ready for you to use in your work. A new version of Firefox is shipped every six weeks – we at Mozilla call this pattern “release trains.”

    Has it been six weeks already?? Firefox 38 is here, and with it come some snazzy new additions to the Web platform. Here are a few highlights:

    For a full list of changes and additions, take a look at the Firefox 38 release notes.

    Responsive Image Support

    Support for both the <picture> element and <img srcset> are now in a stable Firefox! There are lots of great articles available to get you familiar with the new techniques, and a polyfill available so you can take advantage of them today! There is one caveat for Firefox 38 – responsive images will load using the correct media queries, but presently do not respond to viewport resizing. This bug is being actively worked on and tracked here, and will be fixed in a near-future version of Firefox.

    You got WebSockets in my Web Worker!

    Firefox 38 now allows code running in a Web Worker to open up a WebSocket connection. This is great for games or other collaborative applications, which can now do their multiplayer/realtime logic in a separate thread from the UI.

    HTML5 <ruby> markup support

    Ruby Annotation

    Better typography for Japanese and Chinese language sites is now possible without clunky libraries or extensions by using <ruby> markup.

    BroadcastChannel- postMessage All the Windows!

    If you’re building a webapp with multiple tabs or windows, keeping them all in sync, apprised of events and state changes can be a pain. BroadcastChannel is a fully client-side message passing API that lets any scripts running on the same origin broadcast messages to their peers.

    // one tab
    var ch = new BroadcastChannel('test');
    ch.postMessage('this is a test');
    
    // another tab
    ch.addEventListener('message', function (e) {
        alert('I got a message!', e.data);
    });
    
    // yet another tab
    ch.addEventListener('message', function (e) {
        alert('Avast! a message!' e.data);
    });

    Developer Tools

    Network requests coming from XMLHttpRequest are now marked in the Web Console:

    XMLHttpRequest requests marked in the Web Console

    Need to grab a value from your page? The special copy method available in the Web Console has you covered:

    consolecopy

    But Wait

    There are tons more improvements and bug fixes in Firefox 38 I haven’t covered here – check out the Firefox 38 release notes, Developer Release Notes, or even the list of bugs fixed in this release for more information.

    Enjoy!

  2. ES6 In Depth: Generators

    ES6 In Depth is a series on new features being added to the JavaScript programming language in the 6th Edition of the ECMAScript standard, ES6 for short.

    I’m excited about today’s post. Today, we’re going to discuss the most magical feature in ES6.

    What do I mean by “magical”? For starters, this feature is so different from things that already existed in JS that it may seem completely arcane at first. In a sense, it turns the normal behavior of the language inside out! If that’s not magic, I don’t know what is.

    Not only that: this feature’s power to simplify code and straighten out “callback hell” borders on the supernatural.

    Am I laying it on a bit thick? Let’s dive in and you can judge for yourself.

    Introducing ES6 generators

    What are generators?

    Let’s start by looking at one.

    function* quips(name) {
      yield "hello " + name + "!";
      yield "i hope you are enjoying the blog posts";
      if (name.startsWith("X")) {
        yield "it's cool how your name starts with X, " + name;
      }
      yield "see you later!";
    }
    

    This is some code for a talking cat, possibly the most important kind of application on the Internet today. (Go ahead, click the link, play with the cat. When you’re thoroughly confused, come back here for the explanation.)

    It looks sort of like a function, right? This is called a generator-function and it has a lot in common with functions. But you can see two differences right away:

    • Regular functions start with function. Generator-functions start with function*.

    • Inside a generator-function, yield is a keyword, with syntax rather like return. The difference is that while a function (even a generator-function) can only return once, a generator-function can yield any number of times. The yield expression suspends execution of the generator so it can be resumed again later.

    So that’s it, that’s the big difference between regular functions and generator-functions. Regular functions can’t pause themselves. Generator-functions can.

    What generators do

    What happens when you call the quips() generator-function?

    > var iter = quips("jorendorff");
      [object Generator]
    > iter.next()
      { value: "hello jorendorff!", done: false }
    > iter.next()
      { value: "i hope you are enjoying the blog posts", done: false }
    > iter.next()
      { value: "see you later!", done: false }
    > iter.next()
      { value: undefined, done: true }
    

    You’re probably very used to ordinary functions and how they behave. When you call them, they start running right away, and they run until they either return or throw. All this is second nature to any JS programmer.

    Calling a generator looks just the same: quips("jorendorff"). But when you call a generator, it doesn’t start running yet. Instead, it returns a paused Generator object (called iter in the example above). You can think of this Generator object as a function call, frozen in time. Specifically, it’s frozen right at the top of the generator-function, just before running its first line of code.

    Each time you call the Generator object’s .next() method, the function call thaws itself out and runs until it reaches the next yield expression.

    That’s why each time we called iter.next() above, we got a different string value. Those are the values produced by the yield expressions in the body of quips().

    On the last iter.next() call, we finally reached the end of the generator-function, so the .done field of the result is true. Reaching the end of a function is just like returning undefined, and that’s why the .value field of the result is undefined.

    Now might be a good time to go back to the talking cat demo page and really play around with the code. Try putting a yield inside a loop. What happens?

    In technical terms, each time a generator yields, its stack frame—the local variables, arguments, temporary values, and the current position of execution within the generator body—is removed from the stack. However, the Generator object keeps a reference to (or copy of) this stack frame, so that a later .next() call can reactivate it and continue execution.

    It’s worth pointing out that generators are not threads. In languages with threads, multiple pieces of code can run at the same time, usually leading to race conditions, nondeterminism, and sweet sweet performance. Generators are not like that at all. When a generator runs, it runs in the same thread as the caller. The order of execution is sequential and deterministic, and never concurrent. Unlike system threads, a generator is only ever suspended at points marked by yield in its body.

    All right. We know what generators are. We’ve seen a generator run, pause itself, then resume execution. Now for the big question. How could this weird ability possibly be useful?

    Generators are iterators

    Last week, we saw that ES6 iterators are not just a single built-in class. They’re an extension point of the language. You can create your own iterators just by implementing two methods: [Symbol.iterator]() and .next().

    But implementing an interface is always at least a little work. Let’s see what an iterator implementation looks like in practice. As an example, let’s make a simple range iterator that simply counts up from one number to another, like an old-fashioned C for (;;) loop.

    // This should "ding" three times
    for (var value of range(0, 3)) {
      alert("Ding! at floor #" + value);
    }
    

    Here’s one solution, using an ES6 class. (If the class syntax is not completely clear, don’t worry—we’ll cover it in a future blog post.)

    class RangeIterator {
      constructor(start, stop) {
        this.value = start;
        this.stop = stop;
      }
    
      [Symbol.iterator]() { return this; }
    
      next() {
        var value = this.value;
        if (value < this.stop) {
          this.value++;
          return {done: false, value: value};
        } else {
          return {done: true, value: undefined};
        }
      }
    }
    
    // Return a new iterator that counts up from 'start' to 'stop'.
    function range(start, stop) {
      return new RangeIterator(start, stop);
    }
    

    See this code in action.

    This is what implementing an iterator is like in Java or Swift. It’s not so bad. But it’s not exactly trivial either. Are there any bugs in this code? It’s not easy to say. It looks nothing like the original for (;;) loop we are trying to emulate here: the iterator protocol forces us to dismantle the loop.

    At this point you might be feeling a little lukewarm toward iterators. They may be great to use, but they seem hard to implement.

    It probably wouldn’t occur to you to suggest that we introduce a wild, mindbending new control flow structure to the JS language just to make iterators easier to build. But since we do have generators, can we use them here? Let’s try it:

    function* range(start, stop) {
      for (var i = start; i < stop; i++)
        yield i;
    }
    

    See this code in action.

    The above 4-line generator is a drop-in replacement for the previous 23-line implementation of range(), including the entire RangeIterator class. This is possible because generators are iterators. All generators have a built-in implementation of .next() and [Symbol.iterator](). You just write the looping behavior.

    Implementing iterators without generators is like being forced to write a long email entirely in the passive voice. When simply saying what you mean is not an option, what you end up saying instead can become quite convoluted. RangeIterator is long and weird because it has to describe the functionality of a loop without using loop syntax. Generators are the answer.

    How else can we use the ability of generators to act as iterators?

    • Making any object iterable. Just write a generator-function that traverses this, yielding each value as it goes. Then install that generator-function as the [Symbol.iterator] method of the object.

    • Simplifying array-building functions. Suppose you have a function that returns an array of results each time it’s called, like this one:

      // Divide the one-dimensional array 'icons'
      // into arrays of length 'rowLength'.
      function splitIntoRows(icons, rowLength) {
        var rows = [];
        for (var i = 0; i < icons.length; i += rowLength) {
          rows.push(icons.slice(i, i + rowLength));
        }
        return rows;
      }
      

      Generators make this kind of code a bit shorter:

      function* splitIntoRows(icons, rowLength) {
        for (var i = 0; i < icons.length; i += rowLength) {
          yield icons.slice(i, i + rowLength);
        }
      }
      

      The only difference in behavior is that instead of computing all the results at once and returning an array of them, this returns an iterator, and the results are computed one by one, on demand.

    • Results of unusual size. You can’t build an infinite array. But you can return a generator that generates an endless sequence, and each caller can draw from it however many values they need.

    • Refactoring complex loops. Do you have a huge ugly function? Would you like to break it into two simpler parts? Generators are a new knife to add to your refactoring toolkit. When you’re facing a complicated loop, you can factor out the part of the code that produces data, turning it into a separate generator-function. Then change the loop to say for (var data of myNewGenerator(args)).

    • Tools for working with iterables. ES6 does not provide an extensive library for filtering, mapping, and generally hacking on arbitrary iterable data sets. But generators are great for building the tools you need with just a few lines of code.

      For example, suppose you need an equivalent of Array.prototype.filter that works on DOM NodeLists, not just Arrays. Piece of cake:

      function* filter(test, iterable) {
        for (var item of iterable) {
          if (test(item))
            yield item;
        }
      }
      

    So are generators useful? Sure. They are an astonshingly easy way to implement custom iterators, and iterators are the new standard for data and loops throughout ES6.

    But that’s not all generators can do. It may not even turn out to be the most important thing they do.

    Generators and asynchronous code

    Here is some JS code I wrote a while back.

              };
            })
          });
        });
      });
    });
    

    Maybe you’ve seen something like this in your own code. Asynchronous APIs typically require a callback, which means writing an extra anonymous function every time you do something. So if you have a bit of code that does three things, rather than three lines of code, you’re looking at three indentation levels of code.

    Here is some more JS code I’ve written:

    }).on('close', function () {
      done(undefined, undefined);
    }).on('error', function (error) {
      done(error);
    });
    

    Asynchronous APIs have error-handling conventions rather than exceptions. Different APIs have different conventions. In most of them, errors are silently dropped by default. In some of them, even ordinary successful completion is dropped by default.

    Until now, these problems have simply been the price we pay for asynchronous programming. We have come to accept that asynchronous code just doesn’t look as nice and simple as the corresponding synchronous code.

    Generators offer new hope that it doesn’t have to be this way.

    Q.async() is an experimental attempt at using generators with promises to produce async code that resembles the corresponding synchronous code. For example:

    // Synchronous code to make some noise.
    function makeNoise() {
      shake();
      rattle();
      roll();
    }
    
    // Asynchronous code to make some noise.
    // Returns a Promise object that becomes resolved
    // when we're done making noise.
    function makeNoise_async() {
      return Q.async(function* () {
        yield shake_async();
        yield rattle_async();
        yield roll_async();
      });
    }
    

    The main difference is that the asynchronous version must add the yield keyword each place where it calls an asynchronous function.

    Adding a wrinkle like an if statement or a try/catch block in the Q.async version is exactly like adding it to the plain synchronous version. Compared to other ways of writing async code, this feels a lot less like learning a whole new language.

    If you’ve gotten this far, you might enjoy James Long’s very detailed post on this topic.

    So generators are pointing the way to a new asynchronous programming model that seems better suited to human brains. This work is ongoing. Among other things, better syntax might help. A proposal for async functions, building on both promises and generators, and taking inspiration from similar features in C#, is on the table for ES7.

    When can I use these crazy things?

    On the server, you can use ES6 generators today in io.js (and in Node if you use the --harmony command-line option).

    In the browser, only Firefox 27+ and Chrome 39+ support ES6 generators so far. To use generators on the web today, you’ll need to use Babel or Traceur to translate your ES6 code to Web-friendly ES5.

    A few shout-outs to deserving parties: Generators were first implemented in JS by Brendan Eich; his design closely followed Python generators which were inspired by Icon. They shipped in Firefox 2.0 back in 2006. The road to standardization was bumpy, and the syntax and behavior changed a bit along the way. ES6 generators were implemented in both Firefox and Chrome by compiler hacker Andy Wingo. This work was sponsored by Bloomberg.

    yield;

    There is more to say about generators. We didn’t cover the .throw() and .return() methods, the optional argument to .next(), or the yield* expression syntax. But I think this post is long and bewildering enough for now. Like generators themselves, we should pause, and take up the rest another time.

    But next week, let’s change gears a little. We’ve tackled two deep topics in a row here. Wouldn’t it be great to talk about an ES6 feature that won’t change your life? Something simple and obviously useful? Something that will make you smile? ES6 has a few of those too.

    Coming up: a feature that will plug right in to the kind of code you write every day. Please join us next week for a look at ES6 template strings in depth.

  3. How TV Functionality Leverages Web Technology

    The convergence of Internet-based IPTV, Video-on-Demand (VoD) and traditional broadcasting is happening now. As more and more web technology comes to television, the gap between web apps and native apps is rapidly narrowing.

    Firefox OS now supports the TV Manager API, a baseline of the W3C TV Control API (the editor’s draft driven by the TV Control API Community Group), which allows web-based applications to acquire information such as the Electronic Program Guide (or EPG) from service providers, and also to manage native TV hardware such as tuners and remotes. Firefox OS also relies on multiple API specifications to fully support TV functionality on a web platform. Some APIs are still on the road to becoming standards. Here is an overview of some common TV functions which can be implemented today via these Web APIs.

    FxOS_TV

    Tuner, channel, and EPG management

    One of the primary goals of the TV Control API is to enable standard use cases, such as channel switching and other activities generally available and expected in conventional remote controls. The API exposes specific tuner, channel, and EPG information to the web app and also allows indirect interactions with the tuner modules. Some applications, like virtual remote control, are easy to enable with this API. And the web content has the flexibility to manipulate multiple tuners if resource-permitted. In addition, event-driven notifications about channel scanning status and EPG updates provide a dynamic way to access broadcasting information.

    The following example shows how to get the available tuners and set the current playing source via the API.

        // Retrieve all the available tuners.
        navigator.tv.getTuners().then(function(tuners) {
          // Just use the first tuner.
          var tuner = tuners[0];
    
          // Set the 'oncurrentsourcechanged' event handler.
          tuner.oncurrentsourcechanged = function(event) {
            // The current source has changed.
          };
    
          // Get the supported source types for the tuner. 
          var sourceTypes = tuner.getSupportedSourceTypes();
    
          // Just use the first source.
          tuner.setCurrentSource(sourceTypes[0]).then(function() {
            // Succeeded to set the source.
          }, function(error) {
            // Failed to set the source.
          });
        }, function(error) {
          // Failed to get tuners.
        });
    

    Streaming

    When it comes to TV streaming, multiple web specifications work together. The Media Capture and Streams API enables access to multimedia streams from local devices, and it defines a MediaStream interface to carry video/audio tracks and other stream-relevant attributes. The current streaming data for each tuner can be wrapped in a MediaStream instance and retrieved via the TV Control API. Then the web content can start playing the stream by assigning it to HTML5 <video> elements. Here’s an example:

        // Retrieve all the available TV tuners and then play
        // the stream for the first tuner.
        navigator.tv.getTuners().then(function(tuners) {
          // Assuming a video element is already accessible to
          // variable |video|, just assign the stream to it.
          video.srcObject = tuners[0].stream;
        });
    

    The Media Capture and Streams API and the HTML5 <video> element provide attributes and methods to help manage streaming contents. Combining the APIs and HTML5 elements makes the development of some advanced TV streaming scenarios, such as concurrent display for multiple streams (i.e., Picture-in-Picture), easier to accomplish and more flexible.

    Track management

    While playing video streams, sometimes the media content provides multiple audio channels and even includes subtitles. For instance, a film or a sports show may be broadcast with multiple supported languages available for the viewer to select. Thus, there are two lists of VideoTrack and AudioTrack objects in the HTML5 <video> element to help the web content utilize available video and audio tracks respectively. Meanwhile, the Media Capture and Streams API also provides certain methods to dynamically manage associated media tracks. With this flexibility, web content is able to play a video stream that’s originated from another connected device, such as a camera.

    The HTML5 <video> element has a list of TextTrack instances. These tracks can be associated with a specific video tag to represent different instances, such as subtitles, captions, and metadata. In addition, multiple TextTrackCue objects containing time-sensitive data can be affiliated with them, and used to control timing of the display for subtitles and captions.

    Recording

    The MediaStream Recording API provides a MediaRecorder interface to fulfill recording requirements over the MediaStream. It lets the web content select the appropriate supported encoding format for the stream, and also enables the recorded media to be accessed either as a whole blob or in smaller buffers.

    In cooperation with the Task Scheduler API and Service Workers, you can even add DVR-style scheduling functionality to your web app or web-driven device. On the other hand, the EPG data retrieved via TV Control API may also help the application record specific TV programs.

    Emergency alert

    Sometimes a public alert may be sent out via TV broadcasting or other communication systems when an emergency or natural disaster occurs such an earthquake, tsunami, or hurricane. A corresponding event-triggering mechanism included with the TV Control API can be used to help a web application manage an alert.

       // Assuming variable |currentSource| is associated with
        // the playing TV signal.
        currentSource.onemergencyalerted = function (event) {
          var type = event.type; // i.e. “Earthquake”.
          var severityLevel = event.severityLevel;
          var description = event.description;
          // Display the emergency information.
          // (More attributes could be available.)
        };
    

    Final thoughts

    TV broadcast mechanisms and applications are on a fast track to evolve rapidly, as is the web technology. Since many of the web specifications and APIs mentioned are still in the standardization progress, more functionality or further improvements might be added to make television experience more webby. As always, you can contribute to the evolution of these Web APIs by following along on relevant standards mailing lists and filing bugs when you find them.

  4. RDP Inspector: An extension for Firefox Developer Tools

    RDP Inspector is a Firefox extension that intercepts the Remote Debugging Protocol (RDP) and allows inspection of all data sent and received.

    This extension is useful for anyone who wants to extend native developer tools in Firefox by implementing new remotable features or for those who want to learn more about how built-in tools use the protocol internally to communicate with the backend debugger server.

    Getting started

    The latest RDP Inspector can be installed from addons.mozilla.org (you need to have at least Firefox 38 installed). The source code is also available.

    You should see a new RDP Inspector button at the top-right corner of your browser window after installation.

    start-button

    Clicking the button opens the RDP Inspector console window.

    rdp-console

    The console shows all packets transmitted over the wire. It also shows packet details within the right side panel.

    The screenshot above shows also the very first packet received from the server (from the root, with applicationType="browser").
    This is how the connection between the developer tools toolbox and the backend server is initiated.

    Filtering Packets

    The packet list can be long and you can filter it. For example, in order to see only getTab packets sent to the root actor you can filter the packet list by typing getTab into a box located at the top right corner of the console window.

    Tip: You can also press Ctrl+F and use the browser Find Bar to search within the packet list.

    Summary Data

    It’s sometimes useful to know how many packets or bytes are sent/received in total. This usually also helps to optimize protocol traffic and make new or existing features faster.

    The console helps you get this summary info at at any time. All you need to do is press the Summary button in the toolbar.

    The following screenshot shows a summary for the http://www.washingtonpost.com/ page load time with the Network panel selected (see the bottom of the packet list).

    summary

    You can see that 1266 packets have been sent, 2973 packets received, 75,80 KB sent, and 2.27 MB of data received from the server.

    Chatting with the server

    It’s also possible to send test packets to the server backend. You can put together a new packet with your own properties, send it to the server, and get a response as if it were a packet send by the developer toolbox. All you need to do is select the Send Packet side panel, set some properties, and press the Send button.

    In order to create a new packet property click on the New… (yellow) line at the top of the panel and type its name.

    As soon as you press the Enter key, a new property is inserted at the end of the list.

    The default value is set to undefined and you can change it by clicking on the value text input box. Strings need to be inserted within quotes and new objects (JSON packet sub-tree) can be created by typing {} into the value input box.

    When the packet is ready press the Send button and check out new packets displayed in the list.

    The screenshot above shows that our test property has been sent. You can also see the response from the debugger server.

    Tip: You might want to set the Show Packet Details Inline option (see the Options button in the toolbar) and see all packet properties directly within the packet list. This way you don’t need to constantly switch between the Packet Details and Send Packet side panels.

    Introspecting the protocol

    There are cases when you want to know what services are available on the backend server and test them. These can be both native or custom (installed) backend APIs. The protocol supports the following packet types that can be used for dynamic introspection.

    • requestTypes Send to any actor to get the list of supported packet types (methods).
    • protocolDescription Send to the root actor to get the list of all backend services (actors) and their methods

    A response for requestType is already visible on the previous screenshot and you can see that protocolDescription is one of the packet types you can send to the root actor.

    The next screenshot shows the response for the protocolDescription packet request.

    Isn’t it great, you can chat with your protocol ;-)

    Learn more about RDP Inspector on the

    Learn more about the RDP Inspector over on the project wiki, and please help by filing any issues or bugs you discover. As always, we welcome your feedback.

    Jan ‘Honza’ Odvarko

  5. Creating a mobile app from a simple HTML site: Part 3

    Adding a server to separate the app from its data

    This is the third part in our series of posts about creating a dynamic mobile app from a simple HTML site. In Part 2 we separated the data from its visual representation, but the data is still contained inside the app. In this article, we take that data, remove it from the app altogether, and serve it from the server instead, to maximise reusability between different users.

    We will go through the steps required to create a suitable server using NodeJS. Then we will make the app work as a client of this server.

    If you have your code handy from last time, then you are ready to go. Make sure you have NodeJS installed. If you don’t have a previous code base setup you can follow the instructions on how to load any stage in this tutorial. Use stage5 as a starting point.

    Refactoring our code

    Let’s quickly look at the code created in part 2.

    Two things happen in the app.onDeviceReady method (see js/index.js) — data is loaded from a JSON file and touch events are listened for on <brick-deck id="plan-group">. After data is loaded, app.renderData parses the JSON string and app.createUI creates a UI for each plan separately.

    onDeviceReady and createUI are currently not very efficient, so let’s update them. Let’s split onDeviceReady by creating a new method called activateFingerSwipe that will contain all the code after the request.send() line and simply call it without arguments. Update your code as follows:

    onDeviceReady: function() {
         var request = new XMLHttpRequest();
         request.onload = app.renderData;
         request.open("get", "app_data/plans.json", true);
         request.send();
    
         app.activateFingerSwipe();
    },
    
    activateFingerSwipe: function() {
        // Switching from one tab to another is done automatically
        // We just need to link it backwards - change menu if slides
        // changed without touching the menu
        app.planGroupMenu = document.getElementById('plan-group-menu');
        
        // Implementing one finger swipe to change deck card
        app.planGroup = document.getElementById('plan-group');
    
        var startX = null;
        var slideThreshold = 100;
    
        // ...
    

    Now, let’s move on to updating createUI. Instead of having the code to create the UI for each individual plan inside createUI, we will create a new user-defined object type called Plan and instantiate it in the loop. Update app.renderData to look like the block below:

    renderData: function() {
        var plans = JSON.parse(this.responseText);
        var deck = document.getElementById('plan-group');
        var tabbar = document.getElementById('plan-group-menu');
        navigator.globalization.getDateNames(function(dayOfWeek){
          for (var i = 0; i < plans.length; i++) {
              var plan = new Plan(plans[i]);
              plan.createUI(deck, tabbar, dayOfWeek);
          }
        }, function() {}, {type: 'narrow', item: 'days'});
    },

    We will define the Plan type as an object having two methods — createUI and selectTab — which are copied from the existing methods and functions. The only changes are related to the data now having an object nature. Instead of plan.week we use this.schedule. this always relates to the current plan’s scope. All changes related to storing parameters in the object are as follows:

    • plan.title -> this.title
    • plan.week -> this.schedule
    • plan.id -> this.id
    • plan.active -> this.active
    • var tab -> this.tab
    • var card -> this.card
    • var table -> this.table
    • selectTab(deck, tab) -> this.selectTab(deck)

    At the top of your index.js file, add the following code:

    function Plan(plan) {
        this.schedule = plan.week;
        this.title = plan.title;
        this.id = plan.id;
        this.active = plan.active;
        this.tab = null;
        this.card = null;
        this.table = null;
    };
    
    Plan.prototype.selectTab = function(deck) {
        var self = this;
        function selectActiveTab() {
            if (!self.tab.targetElement) {
                return window.setTimeout(selectActiveTab, 100);
            }
            deck.showCard(self.tab.targetElement);
        }
        selectActiveTab();
    }
    
    Plan.prototype.createUI = function(deck, tabbar, dayOfWeek) {
        // create card
        this.card = document.createElement('brick-card');
        this.card.setAttribute('id', this.id);
        deck.appendChild(this.card);
    
        //create tab
        this.tab = document.createElement('brick-tabbar-tab');
        this.tab.setAttribute('target', this.id);
        this.tab.appendChild(document.createTextNode(this.title));
        tabbar.appendChild(this.tab);
    
        // link card and tab DOM Elements
        this.card.tabElement = this.tab;
        this.card.addEventListener('show', function() {
            this.tabElement.select();
        });
    
        // create plan table
        this.table = document.createElement('table');
    
        var numberOfDays = this.schedule.length;
        var cleanPlan = [];
        for (var j = 0; j  0) {
                cleanPlan.push(this.schedule[j]);
            }
        }
    
        var daysInHours = [];
        for (j = 0; j < cleanPlan.length; j++) {
            for (var k = 0; k < cleanPlan[j].length; k++) {
                if (!daysInHours[k]) {
                    daysInHours[k] = [];
                }
                daysInHours[k][j] = cleanPlan[j][k];
            }
        }
    
        for (var j = 0; j < daysInHours.length; j++) {
            var tr = this.table.insertRow(-1);
            var td = tr.insertCell(-1);
            td.appendChild(document.createTextNode(j + 1));
            for (var k = 0; k < cleanPlan.length; k++) {
                var td = tr.insertCell(-1);
                if (daysInHours[j][k]) {
                    td.appendChild(document.createTextNode(daysInHours[j][k]));
                }
            }
        }
    
        var thead = this.table.createTHead();
        var tr = thead.insertRow();
        var th_empty = document.createElement('th');
        tr.appendChild(th_empty);
        var weekDayNumber;
         for (var j = 0; j  0) {
                var th = document.createElement('th');
                th.appendChild(document.createTextNode(dayOfWeek.value[weekDayNumber]));
                tr.appendChild(th);
            }
        }
    
        this.card.appendChild(this.table);
    
        if (this.active) {
          this.selectTab(deck);
        }
    }

    You can check your work against the full refactored code source in github.

    You might notice var self = this; and then deck.showCard(self.tab.targetElement); in Plan.prototype.selectTab. this in scope of selectActiveTab would represent a different value then outside of it.

    Read more about the new operator and the this keyword on MDN if you want more information.

    Building the server

    Building a server using NodeJS is fairly simple — http is the only module required, although we will also include fs (as we need to load the file from disk) and sys (to display logs.)

    We will place the server’s code into a separate directory (it’s named stage6-server/ in the related Github project) as it is not part of the app.

    First of all, create a new directory in the same level as school-plan called server. Move the plans.json file out from the school-plan/www/app-data directory to the server directory, then remove school-plan/www/app-data. You could do these actions using the following terminal commands from school-plan‘s parent directory:

    mkdir server
    mv school-plan/www/app_data/plans.json server/
    rm -rf school-plan/www/app_data
    

    Now onto the NodeJS server code. Create a new file called server.js inside the server directory, and fill it with the following content — this simply reads the file from disk:

    var fs = require('fs'),
        sys = require("sys");
    
    fs.readFile(__dirname + "/plans.json", function (err, data) {
        sys.puts(data);
    });

    Run it with the terminal command node server.js — you should see the content of the plans.json file listed in terminal.

    Now we will serve this file using the http module. Modify your NodeJS code like so:

    var fs = require('fs'),
        sys = require("sys"),
        http = require('http');
    
    http.createServer(function (request, response) {
      fs.readFile(__dirname + "/plans.json", function (err, data) {
        response.writeHead(200, {"Content-Type": "application/json"});
        response.end(data);
        sys.puts("accessed");
      });
    }).listen(8080);
    sys.puts("Server Running on http://127.0.0.1:8080");

    First we’ve created the server using the http.createServer method and ordered it to listen on port 8080. On every single request, the plans.json file is read and returned as an HTTP response. Then we simply log accessed to the terminal.

    Test your file again, as before.

    Navigate to http://127.0.0.1:8080 using your browser and you should see the contents of the file inside the browser. (I use the JSON View add-on to make the code look nice too — it’s worth getting.)

    So we’re able to serve the file from our machine — now we just need to read it in our app.

    Note: The server is serving for any address – it works on http://localhost:8080 and also on your local network address (usually http://192.168.xx.xx:8080). This address should be used when testing the app on a device.

    Reading the data from the server

    We need to change the app to read from the server instead of the file distributed inside the app. Let’s change the request.open call (inside deviceReady method) to read from the URL instead of the local file. Replace app_data/plans.json with http://127.0.0.1:8080, so it will look like this:

    request.open("get", "http://127.0.0.1:8080", true);
    

    Now for a test. Run the cordova prepare command in the terminal, and reload the app in WebIDE.

    You will receive an error in the browser console: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8080/. This can be fixed by moving the resource to the same domain or enabling CORS..

    CORS, and cross-origin fixes

    The error is due to a CORS security policy preventing us from loading a script from a different domain.

    There are two ways of loading a script from a different domain. Whitelisting it in Cordova is one of them, but as we’ve got control over the server, we can simply allow cross-site HTTP requests. This is done by setting a header call Access-Control-Allow-Origin in the request. Its value is the domain name(s) that can request content from the server. As our app will be used on phones, all domains should have access. The needed headers are as follows:

    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept"
    

    We will add these headers to the existing Content-Type one specified in our server.js script — update the response.writeHead() call to the following:

    response.writeHead(200, {
      "Content-Type": "application/json",
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept"});

    Save your NodeJs code, stop (Control + C) the server running in your terminal, and run it again. The application should now be able to read from the server as desired.

    If you are having problems getting the app to work, check your code for the app and server.

    Serving and loading user plans

    Currently we load all plans available in plans.json. As we want to be able to serve plans for any user we need to identify and serve a set.

    We will need to identify a plan. To find a plan in our “database” (JSON file) we will change the plan structure from array to object. For example:

    {
      "somehashtag": {
      "title": "A",
      "id": "a",
      "active": 1,
      "week": [
        // ...
      ]
    }, {
      "otherhashtag": {
      "title": "B",
      "id": "b",
      "week": [
        // ...
      ]
    }

    We also need to find a way to store hashtags. Most of the users will have a different list of them. Should they be stored only on the device or on the server? Considering that many users change their phone fairly often, it’s best to keep the list of hashtags on the server. In production we would have separate user accounts, but for the sake of this tutorial and the simplicity of the server’s code no security is provided.

    We again need to modify the JSON file, to allow for different users and separate plans:

    {
      "users": {
        "userA": {
          "name": "John Doe",
          "plans": ["somehashtag", "otherhashtag"]
        },
        // ...  
      },
      "plans": {
        "somehashtag": {
        "title": "A",
        "id": "a",
        "active": 1,
        "week": [
          // ...
        ]
      }, {
        "otherhashtag": {
        "title": "B",
        "id": "b",
        "week": [
          // ...
        ]
      }
    }

    From now on, data.plans will represent all plans and data.users will represent all of the users.

    At this point, download the updated plans.json file from Github, and replace old with new.

    I defined the URL to access a user’s plans as follows:

    http://{address}/plans/{userid}

    Reading URLs is easy with the url module — now you should add it to the loaded modules:

    var fs = require('fs'),
        sys = require("sys"),
        http = require('http'),
        url = require('url');
    

    Now remove the current response.end(); and sys.puts() calls, replacing them with:

    var args = url.parse(request.url).pathname.split('/');
    var command = args[1];
    var data = JSON.parse(data);
    
    if (command === 'plans') {
        // get user from data.users
        var userid = args[2];
        var user = data.users[userid];
        var plans = [];
        var i, hashtag;
        for (i = 0; i < user.plans.length; i++) {
           hashtag = user.plans[i];
           // copy each user's plan to plans
           plans.push(data.plans[hashtag]);
        }
        response.end(JSON.stringify(plans));
        sys.puts("accessed user - " + userid);
    }

    The only change in the app’s usage now is that we can load the data for different users using the new URL scheme:

    http://127.0.0.1:8080/plans/someuser

    Go to your index.js file and update the following:

    request.open("get", "http://127.0.0.1:8080/", true);

    to

    request.open("get", "http://127.0.0.1:8080/plans/johndoe", true);

    Conclusion

    We have now provided a way to display different plans for different users. However, we are still downloading the plans every time the app is used, which is not much good for an offline experience, plus we currently can’t change the plans displayed unless we edit the XHR call in the code itself. We’ll tackle these problems in our next article.

    For now, check out the final code for the app and server. And look out for Part 4, coming in May!

  6. ES6 In Depth: Iterators and the for-of loop

    ES6 In Depth is a series on new features being added to the JavaScript programming language in the 6th Edition of the ECMAScript standard, ES6 for short.

    How do you loop over the elements of an array? When JavaScript was introduced, twenty years ago, you would do it like this:

    for (var index = 0; index < myArray.length; index++) {
      console.log(myArray[index]);
    }
    

    Since ES5, you can use the built-in forEach method:

    myArray.forEach(function (value) {
      console.log(value);
    });
    

    This is a little shorter, but there is one minor drawback: you can’t break out of this loop using a break statement or return from the enclosing function using a return statement.

    It sure would be nice if there were just a for-loop syntax that looped over array elements.

    How about a forin loop?

    for (var index in myArray) {    // don't actually do this
      console.log(myArray[index]);
    }
    

    This is a bad idea for several reasons:

    • The values assigned to index in this code are the strings "0", "1", "2" and so on, not actual numbers. Since you probably don’t want string arithmetic ("2" + 1 == "21"), this is inconvenient at best.
    • The loop body will execute not only for array elements, but also for any other expando properties someone may have added. For example, if your array has an enumerable property myArray.name, then this loop will execute one extra time, with index == "name". Even properties on the array’s prototype chain can be visited.
    • Most astonishing of all, in some circumstances, this code can loop over the array elements in an arbitrary order.

    In short, forin was designed to work on plain old Objects with string keys. For Arrays, it’s not so great.

    The mighty for-of loop

    Remember last week I promised that ES6 would not break the JS code you’ve already written. Well, millions of Web sites depend on the behavior of forin—yes, even its behavior on arrays. So there was never any question of “fixing” forin to be more helpful when used with arrays. The only way for ES6 to improve matters was to add some kind of new loop syntax.

    And here it is:

    for (var value of myArray) {
      console.log(value);
    }
    

    Hmm. After all that build-up, it doesn’t seem all that impressive, does it? Well, we’ll see whether forof has any neat tricks up its sleeve. For now, just note that:

    • this is the most concise, direct syntax yet for looping through array elements
    • it avoids all the pitfalls of forin
    • unlike forEach(), it works with break, continue, and return

    The forin loop is for looping over object properties.

    The forof loop is for looping over data—like the values in an array.

    But that’s not all.

    Other collections support for-of too

    forof is not just for arrays. It also works on most array-like objects, like DOM NodeLists.

    It also works on strings, treating the string as a sequence of Unicode characters:

    for (var chr of "😺😲") {
      alert(chr);
    }
    

    It also works on Map and Set objects.

    Oh, I’m sorry. You’ve never heard of Map and Set objects? Well, they are new in ES6. We’ll do a whole post about them at some point. If you’ve worked with maps and sets in other languages, there won’t be any big surprises.

    For example, a Set object is good for eliminating duplicates:

    // make a set from an array of words
    var uniqueWords = new Set(words);
    

    Once you’ve got a Set, maybe you’d like to loop over its contents. Easy:

    for (var word of uniqueWords) {
      console.log(word);
    }
    

    A Map is slightly different: the data inside it is made of key-value pairs, so you’ll want to use destructuring to unpack the key and value into two separate variables:

    for (var [key, value] of phoneBookMap) {
      console.log(key + "'s phone number is: " + value);
    }
    

    Destructuring is yet another new ES6 feature and a great topic for a future blog post. I should write these down.

    By now, you get the picture: JS already has quite a few different collection classes, and even more are on the way. forof is designed to be the workhorse loop statement you use with all of them.

    forof does not work with plain old Objects, but if you want to iterate over an object’s properties you can either use forin (that’s what it’s for) or the builtin Object.keys():

    // dump an object's own enumerable properties to the console
    for (var key of Object.keys(someObject)) {
      console.log(key + ": " + someObject[key]);
    }
    

    Under the hood

    “Good artists copy, great artists steal.” —Pablo Picasso

    A running theme in ES6 is that the new features being added to the language didn’t come out of nowhere. Most have been tried and proven useful in other languages.

    The forof loop, for example, resembles similar loop statements in C++, Java, C#, and Python. Like them, it works with several different data structures provided by the language and its standard library. But it’s also an extension point in the language.

    Like the for/foreach statements in those other languages, forof works entirely in terms of method calls. What Arrays, Maps, Sets, and the other objects we talked about all have in common is that they have an iterator method.

    And there’s another kind of object that can have an iterator method too: any object you want.

    Just as you can add a myObject.toString() method to any object and suddenly JS knows how to convert that object to a string, you can add the myObject[Symbol.iterator]() method to any object and suddenly JS will know how to loop over that object.

    For example, suppose you’re using jQuery, and although you’re very fond of .each(), you would like jQuery objects to work with forof as well. Here’s how to do that:

    // Since jQuery objects are array-like,
    // give them the same iterator method Arrays have
    jQuery.prototype[Symbol.iterator] =
      Array.prototype[Symbol.iterator];
    

    OK, I know what you’re thinking. That [Symbol.iterator] syntax seems weird. What is going on there? It has to do with the method’s name. The standard committee could have just called this method .iterator(), but then, your existing code might already have some objects with .iterator() methods, and that could get pretty confusing. So the standard uses a symbol, rather than a string, as the name of this method.

    Symbols are new in ES6, and we’ll tell you all about them in—you guessed it—a future blog post. For now, all you need to know is that the standard can define a brand-new symbol, like Symbol.iterator, and it’s guaranteed not to conflict with any existing code. The trade-off is that the syntax is a little weird. But it’s a small price to pay for this versatile new feature and excellent backward compatibility.

    An object that has a [Symbol.iterator]() method is called iterable. In coming weeks, we’ll see that the concept of iterable objects is used throughout the language, not only in forof but in the Map and Set constructors, destructuring assignment, and the new spread operator.

    Iterator objects

    Now, there is a chance you will never have to implement an iterator object of your own from scratch. We’ll see why next week. But for completeness, let’s look at what an iterator object looks like. (If you skip this whole section, you’ll mainly be missing crunchy technical details.)

    A forof loop starts by calling the [Symbol.iterator]() method on the collection. This returns a new iterator object. An iterator object can be any object with a .next() method; the forof loop will call this method repeatedly, once each time through the loop. For example, here’s the simplest iterator object I can think of:

    var zeroesForeverIterator = {
      [Symbol.iterator]: function () {
        return this;
      },
      next: function () {
        return {done: false, value: 0};
      }
    };
    

    Every time this .next() method is called, it returns the same result, telling the forof loop (a) we’re not done iterating yet; and (b) the next value is 0. This means that for (value of zeroesForeverIterator) {} will be an infinite loop. Of course, a typical iterator will not be quite this trivial.

    This iterator design, with its .done and .value properties, is superficially different from how iterators work in other languages. In Java, iterators have separate .hasNext() and .next() methods. In Python, they have a single .next() method that throws StopIteration when there are no more values. But all three designs are fundamentally returning the same information.

    An iterator object can also implement optional .return() and .throw(exc) methods. The forof loop calls .return() if the loop exits prematurely, due to an exception or a break or return statement. The iterator can implement .return() if it needs to do some cleanup or free up resources it was using. Most iterator objects won’t need to implement it. .throw(exc) is even more of a special case: forof never calls it at all. But we’ll hear more about it next week.

    Now that we have all the details, we can take a simple forof loop and rewrite it in terms of the underlying method calls.

    First the forof loop:

    for (VAR of ITERABLE) {
      STATEMENTS
    }
    

    Here is a rough equivalent, using the underlying methods and a few temporary variables:

    var $iterator = ITERABLE[Symbol.iterator]();
    var $result = $iterator.next();
    while (!$result.done) {
      VAR = $result.value;
      STATEMENTS
      $result = $iterator.next();
    }
    

    This code doesn’t show how .return() is handled. We could add that, but I think it would obscure what’s going on rather than illuminate it. forof is easy to use, but there is a lot going on behind the scenes.

    When can I start using this?

    The forof loop is supported in all current Firefox releases. It’s supported in Chrome if you go to chrome://flags and enable “Experimental JavaScript”. It also works in Microsoft’s Spartan browser, but not in shipping versions of IE. If you’d like to use this new syntax on the web, but you need to support IE and Safari, you can use a compiler like Babel or Google’s Traceur to translate your ES6 code to Web-friendly ES5.

    On the server, you don’t need a compiler—you can start using forof in io.js (and Node, with the --harmony option) today.

    (UPDATE: This previously neglected to mention that forof is disabled by default in Chrome. Thanks to Oleg for pointing out the mistake in the comments.)

    {done: true}

    Whew!

    Well, we’re done for today, but we’re still not done with the forof loop.

    There is one more new kind of object in ES6 that works beautifully with forof. I didn’t mention it because it’s the topic of next week’s post. I think this new feature is the most magical thing in ES6. If you haven’t already encountered it in languages like Python and C#, you’ll probably find it mind-boggling at first. But it’s the easiest way to write an iterator, it’s useful in refactoring, and it might just change the way we write asynchronous code, both in the browser and on the server. So join us next week as we look at ES6 generators in depth.

  7. WiFi Debugging for Firefox OS

    I am excited to announce that we’re now shipping WiFi debugging for Firefox OS! It’s available in Firefox OS 3.0 / master with Firefox Nightly on desktop.

    WiFi debugging allows WebIDE to connect to your Firefox OS device via your local WiFi network instead of a USB cable.

    The connection experience is generally more straightforward (especially after connecting to a device the first time) than with USB and also more convenient to use since you’re no longer tied down by a cable.

    Background

    Since quite early on in the development of Firefox OS, you’ve been able to debug a device over a USB cable. However, this comes with various drawbacks:

    • You have to connect a cord whenever debugging is needed
    • Drivers are required on some OSes, which causes a lot of confusion
    • The cord requirement makes it harder to debug a phone during a user test

    The mobile device just generally feels a bit less like itself when it’s tied down with a cord.

    We’ve thought about adding some form of WiFi access on the DevTools team for some time. Our key goals were:

    • Ease of use
    • Secure connection

    While we certainly wanted to make this feature available, we wanted to be sure it would be an improvement over the USB method, while also being secure as well. This is important over a shared network like WiFi, since the debugging process by its nature exposes many details of your activity, including potentially private request data. If you’re working at a coffee shop, you don’t want others to have access to this.

    Simplicity

    When connecting over WiFi, there could be many possible devices to pick from on the same network. To avoid this problem, we use a discovery mechanism, similar to Bonjour or mDNS. When you want to connect, your computer sends a multicast ping to look for nearby devices. If there are any, they’ll reply with their name and what services they support. This allows us to present a simple list of device names, instead of dealing with IP addresses.

    The setup process is also nicer than the USB method, which relied on ADB from the Android project. With WiFi debugging, there are no drivers to install on Windows or udev rules to configure on Linux.

    Security

    A large portion of this project has gone towards making the debugging connection secure, so that you can use it safely on shared network, such as an office or coffee shop.

    We use TLS for encryption and authentication. The computer and device both create self-signed certificates. When you connect, a QR code is scanned to verify that the certificates can be trusted. During the connection process, you can choose to remember this information and connect immediately in the future if desired.

    How to Use

    You’ll need to assemble the following:

    • Firefox 39 (2015-03-27 or later)
    • Firefox OS 3.0 (2015-04-16 or later)

    Firefox OS 3.0 is still under heavy development, so it’s not yet available on devices in stores. If you have a Flame device, you can update your Flame to 3.0 / master using a nightly build. For other devices, you may need to build for your device from source to update it.

    On Firefox OS, enable WiFi debugging:

    1. Go to Developer Settings on device (Settings -> Developer)
    2. Enable DevTools via Wi-Fi
    3. Edit the device name if desired

    Firefox OS WiFi Debugging Options

    To connect from Firefox Desktop:

    1. Open WebIDE in Firefox Nightly (Tools -> Web Developer -> WebIDE)
    2. Click “Select Runtime” to open the runtimes panel
    3. Your Firefox OS device should show up in the “WiFi Devices” section
    4. A connection prompt will appear on device, choose “Scan” or “Scan and Remember”
    5. Scan the QR code displayed in WebIDE

    WebIDE WiFi Runtimes

    WebIDE Displays the QR Code

    After scanning the QR code, the QR display should disappear and the “device” icon in WebIDE will turn blue for “connected”.

    You can then access all of your remote apps and browser tabs just as you can today over USB. All of the Firefox DevTools are available over WiFi to inspect, debug, and explore. This is purely a change in how DevTools packets are exchanged, so there are no limits on what tools you can use.

    Supported Devices

    This feature should be supported on any Firefox OS device. So far, I’ve tested it on the Flame and Nexus 4.

    Known Issues

    The QR code scanner can be a bit frustrating at the moment, as real devices appear to capture a very low resolution picture. Bug 1145772 aims to improve this soon. You should be able to scan with the Flame by trying a few different orientations. I would suggest using “Scan and Remember”, so that scanning is only needed for the first connection.

    If you find other issues while testing, please file bugs or contact me on IRC.

    Acknowledgments

    This was quite a complex project, and many people outside of DevTools from teams like Networking and Security provided advice and reviews while working on this feature, including:

    • Brian Warner
    • Trevor Perrin
    • David Keeler
    • Honza Bambas
    • Patrick McManus
    • Jason Duell
    • Panos Astithas
    • Jan Keromnes
    • Alexandre Poirot
    • Paul Rouget
    • Paul Theriault

    I am probably forgetting others as well, so I apologize if you were omitted.

    What’s Next

    I’d like to add this ability for Firefox for Android next. Thankfully, most of the work done here can be reused there. Additionally, we should update other tools like node-firefox to use WiFi to connect to devices. We may also leverage some of this work to make the Browser Toolbox more secure on Firefox desktop.

    If there are features you’d like to see added, file bugs or contact the team via various channels.

  8. Firefox OS, Animations & the Dark Cubic-Bezier of the Soul

    I’ve been using Firefox OS daily for a couple of years now (wow, time flies!). While performance has steadily improved with efforts like Project Silk, I’ve often noticed delays in the user interface. I assumed the delays were because the hardware was well below the “flagship” hardware I’ve become accustomed to with Android and iOS devices.

    Last year, I built Firefox OS for a Nexus 4 and started using that as my daily phone. Quickly I realized that even with better hardware, I sometimes had to wait on Firefox OS for basic interactions, even when the task wasn’t computationally intensive. I moved on to a Nexus 5 and then a Sony Z3 Compact, both with better specs than the Nexus 4, and experienced the same thing.

    Time passed. Frustration grew. Whispers of a nameless fear…

    Running the numbers

    While reading Ralph Thomas’s post about creating animations based on physical models, I wondered about the implementation of animations in Firefox OS, and how that might be involved in this problem. I performed an audit of the number of instances of different animations, grouped by their duration. I removed progress indicators and things like the boot shutdown animation. Here are the animation and transition durations in Firefox OS, grouped by duration, for transitional interactions like scaling, opening, closing and sliding:

    • 0.1s: 15
    • 0.2s: 57
    • 0.3s: 79
    • 0.4s: 40
    • 0.5s: 78
    • 0.6s: 8

    A couple of things stand out. First, we have a pretty wide distribution of animation durations. Second, the vast majority of the animations are more than 300ms long!

    In fact, in more than 80 animations we are making the user wait more than half a second. These slow animations are dragging us down, resulting in a poorer overall experience of Firefox OS.

    How did we get here?

    The Firefox OS UX and interaction designers didn’t huddle in a room and design each interaction to be intentionally slow. The engineers who implemented these animations didn’t ever think to themselves “this feels really responsive… let’s make it slower!”

    My theory is that interactions like these don’t feel slow while you’re designing and implementing them, because you’re working with a single interaction at a time. When designing and developing an animation, I look for fluidity of motion, the aesthetics of that single action and how the visual impact enhances the task at hand, and then I iterate on duration and effects until it feels right.

    We do have guidelines for responsiveness and user-perceived performance in Firefox OS, written up by Gordon Brander, which you can see in the screenshot below. (Click the image for a larger, more readable version.) However, those guidelines don’t cover the sub-second period between the initial perception of cause and effect and the next actionable state of the user interface.

    Screenshot 2015-04-18 09.38.10

    Users have an entirely different experience than we do as developers and designers. Users make their way through our animations while hurriedly sending a text message, trying to capture that perfect moment on camera, entering their username and password, or arduously uploading a bunch of images one at a time. People are trying to get from point A to point B. They want to complete a task… well, actually not just one: Smartphone users are trying to complete 221 tasks every day, according to a study in the UK last October by Tecmark. All those animations add up! I assert that the aggregate of those 203 animations in Gaia that are 300ms and longer contributes to the frustrating feeling of slowness I was experiencing before digging into this.

    Making it feel fast

    So I tested this theory, by changing all animation durations in Gaia to 200ms, as a starting point. The result? Firefox OS feels far more responsive. Moving through tasks and navigating around the OS felt quick but not abrupt. The camera snaps to readiness. Texting feels so much more fluid and snappy. Apps pop up, instead of slowly hauling their creaky bones out of bed. The Rocketbar gets closer to living up to its name (though I still think the keyboard should animate up while the bar becomes active).

    Here’s a demo of some of our animations side by side, before and after this patch:

    There are a couple of things we can do about this in Gaia:

    1. I filed a bug to get this change landed in Gaia. The 200ms duration is a first stab at this until we can do further testing. Better to err on the snappy side instead of the sluggish side. We’ve got the thumbs-up from most of the 16 developers who had to review the changes, and are now working with the UX team to sign off before it can land. Kevin Grandon helped by adding a CSS variable that we can use across all of Gaia, which will make it easier to implement these types of changes OS-wide in the future as we learn more.
    2. I’m working with the Firefox OS UX team to define global and consistent best-practices for animations. These guidelines will not be correct 100% of the time, but can be a starting point when implementing new animations, ensuring that the defaults are based on research and experience.
    If you are a Firefox OS user, report bugs if you experience anything that feels slow. By reporting a bug, you can make change happen and help improve the user experience for everyone on Firefox OS.

    If you are a developer or designer, what are your animation best-practices? What user feedback have you received on the animations in your Web projects? Let us know in the comments below!

  9. ES6 In Depth: An Introduction

    Welcome to ES6 In Depth! In this new weekly series, we’ll be exploring ECMAScript 6, the upcoming new edition of the JavaScript language. ES6 contains many new language features that will make JS more powerful and expressive, and we’ll visit them one by one in weeks to come. But before we start in on the details, maybe it’s worth taking a minute to talk about what ES6 is and what you can expect.

    What falls under the scope of ECMAScript?

    The JavaScript programming language is standardized by ECMA (a standards body like W3C) under the name ECMAScript. Among other things, ECMAScript defines:

    What it doesn’t define is anything to do with HTML or CSS, or the Web APIs, such as the DOM (Document Object Model). Those are defined in separate standards. ECMAScript covers the aspects of JS that are present not only in the browser, but also in non-browser environments such as node.js.

    The new standard

    Last week, the final draft of the ECMAScript Language Specification, Edition 6, was submitted to the Ecma General Assembly for review. What does that mean?

    It means that this summer, we’ll have a new standard for the core JavaScript programming language.

    This is big news. A new JS language standard doesn’t drop every day. The last one, ES5, happened back in 2009. The ES standards committee has been working on ES6 ever since.

    ES6 is a major upgrade to the language. At the same time, your JS code will continue to work. ES6 was designed for maximum compatibility with existing code. In fact, many browsers already support various ES6 features, and implementation efforts are ongoing. This means all your JS code has already been running in browsers that implement some ES6 features! If you haven’t seen any compatibility issues by now, you probably never will.

    Counting to 6

    The previous editions of the ECMAScript standard were numbered 1, 2, 3, and 5.

    What happened to Edition 4? An ECMAScript Edition 4 was once planned—and in fact a ton of work was done on it—but it was eventually scrapped as too ambitious. (It had, for example, a sophisticated opt-in static type system with generics and type inference.)

    ES4 was contentious. When the standards committee finally stopped work on it, the committee members agreed to publish a relatively modest ES5 and then proceed to work on more substantial new features. This explicit, negotiated agreement was called “Harmony,” and it’s why the ES5 spec contains these two sentences:

    ECMAScript is a vibrant language and the evolution of the language is not complete. Significant technical enhancement will continue with future editions of this specification.

    This statement could be seen as something of a promise.

    Promises resolved

    ES5, the 2009 update to the language, introduced Object.create(), Object.defineProperty(), getters and setters, strict mode, and the JSON object. I’ve used all these features, and I like what ES5 did for the language. But it would be too much to say any of these features had a dramatic impact on the way I write JS code. The most important innovation, for me, was probably the new Array methods: .map(), .filter(), and so on.

    Well, ES6 is different. It’s the product of years of harmonious work. And it’s a treasure trove of new language and library features, the most substantial upgrade for JS ever. The new features range from welcome conveniences, like arrow functions and simple string interpolation, to brain-melting new concepts like proxies and generators.

    ES6 will change the way you write JS code.

    This series aims to show you how, by examining the new features ES6 offers to JavaScript programmers.

    We’ll start with a classic “missing feature” that I’ve been eager to see in JavaScript for the better part of a decade. So join us next week for a look at ES6 iterators and the new for-of loop.

  10. Easier in-app payments with fxpay

    For developers building web applications on Firefox OS or Firefox Desktop, supporting payments is easy with Mozilla’s fxpay library. In addition to accepting credit cards, Mozilla’s payment system lets users charge purchases directly to their phone bill in many countries—making it ideal for mobile commerce.

    Since our first introduction to fxpay the library has received a lot of bug fixes and new features. Based on developer feedback, we also decided to offer a new interface supporting native promises (shimmed on older browsers) for flexibility and better error handling. This article explains how to retrieve products, process payments, and restore products from receipts.

    If you’ve already set up in-app payments using the mozPay API directly, consider porting to fxpay for the convenience of Mozilla-hosted products and additional features such as desktop payments. At the very least, please make sure your JWT libraries are patched for the latest security vulnerabilities.

    Let’s get started! After installing the fxpay library, you can begin testing it out with some fake products.

    fxpay.configure({fakeProducts: true});
    fxpay.getProducts()
      .then(function(products) {
        products.forEach(function(product) {
          addBuyButtonForProduct(product);
        });
      })
      .catch(function(error) {
        console.error('error getting products: ' + error);
      });
    

    This retrieves some pre-configured fake products that you can play around with. Once you’ve configured real products on the Firefox Marketplace Developer Hub, you can remove this configuration value to work with real products.

    In the example function called above, you could display a buy button per product like this:

    function addBuyButtonForProduct(product) {
      var button = document.createElement('button');
      button.textContent = 'Buy ' + product.name;
      button.addEventListener('click', function () {
     
        fxpay.purchase(product.productId)
          .then(function(purchasedProduct) {
            console.log('product purchased! ', 
                        purchasedProduct);
          })
          .catch(function(error) {
            console.error('error purchasing: ' + error);
          });
     
      });
      document.body.appendChild(button);
    }
    

    The fxpay library does all the payment processing behind the scenes using Mozilla’s web services so when the promise resolves, it’s safe to deliver the product. At this time, fxpay also installs a receipt on the user’s device. When the user returns to your app later on, you’ll want to check for any receipts so you can restore their purchases.

    Here’s a rewrite of the product fetching code to restore purchased products:

    fxpay.getProducts()
      .then(function(products) {
        products.forEach(function(product) {
        
          if (product.hasReceipt()) {
            product.validateReceipt()
              .then(function(restoredProduct) {
                console.log('restored product from receipt:', 
                            restoredProduct);
              })
              .catch(function(error) {
                console.error('error validating receipt: ' + 
                              error);
              });
          } else {
            addBuyButtonForProduct(product);
          }
        
        });
      });
    

    We’re hoping this new interface makes experimenting with in-app payments even easier than before. You never know what kind of business model will work in your app so why not try out some ideas?

    The complete usage guide to fxpay is here on MDN.