<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Techno Barje</title>
  <link href="http://techno-barje.fr/atom.xml" rel="self"/>
  <link href="http://techno-barje.fr/"/>
  <updated>2013-03-09T00:00:06+00:00</updated>
  <id>http://techno-barje.fr/</id>
  <author>
    <name>Alexandre Poirot</name>
    
  </author>

  
  <entry>
    <title>Debug pure javascript leaks</title>
    <link href="http://techno-barje.fr/post/2013/03/09/js-memory-debugging/"/>
    <updated>2013-03-09T00:00:00+00:00</updated>
    <id>http://techno-barje.fr/post/2013/03/09/js-memory-debugging</id>
    <content type="html">&lt;p&gt;Mozilla ecosystem already has plenty of &lt;a href=&quot;https://wiki.mozilla.org/Performance:Leak_Tools&quot;&gt;built-in features, scripts and addons&lt;/a&gt; to debug memory usage. But most of them are focused on the internals of the C++ codebase. These tools are very verbose and expose very-very few Javascript metadata. So that you have to start learning tons of internal C++ classes before being able to undersstand that your Javascript objects are actually visible in these tools output!&lt;/p&gt;

&lt;p&gt;For now, when chasing Addon SDK memory leaks, I was just looking at overall memory usage and tried to read and re-read our codebase until I finally find the leak by seeing it in the code&amp;#8230; But that practice may come to an end!
We should have Javascript-oriented memory debugging tool. With a clear picture of which objects are still allocated at a given point in time. &lt;strong&gt;Without any C++ aspect.&lt;/strong&gt; With an output that any confirmed Javascript developer can easily read and understand without knowing much about how Mozilla engine works.&lt;/p&gt;

&lt;p&gt;With that in mind, I started looking at &lt;strong&gt;the object CC/GC graph&lt;/strong&gt;. This graph contains a view of all objects allocated dynamically by the Garbage collector. All Javascript objects end up being in this graph. But also way more other C++ objects that we will have to translate into a meaningfull Javascript paradigm to the developer.&lt;/p&gt;

&lt;p&gt;Then I realized that an XPCOM component already expose the whole CC graph: &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsICycleCollectorListener&quot;&gt;nsICycleCollectorListener&lt;/a&gt;. But again, with very few Javascript information other than &amp;#8220;this is a Javascript object&amp;#8221;, or, &amp;#8220;this is a javascript function&amp;#8221;. Not much more. It ends up being quite frustrating as most of the information is there, we just miss few pinches of Javascript metadata.
Like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what are the attributes of this object?&lt;/li&gt;
&lt;li&gt;in which document it lives?&lt;/li&gt;
&lt;li&gt;in which script it has been allocated?&lt;/li&gt;
&lt;li&gt;in which line?&lt;/li&gt;
&lt;li&gt;in which function?&lt;/li&gt;
&lt;li&gt;what other Javascript objects refers this one?&lt;/li&gt;
&lt;li&gt;what is the function name/source?&lt;/li&gt;
&lt;li&gt;&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Finally, because of -or- thanks to the extra motivation given by &lt;a href=&quot;http://paul.cx/&quot;&gt;padenot&lt;/a&gt; and &lt;a href=&quot;https://github.com/vingtetun&quot;&gt;vingtetun&lt;/a&gt;, I ended up doing crazy hacks to fetch this few information directly from Javascript: Call the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference&quot;&gt;jsapi&lt;/a&gt; library by using jsctypes with the object addresses given by the nsICycleCollectorListener interface. The benefit is that this experiment can run on any firefox release build (i.e. no need for a custom Firefox build). Using only JS also allows to experiment faster by avoiding the compiling phase. But that should definitely be kept as an experiment as I would not consider this as a safe practice!!&lt;/p&gt;

&lt;p&gt;The result of this is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;a href=&quot;https://github.com/ochameau/jscpptypes&quot;&gt;jsctypes C++ mangling library&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;a &lt;a href=&quot;http://techno-barje.fr/public/demo/cc-js-tool/cc-js-tool.xpi&quot;&gt;work-in-progress addon&lt;/a&gt; to identify DOM node leaks involving multiple compartments/documents, and,&lt;/li&gt;
&lt;li&gt;two (&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=833783&quot;&gt;1&lt;/a&gt;, &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=839280&quot;&gt;2&lt;/a&gt;) bug fixes.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You can install this &lt;a href=&quot;http://techno-barje.fr/public/demo/cc-js-tool/cc-js-tool.xpi&quot;&gt;addon&lt;/a&gt;, it should work on Windows and Linux with FF20+. You can easily see bug 839280&amp;#8217;s leaks on today&amp;#8217;s Aurora (FF21) by opening firefox with this addon, then open and close the devtool inspector panel (CTRL+MAJ+I) and finally run the memory script by pressing ALT+SHIFT+D shortcut.
Wait a bit, the addon is processing the whole CC graph and will freeze your firefox instance. And then open a folder with a log file that displays various information about potential cross compartment leaks.&lt;/p&gt;

