Mozilla

Apps Articles

Sort by:

View:

  1. Firefox OS App Workshop Prague

    Back in March, Mozilla tech evangelist Frédéric Harper visited Prague in the Czech Republic and gave a talk at the local Prague JavaScript meetup. His presentation, Empower Mobile Web Developers With JavaScript and WebAPI introduced a roomful of Czech JavaScripters to Firefox OS, Open Web Apps, and our recent integration with Apache Cordova and Adobe PhoneGap. PhoneGap/Cordova developers who’ve built native apps for other platforms and stores can now port PhoneGap-built apps to Firefox OS.

    Just as sure as the coming of summer, Firefox OS is coming to the Czech Republic in 2014, and Fred and friends are heading back to Prague to host a full-day, invitation-only Firefox OS App Workshop on Saturday, June 28. There will be phones! All participants will receive a developer device to test and demo their apps, and to keep for future app development. For free.

    Requirements: Show us your app

    REQUIRED: To qualify for this free hands-on, technical workshop, you must be able to show us a published HTML5 app that you’re porting to Firefox OS or a working Firefox OS app in progress. Show us a link to your existing app or to working code for the app you’re building.

    Apply now for the Prague App Workshop, June 28, 2014.

    FoxSay500


    NOTE: If you do not provide relevant links to working app code we will not be able to consider your application. Firefox Marketplace currently offers plenty of tic-tac-toe games, sliding puzzles, calculators, and to-do list apps. We love to be impressed by new, original, and locally relevant apps, for work and play.

    In the Czech Republic, we need apps that are in Czech. And if you want to extend the reach of your app by translating it to other languages, we have a pilot localization program to help you.

    What to expect

    This workshop is open to individual developers and teams of up to 4 people. The workshop begins with a technical introduction in English in the morning; the rest of the time is for coding and testing your app using the App Manager that’s built in Firefox Developer Tools. Bring laptops and devices.

    At the close of the day, there will be demos of all the apps in progress. After demos, we’ll all go to dinner. Mozilla will provide food and drink throughout the day of the workshop, but travel and lodging arrangements are up to you. And after the workshop, we will stay in touch while you complete your apps and submit them to Firefox Marketplace.

    Resources

    If you don’t have a Firefox OS app in progress, here are some resources to help you get started. There’s never been a better time:

  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. Powerful tools for developing Web Apps

    In the recent years, web development changed drastically. The emergence of the mobile web and the new form factor of smart phones created the demand for different solutions than the former desktop-only web.

    Since then a lot of frameworks and tools have been created, with new ones being added almost weekly. Now, we web developers are faced with a different problem: for every development concern, there are multiple options to consider, without clear pros or cons. It is easy to feel intimidated not only by the choices available, but also by how similar those choices are.

    Every day, web developers have to successfully overcome this issue and turn this diversity from a daunting proposition into an empowering one.

    But why reinvent the wheel all the time?

    A set of solid recommendations for app developers

    Mozilla is putting together a core set of tools and recommendations that we believe are the most useful for making Web apps.

    The key considerations for what we might recommend are:

    • Sufficiently well-documented and straightforward to use for an average developer (we will concisely document the required knowledge one needs in order to engage with the technology).
    • Loosely coupled and as modular as possible (so you can follow one recommendation but not another if you are so inclined).
    • Tested on Mozilla products (i.e. the UI components will perform well on Firefox OS, etc), but with cross-platform apps in mind

    The upcoming, initial set of recommendations involves a toolchain that’s core to any modern web app, like a JavaScript framework, templating interface, UI framework and task runner. We will employ existing solutions wherever possible and write libraries or utilities to fill in the gaps.

    On an ongoing basis, we’ll expand this systematically across the different parts of the development experience, such as offline handling or the use of various Web APIs.

    All of this will be delivered in one central spot: The App Center on the Mozilla Developer Network (MDN), our established, renowned resource for web app development.

    But I already have it all figured out!

    We encourage you to share your success story with us. Heck, share your failures too. We need all the feedback we can get from everyday web developers. If you have a tool chain of your own, with your favorite JavaScript framework, etc., we’re not interested in converting you to something else. We’re trying to help developers who aren’t sure how to go about making these kinds of decisions.

    Come join us!

    In the Mozilla tradition, this is a community-driven process. This means your input is encouraged and appreciated, and we would like your help to make this a successful initiative!

    The main discussions around this will happen in the following places:

    For the initial tool chain recommendations, I started a thread on the mailing list already, go ahead and weigh in.

    If you have ideas for topics worth exploring in future iterations, don’t be shy and open a new thread to get the discussion started.

    What’s next?

    If this whets your appetite, then great! 2014 is an exciting year to be a web app developer. We’ll keep you updated here on Hacks, as well as the MDN App Center over the coming months.

  4. Rormix – Discover Emerging Music Videos with Firefox OS

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

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

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

    What screen sizes am I developing for?

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

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

    Back Button?

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

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

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

    Stateful design

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

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

    Creating a menu

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

    Adding some Firefox OS flavour

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

    Submitting your app

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

    zip -r package.zip *

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

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

    Aside: Using PhoneGap / Cordova and HTML5

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

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

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

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

    Contact:
    @pixelcodeUK

  5. Building a persistent Notes app for Firefox OS

    In this tutorial we will be building a notes app (like Evernote) from scratch and deploy it to Firefox OS! See a live demo.

    A persistent notes app needs a place to store all the notes for a user (so no one else can read it). For this we will use my own backend solution called Sproute. Sproute is a hosted web framework for quickly building dynamic webapps.

    First create an account with a unique subdomain then access the Dashboard through http://<mysubdomain>.sproute.io/admin. You must login with the same details used to signup to Sprotue.

    Models

    In Sproute there is a concept called Models. A model defines the dynamic data in our app with properties for data integrity. Create a new model called notes with the following fields and properties:

    • body: Text, Required, Min: 1
    • sharing: Text, Allowed Values: public, private, Default Value: private
    The model form filled out for notes

    The model form filled out for notes

    The body field will store the contents of the note. The sharing field will specify whether the note can be viewed by others (with a direct link) or just the owner. This is all the data we need to define, everything else is covered by built-in fields.

    List notes

    We need a way to list the available notes for a user. This can be done with Pages. A page is HTML with embedded template tags for retrieving and processing data.

    Open the index page. This is the home page when people view your space. We will list the notes here. Add the following:

    {{ get /data/notes?sort=_lastUpdated,desc as notes }}

    All data is retrieved through an HTTP interface so the {{ get }} tag must take a URL. The request above is retrieving all notes for the logged in user and stores the results in a variable called notes. We use a query parameter to sort the results by last modified first (An underscore denotes a built-in field).

    Let’s display each note in a list:

    <ul>
        {{ each notes as note }}
            <li><a href="/view/{{note._id}}">
            {{ word note.body 0 5 }}
            </a></li>
        {{ / }}
    </ul>

    The {{ word }} template tag will extract the first 5 words from the body content. We link to a not-yet-made page with the URL /view/<id>. note._id is a built-in unique identifier.

    Add the above code in the 'index' page

    Add the above code in the ‘index’ page

    Create a note

    Before creating the view page for a note, let’s make a new page for creating a note. Create a new page called create. Add the following HTML:

    <form action="/data/notes?goto=/" method="post">
        <div><textarea name="body"></textarea></div>
        <div><select name="sharing">
            <option value="private">Private</option>
            <option value="public">Public</option>
        </select></div>
        <button type="submit">Create Note</button>
    </form>

    Simple! As mentioned above, all data is retrieved and modified through an HTTP interface. This means we can use a simple HTML form to create a new note. The goto query parameter will redirect the user to that URL.

    Because this is a new page we need to create a new route so the page is accessible. A route is a pattern for a requested URL that will render a page if matched. There will already be a route for the index page. Click Routes and create a new one with the following:

    • Route: /create, Page: create.
    New route to 'create' page

    New route to ‘create’ page

    User login and registration

    User accounts are built into Sproute but we still need to create a Register and Login page. Thankfully this is also a simple HTML form so create a new page called users and add the following:

    <h2>Login</h2>
    <form action="/api/login?goto=/" method="post">
        <label>
            <div>Username:</div>
            <input type="text" name="name" />
        </label>
        <label>
            <div>Password:</div>
            <input type="password" name="pass" />
        </label>
        <button type="submit">Login</button>
    </form>

    You may add the Register form on the same page by copying the login form and replace the action attribute to /api/register. Create two new routes with the following:

    • Route: /login, Page: users
    • Route: /register, Page: users

    View and update a note

    Previously we created a link to view a note. This will also be where we let users modify the note. Create a new page called view and add the following:

    {{ get /data/notes/_id/:params.id?single=true admin as note }}
     
    {{ if note.sharing eq private }}
        {{ if note._creator neq :session.user._id }}
            {{ error This note is private }}
        {{ / }}
    {{ / }}
     
    <form action="/data/notes/_id/{{params.id}}?goto=/" method="post">
        <div><textarea name="body">{{note.body}}</textarea></div>
        <div><select name="sharing">
           <option value="private" selected>Private</option>
           <option value="public">Public</option>
        </select></div>
        <button type="submit">Update Note</button>
    </form>

    We make a request to get the note data for the note that was passed into the URL (through the params object). The query parameter single=true will return just the object instead of a one item collection. admin will run the request with the specified user-type. Next we check whether the note is private. If so throw an error if the user is not the creator.

    The update form is very similar to the create form. We only need to change the action to update notes where the _id matches the one in the URL.

    This page requires a slightly complex route. We need to use a placeholder in the route so that /view/anything will still match the view page and store anything in a variable.

    Create a route with the following:

    • Route: /view/:id, Page: view

    Now you can see where params.id comes from. params is an object for all placeholders in the route and the matched values.

    Permissions

    The last important concept of Sproute is permissions. Permissions are just like routes where a requested URL matches a pattern but instead of pointing to a page, it validates against a required user type.

    Click Permissions and add the following:

    • Method: GET, Route: /data/notes, User: Owner
    • Method: GET, Route: /data/notes/*, User: Owner

    This will make sure the only notes listed will be ones the user has created (i.e. the owner). Because of the second permission, we needed to run the {{ get }} request as admin otherwise it would fail for everyone (except for admins and the creator) even if the note is public.

    Adding a permission to retrieving notes

    Adding a permission to retrieving notes

    Firefox OS support

    Sproute can very easily support hosted apps on Firefox OS by creating a page with the manifest JSON data and the route: /manifest.webapp.

    Create a new page called manifest with the following:

    {
        "name": "{{self.name}}",
        "description": "A persistent notes app",
        "launch_path": "/",
        "icons": {
            "128": "/absolute/path/to/icon"
        }
    }

    Create a Route with the pattern /manifest.webapp pointing to the manifest page.

    We’re done! Test this in the app manager by using the link to the manifest (http://notes.sproute.io/manifest.webapp). Sproute is open-source and on GitHub under the Mozilla Public License v2 so you may clone the repo for private hosting.

    Notes app at mobile width

    Notes app at mobile width

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

  7. Better integration for open web apps on Android

    Up until now, developing web apps on mobile has been a little tricky.

    After spending the time developing your app, getting your users to install it is difficult, especially when the concept of “installing a web app” is not very well defined.

    The most popular method is synonymous with adding a shortcut to the homescreen. This is problematic on a number of fronts, not least because the management of web apps – especially around launching, switching between and uninstalling web apps – differs significantly from that of native apps.

    The web app “exists” only on the homescreen, not in the app drawer.

    When it’s running, it is not clearly marked in the Recent Apps list.

    Even once you get something like a smooth user-flow of installing your app onto the user’s phone’s homescreen, you often find that your app is running in a degraded or out-of-date web view, missing out on compatibility or speed optimizations of a desktop class browser.

    What we as developers would like is a modern, fast web runtime, which is kept up-to-date on our devices.

    Wouldn’t it also be nice for our users to launch and manage their web apps in the same way as native apps?

    Introducing APK Factory

    We have been working on making web apps be real on the desktop for some time. On the desktop, if you install a web app, Firefox will repackage the app as a desktop app so that it will integrate perfectly with the rest of your system – as outlined in more detail in Progress report on cross-platform Open Web Apps.

    That means being in the Start menu on Windows, or in the Launch Control screen on Mac OS X.

    From Firefox 29, that will apply to Android too.

    This means that as a web developer, you can rely on a modern, up-to-date web runtime on Android to run your web apps. Even better, that web runtime is provided by an ordinary Android app, which means it will stay modern and up-to-date, and you can finally say goodbye to the Android Browser.

    A web app, called ShotClock. Notice its icon in the top right of the screen.

    The user will experience your web app as if it is a real native Android app:

    • The app appears in the App Drawer, the Recent Apps list, with its own names and icons,
    • The app can be installed and uninstalled just like a native Android app,
    • The app can be updated just like a native Android app.

    In the App Drawer

    In the Recent Apps list: all these apps are web apps

    Installed with certain permissions

    Best yet, is that we make these changes without the developer needing to do anything. As a developer, you get to write awesome web apps, and not worry about different packaging needed to deliver the web app to your users.

    So if you’re already making first-class apps for Firefox OS, you’re already making first-class apps for Android.

    The Technical details

    On Firefox, you can install an app using the window.navigator.mozApps.install(manifestUrl) method call. Any website can use this API, so any website can become an app store.

    The manifestUrl is the URL of a manifest.json document which describes the app to your phone without actually loading the app:

    • The app’s name and description, translated into any number of languages.
    • The app’s icon, in various sizes for different pixel densities.
    • The permissions that the app needs to run.
    • The WebActivities that the app wants to register.
    • For packaged apps only, this provides a URL to the zip file containing the app’s code and resources.

    On Firefox for Android, we implement this method by sending the URL to a Mozilla-managed service which builds an Android APK specifically for the app.

    APKs created by the Factory use Android’s excellent Resource framework so that the correct icon and translation is displayed to the user, respecting the user’s locale or phone screen.

    Web app permissions are rendered as Android permissions, so the user will have a completely native experience of installing your app.

    For packaged apps, the APK also includes a copy of the packaged zip file, so that no extra networking is required once the app is downloaded.

    For hosted apps, the first time the app is launched, the resources listed in its appcache are downloaded, so that subsequent launches can happen as quickly as possible, without requiring a network connection.

    And if you want to detect if the app is running in a web app versus in a webpage, checking the getSelf() method call will help you:

    if (window.navigator.mozApps) {
      // We're on a platform that supports the apps API.
      window.navigator.mozApps.getSelf().onsuccess = function() {
        if (this.result) {
          // We're running in an installed web app.
        } else {
          // We're running in an webpage.
          // Perhaps we should offer an install button.
        }
      };
    }

    Keeping your apps up-to-date

    For hosted apps, you update your apps as usual: just change your app on your server, and your users will pick up those changes the next time they run your app. You can change as much as you want, and your users will get the latest version of the app each time they launch and connect to your servers.

    For anything needing changes to the app’s manifest, your users will get an updated APK sent to them to update their existing installation.

    For example, if you want to change the app’s icon, or even name, changing the app’s manifest will cause the APK Factory service to regenerate the app’s APK, and notify your users that there is a new version available for install.

    For packaged apps, the same mechanism applies: change the app’s package zip file, then update the version number in the app’s manifest file, and the APK Factory will pick up those changes and notify your users that an updated app is available. Your users will get an notified that there’s a new APK to install. Simples.

    Is that it?

    This is an exciting project. It has very little web developer involvement, and no extra API for developers to use: however, it should represent a step forward in usability of web apps on Android.

    Now that we have taken the step to generate APKs for web apps, this gives us a platform for further blurring the lines between web apps and apps. Check it out for yourself and help us improve the feature: get Firefox Beta from the Google Play Store, install apps from the Firefox Marketplace, and let us know what you think!

  8. App basics for Firefox OS – a screencast series to get you started

    Over the next few days we’ll release a series of screencasts explaining how to start your first Open Web App and develop for Firefox OS.

    Firefox OS - Intro and hello

    Each of the screencasts is terse enough to watch in a short break and the whole series should not take you more than an hour of your time. The series features Jan Jongboom (@janjongboom), Sergi Mansilla (@sergimansilla) of Telenor Digital and Chris Heilmann (@codepo8) of Mozilla and was shot in three days in Oslo, Norway at the offices of Telenor Digital in February 2014.

    Here are the three of us telling you about the series and what to expect:

    Firefox OS is an operating system that brings the web to mobile devices. Instead of being a new OS with new technologies and development environments it builds on standardised web technologies that have been in use for years now. If you are a web developer and you want to build a mobile app, Firefox OS gives you the tools to do so, without having to change your workflow or learn a totally new development environment. In this series of short videos, developers from Mozilla and Telenor met in Oslo, Norway to explain in a few steps how you can get started to build applications for FirefoxOS. You’ll learn:

    • how to build your first application for Firefox OS
    • how to debug and test your application both on the desktop and the real device
    • how to get it listed in the marketplace
    • how to use the APIs and special interfaces Firefox OS offers a JavaScript developer to take advantage of the hardware available in smartphones.

    In addition to the screencasts, you can download the accompanying code samples from GitHub . If you want to try the code examples out for yourself, you will need to set up a very simple development environment. All you need is:

    • A current version of Firefox (which comes out of the box with the developer tools you need) – we recommend getting Firefox Aurora or Nightly if you really want to play with the state-of-the-art technology.
    • A text editor – in the screencasts we used Sublime Text, but any will do. If you want to be really web native, you can try Adobe Brackets.
    • A local server or a server to push your demo files to. A few of the demo apps need HTTP connections instead of local ones.

    sergi and chris recording

    Over the next few days we’ll cover the following topics:

    In addition to the videos, you can also go to the Wiki page of the series to get extra information and links on the subjects covered.

    Come back here to see the links appear day by day or follow us on Twitter at @mozhacks to get information when the next video is out.

    jan recording his video

    Once the series is out, there’ll be a Wiki resource to get them all in one place. Telenor are also working on getting these videos dubbed in different languages. For now, stay tuned.

    Many thanks to Sergi, Jan, Jakob, Ketil, Nathalie and Anne from Telenor to make all of this possible.

  9. The Translation of the Firetext App

    The History

    Firetext is an open-source word processor. The project was started in early 2013 by @HRanDEV, @logan-r, and me (@Joshua-S). The goal of the project was to provide a user-friendly editing experience, and to fill a major gap in functionality on Firefox OS.

    Firetext 0.3Firetext 0.3

    In the year since its initiation, Firetext became one of the top ten most popular productivity apps in the Firefox Marketplace. We made a myriad of new additions, and Firetext gained Dropbox integration, enabling users to store documents in the cloud. We also added Night Mode, a feature that automatically adjusts the interface to the surrounding light levels. There was a new interface design, better performance, and web activity support.

    Even with all of these features, Firetext’s audience was rather small. We had only supported the English language, and according to Exploredia, only 17.65% of the world’s population speak English fluently. So, we decided to localize Firetext.

    The Approach

    After reading a Hacks post about Localizing Firefox Apps, we determined to use a combination of webL10n and Google Translate as our localization tools. We decided to localize in the languages known by our contributors (Spanish and German), and then use Google Translate to do the others. Eventually, we planned to grow a community that could contribute translations, instead of just relying on the often erratic machine translations.

    The Discovery

    A few months passed, and still no progress. The task was extremely daunting, and we did not know how to proceed. This stagnation continued until I stumbled upon a second Hacks post, Localizing the Firefox OS Boilerplate App.

    It was like a dream come true. Mozilla had started a program to help smaller app developers with the localization process. We could benefit from their larger contributor pool, while helping them provide a greater number of apps to foreign communities.

    I immediately contacted Mozilla about the program, and was invited to set up a project on Transifex. The game was on!

    The Code

    I started by creating a locales directory that would contain our translation files. I created a locales.ini file in that directory to show webL10n where to find the translations. Finally, I added a folder for each locale.

    locales.ini - Firetext

    I then tagged each translatable element in the html files with a data-l10n-id attribute, and localized alert()s and our other scripted notifications by using webL10n’s document.webL10n.get() or _() function.

    It was time to add the translations. I created a app.properties file in the locales/en_US directory, and referenced it from locales.ini. After doing that, I added all of the strings that were supposed to be translated.

    app.properties - Firetext

    webL10n automatically detects the user’s default locale, but we also needed to be able to change locales manually. To allow this, I added a select in the Firetext settings panel that contained all of the prospective languages.Settings - Firetext

    Even after all of this, Firetext was not really localized; we only had an English translation. This is where Transifex comes into the picture.

    The Translation

    I created a project for Firetext on Transifex, and then added a team for each language on our GitHub issue. I then uploaded the app.properties file as a resource.

    I also uploaded the app description from our manifest.webapp for translation as a separate resource.

    Firetext on Transifex

    Within hours, translations came pouring in. Within the first week, Hebrew, French, and Spanish were completely translated! I added them to our GitHub repository by downloading the translation properties file, and placing it in the appropriate locale directory. I then enabled that language in the settings panel. The entire process was extremely simple and speedy.

    The Submission

    Now that Firetext had been localized, I needed to submit it back to the Mozilla Marketplace.  This was a fairly straight forward process; just download the zip, extract git files, and add in the API key for our error reporting system.

    In less than one day, Firetext was approved, and made available for our global user base.  Firetext is now available in eight different languages, and I can’t wait to see the feedback going forward!

    The Final Thoughts

    In retrospect, probably the most difficult part of localizing Firetext was supporting RTL (Right To Left) languages.  This was a bit of a daunting task, but the results have totally been worth the effort!  All in all, localization was one of the easiest features that we have implemented.

    As Swiss app developer Gerard Tyedmers, creator of grrd’s 4 in a Row and grrd’s Puzzle, said:

    “…I can say that localizing apps is definitely worth the work. It really helps finding new users.

    The l10n.js solution was a very useful tool that was easy to implement. And I am very happy about the fact that I can add more languages with a very small impact on my code…”

    I couldn’t agree more!

    Firetext Editor - Spanish

    Editor’s Note: The Invitation

    Have a great app like Firetext?  You’re invited too!  We encourage you to join Mozilla’s app localization project on Transifex. With a localized app, you can extend your reach to include users from all over the world, and by so doing, help to support a global base of open web app users.

    For translators, mobile app localization presents some interesting translation and interface design challenges. You’ll need to think of the strings you’re working with in mobile scale, as interaction elements on a small screen. The localizer plays an important role in creating an interface that people in different countries can easily use and understand.  Please, get involved with Firetext or one of our other projects.

    This project is just getting started, and we’re learning as we go. If you have questions or issues not addressed by existing resources such the Hacks blog series on app localization, Transifex help pages, and other articles and repos referenced above, you can contact us. We’ll do our best to point you in the right direction. Thanks!

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