Mozilla

Apps Articles

Sort by:

View:

  1. Creating a mobile app from a simple HTML site

    This article is a simple tutorial designed to teach you some fundamental skills for creating cross platform web applications. You will build a sample School Plan app, which will provide a dynamic “app-like” experience across many different platforms and work offline. It will use Apache Cordova and Mozilla’s Brick web components.

    The story behind the app, written by Piotr

    I’ve got two kids and I’m always forgetting their school plan, as are they. Certainly I could copy the HTML to JSFiddle and load the plan as a Firefox app. Unfortunately this would not load offline, and currently would not work on iOS. Instead I would like to create an app that could be used by everyone in our family, regardless of the device they choose to use.

    We will build

    A mobile application which will:

    1. Display school plan(s)
    2. Work offline
    3. Work on many platforms

    Prerequisite knowledge

    • You should understand the basics of HTML, CSS and JavaScript before getting started.
    • Please also read the instructions on how to load any stage in this tutorial.
    • The Cordova documentation would also be a good thing to read, although we’ll explain the bits you need to know below.
    • You could also read up on Mozilla Brick components to find out what they do.

    Preparation

    Before building up the sample app, you need to prepare your environment.

    Installing Cordova

    We’ve decided to use Apache Cordova for this project as it’s currently the best free tool for delivering HTML apps to many different platforms. You can build up your app using web technologies and then get Cordova to automatically port the app over to the different native platforms. Let’s get it installed first.

    1. First install NodeJS: Cordova is a NodeJS package.
    2. Next, install Cordova globally using the npm package manager:
      npm install -g cordova

    Note: On Linux or OS X, you may need to have root access.

    Installing the latest Firefox

    If you haven’t updated Firefox for a while, you should install the latest version to make sure you have all the tools you need.

    Installing Brick

    Mozilla Brick is a tool built for app developers. It’s a set of ready-to-use web components that allow you to build up and use common UI components very quickly.

    1. To install Brick we will need to use the Bower package manager. Install this, again using npm:
      npm install -g bower
    2. You can install Brick for your current project using
      bower install mozbrick/brick

      but don’t do this right now — you need to put this inside your project, not just anywhere.

    Getting some sample HTML

    Now you should find some sample HTML to use in the project — copy your own children’s online school plans for this purpose, or use our sample if you don’t have any but still want to follow along. Save your markup in a safe place for now.

    Stage 1: Setting up the basic HTML project

    In this part of the tutorial we will set up the basic project, and display the school plans in plain HTML. See the stage 1 code on Github if you want to see what the code should look like at the end of this section.

    1. Start by setting up a plain Cordova project. On your command line, go to the directory in which you want to create your app project, and enter the following command:
      cordova create school-plan com.example.schoolplan SchoolPlan

      This will create a school-plan directory containing some files.

    2. Inside school-plan, open www/index.html in your text editor and remove everything from inside the <body> element.
    3. Copy the school plan HTML you saved earlier into separate elements. This can be structured however you want, but we’d recommend using HTML <table>s for holding each separate plan:
      </head>
      <body>
        <h1>Angelica</h1>
        <table>
          <thead>
            <tr> 
              <th></th>
              <th>Monday</th>
              <th>Tuesday</th>
              <th>Wednesday</th>
              <th>Thursday</th>
              <th>Friday</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>1.</td>
              <td>Art</td>
              <td>English</td>
          ...
    4. Change the styling contained within www/css/index.css if you wish, to make the tables look how you want. We’ve chosen to use “zebra striping” for ease of reading.
      table {
        width: 100%;
        border-collapse: collapse;
        font-size: 10px;
      }
      th {
        font-size: 12px;
        font-weight: normal;
        color: #039;
        padding: 10px 8px;
      }
      td {
        color: #669;
        padding: 8px;
      }
      tbody tr:nth-child(odd) {
        background: #e8edff;
      }
    5. To test the app quickly and easily, add the firefoxos platform as a cordova target and prepare the application by entering the following two commands:
      cordova platform add firefoxos
      cordova prepare

      The last step is needed every time you want to check the changes.

    6. Open the App Manager in the Firefox browser. Press the [Add Packaged App] button and navigate to the prepared firefoxos app directory, which should be available in school-plan/platforms/firefoxos/www.

      Note: If you are running Firefox Aurora or Nightly, you can do these tasks using our new WebIDE tool, which has a similar but slightly different workflow to the App Manager.

    7. Press the [Start Simulator] button then [Update] and you will see the app running in a Firefox OS simulator. You can inspect, debug and profile it using the App Manager — read Using the App Manager for more details. App Manager buttons<br />
    8. Now let’s export the app as a native Android APK so we can see it working on that platform. Add the platform and get Cordova to build the apk file with the following two commands:
      cordova platform add android
      cordova build android
    9. The apk is build in school-plan/platforms/android/ant-build/SchoolPlan-debug.apk — read the Cordova Android Platform Guide for more details on how to test this.

    Stage1 Result Screenshot<br />

    Stage 2

    In Stage 2 of our app implementation, we will look at using Brick to improve the user experience of our app. Instead of having to potentially scroll through a lot of lesson plans to find the one you want, we’ll implement a Brick custom element that allows us to display different plans in the same place.

    You can see the finished Stage 2 code on Github.

    1. First, run the following command to install the entire Brick codebase into the app/bower_components directory.
      bower install mozbrick/brick
    2. We will be using the brick-deck component. This provides a “deck of cards” type interface that displays one brick-card while hiding the others. To make use of it, add the following code to the <head> of your index.html file, to import its HTML and JavaScript:
      <script src="app/bower_components/brick/dist/platform/platform.js"></script>
      <link rel="import" href="app/bower_components/brick-deck/dist/brick-deck.html">
    3. Next, all the plans need to be wrapped inside a <brick-deck> custom element, and every individual plan should be wrapped inside a <brick-card> custom element — the structure should end up similar to this:
      <brick-deck id="plan-group" selected-index="0">
        <brick-card selected>
          <table>
            <!-- school plan 1 -->
          </table>
        </brick-card>
        <brick-card>
          <table>
            <!-- school plan 2 -->
          </table>
        </brick-card>
      </brick-deck>
    4. The brick-deck component requires that you set the height of the <html> and <body> elements to 100%. Add the following to the css/index.css file:
      html, body {height: 100%}
    5. When you run the application, the first card should be visible while the others remain hidden. To handle this we’ll now add some JavaScript to the mix. First, add some <link> elements to link the necessary JavaScript files to the HTML:
      <script type="text/javascript" src="cordova.js"></script>
      <script type="text/javascript" src="js/index.js"></script>
    6. cordova.js contains useful general Cordova-specific helper functions, while index.js will contain our app’s specific JavaScript. index.js already contains a definition of an app variable. The app is running after app.initialize() is called. It’s a good idea to call this when window is loaded, so add the following:
      window.onload = function() { 
          app.initialize(); 
      }
    7. Cordova adds a few events; one of which — deviceready — is fired after all Cordova code is loaded and initiated. Let’s put the main app action code inside this event’s callback — app.onDeviceReady.
      onDeviceReady: function() {
          // starts when device is ready
      },
    8. Brick adds a few functions and attributes to all its elements. In this case loop and nextCard are added to the <brick-deck> element. As it includes an id="plan-group" attribute, the appropriate way to get this element from the DOM is document.getElementById. We want the cards to switch when the touchstart event is fired; at this point nextCard will be called from the callback app.nextPlan.
      onDeviceReady: function() {
          app.planGroup = document.getElementById('plan-group');
          app.planGroup.loop = true;
          app.planGroup.addEventListener('touchstart', app.nextPlan);
      },
      nextPlan: function() {
          app.planGroup.nextCard();
      }

    Stage2 Result Animation<br />

    Stage 3

    In this section of the tutorial, we’ll add a menu bar with the name of the currently displayed plan, to provide an extra usability enhancement. See the finished Stage 3 code on GitHub.

    1. To implement the menu bar, we will use Brick’s brick-tabbar component. We first need to import the component. Add the following lines to the <head> of your HTML:
      <script src="app/bower_components/brick/dist/platform/platform.js"></script>
      <link rel="import" href="app/bower_components/brick-deck/dist/brick-deck.html">
      <link rel="import" href="app/bower_components/brick-tabbar/dist/brick-tabbar.html">
    2. Next, add an id to all the cards and include them as the values of target attributes on brick-tabbar-tab elements like so:
      <brick-tabbar id="plan-group-menu" selected-index="0">
          <brick-tabbar-tab target="angelica">Angelica</brick-tabbar-tab>
          <brick-tabbar-tab target="andrew">Andrew</brick-tabbar-tab>
      </brick-tabbar>
      <brick-deck id="plan-group" selected-index="0">
          <brick-card selected id="angelica">
          ...
    3. The Deck’s nextCard method is called by Brick behind the scenes using tab’s reveal event. The cards will change when the tabbar element is touched. The app got simpler, as we are now using the in-built Brick functionality, rather than our own custom code, and Cordova functionality. If you wished to end the tutorial here you could safely remove the <script> elements that link to index.js and cordova.js from the index.html file.

    Stage3 Result Animation<br />

    Stage 4

    To further improve the user experience on touch devices, we’ll now add functionality to allow you to swipe left/right to navigate between cards. See the finished stage 4 code on GitHub.

    1. Switching cards is currently done using the tabbar component. To keep the selected tab in sync with the current card you need to link them back. This is done by listening to the show event of each card. For each tab from stored in app.planGroupMenu.tabs:
      tab.targetElement.addEventListener('show', function() {
          // select the tab
      });
    2. Because of the race condition (planGroupMenu.tabs might not exist when the app is initialized) polling is used to wait until the right moment before trying to assign the events:
      function assignTabs() {
          if (!app.planGroupMenu.tabs) {
              return window.setTimeout(assignTabs, 100);
          } 
          // proceed

      The code for linking the tabs to their associated cards looks like so:

      onDeviceReady: function() {
          app.planGroupMenu = document.getElementById('plan-group-menu');
          function assignTabs() {
              if (!app.planGroupMenu.tabs) {
                  return window.setTimeout(assignTabs, 100);
              }
              for (var i=0; i < app.planGroupMenu.tabs.length; i++) {
                  var tab = app.planGroupMenu.tabs[i];
                  tab.targetElement.tabElement = tab;
                  tab.targetElement.addEventListener('show', function() {
                      this.tabElement.select();
                  });
              }
          };
          assignTabs();
       
          // continue below ...
    3. Detecting a one finger swipe is pretty easy in a Firefox OS app. Two callbacks are needed to listen to the touchstart and touchend events and calculate the delta on the pageX parameter. Unfortunately Android and iOS do not fire the touchend event if the finger has moved. The obvious move would be to listen to the touchmove event, but that is fired only once as it’s intercepted by the scroll event. The best way forward is to stop the event from bubbling up by calling preventDefault() in the touchmove callback. That way scroll is switched off, and the functionality can work as expected:
      // ... continuation
      app.planGroup = document.getElementById('plan-group');
      var startX = null;
      var slideThreshold = 100;
       
      function touchStart(sX) {
          startX = sX;
      }
       
      function touchEnd(endX) {
          var deltaX;
          if (startX) {
              deltaX = endX - startX;
              if (Math.abs(deltaX) > slideThreshold) {
                  startX = null;
                  if (deltaX > 0) {
                      app.previousPlan();
                  } else {
                      app.nextPlan();
                  }
              }
          }
      }
       
      app.planGroup.addEventListener('touchstart', function(evt) {
          var touches = evt.changedTouches;
          if (touches.length === 1) {
              touchStart(touches[0].pageX);
          }
      });
       
      app.planGroup.addEventListener('touchmove', function(evt) {
          evt.preventDefault(); 
          touchEnd(evt.changedTouches[0].pageX);
      });

    You can add as many plans as you like — just make sure that their titles fit on the screen in the tabbar. Actions will be assigned automatically.

    Stage4 Result Screenshot<br />

    To be continued …

    We’re preparing the next part, in which this app will evolve into a marketplace app with downloadable plans. Stay tuned!

  2. The Missing SDK For Hybrid App Development

    Hybrid vs. native: The debate has gone on, and will go on, for ages. Each form of app development has its pros and cons, and an examination of the key differences between the two methods reveals that a flat correlation is like comparing apples to oranges. Many hybrid app developers understand that they’re not starting on a level playing field with native developers, but it’s important for them to understand exactly how that field fails to be level. We should analyze the differences at the app development framework level, instead of simply comparing hybrid to native.

    Native App Development

    Native software development kits (SDKs) come prepackaged with the required tools to compile and sign apps–all that boring stuff that “just works.” Their canned templates and the common code they provide determines “how” an app works, which are hugely beneficial features hiding in plain sight.

    For example, Apple’s own development environment, Xcode, is a suite of tools that make it easier to develop software for Apple platforms. As soon as you launch Xcode, it provides a list of templates for a new project. Let’s create an iOS tabbed application and see just how many tools native app developers have available to them from the start.

    After plugging in a few settings, I quickly have a working tabbed app that can be run within a minute of Xcode’s launch. Awesome! The easy part is done, and now it’s time to sport the hoodie and headphones and focus on my goal of creating a best-selling iOS app.

    Let’s drill into this a little further and take a look at what Xcode built for me, without me even having to give it a second thought. The app fills 100% of the device’s display; the tabs are aligned to the base with a gray background; one tab is highlighted blue, the other one gray, with icons on top of the tab’s title. Event listeners are added to the tab buttons, and when I click the second tab, it then turns blue, and the other one turns gray, along with switching out the content for the second view.

    After a little more development, my app will have a separate navigation stack for each tab; the back button will show when needed; the title of each view will switch out in the header; and smooth transitions will happen as I navigate between different views. Fonts, colors, gradients, and styles will all follow what an app should look like on that platform. By expanding folders in Xcode’s project navigator, I notice the ridiculous amount of files that were placed there for me. I have no clue what they do and honestly don’t really care, but they’re actually extremely important: They’re the files that made the development of my app so seamless.

    Hybrid App Development

    Honestly, though, I’m a web developer. My organization isn’t filled with Objective-C and Java developers ready to build multiple apps with the ultimate goal of just trying to be the same app (but built entirely differently, from the ground up). I have existing HTML/CSS/JS skills, and I want my app to hit not only Apple’s App Store, but Google’s Play Store and all the others. Instead of locking myself into each platform and having to learn and maintain multiple proprietary languages, hybrid app development makes more sense, given my skill set and my time constraints.

    Don’t let hybrid app development scare you. In its simplest form, a hybrid app is still just a web browser, but without the URL bar and back button. This means you can build a full-fledged app using HTML/CSS/JS but still have it work like a native app, with all the same superpowers, like accessing bluetooth, GPS, camera, files, device motion, etc. Hybrid apps offers the best of both worlds.

    Let’s Build A Hybrid App

    For my use-case, I’ve decide a hybrid app is perfect, so let’s fire up….wait, there is no Xcode for hybrid apps! Where do I get all those files that makes my app do app things? Where’s the built-in UI, cool animations, and smooth transitions? The disadvantage to hybrid app development is that those starting with the web platform have to start from scratch. It’s the Wild West, and each developer is on his or her own.

    I absolutely love the web platform. It provides a core set of tools to not only share information but consume it. However, the web platform offers only the basic building blocks for structuring content; styling and interacting with that content; and navigating between documents. The core of the web platform does not provide pre-packaged libraries like those in iOS and Android. At the lowest level, a web browser represents one “view” and one navigation/history stack. This is another area in which native apps have an advantage, and hybrid devs burn up time generating code to give browsers the ability to handle multiple views with multiple stacks.

    Hybrid app developers quickly find themselves dealing with countless issues just to get their heads above water: figuring out the CSS to fill 100% of the viewport, sticking the tabs on the bottom and hovering content, adding event listeners, switching active states for icons and views, keeping track of navigation stacks of each tab, implementing touch gestures, generating a common way to navigate and transition between view, using hardware accelerated animations for the transitions, removing 300ms delays, knowing when to show or hide the back button, updating and animating the header title, interacting with Android’s back button, smooth scrolling through thousands of items, etc. All of these things come with native SDKs. And as an app grows, it’ll seem as though recreating natural, native interactions is a constant uphill battle–all of which native developers rarely think about, because for them it was baked in from the start.

    I believe the solution is to use a framework/library that levels the playing field, giving hybrid developers a toolkit similar to that of native developers. Most developers have a sense of pride in writing everything themselves, and there are certainly plenty of use-cases in which frameworks and/or libraries are not required. But when it comes to hybrid app development, there is a whole world of common code being recreated by each developer, for each app, and that’s a lot of work and time to invest in something that native developers already get.

    Cordova (the guts to Phonegap) is the predominant open-source software to morph the web platform into a native app. But just like the web platform, it only offers the basic building blocks, rather than a built-in framework to start with.

    Frameworks and libraries amplify app development and allow devs to focus on how their apps work, not the logic of how apps work.

    Hybrid Development Frameworks: Hybrid’s Missing SDK

    I define frameworks and libraries as any software package that increases productivity. In my experience, hybrid developers’ main frustration lies not in creating their app, but rather in getting their app to work like an app, which is a subtle, yet significant difference.

    With the advent of development frameworks focused on hybrid app development, developers finally have that missing SDK that levels the playing field with native. Cross-platform frameworks that embrace HTML/CSS/JS allow web developers to take their skills to app development. To increase productivity, hybrid app development frameworks should not only stick to the standards with pretty CSS and markup; they should also provide a MVC for serious, large-scale app development by a team.

    Sworkit, a hybrid app built using the Ionic Framework, featured in the iOS App Store.

    Sworkit, a hybrid app built using the Ionic Framework, featured in the iOS App Store.

    Frameworks like the Ionic Framework provide a common set of logic used to create apps, which isn’t already baked into the web platform (full disclosure: I am a co-creator of Ionic and a core contributor to AngularJS Material Design). Rather than inventing yet another MVC, Ionic chose to build on top of AngularJS, which has proven itself to be a leader among popular front-end frameworks in the last few years. Ionic is backed by a large and active community, solid documentation, and its own command-line tool to increase productivity (the CLI isn’t required but is highly recommended).

    Ionic’s use of AngularJS directives to create the user-interface allows for fast development, but most importantly, it’s highly customizable, through its use of Sass and simple markup. If you’re unfamiliar with AngularJS, Ionic offers a great way to learn it quickly, via numerous examples and templates.

    Google’s Polymer project and Mozilla Brick are built on top of the cutting-edge Web Components specification. As with AngularJS directives, Web Components offer a great way to abstract away complex code with simple HTML tags.

    Other proven hybrid development frameworks that have been around longer and offer their own powerful MVC/MVVM include Sencha Touch and Kendo UI. Both frameworks come with a large list of built-in components and widgets that enable developers to build powerful apps that work on iOS, Android, BlackBerry, Windows Phone, and more.

    I do not consider front-end frameworks, such as AngularJS, Ember, and Backbone to be hybrid app development frameworks. While I highly recommend front-end frameworks for large-scale app development, they’re focused on the logic, rather than the user interface.

    Frameworks like Twitter Bootstrap and Foundation offer a great user interface and responsive design capabilities. However, CSS frameworks focus on the UI and a responsive design pattern; but a UI alone still requires each developer to recreate the way a native app “works.”

    App frameworks abstract away the complexity of building an app and offer developers both the core logic and the UI, similar to what iOS and Android provide. I believe it is important to embrace the web standards and the web platform at the core, so it can be easily run from Cordova and built for multiple platforms (including a standard web browser).

    Software Engineering: Still Required

    Hybrid app development frameworks have come a long way in the last few years, and they have a bright future ahead of them. However, Developing Hybrid Apps Still Requires Actual Software Engineering, just as developing native apps does. As in any form of web development, if only a few hours are put into a project, the result is rarely a highly polished and production-ready piece of work.

    Hybrid fans sometimes offer the impression that frameworks create a unicorn and rainbow filled wonderland during development, which may mislead new developers. Just because you can write once and deploy everywhere doesn’t mean you’re exempt from the rules of software development. Hybrid offers many benefits, but as with so many things in life, cutting corners does not produce quality results, so please don’t claim all is lost after minimal effort.

    Making An Accurate Comparison

    The comparison of a hybrid app without a framework to a native app isn’t a fair one. To accurately examine hybrid vs. native development, we need to analyze each method at the framework level (hybrid with a framework vs. native, like Ionic Framework vs. iOS or Polymer vs. Android). As for hybrid vs. native: It’s a matter of studying your use-case first, rather than a choosing a definitive level of abstraction over everything else. It all ends up as 1s and 0s anyway, so jumping up another level of abstraction (HTML/CSS/JS) may be the right fit for your use-case and organization.

    I often feel that opinions regarding hybrid app development were formed well before hybrid was ready for prime time. The world has quickly been transitioning to faster devices and browsers, as well as improved web standards, and there’s no signs of either one slowing down. There is no better time than now to leverage your existing web development skills and build quality apps by standing on the shoulders of hybrid SDKs.

    @adamdbradley

  3. Introducing fxpay for in-app payments

    A while ago Mozilla announced navigator.mozPay() for accepting payments on Firefox OS. This was our first step toward helping developers do commerce on the web. It solved the problem of processing payments but what about the rest? Today we’re announcing an early peek at fxpay, a library for the rest of what you need as a developer to sell digital products in your app. This small JavaScript library (11kB minified) gives you some nice additional features on top of payment processing:

    • Work with a catalog of in-app products without hosting your own server
    • Securely verify each payment in one simple JavaScript callback
    • Restore previous purchases from receipts

    The mozPay() API is great if you need to integrate with an existing system but building a product catalog from scratch is a lot of work. If you have an idea for adding revenue to your app, why not quickly toss in some products and see what sells?

    The fxpay library is designed to get you selling as quickly as possible. Because it interacts with the Firefox Marketplace API you don’t need to manage code on your own server — you enter product details on Firefox Marketplace and call some JavaScript functions in your app to sell them.

    First: A Warning

    fxpay is in an early experimental state. We’re looking for your help to make it a concise, intuitive library which means the API might change rapidly. There’s a section below for details about how to get involved.

    Offer Some Products For Sale

    After running bower install fxpay (installation details), show some products for sale within your app using getProducts():

    // First, let's test with some fake products.
    fxpay.configure({fakeProducts: true});
     
    fxpay.getProducts(function(error, products) {
      if (error) {
        console.error(error);
      } else {
        products.forEach(function(product) {
          addBuyButtonForProduct(product);
        });
      }
    });

    The code here would add a buy button for each product so that tapping the button would start a purchase. Here’s a simplistic example:

    function addBuyButtonForProduct(product) {
      var button = document.createElement('button');
      button.textContent = 'Buy ' + product.name;
      button.addEventListener('click', function () {
     
        fxpay.purchase(product.productId, 
                       function(error, product) {
          if (error) {
            console.error(error);
          } else {
            console.log(product.name + ' bought!');
          }
        });
     
      });
      document.body.appendChild(button);
    }

    That’s it. The call to fxpay.purchase() guides the user through payment via mozPay() and verifies the result on the Firefox Marketplace server. If you receive the callback without an error that means the purchase was verified and funds will be transferred to your account upon completion. It is safe to deliver the product.

    Try It Out

    Install an app on the Firefox OS Simulator using the App Manager and tap your custom buy button. Since this is a test with fake products, you’ll see a payment simulation screen. Tap Continue and your purchase callback will fire, allowing you to get your product delivery code working.

    Restoring Purchases

    When a user completes a purchase, a portable receipt is installed on their device behind the scenes. This is a cryptographically signed JSON object that proves ownership of the product. Each time the user returns to your application, you’ll want to check for any receipts so you can restore their purchased products. The fxpay library does the validation for you but you have to define a callback for when each product is restored like this:

    fxpay.init({
      onerror: function(error) {
        console.error('init error:', error);
      },
      onrestore: function(error, product) {
        if (error) {
          console.error('onrestore error:', error);
        } else {
          console.log(product.name + ' restored');
        }
      }
    });

    Just like the purchase callback, if you don’t get an error it means the receipt is valid; the user owns the product so you should make it available. You probably only need to run init() once when your app starts up.

    Publishing Your Application

    Once you get everything working with fake products, the next step is to submit your app to the Firefox Marketplace developer hub so users can install it. The submission process is detailed in the documentation; it includes entering bank account details to receive payouts and submitting real names and prices of the products you wish to sell.

    Once all of your products are in place and your app has been approved, set {fakeProducts: false} and the same code you see here will begin to work with real products. The getProducts() function will use your app’s origin to retrieve the configured products.

    Example App

    The fxpay library ships with an example app that you can install from the App Manager and play around with.

    Get Involved

    Do you have an idea for an app with in-app payments? Try it out. We’re announcing an early version of fxpay so we can make it work well for you, the developer. If something breaks or just feels awkward or if you have an idea to make the library better, get in touch!

    Going Further

    The Payments team at Mozilla is small (but mighty!). This release has a lot of missing features but we wanted to start getting early feedback. Here are a few ideas for features we’d like to add next:

    Support More App Types

    Right now, fxpay is limited to privileged packaged apps on mobile only. See all prerequisites. We’re working to open up access to other app types such as hosted apps and desktop apps.

    Receipt Recovery

    If a user loses their device or deletes the app they will lose their in-app purchase receipts. Those receipts are backed up on the Marketplace server but users don’t have an interface to reinstall them yet. We’re trying to figure out a way to do that in bug 1045228.

    Exact Product Prices

    Price points and currencies vary by mobile network but non-certified apps don’t have a reliable way to detect users’ networks. Currently you can’t display prices next to your custom buy buttons. We’d like to offer some solutions for this even if it’s just a manual currency selector. See bug 1063758.

    Product Assets

    This first release of fxpay is best suited for local content such as unlocking a level in a game. If an app were to distribute remote content such as a MP3 file as a ring tone, there would be no way to securely protect the contents of that file. We’ll be considering how to add support for this in bug 1063059.

    We’re planning lots of other stuff too!

  4. Enabling Voice Input into the Open Web and Firefox OS

    With the advent of smartphones triggered by iPhone in 2007, Touch became the primary mode of input for interacting with these devices. And now with the advent of wearables (and other hands-free technologies that existed before), Voice is becoming another key method of input. The possibilities of experiences Voice Input enables are huge, to say the least.

    They go beyond just merely interacting with in-vehicle devices, accessories and wearables. Just think of the avenues Voice Input opens up for bringing more technologies to more people. It’s enormous: Accessibility, Literacy, Gaming, VR and the list goes on. There is a social vibe there that definitely resonates with our mission at Mozilla detailed in our Mozilla Manifesto

    How it started

    Both current leading mobile OS/ecosystem providers of today- Apple & Google have their native experiences with Siri and “OK Google” (coupled with Google Now). We really needed an effort to enable Voice Input into the first ecosystem that existed – the open Web. Around MWC 2013 in Barcelona, when Desigan Chinniah introduced me to André Natal – Firefox contributor from Brazil, we had a conversation around this and we instantly agreed to do something about this in whichever way possible. Andre told me about being inspired from a talk by Brendan Eich in BrazilJS, so I did not have much convincing to do. :-)

    First steps

    We had numerous calls and meetings over the past year on the approach and tactics around this. Since “code wins arguments”, the basic work started in parallel with Firefox desktop and FxOS Unagi devices, later switching to Mozilla Flame devices over time. Over a period of the past year, we had several meetings with Mozilla engineering leads on exact approach and decided to break this effort into several smaller phases (“baby steps”).

    The first target was getting Web Speech API implemented, and getting acoustic/language modules integrated with a decoder and giving that a try. Lots of similar minded folks in Mozilla Engineering/QA & community helped along with guidance and code-reviews while Andre moonlighted (on top of his day job) with a very high focus. Things moved fast in past month or so. (Well, to be honest, the only day this effort slowed down was when Team Brazil lost to Germany in FIFA 2014. :-)) Full credit to André for his hard work!

    Where are we?

    Our current thinking is to get a grammar-based (limited commands) app working first and distribute it in our rich & diverse international Mozilla community for accent-based testing and enhancements. Once we have this stablilized, we will get into the phase 2 where we can focus more on natural language processing and get closer to a virtual assistant experience sometime in future that can give users voice based answers. There is lots of work to do there and we are just beginning.

    I will save the rest of the details for later and jump to the current status this month. Where are we so far?

    We now have the Web Speech API ready for testing and we have a couple demos for you to see!

    Desktop: Firefox Nightly on Mac

    Editor’s note: for full effect, start playing the two above videos at the same time.

    Firefox OS demo

    Come, Join us!

    If you want to follow along, please look at the SpeechRTC – Speech enabling the open web wiki and Bug 1032964 – Enabling Voice input in Firefox OS.

    So jump in and help out if you can. We need all of you (and your voices). Remember “Many Voices, One Mozilla”!

  5. Webapplate – Maintainable web app template for Firefox OS and Chrome Apps

    There are many powerful tools and technologies surrounding the Web, and we can reuse them to develop cross platform mobile and desktop apps, especially in light of installable apps appearing on platforms such as Firefox OS. This article looks at the best way to do this, and presents Webapplate, a powerful new template to help facilitate this.

    Why invent the wheel (for the new frontier)

    As is the nature of the whole web, web apps are simple to write but hard to get done right. Even though the Web doesn’t provide an SDK or simple ready-to-use templates like other mobile platforms, you can still come out with a workable web app from candidates like Mozilla Open Web Apps, Chrome Apps, or Apache Cordova. But developers who want to quickly build a web app usually take longer time than say, an iOS developer.

    Here is the state of web app support by those candidates:

    • Firefox (desktop), Firefox OS, Firefox for Android support hosted web apps. Those web apps could be hosted on a static or dynamic web server just like normal web sites. Hosted web apps don’t allow some certified web APIs such as the TCP socket API because of security concerns.
    • Firefox OS and Chrome (desktop) support packaged web apps with different APIs for different purposes, because currently they focus on different types of devices.
    • Cordova provides device adapters for many platforms, including Android, iOS and Firefox OS.
    • Google has its Cordova variant to adapt Chrome App’s specific APIs to run on Android devices.

    In quick summary, the web app concept is not totally unified yet, but powerful enough to compete with native apps. Currently packaged web apps are mainstream because of the security concerns with new web API’s. Mozilla is mainly focusing on exposing new web APIs to mobile devices, Google is developing new web APIs for desktop. Apache Cordova is a good container to expose web APIs to different platforms.

    To make things harder, provided examples are often focused on teaching you how to pick up new web APIs rather than utilizing proper web app concepts with your development process.

    I’ve had the chance to join the development of an evolving web app project called Gaia, the Firefox OS user interface. The Gaia project contains the very first Mozilla installable web app implementation, including apps for music, photo gallery, e-mail, calendar and much more. According to GitHub’s pulse monthly, there are about 850 commits per month to the Gaia web apps. In the Gaia project, Mozilla developers and community members devoted lots of time and effort to bring it from the prototype stage to a shippable product within 2 years, and iteratively make it a competitive option for smartphone consumers. As a living large web app project, there are many lessons that can be learned from it, and applied to general web app development.

    Introducing webapplate

    Like other software projects, there are many things beside commiting code to develop a web app, such as:

    • How to organize the source code
    • How to handle library dependencies
    • How to keep the coding style in convention
    • How to optimize web app load performance
    • How to unit/integrate test your web app
    • How to localize your web app
    • How to automate those processes

    Those are topics that need to be resolved to develop a quality web app. In Gaia we have addressed these issues by utilizing a bunch of build scripts (Makefiles).

    You may wonder why we didn’t use Grunt or gulp for building? The answer: at the time Firefox OS was started, these tools didn’t exist. And the module owner wanted to make the core build process run in a Firefox extension one day.

    For general web app development, we didn’t have to follow those constraints. And we could do some experiments rapidly by reusing 3rd-party tools and libraries. From 2013, I’ve initiated a side project called webapplate, the open-sourced web app template that attempts to make Gaia’s solutions compatible with emerging toolkits like npm, Grunt and Bower. It also tries to transport good practices from Gaia to make new web apps more maintainable.

    How to setup webapplate

    Webapplate utilizes many powerful tools. With node.js, Grunt, Bower, Karma, Mocha and l20n, we come out with a maintainable full stack and self-contained web app template with JavaScript. So you could just copy or download the webapplate from Github, and develop and deploy to a hosting server or correspondent web app store.

    You need to install node.js in your desktop first. With Node.js installed, you’ll have the npm tool to manage Node.js modules. Now run this command:

    $ npm install -g grunt-cli bower karma

    to install the primary tools.

    Grunt is a JavaScript task runner tool (like Make) and grunt-cli is its command interface. Gruntfile.js file is similar to Makefile, but written in Javascript.

    Bower is a management tool for the front-end libraries. It helps developer manage different library versions. In webapplate, Bower will download client side libraries into the public/vendor folder when you run

    $ bower install

    command.

    Karma is the test runner that runs test code for each of the browsers. karma.conf.js defines the detail settings to specify how the test runner goes.

    Next, enter the webapplate folder and run:

    $ npm install

    npm will reference package.json to install all dependent node modules. The command will trigger Bower to install client-side library dependencies as well.

    Then you are all set! What you get is:

    • Pre-commit lint checking
    • Firefox and Chrome web app-compatible templates
    • Library dependency management
    • Client-side localization framework
    • Unit test and mock framework
    • Deployable web server

    If you use Firefox nightly, you could open the webapplate/public folder as a packaged app in the WebIDE developer tool.

    WebIDE allows you to edit, debug or execute your web app in the Simulator or on the device, with your favorite Firefox Developer Tools.

    With the Chrome Apps & Extensions developer tool, you can import the webapplate/public folder as a Chrome App and check the UI on desktop.

    webapplate on Chrome devtool

    Pre-commit lint checking

    The very first good practice that Gaia and webapplate provide is git pre-commit lint checking.

    Since in Gaia every commit needs to get reviewed and verified by the module owner before the code is checked in, we have followed the Google JavaScript style conventions. At that time we used gjslint to test it. It sounds good but actually forcing people to follow the exact same discipline manually is hard; asking the reviewer to pick through those style errors is another waste of time. So some genius introduced a git pre-commit hook to check several kinds of lint errors when the developer tries to commit their code, and provide a whitelist for the code that isn’t fully lint-free but should be allowed. Currently in Gaia we have pre-commit checks for JavaScript, CSS and JSON! This is a big relief.

    Currently webapplate utilizes code quality and style checking for JavaScript, JSON via JSHint, JSCS and JSONLint.

    It has exactly the same settings as Gaia for JSHint and also comes with the whitelist. Gaia is also planning to migrate to jscs to replace gjslint. If you use git for version control, run:

    $ grunt githooks

    to bind the git pre-commit code style check to your development process.

    Firefox OS- and Chrome App- compatible templates

    Webapplate uses HTML5 mobile boilerplate as the template base, and adds web app install helpers, icon links and usemin annotation for web app optimization on top. The main web app source is located in the public/ folder. You could check the webapplate wiki to see the full webapplate structure.

    Currently, Firefox web apps use manifest.webapp and Chrome Apps use manifest.json as the manifest file. The syntaxes are mutually compatible, except the localization part (we’ll address this issue later).

    After you edit one of these files, use:

    # firefox to chrome
    $ grunt f2c

    or

    # chrome to firefox
    $ grunt c2f

    to overwrite manifest.webapp with manifest.json, or viceversa.

    To generate a Firefox OS packaged app or Chrome App, run this command:

    $ grunt pack

    to package your web app to an uploadable zip file. With the default settings, webapplate-generated packaged web apps could be uploaded to the Firefox Marketplace and the Chrome App store.

    Library dependency management

    For Gaia we manage development tools via npm and generally don’t use many 3rd-party client side libraries. We host commonly-used libraries between apps in a shared/ folder, and then copy them in at build time via a build script.

    webapplate defines these libraries in package.json, uses npm to require build tools, and doesn’t assume any app framework (e.g. Backbone or Angular.js, or a UI framework such as Bootstrap.) Client-side libraries could be managed via Bower in bower.json.

    Client side localization framework

    Since web apps might be run without an Internet connection, we can’t count on the server to detect multiple languages. Currently Firefox OS uses navigator.mozL10n and Chrome Apps uses chrome.i18n for localization. Both of them are non-standard.

    In webapplate we take the l20n library to address the client-side localization issue. l20n is crafted by Mozilla and the developers are currently working on enhancing the Firefox OS localization framework as well.

    Check out index.html; the localization syntax looks exactly like what we used in Gaia:

    <h1 data-l10n-id="hello">Hello WebApplate</h1>

    The locale file however is in a different format, locales.en.l20n:

    <projectName "WebApplate">
    <hello "Hello {{ projectName }}">

    Also, check out the Multiple Language Support Framework section for how l20n is integrated with webapplate.

    Unit test and mock framework

    Gaia uses its own test-agent to trigger unit tests on Firefox. Gaia uses the Mocha test framework, Chai assertion library and the Sinon test helper library for unit tests.

    Webapplate uses the above unit test libraries plus the Karma test runner to run unit tests on all mainstream browsers.

    Deployable web server

    For developing Firefox OS hosted web apps, we need a working web server and maybe some dynamic web server support. Now that’s what we call the 21st century: it is possible to write server-side code in JavaScript as well.

    Running the command:

    $ grunt server

    will trigger the Express-powered server with django-like Swig template support. It’s been pre-configured for performance. Measure with YSlow and you’ll get a pretty good grade for your web site.

    Webapplate has been tested on some free dynamic web page hosting providers such as openshift, heroku and appfog. Check the deployment section to find out more details.

    If you like to host your web apps on a static web server, run:

    $ grunt static

    to generate optimized web pages for hosting.

    If you want to deploy your web app on a GitHub page (as a free static hosting server), run:

    $ grunt github

    Start your new web app project with webapplate!

    Webapplate is the web app template that borrows good practices for web app maintenance from the Gaia project. It provides ready-to-use Firefox OS and Chrome App support, an integrated toolbox to optimize your web app and maintain quality, and uses JavaScript through client/server side build/test frameworks. If you are about to make a web app or want to see how to maintain a web app, webapplate is a good start.

    References

  6. PhoneGap Developer App preview for Firefox OS

    The cross-platform team at Mozilla is always looking for ways to improve how developers build apps with open web standards. We consider Cordova and PhoneGap to be great tools to achieve that. We are excited to work on improving support for PhoneGap by getting the PhoneGap Developer App into Firefox OS.

    The PhoneGap Developer App allows you to easily run PhoneGap apps in multiple platforms, without the need to install SDKs or have a developer subscription. The app is available for Android, iOS and Windows Phone at their respective app stores. You can pair your app with multiple devices at a time and any changes you make to your app’s code get propagated to all devices.

    Even though developing for Firefox OS does not require a beefy SDK or a developer subscription, being able to have your changes propagate to multiple devices at once is pretty cool!

    We have started working on support for Firefox OS and you can try it out today. In this post we’re going through the steps needed to get the preview version of the PhoneGap developer app in Firefox OS. As they say, a video is worth 1k images:

    Getting the dependencies

    We will be using a development version of Cordova combined with a development version of the PhoneGap command line interface to get it all working. Luckily, they are very compatible and work well together. You will need to have git, nodejs and npm installed before proceeding.

    Let’s first get all modules we’ll need from github:

      $ git clone https://github.com/apache/cordova-firefoxos.git
      $ git clone https://github.com/apache/cordova-cli.git
      $ git clone https://github.com/apache/cordova-lib.git
      $ git clone -b fxos https://github.com/rodms10/phonegap-app-developer.git
      $ git clone -b fxos https://github.com/rodms10/connect-phonegap.git
      $ git clone https://github.com/phonegap/phonegap-cli.git

    Now let’s set dependencies up:

      $ cd connect-phonegap
      $ npm link
      $ cd ../phonegap-cli
      $ npm link connect-phonegap
      $ npm install
      $ cd ../cordova-lib/cordova-lib
      $ npm link
      $ cd ../../cordova-cli
      $ npm link cordova-lib
      $ npm install
      $ cd ..

    Load the app to your device

    The app is available at phonegap-app-developer/platforms/firefoxos/www/, just point the app manager or webIDE to this path and load it to your device or simulator. Once you start the app, you should see a screen with an IP address. That’s where you enter the address of your server.

    Starting the server

    Let’s get the server going. It will serve your app’s content to the PhoneGap Developer App. Create a new Cordova app:

      $ cordova-cli/bin/cordova create myapp org.app.my "I Heart PhoneGap Dev App"
      $ cd myapp

    Now we need to point cordova to the development version of cordova-firefoxos. In your root app folder, myapp in our case, create a folder named .cordova (with the leading dot) and add a file named config.json to the new folder with the following contents:

    {
      "lib": {
        "firefoxos": {
          "uri": "/&lt;Full/Path/To&gt;/cordova-firefoxos",
          "version": "dev",
          "id": "cordova-firefoxos-dev"
        }
      }
    }

    Make sure you have the correct full path to cordova-firefoxos in the uri property above.

    Time to start the server, we’ll switch back to PhoneGap for that:

      $ ../phonegap-cli/bin/phonegap.js serve

    You should see a line saying [phonegap] listening on 10.0.0.1:3000. Enter that IP in the PhoneGap Developer App and see your app start running there! Easy.

    Ship It!

    If you got this far, you’re probably asking why isn’t the app in the marketplace already! As you saw, to get all up an running we required the development version of the PhoneGap command line interface. Once a new version with our new code is released, we can publish the app and not require development version of the command line.

    If you have any questions leave a comment, find us at the #apps channel on IRC or send us an email at mozilla-cordova@mozilla.org.

  7. Launching Open Web Apps feedback channels – help us make the web better!

    About three months ago we launched a feedback channel for the Firefox Developer Tools, and since it was a great success, we’re happy announce a new one for Open Web Apps!

    For Developer Tools, we have, and keep on getting, excellent suggestions at http://mzl.la/devtools, which has lead to features coming from ideas there being implemented in both Firefox 32 & 33 – the first ideas shipped in Firefox only 6 weeks after we launched the feedback channels!

    Your feedback as developers is crucial to building better products and a better web, so we want to take this one step further.

    A channel for Open Web Apps

    We have now just opened another feedback channel on UserVoice about Open Web Apps, available at http://mzl.la/openwebapps

    It is a place for constructive feedback around Open Web Apps with ideas and feature suggestions for how to make them more powerful and a first-class citizen on all platforms; desktop, mobile and more.

    What we cover in the feedback channel is collecting all your ideas and also updating you on the different areas we are working on. In many cases these features are non-standard, yet: we are striving to standardize Apps, APIs, and features through the W3C/WHATWG – so expect these features to change as they are transitioned to become part of the Web platform.

    If you want to learn more about the current state, there’s lots of documentation for Open Web Apps and WebAPIs on MDN.

    Contributing is very easy!

    If you have an idea for how you believe Open Web Apps should work, simply just go to the feedback channel, enter a name and an e-mail address (no need to create an account!) and you’re good to go!

    In addition to that, you have 10 votes assigned which you can use to vote for other existing ideas there.

    Just make sure that you have an idea that is constructive and with a limited scope, so it’s actionable; i.e. if you have a list of 10 things you are missing, enter them as a separate ideas so we can follow up on them individually.

    We don’t want to hear “the web sucks” – we want you to let us know how you believe it should be to be amazing.

    What do you want the web to be like?

    With all the discussions about web vs. native, developers choosing iOS, Android or the web as their main target, PhoneGap as the enabler and much more:

    Let us, and other companies building for the web, know what the web needs to be your primary developer choice. We want the web to be accessible and fantastic on all platforms, by all providers.

    Share your ideas and help us shape the future of the web!

  8. Time to get hacking – Introducing Rec Room

    It’s no secret that the best frameworks and tools are extracted, not created out of thin air. Since launching Firefox OS, Mozilla has been approached by countless app developers and web developers with a simple question: “How do I make apps for Firefox OS?” The answer: “It’s the web; use existing web technologies.” was—and still is—a good answer.

    But if you don’t already have an existing toolchain as a web developer, I’ve been working on extracting something out of the way I’ve been creating web apps at Mozilla that you can use to write your next web app. From project creation to templating to deployment, Mozilla’s Rec Room will help you create awesome web apps in less time with more ease.

    Rec Room is a Node.js utility belt you can wear to build client side web apps. It includes:

    • Brick to add components like appbars and buttons to your UI.
    • Ember for your app’s controllers, models, and views.
    • Handlebars to write your app’s templates.
    • Grunt to run the tasks for your app, including building for production.
    • I18n.js to localize your app.
    • Mocha to test your app.
    • Stylus to write your CSS.
    • Yeoman to scaffold new code for your app’s models and templates.

    In this post I’ll walk through how to create a simple world clock web app with Rec Room, how to deploy it, and how you can try out Rec Room for yourself.

    Where Does Rec Room Come From?

    Much of Rec Room came from a recent rewrite of the HTML5 podcast app. I started working on this app well over a year ago, but its original version wasn’t as easy to work on; it had a lot of global state and a lot of by-hand data-binding. I liked the look of Ember for app development, but back when I started it didn’t quite feel mature enough. These days it’s much better, and I’ve tweaked it in Rec Room to work perfectly without a server.

    I tried to take the best from that system and extract it into a set of tools and documentation that anyone can use.

    Create your own Rec Room app

    Rec Room has just recently been extracted from my experiences with Podcasts; it hasn’t been tested by more than a handful of developers. That said: we’d love your help trying to build your own app for Firefox OS using these tools. They integrate well with tools you probably already know and use–like Node.js and Firefox’s own Web IDE.

    To get started, install Rec Room using Node.js:

    npm install -g recroom

    Clock App

    We’ll create a simple clock app with (minimal) time zone support for our example. The app will let you have a clock and compare it with a few time zones.

    The recroom binary is your entry point to all of the cool things Rec Room can do for you. First, create your app using recroom new world-clock. This creates the basic app structure. To see the basic app skeleton that Rec Room creates we can now enter that directory and run our app: cd world-clock and then type recroom run. The app will open in your default browser.

    First, we’ll add the current time to the main tab. Rec Room supports Ember’s MVC app structure, but also offers simple “pages” for a controller without a 1:1 relationship to a model. We’ll generate a new page that will show our actual clock:

    recroom generate page Clock

    We can edit its template by opening app/templates/clock.hbs. Let’s change clock.hbs to include the variable that will output our local time:

    <h2>Local Time: {{localTime}}</h2>

    That won’t do much yet, so let’s add that variable to our ClockController, in app/scripts/controllers/clock_controller.js:

    WorldClock.ClockController = Ember.ObjectController.extend({
        localTime: new Date().toLocaleTimeString()
    });

    You can see that any property inside the controller is accessible inside that controller’s template. We define the 1ocalTime property and it gets carried into our template context.

    Now our clock app will show the current local time when we navigate to http://localhost:9000/#clock. Of course, it just shows the time it was when the controller was initialized; there is no live updating of the time. We should update the time every second inside the controller:

    WorldClock.ClockController = Ember.ObjectController.extend({
        init: function() {
            // Update the time.
            this.updateTime();
     
        // Run other controller setup.
            this._super();
        },
     
        updateTime: function() {
            var _this = this;
     
            // Update the time every second.
            Ember.run.later(function() {
                _this.set('localTime', new Date().toLocaleTimeString());
                _this.updateTime();
            }, 1000);
        },
     
        localTime: new Date().toLocaleTimeString()
    });

    Now we can go to our clock URL and see our clock automatically updates every second. This is thanks to Ember’s data-binding between controllers and templates; if we change a value in a controller, model, or view that’s wired up to a template, the template will automatically change that data for us.

    Adding Timezones

    Next, we want to add a few timezones that the user can add to their own collection of timezones to compare against local time. This will help them schedule their meetings with friends in San Francisco, Buenos Aires, and London.

    We can create a timezone model (and accompanying controllers/routes/templates) with the same generate command, but this time we’ll generate a model:

    recroom generate model Timezone

    We want each timezone we’re to include in our app to have a name and an offset value, so we should add them as model attributes. We use Ember Data for this, inside app/scripts/models/timezone_model.js:

    WorldClock.Timezone = DS.Model.extend({
        name: DS.attr('string'),
        offset: DS.attr('number')
    });

    Next we’ll want a list of all timezones to offer the user. For this we’ll grab a copy of Moment Timezone. It’s an awesome JavaScript library for dealing with dates and times in JavaScript. We’ll install it with bower:

    bower install moment-timezone --save

    And then add it to our app inside app/index.html:

    <!-- build:js(app) scripts/components.js -->
    <!-- [Other script tags] -->
    <script src="bower_components/moment/moment.js"></script>
    <script src="bower_components/moment-timezone/builds/moment-timezone-with-data-2010-2020.js"></script>
    <!-- endbuild -->

    Adding that tag will automatically add moment-timezone-with-data-2010-2020.js to our built app. We’ll add a tab to the page that lets us edit our timezones, on a different screen than the clocks. To add a tab, we just need to open app/templates/application.hbs and add a tab. While we’re there, we’ll change the main tab from the useless {{#linkTo 'index'}} and point it to {{#linkTo 'clock'}}. The new application.hbs should look like this:

    <x-layout>
      <header>
        <x-appbar>
          <h1>{{t app.title}}</h1>
        </x-appbar>
      </header>
      <section>
        {{outlet}}
      </section>
      <footer>
        <x-tabbar>
          <x-tabbar-tab>
            {{#link-to 'clock'}}Clock{{/link-to}}
          </x-tabbar-tab>
          <x-tabbar-tab>
            {{#link-to 'timezones'}}Timezones{{/link-to}}
          </x-tabbar-tab>
        </x-tabbar>
      </footer>
    </x-layout>

    Side note: notice the root URL points to a useless welcome page? We probably want the default route to be our ClockController, so we can set the index route to redirect to it. Let’s do that now, in app/scripts/routes/application_route.js:

    WorldClock.ApplicationRoute = Ember.Route.extend({
        redirect: function() {
            this.transitionTo('clock');
        }
    });

    Interacting with Timezone models

    We’ll keep things simple for our example and allow users to select a timezone from a <select> tag and add it with a button. It will show up in their list of timezones, and they can delete it if they want from there. The clock tab will show all times. First, we’ll add our timezone data from Moment.js into our TimezonesController in app/scripts/controllers/timezones_controller.js. We’re also going to implement two actions: “add” and “remove”. These will be used in our template:

    WorldClock.TimezonesController = Ember.ObjectController.extend({
        init: function() {
            var timezones = [];
     
            for (var i in moment.tz._zones) {
              timezones.push({
                  name: moment.tz._zones[i].name,
                  offset: moment.tz._zones[i].offset[0]
              });
          }
     
          this.set('timezones', timezones);
     
          this._super();
      },
     
      selectedTimezone: null,
     
      actions: {
          add: function() {
              var timezone = this.store.createRecord('timezone', {
                  name: this.get('selectedTimezone').name,
                  offset: this.get('selectedTimezone').offset
              });
     
              timezone.save();
          },
     
          remove: function(timezone) {
              timezone.destroyRecord();
          }
      }
    });

    So we create a list of all available timezones with offsets. Then we add methods that allow us to add or remove timezones from our offline data store. Next we modify the timezones template in app/templates/timezones.hbs to use the actions and variables we created. All we need to utilize these variables is the Ember SelectView and the {{action}} helper to call our add and remove methods:

    <h2>Add Timezone</h2>
     
    <p>{{view Ember.Select content=timezones selection=selectedTimezone
           optionValuePath='content.offset' optionLabelPath='content.name'}}</p>
     
    <p><button {{action add}}>Add Timezone</button></p>
     
    <h2>My Timezones</h2>
     
    <ul>
      {{#each model}}
        <li>{{name}} <button {{action remove this}}>Delete</button></li>
      {{/each}}
    </ul>

    Now we have a Timezones tab that allows us to add and remove Timezones we want to track. This data persists between app refreshes. The last thing we need to do is show these times relative to our local time in our clock tab. To do this we need to load all the Timezone models in the ClockRoute. They’re automatically loaded in the TimezonesRoute, but it’s easy to add them in the ClockRoute (in app/scripts/routes/clock_route.js):

    WorldClock.ClockRoute = Ember.Route.extend({
        model: function() {
            return this.get('store').find('timezone');
        }
    });

    Because of the way our Ember app is wired up, we load all our models in the route and they are sent to the controller once the data store has asynchonously loaded all of the models. The request to find('timezone') actually returns a Promise object, but Ember’s router handles the Promise resolving for us automatically so we don’t have to manage callbacks or Promises ourselves.

    Now we have access to all the user’s Timezones in the ClockController, so we can make times in each timezone the user has requested and show them in a list. First we’ll add each Timezone’s current time to our ClockController in app/scripts/controllers/clock_controller.js using Moment.js:

    WorldClock.ClockController = Ember.ObjectController.extend({
        updateTime: function() {
            var _this = this;
     
            // Update the time every second.
            Ember.run.later(function() {
                _this.set('localTime', moment().format('h:mm:ss a'));
     
                _this.get('model').forEach(function(model) {
                    model.set('time',
                              moment().tz(model.get('name')).format('h:mm:ss a'));
                });
     
                _this.updateTime();
            }, 1000);
        }.on('init'),
     
        localTime: moment().format('h:mm:ss a')
    });

    Our final app/templates/clock.hbs should look like this:

    <h2>Local Time: {{localTime}}</h2>
     
    <p>
      {{#each model}}
        <h3>{{name}}: {{time}}</h3>
      {{/each}}
    </p>

    And that’s it! Now we have an offline app that shows us time zones in various places, saves the data offline, and updates every second without us having to do much work!

    Command Line Tools

    The old Podcasts app used a (rather awful) Makefile. It wasn’t very useful, and I don’t think it ran on Windows without some serious effort. The new build system uses Node so it runs comfortably on Windows, Mac, and Linux. Commands are proxied via the recroom binary, also written in Node, so you don’t have to worry about the underlying system if you don’t need to modify build steps. recroom new my-app creates a new app; recroom serve serves up your new app, and recroom generate model Podcast creates a new model for you.

    To build your app, you just need to run recroom build and a version with minified CSS, JS, and even HTML will be created for you in the dist/ folder. This version is ready to be packaged into a packaged app or uploaded to a server as a hosted app. You can even run recroom deploy to deploy directory to your git repository’s GitHub pages branch, if applicable.

    See the app in action!

    This entire sample app is available at worldclock.tofumatt.com and the source code is available on GitHub.

    Try Using Rec Room for Your Next Web App

    You can try out Rec Room on Github. Right now some docs and tools are still being abstracted and built, but you can start building apps today using it and filing bugs for missing features. We’d really love it if you could give it a try and let us know what’s missing. Together we can build a cohesive and polished solution to the all-too-common question: “How do I build a web app?”

  9. Turn your Facebook page into a Firefox OS mobile app

    Whether you are a business or community page owner, what would be better than increasing your page reachability by offering your standalone mobile app?

    Apptuter is an open source framework to help you achieve that, with minimum coding knowledge and easy to follow steps you would be able to produce your own app. The framework currently supports Facebook pages as a content source and is capable of producing apps for Firefox OS and Android platforms.

    How it works

    Let us take a test drive on how this is supposed to work. In our example we will generate a standalone app using Mozilla’s Facebook page as a content source.

    Clone the repository

    First step would be to download or clone the Apptuter-Firefox directory from the Apptuter repository:

    git clone https://github.com/egirna/apptuter.git
    

    Directory structure should look like this:

    Get the Facebook numerical id

    Then we will need to get the Facebook numerical page id. If you have assigned a friendly page name, the page ID will not be visible from the page URL, in this case we will need to visit the following URL to retrieve it: https://graph.facebook.com/mypagename

    In our example this would be: https://graph.facebook.com/mozilla

    Page ID will be visible on the first line of data returned.

    Create a Facebook app

    Next step would be creating a Facebook app: You will able to get App ACCESS TOKEN by combining APP ID & APP SECRET so that the requested URL should be in the following form: http://graph.facebook.com/endpoint?key=value&access_token=app_id|app_secret

    Requesting Page Info (Info.js) is where we are going to define those parameters, replace PageID with the numerical that can be found at /Apptuter-Firefox/js

    var Main = function () {
        this.pageName = ‘pageID’;
        this.name = null;
        this.category = null;
        this.description = null;
        this.photoArray = null;
        this.postArray = null;
        this.infoArray = [];
        this.accessToken = 'AppID|AppSecret';
        this.pictureUrl = null;
        this.paging = 'https://graph.facebook.com/' + this.pageName + '/posts?limit=20&amp;access_token='+this.accessToken;
        this.pagingNext = 'https://graph.facebook.com/' + this.pageName + '/posts?limit=20&amp;access_token='+this.accessToken;
    }

    Let us define our new app properties in the manifest.webapp file found at the directory root:

    {
      "name": "Mozilla App",
      "description": "This is an example app of apptuter framework",
      "launch_path": "/Shared/index.html",
      "icons": {
        "32": "/images/app_icon_32.png",
        "60": "/images/app_icon_60.png",
        "90": "/images/app_icon_90.png",
        "120": "/images/app_icon_120.png",
        "128": "/images/app_icon_128.png",
        "256": "/images/app_icon_256.png"
      },
      "chrome": {
        "navigation": true
      },
      "version": "1.0.1",
      "developer": {
        "name": "Egirna Technologies Limited",
        "url": "http://www.apptuter.org"
      },
      "orientation": [
        "portrait"
      ],
      "default_locale": "en"
    }

    Artwork

    Only thing left is the artwork. From the repository, go to /Apptuter-Firefox/images and replace the default images with those of our example logo with matching dimensions and file name.

    Success!

    And we are done! Let us test what the app would look like using Firefox OS Simulator:

    You ultimately are responsible to use this software in compliance with Facebook, Google and Mozilla terms of service and end user license agreement. This applies to any service this software may integrate with.

  10. Building applications for Firefox OS using AngularJS

    When you start developing for Firefox OS you might be underwhelmed by the tools that are provided. There is no standard UI toolkit, or a JavaScript framework that all apps build on. This is not a situation that’s inherently bad because in essence Firefox OS is the web; and thus gives you complete freedom in the toolchain you use. This gives us the advantage to use any new technology that pops up also on Firefox OS. The downside is that you’ll miss out on things you might be used to on Android or iOS, like built-in templates; view transitions and UI components.

    In Telenor Digital we decided to build a ready-to-go application framework that deals with these shortcomings, built on top of AngularJS, the MVW framework by Google. The template is the result of iterating over our internal applications that we built for Firefox OS, and addresses the following things:

    1. Built on top of AngularJS, that has provides data binding; templating; routes; and code structure
    2. Built in set of UI components
      and transitions, in the style of Firefox OS
    3. Ability to publish apps as a mobile web page (hosted app),
      or as a packaged app for the Firefox OS marketplace
    4. Offline first approach. Every app built on top of the template works offline,
      also when hosted on your own web server.
    5. A build system to create release builds with one command,
      that does minification and template caching for optimal performance

    Let’s look at how the demo application looks like. It’s a standard CRUD app that shows a list-detail pattern: http://janjongboom.com/ffos-list-detail/. You can click on items to go to the detail view, you can edit items, or add new items. The ‘+’ button is an install button (only visible in Firefox) and allows you to add the app to your phone (Android / FxOS).

    Getting the code

    To start building, do this:

    • git clone git@github.com:comoyo/ffos-list-detail.git
    • npm install
    • ./node_modules/bower/bin/bower install
    • Now you can open www/index.html in any browser, or use the app manager and add the
      www folder as a packaged app.

    Structure

    The application lives in the www/ folder, and is made up of the following subfolders:

    • components/, third party libraries, loaded through bower
    • css/, style sheets. List all styles used by your app in
      css/main.css.
      They will be combined into one big stylesheet, for optimal performance.
    • img/, holds the icons for the app in three formats.
    • js/, our code
      • controllers/, the code that binds data to our UI
      • lib/, external libraries that are not in bower
      • services/, data providers, or code that is not bound to UI
      • app.js, starting point of the application, contains global configuration like routes
      • main.js, bootstrap file based on RequireJS.
        Lists all the JavaScript files we use. When you create a new JS file, add it here.
    • views/, view templates
    • index.html, bootstrap file where we load the application. You probably never will touch this.
    • manifest.appcache, AppCache file.
      You’ll need to list all the images & other resources (other than CSS/JS) that your app needs here,
      to enable offline for hosted applications.
    • manifest.webapp, Firefox OS App manifest file.

    You don’t need any build chain set up during development, you can just edit files in www, and refresh index.html at will. That’s the power of the web :-) Of course if you’re developing in the app manager, press UPDATE to refresh the app.

    Now let’s add some new functionality to this application, so we can see how developing new features works in practice.

    Adding a new button

    Let’s say that we want to add a credits screen that shows who built the application. First thing we need to do is add a button somewhere. In our case let’s put it on the home screen of the app. The code of the view is in www/views/list.html

    The components that you see come from the Firefox OS Building Blocks, which are the same blocks that are used to build Firefox OS itself. Let’s add a new button at the bottom of the screen (below the </ul> and the </section>:

    <a class="recommend" role="button" ng-tap="go('/credits', 'popup')">Credits</a>

    Important here is the ng-tap attribute. When we tap this item we go to /credits URL, with animation popup. There are four built in animations: forward, backward, popup and popdown; but you can create your own using simple CSS.

    Now when we look at this it doesn’t look like a button yet, because we didn’t tell that we needed the button building block. Go to css/main.css and add the following line to make it look nice:

    @import url("../components/building-blocks/style/buttons.css");

    All this is always documented on the page on the Building Blocks website.

    Hooking it up

    When we click on the button nothing happens though (well, we get redirected back to the list view), and that’s because we don’t listen on the /credits URL yet. To fix that we need to create a route handler (like in any MV* server side framework as well). Open the list of routes in js/app.js, and add a handler for the credits URL (before the otherwise handler):

    .when('/credits', {
      templateUrl: 'views/credits.html',
      controller: 'CreditsCtrl'
    })

    Here we tell which controller we want to consult (with JS code), and which view (with HTML) belongs to that. Let’s create the view first. Add a new file called credits.html in the views folder.

    <section role="region">
      <!-- Header building block http://buildingfirefoxos.com/building-blocks/headers.html -->
      <header>
        <!-- here we handle the back click and we do a popdown animation -->
        <a ng-tap="go('/', 'popdown')"><span class="icon icon-back">back</span></a>
        <h1>Credits</h1>
      </header>
    </section>
    <!-- The content of the view should have a 'view' class, and add the name of
         the view to easily style the view later -->
    <section class="view credits">
      This application is made by {{ name }}. <!-- AngularJS does data binding for us -->
    </section>

    To style this view we can add some content in css/app.css, f.e. add some padding and make the text bigger:

    .view.credits {
      padding: 1.5rem;
      font-size: 2rem;
    }

    Now write a simple controller to fill the content of {{ name }}, using standard AngularJS data binding. Add a new file called credits.js in www/js/controllers:

    /* We use RequireJS AMD style modules to get a reference to the app object */
    define(['app'], function(app) {
      /* Tell that we're defining a controller with name
        CreditsCtrl, and with dependencies on $scope, we specify this as string
        to not break when minifying
      */
      app.controller('CreditsCtrl', ['$scope',
        /* Implementation. AngularJS does dependency injection to fill the $scope var */
        function CreditsCtrl($scope) {
          /* Data binding to the view */
          $scope.name = 'Your name';
        }
      ]);
    });

    Last thing is to tell RequireJS that we have a new JS file that needs to be included in our builds, by editing js/main.js and adding a line above 'js/controllers/edit.js':

    'js/controllers/credits.js',

    When we now click the button in the app, everything works as expected. The view pops in, we have data, and we can dismiss by clicking the back button. What’s also great is that when you send the URL to someone else (f.e. http://your/url/index.html#/credits) they will go to the same view by default. That’s because we do proper state management through URLs by default.

    Talking to a third party data source

    The app currently only talks static data, so we want to hook it up to a real data source. In our case the project list should come from GitHub’s page with projects by mozilla-b2g. They have an API at: https://api.github.com/users/mozilla-b2g/repos.

    AngularJS has an idea of services, that abstract data away from your controller. For this app we have a database service that currently returns in-mem data. We can modify the service to talk to a web service instead. Clear out www/js/services/database.js and replace the content with:

    /*global define */
    "use strict";
    define(['app'], function(app) {
      /* Add a new factory called database, with a dependency on http */
      app.factory('database', ['http', function(http) {
        var getItems = function() {
          /* getItems makes a HTTP get call to github */
          return http.get('https://api.github.com/users/mozilla-b2g/repos', {
            // this is the cache configuration, we want to always cache requests
            // because it gives better UX. Plus when there is no internet, we can
            // get the data from cache and not break for the user...
            idbCache: {
              cacheKey: 'api.index',
              // expiration time in ms. from now (this is 5 minutes)
              // This is only obeyed if there is an internet connection!
              expiresInMs: 5 * 60 * 1000
            }
          }).then(function(res) {
            // Format it, sort it and map it to have the same format as our previous in mem dataset
            return res.data.sort(function(a, b) {
              return a.stargazers_count < b.stargazers_count;
            }).map(function(item) {
              return {
                title: item.name,
                description: item.description,
                id: item.name
              };
            });
          });
        };
     
        // Similar story but now for just one item
        var getItemById = function(id) {
          return http.get('https://api.github.com/repos/mozilla-b2g/device-flatfish', {
            idbCache: {
              cacheKey: 'api.detail.' + id,
              expiresInMs: 10 * 60 * 1000
            }
          }).then(function(res) {
            var repo = res.data;
            return {
              title: repo.name,
              description: repo.description,
              id: repo.name,
              date: new Date((repo.pushed_at || "").replace(/-/g,"/").replace(/[TZ]/g," "))
            };
          });
        };
     
        return {
          getItems: getItems,
          getItemById: getItemById
        };
      }]);
    });

    This API is now asynchronous though, but that doesn’t matter for Angular. If you data-bind to a promise, Angular will wait until the promise resolves until data binding happens.

    The beauty here is now that even when there is no Internet connection, the data will still load (as long as it was loaded at least once), and the data is auto-cached. No need for the controller to worry about that.

    Publishing the app

    These were two ways we quickly added some functionality to this application. First, adding a new button and a new view; and second, showing data binding and offline caching of server data. Please note that this application template can be used for much more than just list->detail applications, you’ve got the whole power of AngularJS at your hands!

    Now when we want to share this application with the rest of the world, we can go two ways:

    • Create a hosted application. This is an app that lives on your own server, like any mobile website. Hosted apps can still be published on the marketplace, and will work offline, but cannot use all the APIs in Firefox OS due to security limitations.
    • Create a packaged application. This is a ZIP file, similar to APK files on Android, that contain all the assets of your app, and are distributed through the marketplace.

    Both of these applications can be generated using our build script. The script will create a new folder dist/ that lists all the files the app needs. If you want to publish the app to your own server, just copy over the contents of the folder. If you want to publish the app as a packaged app, ZIP up the content and publish to the marketplace.

    To build, run:

    • Packaged: node build.js
    • Hosted: node build.js appcache

    Happy coding!