&lt;p&gt;Let me show you addon&amp;#8217;s output for this leak.
The code involved in this leak is the following button&amp;#8217;s click listener:
&lt;a href=&quot;http://hg.mozilla.org/mozilla-central/annotate/5d7a14c71f51/browser/devtools/shared/DeveloperToolbar.jsm#l102&quot;&gt;/browser/devtools/shared/DeveloperToolbar.jsm&lt;/a&gt;&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;6&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;7&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;8&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;9&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;10&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;11&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;button.addEventListener(&quot;click&quot;, function() {
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  requisition.update(buttonSpec.typed);
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  //if (requisition.getStatus() == Status.VALID) {
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;    requisition.exec();
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  /*
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  }
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  else {
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;    console.error(&#8216;incomplete commands not yet supported&#8217;);
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  }
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  */
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;}, false);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;The script will print this in the log file:&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;6&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;7&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;8&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;9&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;10&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;11&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;12&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;13&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;14&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;15&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;16&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;17&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;18&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;19&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;20&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;21&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;22&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;23&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;24&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;25&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;26&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;27&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;28&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;29&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;30&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;31&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;32&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;33&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;34&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;35&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;36&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;37&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;38&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;39&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;40&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;41&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;############################################################################
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;DOM Listener leak.
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&amp;gt;&amp;gt;&amp;gt; Leaked listener ctypes.uint64_t.ptr(ctypes.UInt64(&quot;0x128a16c0&quot;)) - JS Object (Function)
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;Function source:
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;function () {
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&quot;use strict&quot;;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          requisition.update(buttonSpec.typed);
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          //if (requisition.getStatus() == Status.VALID) {
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;            requisition.exec();
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          /*
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          }
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          else {
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;            console.error(&#8216;incomplete commands not yet supported&#8217;);
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          }
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          */
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;        }
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&amp;gt;&amp;gt;&amp;gt; DOM Event target holding the listener ctypes.uint64_t.ptr(ctypes.UInt64(&quot;0x12a95f60&quot;))
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;FragmentOrElement (XUL) toolbarbutton id=&#8217;command-button-responsive&#8217; class=&#8217;command-button&#8217; chrome://browser/content/devtools/framework/toolbox.xul
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;############################################################################
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;Scope variable leak.
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&amp;gt;&amp;gt;&amp;gt; Function keeping &#8216;button&#8217; scope variable alive ctypes.uint64_t.ptr(ctypes.UInt64(&quot;0xf9a1640&quot;)) - JS Object (Function)
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;Function source:
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;function () {
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&quot;use strict&quot;;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          requisition.update(buttonSpec.typed);
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          //if (requisition.getStatus() == Status.VALID) {
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;            requisition.exec();
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          /*
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          }
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          else {
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;            console.error(&#8216;incomplete commands not yet supported&#8217;);
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          }
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;          */
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;        }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;It immediatly tells you that you &lt;strong&gt;may&lt;/strong&gt; leak something via this anonymous function. &lt;strong&gt;may leak&lt;/strong&gt;, and not &lt;strong&gt;do leak&lt;/strong&gt;, as it is always hard to tell which references are expected to be removed or not, but at least, it tells you that this reference still exist and may keep your compartment/document/global alive.&lt;/p&gt;

&lt;p&gt;To make it short, the script first search for FragmentOrElement objects in the CC and search for all objects from the same compartment. Then I focused my work on cross compartment leaks so that I looked for edges going from and to these objects. Finally I analysed each of these objects having references from and to other compartments and tried to translate C++ object patterns into a meaningfull sentence for the Javascript paradigm.&lt;/p&gt;

&lt;p&gt;Now What?&lt;/p&gt;

&lt;p&gt;I&amp;#8217;d like to get feedback from people used to debug leaks (no matter the language) and also discuss with people used to gecko internals like nsXPCWrappedJS, JS Object (Call), &amp;#8230; in order to know if assumptions I made &lt;a href=&quot;https://github.com/ochameau/cc-js-tool/blob/master/main.js#L213-L250&quot;&gt;here&lt;/a&gt; are correct. So that I can continue translating new potential C++ object patterns into meaningfull Javascript usecases.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>How to write a new WebAPI in Firefox Desktop, mobile, OS - part 1 ?</title>
    <link href="http://techno-barje.fr/post/2013/02/14/how-to-write-a-webapi/"/>
    <updated>2013-02-14T00:00:00+00:00</updated>
    <id>http://techno-barje.fr/post/2013/02/14/how-to-write-a-webapi</id>
    <content type="html">&lt;p&gt;Mozilla teams recently wrote &lt;a href=&quot;https://wiki.mozilla.org/WebAPI&quot;&gt;tons of new API&lt;/a&gt;
in a very short period of time, mostly for Firefox OS, but not only.
As Firefox Desktop, Firefox Mobile and Firefox OS are based on the same source
code, some of these API can easily be enabled on Desktop and mobile.&lt;/p&gt;

