Mozilla

Mobile Articles

Sort by:

View:

  1. Pre-orders start today for Flame, the Firefox OS developer phone

    Update 2014-07-15: The pre-order period has ended and the Flame is now available as a standard order, with shipping in 7-10 days.

    The Firefox OS Flame reference device that we announced at end of February is now available for pre-order at everbuying.com for $170 including free shipping.

    Pre-order now.

    To standardize the design, development, and testing of Firefox OS, Mozilla has partnered with a company called Thundersoft to manufacture, distribute, and update a Firefox OS reference phone called the Flame. Until now, there has been no “reference device” and the options for getting something through retail were limited.

    Mid-tier phone hardware

    The Flame is representative of the mid-tier phone hardware Mozilla and its partners are targeting over the coming year. It was designed for our developer and contributor community, so we worked with the manufacturer to keep the price as low as possible. We’re excited that we are able to bring a high quality reference device to our developer community at an affordable price.

    The Flame will also be a great development and testing environment for third party app developers targeting Firefox OS and HTML5. The phone offers a software configurable RAM option that can be made to emulate many different devices that will be commercially available later this year.

    Our partner will provide the Flame with updates to each new major version of Firefox OS and a simple mechanism for switching between different release channels; offering Nightly builds that will keep you at the forefront of Firefox OS development.

    If you’ve held off on getting a Firefox OS phone because they weren’t available in your region or the phones in market didn’t meet your development and testing needs, don’t miss out on the opportunity to pre-order one of these Flame reference phones today.

    Specifications & unlocked!

    The Flame is unlocked from any network and comes with the bootloader unlocked.

    • Qualcomm MSM8210 Snapdragon, 1.2GHZ Dual core processor
    • 4.5” screen (FWVGA 854×480 pixels)
    • Cameras: Rear: 5MP with auto-focus and flash / Front: 2MP
    • Frequency: GSM 850/900/1800/1900MHz
      UMTS 850/900/1900/2100MHz
    • 8GB memory, MicroSD slot
    • 256MB – 1GB RAM (adjustable by developer)
    • A-GPS, NFC
    • Dual SIM Support
    • Battery capacity: 1,800 mAh
    • WiFi: 802.11 b/g/n, Bluetooth 3.0, Micro USB

    NOTE: Once pre-ordered, the Flame will take approximately four weeks before it ships. The Flame ships free to anywhere in the world except for Japan. If you want to pre-order a Flame device certified for use in Japan, please visit here for more information.

    For more information:
    Mozilla Developer Network guide to the Flame reference phone

  2. HTML out of the Browser

    Amongst my friends, I’m known as something of a Star Wars nerd. My longtime nick has been cfjedimaster (a combination of two passions, the other being ColdFusion), I work in a room packed to the gills with Star Wars toys, and I’ve actually gotten inked up twice now with Star Wars tats. That being said, it was another movie that had the most influence on my current career – Tron.

    Tron_poster

    I had already discovered an interest in computers before then, but it was Tron that really crystallized the idea for me. All of sudden I imagined myself being the programmer – creating intelligent programs and dominating the grid. Yeah, I know, I was a nerd back then too.

    My dreams, though, ran into reality rather quickly during my time as a Comp Sci major in college. First – I discovered that “Hey, I’m good at math!” means crap all when you hit Calculus 3, and secondly, I discovered that I really wasn’t that interested in the performance of one sort versus another. I switched to English as a major (always a good choice) but kept messing around with computers. It was during this time that I was exposed to Mosaic and the early web.

    I quickly jumped into the web as – well – I’ll put it bluntly – easier programming than what I had been exposed to before. I can remember LiveScript. I can remember my first Perl CGI scripts. This wasn’t exactly light cycle coding but it was simpler, fun, and actually cutting edge. I’ve spent a good chunk of my adult life now as a web developer, and while I certainly have delusions of the web being a pristine environment, it has been good to me (and millions of others) and I’m loving to see how much it evolves over time.

    One of the most fascinating ways that web technologies have grown is outside of the web itself. In this article I’m going to look at all the various ways we can reuse our web-based technologies (HTML, JavaScript, and CSS) in non-web based environments. While it would be ludicrous to say that one shouldn’t learn other technologies, or that web standards work everywhere and in every situation, I feel strongly that the skills behind the web are ones open to a large variety of people in different disciplines – whether or not you got that PhD in computer science!

    Mobile

    This is typically the point where I’d discuss how important mobile is, but it’s 2014 and I think we’re past that now. Mobile development has typically involved either Java (Android) or Objective-C (iOS). Developers can also use web standards to build native applications. One solution is Apache Cordova (AKA PhoneGap).

    Cordova uses a web view wrapped in a native application to allow web developers to build what are typically referred to as hybrid applications. Along with providing an easy way to get your HTML into an app, Cordova provides a series of different plugins that let you do more than what a typical web page can do on a device. So for example, you have easy access to the camera:

    navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
        destinationType: Camera.DestinationType.DATA_URL
    });
     
    function onSuccess(imageData) {
        var image = document.getElementById('myImage');
        image.src = "data:image/jpeg;base64," + imageData;
    }
     
    function onFail(message) {
        alert('Failed because: ' + message);
    }

    You can also work with the accelerometer, GPS, contacts, the file system, and more. Cordova provides a JavaScript API that handles the communication to native code in the back end. Best of all, the same code can be used to build native applications for multiple different platforms (including Firefox OS, now supported in Cordova & PhoneGap).

    To be clear, this isn’t a case of being able to take an existing web site and just package it up. Mobile applications are – by definition – completely different from a simple web site. But the fact that you can use your existing knowledge gives the developer a huge head start.

    Another example of this (and one that is hopefully well known to readers of this site) is Firefox OS. Unlike Cordova, developers don’t have to wrap their HTML inside a web view wrapper. The entire operating system is web standards based. What makes Firefox OS even more intriguing is support for hosted applications. Firefox OS is a new platform, and the chance that your visitors are using a device with it is probably pretty slim. But with a hosted application I can easily provide support for installation on the device while still running my application off a traditional URL.

    Consider a simple demo I built called INeedIt. If you visit this application in Chrome, it just plain works. If you visit it in a mobile browser on Android or iOS – it just works. But visit it with Firefox and code will trigger to ask if you want to install the application. Here is the block that handles this.

    if(!$rootScope.checkedInstall && ("mozApps" in window.navigator)) {
     
        var appUrl = 'http://'+document.location.host+'/manifest.webapp';
        console.log('havent checked and can check');
        var request = window.navigator.mozApps.checkInstalled(appUrl);
     
        //silently ignore
        request.onerror = function(e) {
            console.log('Error checking install '+request.error.name);
        };
     
        request.onsuccess = function(e) {
            if (request.result) {
                console.log("App is installed!");
            }
            else {
                console.log("App is not installed!");
                if(confirm('Would you like to install this as an app?')) {
                    console.log('ok, lets try to install'); 
                    var installRequest = window.navigator.mozApps.install(appUrl);
     
                    installRequest.onerror = function() {
                        console.log('install failure: '+this.error.name);
                        alert('Sorry, install failed.');    
                    };
     
                    installRequest.onsuccess = function() {
                        console.log('did it');
                        alert('Thanks, app installed!');    
                    };
                }
                $rootScope.checkedInstall=true;
            }
        };
     
    } else {
        console.log('either checked or non compat');                
    }

    Pretty simple, right? What I love about this is that the code is 100% ignored outside of Firefox OS but automatically enhanced for folks using that operating system. I risk nothing – but I get the benefit of providing them a way to download and have my application on their device screen.

    FF OS prompting you to install the app

    Desktop

    Of course, there are still a few people who sit in front of a gray box (or laptop) for their day to day work. Many desktop applications have been replaced by web pages, but there are still things that outside the scope of web apps. There are still times when a desktop app makes sense. And fortunately – there’s multiple ways of building them with web standards as well.

    So you know the code example I just showed you? The one where Firefox OS users would be given a chance to install the application from the web page? That exact same code works on the desktop as well. While still in development (in fact, the application I built doesn’t work due to a bug with Geolocation), it will eventually allow you to push your web based application both to a mobile Firefox OS user as well as the other billion or so desktop users. Here’s the application installed in my own Applications folder.

    INeedIt as a desktop app

    As I said though – this is still relatively new and needs to bake a bit longer before you can make active use of it. Something you can use right now is Node Webkit. This open source project allows you to wrap Node.js applications in a desktop shell. Executables can than be created for Windows, Mac, and Linux. You get all the power of a “real” desktop application with the ease of use of web standards as your platform. There’s already a growing list of real applications out there making use of the framework – some I had even used before what realizing they used Node Webkit behind the scenes.

    As an example, check out A Wizard’s Lizard, a RGP with random dungeons and great gameplay.

    Screen shot - Wizard's Lizard

    Native App Extensions

    In the previous section we covered applications built with web standards. There are also multiple applications out there today, built natively, that can be extended with web standards. As a web developer you are probably already familiar with Firefox Add-Ons and Chrome extensions. There is an incredibly rich ecosystem of browser extensions for just about any need you can think of. What interests me however is the move to use web standards to open other products as well.

    Did you know Photoshop, yes, Photoshop, now has the ability to extended with Node.js? Dubbed “Adobe Generator”, this extensibility layer allows for a script-based interface to the product. One example of this is the ability to generate web assets from layers based on a simple naming scheme. If you’ve ever had to manually create web assets, and update them, from a PSD, you will appreciate this. The entire feature though is driven by JavaScript and all makes use of a public API you can build upon. The code, and samples, are all available via GitHub.

    Generator running within Photoshop

    What Next?

    Coming from the perspective of someone who has been in this industry for way too long, I can say that I feel incredibly lucky that web standards have become such a driving force of innovation and creativity. But it is not luck that has driven this improvement. It is the hard work of many people, companies, and organizations (like Mozilla) that have created the fertile landscape we have before us today. To continue this drive requires all of us to become involved, evangelize to others, and become proponents of a web created by everyone – for everyone.

  3. It’s a wrap! “App Basics for FirefoxOS” is out and ready to get you started

    A week ago we announced a series of video tutorials around creating HTML5 apps for Firefox OS. Now we released all the videos and you can watch the series in one go.

    wrap
    Photo by Olliver Hallmann

    The series is aimed at web developers who want to build their first HTML5 application. Specifically it is meant to be distributed in the emerging markets, where Firefox OS is the first option to get an affordable smartphone and start selling apps to the audiences there.

    Over the last week, we released the different videos of the series – one each day:

    Yesterday we announced the last video in the series. For all of you who asked for the whole series to watch in one go, you now got the chance to do so.

    There are various resources you can use:

    What’s next?

    There will be more videos on similar topics coming in the future and we are busy getting the videos dubbed in other languages. If you want to help us get the word out, check the embedded versions of the videos on Codefirefox.com, where we use Amara to allow for subtitles.

    Speaking of subtitles and transcripts, we are currently considering both, depending on demand. If you think this would be a very useful thing to have, please tell us in the comments.

    Thanks

    Many thanks to Sergi, Jan, Jakob, Ketil, Nathalie and Anne from Telenor, Brian Bondy from Khan Academy, Paul Jarrat and Chris Heilmann of Mozilla to make all of this possible. Technologies used to make this happen were Screenflow, Amazon S3, Vid.ly by encoding.com and YouTube.

  4. Flambe Provides Support For Firefox OS

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

    Flambe provides many other features, including:

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

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

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

    Firefox Marketplace Games

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

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

    Building a Firefox OS App using Flambe

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

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

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

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

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

    Create a Project

    To create a new project, run the following command.

    flambe new

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

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

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

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

    Build the Project

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

    flambe build <output>

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

    Debug the Project

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

    A Bit about Haxe and Flambe

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

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

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

    Haxe Packages and Classes

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

    Flambe Subsystem Setup and Entry point

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

    Flambe Asset Management

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

    Flambe Entities and Components

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

    Creating Entities and Components in the Sample App

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

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

    Flambe Animated Data Types

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

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

    Flambe Event Model

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

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

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

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

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

    Demo Apps

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

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

    haxelib install nape

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

    Wrapping Up

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

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

  5. Custom Elements for Custom Applications – Web Components with Mozilla’s Brick and X-Tag

    In this article, we will explore the use of Mozilla’s Brick and X-Tag libraries. First we’ll use Brick to rapidly prototype a simple application. Then, we’ll build a custom web component using X-Tag.

    The Technology

    Brick: Curated Web Components

    Brick is a set of modular, reusable UI components. The components are designed for adaptive, responsive applications and are a great choice for going mobile first, which is by and large how web-based applications should be developed. This philosophy and its design patterns accomodate a wide range of devices. Brick components aren’t just for mobile apps, they are for modern apps.

    Brick is kind of like a library, but really you should think of it as a curated collection of web components.

    Brick’s collection of components are used declaratively in your HTML <like-this> and can be styled with CSS like regular non-custom elements. Brick components have their own micro-APIs for interacting with them. These components are building blocks. Do you like Lego? Good. You will like Brick.

    Brick web components are made using the X-Tag custom elements polyfill.

    What is X-Tag?

    X-Tag is a library that polyfills several (and soon all) features that enable web components in the browser. In particular, X-Tag is focused on polyfilling the creation of Custom Elements so that you can extend the DOM using your own declarative syntax and element-specific API.

    When you are using components from Brick, you are using web components made using the X-Tag library. Brick includes X-Tag core, so if you include Brick and then decide to make your own custom elements — you do not need to include X-Tag to do so, all the features of X-Tag are already available for you.

    Download Demo Project Files

    Download the demo project files. First we’ll use the material in the simple-app-with-bricks folder.

    Using Bricks in an app

    Here we will build a simple skeleton app using <x-appbar>, <x-deck>, and <x-card>. x-appbar provides a tidy header bar for our application, and x-cards placed as children of an x-deck give us multiple views with transitions.

    First, we start with a barebones HTML document and then include Brick’s CSS and JS, along with our own application-specific code (app.css and app.js respectively in the example to follow).

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width">
        <link rel="stylesheet" type="text/css" href="css/brick.min.css">
        <link rel="stylesheet" type="text/css" href="css/app.css">
        <title>Simple - Brick Demo</title> 
      </head> 
      <body> 
        <!--- Some Brick components will go here -->
        <script type="text/javascript" src="js/brick.min.js"></script>
        <script type="text/javascript" src="js/app.js"></script>
      </body>
      </html>

    Now we add some Brick elements:

    <x-appbar id="bar">
      <header>Simple Brick App</header>
      <button id="view-prev">Previous View</button>
      <button id="view-next">Next View</button>
    </x-appbar>

    Below your x-appbar, create an x-deck with some x-cards as children. You can give the x-cards any content you like.

    <!-- Place your x-deck directly after your x-appbar -->
    <x-deck id="views">
      <x-card>
        <h1>View 1</h1>
        <p>Hello, world!</p>
      </x-card>
      <x-card>
        <h1>Pick a Date</h1>
        <p>&lt;x-datepicker&gt;s are a polyfill for &lt;input type="date"&gt;</p>
        <x-datepicker></x-datepicker>
        <p>Just here to show you another tag in action!</p>
      </x-card>
      <x-card>
        <h1>A Random Cat To Spice Things Up</h1>
        <!-- Fetches from the Lorem Pixel placeholder content service -->
        <img src="http://lorempixel.com/300/300/cats">
      </x-card>
    </x-deck>

    We have already almost completed the structure for a simple application. All we need now is a little bit of CSS and Javascript to tie it together.

    document.addEventListener('DOMComponentsLoaded', function() { 
      // Run any code here that depends on Brick components being loaded first 
      // Very similar to jQuery's document.ready() 
     
      // Grab the x-deck and the two buttons found in our x-appbar and assign to local vars
      var deck = document.getElementById("views"),
      nextButton = document.getElementById("view-next"),
      prevButton = document.getElementById("view-prev"); 
     
      // Add event listeners so that when we click the buttons, our views transition between one another
      prevButton.addEventListener("click", function(){ deck.previousCard(); }); 
      nextButton.addEventListener("click", function(){ deck.nextCard(); });
    });

    <x-calendar> example in our demo application

    Some simple CSS to style our fledgling application:

    html, body {
      margin: 0;
      padding: 0;
      font-family: sans-serif;
      height: 100%;
    }
     
    h1 {
      font-size: 100%;
    }
     
    x-deck > x-card {
      background: #eee;
      padding: 0.6em
    }

    Ka-bam! With a little bit of declarative markup and a few tweaks, we have a skeleton that anyone can use to make a multi-view app within a single HTML document. If you check out the markup in the developer tools, you’ll see the Brick custom elements living happily alongside vanilla HTML elements – you can use the developer tools to inspect and manipulate them in the same way as regular old HTML.

    Custom elements alongside HTML elements in the Firefox Developer Tools

    Now let’s learn how to make our own custom element using X-Tag.

    Creating Custom Elements (Your Own ‘Bricks’) Using X-Tag

    Let’s say we have a mobile application in which the user takes an action that results in a blocking task. Maybe the application is waiting for an external service. The program’s next instruction to complete the user-initiated task depends on the data from the server, so unfortunately we have to wait. For the sake of our purposes here, let’s pretend we can’t modify our program too much and assume an entrenched architecture – maybe we can’t do much else other than communicate to the user until we find a way to deal with the blocking better. We have to do the best with what we have.

    We will create a custom modal spinner that will tell the user to wait. It’s important to give your users feedback on what’s happening in your app when they don’t get to complete their task in a timely manner. A frustrated or confused user might give up on using your app.

    You will want to switch to the x-status-hud folder inside of the demo materials now.

    1. Registering Your Custom Element

    X-Tag relies on several different events to detect and upgrade elements to custom elements. X-Tag will work whether the element was present in the original source document, added by setting the innerHTML property, or created dynamically via document.createElement. You should take a look at the Helpers section of the X-Tag documentation as it covers various functions that will allow you to work with your custom elements just like vanilla ones.

    The first thing that we need to do is register our custom element with X-Tag so that X-Tag knows what to do if and when it encounters our custom element. We do that by calling xtag.register.

    xtag.register('x-status-hud', {
      // We will give our tag custom behavior here for our status indicating spinner
    });

    !IMPORTANT: All custom element names must contain a hyphen. Why is this? The idea here is that there are no standard HTML elements with a hyphen in them, so we don’t trample existing namespaces and have collisions. You do not have to prefix with ‘x-’, this is just a convention used for components create with X-Tag in the Brick ecosystem. Once upon a time in the early days of the W3C specification for custom elements, it was speculated that all custom elements would have an x- prefix; this restriction was relaxed in later versions of the specification. If you were to name an element ‘bacon-eggs’ or ‘adorable-kitten’, both of these would be perfectly valid names. Choose a name that describes what your element is or does.

    If we wanted to, we could choose to set what HTML element is being used as our base element before upgrading. We can also set a specific prototype for our element if we want to involve functionality from a different element. You can declare these as follows:

    xtag.register('x-superinput', {
      extends: 'input',
      prototype: Object.create(HTMLInputElement.prototype)
    });

    The element we are building doesn’t require these properties to be set explicitly. They are worth mentioning because they will be useful to you when you write more advanced components and want a specific level of control over them.

    2. The Element Lifecycle

    Custom elements have events that fire at certain times during their lifetime. Events are fired when an element is created, inserted into the DOM, removed from the DOM, and when attributes are set. You can take advantage of none or all of these events.

    lifecycle:{
      created: function(){
        // fired once at the time a component
        // is initially created or parsed
      },
      inserted: function(){
        // fired each time a component
        // is inserted into the DOM
      },
      removed: function(){
        // fired each time an element
        // is removed from DOM
      },
      attributeChanged: function(){
        // fired when attributes are set
      }

    Our element is going to use the created event. When this event fires, our code will add some child elements.

    xtag.register('x-status-hud', {
      lifecycle: {
        created: function(){
            this.xtag.textEl = document.createElement('strong');
     
            this.xtag.spinnerContainer = document.createElement('div');
            this.xtag.spinner = document.createElement('div');
     
            this.xtag.spinnerContainer.className = 'spinner';
     
            this.xtag.spinnerContainer.appendChild(this.xtag.spinner);
            this.appendChild(this.xtag.spinnerContainer);
            this.appendChild(this.xtag.textEl);
        }
      }
      // More configuration of our element will follow here
    });

    3. Adding Custom Methods

    We need to have control over when we show or hide our status HUD. To do that, we need to add some methods to our component. Let’s add some functions to do that. A simple toggle() may suffice for some use cases, but let’s throw in individual hide() and show() functions too.

     
    xtag.register('x-status-hud', {
      lifecycle: {
        created: function(){
          this.xtag.textEl = document.createElement('strong');
     
          this.xtag.spinnerContainer = document.createElement('div');
          this.xtag.spinner = document.createElement('div');
     
          this.xtag.spinnerContainer.className = 'spinner';
     
          this.xtag.spinnerContainer.appendChild(this.xtag.spinner);
          this.appendChild(this.xtag.spinnerContainer);
          this.appendChild(this.xtag.textEl);
        }
      },
     
      methods: {
        toggle: function(){
          this.visible = this.visible ? false : true;
        },
     
        show: function (){
          this.visible = true;
        },
     
        hide: function (){
          this.visible = false;
        }
      }

    4. Adding Custom Accessors

    Something important to note about properties on custom elements: they do not have to map to an attribute. This is by design because some setters could be very complex and not have a sensible attribute equivalent.

    If you would like an attribute and property to be linked, pass in an empty object literal to the attribute. You’ll see below where this has been done for the label attribute.

    xtag.register('x-status-hud', {
      lifecycle: {
        created: function(){
          this.xtag.textEl = document.createElement('strong');
     
          this.xtag.spinnerContainer = document.createElement('div');
          this.xtag.spinner = document.createElement('div');
     
          this.xtag.spinnerContainer.className = 'spinner';
     
          this.xtag.spinnerContainer.appendChild(this.xtag.spinner);
          this.appendChild(this.xtag.spinnerContainer);
          this.appendChild(this.xtag.textEl);
        }
      },
     
      methods: {
        toggle: function(){
          this.visible = this.visible ? false : true;
        },
     
        show: function (){
          this.visible = true;
        },
     
        hide: function (){
          this.visible = false;
        }
      },
     
      accessors: {
        visible: {
          attribute: { boolean: true }
        },
     
        label: {
          attribute: {},
     
          set: function(text) {
            this.xtag.textEl.innerHTML = text;
          }
        }
      }
    }); // End tag declaration

    If the difference between attributes and properties is unclear to you, take a look at the top answer to this Stack Overflow question. Although the question being asked is about something else entirely (jQuery), the top answer has a great explanation that will help you understand the relationship between attributes and properties.

    The Finished Component

    When we write code that depends on custom elements having been loaded already, we add an event listener that fires when the components have finished loading. This is sort of like jQuery’s document.ready.

    <script type="text/javascript">
    document.addEventListener('DOMComponentsLoaded', function(){
      // Any HUD customizations should be done here.
      // We just pop up the HUD here to show you it works!
      var testHUD = document.getElementById("test");
      testHUD.label = "Please Wait...";
      testHUD.show();
    }, false);
    </script>

    X-Tag Status HUD Demo

    There you have it. We’ve created a simple modular, reusable widget for our client-side code. It’s a good starting point. But is it really finished?

    Some ways we may improve this element:

    • Have the element recalculate it’s size when the attributeChanged event is fired and have the component resize to fit the label as it is updated rather than truncate the label with an ellipsis
    • Let the developer set an image, such as an animated GIF, in place of the CSS spinner to customize the user experience further
    • Have a progress bar instead of a spinner to give the user some additional information about task progress

    Use your creativity to come up with a small set of practical features and improvements beyond these as an exercise on your own.

    After following this tutorial you should understand how to extend the DOM with your own custom elements. If you’re stuck, leave a comment and we’ll do our best to get you back on track. If you’re not stuck, post your GitHub repo and show us what you’ve made with Brick and X-Tag. Happy hacking!

  6. Designing Web Apps For Multiple Devices

    Before 2010, there were few devices on the Web other than smartphones and desktop/laptop computers. Developers could assume phone users had a small screen, low bandwidth and used a webapp for brief moments. Desktop users were assumed to have a large screen, high bandwidth and spend large amounts of time within an application.

    Designing a webapp now means designing for 2014 and beyond, where users buy giant phones, phablets and tablets in many sizes. 4G connections may be faster than DSL or the throttled Wi-Fi at a coffee-shop. A number of laptop and “all-in-one” computers have touchscreens. Users may spend an evening hour on the couch with a tablet. And it was never true that all desktop users wanted apps to take up their whole screen – writing an e-mail or report often requires consulting another app, which ought to be content with half the screen.

    Segmenting users by device today typically leads to bad assumptions for large minorities. Users use multiple devices throughout the day and dislike learning different interaction patterns for different devices. Apple’s “Back to the Mac” initiative sought to bring smartphone features to OS X, and Windows 8 and Ubuntu Unity strive to have a single experience from phones to desktops.

    App examples

    It is difficult to achieve a good user experience for all devices and screen sizes, as seen by the criticism of Windows 8 and “Back to the Mac”. It can be done for a range of devices, especially by new apps unburdened by legacy expectations. I present here two web apps optimized for smartphones through desktops (but not “smart” TVs, feature phones nor smartwatches): a photo gallery and a memo app.

    Photo gallery

    The photo gallery is half of a photo sharing app. A sample album of the gallery can be seen online. (The application described as a whole is worth seeing.)

    photo gallery: thumbnail grid

    The photo gallery follows the paradigm used by a number of prior photo browsing apps. Thumbnails are presented in a grid which scrolls vertically. The number and width of columns depends on the screen width. Grid cells could be small or large; I chose the minimum cell size to be the smallest common screen width for smartphones: 320 CSS pixels. Thus, the number of columns is floor(windowWidth / 320) and the cell size is windowWidth / number of columns. Columns normally are from 320 to 639 pixels wide.

    Window Width # Columns Typical Device
    320-639 1 phone/phablet (portrait)
    640-959 2 phablet (landscape), tablet (portrait)
    960-1279 3 tablet (landscape)
    1280- 4 laptop, desktop

    The number of columns is capped at four, so scrolling doesn’t outpace data transfer.

    One approach would use fixed size thumbnails of 300×300 and increase the padding as cells get larger. However, the image library available (libjpeg) only supports half-, quarter- and eighth-size reductions, so padding is fixed and images are resized to fill. The web app requests a photo of appropriate size and the server (written in node.js, and normally running on a phone) returns the smallest version of the photo that fills the requested size cell.

    photo gallery: carousel

    Tapping on a thumbnail switches to a carousel which fills the window. The user can zoom in further by double-tapping the image or using the mousewheel. Originally, full-screen mode was engaged when the carousel was displayed; however, changing to full-screen takes several seconds on many devices, so now full-screen mode must be manually set. Touchscreen users can swipe to navigate forward and backward, while desktop users can use the keyboard. A weakness is that a mouse user can click on a picture to navigate forward, but must swipe (or use the keyboard) to navigate backward. Mouse users could benefit from visible navigation buttons, but mice aren’t easy for a web app to detect.

    Switching modes from the thumbnail gallery to the carousel and back is easy on any device. This supports the typical scenario of: user skims thumbnails to photo of interest, taps to enlarge, uses carousel to go through related photos, and returns to thumbnails. Users can navigate a substantial number of photos the same way on any device. A larger screen is shows more thumbnails at once and more detail on individual photos, but interaction is the same.

    Development was eased by creative use of the List widget of Enyo 2 (though any list widget could have been used). Application code sizes the cells and fills each row with 1-4 thumbnails, while the List widget handles creating and re-using DOM elements. The carousel is Enyo’s ImageCarousel, which is designed from the ground up to run well on multiple types of devices.

    Memo app

    The second example is a deceptively simple memo app, which can be used on-line or installed on Firefox OS from the Marketplace

    Memos: phablet landscape (two columns)

    The fundamental layout is two panels side-by-side. In windows narrower than 640 CSS pixels, the second panel slides in on top of the first. Collapse is based solely on window width, not device class, so phablet users will have one column in portrait mode and two columns in landscape mode.

    Memos: phablet portrait (one column)

    Tablet and desktop users don’t need to muck with dialogs or layers, while phone users have fast transitions. Most importantly, the shift in mental models is easy when going from a phone to a larger device. While this app does not currently sync user data between devices, adding that would give a seamless experience across devices.

    Presently, the Help pane displaces the Details pane. In windows wider than 960px, Help should really be a third panel.

    The collapsing panels use the Enyo Panels widget. Another instance of Panels is used to swap the Details and Help panes in the second panel. Using a JavaScript framework designed to support multiple devices really speeds development.

    To maximize display of user data the list foregoes controls on items in favor of direct manipulation: items can be swiped (or double-clicked) for operations such as Delete. Reordering is done by hold-then-drag. Discoverability was traded off for power – many apps will need to strike a different balance. A possible future enhancement on larger screens would be to add visible controls or at least tool tips.

    Memos: live search (phone)

    Fixed groupings such as folders or notebooks would require the user to navigate an extra level to access data. Search allows a memo to be in multiple groupings, and requires less UI. (However, it is not appropriate for users who rely on spatial memory.)

    While typing on a touchscreen is laborious, the app minimizes typing by using prefix searches. Searching for “s fra” will find all memos that contain “San Francisco” and few false positives among hundreds of memos. The on-screen keyboard on most phones obscures all but a few list items, but live search and the counter of hits tells the user when she has narrowed the search to a handful of memos. Skimming the list then allows the user to select the desired record. Live full-text search is implemented using IndexedDB.

    Typing is also minimized by localizing the search to the preferred language of the browser or OS. In Spanish ñ is a different letter than n (and Spanish keyboards have a key devoted to it), just as w is a different letter than u in English. For Spanish users, peña never matches pena, reducing false matches. However, users are not required to know languages other than their own, so for a Spanish user “cote” matches the French cote, coté, côte and côté.

    Hardware keyboards allow users to type more quickly and accurately, larger screens minimize scrolling, and faster processors and disks make complicated searches nearly instantaneous, but the interface works the same for all devices.

    Mobile first

    Both apps were designed “mobile-first”, which tends to result in lean apps, with fewer features than standard desktop apps. Given that most features in desktop apps are rarely used, that’s not necessarily a problem for desktop users. Carefully-chosen defaults eliminate the need for preference settings.

    Working out a user interface design that works well across a range of devices often requires more effort initially, but can result in a more user friendly experience with the added benefit of being easier to maintain. A few powerful user-interface elements can eliminate the need for many panes, dialogs, dropdowns and buttons.

  7. Who moved my geolocation?

    One of the questions we often get when we are talking about Firefox OS is: “What about the GPS on some devices”? You may have noticed that on some devices, the GPS position is not quite accurate or can take a long time to report even when you are outside. Let me start by explaining how it works first. After, we’ll see what the issue is right now, and how we can, as developers, continue to work our magic, and create awesome applications using geolocation.

    How the devices give you geolocation

    Most smartphones use two techniques to help you get the longitude and latitude of the phone: the GPS itself, but also something called A-GPS (Assisted GPS) servers. When you are outside, the GPS connects with satellite signals, and gets you the coordinates of the device: latitude and longitude. It works well as long as the GPS can connect with satellites, but it can take some time to achieve this, or to give you something more accurate.

    To help the device achieve its goal faster, often you’ll get a location from an A-GPS server: this is why most of the time, you’ll first get a location within maybe 50 meters, and if you wait a little longer, you’ll get something more accurate. It’s also why, when you are using dedicated GPS devices (like the one you use for hiking or geocaching), it takes longer: they just use the GPS, and need to connect to more satellite, no assisted GPS connection.

    What about Firefox OS?

    Mozilla doesn’t provide any Firefox OS images; we provide source code to chip manufacturer, and OEMs like Geeksphone. These parties customize various parts and create binary images for devices. The final Firefox OS image is mostly representative of what we have in the public source repositories, but with some modifications. This is an important distinction because the configuration of some parts (like Linux config, device setup, etc.) is not in Mozilla’s hands.

    With that in mind, some devices have configuration problems for A-GPS. We are actively working with OEMs to solve that issue, but it’s not something we can fix by ourselves. Once it is fixed for specific devices with A-GPS problems, we’ll let you know about the procedure to fix your device on this blog.

    But I need geolocation for my application

    There are many ways to develop applications needing geolocation information even with this little A-GPS issue. First, you can use the simulator to test your application. There is a nice little option right in the simulator to let you emulate any coordinates you need.

    Screenshot of the Firefox OS Simulator

    Of course, while the simulator is perfect for the development part and the first series of tests, you’ll need to test your new masterpiece on a real device. If you are using Linux or OS X (I’m working on a solution for Windows users), our friend, Doug Turner, created a mock location provider which you can install on your (rooted) phone to do some tests. It can hardcode the latitude and longitude that Firefox OS itself returns to your phone. You can change those coordinates by editing MockGeolocationProvider.js file in the components folder of the project. Of course, you could hardcode this yourself in your code, but you won’t be able to see how well your code handles what the device returns to you.

    Last but not least, you can also use free services like freegeoip.net. It’s a database that you can use to detect geolocation from IP addresses. It’s not perfect, but it’s a good start to give a more accurate location to the user and a good fallback solution for any applications. You never know when there will be a problem with A-GPS or GPS.

    Best practices for apps using GPS

    There are a couple of things you need to keep in mind when you are building an application that needs geolocation. First, you need to think about the accuracy of the result you’ll receive. What you need to know is that using getCurrentPosition tries to return a result as fast as possible: sometimes it means using wifi or the IP address to get the result. When using the GPS device, it may take minutes before it connects to satellites, so in that situation, you have two choices:

    1. You can get the accuracy of the result, in meters, by getting accuracy for the coordinates returned by getCurrentPosition (see code below);
    2. Alternatively, you can define a HighAccuracy option when you call getCurrentPosition (see code below).
    var options = {
        enableHighAccuracy: true,
        timeout: 5000,
        maximumAge: 0
    };
     
    function success(pos) {
        var crd = pos.coords;
     
        console.log('Your current position is:');
        console.log('Latitude : ' + crd.latitude);
        console.log('Longitude: ' + crd.longitude);
        console.log('More or less ' + crd.accuracy + ' meters.');
    };
     
    function error(err) {
        console.warn('ERROR(' + err.code + '): ' + err.message);
    };
     
    navigator.geolocation.getCurrentPosition(success, error, options);

    You also need to think about the fact that the user may move, so you need to re-estimate the user’s coordinates every so often, depending on what you are trying to achieve. You can do this either manually or by using the watchPosition method of the geolocation API in Firefox OS.

    var watchID = navigator.geolocation.watchPosition(function(position) {
        do_something(position.coords.latitude, position.coords.longitude);
    });

    In that situation, if the position changes, either because the devices moves or because more accurate geolocation information arrives, your function will be called, and you’ll be able to handle the new information.

    If you want more information about how to use geolocation in your application, you can always check the Mozilla Developer Network documentation on using geolocation. If you have any questions about using geolocation in your Firefox OS application, please leave a question in the comments’ section.

  8. User-Agent detection, history and checklist

    History

    User-Agent: <something> is a string of characters sent by HTTP clients (browsers, bots, calendar applications, etc.) for each individual HTTP request to a server. The HTTP Protocol as defined in 1991 didn’t have this field, but the next version defined in 1992 added User-Agent in the HTTP requests headers. Its syntax was defined as “the software product name, with an optional slash and version designator“. The prose already invited people to use it for analytics and identify the products with implementation issues.

    This line if present gives the software program used by the original client. This is for statistical purposes and the tracing of protocol violations. It should be included.

    Fast forward to August 2013, the HTTP/1.1 specification is being revised and also defines User-Agent.

    A user agent SHOULD NOT generate a User-Agent field containing
    needlessly fine-grained detail and SHOULD limit the addition of
    subproducts by third parties. Overly long and detailed User-Agent
    field values increase request latency and the risk of a user being
    identified against their wishes (“fingerprinting”).

    Likewise, implementations are encouraged not to use the product
    tokens of other implementations in order to declare compatibility
    with them
    , as this circumvents the purpose of the field. If a user
    agent masquerades as a different user agent, recipients can assume
    that the user intentionally desires to see responses tailored for
    that identified user agent, even if they might not work as well for
    the actual user agent being used.

    Basically, the HTTP specification discouraged since its inception the detection of the User-Agent string for tailoring the user experience. Currently, the user agent strings have become overly long. They are abused in every possible way. They include detailed information. They lie about what they really are and they are used for branding and advertising the devices they run on.

    User-Agent Detection

    User agent detection (or sniffing) is the mechanism used for parsing the User-Agent string and inferring physical and applicative properties about the device and its browser. But let get the record straight. User-Agent sniffing is a future fail strategy. By design, you will detect only what is known, not what will come. The space of small devices (smartphones, feature phones, tablets, watches, arduino, etc.) is a very fast-paced evolving space. The diversity in terms of physical characteristics will only increase. Updating databases and algorithms for identifying correctly is a very high maintenance task which is doomed to fail at a point in the future. Sites get abandoned, libraries are not maintained and Web sites will break just because they were not planned for the future coming devices. All of these have costs in resources and branding.

    New solutions are being developed for helping people to adjust the user experience depending on the capabilities of the products, not its name. Responsive design helps to create Web sites that are adjusting for different screen sizes. Each time you detect a product or a feature, it is important to thoroughly understand why you are trying to detect this feature. You could fall in the same traps as the ones existing with user agent detection algorithms.

    We have to deal on a daily basis with abusive user agent detection blocking Firefox OS and/or Firefox on Android. It is not only Mozilla products, every product and brand has to deal at a point with the fact to be excluded because they didn’t have the right token to pass an ill-coded algorithm. User agent detection leads to situation where a new player can hardly enter the market even if it has the right set of technologies. Remember that there are huge benefits to create a system which is resilient to many situations.

    Some companies will be using the User-Agent string as an identifier for bypassing a pay-wall or offering specific content for a group of users during a marketing campaign. It seems to be an easy solution at first but it creates an environment easy to by-pass in spoofing the user agent.

    Firefox and Mobile

    Firefox OS and Firefox on Android have very simple documented User-Agent strings.

    Firefox OS

    Mozilla/5.0 (Mobile; rv:18.0) Gecko/18.0 Firefox/18.0

    Firefox on Android

    Mozilla/5.0 (Android; Mobile; rv:18.0) Gecko/18.0 Firefox/18.0

    The most current case of user agent detection is to know if the device is a mobile to redirect the browser to a dedicated Web site tailored with mobile content. We recommend you to limit your detection to the simplest possible string by matching the substring mobi in lowercase.

    /mobi/i

    If you are detecting on the client side with JavaScript, one possibility among many would be to do:

    // Put the User Agent string in lowercase
    var ua = navigator.userAgent.toLowerCase();
    // Better to test on mobi than mobile (Firefox, Opera, IE)
     
    if (/mobi/i.test(ua)) {
     
        // do something here
     
    } else {
     
        // if not identified, still do something useful
     
    }

    You might want to add more than one token in the if statement.

    /mobi|android|touch|mini/i.test(ua)

    Remember that whatever the number of tokens you put there, you will fail at a point in the future. Some devices will not have JavaScript, will not have the right token. The pattern or the length of the token was not as you had initially planned. The stones on the path are plenty, choose the way of the simplicity.

    Summary: UA detection Checklist Zen

    1. Do not detect user agent strings
    2. Use responsive design for your new mobile sites (media queries)
    3. If you are using a specific feature, use feature detections to enhance, not block
    4. And if finally you are using UA detection, just go with the most simple and generic strings.
    5. Always provide a working fallback whatever the solutions you chose are.

    Practice. Learn. Imagine. Modify. And start again. There will be many road blocks on the way depending on the context, the business requirements, the social infrastructure of your own company. Keep this checklist close to you and give the Web to more people.

  9. The Proximity API

    Something that’s very nice with bringing the web to the mobile platform with Firefox OS and WebAPIs is the ability to connect more into the physical world. One part there is the Proximity API, which is also a W3C Working Draft – Proximity Events.

    What it is

    The API is about detecting how close the device is to any other physical object, by accessing the proximity sensor. There are two ways of working with proximity

    • Device proximity
    • User proximity

    From the spec:

    The DeviceProximityEvent interface provides web developers information about the distance between the hosting device and a nearby object.

    The UserProximityEvent interface provides web developers a user-agent- and platform-specific approximation that the hosting device has sensed a nearby object.

    Using it

    Working with proximity is as easy as adding a couple of event handlers, depending on what you want to do. The deviceproximity event works with the metric system, and you will get back the distance in centimeters (these examples take for granted that you have an existing proximityDisplay element to present the values in). You are also able to check the minimum and maximum distance the sensor in your device supports.

    window.ondeviceproximity = function (event) {
        // Check proximity, in centimeters
        var prox = "<strong>Proximity: </strong>" + event.value + " cm<br>";
            prox += "<strong>Min value supported: </strong>" + event.min + " cm<br>";
            prox += "<strong>Max value supported: </strong>" + event.max + " cm";
        proximityDisplay.innerHTML = prox;
    };

    It should be noted that the values sensors currently can return a quite small value, ranging from 0 up to 5 or 10 centimeters. In general, I believe the use case has been to detect if the user is holding the device up to the ear or not, but my personal opinion is that this could provide to be even more exciting if it supported, say, up to a meter!

    With userproximity, the value you get back is a near property on the event object, which is a boolean returning whether the user is near to the sensor or not.

    window.onuserproximity = function (event) {
        // Check user proximity
        var userProx = "<strong>User proximity - near: </strong>" + event.near + "<br>";
        userProximityDisplay.innerHTML = userProx;
    };

    I’ve also added device and proximity code and testing to the Firefox OS Boilerplate App so feel free to get the latest code there and play around with it.

    Web browser support

    The Proximity API is currently supported in:

    Conclusion

    Working with proximity is yet another example of crossing the gap between software and real physical context, and showing just how powerful the web can be. We hope to see you creating many interesting things based on it!

  10. Announcing the winners of the March 2013 Dev Derby!

    This past March, some of the most creative web developers out there showed us what they could do for the mobile Web in the March Dev Derby contest. After looking through the entries, our our three expert judges–Craig Cook, Franck Lecollinet, and Guillaume Lecollinet–decided on three winners and two runners-up.

    Not a contestant? There are other reasons to be excited. Most importantly, all of these demos are completely open-source, making them wonderful lessons in the exciting mobile experiences you can create today using only the skills you already have.

    Dev Derby

    The Results

    Winners

    Runners-up

    The March Derby saw some great entries, from games to productivity applications to wonderfully useful location-based services and more. Please join me in congratulating these winners and all of our contributors for making the wireless world a better and more exciting place.

    Want to get a head start on an upcoming Derby? We are now accepting demos related to getUserMedia (May) and WebGL (June). Head over to the Dev Derby to get started.