Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

add 1.3rc1 docset

  • Loading branch information...
commit e78ca56780961ff89bea5971751ad7eff92eb3db 1 parent 9460453
@wbamberg wbamberg authored
Showing with 7,578 additions and 1,050 deletions.
  1. 0  dev-guide-source/addon-development/about.md
  2. 0  dev-guide-source/addon-development/annotator/annotator.md
  3. +2 −2 dev-guide-source/addon-development/annotator/creating.md
  4. 0  dev-guide-source/addon-development/annotator/displaying.md
  5. 0  dev-guide-source/addon-development/annotator/overview.md
  6. +3 −3 dev-guide-source/addon-development/annotator/storing.md
  7. +2 −2 dev-guide-source/addon-development/annotator/widget.md
  8. 0  dev-guide-source/addon-development/api-idioms.md
  9. 0  dev-guide-source/addon-development/api-intro.md
  10. 0  dev-guide-source/addon-development/api-modules.md
  11. +29 −11 dev-guide-source/addon-development/cfx-tool.md
  12. +8 −6 dev-guide-source/addon-development/commonjs.md
  13. 0  dev-guide-source/addon-development/console.md
  14. +38 −11 dev-guide-source/addon-development/content-scripts/access.md
  15. 0  dev-guide-source/addon-development/content-scripts/loading.md
  16. 0  dev-guide-source/addon-development/content-scripts/reddit-example.md
  17. 0  dev-guide-source/addon-development/content-scripts/using-port.md
  18. 0  dev-guide-source/addon-development/content-scripts/using-postmessage.md
  19. 0  dev-guide-source/addon-development/events.md
  20. 0  dev-guide-source/addon-development/getting-started.md
  21. 0  dev-guide-source/addon-development/guides.md
  22. +84 −117 dev-guide-source/addon-development/implementing-reusable-module.md
  23. +65 −81 dev-guide-source/addon-development/implementing-simple-addon.md
  24. +41 −12 dev-guide-source/addon-development/installation.md
  25. +215 −0 dev-guide-source/addon-development/library-detector.md
  26. 0  dev-guide-source/addon-development/module-search.md
  27. +11 −5 dev-guide-source/addon-development/package-spec.md
  28. +22 −5 dev-guide-source/addon-development/program-id.md
  29. 0  dev-guide-source/addon-development/reference.md
  30. +104 −0 dev-guide-source/addon-development/sdk-vs-xul.md
  31. +136 −0 dev-guide-source/addon-development/third-party-packages.md
  32. 0  dev-guide-source/addon-development/troubleshooting.md
  33. 0  dev-guide-source/addon-development/tutorials.md
  34. 0  dev-guide-source/addon-development/two-types-of-scripts.md
  35. 0  dev-guide-source/addon-development/web-content.md
  36. +320 −0 dev-guide-source/addon-development/xul-migration.md
  37. +1 −0  dev-guide-source/appendices/credits.md
  38. 0  dev-guide-source/appendices/glossary.md
  39. 0  dev-guide-source/module-development/about.md
  40. 0  dev-guide-source/module-development/best-practices.md
  41. 0  dev-guide-source/module-development/chrome.md
  42. 0  dev-guide-source/module-development/e10s.md
  43. 0  dev-guide-source/module-development/globals.md
  44. 0  dev-guide-source/module-development/guides.md
  45. 0  dev-guide-source/module-development/reference.md
  46. 0  dev-guide-source/module-development/tutorials.md
  47. 0  dev-guide-source/module-development/xpi.md
  48. 0  dev-guide-source/welcome.md
  49. +18 −4 dev-guide/addon-development/about.html
  50. +18 −4 dev-guide/addon-development/annotator/annotator.html
  51. +20 −6 dev-guide/addon-development/annotator/creating.html
  52. +18 −4 dev-guide/addon-development/annotator/displaying.html
  53. +18 −4 dev-guide/addon-development/annotator/overview.html
  54. +21 −7 dev-guide/addon-development/annotator/storing.html
  55. +20 −6 dev-guide/addon-development/annotator/widget.html
  56. +18 −4 dev-guide/addon-development/api-idioms.html
  57. +18 −4 dev-guide/addon-development/api-intro.html
  58. +18 −4 dev-guide/addon-development/api-modules.html
  59. +46 −15 dev-guide/addon-development/cfx-tool.html
  60. +26 −9 dev-guide/addon-development/commonjs.html
  61. +18 −4 dev-guide/addon-development/console.html
  62. +52 −13 dev-guide/addon-development/content-scripts/access.html
  63. +18 −4 dev-guide/addon-development/content-scripts/loading.html
  64. +18 −4 dev-guide/addon-development/content-scripts/reddit-example.html
  65. +18 −4 dev-guide/addon-development/content-scripts/using-port.html
  66. +18 −4 dev-guide/addon-development/content-scripts/using-postmessage.html
  67. +18 −4 dev-guide/addon-development/events.html
  68. +18 −4 dev-guide/addon-development/getting-started.html
  69. +18 −4 dev-guide/addon-development/guides.html
  70. +107 −122 dev-guide/addon-development/implementing-reusable-module.html
  71. +77 −82 dev-guide/addon-development/implementing-simple-addon.html
  72. +51 −16 dev-guide/addon-development/installation.html
  73. +666 −0 dev-guide/addon-development/library-detector.html
  74. +18 −4 dev-guide/addon-development/module-search.html
  75. +30 −11 dev-guide/addon-development/package-spec.html
  76. +38 −9 dev-guide/addon-development/program-id.html
  77. +18 −4 dev-guide/addon-development/reference.html
  78. +574 −0 dev-guide/addon-development/sdk-vs-xul.html
  79. +599 −0 dev-guide/addon-development/third-party-packages.html
  80. +18 −4 dev-guide/addon-development/troubleshooting.html
  81. +18 −4 dev-guide/addon-development/tutorials.html
  82. +18 −4 dev-guide/addon-development/two-types-of-scripts.html
  83. +18 −4 dev-guide/addon-development/web-content.html
  84. +756 −0 dev-guide/addon-development/xul-migration.html
  85. +19 −4 dev-guide/appendices/credits.html
  86. +18 −4 dev-guide/appendices/glossary.html
  87. +18 −4 dev-guide/module-development/about.html
  88. +18 −4 dev-guide/module-development/best-practices.html
  89. +18 −4 dev-guide/module-development/chrome.html
  90. +18 −4 dev-guide/module-development/e10s.html
  91. +18 −4 dev-guide/module-development/globals.html
  92. +18 −4 dev-guide/module-development/guides.html
  93. +18 −4 dev-guide/module-development/reference.html
  94. +18 −4 dev-guide/module-development/tutorials.html
  95. +18 −4 dev-guide/module-development/xpi.html
  96. +18 −4 dev-guide/welcome.html
  97. +18 −4 index.html
  98. +19 −5 packages/addon-kit/addon-kit.html
  99. +18 −4 packages/addon-kit/docs/clipboard.html
  100. +18 −4 packages/addon-kit/docs/context-menu.html
  101. +5 −4 packages/addon-kit/docs/hotkeys.div
  102. +23 −8 packages/addon-kit/docs/hotkeys.html
  103. +1 −1  packages/addon-kit/docs/hotkeys.json
  104. +18 −4 packages/addon-kit/docs/notifications.html
  105. +1 −1  packages/addon-kit/docs/page-mod.div
  106. +19 −5 packages/addon-kit/docs/page-mod.html
  107. +1 −1  packages/addon-kit/docs/page-mod.json
  108. +18 −4 packages/addon-kit/docs/page-worker.html
  109. +2 −13 packages/addon-kit/docs/panel.div
  110. +20 −17 packages/addon-kit/docs/panel.html
  111. +1 −1  packages/addon-kit/docs/panel.json
  112. +18 −4 packages/addon-kit/docs/passwords.html
  113. +18 −4 packages/addon-kit/docs/private-browsing.html
  114. +18 −4 packages/addon-kit/docs/request.html
  115. +1 −4 packages/addon-kit/docs/selection.div
  116. +19 −8 packages/addon-kit/docs/selection.html
  117. +1 −1  packages/addon-kit/docs/selection.json
  118. +18 −4 packages/addon-kit/docs/self.html
  119. +18 −4 packages/addon-kit/docs/simple-storage.html
  120. +18 −4 packages/addon-kit/docs/tabs.html
  121. +18 −4 packages/addon-kit/docs/timers.html
  122. +7 −2 packages/addon-kit/docs/widget.div
  123. +25 −6 packages/addon-kit/docs/widget.html
  124. +1 −1  packages/addon-kit/docs/widget.json
  125. +20 −2 packages/addon-kit/docs/windows.div
  126. +38 −6 packages/addon-kit/docs/windows.html
  127. +1 −1  packages/addon-kit/docs/windows.json
  128. +23 −5 packages/api-utils/api-utils.html
  129. +18 −4 packages/api-utils/docs/api-utils.html
  130. +18 −4 packages/api-utils/docs/app-strings.html
  131. +18 −4 packages/api-utils/docs/byte-streams.html
  132. +18 −4 packages/api-utils/docs/collection.html
  133. +18 −4 packages/api-utils/docs/content.html
  134. +3 −3 packages/api-utils/docs/content/loader.div
  135. +21 −7 packages/api-utils/docs/content/loader.html
  136. +1 −1  packages/api-utils/docs/content/loader.json
  137. +18 −4 packages/api-utils/docs/content/proxy.html
  138. +2 −2 packages/api-utils/docs/content/symbiont.div
  139. +20 −6 packages/api-utils/docs/content/symbiont.html
  140. +1 −1  packages/api-utils/docs/content/symbiont.json
  141. +1 −1  packages/api-utils/docs/content/worker.div
  142. +19 −5 packages/api-utils/docs/content/worker.html
  143. +1 −1  packages/api-utils/docs/content/worker.json
  144. +18 −4 packages/api-utils/docs/cortex.html
  145. +18 −4 packages/api-utils/docs/cuddlefish.html
  146. +18 −4 packages/api-utils/docs/e10s.html
  147. +18 −4 packages/api-utils/docs/errors.html
  148. +18 −4 packages/api-utils/docs/es5.html
  149. +18 −4 packages/api-utils/docs/events.html
  150. +18 −4 packages/api-utils/docs/file.html
  151. +1 −1  packages/api-utils/docs/hidden-frame.div
  152. +19 −5 packages/api-utils/docs/hidden-frame.html
  153. +1 −1  packages/api-utils/docs/hidden-frame.json
  154. +18 −4 packages/api-utils/docs/light-traits.html
  155. +1 −1  packages/api-utils/docs/list.div
  156. +19 −5 packages/api-utils/docs/list.html
  157. +1 −1  packages/api-utils/docs/list.json
  158. +18 −4 packages/api-utils/docs/match-pattern.html
  159. +18 −4 packages/api-utils/docs/memory.html
  160. +18 −4 packages/api-utils/docs/observer-service.html
  161. +18 −4 packages/api-utils/docs/plain-text-console.html
  162. +18 −4 packages/api-utils/docs/preferences-service.html
  163. +78 −0 packages/api-utils/docs/runtime.div
  164. +556 −0 packages/api-utils/docs/runtime.html
  165. +1 −0  packages/api-utils/docs/runtime.json
  166. +18 −4 packages/api-utils/docs/securable-module.html
  167. +5 −5 packages/api-utils/docs/tab-browser.div
  168. +23 −9 packages/api-utils/docs/tab-browser.html
  169. +1 −1  packages/api-utils/docs/tab-browser.json
  170. +18 −4 packages/api-utils/docs/text-streams.html
  171. +18 −4 packages/api-utils/docs/traceback.html
  172. +6 −6 packages/api-utils/docs/traits.div
  173. +24 −10 packages/api-utils/docs/traits.html
  174. +1 −1  packages/api-utils/docs/traits.json
  175. +185 −0 packages/api-utils/docs/unit-test.div
  176. +203 −4 packages/api-utils/docs/unit-test.html
  177. +1 −1  packages/api-utils/docs/unit-test.json
  178. +18 −4 packages/api-utils/docs/unload.html
  179. +18 −4 packages/api-utils/docs/url.html
  180. +18 −4 packages/api-utils/docs/window-utils.html
  181. +18 −4 packages/api-utils/docs/xhr.html
  182. +266 −2 packages/api-utils/docs/xpcom.div
  183. +284 −6 packages/api-utils/docs/xpcom.html
  184. +1 −1  packages/api-utils/docs/xpcom.json
  185. +18 −4 packages/api-utils/docs/xul-app.html
  186. +19 −5 packages/development-mode/development-mode.html
  187. +18 −4 packages/development-mode/docs/bootstrap.html
  188. +18 −4 packages/development-mode/docs/main.html
  189. +1 −1  packages/index.json
  190. +18 −4 packages/test-harness/docs/harness.html
  191. +18 −4 packages/test-harness/docs/run-tests.html
  192. +19 −5 packages/test-harness/test-harness.html
  193. +13 −3 static-files/base.html
  194. 0  static-files/css/api-reference.css
  195. +1 −1  static-files/css/base.css
  196. 0  static-files/css/footer.css
  197. 0  static-files/css/header.css
  198. +17 −0 static-files/css/sdk-docs.css
  199. 0  static-files/js/jquery.js
  200. 0  static-files/js/main.js
  201. 0  static-files/md/dev-guide/addon-development/content-scripts/access.md
  202. 0  static-files/md/dev-guide/addon-development/content-scripts/loading.md
  203. 0  static-files/md/dev-guide/addon-development/content-scripts/reddit-example.md
  204. 0  static-files/md/dev-guide/addon-development/content-scripts/using-port.md
  205. 0  static-files/md/dev-guide/addon-development/content-scripts/using-postmessage.md
  206. 0  static-files/media/annotator/annotation-list.png
  207. 0  static-files/media/annotator/annotation-panel.png
  208. 0  static-files/media/annotator/annotator-design.png
  209. 0  static-files/media/annotator/editor-panel.png
  210. 0  static-files/media/annotator/highlight.png
  211. 0  static-files/media/annotator/matcher.png
  212. 0  static-files/media/annotator/pencil-off.png
  213. 0  static-files/media/annotator/pencil-on.png
  214. 0  static-files/media/annotator/widget-icon.png
  215. 0  static-files/media/bg-footer.png
  216. 0  static-files/media/bg-header.png
  217. BIN  static-files/media/commonjs-modules.jpg
  218. BIN  static-files/media/commonjs-modules.png
  219. BIN  static-files/media/commonjs-translator.jpg
  220. BIN  static-files/media/commonjs-wikipanel.png
  221. 0  static-files/media/content-scripting-events.png
  222. 0  static-files/media/content-scripting-overview.png
  223. 0  static-files/media/favicon.png
  224. 0  static-files/media/firefox-32.png
  225. 0  static-files/media/firefox-logo.png
  226. 0  static-files/media/footer-logo-med.png
  227. BIN  static-files/media/librarydetector/library-detector.png
  228. BIN  static-files/media/librarydetector/panel-content.png
  229. 0  static-files/media/mozilla-tab.png
  230. 0  static-files/media/multiple-workers.jpg
  231. 0  static-files/media/screenshots/default-panel-osx.png
  232. 0  static-files/media/screenshots/default-panel-ubuntu.png
  233. 0  static-files/media/screenshots/default-panel-windows.png
  234. 0  static-files/media/screenshots/modules/context-menu-image-osx.png
  235. 0  static-files/media/screenshots/modules/notification-growl-osx.png
  236. 0  static-files/media/screenshots/modules/panel-tabs-osx.png
  237. 0  static-files/media/screenshots/modules/widget-content-osx.png
  238. 0  static-files/media/screenshots/modules/widget-icon-osx.png
  239. 0  static-files/media/screenshots/modules/widget-panel-osx.png
  240. BIN  static-files/media/screenshots/translator/context-menu-osx.png
  241. BIN  static-files/media/screenshots/translator/translated-osx.png
  242. 0  static-files/media/screenshots/widget-panel-clock.png
  243. BIN  static-files/media/screenshots/wikipanel/wikipanel-context-menu.png
  244. BIN  static-files/media/screenshots/wikipanel/wikipanel-panel.png
  245. 0  static-files/media/twitter-widget.png
  246. BIN  static-files/media/xul-migration-cs.png
  247. 0  static-files/syntaxhighlighter/MIT-LICENSE
  248. 0  static-files/syntaxhighlighter/scripts/shBrushCss.js
  249. 0  static-files/syntaxhighlighter/scripts/shBrushJScript.js
  250. 0  static-files/syntaxhighlighter/scripts/shBrushXml.js
  251. 0  static-files/syntaxhighlighter/scripts/shCore.js
  252. 0  static-files/syntaxhighlighter/styles/shCore.css
  253. 0  static-files/syntaxhighlighter/styles/shThemeDefault.css
  254. +1 −1  status.md5
