Rodrigo Silveirahttp://blog.rodms.com/2014-04-15T00:00:00-07:00Contributing to FirefoxOS Cordova initiative2014-04-15T00:00:00-07:00Rodrigo Silveiratag:blog.rodms.com,2014-04-15:posts/Contributing-to-Firefox-OS-Cordova-initiative/<p>After the project I was working on <a href="https://blog.mozilla.org/futurereleases/2014/03/14/metro/">got cancelled</a>, I started contributing to <a href="https://wiki.mozilla.org/CordovaFirefoxOS">Firefox OS Cordova project</a>. <a href="http://cordova.apache.org/">Cordova</a> is an open source framework for writing multi-platform native mobile applications using web technology. Cordova provides you with javascript APIs and the plumbing necessary to access the device's internals, such as battery status, GPS and camera. Neat stuff. Each mobile operating system has its own platform implementation for doing the communication between cordova's javascript API and the native OS code.</p>
<p>This post will focus on how to get started writing the Firefox OS platform and plugins. To get a better understanding on how to use cordova to write a Firefox OS app, I highly recommend the <a href="https://hacks.mozilla.org/2014/02/building-cordova-apps-for-firefox-os/">mozilla hacks post</a> on the subject.</p>
<p>Cordova is written in <a href="http://nodejs.org/">node.js</a>, you just need to understand javascript to work on it. It took me much code digging and asking around to get started, but you won't have to!</p>
<h2>The repositories</h2>
<p>Cordova code is organized into multiple repositories. The main ones you need to be aware of for Firefox OS development are <code>cordova-cli</code>, <code>cordova-firefoxos</code> and <code>cordova-plugin-*</code>. Here is a brief description of them:</p>
<ul>
<li><code>cordova-cli</code> - is where the code for the command line tools is located. There is some platform specific code under <code>src/metadata</code> which are config parsers. Firefox OS uses it to get the initial version of the manifest with the correct app name and other values.</li>
<li><code>cordova-firefoxos</code> - is the repository for the Firefox OS platform tools. The code here is responsible for handling Firefox OS cordova commands and for the initial skeletal app.</li>
<li><code>cordova-plugin-*</code> - are repositories for plugins. A plugin repository contains code for each supported platform too.</li>
</ul>
<h2>Running it locally</h2>
<p>To work on the platform, you need to run on the latest code from the repositories. It's super helpful to run cordova entirely from local files so that you can edit code and see the effects. With the multiple repository organization used by cordova, this can be tricky. Make sure you have <a href="http://git-scm.com/downloads">git</a> and <a href="http://nodejs.org/download/">node.js</a> installed. A <a href="https://github.com/">github</a> account will be handy if you plan to send us your changes. The prompt samples below are using bash.</p>
<p>First lets get <code>cordova-cli</code> from mozilla-cordova github account and install the dependencies. From the directory you'd like to keep cordova code run:</p>
<div class="codehilite"><pre><span class="nv">$ </span>git clone https://github.com/mozilla-cordova/cordova-cli.git
<span class="nv">$ </span><span class="nb">cd </span>cordova-cli
<span class="nv">$ </span>npm install
<span class="nv">$ </span><span class="nb">cd</span> ..
</pre></div>
<p>The cordova binary is located at <code>cordova-cli/bin/cordova</code>. From now on this is the binary we'll use for all our cordova command line needs. You can add it to your <code>PATH</code> if you want, I'll use the relative path for clarity. Next let's clone Firefox OS platform bits from <code>cordova-firefoxos</code> repository:</p>
<div class="codehilite"><pre><span class="nv">$ </span>git clone https://github.com/mozilla-cordova/cordova-firefoxos.git
</pre></div>
<p>No need to install dependencies for <code>cordova-firefoxos</code>, they're already part of the repository. Before creating an app, there's a little trick to tell cordova to use the local platform code we just downloaded. Create a file named <code>firefoxos.json</code> with the following contents:</p>
<div class="codehilite"><pre><span class="p">{</span>
<span class="nt">"lib"</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">"firefoxos"</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">"uri"</span><span class="p">:</span> <span class="s2">"/<FULL PATH TO>/cordova-firefoxos"</span><span class="p">,</span>
<span class="nt">"version"</span><span class="p">:</span> <span class="s2">"dev"</span><span class="p">,</span>
<span class="nt">"id"</span><span class="p">:</span> <span class="s2">"cordova-firefoxos-dev"</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>Make sure to set the full path to <code>cordova-firefoxos</code> folder under <code>uri</code>. We can now create a new cordova app by running <code>create</code>. Let's create the app in <code>myapp</code> folder and give it the even more original project name of <code>io.myapp</code> and name it <code>myapp</code>. The fourth parameter to <code>create</code> is the json config file we just create as a string. To create the app run:</p>
<div class="codehilite"><pre><span class="nv">$ </span>cordova-cli/bin/cordova create myapp io.myapp myapp <span class="s2">"</span><span class="k">$(</span>cat firefoxos.json<span class="k">)</span><span class="s2">"</span>
<span class="nv">$ </span><span class="nb">cd </span>myapp
</pre></div>
<p>Alternatively, to use a local copy of <code>cordova-firefoxos</code> platform code on a cordova app that already exists, you can create a json file with the same content as above under <code>yourapp/.cordova/config.json</code>. In fact, that fourth parameter created that file for you. Go check.</p>
<p>To add the platform, all you need to run is:</p>
<div class="codehilite"><pre><span class="nv">$ </span>../cordova-cli/bin/cordova platform add firefoxos
</pre></div>
<p>That's it. If you make any changes to <code>cordova-firefoxos</code>, remove and add the platform again to make sure you have the latest.</p>
<h2>Adding a plugin</h2>
<p>Working with local plugins is much simpler. Lets download the contacts plugin as an exemple:</p>
<div class="codehilite"><pre><span class="nv">$ </span><span class="nb">cd</span> ..
<span class="nv">$ </span>git clone https://github.com/mozilla-cordova/cordova-plugin-contacts.git
</pre></div>
<p>Adding a local version is pretty simple, just add the path as parameter to <code>plugin add</code> command:</p>
<div class="codehilite"><pre><span class="nv">$ </span><span class="nb">cd </span>myapp
<span class="nv">$ </span>../cordova-cli/bin/cordova plugin add ../cordova-plugin-contacts
</pre></div>
<p><em>NOTE: if at this point you hit a <code>ReferenceError: xml_helpers is not defined</code> error, don't despair. <a href="https://issues.apache.org/jira/browse/CB-6200">It's a bug</a> in <code>cordova-plugman</code> code, which is responsible for plugin management. We can fix it by getting the latest version of <code>cordova-plugman</code>, and making sure cordova-cli uses it too. Here's how:</em></p>
<div class="codehilite"><pre><span class="nv">$ </span><span class="nb">cd</span> ..
<span class="nv">$ </span>git clone https://github.com/apache/cordova-plugman.git
<span class="nv">$ </span><span class="nb">cd </span>cordova-cli
<span class="nv">$ </span>npm install ../cordova-plugman
<span class="nv">$ </span><span class="nb">cd</span> ../myapp
<span class="nv">$ </span>../cordova-cli/bin/cordova plugin add ../cordova-plugin-contacts
</pre></div>
<p>To see changes you made to plugin code you have to remove then add the plugin again. To remove the plugin you need to use the plugin name, not the path. Running <code>../cordova-cli/bin/cordova plugin ls</code> will show you the names of installed plugins. For example, to remove the contacts plugin run <code>../cordova-cli/bin/cordova plugin remove org.apache.cordova.contacts</code>.</p>
<p>That's it, you are now running the latest and greatest versions of it all!</p>
<h2>Firefox OS plugin development: from javascript to javascript</h2>
<p>Cordova provides you with a javascript API. They try to follow standards when possible. Firefox OS is built on web standards too. Sometimes they use the same API. How can a plugin developer access Firefox OS API when they clash?</p>
<p>Cordova provides us with a <code>modulemapper</code> library to access the original values of overwritten properties. Let's take a look at how the <a href="https://github.com/mozilla-cordova/cordova-plugin-battery-status/blob/dev/src/firefoxos/BatteryProxy.js#L22">battery-status plugin uses <code>modulemapper</code></a>:</p>
<div class="codehilite"><pre><span class="kd">var</span> <span class="nx">mozBattery</span> <span class="o">=</span> <span class="nx">cordova</span><span class="p">.</span><span class="nx">require</span><span class="p">(</span><span class="s1">'cordova/modulemapper'</span><span class="p">).</span><span class="nx">getOriginalSymbol</span><span class="p">(</span><span class="nb">window</span><span class="p">,</span> <span class="s1">'navigator.battery'</span><span class="p">);</span>
</pre></div>
<p>The variable <code>mozBattery</code> now points to the original <code>navigator.battery</code>. The first parameter to <code>getOriginalSymbol</code> is the context, pretty much always <code>window</code>. The second is the value you want to get. To find out what value to use on the second parameter, check the <code><js-module></code> element in the plugin's <code>plugin.xml</code> configuration file. For the <a href="https://github.com/mozilla-cordova/cordova-plugin-battery-status/blob/dev/plugin.xml#L14-L16">battery-status plugin it is</a>:</p>
<div class="codehilite"><pre><span class="nt"><js-module</span> <span class="na">src=</span><span class="s">"www/battery.js"</span> <span class="na">name=</span><span class="s">"battery"</span><span class="nt">></span>
<span class="nt"><clobbers</span> <span class="na">target=</span><span class="s">"navigator.battery"</span> <span class="nt">/></span>
<span class="nt"></js-module></span>
</pre></div>
<p>The <code><clobbers></code> element's <code>target</code> attribute has the value that was overwritten.</p>
<h2>Contributing</h2>
<p>If you got this far, you're ready to get started! Open up your favorite editor and hack on. If you want to help with Firefox OS support, check out <a href="http://mozilla-cordova.github.io/">our status site</a> and <a href="https://wiki.mozilla.org/CordovaFirefoxOS">the project's wiki</a>.</p>
<p>While writing this post I got news that I'm joining the team. Super excited to improve cordova support for Firefox OS! If you want to chat with us, we hang out on #cordova channel on <a href="https://wiki.mozilla.org/IRC">mozilla's irc server</a>.</p>Bugzillator: From add-on builder to cfx2013-12-28T00:00:00-08:00Rodrigo Silveiratag:blog.rodms.com,2013-12-28:posts/Bugzillator-from-add-on-builder-to-cfx/<p>I was introduced to the <a href="https://builder.addons.mozilla.org/">add-on builder</a> by a <a href="https://twitter.com/awfurtado">friend</a> a while ago. It's an incredibly easy way to get started writing Firefox add-ons. The online code editor combined with the <a href="https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/index.html">SDK</a> allows you to instantly get an add-on running. It relieves you from having to worry about all the boilerplate and lets you focus on the code. It inspired me to write an add-on I had thought of some time back: the Bugzillator.</p>
<p>Sometimes I read blogs and mailing lists that contain bug references. Most of the time I just want to know the title of the bug for some extra context. When they don't have links, I have to copy the bug number to search in bugzilla. Bugzillator scans the DOM for bug numbers and adds links directly to bugzilla. Plus it adds a hover panel with some useful information on the bug.</p>
<h2>Getting started</h2>
<p>There's no need to scan every single page visited, so I created a toolbar button to activate it. It was just a matter of using the builder <a href="https://builder.addons.mozilla.org/search/">search tool</a> to find <a href="https://builder.addons.mozilla.org/package/167058/">code that did what I wanted</a>.</p>
<p>The code that looks for bug patterns has to run in content to have access to the DOM tree. To load the content script on demand I used the <a href="https://addons.mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/tabs.html#attach%28options%29">tabs attach API</a>:</p>
<div class="codehilite"><pre>let worker = tabs.activeTab.attach({
contentScriptFile: data.url("bugzillator.js")
});
</pre></div>
<h3>Loading bug info</h3>
<p>To get bug information I'm using <a href="https://github.com/harthur/bz.js">bz.js</a> which is a JavaScript wrapper for <a href="https://wiki.mozilla.org/Bugzilla:REST_API">bugzilla's REST API</a>. To keep content script to a minimum it runs in add-on script and communicates using a <a href="https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/guides/content-scripts/using-port.html">port</a>. A <code>getBug</code> message from content gets the bug data and returns a <code>onBug</code> message with the info. On the add-on side we have:</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="codehilite"><pre><span class="nx">worker</span><span class="p">.</span><span class="nx">port</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">"getBug"</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">bugNumber</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">bzClient</span><span class="p">.</span><span class="nx">getBug</span><span class="p">(</span><span class="nx">bugNumber</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">status</span> <span class="o">==</span> <span class="mi">200</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">bug</span> <span class="o">=</span> <span class="nx">response</span><span class="p">.</span><span class="nx">json</span><span class="p">;</span>
<span class="nx">worker</span><span class="p">.</span><span class="nx">port</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s2">"onBug"</span><span class="p">,</span> <span class="nx">bug</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">});</span>
</pre></div>
</td></tr></table>
<p>On the content side it's pretty simple too:</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="codehilite"><pre><span class="c1">// Request bug info</span>
<span class="nx">self</span><span class="p">.</span><span class="nx">port</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s2">"getBug"</span><span class="p">,</span> <span class="nx">bugNumber</span><span class="p">);</span>
<span class="c1">// Receive bug info</span>
<span class="nx">self</span><span class="p">.</span><span class="nx">port</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">"onBug"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">bug</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Do stuff</span>
<span class="p">});</span>
</pre></div>
</td></tr></table>
<h3>Loading the CSS</h3>
<p>The tabs attach API does not take a <code>contentStyleFile</code> property like <a href="https://addons.mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/page-mod.html">page-mod</a>. The simplest solution I found to load a separate CSS file in content was passing the file content as a message. On add-on script side you send the file contents:</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="codehilite"><pre><span class="nx">worker</span><span class="p">.</span><span class="nx">port</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s2">"onCss"</span><span class="p">,</span> <span class="nx">data</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s2">"bugzillator.css"</span><span class="p">));</span>
</pre></div>
</td></tr></table>
<p>Now you just add the CSS to the page in content side:</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="codehilite"><pre><span class="nx">self</span><span class="p">.</span><span class="nx">port</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">"onCss"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">style</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">headStyle</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s2">"style"</span><span class="p">);</span>
<span class="nx">headStyle</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">style</span><span class="p">;</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">head</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nx">headStyle</span><span class="p">);</span>
<span class="p">});</span>
</pre></div>
</td></tr></table>
<p>Simple and effective.</p>
<h2>Graduating from the builder</h2>
<p>After some time playing with the add-on builder I got a <a href="https://builder.addons.mozilla.org/package/207471/latest/">working prototype</a> that I was happy with. But I missed using <a href="http://www.jetbrains.com/webstorm/">my favorite JavaScript editor</a> and wanted a similar workflow using it.</p>
<p>It was harder than I expected. The add-on builder site gives you 2 options for downloading your work: source code and xpi package. The xpi is the fully packaged add-on and contains a lot more than I cared for. The source code options only gives you a zip file with your code and the code for all dependencies. But how can you make changes and have the add-on reinstall itself like when using the builder?</p>
<p>On my first attempt I unpacked the xpi (it's just a zip file), found my code and made changes to it. Then I created a script to repackage everything into an xpi. Now I have the updated xpi but for Firefox to pick it up you have to manually install it every time. No go.</p>
<p>Looking a bit further I found the <a href="https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/cfx-tool.html">cfx tool</a>. The downloaded source code from the add-on builder gives you the package.json files that the cfx tool needs. The easiest way I found to get the tool working with the downloaded source was to create a <code>package</code> folder under the main add-on folder and move all dependencies into it. This way cfx was able to find all dependencies and worked fine without any extra command line parameters. The directory structure looks like this:</p>
<div class="codehilite"><pre>Bugzillator
|- data
| +- content loaded js, css, icon...
|- lib
| +- main.js
|- packages
| |- bugzillaclient
| | |- lib
| | | +- module code
| | +- package.json
| |- toolbarbutton-extended
| | |- lib
| | | +- module code
| | +- package.json
| +- other dependencies...
+- package.json
</pre></div>
<p>With this setup running <code>cfx run</code> will start Firefox on a temporary profile with the current version of the add-on installed. That's almost good enough, I still had to manually load my html test file.</p>
<h3>Testing</h3>
<p>While I was developing using the builder I created a very simple html file with some test cases. It would be neat if I could have a command to open Firefox, load the html and run bugzillator without me having to press buttons. The <code>cfx test</code> command does the trick.</p>
<p>I added my html test file to the add-on data folder and created a <a href="https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/tutorials/unit-testing.html">cfx compatible unit test</a>. Now running <code>cfx test</code> opens up Firefox, loads the html test file and runs bugzillator. It's not automated testing yet, but definitely better.</p>
<h3>Building the xpi.</h3>
<p>There's a cfx command for that: <code>cfx xpi</code>. It packages everything and you won't need to worry about things like <code>install.rdf</code> and getting the directory structure right.</p>
<h2>Conclusion</h2>
<p>Add-on builder is great, but I wish there was a clear path to graduation. Converting the downloaded source to use with cfx tool was trivial but required lots of trial and error and documentation surfing.</p>
<p>The code is available on <a href="https://github.com/rodms10/bugzillator">github</a>. I'm using the <a href="https://github.com/rodms10/bugzillator/issues?state=open">issue tracker</a> for bugs and new features. Hope you find it useful.</p>