Mozilla

Articles

Sort by:

View:

  1. BroadcastChannel API in Firefox 38

    Recently the BroadcastChannel API landed in Firefox 38. This API can be used for simple messaging between browser contexts that have the same user agent and origin. This API is exposed to both Windows and Workers and allows communication between iframes, browser tabs, and worker threads.

    The intent of the BroadcastChannel API is to provide an API that facilitates communicating simple messages between browser contexts within a web app. For example, when a user logs into one page of an app it can update all the other contexts (e.g. tabs or separate windows) with the user’s information, or if a user uploads a photo to a browser window, the image can be passed around to other open pages within the app. This API is not intended to handle complex operations like shared resource locking or synchronizing multiple clients with a server. In those cases, a shared worker is more appropriate.

    API Overview

    A BroadcastChannel object can be created by using the following code:

    var myChannel = new BroadcastChannel("channelname");

    The channelname is case sensitive. The BroadcastChannel instance contains two methods, postMessage and close. The postMessage method is used for sending messages to the channel. The message contents can be any object, including complex objects such as images, arrays, and arrays of objects. When the message is posted, all browser contexts with the same origin, user agent, and a BroadcastChannel with the same channel name are notified of the message. For example, the following code posts a simple string:

    myChannel.postMessage("Simple String");

    The dispatched message can be handled by any page with the channel opened by using the onmessage event handler of the BroadcastChannel instance.

    myChannel.onmessage = function(event) {
        console.log(event.data);
    }

    Note that the data attribute of the event contains the data of the message. Other attributes of the event may be of interest as well. For example, you can check the web app origin using the event.origin attribute or the channel name is available in the event.target.name attribute.

    The close method is used to close the channel for the particular browser context and can be called by simply using:

    broadCastChannel.close();

    Blob Message Posting

    While posting strings and other primitive types is fairly simple, the BroadcastChannel API supports more complex objects as well. For example, to post an Image from one context to another the following code could be used.

    var broadcastExample = {};
    broadcastExample.setupChannel = function() {
        if ("BroadcastChannel" in window) {
            if (typeof broadcastExample.channel === 'undefined' || 
               !broadcastExample.channel) {
                //create channel
                broadcastExample.channel = new BroadcastChannel("foo");
            }
        }
    }
    broadcastExample.pMessage = function() {
        broadcastExample.setupChannel();
        //get image element
        var img = document.getElementById("ffimg");
        //create canvas with image 
        var canvas = document.createElement("canvas");
        canvas.width = img.width;
        canvas.height = img.height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);
        //get blob of canvas
        canvas.toBlob(function(blob) {
            //broadcast blob
            broadcastExample.channel.postMessage(blob);
        });
    }

    The above code contains two functions and represents the sender side of a BroadcastChannel client. The setupChannel method just opens the Broadcast Channel and the pMessage method retrieves an image element from the page and converts it to a Blob. Lastly the Blob is posted to the BroadcastChannel. The receiver page will need to already be listening to the BroadcastChannel in order to receive the message and can be coded similar to the following.

    var broadcastFrame = {};
     
    //setup broadcast channel
    broadcastFrame.setup = function() {
        if ("BroadcastChannel" in window) {
            if (typeof broadcastFrame.channel === 'undefined' || !broadcastFrame.channel) {
                broadcastFrame.channel = new BroadcastChannel("foo");
            }
            //function to process broadcast messages
            function func(e) {
                if (e.data instanceof Blob) {
                    //if message is a blob create a new image element and add to page
                    var blob = e.data;
                    var newImg = document.createElement("img"),
                        url = URL.createObjectURL(blob);
                    newImg.onload = function() {
                        // no longer need to read the blob so it's revoked
                        URL.revokeObjectURL(url);
                    };
                    newImg.src = url;
                    var content = document.getElementById("content");
                    content.innerHTML = "";
                    content.appendChild(newImg);
                }
            };
            //set broadcast channel message handler
            broadcastFrame.channel.onmessage = func;
        }
    }
    window.onload = broadcastFrame.setup();

    This code takes the blob from the broadcast message and creates an image element, which is added to the receiver page.

    Workers and BroadcastChannel messages

    The BroadcastChannel API also works with dedicated and shared workers. As a simple example, assume a worker is started and when a message is sent to the worker through the main script, the worker then broadcasts a message to the Broadcast Channel.

    var broadcastExample = {};
    broadcastExample.setupChannel = function() {
        if ("BroadcastChannel" in window) {
            if (typeof broadcastExample.channel === 'undefined' || 
               !broadcastExample.channel) {
                //create channel
                broadcastExample.channel = new BroadcastChannel("foo");
            }
        }
    }
     
    function callWorker() {
        broadcastExample.setupChannel();
        //verify compat
        if (!!window.Worker) {
            var myWorker = new Worker("worker.js");
            //ping worker to post to Broadcast Channel
            myWorker.postMessage("Broadcast from Worker");
        }
    }
     
     
    //Worker.js
    onmessage = function(e) {
        //Broadcast Channel Message with Worker
        if ("BroadcastChannel" in this) {
            var workerChannel = new BroadcastChannel("foo");
            workerChannel.postMessage("BroadcastChannel Message Sent from Worker");
            workerChannel.close();
        }
    }

    The message can be handled in the main page in the same way as described in previous sections of this post.
    workerbroadcast
    Using a Worker to Broadcast a message to an iframe

    More Information

    In addition to demonstrating how to use in an iframe, another example of using the code in this post is available on github. More information about the BroadcastChannel API is available in the specification, bugzilla entry, and on MDN. The code and test pages for the API are located in the gecko source code.

  2. From Map/Reduce to JavaScript Functional Programming

    Since ECMAScript 5.1, Array.prototype.map & Array.prototype.reduce were introduced to major browsers. These two functions not only allow developers to describe a computation more clearly, but also to simplify the work of writing loops for traversing an array; especially when the looping code actually is for mapping the array to a new array, or for the accumulation, checksum, and other similar reducing operations.

    Left: using ordinary loop; Right: using map & reduce

    Left: using ordinary loop; Right: using map & reduce

     

    Map/Reduce

    Map actually means to compute things with the original array without doing structural changes to the output. For example, when map receives an array, you can make sure the output will be another array, and the only difference is that the elements inside it may be transformed from the original value/type to another value/type. So we can say the doMap function from the above example comes with the following type signature:

    doMap signature

    The signature reveals that [Number] means this is an array of numbers. So we now can read the signature as:

    doMap is a function, which would turn an array of numbers to an array of booleans

    On the other hand, the reducing operation means we may change the structure of the input data type to a new one. For example, the signature of the doReduce is:

    doReduce signature

    Here, the Array of [Number] is gone. So we can see the major difference between map and reduce1.

    Functional Programming

    In fact, the concepts of map and reduce are older even than JavaScript and are widely used in other functional programming languages, such as Lisp or Haskell2. This observation is noted in the famous article ‘JavaScript: The World’s Most Misunderstood Programming Language’ by Douglas Crockford 3:

    JavaScript’s C-like syntax, including curly braces and the clunky for statement, makes it appear to be an ordinary procedural language. This is misleading because JavaScript has more in common with functional languages like Lisp or Scheme than with C or Java.

    This is one reason why JavaScript can do some functional-like things which other orthogonal OOP languages can’t or won’t do. For example, before Java 8 4 5, if we wanted to do some ‘callback’ things common in JavaScript, we’d need to create a redundant ‘anonymous class.':

    Button button =
      (Button) findViewById(R.id.button);
    button.setOnClickListener(
      new OnClickListener() {
        public void onClick(View v) {
          // do something
        }
      }
    );

    Of course, using anonymous callbacks or not in JavaScript is always controversial. We may encounter callback hell especially when the component keeps growing. However, first-class functions can do lots of things beyond the callback. In Haskell, we can organize our whole GUI program similar to the Quake-like games6 with only functions7. That is, we can even make it without the classes, methods, inheritance, templates and other stuff8 people usually expect to have when a program needs to be constructed.

    Frag

    Frag, the Quake-like game in Haskell

    Therefore, in the JavaScript world, it’s possible to follow similar patterns to construct our programs, rather than hurriedly implementing our own ‘class’ and ‘class system,’ as programmers often do when starting on a problem9. Adding some functional flavor in JavaScript is not so bad after all, especially when features like map and reduce are supported by native APIs. To adopt this approach also means we can write more concise code10 by combining features instead of redefining them. The only limitation is the language itself is still not functional enough, so we may run into trouble if we play too many tricks, although this should be solvable with the right library11.

    map and reduce receive other functions as arguments and output them as results. This is important because in this way they present the basic idea of composing computations in the functional world, and are able to glue small pieces together with flexibility and scalability. For example, let’s take a look at the signature of our map expression mentioned above:

    map signature

    You’ll notice that the second argument indicates a function with type Number -> Boolean. In fact, you can give it any function with a -> b type. This may not be so odd in the world of JavaScript — we write tons of callbacks in our daily work. However, the point is that higher-order functions are functions as well. They can be composed into larger ones till we generate the complete program with only first-class functions and some powerful high-order functions like id, reduce, curry, uncurry, arrow and bind12.

    Map/Reduce in Practice

    Since we may encounter language limitations, we can’t write our JavaScript code in fully functional style; however, we can borrow the idea of types and composition to do lots of things. For example, when you think in types, you will find that map is not only for data handling:

    map & fold signatures

    This is what the type signatures for map and reduce would look like in Haskell. We can substitute the a and b with anything. So, what if a becomes SQL and b becomes IO x ? Remember, we’re thinking in type, and IO x is nothing more than an ordinary type like Int or URL:

    -- Let's construct queries from SQL statements.
    makeQueries strs = map str  prepare conn str
    doQuery qrys = foldl (results query  results >> query) (return ()) qrys 
    -- Do query and get results.
    let stmts = [ "INSERT INTO Articles ('Functional JavaScript')"
                , "INSERT INTO Gecko VALUES ('30.a1')"
                , "DELETE FROM Articles WHERE version='deprecated'"
                ]
    main = execute (doQuery (makeQuery stmts))`

    (Note: This is a simplified Haskell example for demo only. It can’t actually be executed.)

    The example creates a makeQueries function with map, which will turn the SQL into IO ()13; this also means we generate several actions which can be performed.

    makeQueries signature

    And then, the doQuery function, which is actually a reducing operation, will execute the queries:

    doQueries signature

    Note its reducing operation performs IO action with the help of the bind function (>>) of the specific Monad. This topic is not covered in this article, but readers should imagine this as a way to compose functions to execute them step by step, just as a Promise does24.

    The technique is useful not only in Haskell but also in JavaScript. We can use this idea with Promises and ES6 arrow functions to organize a similar computation:

      // Use a Promise-based library to do IO.
      var http = require("q-io/http")
         ,noop = new Promise(()=>{})
         ,prepare =
            (str)=> http.read('http://www.example.com/' + str)
                      .then((res)=> res.body.toString())
                      // the 'then' is equal to the '>>'
         ,makeQuery = 
            (strs)=> strs.map((str)=> prepare(str))
         ,doQuery = 
            (qrys)=> qrys.reduce((results, qry)=> results.then(qry), noop)
         ,stmts = [ "articles/FunctionalJavaScript"
                  , "blob/c745ef73-ece9-46da-8f66-ebes574789b1"
                  , "books/language/Haskell"
                  ]
         ,main = doQuery(makeQuery(stmts));

    (NOTE: In Node.js, the similar querying code with map/reduce and Promise would not run like the Haskell version, since we need Lazy Promise14 and Lazy Evaluation15)

    We’re very close to what we want: define computations with functions, and then combine them to perform it later, although the idea of ‘later’ is not actually true since we don’t have real lazy evaluation in JavaScript. This can be accomplished if we play the trick of keeping an undone Promise — a resolve function which is only resolved when we want to do so. However, even this is tricky, and there are still some unsolvable issues.

    Another thing to note is that our program doesn’t need variable variables, but some computation results are transformed and forwarded at every step of our program. In fact, this is just one reason why functional languages can stay pure, and thus they can benefit from the optimization and getting rid of unexpected side-effects 1617.

    More on Functional Programming

    Map/reduce are the most common functional features in JavaScript. With other not-so-functional features like Promise, we can use tricks like Monad-style computation control, or we can easily define curried functions with ES6’s fat-arrow functions18 and so on. Also, there are some excellent libraries which provide nice functional features19 20 21, and some Domain Specific Languages (DSLs) are even born with functional spirit 22 23. Of course, the best way to understand functional programming is to learn a language designed for it, like Haskell, ML or OCaml. Scala, F#, and Erlang are good choices, too.


    1. In fact, map can be implemented with reduce. The most basic operation for structure like this is reduce.
    https://github.com/timoxley/functional-javascript-workshop/blob/440da6737f34b4550301ba3a77b2e4b7721e99fd/problems/implement_map_with_reduce/solution.js#L11

    2. http://en.wikipedia.org/wiki/Lisp_(programming_language)#Control_structures

    3. http://javascript.crockford.com/javascript.html

    4. Java 8 now includes the lambda function: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

    5. C++ traditionally has not been a functional language, but C++11 introduces lambda functions: http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions

    6. https://www.haskell.org/haskellwiki/Frag

    7. Haskell can represent data structure in function sense, even though declaring a function and a data type are still not the same thing: http://book.realworldhaskell.org/read/data-structures.html

    8. Yes, I’m cheating: we have Typeclass, Functor, instance and type variable in Haskell.

    9. For those who can’t live without classes, ES6 is in your future: http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes

    10. I’ve found that some ‘bad functional code’ can be refactored as concisely as possible by strictly following some functional patterns. The most problematic ‘functional’ code happens when the coder mixes two programming styles badly. This can mix problems from two paradigms in a way that makes the code more complicated.

    11. I always hit a wall when I want to have nice Monad and lazy Promise in JavaScript. However, if you don’t mind a ‘crazy’ implementation, these are doable, and we can even have ‘Monad Transformer’ in JavaScript. Other features, like tail-recursion optimization and real lazy-evaluation, are impossible to do without runtime support.

    12. The functions arrow and bind are actually >>> and >>= in Haskell. They’re the keys In Haskell to compose our computation and program with specific effects; hence we can have state machine, networking, event handling, IO statements, and asynchronous flow control. Importantly, these are still plain functions.

    13. The type IO () means ‘do IO without any value returned.’ The IO a means some IO actions may get value a when the function had been performed, although some actions only get (). For example, the function to get a string from user input would be: ask:: IO String, while the function to print string out is print:: String -> IO String.

    14. http://www.jroller.com/vaclav/entry/promises_getting_lazy

    15. http://www.haskell.org/haskellwiki/Lazy_evaluation

    16. JavaScript can do this with a library for structures like map, set, and list. Facebook created a library of immutable data structures called immutable-js for this: https://github.com/facebook/immutable-js

    17. You can do almost the same thing with immutable-js and convince everyone to use only let and const to define variables.

    18. http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax

    19. wu.js: http://fitzgen.github.io/wu.js/

    20. Ramda: http://ramdajs.com/ramdocs/docs/

    21. transducer.js: http://jlongster.com/Transducers.js–A-JavaScript-Library-for-Transformation-of-Data

    22. LiveScript: http://livescript.net/

    23. Elm: http://elm-lang.org/

    24. No, they’re not really the same, but you *could* implement Promise in Monad

  3. Project Silk

    Editor’s Note: An earlier version of this post appeared on Mason Chang’s personal blog.

    For the past few months, I’ve been working on Project Silk which improves smoothness across the browser. Very much like Project Butter for Android, part of it is finally live on Firefox OS. Silk does three things:

    1. Align Painting with hardware vsync
    2. Resample touch input events based on hardware vsync
    3. Align composites with hardware vsync

    What is vsync, why vsync, and why does it matter at all?

    Vertical synchronization (vsync) occurs when the hardware display shows a new frame on the screen. This rate is set by specific hardware, but major displays in the US occur at a rate of 60 times a second, or every 16.6 ms (milliseconds). This is where you hear about 60 frames per second, one frame each time the hardware display refreshes. What this means in reality is that no matter how many frames are produced in software, the hardware display will still only show at most 60 unique frames per second.

    Currently in Firefox, we mimic 60 frames per second and therefore vsync with a software timer that schedules rendering every 16.6 ms. However, the software scheduler has two problems: (a) it’s noisy and (b) it can be scheduled at bad times relative to vsync.

    In regards to noise, software timers are much noisier than hardware timers. This creates micro-jank for a number of reasons. First, many animations are keyed off timestamps that are generated by the software scheduler to update the position of the animation. If you’ve ever used requestAnimationFrame, you get a timestamp from a software timer. If you want smooth animations, the timestamp provided to requestAnimationFrame should be uniform. Non-uniform timestamps will create non-uniform and janky animations. Here is a graph showing software versus hardware vsync timer uniformity:

    timer

    Wow! Big improvement with a hardware timer. We get a much more uniform, and therefore smoother, timestamp to key animations off of. So that addresses problem (a), noisy timers in software versus hardware.

    With part (b), software timers can be scheduled at bad times relative to vsync. Regardless of what the software does, the hardware display will refresh on its own clock. If our rendering pipeline finishes producing a frame before the next vsync, the display is updated with new content. If we fail to finish producing a frame before the next vsync, the previous frame will be displayed, causing jankiness. Some rendering functions can occur close to vsync and overflow until the next interval. Thus, we actually introduce more potential latency since the frame won’t be displayed on the screen anyway until the next vsync. Let’s look at this in graphic form:

    frames

    At time 0, we start producing frames. For example, let’s say all frames take a constant time of 10 ms. Our frame budget is 16.6 ms because we only have to finish producing a frame before the next hardware vsync occurs. Since frame 1 is finished 6 ms before the next vsync (time t=16 ms), everything is successful and life is good. The frame is produced in time and the hardware display will be refreshed with the updated content.

    Now let’s look at Frame 2. Since software timers are noisy, we start producing a frame 9 ms from the next vsync (time t=32). Since our frame takes 10 ms to produce, we actually finish producing this frame at 1 ms AFTER the next vsync. That means at vsync number 2 (t=32), there is no new frame to display, so the display still shows the previous frame. In addition, the frame just produced won’t be shown until vsync 3 (t=48), because that’s when the hardware updates itself. This creates jank since now the display will have skipped one frame and will try to catch up in the upcoming frames. This also produces one extra frame of latency, which is terrible for games.

    Vsync addresses both of these problems since we get a much more uniform timer and the maximum amount of frame budget time to produce a new frame. Now that we know what vsync is, we can finally go on to what Project Silk is and how it helps create smooth experiences in Firefox.

    The Rendering Pipeline

    In super simplified terms, Gecko’s rendering pipeline does three things:

    1. Paint / draw the new frame on the main thread.
    2. Send the updated content to the Compositor via a LayerTransaction.
    3. Composite the new content.

    In an ideal world, we’d be able to do all three steps within 16.6 ms, but that’s not the case most of the time. Both steps (1) and (3) occur on independent software timers. Thus, there is no real synchronizing clock between the three steps, they are all ad hoc. They also have no relation to vsync, so the timing of the pipeline isn’t related to when the display actually updates the screen with content. With Silk, we replace both independent software timers with the hardware vsync timer. For our purposes, (2) doesn’t really affect the outcome, but is presented here for completeness.

    Align Painting with Hardware Vsync

    Aligning the timer used to tick the refresh driver with vsync creates smoothness in a couple of ways. First, many animations are still done on the main thread, which means any animation using timestamps to set the position of an animation should be smoother. This includes requestAnimationFrame animations! The other nice thing is that we now have a very strict ordering of when rendering is kicked off. Instead of (1) and (3), which occur at separate synched offsets, we start rendering at a specific time.

    Resample Touch Input Events Based on Vsync

    With Silk, we can enable touch resampling, which improves smoothness while tracking your finger. Since I’ve already blogged about touch resampling quite a bit, I’ll keep this short. With Silk, we can finally enable it!

    Align Composites with Hardware Vsync

    Finally, the last part of Silk is about aligning composites with hardware vsync. Compositing takes all the painted content and merges it together to create the single image you see on the display. With Silk, all composites start right after a hardware vsync occurs. This has actually produced a rather nice side benefit — the reduced composite times seen here:

    compositeTimes

    Within the device driver on a Flame device, there’s a global lock that’s grabbed when close to vsync intervals. This lock can take 5-6 ms to get, greatly increasing the composite times. However, when we start a composite right after a vsync, there is little contention to grab the lock. Thus we can shave off the wait, therefore reducing composite times quite a bit. Not only do we get smoother animations, but also reduced composite times, and therefore better battery life. What a nice win!

    With all three pieces, we now have a nice strict ordering of the rendering pipeline. We paint and send the updated content to the Compositor within 16.6 ms. At the next vsync, we composite the updated content. At the vsync after that, the frame should have gone through the rendering pipeline and will be displayed on the screen. Keeping this order reduces jank because we reduce the chance that the timers will schedule each step at a bad time. In a best-case scenario in the current implementation without Silk, a frame could be painted and composited within a single 16.6 ms frame. This is great. However, if the next frame takes 2 frames instead, we’ve just created extra jank, even though no stage in the pipeline was really slow. Aligning the whole pipeline to create a strict sequence of events reduces the chance that we mis-schedule a frame.

    master

    Here’s a picture of the rendering pipeline without Silk. We have Composites (3) at the bottom of this profile. We have painting (1) in the middle, where you see Styles, Reflow, Displaylist, and Rasterize. We have Vsync, represented by those small orange boxes at the top. Finally we have Layer Transactions (2) at the bottom. At first, when we start, compositing and painting are not aligned, so animations are at different positions depending on whether they are on the main thread or the compositor thread. Second, we see long composites because the compositor is waiting on a global lock in the device driver. Lastly, it’s difficult to read any ordering or see if there is a problem without deep knowledge of why / when things should be happening.

    silk

    Here is a picture of the same pipeline with Silk. Composites are a little shorter, and the whole pipeline only starts at vsync intervals. Composite times are reduced because we start composites exactly at vsync intervals. There is a clear ordering of when things should happen. Both composites and painting are keyed off the same timestamp, ensuring smoother animations. Finally, there is a clear indicator that as long as everything finishes before the next Vsync, things will be smooth.

    Ultimately, Silk aims to create a smoother experience across Firefox and the Web. Numerous people contributed to the project. Thanks to Jerry Shih, Boris Chou, Jeff Hwang, Mike Lee, Kartikaya Gupta, Benoit Girard, Michael Wu, Ben Turner, and Milan Sreckovic for their help in making Silk happen.

  4. The P2P Web: Wi-Fi Direct in Firefox OS

    At Mozilla, we foresee that the future of the Web lies in its ability to connect people directly with multiple devices, without using the Internet. Many different technologies exist and are already implemented to allow peer-to-peer connections. Today is the first in a series of articles presenting these technologies. Let me introduce you to Wi-Fi Direct.

    What is it about?

    Wi-Fi Direct is a communication standard from the Wi-Fi Alliance that allows several devices to connect without using a local network. It has the advantage of using Wi-Fi, a fast and commonly available technology.

    This standard allows devices to discover peers and connect to them by enabling a portable Wi-Fi access point on your device that others can connect to. In Wi-Fi Direct parlance, the access point is called a group owner. The devices connected to a group owner are called clients, or peers.

    Wi-Fi Direct diagram

    Enable Wi-Fi Direct on a Flame

    In order to be usable the device driver must support Wi-Fi Direct, and that’s the case on the Flame. But before starting, the first thing to do is to enable support. Run the code in this gist with a rooted device connected to your computer.

    The Wi-Fi Direct API in Firefox OS is only available to certified apps at this time. Don’t forget to request the wifi-manage permission in your manifest.webapp file. This also means that you cannot distribute such an app in the Firefox Marketplace, but you can still use it and play with the technology.

    The JavaScript code in this article uses promises and some of the ES6 structures supported in the latest release of Firefox OS. Make sure you are familiar with these!

    Let’s see who’s around

    The Wi-Fi Direct API is accessible via the navigator.mozWifiP2pManager object.
    The first thing to do: enable Wi-Fi Direct to get a list of the peers that are around. The methods to enable and get the peers are respectively setScanEnabled(true) and getPeerList() and both return promises.

    navigator.mozWifiP2pManager.setScanEnabled(true)
      .then(result => {
        if (!result) {
          throw(new Error('wifiP2pManager activation failed.'));
        }
     
        // Wi-Fi Direct is enabled! Now, let's check who's around.
        return navigator.mozWifiP2pManager.getPeerList();
      })
      .then(peers => {
        console.log(`Number of peers around: ${peers.length}!`);
      });

    Pass true to navigator.mozWifiP2pManager.setScanEnabled() to start Wi-Fi Direct and the promises will return true if activation was successful. Use this to check whether your device supports Wi-Fi Direct or not.

    The promise returned by navigator.mozWifiP2pManager.getPeerList() will return an array of objects representing the peers located around you with Wi-Fi Direct enabled:

    {
      name: "Guillaume's Flame",
      connectionStatus: "disconnected",
      address: "02:0a:f5:f7:38:44", // MAC address of the device
      isGroupOwner: false
    }

    The peer name can be set using navigator.mozWifiP2pManager.setDeviceName(`Guillaume's Flame`). It is a string that allows a human to identify a device.
    As you can guess, the connectionStatus property tells us whether the device is connected or not. It has 4 possible values:

    • ‘disconnected’
    • ‘connecting’
    • ‘connected’
    • ‘disconnecting’

    You can listen to the peerinfoupdate event fired by navigator.mozWifiP2pManager to know when any peer status changes (new peer appears or disappears ; a peer connection status changes). You need then to call getPeerList() to get the update.

    Knock knock. Who’s there?

    Now that we know the devices located around you, let’s connect with them. We’re going to use navigator.mozWifiP2pManager.connect(address, wps, intent). The 3 parameters stand for:

    1. The MAC address of the device
    2. The WPS method (e.g. ‘pbc’)
    3. A value for intent from 0 to 15

    The MAC address is given in the peer object retrieved with getPeerList().
    The WPS method can be safely ignored for now but keep an eye on MDN for more on this.
    For initial connections, the value of intent will decide who will be the group owner of the Wi-Fi Direct network. The higher the value, the more likely it is that the device issuing the connection is the group owner.

    // Given `peer`, a peer object.
    navigator.mozWifiP2pManager.connect(peer.address, 'pbc', 1)
      .then(result => {
        if (!result) {
          throw(new Error(`Cannot request a connection with ${peer.name}.`));
        }
     
        // The connect request was successfully issued.
      });

    At this stage, you’re still not connected to the peer. The value returned will tell you whether the connection could be initiated or not.
    To know the status of your connection, you need to listen to an event.

    Breaking the ice

    The Wi-Fi Direct object emits different types of events. When another device gets connected the statuschange event is fired.

    The details of the connection are available in navigator.mozWifiP2pManager.groupOwner. Use the information provided by the following properties:

    • isLocal: whether the device is a group owner or not.
    • ipAddress: the IP address of the group owner.

    More properties are also exposed, but the ones above are enough to build a basic application.

    statuschange is also triggered when the other peer is disconnected using navigator.mozWifiP2pManager.disconnect(address).

    Say hello

    Wi-Fi Direct is merely a connection protocol, it’s now up to you to decide how to communicate. Once connected, you get the IP address of the group owner. This can be used with fxos-web-server, a web server running on your device to request information. The group owner will then act as a server.

    You can also use p2p-helper.js, a convenient helper library developed by Justin D’Arcangelo to abstract away the complexity of the Wi-Fi Direct API and build an app with ease.

    I recommend you have a look at the following example apps:

    • Firedrop, a sample app to share media files between devices.
    • Wi-Fi Columns, a game working across multiple devices. See the demo below.

    Now, it’s your turn to create mind-blowing apps where multiple devices can interact together without cellular data or Internet connection!

  5. Canvas 2D: New docs, Path2D objects, hit regions

    Over the last year, a couple of new HTML Canvas 2D features were implemented in Firefox and other recent browsers, with the help of the Adobe Web platform team. Over on MDN, the documentation for Canvas 2D got a major update to reflect the current canvas standard and browser implementation status. Let’s have a look what is new and how you can use it to enhance your canvas graphics and gaming content.

    Path2D objects

    The new Path2D API (available from Firefox 31+) lets you store paths, which simplifies your canvas drawing code and makes it run faster. The constructor provides three ways to create a Path2D object:

    new Path2D();     // empty path object
    new Path2D(path); // copy from another path
    new Path2D(d);    // path from from SVG path data

    The third version, which takes SVG path data to construct, is especially handy. You can now re-use your SVG paths to draw the same shapes directly on a canvas as well:

    var p = new Path2D("M10 10 h 80 v 80 h -80 Z");

    When constructing an empty path object, you can use the usual path methods, which might be familiar to you from using them directly on the CanvasRenderingContext2D context.

    // create a circle
    var circle = new Path2D();
    circle.arc(50, 50, 50, 0, 2 * Math.PI);
    // stroke the circle onto the context ctx
    ctx.stroke(circle);

    To actually draw the path onto the canvas, several APIs of the context have been updated to take an optional Path2D path:

    Hit regions

    Starting with Firefox 32, experimental support for hit regions has been added. You need to switch the canvas.hitregions.enabled preference to true in order to test them. Hit regions provide a much easier way to detect if the mouse is in a particular area without relying on manually checking coordinates, which can be really difficult to check for complex shapes. The Hit Region API is pretty simple:

    CanvasRenderingContext2D.addHitRegion()
    Adds a hit region to the canvas.
    CanvasRenderingContext2D.removeHitRegion()
    Removes the hit region with the specified id from the canvas.
    CanvasRenderingContext2D.clearHitRegions()
    Removes all hit regions from the canvas.

    The addHitRegion method, well, adds a hit region to a current path or a Path2D path. The MouseEvent interface got extended with a region property, which you can use to check whether the mouse hit the region or not.

    Check out the code example on MDN to see it in action (and be sure to enable flags/preferences in at least Firefox and Chrome).

    Focus rings

    Also in Firefox 32, the drawFocusIfNeeded(element) property has been made available without a preference switch. This API allows you to draw focus rings on a canvas, if a provided fallback element inside the <canvas></canvas> element gains focus. If the fallback element gets focused (for example when tabbing through the page that contains the canvas), the pixel representation / shape of that element on the canvas can draw a focus ring to indicate the current focus.

    CSS/SVG filters exposed to Canvas

    Although still behind a preference (canvas.filters.enabled), and not yet in the latest canvas specification (but expected to be added), Firefox 35 gained support for filters on the canvas rendering context. The syntax is the same as the CSS filter property.

    Misc

    Documentation

    If you would like to read more about Canvas 2D graphics, check out the Canvas tutorial on MDN, which guides you through the Canvas APIs. A good bookmark is also the large CanvasRenderingContext2D interface, which you will use often when working with Canvas.

  6. Web Animation tools, Network Security insights, Font Inspector improvements and more – Firefox Developer Tools Episode 37

    A handful of bug fixes, improvements and some new features, of course, just landed in Firefox 37. Update your Firefox Developer Edition, or Nightly builds to try them out!

    Animation Inspector Panel

    A new API that’s quickly gaining traction is the Web Animations API, allowing developers to construct more complex animations using web technologies, rather than proprietary plugins. The foundation for animation tooling has begun in Firefox’s Developer Tools, with the first release revealing play/pause controls and a timeline scrubber. When selecting an element in the Inspector, an animations panel is now available alongside the rules, fonts, and other panels, if the element contains animations. Check out other videos of the animation inspector in action, or try it yourself in this web animation demo.

    This is the first iteration of the web animation tools, and we are looking to hear from you on where we should go with this, and what we should build! Share detailed feedback with us on UserVoice, leave us a comment right here, or tweet to @FirefoxDevTools. (More detail on how to reach us in the closing paragraph below.)

    Security Panel

     
    The Network Monitor is the home of our other new tool, the security panel. Selecting a request in the network panel now displays a security panel in the request inspector. The panel reveals a list of information about the request’s connection, host, as well as the certificate used.

    The security panel can help debug issues related to SSL protocol versions, such as sites not working because of the POODLEBITE issue, and can help ensure that sufficiently strong security measures are implemented.

    DevTools Security Panel, new in Firefox 37

    Some other features and small improvements in this release:

    • Font inspector now shows all fonts (including fonts in iframes) when clicking “show all fonts” button. (Bug 1097150)
    • Addons can now register custom actors. (Bug 1107888)
    • The inspector sidebar now loads and refreshes lazily, leading to better performance of the inspector. (Bug 1103993)
    • Box Model Highlighter colors have been updated so they are easier to see on a wider range of backgrounds, as well as more accessible. (Bug 989053)
    • A new Firefox CLI option was added, –start-debugging-server, for starting the Firefox debugging server on a specific port. (Bug 1119894)
    • The tools tabbar height has decreased to allow more vertical space in the toolbox. (Bug 1109288)

    As we mentioned above, your feedback guides our priorities. Add your comments here, talk to us on Twitter @FirefoxDevTools, or propose changes on the Developer Tools feedback channel. If you’d like to help out with Dev Tools, check out the guide to getting involved.

  7. 2014: Mozilla Hacks looks back

    Wherever you live, it’s a season of work holidays, school vacations, year-end blog posts, and lists. The Hacks blog will be back in early January 2015 to continue writing for developers about the products and technologies created by Mozilla and by builders of the Open Web around the world.

    In the (chronological) list below, we celebrate some 2014 milestones and memorable moments for Mozilla, Firefox, and the web platform:

    • The new improved Firefox Sync launched early in 2014, built atop Firefox Accounts. Here’s a deeper look at the new Sync protocol.
    • Mozilla worked with the Apache Cordova team to integrate Firefox OS with Cordova’s open source device APIs, enabling mobile app developers to access native device functions from JavaScript, and release Cordova apps for the Firefox OS platform. Cordova is the underlying software in Adobe PhoneGap: the integration made it possible for PhoneGap developers to easily port their apps to the Firefox Marketplace.
    • Mozilla Research made great progress on Servo, a prototype browser engine. Servo is written in Rust, a systems programming language designed to support concurrency and parallelism for modern hardware. Another Big Milestone for Servo—Acid2 was reported in the spring.
    • Australis was the codename for our major redesign of the Firefox Desktop browser, which launched in late April. Designer Stephen Horlander wrote a post about the process, titled (Re)Designing Firefox.
    • The summer release of Firefox 31 brought new capabilities for game developers, including access to emscripten for compiling to JavaScript. In Resources for HTML5 game developers, we described some of the tools and techniques for coding and debugging sophisticated, performant HTML5 games. On the Mozilla blog, we featured the first commercial games to leverage asm.js, demonstrating the readiness of HTML5 as a game platform.
    • In October, we shared a Preview of Firefox Hello, a WebRTC-powered voice/video chat service.
    • As part of the festivities surrounding Firefox’s 10th birthday, Mozilla Research launched MozVR to help bring virtual reality to the Web. Grab your oculi and hold on to your hats.
    • At the same time, the Firefox Developer Tools team released Firefox Developer Edition, the first browser created specifically for developers. Though still in its early days, the Developer Edition features Valence, an integrated add-on to let you develop and debug your app across multiple browsers and devices, as well as WebIDE, providing an editing environment for app development and remote debugging.
    • The evolution of asm.js continued with the release of Massive, an open source benchmarking tool that measures asm.js performance specifically. You can run Massive here.
    • Mozilla and partners announced the formation of the Internet Security Research Group (ISRG) and launched the Let’s Encrypt initiative. Let’s Encrypt is a new Certificate Authority that’s free, automated, and open. It’s due to arrive in summer 2015.
    • Our friends at Telenor introduced Gonzo, an ongoing project which explores the use of Firefox OS as an embedded platform. Telenor engineer and Firefox OS evangelist Jan Jongboom is hacking together a wireless camera and sharing what he learns along the way.
    • Firefox OS Expands to Nearly 30 Countries – It’s been an expansive year. At last count, Firefox OS is now up and running on 16 smartphones offered in 29 countries. And in December news, Mozilla and KDDI announced the release of Japan’s first Firefox OS smartphone, which went on sale on December 25. The Fx0 is the first high-spec Firefox OS smartphone and it’s a beauty!

    If you’re interested in writing for the Hacks blog in 2015, we’d love to hear from you. Email us. In the meantime, have a safe and hacky holiday!

  8. You can’t go wrong watching JavaScript talks

    Late last week, I was collecting suggestions for year-end Hacks blog posts. As she headed out for the winter holidays, apps engineer Soledad Penadés gifted me “a bunch of cool talks I watched this year.”

    In fact, it’s a curated collection of presentations from JSConf, JSConf EU, and other recent developer conferences. Presenters include notable Mozillians and opinionated friends: hackers, JavaScripters, teachers, preachers, and hipsters. Many talks come with links to slides. They cover diverse topics: software development, developer culture and practices, developer tools, open source, JavaScript, CSS, new APIs.

    Part 1: Sole’s list

    Part 2: Making video better on Firefox

    Binge-watching JavaScript talks not your idea of a holiday break? If you’re watching video at all, Mozilla could use your help improving the video experience on Firefox.

    Here’s how you can contribute: Download Firefox Nightly, and help us test the implementation of Media Source Extensions (MSE) to support YouTube videos running in HTML5. Over recents weeks, Firefox engineers have been working hard addressing top bugs. To get this into the hands of users as quickly as possible, we need more help testing the experience. Here’s a detailed description of the testing task, thanks to Bugmaster Liz Henry from the QA team.

    File bugs using this link. Describe your platform, OS, and the steps needed to reproduce the problem.

    Thank you for helping to make the Firefox Desktop video experience awesome. See you in the new year.

  9. Pseudo elements, promise inspection, raw headers, and much more – Firefox Developer Edition 36

    Firefox 36 was just uplifted to the Developer Edition channel, so let’s take a look at the most important Developer Tools changes in this release. We will also cover some changes from Firefox 35 since it was released shortly before the initial Developer Edition announcement. There is a lot to talk about, so let’s get right to it.

    Inspector

    You can now inspect ::before and ::after pseudo elements.  They behave like other elements in the markup tree and inspector sidebars. (35, development notes)

    before-after-inspection

    There is a new “Show DOM Properties” context menu item in the markup tree. (35, development notes, documentation about this feature on MDN)

    show-dom-properties

    The box model highlighter now works on remote targets, so there is a full-featured highlighter even when working with pages on Firefox for Android or apps on Firefox OS. (36, development notes, and technical documentation for building your own custom highlighter)

    Shadow DOM content is now visible in the markup tree; note that you will need to set dom.webcomponents.enabled to true to test this feature (36, development notes, and see bug 1053898 for more work in this space).

    We borrowed a useful feature from Firebug and are now allowing more paste options when right clicking a node in the markup tree.  (36, development notes, documentation about this feature on MDN)

    paste-options

    Some more changes to the Inspector included in Firefox 35 & 36:

    • Deleting a node now selects the previous sibling instead of the parent (36, development notes)
    • There is higher contrast for the currently hovered node in the markup view (36, development notes)
    • Hover over a CSS selector in the computed view to highlight all the nodes that match that selector on the page. (35, development notes)

    Debugger / Console

    DOM Promises are now inspectable. You can inspect the promises state and value at any moment. (36, development notes)

    promise-inspection

    The debugger now recognizes and works with eval’ed sources. (36, development notes)

    Eval’ed sources support the //# sourceURL=path.js syntax, which will make them appear as a normal file in the debugger and in stack traces reported by Error.prototype.stack. See this post: http://fitzgeraldnick.com/weblog/59/ for much more information. (36, development notes,  more development notes)

    Console statements now include the column number they originated from. (36, development notes)

    WebIDE

    You are now able to connect to Firefox for Android from the WebIDE.  See documentation for debugging firefox for android on MDN.  (36, development notes).

    We also made some changes to improve the user experience in the WebIDE:

    • Bring up developer tools by default when I select a runtime app / tab (35, development notes)
    • Re-select project on connect if last project is runtime app (35, development notes)
    • Auto-select and connect to last used runtime if available (35, development notes)
    • Font resizing (36, development notes)
    • You can now adding a hosted app project by entering the base URL (eg: “http://example.com”) instead of requiring the full path to the manifest.webapp file (35, development notes)

    Network Monitor

    We added a plain request/response headers view to make it easier to view and copy the raw headers on a request. (35, development notes)

    net-headers-raw

    Here is a list of all the bugs resolved for Firefox 35 and all the bugs resolved for Firefox 36.

    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.

  10. Mozilla and Web Components: Update

    Editor’s note: Mozilla has a long history of participating in standards development. The post below shows a real-time slice of how standards are debated and adopted. The goal is to update developers who are most affected by implementation decisions we make in Firefox. We are particularly interested in getting feedback from JavaScript library and framework developers.

    Mozilla has been working on Web Components — a technology encompassing HTML imports, custom elements, and shadow DOM — for a while now and testing this approach in Gaia, the frontend of Firefox OS. Unfortunately, our feedback into the standards process has not always resulted in the changes required for us to ship Web Components. Therefore we decided to reevaluate our stance with members of the developer community.

    We came up with the following tentative plan for shipping Web Components in Firefox and we would really appreciate input from the developer community as we move this forward. Web Components changes a core aspect of the Web Platform and getting it right is important. We believe the way to do that is by having the change be driven by the hard learned lessons from JavaScript library developers.

    • Mozilla will not ship an implementation of HTML Imports. We expect that once JavaScript modules — a feature derived from JavaScript libraries written by the developer community — is shipped, the way we look at this problem will have changed. We have also learned from Gaia and others, that lack of HTML Imports is not a problem as the functionality can easily be provided for with a polyfill if desired.
    • Mozilla will ship an implementation of custom elements. Exposing the lifecycle is a very important aspect for the creation of components. We will work with the standards community to use Symbol-named properties for the callbacks to prevent name collisions. We will also ensure the strategy surrounding subclassing is sound with the latest work on that front in JavaScript and that the callbacks are sufficiently capable to describe the lifecycle of elements or can at least be changed in that direction.
    • Mozilla will ship an implementation of shadow DOM. We think work needs to be done to decouple style isolation from event retargeting to make event delegation possible in frameworks and we would like to ensure distribution is sufficiently extensible beyond Selectors. E.g Gaia would like to see this ability.

    Our next steps will be working with the standards community to make these changes happen, making sure there is sufficient test coverage in web-platform-tests, and making sure the specifications become detailed enough to implement from.

    So please let us know what you think here in the comments or directly on the public-webapps standards list!