Mozilla

Articles

Sort by:

View:

  1. 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 for-in 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, for-in 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 for-in—yes, even its behavior on arrays. So there was never any question of “fixing” for-in 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 for-of 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 for-in
    • unlike forEach(), it works with break, continue, and return

    The for-in loop is for looping over object properties.

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

    But that’s not all.

    Other collections support for-of too

    for-of 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. for-of is designed to be the workhorse loop statement you use with all of them.

    for-of does not work with plain old Objects, but if you want to iterate over an object’s properties you can either use for-in (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 for-of 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, for-of 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 for-of 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 for-of 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 for-of 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 for-of 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 for-of 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 for-of 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: for-of 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 for-of loop and rewrite it in terms of the underlying method calls.

    First the for-of 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. for-of is easy to use, but there is a lot going on behind the scenes.

    When can I start using this?

    The for-of 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 for-of in io.js (and Node, with the --harmony option) today.

    (UPDATE: This previously neglected to mention that for-of 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 for-of loop.

    There is one more new kind of object in ES6 that works beautifully with for-of. 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.

  2. 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.

  3. 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!

  4. 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.

  5. 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.

  6. Network Activity and Battery Drain in Mobile Web Apps

    Editor’s note: This post describes the work of a group of students from Portland State University who worked with Mozilla on their senior project. Over the course of the last 6 months, they’ve worked with Mozillian Dietrich Ayala to create a JavaScript library that allows developers to optimize the usage of network operations, thus saving battery life. The group consists of 8 students with varied technology backgrounds, each assigned to take on a different task for the project. Congratulations to the team:

    Overview and Goals of the Project

    The goal of our senior Capstone project was to develop a JavaScript library to make it easier for developers to write applications that use less power by making fewer network requests. In emerging markets, where battery capacities in mobile devices may be smaller and signal strength may be poor, applications that make many requests create serious challenges for the usability of smartphones. Sometimes, applications designed for users in regions with robust network infrastructure can create significant negative effects for users with less reliable access. Reducing battery drain can provide better battery life and better user experiences for everyone. To improve this situation, we’ve created APIs that help developers write mobile applications in a way that minimizes network usage.

    In order to solve this problem effectively, we provide developers with mechanisms to delay non-critical requests, batch requests together, and detect when the network conditions are best for a given activity. This involved doing research to determine the efficacy of various solutions. Regardless of the effectiveness of our APIs, this research provides insight into saving battery usage. In addition to our research, we also focused on the developer ergonomics, hoping to make this easy for developers to use.

    Installation & Usage

    Installation of the library is simple: clone the “dist” folder and choose the library variant that best suits your needs. LocalForage is used in the library for storing the statistical details for each XMLHttpRequest (XHR). This way the developer can perform analysis to develop a set of dynamic heuristics such as utilizing when the user is most likely to make successful XHRs. However, if this is something you do not think will be commonly used, you can opt for a LocalForage-free version to get a smaller library memory footprint.

    We encourage you to check out our General Usage section and API Usage section to get a comprehensive idea of usage and context. A brief overview of how to use the core functions of the APIs is provided.

    Critical Requests

    When you need to make a critical XHR for something that the user needs right away, you make it using the following syntax:

    AL.ajax(url [, data] [, success] [, method])

    Where url indicates the endpoint, data is the parameter you pass JSON data to (i.e., POST XHR), success is called after the request has completed successfully, and the optional method parameter specifies the HTTP method to use (e.g. Patch, Post). If method is not specified, and the data field is null, GET will be used, but if data is used, POST will be the default.

    A sample critical request would look like this:

    AL.ajax('http://rocky-lake-3451.herokuapp.com/', {cats: 20}, function(response, status, xhr) {
    console.log('Response: ', response);
    console.log('Status: ', status);
    console.log('Xhr: ', xhr);
    });

    This code when executed would result in the following output:

    Response: {"request_method":"POST","request_parameters":[]}
    Status: 200
    Xhr: XMLHttpRequest { readyState=4, timeout=0, withCredentials=false, ...}

    Non-Critical Requests

    Non-critical requests are used for non-urgent needs and work by placing the non-critical XHR(s) in a queue which is fired upon certain conditions. The two default conditions are ‘battery is more than 10% and a critical request was just fired’ or ‘battery is more than 10% and the device is plugged in to a power source’. The syntax for making a non-critical request is the same as a critical one, with the exception of the function name and an additional parameter, timeout:

    AL.addNonCriticalRequest(url [, data] [, success] [, method] [, timeout])

    Here’s how timeout works: given a number of milliseconds, the XHR added (and all other XHR in the queue) will fire off if the queue is not already fired off by some other mechanism such as a critical request firing.

    Recording & Analysis

    XHRs are stored within LocalForage. There are a variety of functions to either retrieve the data or trim it. General retrieval syntax is in this format, where callback is an array of XHR-related objects that contain data relevant to the XHR such as start time, end time, and size of the request.

    AL.getHistory(callback)

    You can use this data in all manner of interesting ways, but at a basic level you’ll want to time the XHRs. Calculate the difference between start time and end time of the request for the five most recent requests by doing the following:

    
    function getRecords() {
    var elem = document.getElementById('recordsList');
    AL.getHistory(function (records) {
    if (records) {
    var counter = 0;
    var string = [];
    for (var i = Math.max(records.length - 5, 0); i < Math.max(records.length, 0); ++i) {
    string[counter] = records[i].end - records[i].begin;
    ++counter;
    }
    elem.innerHTML = string.toString();
    }
    else {
    console.log("Records is null");
    }
    });
    }

    Research Findings

    In order to gather data about the effectiveness of our APIs on reducing battery usage, we hooked up our reference device (a Flame) to a battery harness and used our demo app to process 30 requests of various different types of media (text, images, and video). All three tests were run on a WiFi network (our university’s WiFi network, specifically). We attempted to run all three tests on a 3G (T-Mobile) network, but due to poor connectivity, we were only able to run the text test over a cellular network.

    When running the tests on WiFi, we noticed that the WiFi chip was extremely efficient. It would turn on almost instantly and once all network requests were done, it would turn off just as quickly. Because of this, we realized that the library is not very useful when on a WiFi network; it is hard to be more efficient than instant on/off.

    When testing on a 3G network however, it became very apparent that this library could be useful. On the graph of power consumption, there is a very clear (and relatively slow) period where the chip warms up, increasing its power usage gradually until it is fully powered. Once all network activity is complete, there is an even longer period of cool down, as the power draw of the chip gradually declines. It is clear that stacking the requests together is useful on this type of network to avoid dead periods, when the phone is powering down the chips due to lack of activity just as another request comes in, causing chips to be powered back up again at the same slow rate.

    Text over WiFi

    Screen turned on around 2 seconds, 30 XHMLHttpRequest burst sent from roughly the 6 second mark to the end of the graph (~13.5 second mark)

    Text over 3G

    Screen turned on around 2 seconds, 30 XHMLHttpRequest burst sent from roughly the 2 second mark to roughly the 18 second mark

    In conclusion, we believe our library will prove useful when the cellphone is using a 3G network and will help conserve battery usage for requests that are not immediately necessary. Furthermore, the optional data analytics backbone can help advanced developers generate unique heuristics per user to further minimize battery drain.

    Portland State University Firefox OS Capstone Team

    Portland State University Firefox OS Capstone Team: Back row: Tim Huynh, Casey English, Nathan Kerr, Scott Anecito. Front row: Brianna Buckner, Ryan Niebur, Sean Mahan, Bin Gao (left to right)

  7. Creating a mobile app from a simple HTML site: Part 2

    Or: Making our simple app work for others

    In the first part of this series, which began late last year, we worked through the process of developing a school planner app. At this point (see the final code from Part 1) we’ve got multiple school plans displayed at once, and we’ve got Web, iOS and Android support via Cordova.

    Stage4 Result Screenshot<br />

    Let’s imagine that others have seen the benefits and would like to use our app as well. Creating an app tailored to them should be possible by simply replacing one file (let’s name it www/app_data/plans.json) with their family’s data and making a few other tweaks. This is where we will focus in the beginning of this part.

    Our eventual goal is to create an app to display data (school plans) stored on a server, so every user can view their own data from any computer. In this tutorial, the server part will be minimized to avoid distraction from the main goal — the database of plans is going to be written into a JSON file. If you wish to extend it into SaaS please do so, and let us know in the comments section below.

    What will be built

    A mobile application which will:

    1. Display school plan(s).
    2. Work offline.
    3. Work on many platforms.
    4. Use school plans stored on a server/in a JSON file (our goal for next parts of the series).

    Prerequisites

    If you haven’t worked through the first article then we suggest you do so now. You should at least go through the part 1 prerequisites and make sure you are familiar with them.

    Then follow the steps below, updating your code example from the previous article. If you don’t have this code example, (i.e., if you’ve not gone through the previous article), follow the instructions on how to load any stage in this tutorial. Use stage4 as a starting point.

    You should also make sure you have NodeJS installed.

    Adding an icon

    In Part 1, I omitted the icon, so Cordova added a default one. Let’s make the app look more professional with a custom icon. I’ve downloaded a backpack icon from findicon.com resized it and copied to www/img. In the app directory (school-plan/ — created after running cordova create) — edit the config.xml file and add the following:

    <icon src="www/img/backpack-128.png" />

    If you wish you can add more specific information – for example, more image sizes for each desired platform. You can find more information in Cordova docs. Here is the special definition for Firefox OS:

    <platform name="firefoxos">
    	<icon width="128" height="128" src="www/img/backpack-128.png" />
    	<icon width="64" height="64" src="www/img/backpack-64.png" />
    	<icon width="32" height="32" src="www/img/backpack-32.png" />
    </platform>
    

    Due to an error in the Firefox OS part of Cordova, please also create the www/icon directory using the following command.

    mkdir www/icon

    Modifying the data code

    In this stage we will modify the school plan app to work with data instead of plain HTML (see finished stage 5 code on GitHub.)

    Before we had all school plan’s data hard coded into index.html. Now we will separate the data from its visual representation. To do so, we will remove the old data from www/index.html, leaving only the minimal structure behind.

    Empty both the <brick-tabbar> and <brick-deck> elements in your index.html file, so they are left looking like so:

    <brick-tabbar id="plan-group-menu" selected-index="0">
    </brick-tabbar>
    <brick-deck id="plan-group" selected-index="0">
    </brick-deck>
    

    The most common data structure used in JavaScript projects is JSON; we will therefore add our data in this format. For now it’s OK to distribute the school plan together with the app (later on we will probably serve it from a server instead, for greater flexibility). Our JSON contains an Array of plans. Plan is an Object containing title, id, optional active field and week. The latter is itself an Array of lesson plans.

    Note: use jsHint to check the quality of your code.

    [
        {
          "title": "Name of the plan",
          "id": "id-of-the-plan",
          "active": 1,  // should the plan be active now?
          "week": [
            [
              "first hour of Monday",
              "second hour",
              "third",
              // ... and so on
            [],  // no activities on Tuesday
            ], [
              "",
              "",
              "Wednesday is starting on third hour",
              "fourth"
            ]
        }
    ]
    

    You can find a sample file on Github. Copy this into your project at www/app_data/plans.json.

    Now we need to read this JSON file from the app’s directory.

    As the cards and tabs do not exist at the moment of loading the JavaScript file we should now remove the part where these were linked together from www/js/index.js. Go to this file, find the assignTabs() function, and remove it completely, along with the call to it just below.

    The application will show nothing without the data. Data needs to be loaded just after the app is ready — find the onDeviceReady method and just inside it at the top enter the following lines of code:

    var request = new XMLHttpRequest();
    request.onload = app.renderData;
    request.open("get", "app_data/plans.json", true);
    request.send();
    

    Note: Previously I planned to use Cordova’s FileSystem plugin, but it only made the code more complicated.

    After the request successfully returns our JSON, it is passed to app.renderData (seen below). It parses the text in JSON format to JavaScript and sends data to app.createUI so the necessary DOM elements will be created to form the UI.

    Add the following code block below the onDeviceReady method:

    renderData: function() {
        var plans = JSON.parse(this.responseText);
        app.createUI(plans);
    },
    

    To create the UI we will need weekday names. The best option is to use Cordova’s Globalization plugin. To add this plugin to the application simply run the following command in your terminal, making sure you are inside your root school-plan directory:

    cordova plugin add org.apache.cordova.globalization
    

    Next, add the createUI() method we referenced earlier underneath the renderData() method. It looks like so:

    createUI: function(plans) {
        var deck = document.getElementById('plan-group');
        var tabbar = document.getElementById('plan-group-menu');
        navigator.globalization.getDateNames(function(dayOfWeek) {
            // render UI in the callback
        }, function() {}, {type: 'narrow', item: 'days'});
    },

    Week days are retrieved using the navigator.globalization.getDateNames method. dayOfWeek will hold an Array of week day names, for example (Polish in my case) — ['Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So', 'Nd']. If you’d like to use full day names, just change type: 'narrow' to type: 'wide'.

    Now we need to create DOM elements for individual plans. This time brick-tabbar-tab and brick-card elements are created using JavaScript. Tab refers to the corresponding card using its target parameter. It has the same value as the card’s id in each case. Brick will parse this value and create a tab.targetElement, which will link to the card element. Inside the callback of getDateNames, enter the following code (in place of the “// render UI in the callback” comment seen above):

    for (var i = 0; i < plans.length; i++) {
        var plan = plans[i];
    
        // create card
        var card = document.createElement('brick-card');
        card.setAttribute('id', plan.id);
        deck.appendChild(card);
    
        //create tab
        var tab = document.createElement('brick-tabbar-tab');
        tab.setAttribute('target', plan.id);
        tab.appendChild(document.createTextNode(plan.title));
        tabbar.appendChild(tab);
    
        // link card to tab
        card.tabElement = tab;
        card.addEventListener('show', function() {
            this.tabElement.select();
        });
    
        // create plan table
        var table = document.createElement('table');
    }
    

    Unlike when writing plain HTML, we will create the table body now and then the header. This is because table.insertRow() either creates a new tbody and tr inside or adds a row to any existing HTMLTableSectionElement (thead if already created). We could also call table.tBodies(0) instead but it would complicate the code.

    We don’t want to display days which don’t have any lessons. Let’s copy the plan with only non-empty days to new cleanPlan array. Place this code after the line that creates the <table> element (see above listing):

    var numberOfDays = plan.week.length;
    var cleanPlan = [];
    for (j = 0; j < numberOfDays; j++) {
        if (plan.week[j].length > 0) {
            cleanPlan.push(plan.week[j]);
        }
    }
    

    There is a problem that needs to be solved before we can create the other DOM elements (<tr> and <td>) — we’re representing the plan in a JSON file structured as humans understand it — hours inside days. Unfortunately tables in HTML are created row by row (days inside hours), which means that the array representing the plan needs to be flipped over.

    For example our array stored in JSON will look like this: (dXhY represents day X and hour Y):

    d1h1 d1h2 d1h3 ...
    d2h1 d2h2 d2h3 ...
    d3h1 d3h2 d3h3 ...
    ...
    

    But our <table> structure will look like this:

    d1h1 d2h1 d3h1 ...
    d1h2 d2h2 d3h2 ...
    d1h3 d2h3 d3h3 ...
    ...
    

    Add the following code block right after the last one, to start performing this data transformation for us:

    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];
        }
    }
    

    The most important line above is the daysInHours[k][j] = cleanPlan[j][k]; where the indexes are reversed — the kj element of one array becomes the jk element of the other. d3h2 takes the place of d2h3 and vice versa.

    The daysInHours array should now hold the plan prepared for the UI. Now we can iterate over it to render the plan into the HTML table. There is an important thing to note here — table.insertRow needs to use the (otherwise optional) index set to -1, as by default Android inserts the row on top of the table.

    Add the following block right below the previous one:

    for (var j = 0; j < daysInHours.length; j++) {
        var tr = 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]));
            }
        }
    }
    

    We iterate over all the hours (index j). The first <tr> is created at the bottom of the array, then the <td> with the textNode containing that row number. After that we iterate over the days inside the hour (index k) and create more cells — if there is a plan for this hour and day a textNode is created.

    You might be surprised to see this code using cleanPlan.length instead of daysInHours[j].length. This is because we need to create a cell on each day even if no lesson is planned, otherwise we will end up with a broken table structure like this:

    short row issue

    Now we’re ready to create a header with days. Add the following code block right below the previous one:

    var thead = table.createTHead();
    var tr = thead.insertRow();
    var th_empty = document.createElement('th');
    tr.appendChild(th_empty);
    var weekDayNumber;
    for (var j = 0; j < numberOfDays; j++) {
        var weekDayNumber = (j + 1) % 7;
        if (plan.week[j].length > 0) {
            var th = document.createElement('th');
            th.appendChild(document.createTextNode(dayOfWeek.value[weekDayNumber]));
            tr.appendChild(th);
        }
    }
    

    First, an empty header cell is created for the column, containing the corresponding hour of the day. Then we iterate over the days and create a new <th> with a day name only if there is a plan for the current day (in the same manner as for cleanPlan before.)

    Next we need a line to place the created <table> inside the brick-card element — add the following line below the previous block:

    card.appendChild(table);

    When all tabs are ready, we’ll want the first tab to be selected when the app is loaded. To do this we’ll use the following block — add this just below the previous line:

    if (plan.active) {
        selectTab(deck, tab);
    }
    

    selectTab is a helper function created outside of the app object. It is using polling on activeTab.targetElement to detect if Brick had already linked tab with cards, as seen below. Add this block at the very bottom of your index.js file:

    function selectTab(deck, activeTab) {
        function selectActiveTab() {
            if (!activeTab.targetElement) {
                return window.setTimeout(selectActiveTab, 100);
            }
            deck.showCard(activeTab.targetElement);
        }
        selectActiveTab();
    }
    

    Testing time

    At this moment the app should work exactly the same as on Stage 4 in Part 1. The only difference may be in the localized names of the days in the plan’s header.

    When you want to test your app, type in the following terminal commands (from the root directory of your school-plan app):

    cordova prepare
    cordova serve
    

    This will make the app and its different platforms available to you at localhost:8000.

    If you also want to test the app in Firefox OS, you’ll need to open WebIDE in Firefox, go to Open App > Open Packaged App, and from the file chooser select to open the school-plan/platforms/firefoxos/www directory as a packaged app. From here you can choose to load the app in a simulator or a real Firefox OS device. See the MDN WebIDE page for more details.

    Note: If you’d like to tailor the application for different people who want to use it, at this stage you can do so by replacing the www/app_data/plans.json file with different information for each individual user.

    [EDIT] See the <a href="https://hacks.mozilla.org/2015/04/creating-a-mobile-app-from-a-simple-html-site-part-3/"next part where we added the server.

  8. Drag Elements, Console History, and more – Firefox Developer Edition 39

    Quite a few big new features, improvements, and bug fixes made their way into Firefox Developer Edition 39. Update your Firefox Developer Edition, or Nightly builds to try them out!

    Inspector

    The Inspector now allows you to move elements around via drag and drop. Click and hold on an element and then drag it to where you want it to go. This feature was added by contributor Mahdi Dibaiee.

    Back in Firefox 33, a tooltip was added to the rule view to allow editing curves for cubic bezier CSS animations. In Developer Edition 39, we’ve greatly enhanced the tooltip’s UX by adding various standard curves you can try right away, as well as cleaning up the overall appearance. This enhancement was added by new contributor John Giannakos.

    cubic

    The CSS animations panel we debuted in Developer Edition 37 now includes a time machine. You can rewind, fast forward, and set the current time of your animations.

    Console

    Previously, when the DevTools console closed, your past Console history was lost. Now, Console history is persisted across sessions. The recent commands you’ve entered will remain accessible in the next toolbox you open, whether it’s in another tab or after restarting Firefox. Additionally, we’ve added a clearHistory console command to reset the stored list of commands.

    The shorthand $_ has been added as an alias for the last result evaluated in the Console. If you evaluated an expression without storing the result to a variable (for example), you can use this as a quick way to grab the last result.

    We now format pseudo-array-like objects as if they were arrays in the Console output. This makes a pseudo-array-like object easier to reason about and inspect, just like a real array. This feature was added by contributor Johan K. Jensen.

    pseudo-array

    WebIDE and Mobile

    WiFi debugging for Firefox OS has landed. WiFi debugging allows WebIDE to connect to your Firefox OS device via your local WiFi network instead of a USB cable. We’ll discuss this feature in more detail in a future post.

    WebIDE gained support for Cordova-based projects. If you’re working on a mobile app project using Cordova, WebIDE now knows how to build the project for devices it supports without any extra configuration.

    Other Changes

    • Attribute changes only flash the changed attribute in the Markup View, instead of the whole element.
    • Canvas Debugger now supports setTimeout for animations.
    • Inline box model highlighting.
    • Browser Toolbox can now be opened from a shortcut: Cmd-Opt-Shift-I / Ctrl-Alt-Shift-I.
    • Network Monitor now shows the remote server’s IP address and port.
    • When an element’s highlighted in the Inspector, you can now use the arrow keys to highlight the current element’s parent (left key), or its first child, or its next sibling if it has no children, or the next node in the tree if it has no siblings (right key). This is especially useful when an element and its parent occupy the same space on the screen, making it difficult to select one of them using only the mouse.

    For an even more complete list, check out all 200 bugs resolved during the Firefox 39 development cycle.

    Thanks to all the new developers who made their first DevTools contribution this release:

    • Anush
    • Brandon Max
    • Geoffroy Planquart
    • Johan K. Jensen
    • John Giannakos
    • Mahdi Dibaiee
    • Nounours Heureux
    • Wickie Lee
    • Willian Gustavo Veiga

    Do you have feedback, bug reports, feature requests, or questions? As always, you can comment here, add/vote for ideas on UserVoice, or get in touch with the team at @FirefoxDevTools on Twitter.

  9. Mobile game development with the Device Orientation and Vibration APIs

    The market for casual mobile gaming is keeping pace with the growing market for smartphones. There are Web tools that can help web developers like you build games that compete with native games. You’ll need great execution to stand out from the crowd – using the JavaScript APIs correctly can help. For game development, you’ll want to understand the Device Orientation API and the Vibration API.

    Continued…

  10. Trainspotting: Firefox 37, Developer Edition and More

    Welcome to Trainspotting, a new series on Mozilla Hacks designed to help the busy Web developer keep up with what’s new, what’s changed and what is coming soon in all of the Firefoxes, the Web platform, and the tools for building the Web!

    Mozilla develops Gecko and Firefox on a “train model” – we branch the code and ship a release on a time-based schedule (every six weeks). If a feature is not finished, it’s reverted or disabled and has to, as we say, ride the next train. This means we ship new features, performance improvements, and bug fixes to users every six weeks, instead of having to wait up to 18 months.

    Trainspotting will publish every six weeks when we branch the code – and we’ll point out any changes that might require action or cause compatibility issues, as well as new features that Web developers would want to take advantage of.

    Firefox 37

    For a detailed list of all noted changes in the release, check out the official release notes for Firefox 37. Below is a list of notable features, links to documentation, and anything that requires action by developers or site operators.

    Desktop Features

    • A subset of the Media Source Extensions (MSE) API has been implemented and is enabled to allow native playback of HTML5 video on websites such as YouTube. You can read about the various MSE APIs and their usage on MDN.
    • Bing search now uses HTTPS. Hurray for private and secure searching!
    • Heartbeat is a new feedback feature in Firefox desktop: Each day a random subset of Firefox users will be shown a notification bar with an opportunity to provide feedback on their experience. You can see screenshots and read more about how it works on the Heartbeat project page.

    Firefox for Android

    This time around, Firefox for Android is getting a security and stability release. The biggest user-facing changes—improved performance of file downloads, and the addition of some new locales: Albanian, Burmese, Lower Sorbian, Songhai, Upper Sorbian, Uzbek. Read the full list of security fixes for Firefox Android 37 and the full release notes.

    HTML5 & Web Platform

    There are a bunch of new Web platform features that you can now use in production content in Firefox 37, and here are a few examples:

    Keep reading the Firefox 37 for Developers article on MDN for a detailed look at all the rest.

    Developer Tools

    If you’re using Firefox Developer Edition these additions won’t be news, but if you’ve been doing your development in the release build, there are a few new features to note:

    Security

    Firefox 37 has a bunch of security changes. Most of these do not require any action, however if you are a site operator you should definitely look to see if any of these changes impact you. Big thanks to David Keeler, security engineer for Firefox, for his help deciphering this section of the release notes.

    • We removed support for DSA in certificates and TLS, because we found that almost nobody was using these. If you’re a site operator and your certificate was signed with a DSA algorithm, contact your CA and get a new certificate. You can check with `openssl x509 -in {certificate file} -text -noout` and search for “Signature Algorithm.” If you do have one of these certificates and do not change it, users will see an override-able error.
    • HTTP/2 AltSvc is temporarily disabled due to a bug. We implemented HTTP/2 AltSvc support for opportunistic encryption. This feature allows encryption over TLS for unauthenticated connections that would otherwise be clear text. Configuration is very simple, and Patrick McManus has written instructions for how to set it up on your server.
    • We have disabled insecure TLS version fallback. If a secure site isn’t working, you can try setting the “security.tls.version.fallback-limit” preference in about:config to 1 and see if it works then. If you see this anywhere, please file a Tech Evangelism bug, noting the URL of the site, so we can work with the operators to update it. Site operators should make sure their servers aren’t TLS-intolerant, which you can do with the SSL Labs tool.
    • Users can now report SSL connection problems for a variety of non-certificate-related errors. For example, if a user encounters a non-override-able TLS error, they can now send a report to Mozilla directly from the error page. The information in the report consists of the domain you were trying to reach, the certificates the server sent, the time, which error was encountered, and some user agent information. We use this information to work with site operators to fix their configurations, and to improve our software that detects these issues, so please do send reports. Check out a screenshot of what this looks like.
    • TLS False Start optimization now requires a cipher suite using AEAD construction. If you’re running a server and false start isn’t working as expected, try using an AEAD cipher suite. Learn more about AEAD at Wikipedia and in RFC 5288. The only AEAD cipher suite that Firefox supports at this time is AES-GCM.
    • We now log usage of weak ciphers to the web console. For example, if you visit a site with a SHA-1 certificate with the web console open you’ll now see a message like, “This site makes use of a SHA-1 Certificate; it’s recommended you use certificates with signature algorithms that use hash functions stronger than SHA-1. Learn more…” If you run a site and your certificate was signed with SHA-1, get a new certificate from your CA.

    Firefox Beta

    In six short weeks Beta will be available for general release, becoming Firefox 38. Here’s some of what’s coming your way:

    • All Firefox preferences are now in a new tab-based UI.
    • Improved page-load times with speculative connection warmup.
    • MSE support on Mac OS X.
    • EME support for encrypted media playback.
    • Web platform features: WebSockets in Web Workers, KeyboardEvent.code, and the BroadcastChannel API.

    Read the Firefox 38 Beta release notes for the full list.

    Firefox Developer Edition

    This release of Firefox Developer edition (which will be Firefox 39) is frankly kind of ridiculous. The developer tools are getting precariously close to something indistinguishable from magic. Huge props to the developer tools team for what you’re about to see.

    • Developer Tools: Wi-Fi debugging of Firefox OS devices from WebIDE, drag and drop of nodes in the Inspector’s markup view, Web Console input history persistence, localhost works with WebSocket connections when you’re offline, and the cubic bezier tooltip now shows a gallery of pre-sets you can choose from to make your CSS animations super slick.
    • Web platform features include the “switch” role in Aria 1.1, CSS scroll snap points, Cache API, Fetch API, <link rel=”preconnect”> and more.

    Read the full release notes for this release of Firefox Developer Edition.

    Nightly

    The nightly branch of Firefox is where a lot of features are in active development. It’s a place where you can test experimental Web APIs and see user-facing browser features that are not yet ready for hundreds of millions of users. You might see a crash or two, you might lose you session data, but you also might experience the vision and wonder of what the future holds. It’s the Mos Eisley of browsers – a dangerous place, but we stick around for the action.

    There are a number of features that have landed and are shipping nightly builds either enabled by default or by pref:

    • E10s – Web content runs in a separate process from the browser UI.
    • Partial implementation of Service Workers.
    • Shumway – Flash implemented in JavaScript is enabled for some sites.

    Thus concludes the first edition of Trainspotting. Let us know what you think in the comments, and what you’d like to see more of!