&lt;p&gt;Writing a new API can be seen as both complicated and simple. Depending on the
one you want to write, you don&amp;#8217;t necessary need to write anything else than
Javascript code (for example the &lt;a href=&quot;https://wiki.mozilla.org/WebAPI/SettingsAPI&quot;&gt;settings API&lt;/a&gt;).
That makes such task much more accessible and easier to prototype as you do
not enter in compile/run development cycles, nor have to build firefox before even trying to experiment. But there is a significant number of
mozilla specific knowledges to have before being able to write your API code.&lt;/p&gt;

&lt;p&gt;The aim of this article is to write down a simple API example from ground
and try to explain all necessary things you need to know before writing an API
with the same level of expertise than what did Firefox OS engineers.&lt;/p&gt;

&lt;h1&gt;The example API: &amp;laquo; CommonJS require &amp;raquo;&lt;/h1&gt;

&lt;p&gt;Let&amp;#8217;s say we would like to expose to websites a &lt;code&gt;require()&lt;/code&gt; method that act like
the nodejs/commonjs method with the same name. This function allows you to load
javascript files exposing a precise interface, without polluting your current javascript scope.&lt;/p&gt;

&lt;p&gt;So given the following javascript file:&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;http://blog.techno-barje.fr/public/webapi/module.js  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;js&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// All properties set to `exports` variable will be returned to the requirer&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hello&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;World&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Any webpage will be able to use its &lt;code&gt;hello&lt;/code&gt; function like this:&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;the web  &lt;/span&gt;&lt;/figcaption&gt;
 &lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;js&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;navigator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;webapi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://blog.techno-barje.fr/public/webapi/module.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &amp;gt;&amp;gt; Display &amp;quot;World&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h1&gt;Simpliest implementation possible&lt;/h1&gt;

&lt;p&gt;In this first example I stripped various advanced features in order to ease
jumping into Firefox internal code. I bundled this example as a Firefox addon
so that you can easily see it running and also hack it.
You can download it &lt;a href=&quot;http://techno-barje.fr/public/webapi/api-without-idl.xpi&quot;&gt;here&lt;/a&gt;. Once installed, you will have to relaunch Firefox,
open any webpage, then open a Web console and finally execute the
&lt;code&gt;navigator.webapi.require&lt;/code&gt; code I just gave.&lt;/p&gt;

&lt;p&gt;Now let&amp;#8217;s see what&amp;#8217;s inside.
This .xpi file is just a zip file so you can
open it and see three files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;install.rdf&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;  A really boring file describing our addon. The only two important
  fields in this file are: &lt;code&gt;&amp;lt;em:bootstrap&amp;gt;false&amp;lt;/em:bootstrap&amp;gt;&lt;/code&gt; and
  &lt;code&gt;&amp;lt;em:unpack&amp;gt;true&amp;lt;/em:unpack&amp;gt;&lt;/code&gt; required when you need to register a XPCOM file.
  More info &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Install_Manifests#bootstrap&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;chrome.manifest&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;


&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;6&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;7&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;8&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;9&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;# Those two lines allow to register the Javascript xpcom component defined in
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# `web-api.js`
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;component {20bf1550-64b8-11e2-bcfd-0800200c9a77} web-api.js
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;contract @mozilla.org/webapi-example;1 {20bf1550-64b8-11e2-bcfd-0800200c9a77}
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# That line registers the xpcom component in the &quot;JavaScript-navigator-property&quot;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# category which add it to the list of components that inject a new property in
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# `navigator` web pages global object. The second argument defines the name of
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# the property we would like to set.
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;category JavaScript-navigator-property webapi @mozilla.org/webapi-example;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;web-api.js&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;And last but not least. The Javascript XPCOM file. XPCOM is a component object
model overused in Mozilla codebase.
More info &lt;a href=&quot;https://developer.mozilla.org/en/docs/XPCOM&quot;&gt;here&lt;/a&gt;
Let&amp;#8217;s analyse its content by pieces:&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt; &lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;6&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;7&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;8&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;9&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;10&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;11&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;12&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;13&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;14&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;15&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;16&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;17&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;18&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;19&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;20&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;21&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;22&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;23&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;24&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;25&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;26&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;27&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;28&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;29&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;30&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;31&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;32&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;33&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;34&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;35&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;36&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;37&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;38&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;39&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;40&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;js&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;WebAPI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nx&quot;&gt;WebAPI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;c1&quot;&gt;// Define the XPCOM component id, that has to match the one given in&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;c1&quot;&gt;// chrome.manifest file&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;nx&quot;&gt;classID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Components&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;{20bf1550-64b8-11e2-bcfd-0800200c9a77}&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;c1&quot;&gt;// Mandatory XPCOM method, that defines which interfaces&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;c1&quot;&gt;// an object exposes.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;c1&quot;&gt;// * nsIDOMGlobalPropertyInitializer:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;c1&quot;&gt;// https://developer.mozilla.org/fr/docs/XPCOM_Interface_Reference/nsIDOMGlobalPropertyInitializer&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;c1&quot;&gt;// This interface is related to the XPCOM category &amp;quot;JavaScript-navigator-property&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;c1&quot;&gt;// declared in the chrome.manifest file and this interface defines the `init`&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;c1&quot;&gt;// method that is called when a webpage try to access navigator.webapi property.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;nx&quot;&gt;QueryInterface&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;XPCOMUtils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;generateQI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;    &lt;span class=&quot;nx&quot;&gt;Ci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;nsIDOMGlobalPropertyInitializer&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;c1&quot;&gt;// nsIDOMGlobalPropertyInitializer:init&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;nx&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;win&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;    &lt;span class=&quot;c1&quot;&gt;// The `init` method can return an object that will be the one exposed as&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;    &lt;span class=&quot;c1&quot;&gt;// `navigator.webapi`. This object will be created for each web document.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;      &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;win&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;      &lt;span class=&quot;c1&quot;&gt;// Special internal attribute used to define which property the website&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;      &lt;span class=&quot;c1&quot;&gt;// will be able to access. Only attribute whose name is specified here&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;      &lt;span class=&quot;c1&quot;&gt;// are going to be accessible by the page.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;      &lt;span class=&quot;c1&quot;&gt;// https://wiki.mozilla.org/XPConnect_Chrome_Object_Wrappers&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;      &lt;span class=&quot;nx&quot;&gt;__exposedProps__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;        &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// Last XPCOM thingy that allows to expose our WebAPI Component to the system&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// More info here: https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/XPCOMUtils.jsm&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;NSGetFactory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;XPCOMUtils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;generateNSGetFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;WebAPI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;I let you discover the implementation of the &lt;code&gt;require&lt;/code&gt; method, but it will
be your job to implement such method. Now, you have the very minimal set where
you can tweak the returned value of the &lt;code&gt;init&lt;/code&gt; method and expose your own
API to webpages.&lt;/p&gt;

&lt;p&gt;Now note that this is a very minimal example. I&amp;#8217;ll try to continue blogging
about that and eventually talk about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;interfaces definition,&lt;/li&gt;
&lt;li&gt;custom event implementation,&lt;/li&gt;
&lt;li&gt;other XPCOM categories (in order to inject on other object than navigator),&lt;/li&gt;
&lt;li&gt;how to implement a cross process API (mandatory for Firefox OS),&lt;/li&gt;
&lt;li&gt;prototyping via the Addon SDK,&lt;/li&gt;
&lt;li&gt;&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  
  <entry>
    <title>Firefox OS Bootstrap: How to Build It on a VM</title>
    <link href="http://techno-barje.fr/post/2012/10/27/firefox-os-bootstrap/"/>
    <updated>2012-10-27T00:00:00+00:00</updated>
    <id>http://techno-barje.fr/post/2012/10/27/firefox-os-bootstrap</id>
    <content type="html">&lt;p&gt;During my on-boarding on Firefox OS team I kept a draft of all necessary stuff that need to be done in order to build the project and flash it to the phone.
I&amp;#8217;m pretty sure it can help people on-boarding the project by having a single page that would allow anyone to start working on Firefox OS. I highly suggest you to take a look at &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS&quot;&gt;MDN Firefox OS documentation&lt;/a&gt; if you visit this page later on, as this blogpost will most likely be outdated in some weeks.&lt;/p&gt;

&lt;h1&gt;Environnement&lt;/h1&gt;

&lt;h2&gt;Use a Virtual Machine&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;m suggesting everyone to use a VM. It allows you to use exactly same environment, in order to maximize your chances to succeed building Firefox OS!
Using another OS, another linux distro or even another Ubuntu version will introduce differences in dependencies versions and can easily give you errors no one but you are facing :(&lt;/p&gt;

&lt;p&gt;You can use VMware Player which is free and available &lt;a href=&quot;https://my.vmware.com/web/vmware/free#desktop_end_user_computing/vmware_player/4_0&quot;&gt;here&lt;/a&gt;, or any other VM software you are confortable with that has decent USB support (required to flash the phone).&lt;/p&gt;

&lt;h2&gt;Use Ubuntu 11.10&lt;/h2&gt;

&lt;p&gt;For the same reason than the VM, I suggest you to use the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Mozilla/Boot_to_Gecko/B2G_build_prerequisites#Requirements_for_Linux&quot;&gt;recommended linux distro and version&lt;/a&gt;
You can download this &lt;a href=&quot;http://releases.ubuntu.com/oneiric/ubuntu-11.10-desktop-amd64.iso&quot;&gt;Ubuntu 11.10 x64 ISO image&lt;/a&gt; and create a VM out of it (It is super easy with VMware, it almost does everything for you). The only important things are to set a large enough virtual drive, 30GB is a safe minimum, and enough memory, 4GB is a safe minimum.&lt;/p&gt;

&lt;p&gt;Now open a terminal and launch all following commands in order to install all necessary dependencies.&lt;/p&gt;

&lt;h1&gt;Install dependencies&lt;/h1&gt;

&lt;h2&gt;Install build dependencies:&lt;/h2&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;sudo apt-get install build-essential bison flex lib32ncurses5-dev lib32z1-dev lib32z1-dev ia32-libs libx11-dev libgl1-mesa-dev gawk make curl bzip2  g++-multilib libc6-dev-i386 autoconf2.13 ccache git
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;sudo apt-get build-dep firefox&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Java JDK 6 needed for adb&lt;/h2&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;# The following PPA allows you to easily install the JDK through apt-get
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;sudo add-apt-repository ppa:ferramroberto/java
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;sudo apt-get update
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;sudo apt-get install sun-java6-jdk&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Android SDK in order install adb&lt;/h2&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;6&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;7&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;8&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;9&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;10&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;11&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;12&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;13&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;14&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;15&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;16&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;17&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;18&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;19&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;# Your first need to install 32 bit libs as we are using 64bit OS
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# otherwise, you will have following error while running adb:
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# $ adb: No such file or directory
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;sudo apt-get install ia32-libs
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# There is no particular reason to use this SDK version
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# It was the current version when I&#8217;ve installed it
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;wget http://dl.google.com/android/android-sdk_r20.0.3-linux.tgz
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;tar zxvf android-sdk_r20.0.3-linux.tgz
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;cd android-sdk-linux/
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# The following command installs only &quot;platform-tools&quot; package which
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# contains adb and fastboot
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;./tools/android update sdk &#8211;no-ui &#8211;filter 1,platform-tool
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# Register adb in your PATH
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;echo &quot;PATH=`pwd`/platform-tools:\$PATH&quot; &amp;gt;&amp;gt; ~/.bashrc
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# Execute in a new bash instance in order to gain from this new PATH
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;bash&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Tweak udev in order to recognize your phone&lt;/h2&gt;

&lt;p&gt;If you do not do that at all, or not properly, &lt;code&gt;$ adb devices&lt;/code&gt; will print this:&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;???????????? no permissions&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;You need to put the following content into &lt;code&gt;/etc/udev/rules.d/51-android.rules&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;cat &amp;lt;&amp;lt;EOF | sudo tee -a /etc/udev/rules.d/51-android.rules
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;SUBSYSTEM==&quot;usb&quot;, ATTRS{idVendor}==&quot;19d2&quot;, MODE=&quot;0666&quot;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;SUBSYSTEM==&quot;usb&quot;, ATTRS{idVendor}==&quot;18d1&quot;, MODE=&quot;0666&quot;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;EOF
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;sudo restart udev&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Here I register only internal Mozilla phones otoro and unagi IDs.
You may want to add lines for other phones. See &lt;a href=&quot;http://developer.android.com/tools/device.html#VendorIds&quot;&gt;this webpage&lt;/a&gt; for other vendor IDs.&lt;/p&gt;

&lt;h1&gt;Checkout all necessary projects&lt;/h1&gt;

&lt;h2&gt;Checkout B2G repository&lt;/h2&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;git clone https://github.com/mozilla-b2g/B2G.git&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Take a minute to configure git, otherwise next steps will keep bugging you asking for your name and email.&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;6&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;cat &amp;gt; ~/.gitconfig &amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;[user]
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  name = My name
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  email = me@mail.com
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;[color]
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  ui = auto
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;EOF&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Connect your phone and ensure it is visible from your VM.&lt;/h2&gt;

&lt;p&gt;In order to do so run &lt;code&gt;adb devices&lt;/code&gt;, you should see non-empty list of devices.&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;$ adb devices
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;List of devices attached
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;full_unagi       device&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;If you see &lt;code&gt;no permissions&lt;/code&gt; message, checkout udev step.&lt;br /&gt;
Note that you have to setup your Virtual machine software to connect the USB port to the VM. In VMware player, click on: &lt;code&gt;Player menu &amp;gt; Removable devices &amp;gt; &quot;&#8230;something&#8230;&quot; Android &amp;gt; Connect (Disconnnect from host)&lt;/code&gt;.&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;Checkout all dependencies necessary for your particular phone&lt;/h2&gt;

&lt;p&gt;Before running the following command, ensure that your phone is connected.
Note that you have to run this command with &lt;strong&gt;your phone still being on Android OS and ICS version&lt;/strong&gt;. If your phone is already on B2G, you will have to retrieve the backup-otoro or backup-unagi folder automatically created when running the following command.&lt;br/&gt;
If your device is on an Android version older than ICS, you will have to flash it first to ICS. For both of these issues, ask in #b2g for help.
This step will take a while, as it will download tons of big projects: android, gong, kernel, mozilla-central, gaia,&amp;#8230; More than 4GB of git repositories, so be patient.&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;cd B2G/
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;# Run ./config &#8211;help for the list of supported phones.
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;./config.sh unagi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Install Qualcomm Areno graphic driver&lt;/h2&gt;

&lt;p&gt;Only if you are aiming to build Firefox OS for otoro or unagi phones,
you will have to manually download Qualcomm areno armv7 graphic driver, available &lt;a href=&quot;https://developer.qualcomm.com/file/10127&quot;&gt;here&lt;/a&gt;. &lt;br/&gt;
Unfortunately, you will have to register to this website in order to be able to download this file. Once downloaded, put this &lt;code&gt;Adreno200-AU_LINUX_ANDROID_ICS_CHOCO_CS.04.00.03.06.001.zip&lt;/code&gt; into your &lt;code&gt;B2G&lt;/code&gt; directory.&lt;/p&gt;

&lt;h1&gt;Build Firefox OS&lt;/h1&gt;

&lt;p&gt;If ./config.sh went fine, you can now build Firefox OS!&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;./build.sh&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Here is the possible error you might see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;arm-linux-androideabi-g++: Internal error: Killed (program cc1plus)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You are most likely lacking of memory. 4GB is a safe minimum.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;KeyedVector.h:193:31: error: indexOfKey was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Your gcc version is too recent. Try using gcc 4.6.x version.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;Flash the phone&lt;/h1&gt;

&lt;p&gt;If ./build.sh went fine, you can now flash your phone:&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8221;&gt;&lt;span class=&#8217;line&#8217;&gt;  ./flash.sh&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Note that I have to unplug replug the device in order to make it work in the VM.
When running ./flash.sh, the unagi phone switch to a blue screen, then ./flash.sh script is stuck on &lt;code&gt;&amp;lt; waiting device &amp;gt;&lt;/code&gt; message. If I unplug and plug in back, it immediately starts flashing. Be carefull if you have to do the same, ensure that ./flash.sh doesn&amp;#8217;t start flashing when you unplug it! &lt;br/&gt;&lt;br/&gt;
If ./flash.sh failed by saying that the image is too large, It might mean that you have to root your phone first. Again, ask in #b2g for help.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Addon SDK 1.11 - the page-mod release</title>
    <link href="http://techno-barje.fr/post/2012/09/19/1.11-page-mod-release/"/>
    <updated>2012-09-19T00:00:00+00:00</updated>
    <id>http://techno-barje.fr/post/2012/09/19/1.11-page-mod-release</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;https://addons.mozilla.org/en-US/developers/docs/sdk/latest/packages/addon-kit/page-mod.html&quot;&gt;page-mod API&lt;/a&gt; is the most commonly used API in jetpack. It allows to execute Javascript piece of code against any given website. It is very similar to greasemonkey and userscripts.&lt;/p&gt;

&lt;p&gt;In Addon SDK version 1.11, which is due for October, 30th, we will bring various subtle but very important fixes, features and improvements to this API. In the meantime we will start releasing beta versions on tuesday (09/25) with 1.11b1.&lt;/p&gt;

&lt;p&gt;Here is an overview of these changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You will now be able to execute page-mod scripts to already opened tab, by using the new &lt;code&gt;attachTo&lt;/code&gt; option.
[&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=708190&quot;&gt;bug 708190&lt;/a&gt;]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With the same &lt;code&gt;attachTo&lt;/code&gt; option, you can execute page-mod scripts only on top-level tab documents, and so avoid being applied to iframes.
The &lt;a href=&quot;https://blog.mozilla.org/addons/2012/09/12/introducing-page-mods-attachto/&quot;&gt;following blogpost&lt;/a&gt; goes into detail about this new option.
[&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=684047&quot;&gt;bug 684047&lt;/a&gt;]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;page-mod now ignores non-tab documents like: panel, widget, sidebar, hidden document living in firefox&amp;#8217;s hidden window, &amp;#8230;
[&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=777632&quot;&gt;bug 777632&lt;/a&gt;]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your addon will be more efficient as we removed some costly workaround: the Javascript proxies layer between your content script and the page. We are now relying directly on C++ wrappers, also known as Xraywrappers. We are expecting a major improvement in term of memory and CPU usage. As this change depends on modifications made in Firefox, it will only be enabled on Firefox 17 and greater.
[&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=786976&quot;&gt;bug 786976&lt;/a&gt;]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Content scripts are now correctly frozen when you go back and forth in tab history. Before that, your content script was still alive and could throw some unexpected exception or modify an unexpected document.
[&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=766088&quot;&gt;bug 766088&lt;/a&gt;]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Random fixes: window.top and window.parent will be correct for iframes [&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=784431&quot;&gt;bug 784431&lt;/a&gt;].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Last but not least and still at risk for 1.11 release. You will be able to extend priviledges of your content script to extra domains. So that your script will now be able to execute some action on your own domain in addition to the current page domain, without facing cross domain limitations. This rely on some improvements being made to Firefox and will only be enabled on Firefox 17+.
[&lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=786681&quot;&gt;bug 786681&lt;/a&gt;]&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;It is realy exciting to see our most used API receiving so many improvements and I hope that we fixed most of the long-living issues you may have faced with page-mod!!&lt;/p&gt;

&lt;p&gt;We would really like to get your feedback on these changes. If you find anything wrong, please, file bugs &lt;a href=&quot;https://bugzilla.mozilla.org/enter_bug.cgi?product=Add-on%20SDK&quot;&gt;here&lt;/a&gt; and do not hesitate to come discuss with our team in the &lt;a href=&quot;https://groups.google.com/forum/?fromgroups#!forum/mozilla-labs-jetpack&quot;&gt;mailing-list&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Jetpack localization using YAML format</title>
    <link href="http://techno-barje.fr/post/2011/11/17/jetpack-localization-yaml/"/>
    <updated>2011-11-17T00:00:00+00:00</updated>
    <id>http://techno-barje.fr/post/2011/11/17/jetpack-localization-yaml</id>
    <content type="html">&lt;p&gt;In &lt;a href=&quot;http://techno-barje.fr/post/2011/10/31/jetpack-localization/&quot;&gt;a previous post&lt;/a&gt;, I&amp;#8217;ve described my first proposal for localization support in jetpack addons. I&amp;#8217;ve decided to change locale files format for &lt;a href=&quot;http://en.wikipedia.org/wiki/YAML&quot;&gt;YAML&lt;/a&gt; instead of JSON. During MozCamp event, folks helped me identifying some pitfalls with JSON:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No multiline string support.&lt;/strong&gt; Firefox parser allows multiline but it is not officialy supported! So that it will disallow third party tools to work properly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No easy way to add comments.&lt;/strong&gt; It is mandatory for localizers to have context description in comments next to keys to translate. As there is no way to add comments in JSON, it will end up complexifying a lot locale format.&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;Example&lt;/h1&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;French locale file in YAML format&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;6&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;7&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;8&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;9&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;10&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;11&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;12&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;13&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;14&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;15&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;16&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;17&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;18&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;19&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;20&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;21&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;22&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;yaml&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;# You can add comments with `#`&#8230;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;Hello %s&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;Bonjour %s&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;# almost &#8230;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;hello_key&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;Bonjour %s&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# wherever you want!&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;# For multiline, you need to indent your string with spaces&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;multiline&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;Bonjour&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;   &lt;span class=&quot;s&quot;&gt;%s&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;# Plural forms.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;# we use a nested object with attributes that depends on the target language&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;# in english, we only have &amp;#39;one&amp;#39; (for 1) and &amp;#39;other&amp;#39; (for everything but 1)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;# in french, it is the same except that &amp;#39;one&amp;#39; match 0 and 1&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;# in some language like Polish, there is 4 forms and 6 in arabic&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;# So that having a structured format like YAML,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;# help us writing these translations!&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;pluralString&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;one&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;%s&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;telechargement&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;l-Scalar-Plain&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;%s&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;telechargements&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;# I need to enclode these strings with `&amp;quot;` because of %. See note after.&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;




&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;Addon code&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;6&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;7&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;8&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;9&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;10&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;11&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;javascript&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// Get a reference to `_` gettext method with:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;l10n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// These three forms end up returning the same string.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// We can still use a locale string in code, or use a key.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// And multiline string gets its `\n` removed. (there is a way to keep them)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello %s&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;alex&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;hello_key&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;alex&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;multiline&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;alex&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// Example of non-naive l10n feature, plurals:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;pluralString&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;0 telechargement&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;pluralString&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;1 telechargement&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;pluralString&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;10 telechargements&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h1&gt;Advantages of YAML&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multiline strings are supported nicely / easy to read.&lt;/strong&gt; You do not need to add a final &lt;code&gt;\&lt;/code&gt; on all lines. As mulitiline is easier, localizers can use them more often and it will surely improve readability of locale files!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structured data format.&lt;/strong&gt; we can use this power whenever it is needed. For example, when we need to implement complex l10n features like plural forms or any feature that goes beyond simple 1-1 localization. The cool thing if we compare to JSON is that even if we define structures, we keep a really simple format with no noise (like {, }, &amp;#8220;, &amp;#8230;).&lt;/li&gt;
&lt;/ul&gt;


&lt;br/&gt; 


&lt;p&gt;As nothing comes without any issues, here is what I&amp;#8217;ve found around YAML:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This format is not a Web standard. I don&amp;#8217;t think it makes much sense to avoid using it because of that. We are clearly missing a standardized format for localization in the web world.&lt;/li&gt;
&lt;li&gt;You may hit some issues when you do not enclose your strings with &lt;code&gt;&quot;&lt;/code&gt; or &lt;code&gt;&#8217;&lt;/code&gt;. For example, you can&amp;#8217;t start a string with &lt;code&gt;%&lt;/code&gt;, nor having a &lt;code&gt;:&lt;/code&gt; in middle of your string without enclosing it.&lt;/li&gt;
&lt;li&gt;Even if YAML is not a web standard, it has been formaly specified. And unfortunately, a handy feature becomes a pitfall for our purpose! Some strings are automatically converted. &lt;code&gt;Yes&lt;/code&gt;, &lt;code&gt;True&lt;/code&gt;, &lt;code&gt;False&lt;/code&gt;, &amp;#8230; are automatically converted to a boolean value. We can work around this in multiple ways, either by documenting it, or modifying the parser. The same solution apply here, you need to enclose your string with quotes.&lt;/li&gt;
&lt;/ul&gt;


&lt;br/&gt;&lt;br/&gt;


&lt;p&gt;Again, feedback is welcomed on &lt;a href=&quot;https://groups.google.com/group/mozilla-labs-jetpack/t/da50c6dac33b445b&quot;&gt;this group thread&lt;/a&gt; and you can follow this work in &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=691782&quot;&gt;bug 691782&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Jetpack localization</title>
    <link href="http://techno-barje.fr/post/2011/10/31/jetpack-localization/"/>
    <updated>2011-10-31T00:00:00+00:00</updated>
    <id>http://techno-barje.fr/post/2011/10/31/jetpack-localization</id>
    <content type="html">&lt;p&gt;I&amp;#8217;m going to describe the first proposal of localization support for Jetpack.
This approach uses gettext pattern and json files for locales.
It is the first step of multiple iterations. This one only allows retrieving localized string in javascript code.
We are going to give ways to translate files, mainly HTML files, through another iteration.
And we are about to offer an online tool to ease addon localization (like babelzilla website).&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s start by looking at a concrete example, then I&amp;#8217;ll justify our different choices.&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;French locale file&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;javascript&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello %s&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Bonjour %s&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;s2&quot;&gt;&amp;quot;hello_user&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Bonjour %s&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;




&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;Addon code&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;6&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;7&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;8&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;javascript&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// Retrieve a dynamic reference to `_` gettext method with:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;l10n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// Then print to the console a localized string:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello %s&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;alex&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// =&amp;gt; Prints &amp;quot;Bonjour alex&amp;quot; in french.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;c1&quot;&gt;// Or, if we don&amp;#39;t want to use localized string in addon code:&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;hello_user&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;alex&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Why gettext?&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;It gives a way to automatically fetch localizable strings or ids from source code
by searching for &lt;code&gt;_(  )&lt;/code&gt; pattern.&lt;/li&gt;
&lt;li&gt;It allows to use either strings or IDs as value to translate.
It is obviously better to use IDs. Because locales will broke
each time addon developer fix a typo in the main language hard coded in the code.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;But we should not forget that the high level APIs is trying to
simplify addon development. So that it has to be really easy to translate a simple
addon that has only 2 JS files and less than 50 lines of code!
And the simple fact to mandatory require a locale file for the default language
appears like a big burden for such small addon.&lt;/p&gt;

&lt;p&gt;Having said that, I&amp;#8217;m really happy that gettext approach doesn&amp;#8217;t discourage, nor
makes it harder to use IDs, and so, if an addon developer build a big addon
or just want to take more time to use better pratice, he still can do it, easily!&lt;/p&gt;

&lt;h2&gt;Why JSON for locales?&lt;/h2&gt;

&lt;p&gt;We could have used properties files, like XUL addons. But this format has some
limitations that are not compatible with gettext pattern. Keys can&amp;#8217;t contain spaces
and are limited to ASCII or something alike, so that we can&amp;#8217;t put text in a key.&lt;/p&gt;

&lt;p&gt;So instead of using yet another specific format, I&amp;#8217;m suggesting here to use JSON.
JSON is really easy to parse and generate from both client and server side,
and I&amp;#8217;m convinced that it is simple enough to be edited with a text editor.
On top of that we can build a small web application to ease localization.&lt;/p&gt;

&lt;p&gt;In my very first proposal, I used a complex JSON object with nested attributes.
But it ends up complexifying the whole story without real advantage.
So I&amp;#8217;m suggesting now to use the most simple JSON file we can require:
one big object with keys being strings or id to translate and values being translated strings.
Then we will be able to use JSON features to implement complex localization features,
like plurals handling. So that values may be an array of plurals forms.&lt;/p&gt;

&lt;h2&gt;The big picture&lt;/h2&gt;

&lt;p&gt;Everything starts with one addon developer or one of its contributor.
If one of them want to make the addon localizable, they have to use this new localization module.&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;js&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;l10n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;There is already multiple choices that has been made here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_&lt;/code&gt; is not a &lt;em&gt;magic global&lt;/em&gt;. We need to explicitely require it.
This choice will simplify compatibility with other CommonJS environnements, like NodeJS.&lt;/li&gt;
&lt;li&gt;The name of the module itself is &lt;code&gt;l10n&lt;/code&gt; instead of &lt;code&gt;localization&lt;/code&gt; in order to ease the use of it.&lt;/li&gt;
&lt;li&gt;This module expose &lt;code&gt;_&lt;/code&gt; function on &lt;code&gt;get&lt;/code&gt; attribute in order to be able to
expose another methods. I&amp;#8217;m quite confident we will need some functions for plurals or files localization.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Then, they need to use &lt;code&gt;_&lt;/code&gt; on localizable strings:&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;4&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;js&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;context-menu&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nx&quot;&gt;cm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;My Menu Item&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;URLContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;*.mozilla.org&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Now, they have two choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use a string written in their prefered language, like here.
So that they don&amp;#8217;t have to create a locale file.&lt;/li&gt;
&lt;li&gt;use an ID. Instead of &lt;code&gt;_(&quot;My Menu Item&quot;)&lt;/code&gt;, we will use: &lt;code&gt;_(&quot;contextMenuLabel&quot;)&lt;/code&gt;.
But it forces to create a localization file in order to map &lt;code&gt;contextMenuLabel&lt;/code&gt; to &lt;code&gt;My Menu Item&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Then, either a developer or a localizer can generate or modify locales files.
Each jetpack package can have its own &lt;code&gt;locale&lt;/code&gt; folder.
This folder contains one JSON file per supported language.
Here is how looks like a jetpack addon:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;* my-addon/
  * package.json   # manifest file with addon name, description, version, &#8230;
  * data/          # folder for all static files
    * images, 
    * html files, 
    * &#8230;
  * lib /          # folder that contains all JS modules:
    * main.js      # main module to execute on startup
    * my-module.js # custom module that may use localization module
    * &#8230;
  * locale/       # our main interest!
    * en-US.json
    * fr-FR.json
    * en-GB.json
    * &#8230;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The next iteration will add a new feature to our command line tool,
that is going to generate or update a locale file for a given language by fetching localization strings from source code.
For example, the following command will generate &lt;code&gt;my-addon/locale/fr-FR.json&lt;/code&gt; file:&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;sh&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;cfx fetch-locales fr-FR
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;




&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;my-addon/locale/fr-FR.json&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;javascript&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;s2&quot;&gt;&amp;quot;My Menu Item&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;My Menu Item&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Finally, we need to replace right side values with the localized strings:&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;2&lt;/span&gt;
&lt;span class=&#8217;line-number&#8217;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;javascript&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;  &lt;span class=&quot;s2&quot;&gt;&amp;quot;My Menu Item&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Mon menu&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;And build the final addon XPI file with:&lt;/p&gt;

&lt;figure class=&#8217;code&#8217;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#8217;line-number&#8217;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#8217;code&#8217;&gt;&lt;pre&gt;&lt;code class=&#8217;sh&#8217;&gt;&lt;span class=&#8217;line&#8217;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;cfx xpi
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Any kind of feedback would be highly appreciated on &lt;a href=&quot;https://groups.google.com/group/mozilla-labs-jetpack/t/da50c6dac33b445b&quot;&gt;this group thread&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to follow this work,
subscribe to &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=691782&quot;&gt;bug 691782&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
</feed>