View
0  dev-guide-source/addon-development/about.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/annotator/annotator.md 100755 → 100644
File mode changed
View
4 dev-guide-source/addon-development/annotator/creating.md 100755 → 100644
@@ -133,7 +133,7 @@ later on
At the top of the file import the `page-mod` module and declare an array for
the workers:
- const pageMod = require('page-mod');
+ var pageMod = require('page-mod');
var selectors = [];
Add `detachWorker`:
@@ -269,7 +269,7 @@ Now we'll update `main.js` again to create the editor and use it.
First, import the `panel` module:
- const panels = require('panel');
+ var panels = require('panel');
Then add the following code to the `main` function:
View
0  dev-guide-source/addon-development/annotator/displaying.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/annotator/overview.md 100755 → 100644
File mode changed
View
6 dev-guide-source/addon-development/annotator/storing.md 100755 → 100644
@@ -14,7 +14,7 @@ In this section we are only touching the `main.js` file.
First, import the `simple-storage` module with a declaration like:
- const simpleStorage = require('simple-storage');
+ var simpleStorage = require('simple-storage');
In the module scope, initialize an array which will contain the stored annotations:
@@ -264,7 +264,7 @@ respond to it. Add the following to your add-on's `main` function:
Because we use a notification to alert the user, we need to import the
`notifications` module:
- const notifications = require("notifications");
+ var notifications = require("notifications");
(It should be obvious that this is an incredibly unhelpful way to deal with the
problem. A real add-on should give the user a chance to choose which data to
@@ -279,7 +279,7 @@ from creating annotations while the browser is in
First let's import the `private-browsing` module into `main.js`:
- const privateBrowsing = require('private-browsing');
+ var privateBrowsing = require('private-browsing');
We already have a variable `annotatorIsOn` that we use to indicate whether the
user can enter annotations. But we don't want to use that here, because we want
View
4 dev-guide-source/addon-development/annotator/widget.md 100755 → 100644
@@ -55,8 +55,8 @@ You can copy the widget's icons from here:
Now in the `lib` directory open `main.js` and replace its contents with this:
- const widgets = require('widget');
- const data = require('self').data;
+ var widgets = require('widget');
+ var data = require('self').data;
var annotatorIsOn = false;
View
0  dev-guide-source/addon-development/api-idioms.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/api-intro.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/api-modules.md 100755 → 100644
File mode changed
View
40 dev-guide-source/addon-development/cfx-tool.md 100755 → 100644
@@ -112,11 +112,9 @@ your add-on alongside debuggers like [Firebug](http://getfirebug.com/).
<code>-jsconsole</code> argument to Firefox, which will launch the
<a href="https://developer.mozilla.org/en/Error_Console">JavaScript
Error Console</a>, try the following:</p<>
- <pre>
- cfx run --binary-args -jsconsole</pre>
+ <pre>cfx run --binary-args -jsconsole</pre>
<p>To pass multiple arguments, or arguments containing spaces, quote them:</p>
- <pre>
- cfx run --binary-args '-url "www.mozilla.org" -jsconsole'</pre>
+ <pre>cfx run --binary-args '-url "www.mozilla.org" -jsconsole'</pre>
</td>
</tr>
@@ -145,10 +143,19 @@ your add-on alongside debuggers like [Firebug](http://getfirebug.com/).
<code>-p PROFILEDIR, --profiledir=PROFILEDIR</code>
</td>
<td>
- Use an existing
+ <p>Use an existing
<a href="http://support.mozilla.com/en-US/kb/profiles">profile</a>
located in PROFILEDIR. PROFILEDIR may be specified as
- a full path or as a path relative to the current directory.
+ a full path or as a path relative to the current directory.</p>
+
+ <p>You can use this option to create a new profile. Calling:</p>
+ <pre>mkdir /path/to/dir
+cfx run --profiledir /path/to/dir</pre>
+ <p>will create a new profile at <code>/path/to/dir</code>, which would be
+ reused in any subsequent calls to
+ <code>cfx run --profiledir /path/to/dir</code>.</p>
+ <p>The directory must exist, and the path must contain at least one "/"
+ (although you may specify just "./dir").</p>
</td>
</tr>
@@ -280,10 +287,14 @@ To launch the application, enter the following command:
Run available tests for the specified package.
+<span class="aside">Note the hyphen after "test" in the module name.
+`cfx test` will include a module called "test-myCode.js", but will exclude
+modules called "test_myCode.js" or "testMyCode.js".</span>
+
Called with no options this command will look for a file called `package.json`
in the current directory. If `package.json` exists, `cfx` will load the
corresponding add-on and run its tests by loading from the `tests` directory
-any modules that start with the word `test` and calling each of their exported
+any modules that start with the word `test-` and calling each of their exported
functions, passing them a [test runner](packages/api-utils/docs/unit-test.html)
object as an argument.
@@ -323,11 +334,9 @@ times.
<code>-jsconsole</code> argument to Firefox, which will launch the
<a href="https://developer.mozilla.org/en/Error_Console">JavaScript
Error Console</a>, try the following:</p<>
- <pre>
- cfx run --binary-args -jsconsole</pre>
+ <pre>cfx run --binary-args -jsconsole</pre>
<p>To pass multiple arguments, or arguments containing spaces, quote them:</p>
- <pre>
- cfx run --binary-args '-url "www.mozilla.org" -jsconsole'</pre>
+ <pre>cfx run --binary-args '-url "www.mozilla.org" -jsconsole'</pre>
</td>
</tr>
@@ -378,6 +387,15 @@ times.
<a href="http://support.mozilla.com/en-US/kb/profiles">profile</a>
located in PROFILEDIR. PROFILEDIR may be specified as
a full path or as a path relative to the current directory.
+
+ <p>You can use this option to create a new profile. Calling:</p>
+ <pre>mkdir /path/to/dir
+cfx run --profiledir /path/to/dir</pre>
+ <p>will create a new profile at <code>/path/to/dir</code>, which would be
+ reused in any subsequent calls to
+ <code>cfx run --profiledir /path/to/dir</code>.</p>
+ <p>The directory must exist, and the path must contain at least one "/"
+ (although you may specify just "./dir").</p>
</td>
</tr>
View
14 dev-guide-source/addon-development/commonjs.md 100755 → 100644
@@ -16,10 +16,10 @@ CommonJS defines:
module wants to make available to other modules
* a function called `require` which a module can use to import the `exports`
-object of another module. Your translator add-on uses `require` to import the
+object of another module. The "wikipanel" add-on uses `require` to import the
SDK modules it uses.
-![CommonJS modules](static-files/media/commonjs-modules.jpg)
+![CommonJS modules](static-files/media/commonjs-modules.png)
The SDK
[freezes](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/freeze)
@@ -48,6 +48,9 @@ structure `cfx init` created for your add-on.
## CommonJS and the Add-on SDK ##
+<img class="image-right" src="static-files/media/commonjs-wikipanel.png"
+alt="CommonJS wikipanel">
+
* The JavaScript modules which the SDK provides are CommonJS modules, and they
are collected into CommonJS packages.
@@ -59,10 +62,9 @@ CommonJS package, that module will be evaluated as soon as your program is
loaded. For an add-on, that means that the `main` module will be evaluated as
soon as Firefox has enabled the add-on.
-So in terms of CommonJS objects the translator consists of a package that
-contains a single module called `main`, and which imports three SDK modules:
-
-![CommonJS translator](static-files/media/commonjs-translator.jpg)
+So in terms of CommonJS objects the wikipanel add-on consists of a package
+that contains a single module called `main`, and which imports two SDK
+modules.
Because an add-on is a CommonJS package it's possible to include more than one
module in an add-on, and to make your modules available to any code that want
View
0  dev-guide-source/addon-development/console.md 100755 → 100644
File mode changed
View
49 dev-guide-source/addon-development/content-scripts/access.md 100755 → 100644
@@ -65,8 +65,6 @@ But thanks to the content proxy, a content script which calls
tabs.open(data.url("xray.html"));
-You can try out this example [using the builder](https://builder.addons.mozilla.org/addon/1013777/revision/4/).
-
The proxy is transparent to content scripts: as far as the content script
is concerned, it is accessing the DOM directly. But because it's not, some
things that you might expect to work, won't. For example, if the page includes
@@ -75,17 +73,50 @@ adds other objects to any DOM nodes, they won't be visible to the content
script. So to use jQuery you'll typically have to add it as a content script,
as in [this example](dev-guide/addon-development/content-scripts/reddit-example.html).
+### Adding Event Listeners ###
+
+You can listen for DOM events in a content script just as you can in a normal
+page script, but there's one important difference: if you define an event
+listener by passing it as a string into
+[`setAttribute()`](https://developer.mozilla.org/en/DOM/element.setAttribute),
+then the listener is evaluated in the page's context, so it will not have
+access to any variables defined in the content script.
+
+For example, this content script will fail with the error "theMessage is not
+defined":
+
+ var theMessage = "Hello from content script!";
+
+ anElement.setAttribute("onclick", "alert(theMessage);");
+
+So using `setAttribute()` is not recommended. Instead, add a listener by
+assignment to
+[`onclick`](https://developer.mozilla.org/en/DOM/element.onclick) or by using
+[`addEventListener()`](https://developer.mozilla.org/en/DOM/element.addEventListener),
+in either case defining the listener as a function:
+
+ var theMessage = "Hello from content script!";
+
+ anElement.onclick = function() {
+ alert(theMessage);
+ };
+
+ anotherElement.addEventListener("click", function() {
+ alert(theMessage);
+ });
+
+Note that with both `onclick` assignment and `addEventListener()`, you must
+define the listener as a function. It cannot be defined as a string, whether
+in a content script or in a page script.
+
### unsafeWindow ###
If you really need direct access to the underlying DOM, you can use the
global `unsafeWindow` object.
-To see the difference, try editing the
-[example in the builder](https://builder.addons.mozilla.org/addon/1013777/revision/4/)
+To see the difference, try editing the example above
so the content script uses `unsafeWindow.confirm()` instead of
-`window.confirm()` (to edit the example, you'll need to create an account
-with the Add-on Builder and clone the original add-on). Alternatively, try out
-[the example here](https://builder.addons.mozilla.org/addon/1015979/revision/3/).
+`window.confirm()`.
Avoid using `unsafeWindow` if possible: it is the same concept as
Greasemonkey's unsafeWindow, and the
@@ -93,7 +124,6 @@ Greasemonkey's unsafeWindow, and the
here. Also, `unsafeWindow` isn't a supported API, so it could be removed or
changed in a future version of the SDK.
-
## Access to Other Content Scripts ##
Content scripts loaded into the same document can interact
@@ -170,6 +200,3 @@ Content scripts can send it messages using `document.defaultView.postMessage()`:
});
tabs.open(data.url("listener.html"));
-
-You can see this add-on at
-[https://builder.addons.mozilla.org/addon/1013849/revision/8/](https://builder.addons.mozilla.org/addon/1013849/revision/8/).
View
0  dev-guide-source/addon-development/content-scripts/loading.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/content-scripts/reddit-example.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/content-scripts/using-port.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/content-scripts/using-postmessage.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/events.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/getting-started.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/guides.md 100755 → 100644
File mode changed
View
201 dev-guide-source/addon-development/implementing-reusable-module.md 100755 → 100644
@@ -11,199 +11,166 @@ collection of modules. This makes the design of the add-on easier to understand
and provides some encapsulation as each module will export only what it chooses
to, so you can change the internals of the module without breaking its users.
-In this example we'll start with the [translator
+In this example we'll start with the [wikipanel
add-on](dev-guide/addon-development/implementing-simple-addon.html), and create
-a separate module containing the code that performs the translation.
+a separate module containing the code that loads the panel.
-## Implementing "translate.js" ##
+## Implementing "wikipanel.js" ##
-In the `lib` directory under your translator's root, create a new file called
-`translate.js` with the following contents:
+In the `lib` directory under your wikipanel's root, create a new file called
+`wikipanel.js` with the following contents:
- // Import the APIs we need.
- var request = require("request");
+ // Define the 'lookup' function using Panel
+ function lookup(item) {
+ var panel = require("panel").Panel({
+ width: 240,
+ height: 320,
+ contentURL: getURL(item)
+ });
+ panel.show();
+ }
- // Define the 'translate' function using Request
- function translate(text, callback) {
- if (text.length === 0) {
- throw ("Text to translate must not be empty");
+ // Define a function to build the URL
+ function getURL(item) {
+ if (item.length === 0) {
+ throw ("Text to look up must not be empty");
}
- var req = request.Request({
- url: "http://ajax.googleapis.com/ajax/services/language/translate",
- content: {
- v: "1.0",
- q: text,
- langpair: "|en"
- },
- onComplete: function (response) {
- callback(response.json.responseData.translatedText);
- }
- });
- req.get();
+ return "http://en.wikipedia.org/w/index.php?title=" + item + "&useformat=mobile";
}
- // Export the 'translate' function
- exports.translate = translate;
+ // Export the 'lookup' and 'getURL' functions
+ exports.lookup = lookup;
+ exports.getURL = getURL;
+The `lookup()` function here is essentially the same as the `lookup()` in the
+original code.
-The `translate` function here is essentially the same as the listener function
-assigned to `onMessage` in the original code, except that it calls a callback
-with the translation instead of assigning the result directly to the selection.
+Just so we can demonstrate the SDK's unit testing framework, we've also
+split the code that creates the URL into its own trivial `getURL()` function.
-We export the function by adding it to the global `exports` object.
+We export both functions by adding them to the global `exports` object.
## Editing "main.js" ##
-Next we edit `main.js` to make it use our new module rather than the `request`
+Next we edit `main.js` to make it use our new module rather than the `panel`
module:
// Import the APIs we need.
var contextMenu = require("context-menu");
- var selection = require("selection");
- var translate = require("translate");
+ var wikipanel = require("wikipanel");
exports.main = function(options, callbacks) {
console.log(options.loadReason);
// Create a new context menu item.
- var menuItem = contextMenu.Item({
- label: "Translate Selection",
+ var menuItem = contextMenu.Item({
+ label: "What's this?",
// Show this item when a selection exists.
context: contextMenu.SelectionContext(),
- // When this item is clicked, post a message to the item with the
- // selected text and current URL.
+ // When this item is clicked, post a message back with the selection
contentScript: 'self.on("click", function () {' +
' var text = window.getSelection().toString();' +
' self.postMessage(text);' +
'});',
-
- // When we receive the message, call the translator with the
- // selected text and replace it with the translation.
- onMessage: function (text) {
- translate.translate(text, function(translation) {
- selection.text = translation; })
+ // When we receive a message, look up the item
+ onMessage: function (item) {
+ console.log('looking up "' + item + '"');
+ wikipanel.lookup(item);
}
});
};
- exports.onUnload = function (reason) {
- console.log(reason);
- };
-
-
Next, execute `cfx run` again, and try out the add-on. It should work in
exactly the same way as the previous version, except that now the core
-translate function has been made available to other parts of your add-on or
-to *any other program* that imports it.
+`lookup()` function has been made available to other parts of your add-on or
+to any other module that imports it.
## Testing Your Module ##
The SDK provides a framework to help test any modules you develop. To
-demonstrate this we will add some slightly unlikely tests for the translator
-module.
+demonstrate this we will add a test for the `getURL` function.
Navigate to the `test` directory and delete the `test-main.js` file. In its
-place create a file called `test-translate.js` with the following contents:
+place create a file called `test-wikipanel.js` with the following contents:
- var translate = require("translator/translate")
- var testRunner;
- var remainingTests;
+ var wikipanel = require("wikipanel/wikipanel")
- function check_translation(translation) {
- testRunner.assertEqual("Lizard", translation);
- testRunner.done();
- }
-
- function test_languages(test, text) {
- testRunner= test;
- testRunner.waitUntilDone(2000);
- translate.translate(text, check_translation);
- }
+ var referenceURL =
+ "http://en.wikipedia.org/w/index.php?title=Mozilla&useformat=mobile";
- exports.test_german = function(test) {
- test_languages(test, "Eidechse");
+ function test_getURL(test) {
+ test.assertEqual(wikipanel.getURL("Mozilla"), referenceURL);
+ test.done();
}
- exports.test_italian = function(test) {
- test_languages(test, "Lucertola");
- }
-
- exports.test_finnish = function(test) {
- test_languages(test, "Lisko");
- }
-
- exports.test_error = function(test) {
+ function test_empty_string(test) {
test.assertRaises(function() {
- translate.translate("", check_translation);
+ wikipanel.getURL("");
},
- "Text to translate must not be empty");
+ "Text to look up must not be empty");
};
-This file exports four functions, each of which expects to receive a single
+ exports.test_getURL = test_getURL;
+ exports.test_empty_string = test_empty_string;
+
+This file:
+
+* exports two functions, each of which expects to receive a single
argument which is a `test` object. `test` is supplied by the
[`unit-test`](packages/api-utils/docs/unit-test.html) module and provides
-functions to simplify unit testing. The file imports one module, the
-`translate` module that lives in our `translator` package. The
-`PACKAGE/MODULE` syntax lets you identify a specific module in a specific
-package, rather than searching all available packages (using, for example,
-`require("request")`). The
+functions to simplify unit testing.
+The first function calls `getURL()` and uses [`test.assertEqual()`](packages/api-utils/docs/unit-test.html#assertEqual(a, b, message))
+to check that the URL is as expected.
+The second function tests the wikipanel's error-handling code by passing an
+empty string into `getURL()` and using
+[`test.assertRaises()`](packages/api-utils/docs/unit-test.html#assertRaises(func%2C predicate%2C message))
+to check that the expected exception is raised.
+
+* imports one module, the `wikipanel` module that lives in our
+`wikipanel` package. The `PACKAGE/MODULE` ("wikipanel/wikipanel") syntax lets
+you identify a specific module in a specific package, rather than searching
+all available packages (using, for example, `require("request")`). The
[module-search](dev-guide/addon-development/module-search.html) documentation
-has more detail.
-
-<span class="aside">
-`waitUntilDone()` and `done()` are needed here because the translator is
-asynchronous. To test an asynchronous function (a function that completes
-using a callback, rather than a return value), you call `test.waitUntilDone(),`
-supplying a delay time in milliseconds long enough for the function to
-complete. You put the test assertion in the callback, then call `test.done()`
-to signal that the test has finished.
-</span>
-
-The first three functions call `translate` and in the callback use
-`test.assertEqual()` to check that the translation is as expected.
-
-The fourth function tests the translator's error-handling code by passing an
-empty string into `translate` and using `test.assertRaises()` to check that the
-expected exception is raised.
+has more detail on this.
At this point your package ought to look like this:
<pre>
- /translator
+ /wikipanel
package.json
README.md
/doc
main.md
/lib
main.js
- translate.js
+ wikipanel.js
/test
- test-translate.js
+ test-wikipanel.js
</pre>
Now execute `cfx --verbose test` from under the package root directory.
You should see something like this:
<pre>
- Running tests on Firefox 4.0.1/Gecko 2.0.1 ...
- info: executing 'test-translate.test_german'
- info: pass: a == b == "Lizard"
- info: executing 'test-translate.test_italian'
- info: pass: a == b == "Lizard"
- info: executing 'test-translate.test_finnish'
- info: pass: a == b == "Lizard"
- info: executing 'test-translate.test_error'
- info: pass: a == b == "Text to translate must not be empty"
- 4 of 4 tests passed.
- OK
+Running tests on Firefox 7.0.1/Gecko 7.0.1 ({ec8030f7-c20a-464f-9b0e-13a3a9e97384}) under Darwin/x86_64-gcc3.
+info: executing 'test-wikipanel.test_empty_string'
+info: pass: a == b == "Text to look up must not be empty"
+info: executing 'test-wikipanel.test_getURL'
+info: pass: a == b == "http://en.wikipedia.org/w/index.php?title=Mozilla&useformat=mobile"
+
+2 of 2 tests passed.
+OK
</pre>
What happens here is that `cfx test`:
+<span class="aside">Note the hyphen after "test" in the module name.
+`cfx test` will include a module called "test-myCode.js", but will exclude
+modules called "test_myCode.js" or "testMyCode.js".</span>
+
* looks in the `test` directory of your
package
-
-* loads any modules that start with the word `test`
+* loads any modules whose names start with the word `test-`
* calls all their exported functions, passing them a `test` object
implementation as their only argument.
View
146 dev-guide-source/addon-development/implementing-simple-addon.md 100755 → 100644
@@ -2,12 +2,13 @@
This section of the tutorial takes you through the process of implementing,
running and packaging a simple add-on using the SDK. The add-on will add a
-menu item to Firefox's context menu that replaces selected text with its
-English translation.
+menu item to Firefox's context menu, to appear when anything in the page
+is selected. The menu item displays a popup dialog containing the
+Wikipedia entry for the selected text.
## Initializing Your Add-on ##
-Create a directory called `translator`. This is where we will keep all the
+Create a directory called `wikipanel`. This is where we will keep all the
files for this add-on.
You *do not* have to create this directory under the SDK root: once you have
@@ -19,7 +20,7 @@ for you to update the SDK and to manage your code using a version control
system.
Next we'll use `cfx init` to create a skeleton structure for your add-on.
-Navigate to the `translator` directory and execute `cfx init`. You should see
+Navigate to the `wikipanel` directory and execute `cfx init`. You should see
something like this:
<pre>
@@ -61,14 +62,14 @@ Add-on SDK's [`self`](packages/addon-kit/docs/self.html) module.
* `/test` contains unit test code.
-Next, `cfx init` creates a file called `package.json` in the root `translator`
+Next, `cfx init` creates a file called `package.json` in the root `wikipanel`
directory. This contains information about your add-on and should look
something like this:
<pre>
{
- "name":"translator",
- "fullName":"translator",
+ "name":"wikipanel",
+ "fullName":"wikipanel",
"description":"This is an example of addon description.",
"author":"",
"license":"MPL",
@@ -86,84 +87,64 @@ contents with the following:
// Import the APIs we need.
var contextMenu = require("context-menu");
- var request = require("request");
- var selection = require("selection");
+ var panel = require("panel");
exports.main = function(options, callbacks) {
console.log(options.loadReason);
// Create a new context menu item.
var menuItem = contextMenu.Item({
-
- label: "Translate Selection",
-
+ label: "What's this?",
// Show this item when a selection exists.
-
context: contextMenu.SelectionContext(),
-
- // When this item is clicked, post a message to the item with the
- // selected text and current URL.
+ // When this item is clicked, post a message back with the selection
contentScript: 'self.on("click", function () {' +
' var text = window.getSelection().toString();' +
' self.postMessage(text);' +
'});',
-
- // When we receive the message, call the Google Translate API with the
- // selected text and replace it with the translation.
- onMessage: function (text) {
- if (text.length === 0) {
- throw ("Text to translate must not be empty");
- }
- console.log("input: " + text);
- var req = request.Request({
- url: "http://ajax.googleapis.com/ajax/services/language/translate",
- content: {
- v: "1.0",
- q: text,
- langpair: "|en"
- },
- onComplete: function (response) {
- translated = response.json.responseData.translatedText;
- console.log("output: " + translated);
- selection.text = translated;
- }
- });
- req.get();
+ // When we receive a message, look up the item
+ onMessage: function (item) {
+ console.log('looking up "' + item + '"');
+ lookup(item);
}
});
};
- exports.onUnload = function (reason) {
- console.log(reason);
- };
-
+ function lookup(item) {
+ wikipanel = panel.Panel({
+ width: 240,
+ height: 320,
+ contentURL: "http://en.wikipedia.org/w/index.php?title=" +
+ item + "&useformat=mobile"
+ });
+ wikipanel.show();
+ }
### Importing Modules ###
-The first three lines are used to import three SDK modules from the
+The first two lines are used to import two SDK modules from the
addon-kit package:
* [`context-menu`](packages/addon-kit/docs/context-menu.html) enables add-ons
to add new items to the context menu
-* [`request`](packages/addon-kit/docs/request.html) enables add-ons to make
-network requests
-* [`selection`](packages/addon-kit/docs/selection.html) gives add-ons access
-to selected text in the active browser window
+* [`panel`](packages/addon-kit/docs/panel.html) enables add-ons to display
+popup windows
### Creating a Context Menu Item ###
Next, this code constructs a context menu item. It supplies:
-* the name of the item to display: "Translate Selection"
+* the text to appear in the menu: "What's this?"
* a context in which the item should be displayed: `SelectionContext()`,
meaning: include this item in the context menu whenever some content on the
page is selected
* a script to execute when the item is clicked: this script sends the selected
text to the function assigned to the `onMessage` property
* a value for the `onMessage` property: this function will now be called with
-the selected text, whenever the user clicks the menu. It uses Google's
-AJAX-based translation service to translate the selection to English and sets
-the selection to the translated text.
+the selected text, whenever the user clicks the menu.
+
+The supplied function loads the Wikipedia entry for the selection into a
+panel.
### Listening for Load and Unload ###
@@ -199,8 +180,8 @@ your add-on's code at the top level instead of wrapping it in a function
assigned to `exports.main`: it will be loaded in the same circumstances, but
you won't get access to the `options` or `callbacks` arguments.
-This particular add-on doesn't need to use `exports.main` or `exports.onUnload`
-for anything, and only includes them to illustrate their use.
+This particular add-on doesn't need to use `exports.main` for anything, and
+only includes it to illustrate its use.
### Logging ###
@@ -220,7 +201,7 @@ For more information on the `console` object see its
## Running It ##
-To run your program, navigate to the `translator` directory and type:
+To run your program, navigate to the `wikipanel` directory and type:
<pre>
cfx run
@@ -233,44 +214,33 @@ The first time you do this, you'll see a message like this:
package.json modified: please re-run 'cfx run'
</pre>
-Run it again, and it will run an instance of Firefox with your add-on
-installed.
-
+<span class="aside">
The ID that `cfx` generated the first time you executed `cfx run` is a unique
-identifier for you add-on called the **Program ID** and it is important. It is
-used by various tools and services to distinguish this add-on from any other.
-
-To learn more about the Program ID refer to the
+identifier for your add-on. To learn more about it refer to the
[Program ID](dev-guide/addon-development/program-id.html) document.
+</span>
+
+Run it again, and it will run an instance of Firefox with your add-on
+installed.
Once `cfx run` has launched Firefox you can try out the new add-on. Load a
page containing some text that is not in English, for example:
[http://www.mozilla.org/about/manifesto.fr.html](http://www.mozilla.org/about/manifesto.fr.html)
Select some text on that page and right-click to activate the context menu.
-You should see a new item labeled "Translate Selection":
+You should see a new item labeled "What's this?":
-![translator context-menu](static-files/media/screenshots/translator/context-menu-osx.png)
+![wikipanel context-menu](static-files/media/screenshots/wikipanel/wikipanel-context-menu.png)
-Select that item and the text you selected should be replaced with its English
-translation:
+Select that item and you'll see a popup panel showing the Wikipedia entry for
+the selection:
-![translator context-menu](static-files/media/screenshots/translator/translated-osx.png)
+![wikipanel panel](static-files/media/screenshots/wikipanel/wikipanel-panel.png)
You will also see output like this appear in your command shell:
<pre>
- info: input: Le projet Mozilla est une communauté mondiale de personnes
- qui pensent que l'ouverture, l'innovation et la saisie des chances qui nous
- sont offertes sont les clés de la vitalité d'Internet. Nous travaillons
- ensemble depuis 1998 pour nous assurer qu'Internet se développe d'une manière
- qui bénéficie à tout le monde. On nous connaît surtout pour la création du
- navigateur Web Mozilla Firefox.
- info: output: The Mozilla project is a global community of people who believe
- that openness, innovation and seizing opportunities offered to us are the
- keys to the vitality of the Internet. We have been working together since
- 1998 to ensure that the Internet develops in a way that benefits everyone.
- We are best known for creating the Mozilla Firefox Web browser.
+ info: looking up "Jetpack"
</pre>
## Preparing Your Add-on for Deployment ##
@@ -279,14 +249,28 @@ Once you have finished testing your add-on you can package it for deployment
like any other Firefox add-on, as a XPI file. The Add-on SDK simplifies the
packaging process by generating this file for you.
+### Specifying an Icon ###
+
+You can specify an icon for your add-on. This icon will appear beside your
+add-on in Firefox's Add-ons Manager and on
+[addons.mozilla.org](https://addons.mozilla.org/en-US/firefox/).
+
+To specify an icon, save it as "icon.png" in your add-on's root directory. To
+give the icon a different name or to store it in a different location
+under the root, use the "icon" key in your `package.json` file. See the
+[Package Specification](file:///Users/Work/mozilla/jetpack-sdk/doc/dev-guide/addon-development/package-spec.html)
+for more details.
+
+### cfx xpi ###
+
To package your program as a XPI, navigate to the root of your package
-directory in your shell and run `cfx xpi`. You should see a message:
+directory in your shell and run `cfx xpi`. You should see a message like:
<pre>
- Exporting extension to translator.xpi.
+ Exporting extension to wikipanel.xpi.
</pre>
-The `translator.xpi` file can be found in the directory in which you ran
+The `wikipanel.xpi` file can be found in the directory in which you ran
the command.
## Installing the Package ##
@@ -296,7 +280,7 @@ installation.
You can do this by pressing the Ctrl+O key combination (Cmd+O on Mac) from
within Firefox. This will bring up a file selection dialog: navigate to the
-`translator.xpi` file, open it and follow the prompts to install the
+`wikipanel.xpi` file, open it and follow the prompts to install the
add-on.
Alternatively:
View
53 dev-guide-source/addon-development/installation.md 100755 → 100644
@@ -9,7 +9,7 @@ To develop with the Add-on SDK, you'll need:
* Firefox version 4.0 or later.
-At the moment, the latest stable version of the Add-on SDK is 1.2.1.
+At the moment, the latest stable version of the Add-on SDK is 1.3.
You can obtain it as a
[tarball](https://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/jetpack-sdk-latest.tar.gz)
or a [zip file](https://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/jetpack-sdk-latest.zip).
@@ -22,22 +22,21 @@ Extract the file contents wherever you choose, and navigate to the root
directory of the SDK with a shell/command prompt. For example:
<pre>
- ~/mozilla > tar -xf addon-sdk-1.2.1.tar.gz
- ~/mozilla > cd addon-sdk-1.2.1
- ~/mozilla/addon-sdk-1.2.1 >
+ tar -xf addon-sdk-1.3.tar.gz
+ cd addon-sdk-1.3
</pre>
Then run:
<pre>
- ~/mozilla/addon-sdk-1.2.1 > source bin/activate
+ source bin/activate
</pre>
Your command prompt should now have a new prefix containing the name of the
SDK's root directory:
<pre>
- (addon-sdk-1.2.1)~/mozilla/addon-sdk-1.2.1 >
+ (addon-sdk-1.3)~/mozilla/addon-sdk-1.3 >
</pre>
## Installation on Windows ##
@@ -46,15 +45,14 @@ Extract the file contents wherever you choose, and navigate to the root
directory of the SDK with a shell/command prompt. For example:
<pre>
- C:\Users\mozilla\sdk>7z.exe x addon-sdk-1.2.1.zip
- C:\Users\mozilla\sdk>cd addon-sdk-1.2.1
- C:\Users\mozilla\sdk\addon-sdk-1.2.1>
+ 7z.exe x addon-sdk-1.3.zip
+ cd addon-sdk-1.3
</pre>
Then run:
<pre>
- C:\Users\mozilla\sdk\addon-sdk-1.2.1>bin\activate
+ bin\activate
</pre>
You might see an error like this:
@@ -71,7 +69,7 @@ Your command prompt should now have a new prefix containing the full path to
the SDK's root directory:
<pre>
- (C:\Users\mozilla\sdk\addon-sdk-1.2.1) C:\Users\Work\sdk\addon-sdk-1.2.1>
+ (C:\Users\mozilla\sdk\addon-sdk-1.3) C:\Users\Work\sdk\addon-sdk-1.3>
</pre>
## SDK Virtual Environment ##
@@ -92,12 +90,43 @@ You can have multiple copies of the SDK in different locations on disk and
switch between them, or even have them both activated in different command
prompts at the same time.
+### Making `activate` Permanent ###
+
+All `activate` does is to set a number of environment variables for the
+current command prompt, using a script located in the top-level `bin`
+directory. By setting these variables permanently in your environment so
+every new command prompt reads them, you can make activation permanent. Then
+you don't need to type `activate` every time you open up a new command prompt.
+
+Because the exact set of variables may change with new releases of the SDK,
+it's best to refer to the activation scripts to determine which variables need
+to be set. Activation uses different scripts and sets different variables for
+bash environments (Linux and Mac OS X) and for Windows environments.
+
+#### Windows ####
+
+On Windows, `bin\activate` uses `activate.bat`, and you can make activation
+permanent using the command line `setx` tool or the Control Panel.
+
+#### Linux/Mac OS X ####
+
+On Linux and Mac OS X, `source bin/activate` uses the `activate` bash
+script, and you can make activation permanent using your `~/.bashrc`
+(on Linux) or `~/.bashprofile` (on Mac OS X).
+
+As an alternative to this, you can create a symbolic link to the `cfx`
+program in your `~/bin` directory:
+
+<pre>
+ ln -s PATH_TO_SDK/bin/cfx ~/bin/cfx
+</pre>
+
## Sanity Check ##
Run this at your shell prompt:
<pre>
- ~/mozilla/addon-sdk-1.2.1 > cfx
+ ~/mozilla/addon-sdk-1.3 > cfx
</pre>
It should produce output whose first line looks something like this, followed by
View
215 dev-guide-source/addon-development/library-detector.md
@@ -0,0 +1,215 @@
+# Porting the Library Detector #
+
+This example walks through the process of porting a XUL-based add-on to the
+SDK. It's a very simple add-on and a good candidate for porting because
+there are suitable SDK APIs for all its features.
+
+<img class="image-right" src="static-files/media/librarydetector/library-detector.png" alt="Library Detector Screenshot" />
+
+The add-on is Paul Bakaus's
+[Library Detector](https://addons.mozilla.org/en-US/firefox/addon/library-detector/).
+
+The Library Detector tells you which JavaScript frameworks the current
+web page is using. It does this by checking whether particular objects
+that those libraries add to the global window object are defined.
+For example, if `window.jQuery` is defined, then the page has loaded
+[jQuery](http://jquery.com/).
+
+For each library that it finds, the library detector adds an icon
+representing that library to the status bar. It adds a tooltip to each
+icon, which contains the library name and version.
+
+You can browse and run the ported version in the SDK's `examples` directory.
+
+### How the Library Detector Works ###
+
+All the work is done inside a single file,
+[`librarydetector.xul`](http://code.google.com/p/librarydetector/source/browse/trunk/chrome/content/librarydetector.xul)
+This contains:
+
+<ul>
+ <li>a XUL overlay</li>
+ <li>a script</li>
+</ul>
+
+The XUL overlay adds a `box` element to the browser's status bar:
+
+<script type="syntaxhighlighter" class="brush: html"><![CDATA[
+ &lt;statusbar id="status-bar"&gt; &lt;box orient="horizontal" id="librarydetector"&gt; &lt;/box&gt; &lt;/statusbar&gt;
+]]>
+</script>
+
+The script does everything else.
+
+The bulk of the script is an array of test objects, one for each library.
+Each test object contains a function called `test()`: if the
+function finds the library, it defines various additional properties for
+the test object, such as a `version` property containing the library version.
+Each test also contains a `chrome://` URL pointing to the icon associated with
+its library.
+
+The script listens to [gBrowser](https://developer.mozilla.org/en/Code_snippets/Tabbed_browser)'s
+`DOMContentLoaded` event. When this is triggered, the `testLibraries()`
+function builds an array of libraries by iterating through the tests and
+adding an entry for each library which passes.
+
+Once the list is built, the `switchLibraries()` function constructs a XUL
+`statusbarpanel` element for each library it found, populates it with the
+icon at the corresponding `chrome://` URL, and adds it to the box.
+
+Finally, it listens to gBrowser's `TabSelect` event, to update the contents
+of the box for that window.
+
+### Content Script Separation ###
+
+The test objects in the original script need access to the DOM window object,
+so in the SDK port, they need to run in a content script. In fact, they need
+access to the un-proxied DOM window, so they can see the objects added by
+libraries, so we’ll need to use the experimental
+[unsafeWindow](dev-guide/addon-development/content-scripts/access.html) object.
+
+The main add-on script, `main.js`, will use a
+[`page-mod`](packages/addon-kit/docs/page-mod.html)
+to inject the content script into every new page.
+
+The content script, which we'll call `library-detector.js`, will keep most of
+the logic of the `test` functions intact. However, instead of maintaining its
+own state by listening for `gBrowser` events and updating the
+user interface, the content script will just run when it's loaded, collect
+the array of library names, and post it back to `main.js`:
+
+ function testLibraries() {
+ var win = unsafeWindow;
+ var libraryList = [];
+ for(var i in LD_tests) {
+ var passed = LD_tests[i].test(win);
+ if (passed) {
+ var libraryInfo = {
+ name: i,
+ version: passed.version
+ };
+ libraryList.push(libraryInfo);
+ }
+ }
+ self.postMessage(libraryList);
+ }
+
+ testLibraries();
+
+`main.js` responds to that message by fetching the tab
+corresponding to that worker using
+[`worker.tab`](packages/api-utils/docs/content/worker.html#tab), and adding
+the array of library names to that tab's `libraries` property:
+
+ pageMod.PageMod({
+ include: "*",
+ contentScriptWhen: 'end',
+ contentScriptFile: (data.url('library-detector.js')),
+ onAttach: function(worker) {
+ worker.on('message', function(libraryList) {
+ if (!worker.tab.libraries) {
+ worker.tab.libraries = [];
+ }
+ libraryList.forEach(function(library) {
+ if (worker.tab.libraries.indexOf(library) == -1) {
+ worker.tab.libraries.push(library);
+ }
+ });
+ if (worker.tab == tabs.activeTab) {
+ updateWidgetView(worker.tab);
+ }
+ });
+ }
+ });
+
+The content script is executed once for every `window.onload` event, so
+it will run multiple times when a single page containing multiple iframes
+is loaded. So `main.js` needs to filter out any duplicates, in case
+a page contains more than one iframe, and those iframes use the same library.
+
+### Implementing the User Interface ###
+
+#### Showing the Library Array ####
+
+The [`widget`](packages/addon-kit/docs/widget.html) module is a natural fit
+for displaying the library list. We'll specify its content using HTML, so we
+can display an array of icons. The widget must be able to display different
+content for different windows, so we'll use the
+[`WidgetView`](packages/addon-kit/docs/widget.html) object.
+
+`main.js` will create an array of icons corresponding to the array of library
+names, and use that to build the widget's HTML content dynamically:
+
+ function buildWidgetViewContent(libraryList) {
+ widgetContent = htmlContentPreamble;
+ libraryList.forEach(function(library) {
+ widgetContent += buildIconHtml(icons[library.name],
+ library.name + "<br>Version: " + library.version);
+ });
+ widgetContent += htmlContentPostamble;
+ return widgetContent;
+ }
+
+ function updateWidgetView(tab) {
+ var widgetView = widget.getView(tab.window);
+ if (!tab.libraries) {
+ tab.libraries = [];
+ }
+ widgetView.content = buildWidgetViewContent(tab.libraries);
+ widgetView.width = tab.libraries.length * ICON_WIDTH;
+ }
+
+`main.js` will
+use the [`tabs`](packages/addon-kit/docs/tabs.html) module to update the
+widget's content when necessary (for example, when the user switches between
+tabs):
+
+ tabs.on('activate', function(tab) {
+ updateWidgetView(tab);
+ });
+
+ tabs.on('ready', function(tab) {
+ tab.libraries = [];
+ });
+
+#### Showing the Library Detail ####
+
+The XUL library detector displayed the detailed information about each
+library on mouseover in a tooltip: we can't do this using a widget, so
+instead will use a panel. This means we'll need two additional content
+scripts:
+
+* one in the widget's context, which listens for icon mouseover events
+and sends a message to `main.js` containing the name of the corresponding
+library:
+
+<pre><code>
+function setLibraryInfo(element) {
+ self.port.emit('setLibraryInfo', element.target.title);
+}
+
+var elements = document.getElementsByTagName('img');
+
+for (var i = 0; i &lt; elements.length; i++) {
+ elements[i].addEventListener('mouseover', setLibraryInfo, false);
+}
+</code></pre>
+
+* one in the panel, which updates the panel's content with the library
+information:
+
+<pre><code>
+self.on("message", function(libraryInfo) {
+ window.document.body.innerHTML = libraryInfo;
+});
+</code></pre>
+
+Finally `main.js` relays the library information from the widget to the panel:
+
+<pre><code>
+widget.port.on('setLibraryInfo', function(libraryInfo) {
+ widget.panel.postMessage(libraryInfo);
+});
+</code></pre>
+
+<img class="image-center" src="static-files/media/librarydetector/panel-content.png" alt="Updating panel content" />
View
0  dev-guide-source/addon-development/module-search.md 100755 → 100644
File mode changed
View
16 dev-guide-source/addon-development/package-spec.md 100755 → 100644
@@ -36,20 +36,26 @@ called `package.json`. This file is also referred to as the
PNG file containing the icon for the package. By default, this
is `icon.png`. If the package is built as an XPI, this is used
as the add-on's icon to display in the Add-on Manager's add-ons list.
+ This key maps on to the
+ [`iconURL` entry in the Install Manifest](https://developer.mozilla.org/en/install_manifests#iconURL),
+ so the icon may be up to 48x48 pixels in size.
* `icon64` - the relative path from the root of the package to a
PNG file containing the icon64 for the package. By default, this
is `icon64.png`. If the package is built as an XPI, this is used
as the add-on's icon to display in the Addon Manager's add-on details view.
+ This key maps on to the
+ [`icon64URL` entry in the Install Manifest](https://developer.mozilla.org/en/install_manifests#icon64URL),
+ so the icon should be 64x64 pixels in size.
+
* `license` - the name of the license as a String, with an optional
URL in parentheses.
-* `id` - a globally unique identifier for the package, a String
- derived from the public half of a private/public keypair, generated
- the first time you run `cfx xpi`. When the package is built as an
- XPI, this is used as the add-on's `em:id` element in its
- `install.rdf`.
+* `id` - a globally unique identifier for the package. When the package is
+ built as an XPI, this is used as the add-on's `em:id` element in its
+ `install.rdf`. See the
+ [Program ID page](dev-guide/addon-development/program-id.html).
* `version` - a String representing the version of the package. If the
package is ever built as an XPI, this is used as the add-on's
View
27 dev-guide-source/addon-development/program-id.md 100755 → 100644
@@ -1,12 +1,29 @@
# The Program ID #
-The Program ID is a unique identifier for your add-on and is used for a variety
+The Program ID is a unique identifier for your add-on. When you package your
+add-on for distribution using `cfx xpi`, it will become the
+[ID field in the add-on's Install Manifest](https://developer.mozilla.org/en/install.rdf#id).
+
+The ID is used for a variety
of purposes. For example: [addons.mozilla.org](http://addons.mozilla.org) uses
it to distinguish between new add-ons and updates to existing add-ons, and the
[`simple-storage`](packages/addon-kit/docs/simple-storage.html) module uses it
to figure out which stored data belongs to which add-on.
-The program ID is a randomly-generated string, embedded in `package.json` as
-the `id` property. If your `package.json` does not already have an `id` when
-you run `cfx xpi`, it will generate one for you and then ask you to run `cfx
-xpi` again.
+It is read from the `id` key in your add-on's [`package.json`](dev-guide/addon-development/package-spec.html) file.
+`cfx init` does not create this key, so if you don't set it yourself, the
+first time you execute `cfx run` or `cfx xpi`, then `cfx` will create an
+ID for you, and will show a message like this:
+
+<pre>
+ No 'id' in package.json: creating a new ID for you.
+ package.json modified: please re-run 'cfx run'
+</pre>
+
+The ID generated by `cfx` in this way is a randomly-generated string, but
+you can define your own ID by editing the `package.json` file
+directly. In particular, you can use the `extensionname@example.org` format
+described in the
+[Install Manifest documentation](https://developer.mozilla.org/en/install.rdf#id).
+However, you can't use the
+[GUID-style](https://developer.mozilla.org/en/Generating_GUIDs) format.
View
0  dev-guide-source/addon-development/reference.md 100755 → 100644
File mode changed
View
104 dev-guide-source/addon-development/sdk-vs-xul.md
@@ -0,0 +1,104 @@
+
+# SDK and XUL Comparison #
+
+## Advantages of the SDK ##
+
+<table>
+<colgroup>
+<col width="20%">
+<col width="80%">
+</colgroup>
+
+<tr>
+<td> <strong><a name="simplicity">Simplicity</a></strong></td>
+<td><p>The SDK provides high-level JavaScript APIs to simplify many
+common tasks in add-on development, and tool support which greatly simplifies
+the process of developing, testing, and packaging an add-on.</p>
+</td>
+</tr>
+
+<tr>
+<td> <strong><a name="compatibility">Compatibility</a></strong></td>
+<td><p>Although we can't promise we'll never break a
+<a href="packages/addon-kit/addon-kit.html">supported API</a>,
+maintaining compatibility across Firefox versions is a top priority for us.</p>
+<p>We've designed the APIs to be forward-compatible with the new
+<a href="https://wiki.mozilla.org/Electrolysis/Firefox">multiple process architecture</a>
+(codenamed Electrolysis) planned for Firefox.</p>
+<p>We also expect to support both desktop and mobile Firefox using a single
+edition of the SDK: so you'll be able to write one extension and have it work
+on both products.</p></td>
+</tr>
+
+<tr>
+<td> <strong><a name="security">Security</a></strong></td>
+<td><p>If they're not carefully designed, Firefox add-ons can open the browser
+to attack by malicious web pages. Although it's possible to write insecure
+add-ons using the SDK, it's not as easy, and the damage that a compromised
+add-on can do is usually more limited.</p></td>
+</tr>
+
+<tr>
+<td> <strong><a name="restartlessness">Restartlessness</a></strong></td>
+<td><p>Add-ons built with the SDK are can be installed without having
+to restart Firefox.</p>
+<p>Although you can write
+<a href="https://developer.mozilla.org/en/Extensions/Bootstrapped_extensions">
+traditional add-ons that are restartless</a>, you can't use XUL overlays in
+them, so most traditional add-ons would have to be substantially rewritten
+anyway.</p></td>
+</tr>
+
+<tr>
+<td> <strong><a name="ux_best_practice">User Experience Best Practices</a></strong></td>
+<td><p>The UI components available in the SDK are designed to align with the usability
+guidelines for Firefox, giving your users a better, more consistent experience.</p></td>
+</tr>
+
+</table>
+
+## Advantages of XUL-based Add-ons ##
+
+<table>
+<colgroup>
+<col width="20%">
+<col width="80%">
+</colgroup>
+<tr>
+<td><strong><a name="ui_flexibility">User interface flexibility</a></strong></td>
+<td><p>XUL overlays offer a great deal of options for building a UI and
+integrating it into the browser. Using only the SDK's supported APIs you have
+much more limited options for your UI.</p></td>
+</tr>
+
+<tr>
+<td><strong><a name="xpcom_access">XPCOM</a></strong></td>
+<td><p>Traditional add-ons have access to a vast amount of Firefox
+functionality via XPCOM. The SDK's supported APIs expose a relatively
+small set of this functionality.</p></td>
+</tr>
+
+<tr>
+<td><strong><a name="localization">Localization Support</a></strong></td>
+<td><p>The SDK doesn't yet support localization, although this is
+<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=691782">coming soon</a>.
+</p></td>
+</tr>
+
+</table>
+
+### Low-level APIs and Third-party Modules ###
+
+That's not the whole story. If you need more flexibility than the SDK's
+["supported" APIs](packages/addon-kit/addon-kit.html) provide, you can
+use its ["low-level" APIs](packages/api-utils/api-utils.html) to load
+XPCOM objects directly or to manipulate the DOM directly as in a
+traditional
+<a href="https://developer.mozilla.org/en/Extensions/Bootstrapped_extensions">bootstrapped extension</a>.
+
+Alternatively, you can load third-party modules, which extend the SDK's
+core APIs.
+
+Note that by doing this you lose some of the benefits of programming
+with the SDK including simplicity, compatibility, and to a lesser extent
+security.
View
136 dev-guide-source/addon-development/third-party-packages.md
@@ -0,0 +1,136 @@
+# Third Party Packages #
+
+The SDK APIs are implemented by modules, which are collected into packages
+such as [`addon-kit`](packages/addon-kit/addon-kit.html) and
+[`api-utils`](packages/api-utils/api-utils.html). The packages are kept
+in the "packages" directory under the SDK root:
+
+<pre>
+ls -C -1 ~/addon-sdk/packages/
+ addon-kit
+ api-utils
+ development-mode
+ test-harness
+</pre>
+
+The SDK is extensible by design: any developer can build their own modules
+which fill gaps in the SDK's supported APIs, and package them up for
+distribution. Add-on developers can download these packages and use the
+modules they contain in exactly the same way they use the modules in
+built-in packages like `addon-kit` and `api-utils`.
+
+To start using third party packages involves the following steps:
+
+* find a third party package that does what you want
+* copy it into the "packages" directory, along with any packages it depends on
+* declare your dependency on the package by adding the `dependencies` entry in
+your add-on's [`package.json`](dev-guide/addon-development/package-spec.html)
+
+After that you can `require()` modules in the package and use their APIs in
+exactly the same way that you do with the built-in packages.
+
+In this tutorial we'll go through this process, using Erik Vold's
+[`menuitems`](https://github.com/erikvold/menuitems-jplib) package to add a
+menu item to Firefox's Tools menu.
+
+## Installing `menuitems` ##
+
+First we'll download `menuitems` from
+[https://github.com/erikvold/menuitems-jplib](https://github.com/erikvold/menuitems-jplib/zipball/51080383cbb0fe2a05f8992a8aae890f4c014176).
+Like [`addon-kit`](packages/addon-kit/addon-kit.html) and
+[`api-utils`](packages/api-utils/api-utils.html), it's a
+[CommonJS package](dev-guide/addon-development/commonjs.html),
+so we'll extract it under the SDK's `packages` directory:
+
+<pre>
+cd packages
+tar -xf ../erikvold-menuitems-jplib-d80630c.zip
+</pre>
+
+Now if you run `cfx docs` you'll see the `menuitems` package appearing
+in the sidebar below `addon-kit`. As with `addon-kit`, the modules it contains
+are listed below it: you'll see that `menuitems` contains a single module, also
+called `menuitems`.
+
+Click on the module name and you'll see API documentation for the module. Click
+on the package name and you'll see basic information about the package.
+
+One important entry in the package page lists the package's dependencies:
+
+<pre>
+Dependencies api-utils, vold-utils
+</pre>
+
+This tells us that we need to install the `vold-utils` package,
+which we can do by downloading it from [its source repository](https://github.com/erikvold/vold-utils-jplib)
+and adding it under the `packages` directory alongside `menuitems`.
+
+## Using `menuitems` ##
+
+We can use the `menuitems` module in exactly the same way we use built-in
+modules.
+
+The documentation for the `menuitems` module tells us to we create a menu
+item using `MenuItem()`. Of the options accepted by `MenuItem()`, we'll use
+this minimal set:
+
+* `id`: identifier for this menu item
+* `label`: text the item displays
+* `command`: function called when the user selects the item
+* `menuid`: identifier for the item's parent element
+* `insertbefore`: identifier for the item before which we want our item to
+appear
+
+Next, create a new add-on. Make a directory called 'clickme' wherever you
+like, navigate to it and run `cfx init`. Open `lib/main.js` and replace its contents
+with this:
+
+ var menuitem = require("menuitems").Menuitem({
+ id: "clickme",
+ menuid: "menu_ToolsPopup",
+ label: "Click Me!",
+ onCommand: function() {
+ console.log("clicked");
+ },
+ insertbefore: "menu_pageInfo"
+ });
+
+Next, we have to declare our dependency on the `menuitems` package.
+In your add-on's `package.json` add the line:
+
+<pre>
+"dependencies": "menuitems"
+</pre>
+
+Note that due to
+[bug 663480](https://bugzilla.mozilla.org/show_bug.cgi?id=663480), if you
+add a `dependencies` line to `package.json`, and you use any modules from
+built-in packages like [`addon-kit`](packages/addon-kit/addon-kit.html), then
+you must also declare your dependency on that built-in package, like this:
+
+<pre>
+"dependencies": ["menuitems", "addon-kit"]
+</pre>
+
+Now we're done. Run the add-on and you'll see the new item appear in the
+`Tools` menu: select it and you'll see `info: clicked` appear in the
+console.
+
+## Caveats ##
+
+Eventually we expect the availability of a rich set of third party packages
+will be one of the most valuable aspects of the SDK. Right now they're a great
+way to use features not supported by the supported APIs without the
+complexity of using the low-level APIs, but there are some caveats you should
+be aware of:
+
+* our support for third party packages is still fairly immature. One
+consequence of this is that it's not always obvious where to find third-party
+packages, although some are collected in the
+[Jetpack Wiki](https://wiki.mozilla.org/Jetpack/Modules)
+
+* because third party modules typically use low-level APIs, they may be broken
+by new releases of Firefox. In particular, many third party modules will be
+broken by the
+[multiple process architecture](https://wiki.mozilla.org/Electrolysis/Firefox)
+(Electrolysis) planned for Firefox
View
0  dev-guide-source/addon-development/troubleshooting.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/tutorials.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/two-types-of-scripts.md 100755 → 100644
File mode changed
View
0  dev-guide-source/addon-development/web-content.md 100755 → 100644
File mode changed
View
320 dev-guide-source/addon-development/xul-migration.md
@@ -0,0 +1,320 @@
+
+# XUL Migration Guide #
+
+This guide aims to help you migrate a XUL-based add-on to the SDK.
+
+First we'll outline how to decide whether
+<a href="dev-guide/addon-development/xul-migration.html#should-you-migrate">
+your add-on is a good candidate for migration</a> via a
+[comparison of the benefits and limitations of the SDK versus XUL development](dev-guide/addon-development/sdk-vs-xul.html).
+
+Next, we'll look at some of the main tasks involved in migrating:
+
+* <a href="dev-guide/addon-development/xul-migration.html#content-scripts">
+working with content scripts</a>
+* <a href="dev-guide/addon-development/xul-migration.html#supported-apis">
+using the SDK's supported APIs</a>
+* how to
+go beyond the supported APIs when necessary, by:
+ * <a href="dev-guide/addon-development/xul-migration.html#third-party-packages">
+using third party modules</a>
+ * <a href="dev-guide/addon-development/xul-migration.html#low-level-apis">
+using the SDK's low-level APIs</a>
+ * <a href="dev-guide/addon-development/xul-migration.html#xpcom">
+getting direct access to XPCOM</a>
+
+Finally, we'll walk through a
+<a href="dev-guide/addon-development/xul-migration.html#library-detector">
+simple example</a>.
+
+## <a name="should-you-migrate">Should You Migrate?</a> ##
+
+See this [comparison of the benefits and limitations of SDK development
+and XUL development](dev-guide/addon-development/sdk-vs-xul.html).
+
+Whether you should migrate a particular add-on is largely a matter of
+how well the SDK's
+<a href="dev-guide/addon-development/xul-migration.html#supported-apis">
+supported APIs</a> meet its needs.
+
+* If your add-on can accomplish everything it needs using only the
+supported APIs, it's a good candidate for migration.
+
+* If your add-on needs a lot of help from third party packages, low-level
+APIs, or XPCOM, then the cost of migrating is high, and may not be worth
+it at this point.
+
+* If your add-on only needs a little help from those techniques, and can
+accomplish most of what it needs using the supported APIs, then it might
+still be worth migrating: we'll add more supported APIs in future releases
+to meet important use cases.
+
+## <a name="content-scripts">Content Scripts</a> ##
+
+In a XUL-based add-on, code that uses XPCOM objects, code that manipulates
+the browser chrome, and code that interacts with web pages all runs in the
+same context. But the SDK makes a distinction between:
+
+* **add-on scripts**, which can use the SDK APIs, but are not able to interact
+with web pages
+* **content scripts**, which can access web pages, but do not have access to
+the SDK's APIs
+
+Content scripts and add-on scripts communicate by sending each other JSON
+messages: in fact, the ability to communicate with the add-on scripts is the
+only extra privilege a content script is granted over a normal remote web
+page script.
+
+A XUL-based add-on will need to be reorganized to respect this distinction.
+
+Suppose an add-on wants to make a cross-domain XMLHttpRequest based on some
+data extracted from a web page. In a XUL-based extension you would implement
+all this in a single script. An SDK-based equivalent would need to be
+structured like this:
+
+* the main add-on code (1) attaches a content script to the page, and (2)
+registers a listener function for messages from the content script
+* the content script (3) extracts the data from the page and (4) sends
+it to the main add-on code in a message
+* the main add-on code (5) receives the message and (6) sends the request,
+using the SDK's [`request`](packages/addon-kit/docs/request.html) API
+
+<img class="image-center" src="static-files/media/xul-migration-cs.png"
+alt="Content script organization">
+
+There are two related reasons for this design. The first is security: it
+reduces the risk that a malicious web page will be able to access privileged
+APIs. The second is the need to be compatible with the multi-process architecture
+planned for Firefox: after this is implemented in Firefox, all add-ons will
+need to use a similar pattern, so it's likely that a XUL-based add-on will
+need to be rewritten anyway.
+
+There's much more information on content scripts in the
+[Working With Content Scripts](dev-guide/addon-development/web-content.html) guide.
+
+## <a name="supported-apis">Using the Supported APIs</a> ##
+
+The SDK provides a set of high level APIs providing some basic user
+interface components and functionality commonly required by add-ons.
+These are collected together in the
+[`addon-kit`](packages/addon-kit/addon-kit.html) package. Because we expect
+to keep these APIs compatible as new versions of Firefox are released, we
+call them the "supported" APIs.
+
+See this
+[quick overview](dev-guide/addon-development/api-modules.html) and
+[links to detailed API documentation](packages/addon-kit/addon-kit.html).
+If the supported APIs do what you need, they're the best option: you get the
+benefits of compatibility across Firefox releases and of the SDK's security
+model.
+
+APIs like [`widget`](packages/addon-kit/docs/widget.html) and
+[`panel`](packages/addon-kit/docs/panel.html) are very generic and with the
+right content can be used to replace many specific XUL elements. But there are
+some notable limitations in the SDK APIs and even a fairly simple UI may need
+some degree of redesign to work with them.
+
+Some limitations are the result of intentional design choices. For example,
+widgets always appear by default in the
+[add-on bar](https://developer.mozilla.org/en/The_add-on_bar) (although users
+may relocate them by
+[toolbar customization](http://support.mozilla.com/en-US/kb/how-do-i-customize-toolbars))
+because it makes for a better user experience for add-ons to expose their
+interfaces in a consistent way. In such cases it's worth considering
+changing your user interface to align with the SDK APIs.
+
+Some limitations only exist because we haven't yet implemented the relevant
+APIs: for example, there's currently no way to add items to the browser's main
+menus using the SDK's supported APIs.
+
+Many add-ons will need to make some changes to their user interfaces if they
+are to use only the SDK's supported APIs, and add-ons which make drastic
+changes to the browser chrome will very probably need more than the SDK's
+supported APIs can offer.
+
+Similarly, the supported APIs expose only a small fraction of the full range
+of XPCOM functionality.
+
+## <a name="third-party-packages">Using Third Party Packages</a> ##
+
+The SDK is extensible by design: developers can create new modules filling gaps
+in the SDK, and package them for distribution and reuse. Add-on developers can
+install these packages and use the new modules.
+
+If you can find a third party package that does what you want, this is a great
+way to use features not supported in the SDK without having to use the
+low-level APIs.
+
+See the
+[guide to using third party packages](dev-guide/addon-development/third-party-packages.html). Some useful third party packages are
+[collected in the Jetpack Wiki](https://wiki.mozilla.org/Jetpack/Modules).
+
+Note, though, that by using third party packages you're likely to lose the
+security and compatibility benefits of using the SDK.
+
+## <a name="low-level-apis">Using the Low-level APIs</a> ##
+
+<span class="aside">
+But note that unlike the supported APIs, low-level APIs do not come with a
+compatibility guarantee, so we do not expect code using them will necessarily
+continue to work as new versions of Firefox are released.
+</span>
+In addition to the supported APIs, the SDK includes a number of
+[low-level modules](packages/api-utils/api-utils.html) some of which, such
+as [`tab-browser`](packages/api-utils/docs/tab-browser.html), [`xhr`](packages/api-utils/docs/xhr.html), and
+[`window-utils`](packages/api-utils/docs/window-utils.html), expose powerful
+browser capabilities.
+
+In this section we'll use low-level modules how to:
+
+* modify the browser chrome using dynamic manipulation of the DOM
+* directly access the [tabbrowser](https://developer.mozilla.org/en/XUL/tabbrowser)
+object
+
+### <a name="browser-chrome">Modifying the Browser Chrome</a> ###
+
+The [`window-utils`](packages/api-utils/docs/window-utils.html) module gives
+you direct access to chrome windows, including the browser's chrome window.
+Here's a really simple example add-on that modifies the browser chrome using
+`window-utils`:
+
+ var windowUtils = require("window-utils");
+
+ windowUtils = new windowUtils.WindowTracker({
+ onTrack: function (window) {
+ if ("chrome://browser/content/browser.xul" != window.location) return;
+ var forward = window.document.getElementById('forward-button');
+ var parent = window.document.getElementById('unified-back-forward-button');
+ parent.removeChild(forward);
+ }
+ });
+
+This example just removes the 'forward' button from the browser. It constructs
+a `WindowTracker` object and assigns a function to the constructor's `onTrack`
+option. This function will be called whenever a window is opened. The function
+checks whether the window is the browser's chrome window, and if it is, uses
+DOM manipulation functions to modify it.
+
+There are more useful examples of this technique in the Jetpack Wiki's
+collection of [third party modules](https://wiki.mozilla.org/Jetpack/Modules).
+
+### <a name="accessing-tabbrowser">Accessing <a href="https://developer.mozilla.org/en/XUL/tabbrowser">tabbrowser</a> ###
+
+
+The [`tab-browser`](packages/api-utils/docs/tab-browser.html) module gives
+you direct access to the
+[tabbrowser](https://developer.mozilla.org/en/XUL/tabbrowser) object. This
+simple example modifies the selected tab's CSS to enable the user to highlight
+the selected tab:
+
+ var widgets = require("widget");
+ var tabbrowser = require("tab-browser");
+ var self = require("self");
+
+ function highlightTab(tab) {
+ if (tab.style.getPropertyValue('background-color')) {
+ tab.style.setProperty('background-color','','important');
+ }
+ else {
+ tab.style.setProperty('background-color','rgb(255,255,100)','important');
+ }
+ }
+
+ var widget = widgets.Widget({
+ id: "tab highlighter",
+ label: "Highlight tabs",
+ contentURL: self.data.url("highlight.png"),
+ onClick: function() {
+ highlightTab(tabbrowser.activeTab);
+ }
+ });
+
+### Security Implications ###
+
+The SDK implements a security model in which an add-on only gets to access the
+APIs it explicitly imports via `require()`. This is useful, because it means
+that if a malicious web page is able to inject code into your add-on's
+context, it is only able to use the APIs you have imported. For example, if
+you have only imported the
+[`notifications`](packages/addon-kit/docs/notifications.html) module, then
+even if a malicious web page manages to inject code into your add-on, it
+can't use the SDK's [`file`](packages/api-utils/docs/file.html) module to
+access the user's data.
+
+But this means that the more powerful modules you `require()`, the greater
+is your exposure if your add-on is compromised. Low-level modules like `xhr`,
+`tab-browser` and `window-utils` are much more powerful than the modules in
+`addon-kit`, so your add-on needs correspondingly more rigorous security
+design and review.
+
+## <a name="xpcom">Using XPCOM</a> ##
+
+Finally, if none of the above techniques work for you, you can use the
+`require("chrome")` statement to get direct access to the
+[`Components`](https://developer.mozilla.org/en/Components_object) object,
+which you can then use to load and access any XPCOM object.
+
+The following complete add-on uses
+[`nsIPromptService`](https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIPromptService)
+to display an alert dialog:
+
+ var {Cc, Ci} = require("chrome");
+
+ var promptSvc = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Ci.nsIPromptService);
+
+ var widget = require("widget").Widget({
+ id: "xpcom example",
+ label: "Mozilla website",
+ contentURL: "http://www.mozilla.org/favicon.ico",
+ onClick: function() {
+ promptSvc.alert(null, "My Add-on", "Hello from XPCOM");
+ }
+ });
+
+It's good practice to encapsulate code which uses XPCOM by
+[packaging it in its own module](dev-guide/addon-development/implementing-reusable-module.html).
+For example, we could package the alert feature implemented above using a
+script like:
+
+ var {Cc, Ci} = require("chrome");
+
+ var promptSvc = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Ci.nsIPromptService);
+
+ exports.alert = function(title, text) {
+ promptSvc.alert(null, title, text);
+ };
+
+If we save this as "alert.js" in our add-on's `lib` directory, we can rewrite
+`main.js` to use it as follows:
+
+ var widget = require("widget").Widget({
+ id: "xpcom example",
+ label: "Mozilla website",
+ contentURL: "http://www.mozilla.org/favicon.ico",
+ onClick: function() {
+ require("alert").alert("My Add-on", "Hello from XPCOM");
+ }
+ });
+
+One of the benefits of this is that we can control which parts of the add-on
+are granted chrome privileges, making it easier to review and secure the code.
+
+### Security Implications ###
+
+We saw above that using powerful low-level modules like `tab-browser`
+increases the damage that a malicious web page could do if it were able to
+inject code into your add-ons context. This applies with even greater force
+to `require("chrome")`, since this gives full access to the browser's
+capabilities.
+
+## <a name="library-detector">Example: Porting the Library Detector</a> ##
+
+[Porting the Library Detector](dev-guide/addon-development/library-detector.html)
+walks through the process of porting a XUL-based add-on to the
+SDK. It's a very simple add-on and a good candidate for porting because
+there are suitable SDK APIs for all its features.
+
+Even so, we have to change its user interface slightly if we are to use only
+the supported APIs.
View
1  dev-guide-source/appendices/credits.md 100755 → 100644
@@ -15,6 +15,7 @@ We'd like to thank our many Jetpack project contributors! They include:
* [Shane Caraveo](https://github.com/mixedpuppy)
* [Matěj Cepl](https://github.com/mcepl)
* Hernán Rodriguez Colmeiro
+* [Matteo Ferretti (ZER0)](https://github.com/ZER0)
* fuzzykiller
* [Marcio Galli](https://github.com/taboca)
* Felipe Gomes
View
0  dev-guide-source/appendices/glossary.md 100755 → 100644
File mode changed
View
0  dev-guide-source/module-development/about.md 100755 → 100644
File mode changed
View
0  dev-guide-source/module-development/best-practices.md 100755 → 100644
File mode changed
View
0  dev-guide-source/module-development/chrome.md 100755 → 100644
File mode changed
View
0  dev-guide-source/module-development/e10s.md 100755 → 100644
File mode changed
View
0  dev-guide-source/module-development/globals.md 100755 → 100644
File mode changed
View
0  dev-guide-source/module-development/guides.md 100755 → 100644
File mode changed
View
0  dev-guide-source/module-development/reference.md 100755 → 100644
File mode changed
View
0  dev-guide-source/module-development/tutorials.md 100755 → 100644
File mode changed
View
0  dev-guide-source/module-development/xpi.md 100755 → 100644
File mode changed
View
0  dev-guide-source/welcome.md 100755 → 100644
File mode changed
View
22 dev-guide/addon-development/about.html
@@ -2,7 +2,7 @@
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
- <base href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.2.1/" >
+ <base href="https://addons.mozilla.org/en-US/developers/docs/sdk/1.3/" >
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="static-files/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="static-files/syntaxhighlighter/scripts/shBrushCss.js"></script>
@@ -35,7 +35,10 @@
<a id="mozilla-tab" href="http://www.mozilla.org/?ref=logo">Mozilla</a>
<div class="menu">
<p>
- <a href="https://addons.mozilla.org/en-US/developers/">Back to Developer Hub</a>
+ <a href="https://builder.addons.mozilla.org/">Add-on Builder</a>
+ </p>
+ <p>
+ <a href="https://addons.mozilla.org/en-US/developers/">Developer Hub</a>
</p>
</div>
</header>
@@ -99,7 +102,7 @@ <h3 class="sidebar-subsection-header"><a href="dev-guide/addon-development/tutor
<li><a href="dev-guide/addon-development/api-idioms.html">Common Idioms</a></li>
<li><a href="dev-guide/addon-development/api-modules.html">API Overview</a></li>
</ul></li>
- <li><h4><a href="dev-guide/addon-development/annotator/annotator.html">Annotator: a More Complex Add-on</a></h4>
+ <li><h4><a href="dev-guide/addon-development/annotator/annotator.html">Example: Annotator</a></h4>
<ul>
<li><a href="dev-guide/addon-development/annotator/overview.html">Design Overview</a></li>
<li><a href="dev-guide/addon-development/annotator/widget.html">Implementing the Widget</a></li>
@@ -107,7 +110,14 @@ <h3 class="sidebar-subsection-header"><a href="dev-guide/addon-development/tutor
<li><a href="dev-guide/addon-development/annotator/storing.html">Storing Annotations</a></li>
<li><a href="dev-guide/addon-development/annotator/displaying.html">Displaying Annotations</a></li>
</ul></li>
- </ul>
+ <li><h4><a href="dev-guide/addon-development/third-party-packages.html">Using Third Party Packages</a></h4></li>