Skip to content
Browse files

generated some docs to look at

  • Loading branch information...
1 parent 5e1a664 commit d15344d629ec34d2bb38137e402d6a417c275aa6 @wbamberg wbamberg committed Oct 18, 2012
Showing with 19,860 additions and 6 deletions.
  1. +4 −5 README.md
  2. 0 {docs-tools → }/get_releases.sh
  3. 0 {docs-tools → }/git_commit.sh
  4. 0 {docs-tools → }/git_prepare_commit.sh
  5. +1 −1 {docs-tools → }/make_webdocs.sh
  6. 0 {docs-tools → }/obsolete.py
  7. +892 −0 sdk/1.10/dev-guide-source/cfx-tool.md
  8. +46 −0 sdk/1.10/dev-guide-source/console.md
  9. +68 −0 sdk/1.10/dev-guide-source/credits.md
  10. +73 −0 sdk/1.10/dev-guide-source/glossary.md
  11. +146 −0 sdk/1.10/dev-guide-source/guides/commonjs.md
  12. +124 −0 sdk/1.10/dev-guide-source/guides/content-scripts/accessing-the-dom.md
  13. +246 −0 sdk/1.10/dev-guide-source/guides/content-scripts/communicating-with-other-scripts.md
  14. +93 −0 sdk/1.10/dev-guide-source/guides/content-scripts/index.md
  15. +79 −0 sdk/1.10/dev-guide-source/guides/content-scripts/loading.md
  16. +71 −0 sdk/1.10/dev-guide-source/guides/content-scripts/reddit-example.md
  17. +183 −0 sdk/1.10/dev-guide-source/guides/content-scripts/using-port.md
  18. +184 −0 sdk/1.10/dev-guide-source/guides/content-scripts/using-postmessage.md
  19. +153 −0 sdk/1.10/dev-guide-source/guides/events.md
  20. +103 −0 sdk/1.10/dev-guide-source/guides/firefox-compatibility.md
  21. +181 −0 sdk/1.10/dev-guide-source/guides/index.md
  22. +218 −0 sdk/1.10/dev-guide-source/guides/library-detector.md
  23. +117 −0 sdk/1.10/dev-guide-source/guides/module-search.md
  24. +33 −0 sdk/1.10/dev-guide-source/guides/program-id.md
  25. +107 −0 sdk/1.10/dev-guide-source/guides/sdk-vs-xul.md
  26. +119 −0 sdk/1.10/dev-guide-source/guides/two-types-of-scripts.md
  27. +325 −0 sdk/1.10/dev-guide-source/guides/xul-migration.md
  28. +16 −0 sdk/1.10/dev-guide-source/high-level-apis.md
  29. +151 −0 sdk/1.10/dev-guide-source/index.md
  30. +34 −0 sdk/1.10/dev-guide-source/low-level-apis.md
  31. +119 −0 sdk/1.10/dev-guide-source/package-spec.md
  32. +7 −0 sdk/1.10/dev-guide-source/third-party-apis.md
  33. +88 −0 sdk/1.10/dev-guide-source/tutorials/add-a-context-menu-item.md
  34. +122 −0 sdk/1.10/dev-guide-source/tutorials/adding-menus.md
  35. +170 −0 sdk/1.10/dev-guide-source/tutorials/adding-toolbar-button.md
  36. +344 −0 sdk/1.10/dev-guide-source/tutorials/annotator/creating.md
  37. +213 −0 sdk/1.10/dev-guide-source/tutorials/annotator/displaying.md
  38. +31 −0 sdk/1.10/dev-guide-source/tutorials/annotator/index.md
  39. +63 −0 sdk/1.10/dev-guide-source/tutorials/annotator/overview.md
  40. +369 −0 sdk/1.10/dev-guide-source/tutorials/annotator/storing.md
  41. +115 −0 sdk/1.10/dev-guide-source/tutorials/annotator/widget.md
  42. +105 −0 sdk/1.10/dev-guide-source/tutorials/chrome.md
  43. +151 −0 sdk/1.10/dev-guide-source/tutorials/display-a-popup.md
  44. +273 −0 sdk/1.10/dev-guide-source/tutorials/event-targets.md
  45. +170 −0 sdk/1.10/dev-guide-source/tutorials/getting-started-with-cfx.md
  46. +244 −0 sdk/1.10/dev-guide-source/tutorials/index.md
  47. +154 −0 sdk/1.10/dev-guide-source/tutorials/installation.md
  48. +369 −0 sdk/1.10/dev-guide-source/tutorials/l10n.md
  49. +73 −0 sdk/1.10/dev-guide-source/tutorials/list-open-tabs.md
  50. +55 −0 sdk/1.10/dev-guide-source/tutorials/listen-for-page-load.md
  51. +103 −0 sdk/1.10/dev-guide-source/tutorials/load-and-unload.md
  52. +67 −0 sdk/1.10/dev-guide-source/tutorials/logging.md
  53. +247 −0 sdk/1.10/dev-guide-source/tutorials/mobile.md
  54. +153 −0 sdk/1.10/dev-guide-source/tutorials/modifying-web-pages-tab.md
  55. +227 −0 sdk/1.10/dev-guide-source/tutorials/modifying-web-pages-url.md
  56. +57 −0 sdk/1.10/dev-guide-source/tutorials/open-a-web-page.md
  57. +413 −0 sdk/1.10/dev-guide-source/tutorials/reusable-modules.md
  58. +208 −0 sdk/1.10/dev-guide-source/tutorials/troubleshooting.md
  59. +163 −0 sdk/1.10/dev-guide-source/tutorials/unit-testing.md
  60. +1,132 −0 sdk/1.10/dev-guide/cfx-tool.html
  61. +357 −0 sdk/1.10/dev-guide/console.html
  62. +395 −0 sdk/1.10/dev-guide/credits.html
  63. +383 −0 sdk/1.10/dev-guide/glossary.html
  64. +460 −0 sdk/1.10/dev-guide/guides/commonjs.html
  65. +437 −0 sdk/1.10/dev-guide/guides/content-scripts/accessing-the-dom.html
  66. +541 −0 sdk/1.10/dev-guide/guides/content-scripts/communicating-with-other-scripts.html
  67. +406 −0 sdk/1.10/dev-guide/guides/content-scripts/index.html
  68. +401 −0 sdk/1.10/dev-guide/guides/content-scripts/loading.html
  69. +390 −0 sdk/1.10/dev-guide/guides/content-scripts/reddit-example.html
  70. +486 −0 sdk/1.10/dev-guide/guides/content-scripts/using-port.html
  71. +489 −0 sdk/1.10/dev-guide/guides/content-scripts/using-postmessage.html
  72. +465 −0 sdk/1.10/dev-guide/guides/events.html
  73. +413 −0 sdk/1.10/dev-guide/guides/firefox-compatibility.html
  74. +505 −0 sdk/1.10/dev-guide/guides/index.html
  75. +519 −0 sdk/1.10/dev-guide/guides/library-detector.html
  76. +437 −0 sdk/1.10/dev-guide/guides/module-search.html
  77. +356 −0 sdk/1.10/dev-guide/guides/program-id.html
  78. +427 −0 sdk/1.10/dev-guide/guides/sdk-vs-xul.html
  79. +432 −0 sdk/1.10/dev-guide/guides/two-types-of-scripts.html
  80. +609 −0 sdk/1.10/dev-guide/guides/xul-migration.html
  81. +342 −0 sdk/1.10/dev-guide/high-level-apis.html
  82. +474 −0 sdk/1.10/dev-guide/index.html
  83. +364 −0 sdk/1.10/dev-guide/low-level-apis.html
