{"id":4155,"date":"2012-02-06T04:07:44","date_gmt":"2012-02-06T12:07:44","guid":{"rendered":"http:\/\/blog.mozilla.org\/addons\/?p=4155"},"modified":"2012-02-06T12:24:33","modified_gmt":"2012-02-06T20:24:33","slug":"mobile-add-on-development-using-the-add-on-sdk","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/","title":{"rendered":"Mobile Add-on development using the Add-on SDK"},"content":{"rendered":"<p><em>For this post, please welcome guest blogger and SDK developer <a href=\"https:\/\/github.com\/ZER0\/\" target=\"_blank\">Matteo Ferretti<\/a> who has been hard at work porting the SDK to work with the new native version of Mobile Firefox.<\/em><\/p>\n<h2>Getting Started<\/h2>\n<p>Add-on SDK version 1.5 is due to be released on February 21st, and we&#39;re pleased to announce that this version will introduce initial support for creating addons for the new native version of Firefox Mobile (codename &quot;fennec&quot;).<br \/>\nMobile support is still experimental and is currently focused on addons using the SDK&#39;s page-mod module to alter and interact with web pages.<\/p>\n<p>If you&#39;re interested in trying this support out now, you can do so by checking out the \u2018master\u2019 branch of the addon-sdk repository:<\/p>\n<pre><code>git clone git:\/\/github.com\/mozilla\/addon-sdk.git\r\n<\/code><\/pre>\n<p>Alternatively you can just download a zip archive of the current master:<\/p>\n<p>https:\/\/github.com\/mozilla\/addon-sdk\/zipball\/master<\/p>\n<p>Developing an add-on for Firefox Mobile with the Add-on SDK is very similar to the desktop. If you&#39;re not familiar with Add-on SDK development process, you can take a look <a href=\"https:\/\/addons.mozilla.org\/en-US\/developers\/docs\/sdk\/1.4\/dev-guide\/addon-development\/implementing-simple-addon.html\">here<\/a>. It helps but is not mandatory for this tutorial.<\/p>\n<h2>Getting set up<\/h2>\n<p>In addition to having the correct version of the SDK, there are some additional requirements:<\/p>\n<ul>\n<li>you need to have an Android device connected to your computer via USB<\/li>\n<li>on the Android device, you need to install a Nightly build of Firefox Mobile.<\/li>\n<li>you need to download and install the Android SDK, including the SDK Tools. Specifically, the SDK requires that you have installed the &#39;adb&#39; command-line tool.<\/li>\n<\/ul>\n<p>Please see this detailed <a href=\"http:\/\/aaronmt.com\/?p=503\">tutorial<\/a> by Aaron Train for more information on installing and configuring the Android SDK.<\/p>\n<p>Now you&#39;re ready to write the classic &quot;Hello World&quot; example!<\/p>\n<h2>Hello, Fennec!<\/h2>\n<p>Firstly, be sure that you have connected your device to your computer. You can check it running from a shell the following command:<\/p>\n<pre><code>adb devices\r\n<\/code><\/pre>\n<p>Then, be sure that you don&#39;t have any Firefox Mobile already running. That is important because the Add-on SDK will run your add-on using a temporary firefox profile for development, not the default one. If Firefox is already running, you can quit Firefox by opening the application menu, selecting &#39;More&#39;, then selecting &#39;Quit&#39;.<br \/>\nDon&#39;t worry, if Firefox <em>is<\/em> running the Add-on SDK will clearly warn you.<\/p>\n<p>Now open a shell, navigate to the Add-on SDK root directory, and execute:<\/p>\n<pre><code>source bin\/activate\r\n<\/code><\/pre>\n<p>This will activate the SDK&#39;s environment and allow you to run the cfx tool from the current shell prompt nomatter what directory you are currently in..<\/p>\n<p>Change to another directory and then create a directory called <code>hellofennec<\/code>. Keeping your add-on code outside the SDK is good practice. Navigate to that directory and run <code>cfx init<\/code> to create a new addon:<\/p>\n<pre><code>mkdir hellofennec\r\ncd hellofennec\r\ncfx init\r\n<\/code><\/pre>\n<p>With a text editor or IDE of your choice, open <code>lib\/main.js<\/code>, and replace its contents with the following:<\/p>\n<pre lang=\"javascript\">\r\nconsole.log(\"Hello, Fennec!\");\r\n<\/pre>\n<p>Save it. You&#39;re ready to run it on your device using the following command:<\/p>\n<pre><code>cfx run -a fennec-on-device -b ~\/path\/to\/adb --mobile-app fennec --force-mobile\r\n<\/code><\/pre>\n<p>And yes, compared to the desktop version the mobile version needs more arguments. You can learn about all the cfx&#39;s arguments just run it without any parameters, but let&#39;s have a quick look about what they means in this context:<\/p>\n<ul>\n<li>\n<p>-a, &#8211;app : specify the application that runs the add-on, in this case &quot;fennec on device&quot;.<\/p>\n<\/li>\n<li>\n<p>-b, &#8211;binary : is mandatory for <code>fennec-on-device<\/code> app. SDK needs to know where you have installed the adb tool that is installed with the Android SDK in order to communicate with your device. So, replace this value with the right path where you have installed the adb platform tool.<\/p>\n<\/li>\n<li>\n<p>&#8211;mobile-app : is the name of the Android intent. If you have only one Firefox Mobile version installed on your device, you can omit this option. The value for nightly is <code>fennec<\/code>, for aurora this is <code>fennec_aurora<\/code>, for beta this is <code>firefox_beta<\/code> and for release this is <code>firefox<\/code>.<br \/>\nIf you have a Fennec&#39;s custom build on your device, the intent&#39;s name is <code>fennec_&lt;your_username&gt;<\/code> by default.<\/p>\n<\/li>\n<li>\n<p>&#8211;force-mobile : this flag will be removed when the mobile&#39;s support will be stable and not experimental anymore.<\/p>\n<\/li>\n<\/ul>\n<p>When you execute the command the first time you&#39;ll see a message like this:<\/p>\n<pre><code>No &#39;id&#39; in package.json: creating a new ID for you.\r\npackage.json modified: please re-run &#39;cfx run&#39;\r\n<\/code><\/pre>\n<p>Run the command again, and it will run Firefox Mobile on your device with your add-on installed.<\/p>\n<p>Congratulations! You have made your first step in mobile add-ons development with Add-on SDK!<\/p>\n<h2>Hack the web<\/h2>\n<p>As I said previously, Add-on SDK provide a minimal support for mobile at the moment, focused mainly on <a href=\"https:\/\/addons.mozilla.org\/en-US\/developers\/docs\/sdk\/1.4\/packages\/addon-kit\/docs\/page-mod.html\">page-mod<\/a>. In short, they are add-ons that can modify any \u2014 or a specific \u2014 web pages loaded by the browser.<\/p>\n<p>On mobile this is very handy. For instance, you can optimize a website that it wasn&#39;t designed for mobile devices, improve the readability, or adding unique functionality.<\/p>\n<p>For this tutorial I made a simple add-on that &quot;mod&quot; the famous <a href=\"http:\/\/www.penny-arcade.com\/\">penny-arcade.com<\/a> website. You can check it out from github:<\/p>\n<pre><code>git clone git:\/\/github.com\/ZER0\/penny-arcade-comics.git\r\n<\/code><\/pre>\n<p>Alternatively,  you can download it as <a href=\"https:\/\/github.com\/ZER0\/penny-arcade-comics\/zipball\/master\">zip archive<\/a>.<\/p>\n<p>What it does is simple: when you&#39;re on the <a href=\"http:\/\/www.penny-arcade.com\/\">penny-arcade.com<\/a> homepage or reading a news post, switching from portrait to landscape will display the webcomics related to that news, without clicking a link and zooming (landscape fits more the format of penny-arcade comics than portrait, and portrait is more suitable to reading news). Switching back from landscape to portrait will hide it again.<\/p>\n<h2>A deeper look<\/h2>\n<p>So, how it works? The important files are <a href=\"https:\/\/github.com\/ZER0\/penny-arcade-comics\/blob\/master\/data\/content.css\">data\/content.css<\/a>, <a href=\"https:\/\/github.com\/ZER0\/penny-arcade-comics\/blob\/master\/data\/content.js\">data\/content.js<\/a> and <a href=\"https:\/\/github.com\/ZER0\/penny-arcade-comics\/blob\/master\/lib\/main.js\">main.js<\/a>. The first two are the files injected into <a href=\"http:\/\/www.penny-arcade.com\/\">penny-arcade.com<\/a>, and the last one is our add-on entry point.<br \/>\nLet&#39;s start with <a href=\"https:\/\/github.com\/ZER0\/penny-arcade-comics\/blob\/master\/lib\/main.js\">main.js<\/a>.<br \/>\nFirstly, we require the Add-on SDK modules needed:<\/p>\n<pre lang=\"javascript\">\r\nvar PageMod = require(\"page-mod\").PageMod;\r\nvar data = require(\"self\").data;\r\n<\/pre>\n<p>The <a href=\"https:\/\/addons.mozilla.org\/en-US\/developers\/docs\/sdk\/1.4\/packages\/addon-kit\/docs\/page-mod.html\">PageMod<\/a> object allows us to create a page-mod; and <a href=\"https:\/\/addons.mozilla.org\/en-US\/developers\/docs\/sdk\/1.4\/packages\/addon-kit\/docs\/self.html#data\">data<\/a> object provides an access to the <code>data<\/code> directory&#39;s files.<\/p>\n<pre lang=\"javascript\">PageMod({\r\n  \/\/ page-mod will added only on the homepage and news page of penny-arcade.com,\r\n  \/\/ with or without www as prefix.\r\n  include: \/^http:\\\/\\\/(www\\.)?penny-arcade.com(\\\/|\\\/\\d{4})?.*\/,\r\n  contentScriptFile: data.url(\"content.js\"),\r\n  contentScriptWhen: \"ready\",\r\n  onAttach: function (worker) {\r\n    worker.port.emit(\"init\", data.url(\"content.css\"));\r\n  }\r\n});<\/pre>\n<p>For the <a href=\"https:\/\/github.com\/ZER0\/penny-arcade-comics\/blob\/master\/lib\/main.js\">main.js<\/a>, that&#39;s all. The addon will load <a href=\"https:\/\/github.com\/ZER0\/penny-arcade-comics\/blob\/master\/data\/content.js\">content.js<\/a> into the page when the DOM is ready for any URL that matches the <code>include<\/code> property&#39;s regular expression. When the <a href=\"https:\/\/addons.mozilla.org\/en-US\/developers\/docs\/sdk\/1.4\/packages\/addon-kit\/docs\/page-mod.html\">page-mod<\/a> is &quot;attached&quot; to a document, the <code>onAttach<\/code> callback will emit a custom <code>init<\/code> event to the content script, passing the URL of <a href=\"https:\/\/github.com\/ZER0\/penny-arcade-comics\/blob\/master\/data\/content.css\">content.css<\/a>.<\/p>\n<p>So, what happens on the other side when the <code>init<\/code> event is emitted? Let&#39;s see <a href=\"https:\/\/github.com\/ZER0\/penny-arcade-comics\/blob\/master\/data\/content.js\">content.js<\/a>:<\/p>\n<pre lang=\"javascript\">self.port.on(\"init\", function init(cssURL) {\r\n  \/\/ We're not interested in frames\r\n  if (window.frameElement) return;\r\n  addStyleSheet(cssURL);\r\n  var comicsPageURL = document.querySelector(\".btnComic\").href;\r\n  var http = new XMLHttpRequest();\r\n  http.open(\"GET\", comicsPageURL, true);\r\n  http.onload = addComics;\r\n  http.send();\r\n});<\/pre>\n<p>A <a href=\"https:\/\/addons.mozilla.org\/en-US\/developers\/docs\/sdk\/1.4\/packages\/addon-kit\/docs\/page-mod.html\">page-mod<\/a> is attached to every page that matches the include rule, so frames as well. We are not interested in frames, only in the main page, so with:<\/p>\n<pre lang=\"javascript\">\r\nif (window.frameElement) return;\r\n<\/pre>\n<p>We avoid to execute code in that specific case.<\/p>\n<p>Then, we add the stylesheet given using <code>addStyleSheet<\/code> function, defined in the same file, and we obtain the comics page URL by looking into the DOM.<br \/>\nBecause the comic page and the news page are in the same domain, we can use <a href=\"https:\/\/developer.mozilla.org\/en\/XMLHttpRequest\">XMLHttpRequest<\/a> from the content script itself (content scripts follows the <a href=\"https:\/\/developer.mozilla.org\/en\/Same_origin_policy_for_JavaScript\">Same Origin Policy<\/a>) instead of having to delegate  this task to the Add-on code (that can perform Cross Domain requests).<br \/>\nWhen we receive the response, the comic page&#39;s image url is extracted and displayed in the current page. And that&#39;s all!<\/p>\n<p>The behavior related to hide and display the comics image is implemented in <a href=\"https:\/\/github.com\/ZER0\/penny-arcade-comics\/blob\/master\/data\/content.css\">css file<\/a> using <a href=\"https:\/\/developer.mozilla.org\/en\/CSS\/Media_queries\">media queries<\/a>:<\/p>\n<pre lang=\"css\">\r\n@media (orientation:portrait) {\r\n  #penny-arcade-addon-comics {\r\n    display: none;\r\n  }\r\n}\r\n@media (orientation:landscape) {\r\n  #penny-arcade-addon-comics {\r\n    display: block;\r\n  }\r\n}<\/pre>\n<h2>See the results<\/h2>\n<p>Navigate into the <code>penny-arcade-comics<\/code> directory and run it. You should see Fennec Nightly or Aurora ( whichever you specified ) start up on your device. Next, open the Firefox menu, select &#39;More&#39;, then &#39;Addons&#39;. You should see the list of default addons installed into Firefox, as well as two additions: &#39;Mobile Addon-SDK utility addon&#39; and &#39;penny-arcade-comics&#39;. <\/p>\n<p>You can now see how it works at first hand by opening the Penny Arcade site ( <a href=\"http:\/\/penny-arcade.com\/\">http:\/\/penny-arcade.com\/<\/a> ) in Firefox  Mobile:<\/p>\n<h2>Portrait<\/h2>\n<p><a target=\"_blank\" href=\"http:\/\/blog.mozilla.org\/addons\/files\/2012\/02\/SC20120126-223425.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.mozilla.org\/addons\/files\/2012\/02\/SC20120126-223425-150x150.png\" alt=\"\" title=\"Portrait\" width=\"150\" height=\"150\" class=\"alignnone size-thumbnail wp-image-4170\" \/><\/a><\/p>\n<h2>Landscape<\/h2>\n<p><a target=\"_blank\" href=\"http:\/\/blog.mozilla.org\/addons\/files\/2012\/02\/SC20120126-222905.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.mozilla.org\/addons\/files\/2012\/02\/SC20120126-222905-150x150.png\" alt=\"\" title=\"Landscape\" width=\"150\" height=\"150\" class=\"alignnone size-thumbnail wp-image-4169\" \/><\/a><\/p>\n<p>If you do not have an Android device to test this on, you can still see the effect by installing this addon on Firefox Desktop and re-sizing the window to trigger the media queries we&#39;ve used in our customer css.<\/p>\n<p>When running the addon on your deivce, you will notice that your shell will be full of javascript warnings; this is because <code>cfx<\/code> will dump all of Firefox&#39;s log messages there. They can be useful, but especially when you work with <a href=\"https:\/\/addons.mozilla.org\/en-US\/developers\/docs\/sdk\/1.4\/packages\/addon-kit\/docs\/page-mod.html\">page-mod<\/a> it&#39;s easy lost your add-on&#39;s logging information in this flow. What I usually do instead is open a new shell, and execute a command like that:<\/p>\n<pre><code>adb logcat | grep info:\r\n<\/code><\/pre>\n<p>So, in the shell where cfx is executing I will get all the messages, and in the other one I filtered out only the messages from the add-on.<\/p>\n<h2>Conclusion<\/h2>\n<p>We&#39;re very excited about the possibilities around mobile addons and would love any feedback you might have. Working with the Android SDK currently is a bit awkwards, admittedly. If you do get started creating your own addons for Fennec Nightly, please keep in mind that not all SDK modules work properly.<br \/>\nThe modules that currently work are:<\/p>\n<ul>\n<li>page-mod<\/li>\n<li>page-worker<\/li>\n<li>request<\/li>\n<li>self<\/li>\n<li>simple-storage<\/li>\n<li>timers<\/li>\n<\/ul>\n<p>There are additional modules that mostly work; we are currently working on providing as much support for mobile as possible and will keep you up to date on our progress.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For this post, please welcome guest blogger and SDK developer Matteo Ferretti who has been hard at work porting the SDK to work with the new native version of Mobile &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/\">Read more<\/a><\/p>\n","protected":false},"author":316,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[295,588,124,742],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Mobile Add-on development using the Add-on SDK - Mozilla Add-ons Community Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeff Griffiths\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/\",\"url\":\"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/\",\"name\":\"Mobile Add-on development using the Add-on SDK - Mozilla Add-ons Community Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/blog.mozilla.org\/addons\/files\/2012\/02\/SC20120126-223425-150x150.png\",\"datePublished\":\"2012-02-06T12:07:44+00:00\",\"dateModified\":\"2012-02-06T20:24:33+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/e2f4c71eb45392ea29162432c3f1d433\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/#primaryimage\",\"url\":\"http:\/\/blog.mozilla.org\/addons\/files\/2012\/02\/SC20120126-223425-150x150.png\",\"contentUrl\":\"http:\/\/blog.mozilla.org\/addons\/files\/2012\/02\/SC20120126-223425-150x150.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/addons\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Mobile Add-on development using the Add-on SDK\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/addons\/\",\"name\":\"Mozilla Add-ons Community Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/addons\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/e2f4c71eb45392ea29162432c3f1d433\",\"name\":\"Jeff Griffiths\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/b07ae75dd1a5414bf30d7f773ccfc894?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/b07ae75dd1a5414bf30d7f773ccfc894?s=96&d=mm&r=g\",\"caption\":\"Jeff Griffiths\"},\"description\":\"Jeff is Product Manager for the Firefox Developer Tools and occasional Open Web hacker, based in Vancouver, BC.\",\"sameAs\":[\"http:\/\/canuckistani.ca\/\",\"https:\/\/x.com\/canuckistani\"],\"url\":\"https:\/\/blog.mozilla.org\/addons\/author\/jgriffithsmozilla-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Mobile Add-on development using the Add-on SDK - Mozilla Add-ons Community Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/","twitter_misc":{"Written by":"Jeff Griffiths","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/","url":"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/","name":"Mobile Add-on development using the Add-on SDK - Mozilla Add-ons Community Blog","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/addons\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/#primaryimage"},"image":{"@id":"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/#primaryimage"},"thumbnailUrl":"http:\/\/blog.mozilla.org\/addons\/files\/2012\/02\/SC20120126-223425-150x150.png","datePublished":"2012-02-06T12:07:44+00:00","dateModified":"2012-02-06T20:24:33+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/e2f4c71eb45392ea29162432c3f1d433"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/#primaryimage","url":"http:\/\/blog.mozilla.org\/addons\/files\/2012\/02\/SC20120126-223425-150x150.png","contentUrl":"http:\/\/blog.mozilla.org\/addons\/files\/2012\/02\/SC20120126-223425-150x150.png"},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/addons\/2012\/02\/06\/mobile-add-on-development-using-the-add-on-sdk\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/addons\/"},{"@type":"ListItem","position":2,"name":"Mobile Add-on development using the Add-on SDK"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/addons\/#website","url":"https:\/\/blog.mozilla.org\/addons\/","name":"Mozilla Add-ons Community Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/addons\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/e2f4c71eb45392ea29162432c3f1d433","name":"Jeff Griffiths","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/b07ae75dd1a5414bf30d7f773ccfc894?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b07ae75dd1a5414bf30d7f773ccfc894?s=96&d=mm&r=g","caption":"Jeff Griffiths"},"description":"Jeff is Product Manager for the Firefox Developer Tools and occasional Open Web hacker, based in Vancouver, BC.","sameAs":["http:\/\/canuckistani.ca\/","https:\/\/x.com\/canuckistani"],"url":"https:\/\/blog.mozilla.org\/addons\/author\/jgriffithsmozilla-com\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/posts\/4155"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/users\/316"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/comments?post=4155"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/posts\/4155\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/media?parent=4155"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/categories?post=4155"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/tags?post=4155"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}