Académique Documents
Professionnel Documents
Culture Documents
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and many iterations to get reader feedback, pivot until you have the right book and build traction once you do. 2013 by Michael Romer, Grevingstrasse 35, 48151 Mnster, Germany, mail@michael-romer.de All rights reserved.
Contents
1 Introduction (available) . . 1.1 Firefox OS at a glance . 1.2 Open Web Apps . . . . 1.3 Web Runtime . . . . . 1.4 Firefox Marketplace . . 1.5 WebAPIs . . . . . . . . 1.6 Web Activities . . . . . 1.7 Firefox OS Boilerplate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 2 2 3 3 3 3 4 4 4 4 5 6 6 8 10 11 11 12 14 14 16 16 20 25 25 25 31
2 A basic development environment (available) . . . . . . . . . 2.1 The browser now is the mobile apps developers best friend 2.2 Firefox OS Simulator . . . . . . . . . . . . . . . . . . . . . 2.3 Firefox OS hardware devices . . . . . . . . . . . . . . . . . 2.4 Mortar & FxOSstub . . . . . . . . . . . . . . . . . . . . . . 3 Hello, Firefox OS! (available) . . . . . . . . . . . 3.1 Building the first app . . . . . . . . . . . . . 3.2 Firefox OS architecture: Gonk, Gecko & Gaia 3.3 Security . . . . . . . . . . . . . . . . . . . . 4 The Manifest file (available) . . . . 4.1 Meta information about an app . 4.2 App settings . . . . . . . . . . . 4.3 Developer settings . . . . . . . . 4.4 Permission settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5 WebAPIs by example (partly available) . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1 The Grumpy Phone app (using Vibration API & Proximity API) . . . . . . . . . . . . 5.2 More Web APIs (TODO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Web Activities by example (partly available) 6.1 Introduction . . . . . . . . . . . . . . . . 6.2 The Funny Faces app (Pick Activity) . . . 6.3 More Web Activities (TODO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CONTENTS
7 Programming the Firefox OS Web Runtime (partly available) 7.1 HTML & CSS (TODO) . . . . . . . . . . . . . . . . . . . . 7.2 JavaScript (partly available) . . . . . . . . . . . . . . . . . 7.3 Firefox UI Build Blocks & Transitions (partly available) . . 7.4 Single Page Apps (partly available) . . . . . . . . . . . . . . 7.5 HTML5 canvas (TODO) . . . . . . . . . . . . . . . . . . . 7.6 Working offline (TODO) . . . . . . . . . . . . . . . . . . . 7.7 jQuery Mobile UI framework (TODO) . . . . . . . . . . . . 7.8 WebGL (TODO) . . . . . . . . . . . . . . . . . . . . . . . . 8 Distributing apps (partly available) . . . . . 8.1 Introduction (TODO) . . . . . . . . . . . 8.2 Distributing via a website (TODO) . . . . 8.3 Submitting to a Marketplace (available) . 8.4 App updates on a Marketplace (available) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
32 32 32 34 35 36 36 36 36 37 37 37 37 38 39
1 Introduction (available)
We live in crazy times. Not long ago everybody moved to the Web mainly for its killer feature to easily access applications-no downloads, no installs, no updates, no hassle. People more and more moved away from native Windows or Mac applications and into the browser using apps running online directly in the browser. They did so on their PCs and laptops, but then Apple came with its iPhone and later the iPad. Surprisingly, with the iPhone and iPad, locally installed apps had a very successful comeback. Its hard to tell why exactly this happened, but there are definitely good reasons, e.g.: Apple opened up its App Store with a payment system built-in. In fact, the Web still lacks of a standard solution to make it as easy as in an app store to pay for media or applications. In fact, with a typicall app store, it couldnt be much easier anymore to buy digital products. This is the main reason for publishers and developers to hop onto the native apps wave-they can easily monetize their digital products. New apps can be discovered easily using the App Store. Its easy to launch an app (via a home screen icon) and to switch between running apps. Native apps mostly offer great usability and feel snappy. They are built from the ground up for the touch interfaces of smartphones and tablets. Apps can do things which web apps cannot. Mainly because web apps running in a browser are not allowed or simply technically cannot access important device features such as camera, proximity sensor and the like. Push notifications offer a great way to receive messages from the web in a convenient short message (SMS) fashion. Native apps mainly always still work well while being offline. And lastly: Apps are en-vogue. However, in fact, there is no reason why an app needs to be built with proprietary technology. With Firefox OS, Mozilla now brings open web technologies to mobile app development, challenging proprietary platforms from Apple (iOS) or Google (Android). Firefox OS essentially is completely based on open standards and is a new competitor to the established mobile platforms. If one believes in the web, Firefox OS is an interesting new mobile platform which huge potential.
Introduction (available)
JavaScript. Mozilla, the creator of the famous Firefox browser-and now also of Firefox OS-calls these kinds of apps Open Web Apps. This is a fundamentally different approach compared to Apple with iOS and Objectiv-C or Google with Android and Java.
Introduction (available)
web services, however, this is not required. A packaged app works standalone by default, therefore often does not need constant Internet connectivity. As packaged apps can be reviewed for security issues beforehand, they may access more APIs compared to hosted apps. This makes packaged apps particular interesting. As with hosted apps, there is a flip side. Packaged app updates must be distributed to all devices with the app installed. This, obviously, is harder than updating a website. Technically, a packaged app simply is a zip file with some additional metadata. This means, a packaged app is installed completely on the device with its code and assets as well the Manifest file.
1.5 WebAPIs
WebAPIs mainly allow for a closer hardware integration. They let open web apps access device features, very much like Apple exposes certain feature through their native APIs. WebAPIs are consumed by web technology, e.g. by JavaScript. WebAPIs connect the web with the mobile device hardware features.
Firefox OS Simulator: A great way to run apps in a more target-like environment with access to many device features such as Web APIs, however, not to all of them. Firefox OS hardware device: The most native way to run an app with access to all of the devices features, but with somewhat limited debugging possibilities. However, there indeed is a forth option: A desktop build of Firefox OS (also known as B2G) which we will take a look at later in the process.
You will need to have git installed on your system before you can run this command. Open the cloned folder in your favorite IDE and change index.html to:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <title></title> <link rel="stylesheet" href="https://d10ajoocuyu32n.cloudfront.net/mobile/1.3.1/\ jquery.mobile-1.3.1.min.css"> <script src="https://d10ajoocuyu32n.cloudfront.net/jquery-1.9.1.min.js"></script> <script src="https://d10ajoocuyu32n.cloudfront.net/mobile/1.3.1/jquery.mobile-1.\ 3.1.min.js"></script> </head> <body> <div data-role="page" id="page1"> <div data-theme="a" data-role="header"> <h3> Twitter Client </h3> </div> <div data-role="content">
https://github.com/mozilla/mortar-app-stub http://git-scm.com/
<ul data-role="listview" class="ui-listview" id="tweetlist"> </ul> </div> <div data-theme="a" data-role="footer" data-position="fixed"> <span class="ui-title"> </span> </div> </div> <script type="text/javascript" src="js/app.js"></script> </body> </html>
$.getJSON("http://search.twitter.com/search.json?q=Michael+Jackson&callback=?", f\ unction(data) { $(data.results).each(function(i,v) { var tweet='<li class="ui-li ui-li-static ui-btn-up-c">' + this.text + '</li>\ '; $('#tweetlist').append(tweet); }) });
Last but not least, lets add a custom icon to our app. A Firefox OS application icon may be given in different dimensions for different use cases. For the sake of simplicity, we add a 64px icon only. We download the file and add it to img/icons with the filename twitter-64.png. Add the following to manifest.webapp while replacing the existing file content:
1 2 3 4 5 6 7 8 9 10
{ "version": "0.1", "name": "Twitter Demo Client", "description": "Twitter Demo Client from Firefox OS book", "launch_path": "/index.html", "icons": { "64": "/img/icons/twitter-64.png" }, "developer": { "name": "Michael Romer",
https://assets.mozillalabs.com/Projects/Firefox%20OS/UX/VsD/v01.0/Icon%20App%20Templates/PNG/MozillaFXOSIconTemplate1.png
Now, head over to the Firefox browser and its Firefox OS Simulator add-on. Make sure the simulator is running-there is a toggle switch on the side-and then pick the app directory from your local disk. Then click run and see the result (also notice the icon added to the home screen):
Et voil-we just developed our first Firefox OS app. Sure, the world hasnt been waiting for this app and its benefits are limited, but it still is a fully function mobile app built in minutes and with only standard web technologies involved.
does all the bootstrapping and finally runs Gecko. Gecko essentially is the runtime environment for apps built with web technology. So its no surprise that Gecko is also already used by Firefox, Thunderbird as well as other browsers like Camino or Flock. Gecko paints graphics onto the screen, runs JavaScript, does networking, etc. In short, Gecko runs the apps. During the early alphas of Firefox OS, the system was therefore known as B2G or Boot to Gecko-because the system simply boots to Gecko. And then there is the beautiful Gaia:
Gaia is the main user interface. And, believe it or not, Gaia itself is a web app. So, whenever one interacts with its phone, one interacts with HTML5 web apps already. If one is interested in learning more about the technical details of Gaia-the full source code is available to the world on github. Lets get back to Gecko for a moment. Together with Gecko, a whole bunch of WebAPIs-some of them already standardized and known as a part of HTML5-provide access to device features. Gecko and the WebAPIs together form the so-called Open Web Platform that sits on top of Gonk, the low-level infrastructure layer. Custom Firefox OS apps, as well as the main device UI itself, Gaia, utilize the Open Web Platform to function.
https://github.com/mozilla-b2g/gaia
10
3.3 Security
Clearly, nobody wants to have an insecure mobile device in his or her pocket. As Firefox OS connects a web app with the underlying hardware, there is the risk of malicious applications. Just image that any web app out in the wild may access random data on ones mobile device. Therefore, Firefox OS employs a multi-layered security model. In fact, all functions of a device that a web app such as Gaia or any custom app wants to use, are made available by Gecko exclusively. There is no other way to request access to device functions. So Gecko with its WebAPIs acts as the one and only gatekeeper and enforces security policies. For instance, there is no direct access to any files on the filesystem without going through Gecko and a WebAPI. Not all apps can access all the WebAPIs available. In fact, Firefox OS knowns different trust levels: Certified: Highly trusted system apps that have been approved by the Operator or OEM of the device. Certified apps have permissions to most Web APIs. Privileged: Web apps that have been reviewed, approved, and digitally signed by an authorized Marketplace. As already said, Mozilla doesnt claim to be the one and only marketplace for Firefox OS applications. Privileged apps have access to less APIs than certified apps. Web: Non-privileged hosted or packaged apps again have less APIs available than privileged apps. Mainly, all apps of type web are considered as untrusted web content. As we will see in the next chapter, an app must explicitly require API access via the apps Manifest. If the requested permission is granted by gatekeeper Gecko mainly depends on the apps trust level. An app may become privileged by submitting it for consideration to an authorized Marketplace. In fact, a hosted app never can become privileged or certified. So if one needs access to certain APIs, packaging the app might be required at some point. On runtime, each app is fully separated from other apps that may run at the same time (sandboxing). Technically speaking, each app runs in its own process.
{ "version": "0.1", "name": "Twitter Demo Client", "description": "Twitter Demo Client from Firefox OS book", "launch_path": "/index.html", "icons": { "64": "/img/icons/twitter-64.png" }, "developer": { "name": "Michael Romer", "url": "https://leanpub.com/firefox-os" }, "installs_allowed_from": ["*"] }
Mozilla offers an online manifest schema validator which is very helpful. Also the Firefox OS Simulator for the Firefox Browser does validate the manifest and points the developer to issues. When serving the manifest.webapp file from a webserver one needs to make sure that the file is served with a Content-Type header of application/x-web-app-manifest+json, e.g. by adding the following to the Apache web server configuration:
1
However, this is important only for hosted apps, but not for packaged apps.
https://marketplace.firefox.com/developers/validator
12
For Firefox OS icons should be provided without a drop shadow in the following sizes: 30 x 30 60 x 60 A 128 x 128 icon is required when submitting to Firefox Marketplace. By using type the developer may specify the app type. The value defaults to web, other possible values are privileged and certified. Via orientation one can lock the orientation, even if the device orientation changes. That might be helpful in cases where an app is made for either working in portrait or landscape orientation. Using the values portrait-primary, landscape-primary, portrait-secondary or landscape-secondary provide even more fine-grained settings. One can set fullscreen to true or false to indicate whether the runtime should launch the app in full-screen mode. It defaults to false. When set to true, the status bar is made invisible as well. With the help of locales one may override values from the manifest with localized values:
13
"locales": { "es": { "description": "Accin abierta emocionante del desarrollo del Web!", "developer": { "url": "http://es.mozillalabs.com/" } }, "it": { "description": "Azione aperta emozionante di sviluppo di fotoricettore!", "developer": { "url": "http://it.mozillalabs.com/" } } }
One may override any values from the manifest except default_locale, locales and installs_allowed_from. The idea behind overrides is to provide localized manifest content (e.g. description, icons, etc.) to international users. There is no direct relation between locales given in the manifest and localizations of the app itself. However, its good practice to only include locales in the manifest for which also localizations of the app itself exist. If locales is present, default_locale needs to be present as well indicating the locale which serves as the default. The directive appcache_path may point to the app cache manifest that supports offline operation:
1
"appcache_path": "/cache.manifest"
A later chapter in this book is dedicated to apps working offline. With the directive activities one may specify the Web Activities that the app supports and provides to other apps:
1 2 3 4 5 6 7 8 9 10
"activities": { "share": { "filters": { "type": [ "image/png", "image/gif" ] }, "href": "foo.html", "disposition": "window", "returnValue": true } }
14
In the snippet above, share is the activities identifier. There are certain default identifiers defined by Gaia. In addition, a web app can define its very own activities by simply using a custom identifier. The href is opened if the app is chosen to perform an activity. The key disposition is optional and can take the values window and inline. While window opens the app in a new window, inline uses a layer over the calling app to display the supporting app. The key returnValue shows if the activity will return a value or not. Via filters the apps are determined that are suitable for handling a given activity. Like the activity identifiers, the keys are free-form text and can be named as desired. All filters must be satisfied by an application to qualify as being able to handle the activity requested. We will take a closer look at the exact mechanics of Web Activities later in the book.
"permissions": { "contacts": { "description": "Required for autocompletion in the share screen", "access": "readcreate" }
} In this example, the Contacts API is used to read data from the devices contact list as well as for creating new records. A description that reflects the intent is required for each permission in the list. However, there are WebAPIs that are available by default. In this case, one can omit the permissions request. With the installs_allowed_from directive a developer can limit the app installations to certain origins. If one wants to distribute only via Firefox Marketplace the following statement will work (no trailing slash at the end of the URL!):
https://developer.mozilla.org/en-US/docs/WebAPI/Web_Activities#Firefox_OS_activities
15
"installs_allowed_from":["https://marketplace.firefox.com"]
The wildcard (star-symbol) means any origin is fine, will no content in the brackets means no origin will work. With the csp directive, one can specify a Content Security Policy for the app that can be understood as a specialization of the Same Origin Policy that is used by default. // todo
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript
5.1 The Grumpy Phone app (using Vibration API & Proximity API)
Code download
The code of this demo application is available for download at GitHub.
Today, our Firefox OS device has a bad day. It dislikes to be touched by a human. If no human is close, it shines in a pretty blue color:
http://www.w3.org/2012/sysapps/ https://github.com/michael-romer/firefox-os-book-the-grumpy-phone
17
But if one comes too close, it turns to orange and starts vibrating!
18
In hardware devices, the proximity sensor usually is located above the screen. If one takes his hand and slowly moves from far to close to the sensor, the display turns to orange and the phone vibrates. Move back again and vibration stops, the screen turns back to blue again. All that is needed to build this magic is some lines of straight forward JavaScript code and HTML markup:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <title>The Grumpy Phone</title> <script src="https://d10ajoocuyu32n.cloudfront.net/jquery-1.9.1.min.js"></scrip\ t> <style> html { height: 100%; background-image: -moz-linear-gradient(top,#43BFC7,#008080); background-repeat: repeat-x; }
19
<script type="text/javascript"> window.ondeviceproximity = function (event) { if (event.value < 5) { vibrating = navigator.vibrate(2000); $('html').css('background-image', '-moz-linear-gradient(to '); } else {
{ "version": "1.0", "name": "The Grumpy Phone", "description": "The Grumpy Phone - A demo app taken from https://leanpub.com/fir\ efox-os", "launch_path": "/index.html", "icons": { "64": "/img/icons/grumpy-64.png" }, "developer": { "name": "Michael Romer", "url": "https://leanpub.com/firefox-os" }, "installs_allowed_from": ["*"] }
As the proximity feature is not available on the Firefox OS Simulator, the app is only really fun on a hardware device. How to use the Vibrate API and the Proximity API is nearly self-explanatory: We register a callback function for ondeviceproximity which is constantly called automatically. Via event.value we retrieve the distance in centimeter and vibrate for two seconds as well as paint the screen orange if it is below five centimeters. Thats it!
20
21
22
23
24
Now its time to put a red nose on! The Funny Faces app works like this: First, a face close-up photo is taken:
http://webintents.org/ https://github.com/michael-romer/firefox-os-book-funny-faces
26
This is done either via the phones built-in camera (doesnt work on the Firefox OS Simulator) or taken from the phones image gallery:
27
28
Once the picture is taken, a red nose can be put on by hitting the nose!
29
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <title>Funny Faces</title> <link rel="stylesheet" href="/css/jquery.mobile-1.3.1.min.css"> <script src="/js/jquery-1.9.1.min.js"></script> <script src="/js/jquery.mobile-1.3.1.min.js"></script> <style> #content { margin: 0; padding: 0;
30
} #myCanvas { margin: 0; padding: 0; } </style> </head> <body> <div data-theme="a" data-role="header"> <h3>Funny Faces</h3> </div> <div id="content" data-role="content"> <canvas id="myCanvas"></canvas> </div> <div data-theme="a" data-role="footer" data-position="fixed"> <a href="#" onClick="window.location.reload()" data-role="button">Restart</a> </div> <script type="text/javascript"> var c = document.querySelector('#myCanvas'); c.height = 960; c.width = 540; var cx = c.getContext('2d'); c.addEventListener("touchstart", handleStart, false); alert("Take a face close-up photo!"); var pick = new MozActivity({ name: "pick", data: { type: ["image/png", "image/jpg", "image/jpeg"] } }); pick.onsuccess = function () { var img = new Image(); img.onload = function() { cx.drawImage(img, 0, 0, 540, 540 * img.height / img.width); } img.src = window.URL.createObjectURL(this.result.blob); alert("Now tip the nose!"); }; pick.onerror = function () {
31
alert("Image could not be loaded :-(");
}; function handleStart(evt) { evt.preventDefault(); var touches = evt.changedTouches; var touch = touches[0]; var radius = 70; cx.beginPath(); cx.arc(touch.pageX-2, touch.pageY-2, radius, 0, 2 * Math.PI, false); cx.fillStyle = 'red'; cx.fill(); cx.stroke(); } </script> </body> </html>
The main aspects are MozActivity and a HTML5 canvas element. To make our lives easier, we utilize jQuery and jQuery Mobile as well, however, its not really needed and doesnt matter that much here. It gets more interesting when MozActivity is created using name pick which is a Gaia default Activity. Via data, the file type required is given. Via MozActivity, the Firefox OS camera or gallery app is invoked and if all went well pick.onsuccess is invoked. It paints the photo taken onto the canvas 2D context. The function handleStart has been added as a listener for the touchstart event. It simply adds a filled circle (in red color) on top of the canvas once the screen is tapped. Thats all!
33
External JavaScript files may be embedded like this: Whatever way of adding JavaScript is used, whenever the browser encounters a script tag, it loads the code and interprets it before it resumes processing the HTML. This means that the order of loading scripts matters-if one script block defines a function another script block depends on, the latter must come second. And it also means that one will want to include scripts as late in the source code as possible.
7.2.3 Variables
A variable is easily defined: var a = 1; Theres no need to state a specific types. Simply put a var in front always (if the var is omitted, which is possible indeed, we create a global variable instead). As long as no value is assigned, the variable holds the value undefined. In addition, there are the primitive value types string, boolean (true and false), number (this includes float and int values!) and null available in JavaScript. One can find out a current value type using the type operator: var text = A text; typeof text; // returns the string (!) string In terms of variable naming, we cant use a number in the front, but letters, underscore or the dollar sign will work. Numbers work as well, simply not in the front. Arrays can be defined in two different ways. One may use the more verbose var arr = array(a, b, c, d); // todo
7.2.4 Functions
A function declaration in JavaScript is simple: function myFunction(arg1, arg2, arg3) { return arg1 + arg2 + arg3; } A function that doesnt return a value always returns undefined. Usually this isnt very much of interest, however, e.g. when working on an interactive JS shell such as the one provided by NodeJS or Rhino, the undefined sometimes is printed:
1 2 3
34
There are some more interesting things about function one should know. For instance, there is the fact that functions are objects (Function) with local variables and methods. A function object e.g. references an array-like arguments object corresponding to the arguments passed to a function. Then there also is no concept of default values of parameters. If one is experienced with other programming languages such as PHP, this might be surprising. If one wants to default a parameter value, this needs to be implemented by hand in a functions body. This especially is useful as there are no required parameters as well. A function can be called with less or more parameters than designed. If we define the following function:
1
35
which has nothing in common with other apps with the Firefox OS look & feel. Thats absolutely fine and it is not any different e.g. from the iOS platform. However, if one wants to build a Firefox OS app that seamlessly integrated with the overall look and feel of Firefox OS, the UI components catalog comes in handy. Not only its a visual guideline, but much more re-usable UI code, a UI components code library, if you will. The best way to get started with the UI library is to download the code as a zip file and cherry pick. But on the downloads page there is even more: A photoshop based icon set, design stencil kit as well the default font used called Feura Sans. To go native UI-wise is also a matter of the initial situation as well as the purpose of the app. If an exiting mobile website should be made available as an Open Web App to Firefox OS device, simply adding only the Manifest might be the way to go. In other cases, especially when designing an app from scratch, that targets Firefox OS devices, picking up the Building Blocks might be the way to go to speed up development and to build apps that look native. In addition to UI components, Building Firefox OS also provides support for transitions, UI animations based on CSS, that are used to open dialogs, in-app navigations and more. They are mainly useful when building so-called Single Page Apps.
36
7.5 HTML5 canvas (TODO) 7.6 Working offline (TODO) 7.7 jQuery Mobile UI framework (TODO) 7.8 WebGL (TODO)
38
Once all info is given, the app is in review state. On the Marketplaces Developers Hub page for submitted apps, one can also find information about the estimated waiting period for the app review by Firefox Marketplace. It is even stated how many other apps are on the waiting list. At the time of writing, a waiting period of 20 days or is reported. However, often, feedback on an app submission is sent much more earlier. One missing piece of the puzzle yet is the so-called Mini Manifest. It is created by the Firefox Marketplace on app submission automatically. The Mini Manifest of an app is stored on the phone when once app is installed. The Mini Manifest is updated regularly automatically, usually once a day. The Mini Manifest contains more meta data on the app, partly taken from the apps Manifest, partly added by the Firefox Marketplace.