Sorry, we could not display the entire diff because too many files (744) changed.
View
9 README.md
@@ -1,6 +1,6 @@
-This repository contains two top-level directories:
-- `sdk`: the SDK documentation to be hosted at addons.mozilla.org
-- `doc-tools`: a collection of scripts used to build this documentation
+This repository contains:
+- the SDK documentation to be hosted at addons.mozilla.org
+- a collection of scripts used to build this documentation
## SDK documentation sets ##
@@ -22,9 +22,8 @@ When we release a new version of the SDK, the contents of the `sdk` directory mu
## Building the docs for a release ##
-To build the docs for a release use the top-level script `make_webdocs.sh`, which lives under `docs-tools`:
+To build the docs for a release use the top-level script `make_webdocs.sh`:
- cd docs-tools
bash make_webdocs.sh 1.11rc1 1.10 1.9 mappings
`make_webdocs.sh` takes three mandatory parameters and one optional parameter:
View
0 docs-tools/get_releases.sh → get_releases.sh
File renamed without changes.
View
0 docs-tools/git_commit.sh → git_commit.sh
File renamed without changes.
View
0 docs-tools/git_prepare_commit.sh → git_prepare_commit.sh
File renamed without changes.
View
2 docs-tools/make_webdocs.sh → make_webdocs.sh
@@ -18,4 +18,4 @@ python obsolete.py $old_version1 $latest_version $4
python obsolete.py $old_version2 $latest_version $4
# make the commit
-bash git_commit.sh $1
+#bash git_commit.sh $1
View
0 docs-tools/obsolete.py → obsolete.py
File renamed without changes.
View
892 sdk/1.10/dev-guide-source/cfx-tool.md
@@ -0,0 +1,892 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# cfx #
+
+The `cfx` command-line tool gives you access to the SDK documentation and
+development servers as well as testing, running, and building packages.
+`cfx` usage is:
+
+<pre>
+ cfx [options] command [command-specific options]
+</pre>
+
+"Options" are global options applicable to the tool itself or to all
+commands (for example `--help`). `cfx` supports the following global options:
+
+<pre>
+ -h, --help - show a help message and exit
+ -v, --verbose - enable lots of output
+</pre>
+
+"Command-specific options" are only
+applicable to a subset of the commands.
+
+## Supported Commands ##
+
+### cfx docs ###
+
+This command displays the documentation for the SDK. The documentation is
+shipped with the SDK in [Markdown](http://daringfireball.net/projects/markdown/)
+format. The first time this command is executed, and any time after the
+Markdown files on disk have changed, `cfx docs` will generate a set of HTML
+pages from them and launch a web browser to display them. If the Markdown files
+haven't changed, `cfx docs` just launches a browser initialized to the set of
+generated pages.
+
+To regenerate the documentation associated with a single file, you can
+specify the file as an argument. For example:
+
+<pre>
+ cfx docs doc/dev-guide-source/addon-development/cfx-tool.md
+</pre>
+
+This command will regenerate only the HTML page you're reading.
+This is useful if you're iteratively editing a single file, and don't want to wait for cfx to
+regenerate the complete documentation tree.
+
+### cfx init ####
+Create a new directory, change into it, and run `cfx init`.
+
+This command will create an skeleton add-on, as a starting point for your
+own add-on development, with the following file structure:
+
+<pre>
+ README.md
+ package.json
+ data/
+ lib/
+ main.js
+ tests/
+ test-main.js
+ docs/
+ main.md
+</pre>
+
+### cfx run ###
+
+This command is used to run the add-on. Called with no options it looks for a
+file called `package.json` in the current directory, loads the corresponding
+add-on, and runs it under the version of Firefox it finds in the platform's
+default install path.
+
+#### Supported Options #####
+
+You can point `cfx run` at a different `package.json` file using the
+`--pkgdir` option, and pass arguments to your add-on using the
+`--static-args` option.
+
+You can specify a different version of the
+<a href="dev-guide/glossary.html#host-application">host application</a>
+using the `--binary` option, passing in the path to the application binary to
+run. The path may be specified as a full path or may be relative to the current
+directory. But note that the version must be 4.0b7 or later.
+
+`cfx run` runs the host application with a new
+[profile](http://support.mozilla.com/en-US/kb/profiles). You can specify an
+existing profile using the `--profiledir` option, and this gives you access to
+that profile's history, bookmarks, and other add-ons. This enables you to run
+your add-on alongside debuggers like [Firebug](http://getfirebug.com/).
+See <a href="dev-guide/cfx-tool.html#profiledir">
+"Using --profiledir"</a> for more information.
+
+<table>
+<colgroup>
+<col width="30%">
+<col width="70%">
+</colgroup>
+
+<tr>
+ <td>
+ <code>-b BINARY, --binary=BINARY</code>
+ </td>
+ <td>
+ Use the host application binary specified in BINARY. BINARY may be specified as
+ a full path or as a path relative to the current directory.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--binary-args=CMDARGS</code>
+ </td>
+ <td>
+ <p>Pass <a href="http://kb.mozillazine.org/Command_line_arguments">extra
+ arguments</a> to the binary being executed (for example, Firefox).</p>
+ <p>For example, to pass the
+ <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>
+ <p>To pass multiple arguments, or arguments containing spaces, quote them:</p>
+ <pre>cfx run --binary-args '-url "www.mozilla.org" -jsconsole'</pre>
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--extra-packages=EXTRA_PACKAGES</code>
+ </td>
+ <td>
+ Extra packages to include, specified as a comma-separated list of package
+ names. Defaults to <code>addon-kit</code>.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>-g CONFIG, --use-config=CONFIG</code>
+ </td>
+ <td>
+ Pass a set of options by
+ <a href="dev-guide/cfx-tool.html#configurations">referencing a named configuration</a>.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>-p PROFILEDIR, --profiledir=PROFILEDIR</code>
+ </td>
+ <td>
+ <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.</p>
+
+ <p>See <a href="dev-guide/cfx-tool.html#profiledir">
+ "Using --profiledir"</a> for more information.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--pkgdir=PKGDIR</code>
+ </td>
+ <td>
+ Use an add-on located in PKGDIR. PKGDIR may be specified as
+ a full path or as a path relative to the current directory.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--static-args=STATIC_ARGS</code>
+ </td>
+ <td>
+ <a href="dev-guide/cfx-tool.html#arguments">Pass arguments to your add-on</a>,
+ in JSON format.
+ </td>
+</tr>
+
+</table>
+
+#### Experimental Options ####
+
+<table>
+<colgroup>
+<col width="30%">
+<col width="70%">
+</colgroup>
+
+<tr>
+ <td>
+ <code>-a APP, --app=APP</code>
+ </td>
+ <td>
+ By default, <code>cfx run</code> uses Firefox as the
+ <a href="dev-guide/glossary.html#host-application">host application</a>.
+ This option enables you to select a different host. You can specify
+ "firefox", "xulrunner", "fennec", or "thunderbird". But note that at
+ present only Firefox is supported.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--no-run</code>
+ </td>
+ <td>
+ <p>With this option <code>cfx</code> will not execute the command, but
+ will print out the command that it would have used to execute the
+ command.</p>
+ <p>For example, if you type:</p>
+ <pre>
+cfx run ---no-run</pre>
+ <p>you will see something like:</p>
+ <pre>
+To launch the application, enter the following command:
+ /path/to/firefox/firefox-bin -profile
+ /path/to/profile/tmpJDNlP6.mozrunner -foreground -no-remote</pre>
+ <p>This enables you to run the add-on without going through
+ <code>cfx</code>, which might be useful if you want to run it
+ inside a debugger like GDB.</p>
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--templatedir=TEMPLATEDIR</code>
+ </td>
+ <td>
+ The <code>cfx run</code> command constructs the add-on using a extension
+ template which you can find under the SDK root, in
+ <code>python-lib/cuddlefish/app-extension</code>.
+ Use the <code>--templatedir</code> option to specify a different template.
+ TEMPLATEDIR may be specified as a full path or as a path relative to the
+ current directory.
+ </td>
+</tr>
+
+</table>
+
+#### Internal Options ####
+
+<table>
+<colgroup>
+<col width="30%">
+<col width="70%">
+</colgroup>
+
+<tr>
+ <td>
+ <code>--addons=ADDONS</code>
+ </td>
+ <td>
+ Paths of add-ons to install, comma-separated. ADDONS may be specified as
+ a full path or as a path relative to the current directory.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--e10s</code>
+ </td>
+ <td>
+ If this option is set then the add-on runs in a separate process.
+ This option is currently not implemented.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--keydir=KEYDIR</code>
+ </td>
+ <td>
+ Supply a different location for
+ <a href="dev-guide/guides/program-id.html">signing keys</a>.
+ KEYDIR may be specified as a full path or as a path relative to the
+ current directory.
+ </td>
+</tr>
+
+</table>
+
+### cfx test ###
+
+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, load from the `tests` directory
+any modules that start with the word `test-` and run the unit tests
+they contain.
+
+See the
+[tutorial on unit testing](dev-guide/tutorials/unit-testing.html) and the
+[reference documentation for the `assert` module](packages/api-utils/test/assert.html)
+for details.
+
+#### Supported Options #####
+
+As with `cfx run` you can use options to control which host application binary
+version to use, and to select a profile.
+
+You can also control which tests are run: you
+can test dependent packages, filter the tests by name and run tests multiple
+times.
+
+<table>
+<colgroup>
+<col width="30%">
+<col width="70%">
+</colgroup>
+
+<tr>
+ <td>
+ <code>-b BINARY, --binary=BINARY</code>
+ </td>
+ <td>
+ Use the host application binary specified in BINARY. BINARY may be specified as
+ a full path or as a path relative to the current directory.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--binary-args=CMDARGS</code>
+ </td>
+ <td>
+ <p>Pass <a href="http://kb.mozillazine.org/Command_line_arguments">extra
+ arguments</a> to the binary being executed (for example, Firefox).</p>
+ <p>For example, to pass the
+ <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>
+ <p>To pass multiple arguments, or arguments containing spaces, quote them:</p>
+ <pre>cfx run --binary-args '-url "www.mozilla.org" -jsconsole'</pre>
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--dependencies</code>
+ </td>
+ <td>
+ Load and run any tests that are included with packages that your package
+ depends on.
+ <br>
+ For example: if your add-on depends on <code>addon-kit</code> and you
+ supply this option, then <code>cfx</code> will run the unit tests for
+ <code>addon-kit</code> as well as those for your add-on.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>-f FILTER, --filter=FILTER</code>
+ </td>
+ <td>
+ Run only those test modules whose names match the regexp supplied in
+ FILTER.
+ <br>
+ For example: if you specify <code>--filter data</code>, then
+ <code>cfx</code> will only run tests in those modules whose name contain
+ the string "data".
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>-g CONFIG, --use-config=CONFIG</code>
+ </td>
+ <td>
+ Pass a set of options by
+ <a href="dev-guide/cfx-tool.html#configurations">referencing a named configuration</a>.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>-p PROFILEDIR, --profiledir=PROFILEDIR</code>
+ </td>
+ <td>
+ <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.</p>
+
+ <p>See <a href="dev-guide/cfx-tool.html#profiledir">
+ "Using --profiledir"</a> for more information.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--times=ITERATIONS</code>
+ </td>
+ <td>
+ Execute tests ITERATIONS number of times.
+ </td>
+</tr>
+
+</table>
+
+#### Experimental Options ####
+
+<table>
+<colgroup>
+<col width="30%">
+<col width="70%">
+</colgroup>
+
+<tr>
+ <td>
+ <code>-a APP, --app=APP</code>
+ </td>
+ <td>
+ By default, <code>cfx test</code> uses Firefox as the
+ <a href="dev-guide/glossary.html#host-application">host application</a>.
+ This option enables you to select a different host. You can specify
+ "firefox", "xulrunner", "fennec", or "thunderbird". But note that at
+ present only Firefox is supported.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--no-run</code>
+ </td>
+ <td>
+ <p>With this option <code>cfx</code> will not execute the command, but
+ will print out the command that it would have used to execute the
+ command.</p>
+ <p>For example, if you type:</p>
+ <pre>
+cfx run ---no-run</pre>
+ <p>you will see something like:</p>
+ <pre>
+To launch the application, enter the following command:
+ /path/to/firefox/firefox-bin -profile
+ /path/to/profile/tmpJDNlP6.mozrunner -foreground -no-remote</pre>
+ <p>This enables you to run the add-on without going through
+ <code>cfx</code>, which might be useful if you want to run it
+ inside a debugger like GDB.</p>
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--use-server</code>
+ </td>
+ <td>
+ Run tests using a server previously started with <code>cfx develop</code>.
+ </td>
+</tr>
+
+</table>
+
+#### Internal Options ####
+
+<table>
+<colgroup>
+<col width="30%">
+<col width="70%">
+</colgroup>
+
+<tr>
+ <td>
+ <code>--addons=ADDONS</code>
+ </td>
+ <td>
+ Paths of add-ons to install, comma-separated.
+ ADDONS may be specified as full paths or relative to the
+ current directory.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--e10s</code>
+ </td>
+ <td>
+ If this option is set then the add-on runs in a separate process.
+ This option is currently not implemented.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--keydir=KEYDIR</code>
+ </td>
+ <td>
+ Supply a different location for
+ <a href="dev-guide/guides/program-id.html">signing keys</a>.
+ KEYDIR may be specified as a full path or as a path relative to the
+ current directory.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--logfile=LOGFILE</code>
+ </td>
+ <td>
+ Log console output to the file specified by LOGFILE.
+ LOGFILE may be specified as a full path or as a path relative to the
+ current directory.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--profile-memory=PROFILEMEMORY</code>
+ </td>
+ <td>
+ If this option is given and PROFILEMEMORY is any non-zero integer, then
+ <code>cfx</code> dumps detailed memory usage information to the console
+ when the tests finish.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--test-runner-pkg=TEST_RUNNER_PKG</code>
+ </td>
+ <td>
+ Name of package containing test runner program. Defaults to
+ <code>test-harness</code>.
+ </td>
+</tr>
+
+</table>
+
+### cfx xpi ###
+
+This tool is used to package your add-on as an
+[XPI](https://developer.mozilla.org/en/XPI) file, which is the install file
+format for Mozilla add-ons.
+
+Called with no options, this command looks for a file called `package.json` in
+the current directory and creates the corresponding XPI file.
+
+Once you have built an XPI file you can distribute your add-on by submitting
+it to [addons.mozilla.org](http://addons.mozilla.org).
+
+#### updateURL and updateLink ####
+
+If you choose to host the XPI yourself you should enable the host application
+to find new versions of your add-on.
+
+To do this, include a URL in the XPI called the
+[updateURL](https://developer.mozilla.org/en/install_manifests#updateURL): the
+host application will go here to get information about updates. At the
+`updateURL` you host a file in the
+[update RDF](https://developer.mozilla.org/en/extension_versioning,_update_and_compatibility#Update_RDF_Format)
+format: among other things, this includes another URL called `updateLink` which
+points to the updated XPI itself.
+
+The `--update-link` and `--update-url` options simplify this process.
+Both options take a URL as an argument.
+
+The `--update-link` option builds an update RDF alongside the XPI, and embeds
+the supplied URL in the update RDF as the value of `updateLink`.
+
+The `--update-url` option embeds the supplied URL in the XPI file, as the value
+of `updateURL`.
+
+Note that as the [add-on documentation](https://developer.mozilla.org/en/extension_versioning,_update_and_compatibility#Securing_Updates)
+explains, you should make sure the update procedure for your add-on is secure,
+and this usually involves using HTTPS for the links.
+
+So if we run the following command:
+
+<pre>
+ cfx xpi --update-link https://example.com/addon/latest
+ --update-url https://example.com/addon/update_rdf
+</pre>
+
+`cfx` will create two files:
+
+* an XPI file which embeds
+`https://example.com/addon/update_rdf` as the value of `updateURL`
+* an RDF file which embeds `https://example.com/addon/latest` as the value of
+`updateLink`.
+
+#### Supported Options ####
+
+As with `cfx run` you can point `cfx` at a different `package.json` file using
+the `--pkgdir` option. You can also embed arguments in the XPI using the
+`--static-args` option: if you do this the arguments will be passed to your
+add-on whenever it is run.
+
+<table>
+<colgroup>
+<col width="50%">
+<col width="50%">
+</colgroup>
+
+<tr>
+ <td>
+ <code>--extra-packages=EXTRA_PACKAGES</code>
+ </td>
+ <td>
+ Extra packages to include, specified as a comma-separated list of package
+ names. Defaults to <code>addon-kit</code>.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>-g CONFIG, --use-config=CONFIG</code>
+ </td>
+ <td>
+ Pass a set of options by
+ <a href="dev-guide/cfx-tool.html#configurations">referencing a named configuration</a>.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--pkgdir=PKGDIR</code>
+ </td>
+ <td>
+ Use an add-on located in PKGDIR.
+ PKGDIR may be specified as a full path or as a path relative to the
+ current directory.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--static-args=STATIC_ARGS</code>
+ </td>
+ <td>
+ <a href="dev-guide/cfx-tool.html#arguments">Pass arguments to your add-on</a>,
+ in JSON format.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--update-link=UPDATE_LINK</code>
+ </td>
+ <td>
+ Build an
+ <a href="https://developer.mozilla.org/en/extension_versioning,_update_and_compatibility#Update_RDF_Format">update RDF</a>
+ alongside the XPI file, and embed the URL supplied in UPDATE_LINK in it as
+ the value of <code>updateLink</code>.
+ </td>
+</tr>
+
+<tr>
+ <td>
+ <code>--update-link=UPDATE_URL</code>
+ </td>
+ <td>
+ Embed the URL supplied in UPDATE_URL in the XPI file, as the value
+ of <code>updateURL</code>.
+ </td>
+</tr>
+
+</table>
+
+#### Experimental Options ####
+
+<table>
+<colgroup>
+<col width="50%">
+<col width="50%">
+</colgroup>
+
+<tr>
+ <td>
+ <code>--templatedir=TEMPLATEDIR</code>
+ </td>
+ <td>
+ The <code>cfx xpi</code> command constructs the add-on using a extension
+ template which you can find under the SDK root, in
+ <code>python-lib/cuddlefish/app-extension</code>.
+ Use the <code>--templatedir</code> option to specify a different template.
+ TEMPLATEDIR may be specified as a full path or as a path relative to the
+ current directory.
+ </td>
+</tr>
+
+</table>
+
+#### Internal Options ####
+
+<table>
+<colgroup>
+<col width="50%">
+<col width="50%">
+</colgroup>
+
+<tr>
+ <td>
+ <code>--keydir=KEYDIR</code>
+ </td>
+ <td>
+ Supply a different location for
+ <a href="dev-guide/guides/program-id.html">signing keys</a>.
+ KEYDIR may be specified as a full path or as a path relative to the
+ current directory.
+ </td>
+</tr>
+
+</table>
+
+## Experimental Commands ##
+
+### cfx develop ###
+
+This initiates an instance of a host application in development mode,
+and allows you to pipe commands into it from another shell without
+having to constantly restart it. Aside from convenience, for SDK
+Platform developers this has the added benefit of making it easier to
+detect leaks.
+
+For example, in shell A, type:
+
+<pre>
+ cfx develop
+</pre>
+
+In shell B, type:
+
+<pre>
+ cfx test --use-server
+</pre>
+
+This will send `cfx test --use-server` output to shell A. If you repeat the
+command in shell B, `cfx test --use-server` output will appear again in shell A
+without restarting the host application.
+
+`cfx develop` doesn't take any options.
+
+## Internal Commands ##
+
+### cfx sdocs ###
+
+Executing this command builds a static HTML version of the SDK documentation
+that can be hosted on a web server without the special application support
+required by `cfx docs`.
+
+#### Options ####
+
+<table>
+<colgroup>
+<col width="50%">
+<col width="50%">
+</colgroup>
+
+<tr>
+ <td>
+ <code>--baseurl=BASEURL</code>
+ </td>
+ <td>
+ The root of the static docs tree, for example:
+ <code>http://example.com/sdk-docs/</code>.
+ </td>
+</tr>
+
+</table>
+
+### cfx testcfx ###
+
+This will run a number of tests on the cfx tool, including tests against the
+documentation. Use `cfx testcfx -v` for the specific list of tests.
+
+This accepts the same options as `cfx test`.
+
+### cfx testpkgs ###
+
+This will test all of the available CommonJS packages. Note that the number
+of tests run and their success depends on what application they are run
+with, and which binary is used.
+
+This accepts the same options as `cfx test`.
+
+### cfx testex ###
+
+This will test all available example code. Note that the number
+of tests run and their success depends on what application they are run
+with, and which binary is used.
+
+This accepts the same options as `cfx test`.
+
+### cfx testall ###
+
+This will test *everything*: the cfx tool, all available CommonJS packages,
+and all examples.
+
+This accepts the same options as `cfx test`.
+
+## <a name="profiledir">Using --profiledir</a> ##
+
+By default, `cfx run` and `cfx test` use a new profile each time they
+are executed. This means that any profile-specific data entered from
+one run of `cfx` will not, by default, be available in the next run.
+
+This includes, for example, any extra add-ons you installed, or your
+history, or any data stored using the
+[simple-storage](packages/addon-kit/simple-storage.html) API.
+
+To make `cfx` use a specific profile, pass the `--profiledir` option,
+specifying the path to the profile you wish to use.
+
+If you give `--profiledir` a path to a nonexistent profile, `cfx`
+will create a profile there for you. So you just have to make up
+a path and name the first time, and keep using it:
+
+<pre>
+cfx run --profiledir="~/addon-dev/profiles/boogaloo"
+</pre>
+
+The path must contain at least one "/" (although you may specify
+just "./dir").
+
+## <a name="configurations">Using Configurations</a> ##
+
+The `--use-config` option enables you to specify a set of options as a named
+configuration in a file, then pass them to `cfx` by referencing the named set.
+
+You define configurations in a file called `local.json` which should live
+in the root directory of your SDK. Configurations are listed under a key called
+"configs".
+
+Suppose your the following `local.json` is as follows:
+
+<pre>
+ {
+ "configs": {
+ "ff40": ["-b", "/usr/bin/firefox-4.0"]
+ }
+ }
+</pre>
+
+You can run:
+
+<pre>
+ cfx test --use-config=ff40
+</pre>
+
+And it would be equivalent to:
+
+<pre>
+ cfx test -a firefox -b /usr/bin/firefox-4.0
+</pre>
+
+This method of defining configuration options can be used for all of the `run`,
+build, and test tools. If "default" is defined in the `local.json` cfx will use
+that configuration unless otherwise specified.
+
+## <a name="arguments">Passing Static Arguments</a> ##
+
+You can use the cfx `--static-args` option to pass arbitrary data to your
+program. This may be especially useful if you run cfx from a script.
+
+The value of `--static-args` must be a JSON string. The object encoded by the
+JSON becomes the `staticArgs` member of the `options` object passed as the
+first argument to your program's `main` function. The default value of
+`--static-args` is `"{}"` (an empty object), so you don't have to worry about
+checking whether `staticArgs` exists in `options`.
+
+For example, if your `main.js` looks like this:
+
+ exports.main = function (options, callbacks) {
+ console.log(options.staticArgs.foo);
+ };
+
+And you run cfx like this:
+
+<pre>
+ cfx run --static-args="{ \"foo\": \"Hello from the command line\" }"
+</pre>
+
+Then your console should contain this:
+
+<pre>
+ info: Hello from the command line
+</pre>
+
+The `--static-args` option is recognized by two of the package-specific
+commands: `run` and `xpi`. When used with the `xpi` command, the JSON is
+packaged with the XPI's harness options and will therefore be used whenever the
+program in the XPI is run.
View
46 sdk/1.10/dev-guide-source/console.md
@@ -0,0 +1,46 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# console #
+
+The `console` object enables your add-on to log messages. If you have started
+the host application for your add-on from the command line (for example, by
+executing `cfx run` or `cfx test`) then these messages appear in the command
+shell you used. If the add-on has been installed in the host application, then
+the messages appear in the host application's
+[Error Console](https://developer.mozilla.org/en/Error_Console).
+
+The `console` object has the following methods:
+
+<code>console.**log**(*object*[, *object*, ...])</code>
+
+Logs an informational message to the shell.
+Depending on the console's underlying implementation and user interface,
+you may be able to introspect into the properties of non-primitive objects
+that are logged.
+
+<code>console.**info**(*object*[, *object*, ...])</code>
+
+A synonym for `console.log()`.
+
+<code>console.**warn**(*object*[, *object*, ...])</code>
+
+Logs a warning message.
+
+<code>console.**error**(*object*[, *object*, ...])</code>
+
+Logs an error message.
+
+<code>console.**debug**(*object*[, *object*, ...])</code>
+
+Logs a debug message.
+
+<code>console.**exception**(*exception*)</code>
+
+Logs the given exception instance as an error, outputting information
+about the exception's stack traceback if one is available.
+
+<code>console.**trace**()</code>
+
+Logs a stack trace at the point this function is called.
View
68 sdk/1.10/dev-guide-source/credits.md
@@ -0,0 +1,68 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# Credits #
+
+We'd like to thank our many Jetpack project contributors! They include:
+
+* Adamantium
+* Ehsan Akhgari
+* arky
+* [Heather Arthur](https://github.com/harthur)
+* Dietrich Ayala
+* [Romain B](https://github.com/Niamor)
+* Will Bamberg
+* Zbigniew Braniecki
+* Daniel Buchner
+* James Burke
+* [Shane Caraveo](https://github.com/mixedpuppy)
+* [Matěj Cepl](https://github.com/mcepl)
+* Hernán Rodriguez Colmeiro
+* [David Creswick](https://github.com/dcrewi)
+* dexter
+* [Matteo Ferretti (ZER0)](https://github.com/ZER0)
+* fuzzykiller
+* [Marcio Galli](https://github.com/taboca)
+* [Ben Gillbanks](http://www.iconfinder.com/browse/iconset/circular_icons/)
+* Felipe Gomes
+* Irakli Gozalishvili
+* Luca Greco
+* Mark Hammond
+* Lloyd Hilaiel
+* Bobby Holley
+* Eric H. Jung
+* Hrishikesh Kale
+* Wes Kocher
+* Edward Lee
+* Myk Melez
+* Zandr Milewski
+* Noelle Murata
+* Joe R. Nassimian ([placidrage](https://github.com/placidrage))
+* Nick Nguyen
+* [ongaeshi](https://github.com/ongaeshi)
+* Paul O’Shannessy
+* l.m.orchard
+* Alexandre Poirot
+* Nickolay Ponomarev
+* Aza Raskin
+* Till Schneidereit
+* Justin Scott
+* Ayan Shah
+* [skratchdot](https://github.com/skratchdot)
+* [Mihai Sucan](https://github.com/mihaisucan)
+* Clint Talbert
+* Thomas
+* Dave Townsend
+* Peter Van der Beken
+* Atul Varma
+* [Erik Vold](https://github.com/erikvold)
+* Vladimir Vukicevic
+* Brian Warner
+* [Henri Wiechers](https://github.com/hwiechers)
+* Drew Willcoxon
+* Piotr Zalewa
+* [David Guo](https://github.com/dglol)
+* [Nils Maier](https://github.com/nmaier)
+* [Louis-Rémi Babé](https://github.com/louisremi)
+* [Matthias Tylkowski](https://github.com/tylkomat)
View
73 sdk/1.10/dev-guide-source/glossary.md
@@ -0,0 +1,73 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# Glossary #
+
+This glossary contains a list of terms used in the Add-on SDK.
+
+__Add-on__: A software package that adds functionality to a Mozilla application,
+which can be built with either Mozilla's traditional add-on platform or the SDK.
+
+__Add-on SDK__: A toolchain and associated applications for developing add-ons.
+
+__API Utils__: A small, self-contained set of low-level modules that forms
+the base functionality for the SDK. The library can be "bootstrapped" into
+any Mozilla application or add-on.
+
+__CFX__: A command-line build, testing, and packaging tool for SDK-based code.
+
+__CommonJS__: A specification for a cross-platform JavaScript module
+system and standard library. [Web site](http://commonjs.org/).
+
+__Extension__: Synonym for Add-on.
+
+__Globals__: The set of global variables and objects provided
+to all modules, such as `console` and `memory`. Includes
+CommonJS globals like `require` and standard JavaScript globals such
+as `Array` and `Math`.
+
+<span><a name="host-application">__Host Application__:</a> Add-ons are executed in
+the context of a host application, which is the application they are extending.
+Firefox and Thunderbird are the most obvious hosts for Mozilla add-ons, but
+at present only Firefox is supported as a host for add-ons developed using the
+Add-on SDK.</span>
+
+__Jetpack Prototype__: A Mozilla Labs experiment that predated and inspired
+the SDK. The SDK incorporates many ideas and some code from the prototype.
+
+__Loader__: An object capable of finding, evaluating, and
+exposing CommonJS modules to each other in a given security context,
+while providing each module with necessary globals and
+enforcing security boundaries between the modules as necessary. It's
+entirely possible for Loaders to create new Loaders.
+
+__Low-Level Module__: A module with the following properties:
+
+ * Has "chrome" access to the Mozilla platform (e.g. `Components.classes`)
+ and all globals.
+ * Is reloadable without leaking memory.
+ * Logs full exception tracebacks originating from client-provided
+ callbacks (i.e., does not allow the exceptions to propagate into
+ Mozilla platform code).
+ * Can exist side-by-side with multiple instances and versions of
+ itself.
+ * Contains documentation on security concerns and threat modeling.
+
+__Module__: A CommonJS module that is either a Low-Level Module
+or an Unprivileged Module.
+
+__Package__: A directory structure containing modules,
+documentation, tests, and related metadata. If a package contains
+a program and includes proper metadata, it can be built into
+a Mozilla application or add-on.
+
+__Program__: A module named `main` that optionally exports
+a `main()` function. This module is intended either to start an application for
+an end-user or add features to an existing application.
+
+__Unprivileged Module__: A CommonJS module that may be run
+without unrestricted access to the Mozilla platform, and which may use
+all applicable globals that don't require chrome privileges.
+
+ [Low-Level Module Best Practices]: dev-guide/module-development/best-practices.html
View
146 sdk/1.10/dev-guide-source/guides/commonjs.md
@@ -0,0 +1,146 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# CommonJS, Packages, and the SDK #
+
+CommonJS is the underlying infrastructure for both the SDK and the add-ons
+you build using the SDK.
+
+The [CommonJS group](http://wiki.commonjs.org/wiki/CommonJS) defines
+specifications for **modules** and **packages**.
+
+## CommonJS Modules ##
+
+A CommonJS **module** is a piece of reusable JavaScript: it exports certain
+objects which are thus made available to dependent code. To facilitate this
+CommonJS defines:
+
+* an object called `exports` which contains all the objects which a CommonJS
+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.
+
+![CommonJS modules](static-files/media/commonjs-modules.png)
+
+The SDK
+[freezes](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/freeze)
+the `exports` object returned by `require`. So a if you import a module using
+`require`, you can't change the properties of the object returned:
+
+ self = require("self");
+ // Attempting to define a new property
+ // will fail, or throw an exception in strict mode
+ self.foo = 1;
+ // Attempting to modify an existing property
+ // will fail, or throw an exception in strict mode
+ self.data = "foo";
+
+## CommonJS Packages ##
+
+A CommonJS **package** is a structure which can wrap a collection of related
+modules: this makes it easier to distribute, install and manage modules.
+
+Minimally, a package must include a package descriptor file named
+`package.json`: this file contains information about the package such as a short
+description, the authors, and the other packages it depends on.
+
+Packages must also follow a particular directory structure, which is the
+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.
+
+* The JavaScript components of an add-on constitute one or more
+CommonJS modules, and a complete add-on is a CommonJS package.
+
+According to the CommonJS specification, if a module called `main` exists in a
+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.
+
+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
+to use them.
+
+## Packages in the SDK ##
+
+Navigate to the root of your SDK installation and list the contents of
+the "packages" directory:
+
+<pre>
+ls packages
+</pre>
+
+You will see something like this:
+
+<pre>
+addon-kit api-utils test-harness
+</pre>
+
+So the modules which implement the SDK's APIs are
+collected into three packages, `addon-kit`, `api-utils` and `test-harness`.
+
+### <a name="addon-kit">addon-kit</a> ###
+
+Modules in the `addon-kit` package implement high-level APIs for
+building add-ons:
+
+* creating user interfaces
+* interacting with the web
+* interacting with the browser
+
+These modules are "supported": meaning that they are stable, and that
+we'll avoid making incompatible changes to them unless absolutely
+necessary.
+
+They are documented in the "High-Level APIs" section
+of the sidebar.
+
+### <a name="api-utils">api-utils</a> ###
+
+Modules in the `api-utils` package implement low-level APIs. These
+modules fall roughly into three categories:
+
+* fundamental utilities such as
+[collection](packages/api-utils/collection.html) and
+[url](packages/api-utils/url.html). Many add-ons are likely to
+want to use modules from this category.
+
+* building blocks for higher level modules, such as
+[event/core](packages/api-utils/event/core.html),
+[event/target](packages/api-utils/event/target.html),
+[heritage](packages/api-utils/heritage.html), and
+[namespace](packages/api-utils/namespace.html). You're more
+likely to use these if you are building your own modules that
+implement new APIs, thus extending the SDK itself.
+
+* privileged modules that expose powerful low-level capabilities
+such as [xhr](packages/api-utils/xhr.html) and
+[xpcom](packages/api-utils/xpcom.html). You can use these
+modules in your add-on if you need to, but should be aware that
+the cost of privileged access is the need to take more elaborate
+security precautions. In many cases these modules have simpler,
+more restricted analogs in the high-level addon-kit package (for
+example, [tabs](packages/addon-kit/tabs.html) or
+[request](packages/addon-kit/request.html)).
+
+<div class="warning">
+<p>These modules are still in active development,
+and we expect to make incompatible changes to them in future releases.
+</p>
+If you use these modules in your add-on you may need to rewrite your
+code when upgrading to a newer release of the SDK.
+</div>
+
+They are documented in the "Low-Level APIs" section of the sidebar.
+
+### test-harness ###
+
+Modules in this packages are used internally by the SDK's test code.
View
124 sdk/1.10/dev-guide-source/guides/content-scripts/accessing-the-dom.md
@@ -0,0 +1,124 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# Accessing the DOM #
+
+This page talks about the access content scripts have to DOM objects
+in the pages they are attached to.
+
+Content scripts need to be able to access DOM objects in arbitrary web
+pages, but this could cause two potential security problems:
+
+1. JavaScript values from the content script could be accessed by the page,
+enabling a malicious page to steal data or call privileged methods.
+2. a malicious page could redefine standard functions and properties of DOM
+objects so they don't do what the add-on expects.
+
+To deal with this, content scripts access DOM objects via a proxy.
+Any changes they make are made to the proxy, and so are not visible to
+page content.
+
+The proxy is based on `XRayWrapper`, (also known as
+[`XPCNativeWrapper`](https://developer.mozilla.org/en/XPCNativeWrapper)).
+These wrappers give the user access to the native values of DOM functions
+and properties, even if they have been redefined by a script.
+
+For example: the page below redefines `window.confirm()` to return
+`true` without showing a confirmation dialog:
+
+<script type="syntaxhighlighter" class="brush: html"><![CDATA[
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html lang='en' xml:lang='en' xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <script>
+ window.confirm = function(message) {
+ return true;
+ }
+ &lt;/script>
+ </head>
+</html>
+
+</script>
+
+But thanks to the content proxy, a content script which calls
+`window.confirm()` will get the native implementation:
+
+ var widgets = require("widget");
+ var tabs = require("tabs");
+ var data = require("self").data;
+
+ var widget = widgets.Widget({
+ id: "transfer",
+ label: "Transfer",
+ content: "Transfer",
+ width: 100,
+ onClick: function() {
+ tabs.activeTab.attach({
+ // native implementation of window.confirm will be used
+ contentScript: "console.log(window.confirm('Transfer all my money?'));"
+ });
+ }
+ });
+
+ tabs.open(data.url("xray.html"));
+
+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
+a library like [jQuery](http://www.jquery.com), or any other page script
+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/guides/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 above
+so the content script uses `unsafeWindow.confirm()` instead of
+`window.confirm()`.
+
+Avoid using `unsafeWindow` if possible: it is the same concept as
+Greasemonkey's unsafeWindow, and the
+[warnings for that](http://wiki.greasespot.net/UnsafeWindow) apply equally
+here. Also, `unsafeWindow` isn't a supported API, so it could be removed or
+changed in a future version of the SDK.
View
246 sdk/1.10/dev-guide-source/guides/content-scripts/communicating-with-other-scripts.md
@@ -0,0 +1,246 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# Communicating With Other Scripts #
+
+This section of the guide explains how content scripts can
+communicate with:
+
+* [your `main.js` file](dev-guide/guides/content-scripts/communicating-with-other-scripts.html#main.js),
+or any other modules in your add-on
+* [other content scripts loaded by your add-on](dev-guide/guides/content-scripts/communicating-with-other-scripts.html#Content Scripts)
+* [page scripts](dev-guide/guides/content-scripts/communicating-with-other-scripts.html#Page Scripts) (that is, scripts embedded in the web page or
+included using `<script>` tags)
+
+## main.js ##
+
+Your content scripts can communicate with your add-on's "main.js"
+(or any other modules you're written for your add-on) by sending it messages,
+using either the `port.emit()` API or the `postMessage()` API. See the
+articles on
+[using `postMessage()`](dev-guide/guides/content-scripts/using-postmessage.html)
+and
+[using `port`](dev-guide/guides/content-scripts//using-port.html) for details.
+
+## Content Scripts ##
+
+Content scripts loaded into the same document can interact
+with each other directly as well as with the web content itself. However,
+content scripts which have been loaded into different documents
+cannot interact with each other.
+
+For example:
+
+* if an add-on creates a single `panel` object and loads several content
+scripts into the panel, then they can interact with each other
+* if an add-on creates two `panel` objects and loads a script into each
+one, they can't interact with each other.
+* if an add-on creates a single `page-mod` object and loads several content
+scripts into the page mod, then only content scripts associated with the
+same page can interact with each other: if two different matching pages are
+loaded, content scripts attached to page A cannot interact with those attached
+to page B.
+
+The web content has no access to objects created by the content script, unless
+the content script explicitly makes them available.
+
+## Page Scripts ##
+
+If a page includes its own scripts using `<script>` tags,
+either embedded in the page or linked to it using the `src` attribute, there
+are a couple of ways a content script can communicate with it:
+
+* using the [DOM `postMessage()` API](dev-guide/guides/content-scripts/communicating-with-other-scripts.html#Using the DOM postMessage API)
+* using [custom DOM events](dev-guide/guides/content-scripts/communicating-with-other-scripts.html#Using Custom DOM Events)
+
+### Using the DOM postMessage API ###
+
+You can communicate between the content script and page scripts using
+[`window.postMessage()`](https://developer.mozilla.org/en/DOM/window.postMessage),
+but there's a twist: in early versions of the SDK, the global `postMessage()`
+function in content scripts was used for communicating between the content
+script and the main add-on code. Although this has been
+[deprecated in favor of `self.postMessage`](https://wiki.mozilla.org/Labs/Jetpack/Release_Notes/1.0b5#Major_Changes),
+the old globals are still supported, so you can't currently use
+`window.postMessage()`. You must use `document.defaultView.postMessage()`
+instead.
+
+#### Messaging From Content Script To Page Script ####
+
+Suppose we have a page called "listen.html" hosted at "my-domain.org", and we want to send messages
+from the add-on to a script embedded in that page.
+
+In the main add-on code, we have a
+[`page-mod`](packages/addon-kit/page-mod.html) that attaches the content script
+"talk.js" to the right page:
+
+ var data = require("self").data;
+
+ var pageMod = require("page-mod");
+ pageMod.PageMod({
+ include: "http://my-domain.org/listen.html",
+ contentScriptFile: data.url("talk.js")
+ });
+
+The "talk.js" content script uses `document.defaultView.postMessage()` to send
+the message to the page:
+
+ document.defaultView.postMessage("Message from content script", "http://my-domain.org/");
+
+The second argument may be '*' which will allow communication with any domain.
+
+Finally, "listen.html" uses `window.addEventListener()` to listen for
+messages from the content script:
+
+<script type="syntaxhighlighter" class="brush: html"><![CDATA[
+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;&lt;/head&gt;
+ &lt;body&gt;
+ &lt;script&gt;
+ window.addEventListener('message', function(event) {
+ window.alert(event.data);
+ }, false);
+ &lt;/script&gt;
+ &lt;/body&gt;
+
+&lt;/html&gt;
+]]>
+</script>
+
+#### Messaging From Page Script To Content Script ####
+
+Sending messages from the page script to the content script is just
+the same, but in reverse.
+
+Here "main.js" creates a [`page-mod`](packages/addon-kit/page-mod.html)
+that attaches "listen.js" to the web page:
+
+ var data = require("self").data;
+
+ var pageMod = require("page-mod");
+ pageMod.PageMod({
+ include: "http://my-domain.org/talk.html",
+ contentScriptFile: data.url("listen.js")
+ });
+
+The web page "talk.html" embeds a script that uses `window.postMessage()`
+to send the content script a message when the user clicks a button:
+
+<script type="syntaxhighlighter" class="brush: html"><![CDATA[
+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;&lt;/head&gt;
+ &lt;body&gt;
+ &lt;script&gt;
+ function sendMessage() {
+ window.postMessage("Message from page script", "http://my-domain.org/");
+ }
+ &lt;/script&gt;
+ &lt;button onclick="sendMessage()"&gt;Send Message&lt;/button&gt;
+ &lt;/body&gt;
+
+&lt;/html&gt;
+</script>
+
+Finally, the content script "listen.js" uses
+`document.defaultView.addEventListener()` to listen for messages from the page
+script:
+
+ document.defaultView.addEventListener('message', function(event) {
+ console.log(event.data);
+ console.log(event.origin);
+ }, false);
+
+### Using Custom DOM Events ###
+
+As an alternative to using `postMessage()` you can use
+[custom DOM events](https://developer.mozilla.org/en/DOM/CustomEvent)
+to communicate between page scripts and content scripts.
+
+#### Messaging From Content Script To Page Script ####
+
+Here's an example showing how to use custom DOM events to send a message
+from a content script to a page script.
+
+First, "main.js" will create a [`page-mod`](packages/addon-kit/page-mod.html)
+that will attach "talk.js" to the target web page:
+
+ var data = require("self").data;
+
+ var pageMod = require("page-mod");
+ pageMod.PageMod({
+ include: "http://my-domain.org/listen.html",
+ contentScriptFile: data.url("talk.js")
+ });
+
+Next, "talk.js" creates and dispatches a custom event, passing the payload
+in the `detail` parameter to `initCustomEvent()`:
+
+<!-- This comment is used to terminate the Markdown list above -->
+
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent("addon-message", true, true, { hello: 'world' });
+ document.documentElement.dispatchEvent(event);
+
+Finally "listen.html" listens for the new event and examines its
+`detail` attribute to retrieve the payload:
+
+<script type="syntaxhighlighter" class="brush: html"><![CDATA[
+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;&lt;/head&gt;
+ &lt;body&gt;
+ &lt;script&gt;
+ document.documentElement.addEventListener("addon-message", function(event) {
+ window.alert(JSON.stringify(event.detail))
+ }, false);
+ &lt;/script&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</script>
+
+#### Messaging From Page Script to Content Script ####
+
+Sending messages using custom DOM events from the page script
+to the content script is just the same, but in reverse.
+
+Again, "main.js" creates a [`page-mod`](packages/addon-kit/page-mod.html)
+to target the page we are interested in:
+
+ var data = require("self").data;
+
+ var pageMod = require("page-mod");
+ pageMod.PageMod({
+ include: "http://my-domain.org/talk.html",
+ contentScriptFile: data.url("listen.js")
+ });
+
+The web page "talk.html" creates and dispatches a custom DOM event,
+using `initCustomEvent()`'s `detail` parameter to supply the payload:
+
+<script type="syntaxhighlighter" class="brush: html"><![CDATA[
+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;&lt;/head&gt;
+ &lt;body&gt;
+ &lt;script&gt;
+ function sendMessage() {
+ var event = document.createEvent('CustomEvent');
+ event.initCustomEvent("addon-message", true, true, { hello: 'world' });
+ document.documentElement.dispatchEvent(event);
+ }
+ &lt;/script&gt;
+ &lt;button onclick="sendMessage()"&gt;Send Message&lt;/button&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</script>
+
+Finally, the content script "listen.js" listens for the new event
+and retrieves the payload from its `detail` attribute:
+
+ document.documentElement.addEventListener("addon-message", function(event) {
+ console.log(JSON.stringify(event.detail));
+ }, false);
+
View
93 sdk/1.10/dev-guide-source/guides/content-scripts/index.md
@@ -0,0 +1,93 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# Content Scripts #
+
+Almost all interesting add-ons will need to interact with web content or the
+browser's user interface. For example, they may need to access and modify the
+content of web pages or be notified when the user clicks a link.
+
+The SDK provides several core modules to support this:
+
+**[panel](packages/addon-kit/panel.html)**<br>
+Create a dialog that can host web content.
+
+**[page-worker](packages/addon-kit/page-worker.html)**<br>
+Retrieve a page and access its content, without displaying it to the user.
+
+**[page-mod](packages/addon-kit/page-mod.html)**<br>
+Execute scripts in the context of selected web pages.
+
+**[widget](packages/addon-kit/widget.html)**<br>
+Host an add-on's user interface, including web content.
+
+**[context-menu](packages/addon-kit/context-menu.html)**<br>
+Add items to the browser's context menu.
+
+Firefox is moving towards a model in which it uses separate
+processes to display the UI, handle web content, and execute add-ons. The main
+add-on code will run in the add-on process and will not have direct access to
+any web content.
+
+This means that an add-on which needs to interact with web content needs to be
+structured in two parts:
+
+* the main script runs in the add-on process
+* any code that needs to interact with web content is loaded into the web
+content process as a separate script. These separate scripts are called
+_content scripts_.
+
+A single add-on may use multiple content scripts, and content scripts loaded
+into the same context can interact directly with each other as well as with
+the web content itself. See the chapter on
+<a href="dev-guide/guides/content-scripts/communicating-with-other-scripts.html">
+communicating with other scripts</a>.
+
+The add-on script and content script can't directly access each other's state.
+Instead, you can define your own events which each side can emit, and the
+other side can register listeners to handle them. The interfaces are similar
+to the event-handling interfaces described in the
+[Working with Events](dev-guide/guides/events.html) guide.
+
+The diagram below shows an overview of the main components and their
+relationships. The gray fill represents code written by the add-on developer.
+
+<img class="image-center" src="static-files/media/content-scripting-overview.png"
+alt="Content script events">
+
+This might sound complicated but it doesn't need to be. The following add-on
+uses the [page-mod](packages/addon-kit/page-mod.html) module to replace the
+content of any web page in the `.co.uk` domain by executing a content script
+in the context of that page:
+
+ var pageMod = require("page-mod");
+
+ pageMod.add(new pageMod.PageMod({
+ include: ["*.co.uk"],
+ contentScript: 'document.body.innerHTML = ' +
+ '"<h1>this page has been eaten</h1>";'
+ }));
+
+In this example the content script is supplied directly to the page mod via
+the `contentScript` option in its constructor, and does not need to be
+maintained as a separate file at all.
+
+The next few chapters explain content scripts in detail:
+
+* [Loading Content Scripts](dev-guide/guides/content-scripts/loading.html):
+how to attach content scripts to web pages, and how to control the point at
+which they are executed
+* [Accessing the DOM](dev-guide/guides/content-scripts/accessing-the-dom.html):
+detail about the access content scripts get to the DOM
+* [Communicating With Other Scripts](dev-guide/guides/content-scripts/communicating-with-other-scripts.html):
+detail about how content scripts can communicate with "main.js", with other
+content scripts, and with scripts loaded by the web page itself
+* [Communicating Using <code>port</code>](dev-guide/guides/content-scripts/using-port.html):
+how to communicate between your add-on and its content scripts using the
+<code>port</code> object
+* [Communicating using <code>postMessage()</code>](dev-guide/guides/content-scripts/using-postmessage.html):
+how to communicate between your add-on and its content scripts using the
+<code>postMessage()</code> API
+* [Example](dev-guide/guides/content-scripts/reddit-example.html):
+a simple example add-on using content scripts
View
79 sdk/1.10/dev-guide-source/guides/content-scripts/loading.md
@@ -0,0 +1,79 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+
+# Loading Content Scripts #
+
+The constructors for content-script-using objects such as panel and page-mod
+define a group of options for loading content scripts:
+
+<pre>
+ contentScript string, array
+ contentScriptFile string, array
+ contentScriptWhen string
+ contentScriptOptions object
+</pre>
+
+We have already seen the `contentScript` option, which enables you to pass
+in the text of the script itself as a string literal. This version of the API
+avoids the need to maintain a separate file for the content script.
+
+The `contentScriptFile` option enables you to pass in the local file URL from
+which the content script will be loaded. To supply the file
+"my-content-script.js", located in the /data subdirectory under your package's
+root directory, use a line like:
+
+ // "data" is supplied by the "self" module
+ var data = require("self").data;
+ ...
+ contentScriptFile: data.url("my-content-script.js")
+
+Both `contentScript` and `contentScriptFile` accept an array of strings, so you
+can load multiple scripts, which can also interact directly with each other in
+the content process:
+
+ // "data" is supplied by the "self" module
+ var data = require("self").data;
+ ...
+ contentScriptFile:
+ [data.url("jquery-1.4.2.min.js"), data.url("my-content-script.js")]
+
+Scripts specified using contentScriptFile are loaded before those specified
+using contentScript. This enables you to load a JavaScript library like jQuery
+by URL, then pass in a simple script inline that can use jQuery.
+
+<div class="warning">
+<p>Unless your content script is extremely simple and consists only of a
+static string, don't use <code>contentScript</code>: if you do, you may
+have problems getting your add-on approved on AMO.</p>
+<p>Instead, keep the script in a separate file and load it using
+<code>contentScriptFile</code>. This makes your code easier to maintain,
+secure, debug and review.</p>
+</div>
+
+The `contentScriptWhen` option specifies when the content script(s) should be
+loaded. It takes one of three possible values:
+
+* "start" loads the scripts immediately after the document element for the
+page is inserted into the DOM. At this point the DOM content hasn't been
+loaded yet, so the script won't be able to interact with it.
+
+* "ready" loads the scripts after the DOM for the page has been loaded: that
+is, at the point the
+[DOMContentLoaded](https://developer.mozilla.org/en/Gecko-Specific_DOM_Events)
+event fires. At this point, content scripts are able to interact with the DOM
+content, but externally-referenced stylesheets and images may not have finished
+loading.
+
+* "end" loads the scripts after all content (DOM, JS, CSS, images) for the page
+has been loaded, at the time the
+[window.onload event](https://developer.mozilla.org/en/DOM/window.onload)
+fires.
+
+The default value is "end".
+
+The `contentScriptOptions` is a json that is exposed to content scripts as a read
+only value under `self.options` property.
+
+Any kind of jsonable value (object, array, string, etc.) can be used here.
View
71 sdk/1.10/dev-guide-source/guides/content-scripts/reddit-example.md
@@ -0,0 +1,71 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# Reddit Example #
+
+This example add-on creates a panel containing the mobile version of Reddit.
+When the user clicks on the title of a story in the panel, the add-on opens
+the linked story in a new tab in the main browser window.
+
+To accomplish this the add-on needs to run a content script in the context of
+the Reddit page which intercepts mouse clicks on each title link and fetches the
+link's target URL. The content script then needs to send the URL to the add-on
+script.
+
+This is the complete add-on script:
+
+ var data = require("self").data;
+
+ var reddit_panel = require("panel").Panel({
+ width: 240,
+ height: 320,
+ contentURL: "http://www.reddit.com/.mobile?keep_extension=True",
+ contentScriptFile: [data.url("jquery-1.4.4.min.js"),
+ data.url("panel.js")]
+ });
+
+ reddit_panel.port.on("click", function(url) {
+ require("tabs").open(url);
+ });
+
+ require("widget").Widget({
+ id: "open-reddit-btn",
+ label: "Reddit",
+ contentURL: "http://www.reddit.com/static/favicon.ico",
+ panel: reddit_panel
+ });
+
+This code supplies two content scripts to the panel's constructor in the
+`contentScriptFile` option: the jQuery library and the script that intercepts
+link clicks.
+
+Finally, it registers a listener to the user-defined `click` event which in
+turn passes the URL into the `open` function of the
+[tabs](packages/addon-kit/tabs.html) module.
+
+This is the `panel.js` content script that intercepts link clicks:
+
+ $(window).click(function (event) {
+ var t = event.target;
+
+ // Don't intercept the click if it isn't on a link.
+ if (t.nodeName != "A")
+ return;
+
+ // Don't intercept the click if it was on one of the links in the header
+ // or next/previous footer, since those links should load in the panel itself.
+ if ($(t).parents('#header').length || $(t).parents('.nextprev').length)
+ return;
+
+ // Intercept the click, passing it to the addon, which will load it in a tab.
+ event.stopPropagation();
+ event.preventDefault();
+ self.port.emit('click', t.toString());
+ });
+
+This script uses jQuery to interact with the DOM of the page and the
+`self.port.emit` function to pass URLs back to the add-on script.
+
+See the `examples/reddit-panel` directory for the complete example (including
+the content script containing jQuery).
View
183 sdk/1.10/dev-guide-source/guides/content-scripts/using-port.md
@@ -0,0 +1,183 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+
+# Communicating using "port" #
+
+To enable add-on scripts and content scripts to communicate with each other,
+each end of the conversation has access to a `port` object which defines two
+functions:
+
+**`emit()`** is used to emit an event. It may be called with any number of
+parameters, but is most likely to be called with a name for the event and
+an optional payload. The payload can be any value that is
+<a href = "dev-guide/guides/content-scripts/using-port.html#json_serializable">serializable to JSON</a>
+
+ port.emit("myEvent", myEventPayload);
+
+**`on()`** takes two parameters: the name of the event and a function to handle it:
+
+ port.on("myEvent", function handleMyEvent(myEventPayload) {
+ // Handle the event
+ });
+
+Here's simple add-on that sends a message to a content script using `port`:
+
+ var tabs = require("tabs");
+
+ var alertContentScript = "self.port.on('alert', function(message) {" +
+ " window.alert(message);" +
+ "})";
+
+ tabs.on("ready", function(tab) {
+ worker = tab.attach({
+ contentScript: alertContentScript
+ });
+ worker.port.emit("alert", "Message from the add-on");
+ });
+
+ tabs.open("http://www.mozilla.org");
+
+We could depict the interface between add-on code and content script code like
+this:
+
+<img class="image-center" src="static-files/media/content-scripting-events.png"
+alt="Content script events">
+
+Events are asynchronous: that is, the sender does not wait for a reply from
+the recipient but just emits the event and continues processing.
+
+## Accessing `port` in the Content Script ##
+
+<span class="aside">Note that the global `self` object is completely
+different from the [`self` module](packages/addon-kit/self.html), which
+provides an API for an add-on to access its data files and ID.</span>
+
+In the content script the `port` object is available as a property of the
+global `self` object. Thus, to emit an event from a content script:
+
+ self.port.emit("myContentScriptEvent", myContentScriptEventPayload);
+
+To receive an event from the add-on code:
+
+ self.port.on("myAddonEvent", function(myAddonEventPayload) {
+ // Handle the event
+ });
+
+Compare this to the technique used to receive _built-in_ events in the
+content script. For example, to receive the `context` event in a content script
+associated with a [context menu](packages/addon-kit/context-menu.html)
+object, you would call the `on` function attached to the global `self` object:
+
+ self.on("context", function() {
+ // Handle the event
+ });
+
+So the `port` property is essentially used here as a namespace for
+user-defined events.
+
+## Accessing `port` in the Add-on Script ##
+
+In the add-on code, the channel of communication between the add-on and a
+particular content script context is encapsulated by the `worker` object. Thus
+the `port` object for communicating with a content script is a property of the
+corresponding `worker` object.
+
+However, the worker is not exposed to add-on code in quite the same way
+in all modules. The `panel` and `page-worker` objects integrate the
+worker API directly. So to receive events from a content script associated
+with a panel you use `panel.port.on()`:
+
+ var panel = require("panel").Panel({
+ contentScript: "self.port.emit('showing', 'panel is showing');"
+ });
+
+ panel.port.on("showing", function(text) {
+ console.log(text);
+ });
+
+ panel.show();
+
+Conversely, to emit user-defined events from your add-on you can just call
+`panel.port.emit()`:
+
+ var panel = require("panel").Panel({
+ contentScript: "self.port.on('alert', function(text) {" +
+ " console.log(text);" +
+ "});"
+ });
+
+ panel.show();
+ panel.port.emit("alert", "panel is showing");
+
+The `panel` and `page-worker` objects only host a single page at a time,
+so each distinct page object only needs a single channel of communication
+to its content scripts. But some modules, such as `page-mod`, might need to
+handle multiple pages, each with its own context in which the content scripts
+are executing, so it needs a separate channel (worker) for each page.
+
+So `page-mod` does not integrate the worker API directly: instead, each time a
+content script is attached to a page, the worker associated with the page is
+supplied to the page-mod in its `onAttach` function. By supplying a target for
+this function in the page-mod's constructor you can register to receive
+events from the content script, and take a reference to the worker so as to
+emit events to it.
+
+ var pageModScript = "window.addEventListener('click', function(event) {" +
+ " self.port.emit('click', event.target.toString());" +
+ " event.stopPropagation();" +
+ " event.preventDefault();" +
+ "}, false);" +
+ "self.port.on('warning', function(message) {" +
+ "window.alert(message);" +
+ "});"
+
+ var pageMod = require('page-mod').PageMod({
+ include: ['*'],
+ contentScript: pageModScript,
+ onAttach: function(worker) {
+ worker.port.on('click', function(html) {
+ worker.port.emit('warning', 'Do not click this again');
+ });
+ }
+ });
+
+In the add-on above there are two user-defined events:
+
+* `click` is sent from the page-mod to the add-on, when the user clicks an
+element in the page
+* `warning` sends a silly string back to the page-mod
+
+## <a name="json_serializable">JSON-Serializable Values</a> ##
+
+The payload for an event can be any JSON-serializable value. When events are
+sent their payloads are automatically serialized, and when events are received
+their payloads are automatically deserialized, so you don't need to worry
+about serialization.
+
+However, you _do_ have to ensure that the payload can be serialized to JSON.
+This means that it needs to be a string, number, boolean, null, array of
+JSON-serializable values, or an object whose property values are themselves
+JSON-serializable. This means you can't send functions, and if the object
+contains methods they won't be encoded.
+
+For example, to include an array of strings in the payload:
+
+ var pageModScript = "self.port.emit('loaded'," +
+ " [" +
+ " document.location.toString()," +
+ " document.title" +
+ " ]" +
+ ");"
+
+ var pageMod = require('page-mod').PageMod({
+ include: ['*'],
+ contentScript: pageModScript,
+ onAttach: function(worker) {
+ worker.port.on('loaded', function(pageInfo) {
+ console.log(pageInfo[0]);
+ console.log(pageInfo[1]);
+ });
+ }
+ });
View
184 sdk/1.10/dev-guide-source/guides/content-scripts/using-postmessage.md
@@ -0,0 +1,184 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# Communicating using "postMessage()" #
+
+As an alternative to user-defined events content modules support the built-in
+`message` event. In most cases user-defined events are preferable to message
+events. However, the `context-menu` module does not support user-defined
+events, so to send messages from a content script to the add-on via a context
+menu object, you must use message events.
+
+## Handling Message Events in the Content Script ##
+
+To send a message from a content script, you use the `postMessage` function of
+the global `self` object:
+
+ self.postMessage(contentScriptMessage);
+
+This takes a single parameter, the message payload, which may be any
+<a href = "dev-guide/guides/content-scripts/using-port.html#json_serializable">JSON-serializable value</a>.
+
+To receive a message from the add-on script, use `self`'s `on` function:
+
+ self.on("message", function(addonMessage) {
+ // Handle the message
+ });
+
+Like all event-registration functions, this takes two parameters: the name
+of the event, and the handler function. The handler function is passed the
+message payload.
+
+## Handling Message Events in the Add-on Script ##
+
+To send a message to a content script, use the worker's `postMessage`
+function. Again, `panel` and `page` integrate `worker` directly:
+
+ // Post a message to the panel's content scripts
+ panel.postMessage(addonMessage);
+
+However, for `page-mod` objects you need to listen to the `onAttach` event
+and use the worker supplied to that:
+
+ var pageMod = require('page-mod').PageMod({
+ include: ['*'],
+ contentScript: pageModScript,
+ onAttach: function(worker) {
+ worker.postMessage(addonMessage);
+ }
+ });
+
+To receive messages from a content script, use the worker's `on` function.
+To simplify this most content modules provide an `onMessage` property as an
+argument to the constructor:
+
+ panel = require("panel").Panel({
+ onMessage: function(contentScriptMessage) {
+ // Handle message from the content script
+ }
+ });
+
+## Timing Issues Using postMessage ##
+
+Content scripts are loaded according to the value of the
+[`contentScriptWhen`](dev-guide/guides/content-scripts/loading.html)
+option: until that point is reached, any attempt to send a message to
+the script using `postMessage()` will trigger an exception, probably
+the unintuitive message:
+
+<span class="aside">
+This is a generic message which is emitted whenever we try to
+send a message to a content script, but can't find the worker
+which is supposed to receive it.
+</span>
+
+<pre>
+Error: The page has been destroyed and can no longer be used.
+</pre>
+
+So code like this, where we create a panel and then
+synchronously send it a message using `postMessage()`, will not work:
+
+ var data = require("self").data;
+
+ var panel = require("panel").Panel({
+ contentURL: "http://www.bbc.co.uk/mobile/index.html",
+ contentScriptFile: data.url("panel.js")
+ });
+
+ panel.postMessage("hi from main.js");
+
+[`port.emit()`](dev-guide/guides/content-scripts/using-port.html)
+queues messages until the content script is ready to receive them,
+so the equivalent code using `port.emit()` will work:
+
+ var data = require("self").data;
+
+ var panel = require("panel").Panel({
+ contentURL: "http://www.bbc.co.uk/mobile/index.html",
+ contentScriptFile: data.url("panel.js")
+ });
+
+ panel.port.emit("hi from main.js");
+
+
+## Message Events Versus User-Defined Events ##
+
+You can use message events as an alternative to user-defined events:
+
+ var pageModScript = "window.addEventListener('mouseover', function(event) {" +
+ " self.postMessage(event.target.toString());" +
+ "}, false);";
+
+ var pageMod = require('page-mod').PageMod({
+ include: ['*'],
+ contentScript: pageModScript,
+ onAttach: function(worker) {
+ worker.on('message', function(message) {
+ console.log('mouseover: ' + message);
+ });
+ }
+ });
+
+The reason to prefer user-defined events is that as soon as you need to send
+more than one type of message, then both sending and receiving messages gets
+more complex.
+
+Suppose the content script wants to send `mouseout` events as well as
+`mouseover`. Now we have to embed the event type in the message payload, and
+implement a switch function in the receiver to dispatch the message:
+
+ var pageModScript = "window.addEventListener('mouseover', function(event) {" +
+ " self.postMessage({" +
+ " kind: 'mouseover'," +
+ " element: event.target.toString()" +
+ " });" +
+ "}, false);" +
+ "window.addEventListener('mouseout', function(event) {" +
+ " self.postMessage({" +
+ " kind: 'mouseout'," +
+ " element: event.target.toString()" +
+ " });" +
+ " }, false);"
+
+
+ var pageMod = require('page-mod').PageMod({
+ include: ['*'],
+ contentScript: pageModScript,
+ onAttach: function(worker) {
+ worker.on('message', function(message) {
+ switch(message.kind) {
+ case 'mouseover':
+ console.log('mouseover: ' + message.element);
+ break;
+ case 'mouseout':
+ console.log('mouseout: ' + message.element);
+ break;
+ }
+ });
+ }
+ });
+
+Implementing the same add-on with user-defined events is shorter and more
+readable:
+
+ var pageModScript = "window.addEventListener('mouseover', function(event) {" +
+ " self.port.emit('mouseover', event.target.toString());" +
+ "}, false);" +
+ "window.addEventListener('mouseout', function(event) {" +
+ " self.port.emit('mouseout', event.target.toString());" +
+ "}, false);";
+
+ var pageMod = require('page-mod').PageMod({
+ include: ['*'],
+ contentScript: pageModScript,
+ onAttach: function(worker) {
+ worker.port.on('mouseover', function(message) {
+ console.log('mouseover :' + message);
+ });
+ worker.port.on('mouseout', function(message) {
+ console.log('mouseout :' + message);
+ });
+ }
+ });
View
153 sdk/1.10/dev-guide-source/guides/events.md
@@ -0,0 +1,153 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+# Working with Events #
+
+The Add-on SDK supports event-driven programming through its
+[`EventEmitter`](packages/api-utils/events.html) framework.
+
+Objects emit events on state changes that might be of interest to add-on code,
+such as browser windows opening, pages loading, network requests completing,
+and mouse clicks. By registering a listener function to an event emitter an
+add-on can receive notifications of these events.
+
+<span class="aside">
+We talk about content
+scripts in more detail in the
+[Working with Content Scripts](dev-guide/guides/content-scripts/index.html)
+guide.</span>
+Additionally, if you're using content scripts to interact with web content,
+you can define your own events and use them to communicate between the main
+add-on code and the content scripts. In this case one end of the conversation
+emits the events, and the other end listens to them.
+
+So there are two main ways you will interact with the EventEmitter
+framework:
+
+* **listening to built-in events** emitted by objects in the SDK, such as tabs
+opening, pages loading, mouse clicks
+
+* **sending and receiving user-defined events** between content scripts and
+add-on code
+
+This guide only covers the first of these; the second is explained in the
+[Working with Content Scripts](dev-guide/guides/content-scripts/index.html)
+guide.
+
+## Adding Listeners ##
+
+You can add a listener to an event emitter by calling its `on(type, listener)`
+method.
+
+It takes two parameters:
+
+* **`type`**: the type of event we are interested in, identified by a string.
+Many event emitters may emit more than one type of event: for example, a browser
+window might emit both `open` and `close` events. The list of valid event types
+is specific to an event emitter and is included with its documentation.
+
+* **`listener`**: the listener itself. This is a function which will be called
+whenever the event occurs. The arguments that will be passed to the listener
+are specific to an event type and are documented with the event emitter.
+
+For example, the following add-on registers two listeners with the
+[`private-browsing`](packages/addon-kit/private-browsing.html) module to
+listen for the `start` and `stop` events, and logs a string to the console
+reporting the change:
+
+ var pb = require("private-browsing");
+
+ pb.on("start", function() {
+ console.log("Private browsing is on");
+ });
+
+ pb.on("stop", function() {
+ console.log("Private browsing is off");
+ });
+
+It is not possible to enumerate the set of listeners for a given event.
+
+The value of `this` in the listener function is the object that emitted
+the event.
+
+### Adding Listeners in Constructors ###
+
+Event emitters may be modules, as is the case for the
+`private-browsing` events, or they may be objects returned by
+constructors.
+
+In the latter case the `options` object passed to the constructor typically
+defines properties whose names are the names of supported event types prefixed
+with "on": for example, "onOpen", "onReady" and so on. Then in the constructor
+you can assign a listener function to this property as an alternative to
+calling the object's `on()` method.
+
+For example: the [`widget`](packages/addon-kit/widget.html) object emits
+an event when the widget is clicked.
+
+The following add-on creates a widget and assigns a listener to the
+`onClick` property of the `options` object supplied to the widget's
+constructor. The listener loads the Google home page:
+
+ var widgets = require("widget");
+ var tabs = require("tabs");
+
+ widgets.Widget({
+ id: "google-link",
+ label: "Widget with an image and a click handler",
+ contentURL: "http://www.google.com/favicon.ico",
+ onClick: function() {
+ tabs.open("http://www.google.com/");
+ }
+ });
+
+This is exactly equivalent to constructing the widget and then calling the
+widget's `on()` method:
+
+ var widgets = require("widget");
+ var tabs = require("tabs");
+
+ var widget = widgets.Widget({
+ id: "google-link-alternative",
+ label: "Widget with an image and a click handler",
+ contentURL: "http://www.google.com/favicon.ico"
+ });
+
+ widget.on("click", function() {
+ tabs.open("http://www.google.com/");
+ });
+
+## Removing Event Listeners ##
+
+Event listeners can be removed by calling `removeListener(type, listener)`,
+supplying the type of event and the listener to remove.
+
+The listener must have been previously been added using one of the methods
+described above.
+
+In the following add-on, we add two listeners to private-browsing's `start`
+event, enter and exit private browsing, then remove the first listener and
+enter private browsing again.
+
+ var pb = require("private-browsing");