Mozilla

Articles

Sort by:

View:

  1. Firefox OS Apps run on Android

    At Mozilla we believe that apps and browsing are best viewed as cooperative and symbiotic, each better when working together. We are working to strengthen that relationship by building an apps ecosystem that is built using the Web technologies that so many developers are already familiar with.

    We built Firefox OS as a mobile OS that puts the Web and Open Web Apps at the centre of the mobile experience. The efforts to reduce the performance gaps between the Web and native are paying rich dividends and our work on exposing device capabilities to the Web via WebAPIs, have made web first app development a viable alternative to native platforms.

    Build Open Web Apps, run out-of-the-box on Android

    Now, with Firefox for Android 29, Mozilla is extending this open Open Web Apps ecosystem to Android. Over the past few months, we have been working on providing a “native experience” for Open Web Apps. What this means is that as a user, you can now manage your web app just like you would a native app. You can install/update/uninstall the app and the app will also show up in the App Drawer as well as the Recent Apps list.

    As a developer, you can now build your Open Web App for Firefox OS devices and have that app reach millions of existing Firefox for Android users without having to change a single line of code!

    Check out the video to see an Open Web App in action on an Android device,

    Better yet, if you have installed Firefox for Android try one or build an app and submit it to the Marketplace.

    We also recommend reading Testing Your Native Android App.

  2. Testing Your Native Android App

    It’s an interesting time to be a web developer!

    For years Apps have been eating the web and now we are seeing the Web eat the OS. Mozilla is pushing for a world where you can write standards-based, Open Web Apps. These apps should install as native apps and just work, regardless of the platform.

    Packaged App on Firefox OS

    With the new Firefox for Android, we will now automatically convert your Open Web App into a native Android app.

    Packaged App on Android

    But how can you test you app on Android, before you submit it to the Marketplace?

    We have a new tool to add to your lineup!

    Introducing mozilla-apk-cli

    If you have NodeJS as well as zip/unzip installed, then you can use our new command line tool to build testable .apk installers.

    mozilla-apk-cli is a command-line application, so the commands below would be run from a terminal application.

    Getting setup is easy:

    npm install mozilla-apk-cli

    This will give you a new program mozilla-apk-cli available in ./node_modules/.bin/

    You can also globally install with

    npm install -g mozilla-apk-cli

    I’ll assume you put ./node_modules/.bin in your path or installed globally.

    Open Web Apps come in three flavors and the CLI can build them all:

    • hosted app
    • packaged app zip file
    • packaged app from a directory of source code

    Let’s assume you have a packaged app you are working on.
    You have a directory layout like this:

    www/
       index.html
       manifest.webapp
       css/
           style.css
       i/
         icon-256.png
         icon-128.png
         icon-60.png
       js/
          main.js

    You can build a testable Android app with the following:

    mozilla-apk-cli ./www my_test_app.apk

    This will produce my_test_app.apk which can be side-loaded to your phone in either of the following ways:

    • Put in on the web and download/install form a browser on your Android device
    • Use adb to install the app
    adb install my_test_app.apk

    Setting up adb is out of scope for this blog post, but the Android SDK site has some good resources on adb.

    adb using USB

    Distribution

    Do not distribute this test .apk file!!!

    If you change your app, rebuild and send the APK to your users, the update will fail to install. With each new version of your app, using Android’s app manager, you have to remove the test app before installing the 2nd version.

    mozilla-apk-cli is only for testing and debugging your new Android app locally. When you are happy with your app, you should distribute the Open Web App through the Marketplace or from your website via an install page.

    You don’t need to manage an .apk file directly. Just like you don’t need to manage Mac OS X, Windows or Linux builds for your Open Web App.

    We’ve baked native Android support deeply into the Firefox for Android runtime. When a user chooses to install an Open Web App, the native app is synthesized on demand using the production APK Factory Service. This works regardless of the website or Marketplace you are installing the Open Web App from.

    How does the CLI work?

    Back to our new test tool. This tool is a frontend client to the APK Factory Service. It takes your code and sends it to a reviewer instance of the service. Reviewer as opposed to the production release environment.

    This service synthesizes an native Android app, builds it with the Android SDK and lastly signs it with a development cert. As mentioned, this synthesized APK is debuggable and should not be distributed.

    The nice thing about the service is that you do not have to have Java, ant, the Android SDK and other Android development tools installed on your local computer. You can focus on the web and test on whatever devices you have handy.

    Hosted and Packaged Zip files

    We just looked at how to test a packaged app which is a directory of source code. Now lets look at the other two modes. If you already have built your packaged app into a .zip file, use:

    mozilla-apk-cli ./my_app.zip my_test_app.apk

    If you are building a hosted app, use:

    mozilla-apk-cli http://localhost:8080/ my_test_app.apk

    No Android Devices? No stress

    Perhaps you are saying "Sounds cool, but I don’t have any Android devices… How am I supposed to test?"

    Good point. We’re enabling this automatically.

    On the one hand, don’t worry. One thing mobile first development has taught us, is that there are way more devices and platforms that you will ever have testing resources for. The web is about open standards and progressive enhancement.

    Your web app is just going to be a little bit nicer as a native android app, fitting into the OS as the user expects.

    It doesn’t use native UI widgets or anything like that, so extensive testing is not required. The rendering engine is gecko from the already installed Firefox for Android.

    On the other hand… open standards and compatibility is a nice story, but as web developers, we know things tend to have platform specific bugs. I’d recommend the traditional grading of supported platforms and if Android is a high priority, definitely get a device, Firefox for Android and test your app.

    As we make native experiences automatic across platforms (Android, Mac OS X, etc) we are all ears for feedback. What do you think?

    mozilla-apk-cli Resources

    The source code for the CLI tool is on GitHub. If you need a sample packaged app, here is a demo version. The source code for the APK Factory Service is also on GitHub.

    Join us in with ideas, feedback and questions and please file bugs in Marketplace Integration.

    Thanks to Wil Clouser for the illustrations.

  3. Stack Overflow Dashboard – check engagement, metrics and more

    Recently I put together a little Mozilla tags on Stack Overflow dashboard to check the engagement and numbers for the tags we sponsor. I liked the idea and wanted to create a general purpose dashboard for Stack Overflow, and share the feature, code and thinking with you.

    Features

    Numbers and developer behavior are always interesting areas, especially to spot trends, common questions, related areas and more. As Stack Overflow is one of the de facto channels where developers ask questions to solve problems I find it very interesting to look at those numbers and see possible correlations.

    You can filter the data based on dates and time periods (different data is available through one or the other option), and the areas the dashboard offers information for are:

    • Questions:
      • # with activity
      • # of unanswered
      • Percentage of unanswered questions (Note that a question must have at least one upvoted answer to be considered answered)
      • List of unanswered questions
      • Frequently asked questions
    • Top answerers
    • Top askers
    • Related tags

    The approach

    My thinking was to use the Stack Exchange API and do simple requests for various tags end the engagement around them. I also wanted to make it easy for the user and autocomplete values for the tag criteria field. Given how many tags there are on Stack Overflow, though, to avoid massive overload I only get the 100 most popular tags and put them in a <datalist> element, connected to the <input> element where the user enters the tag to look for data for. This is being done directly on page load.

    General mindset

    The general mindset when building up the dashboard:

    1. Create a simple HTML form with tag, date period input
    2. Use a simple XMLHttpRequest to get the most popular tags for the <datalist> element
    3. For any request, use the basic XHR to get the data directly in JSON
    4. Depending on the requested data – multiple requests are needed to fill the dashboard – parse the returned JSON and present the results

    API methods being used

    The other API methods that are being called are:

    Request throttling

    Note that the limit for each IP number is 300 requests per 24 hours (unless you have an access_token, then the limit is 10,000).

    Code

    The code is available on GitHub and the idea has been to keep it as simple and free of dependencies as possible. It doesn’t use any JavaScript libraries as I see the use cases here, and where we are right now with HTML5, competent enough not to need that.

    Pre-populating the <datalist> element

    As an example, this is (trimmed-down) version of the code to get the most popular tags as JSON through the Stack Exchange API and polulate the <datalist>:

    function getPopularTags () {
        getItems("popularTags", "http://api.stackexchange.com/2.2/tags?pagesize=100&amp;order=desc&amp;sort=popular&amp;site=stackoverflow");
    }
     
    // Run automatically at page load to pre-populate the &lt;datalist&gt; element
    getPopularTags();
     
    function getItems(type, url) {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                var response = xhr.response;
     
                if (response.error_message) {
                    // Show errors
                }
                else {
                    addResults(type);
                }
            }
        };
     
        xhr.open("GET", url, true);
        xhr.responseType = "json";
        xhr.send(null);
    };
     
    function addResults (type) {
        // Popular tags, for filling the &lt;datalist&gt; element
        if (type === "popularTags") {
            var popularTagsList = document.querySelector("#popular-tags"),
                popularTags = questions.popularTags.items,
                popularTagsResults = "";
            for (var i=0,l=popularTags.length, tag; i&lt;l; i++) {
                tag = popularTags[i];
                popularTagsResults += '&lt;option value="' + tag["name"] + '"&gt;';
            }
            popularTagsList.innerHTML = popularTagsResults;
        }
    }

    Give feedback & hack it

    I hope you find this interesting, and a good point to evaluate which areas to focus on and learn more! Also feel more than welcome to use the dashboard, check out the code and issue pull requests, suggest features and more!

  4. Easy audio capture with the MediaRecorder API

    The MediaRecorder API is a simple construct, used inside Navigator.getUserMedia(), which provides an easy way of recording media streams from the user’s input devices and instantly using them in web apps. This article provides a basic guide on how to use MediaRecorder, which is supported in Firefox Desktop/Mobile 25, and Firefox OS 2.0.

    What other options are available?

    Capturing media isn’t quite as simple as you’d think on Firefox OS. Using getUserMedia() alone yields raw PCM data, which is fine for a stream, but then if you want to capture some of the audio or video you start having to perform manual encoding operations on the PCM data, which can get complex very quickly.

    Then you’ve got the Camera API on Firefox OS, which until recently was a certified API, but has been downgraded to privileged recently.

    Web activities are also available to allow you to grab media via other applications (such as Camera).

    the only trouble with these last two options is that they would capture only video with an audio track, and you would still have separate the audio if you just wanted an audio track. MediaRecorder provides an easy way to capture just audio (with video coming later — it is _just_ audio for now.)

    A sample application: Web Dictaphone

    An image of the Web dictaphone sample app - a sine wave sound visualization, then record and stop buttons, then an audio jukebox of recorded tracks that can be played back.

    To demonstrate basic usage of the MediaRecorder API, we have built a web-based dictaphone. It allows you to record snippets of audio and then play them back. It even gives you a visualization of your device’s sound input, using the Web Audio API. We’ll concentrate on the recording and playback functionality for this article.

    You can see this demo running live, or grab the source code on Github (direct zip file download.)

    CSS goodies

    The HTML is pretty simple in this app, so we won’t go through it here; there are a couple of slightly more interesting bits of CSS worth mentioning, however, so we’ll discuss them below. If you are not interested in CSS and want to get straight to the JavaScript, skip to the “Basic app setup” section.

    Keeping the interface constrained to the viewport, regardless of device height, with calc()

    The calc function is one of those useful little utility features that’s cropped up in CSS that doesn’t look like much initially, but soon starts to make you think “Wow, why didn’t we have this before? Why was CSS2 layout so awkward?” It allows you do a calculation to determine the computed value of a CSS unit, mixing different units in the process.

    For example, in Web Dictaphone we have theee main UI areas, stacked vertically. We wanted to give the first two (the header and the controls) fixed heights:

    header {
      height: 70px;
    }
     
    .main-controls {
      padding-bottom: 0.7rem;
      height: 170px;
    }

    However, we wanted to make the third area (which contains the recorded samples you can play back) take up whatever space is left, regardless of the device height. Flexbox could be the answer here, but it’s a bit overkill for such a simple layout. Instead, the problem was solved by making the third container’s height equal to 100% of the parent height, minus the heights and padding of the other two:

    .sound-clips {
      box-shadow: inset 0 3px 4px rgba(0,0,0,0.7);
      background-color: rgba(0,0,0,0.1);
      height: calc(100% - 240px - 0.7rem);
      overflow: scroll;
    }

    Note: calc() has good support across modern browsers too, even going back to Internet Explorer 9.

    Checkbox hack for showing/hiding

    This is fairly well documented already, but we thought we’d give a mention to the checkbox hack, which abuses the fact that you can click on the <label> of a checkbox to toggle it checked/unchecked. In Web Dictaphone this powers the Information screen, which is shown/hidden by clicking the question mark icon in the top right hand corner. First of all, we style the <label> how we want it, making sure that it has enough z-index to always sit above the other elements and therefore be focusable/clickable:

    label {
        font-family: 'NotoColorEmoji';
        font-size: 3rem;
        position: absolute;
        top: 2px;
        right: 3px;
        z-index: 5;
        cursor: pointer;
    }

    Then we hide the actual checkbox, because we don’t want it cluttering up our UI:

    input[type=checkbox] {
       position: absolute;
       top: -100px;
    }

    Next, we style the Information screen (wrapped in an <aside> element) how we want it, give it fixed position so that it doesn’t appear in the layout flow and affect the main UI, transform it to the position we want it to sit in by default, and give it a transition for smooth showing/hiding:

    aside {
       position: fixed;
       top: 0;
       left: 0;
       text-shadow: 1px 1px 1px black;  
       width: 100%;
       height: 100%;
       transform: translateX(100%);
       transition: 0.6s all;
       background-color: #999;
        background-image: linear-gradient(to top right, rgba(0,0,0,0), rgba(0,0,0,0.5));
    }

    Last, we write a rule to say that when the checkbox is checked (when we click/focus the label), the adjacent <aside> element will have it’s horizontal translation value changed and transition smoothly into view:

    input[type=checkbox]:checked ~ aside {
      transform: translateX(0);
    }

    Basic app setup

    To grab the media stream we want to capture, we use getUserMedia() (gUM for short). We then use the MediaRecorder API to record the stream, and output each recorded snippet into the source of a generated <audio> element so it can be played back.

    First, we’ll add in a forking mechanism to make gUM work, regardless of browser prefixes, and so that getting the app working on other browsers once they start supporting MediaRecorder will be easier in the future.

    navigator.getUserMedia = ( navigator.getUserMedia ||
                           navigator.webkitGetUserMedia ||
                           navigator.mozGetUserMedia ||
                           navigator.msGetUserMedia);

    Then we’ll declare some variables for the record and stop buttons, and the <article> that will contain the generated audio players:

    var record = document.querySelector('.record');
    var stop = document.querySelector('.stop');
    var soundClips = document.querySelector('.sound-clips');

    Finally for this section, we set up the basic gUM structure:

    if (navigator.getUserMedia) {
       console.log('getUserMedia supported.');
       navigator.getUserMedia (
          // constraints - only audio needed for this app
          {
             audio: true
          },
     
          // Success callback
          function(stream) {
     
     
          },
     
          // Error callback
          function(err) {
             console.log('The following gUM error occured: ' + err);
          }
       );
    } else {
       console.log('getUserMedia not supported on your browser!');
    }

    The whole thing is wrapped in a test that checks whether gUM is supported before running anything else. Next, we call getUserMedia() and inside it define:

    • The constraints: Only audio is to be captured; MediaRecorder only supports audio currently anyway.
    • The success callback: This code is run once the gUM call has been completed successfully.
    • The error/failure callback: The code is run if the gUM call fails for whatever reason.

    Note: All of the code below is placed inside the gUM success callback.

    Capturing the media stream

    Once gUM has grabbed a media stream successfully, you create a new Media Recorder instance with the MediaRecorder() constructor and pass it the stream directly. This is your entry point into using the MediaRecorder API — the stream is now ready to be captured straight into a Blob, in the default encoding format of your browser.

    var mediaRecorder = new MediaRecorder(stream);

    There are a series of methods available in the MediaRecorder interface that allow you to control recording of the media stream; in Web Dictaphone we just make use of two. First of all, MediaRecorder.start() is used to start recording the stream into a Blob once the record button is pressed:

    record.onclick = function() {
      mediaRecorder.start();
      console.log(mediaRecorder.state);
      console.log("recorder started");
      record.style.background = "red";
      record.style.color = "black";
    }

    When the MediaRecorder is recording, the MediaRecorder.state property will return a value of “recording”.

    Second, we use the MediaRecorder.stop() method to stop the recording when the stop button is pressed, and finalize the Blob ready for use somewhere else in our application.

    stop.onclick = function() {
      mediaRecorder.stop();
      console.log(mediaRecorder.state);
      console.log("recorder stopped");
      record.style.background = "";
      record.style.color = "";
    }

    When recording has been stopped, the state property returns a value of “inactive”.

    Note that there are other ways that a Blob can be finalized and ready for use:

    • If the media stream runs out (e.g. if you were grabbing a song track and the track ended), the Blob is finalized.
    • If the MediaRecorder.requestData() method is invoked, the Blob is finalized, but recording then continues in a new Blob.
    • If you include a timeslice property when invoking the start() method — for example start(10000) — then a new Blob will be finalized (and a new recording started) each time that number of milliseconds has passed.

    Grabbing and using the blob

    When the blob is finalized and ready for use as described above, a dataavailable event is fired, which can be handled using a mediaRecorder.ondataavailable handler:

    mediaRecorder.ondataavailable = function(e) {
      console.log("data available");
     
      var clipName = prompt('Enter a name for your sound clip');
     
      var clipContainer = document.createElement('article');
      var clipLabel = document.createElement('p');
      var audio = document.createElement('audio');
      var deleteButton = document.createElement('button');
     
      clipContainer.classList.add('clip');
      audio.setAttribute('controls', '');
      deleteButton.innerHTML = "Delete";
      clipLabel.innerHTML = clipName;
     
      clipContainer.appendChild(audio);
      clipContainer.appendChild(clipLabel);
      clipContainer.appendChild(deleteButton);
      soundClips.appendChild(clipContainer);
     
      var audioURL = window.URL.createObjectURL(e.data);
      audio.src = audioURL;
     
      deleteButton.onclick = function(e) {
        evtTgt = e.target;
        evtTgt.parentNode.parentNode.removeChild(evtTgt.parentNode);
      }
    }

    Let’s go through the above code and look at what’s happening.

    First, we display a prompt asking the user to name their clip.

    Next, we create an HTML structure like the following, inserting it into our clip container, which is a <section> element.

    <article class="clip">
      <audio controls></audio>
      <p><em>your clip name</em></p>
      <button>Delete</button>
    </article>

    After that, we create an object URL pointing to the event’s data attribute, using window.URL.createObjectURL(e.data): this attribute contains the Blob of the recorded audio. We then set the value of the <audio> element’s src attribute to the object URL, so that when the play button is pressed on the audio player, it will play the Blob.

    Finally, we set an onclick handler on the delete button to be a function that deletes the whole clip HTML structure.

    Conclusion

    And there you have it; MediaRecorder should serve to make your app media recording needs easier. Have a play around with it and let us know what you think: we are looking forward to seeing what you’ll build!

  5. PlayCanvas Goes Open Source

    This is a guest post by Will Eastcott of the PlayCanvas engine. As outlined in What Mozilla Hacks is, we constantly cover interesting information about open source and the Open Web, both from external as well as Mozilla authors, so feel free to share with us!

    On March 22nd 2011, Mozilla released Firefox 4.0 which enabled WebGL by default. A month later, we formed PlayCanvas and started building a game engine unlike anything that had gone before. Fast forward three years, and WebGL is everywhere. Only this week, Apple announced support for WebGL in both OS X and iOS 8. So what better time pass on some more exciting news for you:

    The PlayCanvas Engine has been open sourced!

    MozBlog500

    Introducing the PlayCanvas Engine

    The PlayCanvas Engine is a JavaScript library engineered specifically for building video games. It implements all of the major components that you need to write high quality games:

    • Graphics: model loading, per-pixel lighting, shadow mapping, post effects
    • Physics: rigid body simulation, ray casting, joints, trigger volumes, vehicles
    • Animation: keyframing, skeletal blending, skinning
    • Audio engine: 2D and 3D audio sources
    • Input devices: mouse, keyboard, touch and gamepad support
    • Entity-component system: high level game object management

    We had a couple of goals in mind when we originally designed the engine.

    1. It had to be easy to work with.
    2. It had to be blazingly fast.

    Simple Yet Powerful

    As a developer, you want well documented and well architected APIs. But you also want to be able to understand what’s going on under the hood and to debug when things go wrong. For this, there’s no substitute for a carefully hand-crafted, unminified, open source codebase.

    Additionally, you need great graphics, physics and audio engines. But the PlayCanvas Engine takes things a step further. It exposes a game framework that implements an entity-component system, allowing you to build the objects in your games as if they were made of Lego-like blocks of functionality. So what does this look like? Let’s check out a simple example on CodePen: a cannonball smashing a wall:

    playcanvas_codepen

    As you can see from the Pen’s JS panel, in just over 100 lines of code, you can create, light, simulate and view interesting 3D scenes. Try forking the CodePen and change some values for yourself.

    Need For Speed

    To ensure we get great performance, we’ve built PlayCanvas as a hybrid of hand-written JavaScript and machine generated asm.js. The most performance critical portion of the codebase is the physics engine. This is implemented as a thin, hand-written layer that wraps Ammo.js, the Emscripten-generated JavaScript port of the open source physics engine Bullet. If you haven’t heard of Bullet before, it powers amazing AAA games like Red Dead Redemption and GTAV. So thanks to Mozilla’s pioneering work on Emscripten and asm.js, all of this power is also exposed via the PlayCanvas engine. Ammo.js executes at approximately 1.5x native code speed in recent builds of Firefox so if you think that complex physics simulation is just not practical with JavaScript, think again.

    But what about the non-asm.js parts of the codebase? Performance is clearly still super-important, especially for the graphics engine. The renderer is highly optimized to sort draw calls by material and eliminate redundant WebGL calls. It has also been carefully written to avoid making dynamic allocations to head off potential stalls due to garbage collection. So the code performs brilliantly but is also lightweight and human readable.

    Powering Awesome Projects

    The PlayCanvas Engine is already powering some great projects. By far and away, the biggest is the PlayCanvas web site: the world’s first cloud-hosted game development platform.

    For years, we’ve been frustrated with the limitations of current generation game engines. So shortly after starting work on the PlayCanvas Engine, we began designing a new breed of game development environment that would be:

    Accessible
    using any device with a web browser, plug in a URL and instantly access simple, intuitive yet powerful tools.
    Collaborative
    See what you teammates are working on in real-time or just sit back and watch a game as it’s built live before your eyes.
    Social
    Making games is easier with the help of others. Be part of an online community of developers like you.

    PlayCanvas ticks all of these boxes beautifully. But don’t take our word for it – head to https://playcanvas.com and discover a better way to make games.

    In fact, here’s a game we have built using these very tools. It’s called SWOOOP:

    PLAY NOW!

    It’s a great demonstration of what you can achieve with HTML5 and WebGL today. The game runs great in both mobile and desktop browsers, and you are free to deploy your PlayCanvas games to app stores as well. For Google Play and the iOS App Store, there are wrapping technologies available that can generate a native app of your game. Examples of these are Ludei’s CocoonJS and the open source Ejecta project. For Firefox OS, the process is a breeze since the OS treats HTML5 apps as first class citizens. PlayCanvas games will run out of the box.

    Want!

    So if you think this is sounding tasty, where should you go to get started? The entire engine sourcebase is now live on GitHub:

    https://github.com/playcanvas/engine

    Get cloning, starring and forking while it’s fresh!

    Stay in the Loop

    Lastly, I want to give you some useful links that should help you stay informed and find help whenever you need it.

    We’re super excited to see what the open source community will do with the PlayCanvas Engine. So get creative and be sure to let us know about your projects.

    Toodle pip!

  6. Introducing webcompat.com

    For the past few months a small group of contributors inside and outside of Mozilla have been working on webcompat.com. We just recently celebrated moving past the “too broken to share” milestone to the “functional-under-construction.gif” milestone of the project and are eager to share what we’ve been up to.

    There’s a more elaborate description of web compatibility and the site over at http://webcompat.com/about, but the basic premise of this project is: what if you could “file a bug on the internet” in a public space where developers, users and browser vendors could be made aware of compatibility issues?

    You can report issues to browser vendors today, through bug trackers or other feedback mechanisms, some public and some not. But frequently you cannot see the results of such a report—or see what related issues others have reported. It can feel like a black hole experience.

    This is where webcompat.com comes in. We want to provide a simple, open interface to web compatibility issues that affect us all as users of the web, regardless of our browsers or devices of choice. Perhaps more importantly, we hope to foster and enable a community of people who are passionate about a web for everyone to help out.

    So is this a Mozilla-only effort?

    Not at all. Mozilla kindly allows me to work on this project as a part of my full-time responsibilities on the Mozilla Mobile Web Compatibility team—but the project’s goal has always been to create an open resource for all people who use and build things on the internet. We’ve had some positive conversations with some of our browser vendor colleagues that have motivated us to start initial plans around future collaborations. It’s clear to us that Mozilla isn’t the only entity invested in a compatible web.

    OK Neat. What can I do?

    There’s actually quite a bit to do if this type of work is interesting to you.

    Reporting Issues

    Do you happen to notice sites that block you, nag you to install a different browser, or are just plain broken or buggy? Instead of just tweeting sad emoticons or #fail hashtags, you can help make a difference by creating a record of these issues with the form at webcompat.com.

    We’ve also created some browser extensions to make reporting easier—just click the added UI button to open a new tab with some bug report info pre-filled for you. You can grab that for Firefox Desktop, Firefox for Android, Chrome, Opera, and Safari. There’s also a bookmarklet you can install in your bookmark or favorites bar. These are all open source, so feel free to hack away and port them to new platforms.

    Diagnosing Compatibility Issues

    Do you have a knack for figuring out why things are broken and want to hone your internet CSI skills? Have you considered getting a “TypeError: ‘undefined’ is not a function” tattoo? Do you love reading minified code and debugging the entire web stack? We could use your help confirming and diagnosing issues (tattoos not required).

    Site Outreach

    Are you more interested in doing outreach and making sites and developers aware of issues? We need your help too. Stay tuned for better tooling around this role—or hop into the #webcompat irc channel on the Mozilla IRC network and say hi.

    Development

    Do you know or want to get better at JavaScript, Python, CSS, UX, design, GitHub, browser extensions, testing, and more? We’ve got a pile of issues we’re working on over at GitHub and welcome patches, opinions, issues, and feedback.

    What’s coming next?

    Right now two of our biggest priorities are being able to view and interact with issues in the site itself, and creating tools that will enable importing existing web compatibility issues from bug trackers (both open and closed) and exporting compatibility issues on webcompat.com to browser vendors (when the bug lies with the browser, not the site).

    Our project is still in its infancy, but we look forward to your compatibility bug reports and comments!

  7. Build Your Next App With a Flame

    Earlier this week, we introduced Flame, the Firefox OS reference device for developers, testers and reviewers from T2Mobile, and announced the opening of the everbuying.com pre-order page. The Flame retails at $170 (USD), global shipping included.

    Wanted: Engaging apps for Firefox OS

    Flame2If you are an experienced HTML5 app developer with a published, well-rated app that you’d like to port to Firefox OS, we’d love to hear from you! It’s always exciting to discover topnotch apps (such as PhoneGap app Find the Movie, pictured to the right running on a Flame) and see them ported from native platforms to Firefox OS. We currently have a small inventory of Flame phones for qualified HTML5 app developers with published, well-rated apps.

    How to qualify

    Through our ongoing Phones for Apps program, there’s an opportunity now for a limited number of invited app developers to receive Flame devices in exchange for a commitment to port their qualifying HTML5 apps within a month of receiving the device. Please apply here.

    There are only three ways to qualify:

    1. You’ve built a successful, well-rated HTML5 app on another platform (such as Amazon Web Apps, Blackberry WebWorks, Chrome Web Store, WebOS, Windows Phone or the PhoneGap store) and are ready to port it now to Firefox OS.
    2. You’ve built a successful, well-rated native app for iOS or Android using a cross-platform wrapper like Cordova or PhoneGap and are ready to port it to Firefox OS. Be sure to indicate the cross-platform tool you used.
    3. You’ve already published a well-rated app in Firefox Marketplace, and you have a second app in progress or already built, and are ready to port it now to Firefox OS.

    Resources

    • Learn more about the Flame (Mozilla Developer Network)
    • Get started with Open Web Apps (Mozilla Developer Network)
    • Mark your calendars for Marketplace Day, June 26 – it’s all about Apps and how you can contribute – as app developers, testers, reviewers and localizers. Hope you can join us!
  8. App Framework and Firefox OS

    Intel’s App Framework is an open source, MIT licensed, cross platform HTML5 framework for building mobile applications. It is hosted on GitHub where you can contribute to the project, especially the Firefox OS theme.

    App Framework is comprised of three main areas.

    1. Query selector library
    2. UI/UX library
    3. Plugins

    The query selector library implements a subset of jQuery* API’s, with additional API’s targeted for mobile development. The UI/UX library offers top notch performance on a broad range of devices, including responsive design for phones and tablets. Plugins, the heart of App Framework UI, allow developers to write and share code for App Framework applications.

    Firefox OS support

    With the 2.1 launch of App Framework, Firefox OS is now officially supported. This was easy to accomplish, due to Firefox supporting vendor neutral prefixes on many CSS features, like CSS transforms. We will be adding an official Firefox OS theme soon.

    Getting the code

    To see everything that is offered in the framework, take a look at the App Framework website. You can find the quickstart guide, API documentation, and the UI component preview. You can clone the source code at GitHub

    Download the zip from GitHub and extract the zip file. View the index.html file to see a sample of the kitchen sink and example API’s. You can test drive App Framework UI and see a demonstration of the provided plugins.

    Building your first app

    Here we will build a sample Hello World app with App Framework UI. Create a new folder and copy over the following files from the kitchen sink into your project

    1. build/ui/appframework.ui.min.js
    2. build/css/af.ui.base.css
    3. build/css/icons.css

    Next create an index.html file, manifest.webapp, and app.js. You can find documentation for the manifest.webapp on MDN. See below for the folder structure for this project.

    __folder__
        index.html
        manifest.webapp
        js
            appframework.ui.min.js
            app.js
        css
            af.ui.base.css
            icons.min.css

    Open up your index.html file in your favorite editor and copy in the following code for the basic ‘Hello World’ app

    <!DOCTYPE html>
    <!--HTML5 doctype-->
    <html>
     
        <head>
            <title>FF OS sample</title>
            <meta http-equiv="Content-type" content="text/html; charset=utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
            <link rel="stylesheet" type="text/css" href="css/icons.css" />
            <link rel="stylesheet" type="text/css" href="css/af.ui.base.css" />
            <script type="text/javascript" charset="utf-8" src="ui/appframework.ui.min.js"></script>
            </head>
     
        <body>
            <div id="afui">
                <!-- this is the main container div.  This way, you can have only part of your app use UI -->
                <!-- this is the header div at the top -->
                <div id="header">
                </div>
                <!-- content is where your panels live/scrollable area -->
                <div id="content">
                    <!-- here is where you can add your panels -->
                    <div data-title='Firefox OS' id="main" class="panel" selected="true">
                        Hello World
                    </div>
                </div>
                <!-- bottom navbar. Add additional tabs here -->
                <div id="navbar">
                    <a href="#main" id='navbar_home' class='icon home'>home</a>
                </div>
            </div>
        </body>
     
    </html>

    Test

    Now you can test your sample app on the Firefox OS simulator or a device. You should see the header with the title “Firefox OS”, “Hello World” in the content area, and a footer with a single icon at the bottom. Since we did not add any additional panels, there isn’t much you can do. Let’s update our code and add more. Open up index.html in your editor and change it to the following.

    <!DOCTYPE html>
    <!--HTML5 doctype-->
    <html>
     
        <head>
            <title>FF OS sample</title>
            <meta http-equiv="Content-type" content="text/html; charset=utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
            <link rel="stylesheet" type="text/css" href="css/icons.css" />
            <link rel="stylesheet" type="text/css" href="css/af.ui.base.css" />
            <script type="text/javascript" charset="utf-8" src="ui/appframework.ui.min.js"></script>
            </head>
     
        <body>
            <div id="afui">
                <div id="header">
                </div>
                <div id="content">
                    <div data-title='Firefox OS' id="main" class="panel" selected="true">
                        Hello World
                    </div>
                    <div data-title='Page 2' id="page2" class="panel">
                        <ul class='list'>
                            <li>
                                <a href='#page2'>Item 1</a>
                            </li>
                            <li>
                                <a href='#page2'>Item 2</a>
                            </li>
                            <li>
                                <a href='#page2'>Item 3</a>
                            </li>
                            <li>
                                <a href='#page2'>Item 4</a>
                            </li>
                            <li class='divider'>
                                Divider
                            </li>
                            <li>
                                <a href='#page2'>Item 5</a>
                            </li>
                            <li>
                                <a href='#page2'>Item 6</a>
                            </li>
                            <li>
                                <a href='#page2'>Item 7</a>
                            </li>                                       
                        </ul>
                    </div>
     
                </div>
                <!-- bottom navbar. Add additional tabs here -->
                <div id="navbar">
                    <a href="#main" id='navbar_home' class='icon home'>home</a>
                    <a href="#page2" id='navbar_home' class='icon gear'>home</a>
                </div>
            </div>
        </body>
     
    </html>

    View the new code

    Run your updated code again in the simulator or device. You will see two items in the bottom tab bar, and a link to “Page 2″. Navigate to Page 2 and you will see the slide up transition, along with a stylized list. You can scroll the list using the built in JavaScript scroller. Hit the back button at the top to go back in the history stack.

    What’s next?

    Get a starter template and start building your application! Check out the App Framework website for more documentation and tips.

    We are working on a Firefox OS theme and you can check our work out. We love feedback and are happy to fix any bugs found. Just head on over to GitHub and report the issues. If you want to extend your app more, build plugins and share them with other developers

    Screenshots

    Below are some screen shots from the Intel® XDK App Preview application, powered by App Framework. This is a cross platform application that runs on phones and tablets.

    login

    list

    demo

    *Other names and brands may be claimed as the property of others.

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

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

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

    Pre-order now.

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

    Mid-tier phone hardware

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

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

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

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

    Specifications & unlocked!

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

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

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

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

  10. Treat Open Source Like a Startup

    What am I getting myself into?

    I was never an open source contributor. I had never even filed a GitHub issue. I considered myself an entrepreneur who simply happened to be technical.

    But when the startup I wanted to build needed something that didn’t exist, I followed an unprecedented whim and paused everything I was working on. I pulled a hard left, and I wound up spending three months working full-time on a project that I needed ASAP. Equally as motivating, I knew that other developers needed it too.

    So, I switched hats. I became an insanely focused, sleeping-isn’t-allowed developer.

    The outcome was an animation engine that drastically improved UI performance and workflow across all devices. See it at VelocityJS.org. It’s a powerful JavaScript tool that rivals the performance of CSS transitions. The trick? Simple: In contrast to jQuery (which was initially released in 2006), I was building an engine that incorporated 2014’s performance best practices from the ground-up. No legacy layers; no bloat. Not a Swiss Army knife; a scalpel.

    But, throughout my solitary confinement, I was genuinely concerned that I was building something for a customer base of one — myself.

    I eventually came to realize that switching hats was actually the wrong approach. I was never supposed to take my startup hat off. (Since normal people don’t wear two hats at once, this is where my metaphor breaks down.)

    This is the story of that realization.

    Success

    Let’s momentarily jump ahead three months — to the time of Velocity’s release. Pardon me for a moment while I gloat:

    • Within three days, Velocity reached the top of Hacker News and programming subreddits a total of four times.
    • Within nine days, Velocity amassed 2400 GitHub stars.
    • Within two weeks, Velocity topped the CodePen charts with multiple demos reaching 10,000 views each (codepen.io/rachsmith/pen/Fxuiacodepen.io/okor/pen/fJIEF, and codepen.io/sol0mka/full/kzyjJ).
    • Countless business, front-end platforms, and web agencies migrated to Velocity (examples: everlane.com, discover.typography.com, apartmentlist.com).

    How was this possible? Because I treated Velocity like I treated my businesses: First, there’s development. That’s 10%. Then, there’s marketing. That’s 90%.

    The perspective shift I underwent midway through development was to commit to the following mantra: However much time I wound up spending on development, I would spend even more time on marketing.

    After all, that was the time-split I experienced with my startups. I didn’t see a single reason why it should be different for this project. User acquisition is user acquisition.

    Ultimately, if you develop a startup or an open source project intended for public use, and nobody uses it… you failed. It doesn’t matter how clever it was. It doesn’t matter what technical challenges you overcame.

    Unfortunately, however, the peculiar reality of OSS growth hacking is that there’s a stigma attached to it: The act of marketing invokes pitching, rubbing shoulders, begging, and bribing. It’s stereotypically personified as an overeager, two-bit hustler wearing a cheap shirt and an even cheaper tie. This clashes with our ideals of open source — which itself is stereotypically personified as a headstrong and idealistic code warrior wearing a cheap shirt and an even cheaper haircut.

    I’ll quote GitHub’s Zach Holman to get to the root of the dichotomy, “We like to think that open source is pure; that it’s unadulterated. That marketing an open source project is silly. That’s just silly.” - ZachHolman.com

    To put it bluntly, if you want your open source project to have an impact, you need to step out of your coder bubble. After all, if you build something amazing — and you market it effectively — you’re doing everyone a favor. Not just yourself.

    The best part is, the more people that know about your work, the more people there are to contribute: Bugs get discovered sooner. Useful features get pitched more often.

    And don’t worry — being seen publicly marketing your project doesn’t frame you as an egotistical developer. It frames you as someone who’s passionate. If you take the time to appreciate the fact that more people benefiting from your hard work is a major motivation in your pursuit of open source, then you’ll realize that hustling on behalf of your project fits exactly within your pre-existing ideals.

    Open source growth hacking

    If you look closely at the current open source landscape, those who most often reach the top of GitHub’s charts are developer figureheads with pre-existing followings, and major companies sharing components of their internal stack.

    Looking at this month’s GitHub’s trending chart, the top ranking projects that aren’t educational resources (link collections, tutorials, etc.) include: Pop (Facebook), Atom (GitHub), Quill (Salesforce), Velocity (Me!), Mail-in-a-Box (individual), Famous (Famous), syncthing (individual), betty (individual), Isomer (individual), Bootstrap (Twitter), Angular (Google), PourOver (NY Times).

    There’s a fair representation of individuals in there, but it’s typically corporations that dominate open source marketing. The reality, however, is that these corporations employ developers that are no better than you or I. There’s no inherent natural selection driving the popularity of their projects versus yours

    Fight to get your project out there. Or sit back and watch the marketing teams of huge companies drown your voice out.

    Velocity.js CodePen Demo

    That’s enough with waxing poetic and analyzing the current landscape. Let’s dive into the meaty details: How exactly did I market Velocity?

    • I pre-wrote advanced drafts for major web development blogs to consider publishing. By presenting the editors with the full goods upfront — not a pitch, not an outline — I minimized their workload, making it very easy for them to say “yes.” I also made sure to wait until I had enough GitHub stars (from Hacker News coverage, etc.) before pitching. And, most importantly, I had a strong thematic focus for each article: One article was exclusively about performance, and the other was exclusively about UI workflow. In both cases, I minimized the amount of attention spent pitching Velocity, and focused instead on educating readers about the respective topic. Blogs don’t want to publish a giant ad on your project’s behalf; they want content that their readers will thank them for.
    • I found out where my power-users were. This advice is common in the startup world: Find your core 1,000 early adopters. It’s no different with open source. Who were the users that craved for a performant animation engine — that would do amazing things with it then show off their exploits to the world without me prompting them to? Web animation demo-sceners — that’s who; the passionate, hard-core devs who explore the intersection of technology and design. And, where do they hang out? CodePen.io. I reached out to the demoers whose work I greatly admired, and I gave them access to a pre-release version of Velocity. Sure enough, they eventually pumped out something amazing for me to share.
    • To ensure that new developers always stumble into Velocity.js — even far past the point that I’m still proactively marketing the project — I embedded Velocity into every popular web developer resource that I could find. I pull-requested BentoBox.io and the popular GitHub repo for front end bookmarks. I pitched the Treehouse video blog guys. That was all just the start. I also have upcoming codecasts on Velocity’s workflow that code schools will be presenting to their students. Simply put, I made sure that every developer trying to master web animation would at some point hear about Velocity.
    • Most importantly, I wrote great documentation. To quote GitHub’s Zach Holman once again, “Documentation is marketing. The best part is that documentation is linkable. It’s indexable. It’s tweetable. Particularly if you have a nice, coherent one-page overview of your project that lets people jump in and immediately ‘get’ it.” To expand on Zach’s thoughts, I would frame an open source project’s documentation as what a landing page is to a startup. And make no mistake, you do have to pitch; you can’t merely document your API and call it a day. The developers reading your documentation are no different than anyone else; they have limited time, and they need to be convinced that your project is worth considering.

    When you have great documentation, posting to Reddit and Hacker News will take care of itself. Developers recognize their peers’ hard work, and they’re happy to spread the word.

    On this topic, do you know what the best-kept secret about open source marketing is? That it’s 100x times easier than startup marketing. It’s less work, and you’ll see success with a much greater degree of certainty. Why? Because developers — as compared to the average web user — are more willing to listen, are more willing to retweet, and are generally less skeptical of your marketing claims. Whereas most web users are tired of being pitched with trite social media products, developers are always on the hunt for better tools. Similarly, the web development press is much easier to get a response from than the mainstream tech news press is. The former is scrounging for good content to share with their users whereas the latter is drowning in a sea of half-backed startup pitches.

    Because of the marketing efforts I put into Velocity, and because of the project’s ensuing success, I have become highly motivated to continue working on open source projects.

    I am only just getting started: Velocity is the first in a trilogy of libraries that aim to change the way we visually interact with software. If you’re interested in staying on top of my UI exploits, say hello on Twitter: @Shapiro.