WebExtensions/Hacking: Difference between revisions

Add link to WebExtension-specific Try server article
(Fix typo and consistent quotes in eslint for vim section)
(Add link to WebExtension-specific Try server article)
 
(10 intermediate revisions by 3 users not shown)
Line 20: Line 20:


ESLint will enforce most of these rules.
ESLint will enforce most of these rules.
== Code Guidelines ==
For Chrome APIs we'll support the callback interface to maintain compatibility. For new APIs, not Chrome ones, we'll use the promise interface to all APIs. See the [https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API#Callbacks_and_promises MDN docs] for the difference.


== Checking your code with ESLint ==
== Checking your code with ESLint ==
Line 25: Line 29:
All WebExtension directories in <code>mozilla-central</code> are configured with a set of ESLint rules, which all code is required to pass. Many of these rules help to catch serious errors, such as references to non-existent variables, or a missing trailing comma turning an array literal into an array dereference, so it is extremely important that you check you code against them before it lands.
All WebExtension directories in <code>mozilla-central</code> are configured with a set of ESLint rules, which all code is required to pass. Many of these rules help to catch serious errors, such as references to non-existent variables, or a missing trailing comma turning an array literal into an array dereference, so it is extremely important that you check you code against them before it lands.


The simplest way to check your code is using the <code>mach eslint</code> command. This requires that you have [https://docs.npmjs.com/ NPM] installed (and, if you're on Linux, it may require that you [https://docs.npmjs.com/getting-started/fixing-npm-permissions fix NPM permissions]).
The simplest way to check your code is using the <code>mach eslint</code> command. This requires that you have [https://docs.npmjs.com/ NPM] installed.


To setup ESLint, you need to run the following once:
To setup ESLint, you need to run the following once:
Line 53: Line 57:
The following assumes that you use the [https://github.com/VundleVim/Vundle.vim Vundle package manager]. It should be easy enough to adapt to any other package manager you happen to prefer, though.
The following assumes that you use the [https://github.com/VundleVim/Vundle.vim Vundle package manager]. It should be easy enough to adapt to any other package manager you happen to prefer, though.


You should configure Syntastic roughly as follows:
<code>mach eslint --setup</code> installs a specific ESLint version and some ESLint plugins to a subdirectory of the repository ([https://bugzilla.mozilla.org/show_bug.cgi?id=1305023 changed in Firefox 55]).
You should configure Syntastic roughly as follows (change <code>/path/to/mozilla-central</code> as needed):


  " Initialize Vundle.
  " Initialize Vundle.
Line 62: Line 67:
  Bundle 'scrooloose/syntastic'
  Bundle 'scrooloose/syntastic'
   
   
  " Enable ESLint in Syntastic.
  " Enable the specific ESLint checker for files in mozilla-central/ only.
let g:syntastic_javascript_checkers = ['eslint']
  " Enable the HTML plugin, and enable JavaScript linting for HTML files.
  " Enable the HTML plugin, and enable JavaScript linting for HTML files.
  let g:syntastic_javascript_eslint_args = ['--plugin', 'html']
  autocmd FileType javascript,html
let g:syntastic_filetype_map = { 'html': 'javascript' }
    \ if stridx(expand("%:p"), "/mozilla-central/") != -1 |
    \    let b:syntastic_checkers = ['eslint'] |
    \    let b:syntastic_eslint_exec = '/path/to/mozilla-central/node_modules/.bin/eslint' |
    \    let b:syntastic_html_eslint_args = ['--plugin', 'html'] |
    \ endif


After you've added this to your configuration (and have installed Vundle, if necessary), launch Vim and run:
After you've added this to your configuration (and have installed Vundle, if necessary), launch Vim and run:
Line 100: Line 107:
;xpcshell tests
;xpcshell tests
: These reside under <code>toolkit/components/extensions/test/xpcshell/</code>, and are used to test low-level modules which do not require a browser UI, including those under <code>toolkit/modules/addons/</code>, <code>toolkit/components/utils/simpleServices.js</code>, and various pieces of C++ code.
: These reside under <code>toolkit/components/extensions/test/xpcshell/</code>, and are used to test low-level modules which do not require a browser UI, including those under <code>toolkit/modules/addons/</code>, <code>toolkit/components/utils/simpleServices.js</code>, and various pieces of C++ code.
[[WebExtensions/Try_Server]] has more information about using the try server to test WebExtension code.
=== Test tag ===
All tests in WebExtensions are [https://bugzilla.mozilla.org/show_bug.cgi?id=1296888 now tagged] with the tag: <code>webextensions</code>, so you can pass the <code>--tag</code> argument to <code>mochitest</code>, <code>xpcshell-test</code> and the [http://trychooser.pub.build.mozilla.org/ try server syntax].


=== Code coverage tests ===
=== Code coverage tests ===
Line 118: Line 131:
The above results are generated using [https://people.mozilla.org/~kmaglione/webext-coverage.patch this patch], which could generously be described as a fairly gross hack. If you'd like to run the tests yourself, you can do so with something like the following:
The above results are generated using [https://people.mozilla.org/~kmaglione/webext-coverage.patch this patch], which could generously be described as a fairly gross hack. If you'd like to run the tests yourself, you can do so with something like the following:


  # Install the Instanbul code coverage tool
  # Install the Istanbul code coverage tool
  npm install -g istanbul
  npm install -g istanbul


Line 159: Line 172:
Each API module must be explicitly registered, in order to be loaded. It must also register a schema if it exports any APIs to extensions.
Each API module must be explicitly registered, in order to be loaded. It must also register a schema if it exports any APIs to extensions.


Generic APIs are registered in <code>Extension.jsm</code> as follows:
Starting from Firefox 50 ([https://bugzilla.mozilla.org/1285063 Bug 1285063], [https://hg.mozilla.org/mozilla-central/rev/e9ca8dc4b42e hg commit e9ca8dc4b42e]) all the APIs schema and <code>ext-*.js</code> files must be registered to the category manager through one of the following manifest files:
 
* [https://dxr.mozilla.org/mozilla-central/source/toolkit/components/extensions/extensions-toolkit.manifest toolkit/components/extensions/extensions-toolkit.manifest], for Generic APIs registered at toolkit level
* [https://dxr.mozilla.org/mozilla-central/source/browser/components/extensions/extensions-browser.manifest browser/components/extensions/extensions-browser.manifest], for Firefox desktop APIs
* [https://dxr.mozilla.org/mozilla-central/source/mobile/android/components/extensions/extensions-mobile.manifest mobile/android/components/extensions/extensions-mobile.manifest], for Firefox for Android APIs
 
As an example, here is a snippet of the <code>extension-toolkit.manifest</code>:
# scripts
category webextension-scripts alarms chrome://extensions/content/ext-alarms.js
...
# schemas
category webextension-schemas alarms chrome://extensions/content/schemas/alarms.json
 
In previous Firefox versions, schemas and <code>ext-*.js</code> files were statically
registered through <code>Extension.jsm</code> and <code>nsBrowserGlue.js</code> source
files:
 
Generic APIs were registered in <code>Extension.jsm</code> as follows:


  ExtensionManagement.registerScript("chrome://extensions/content/ext-foobar.js");
  ExtensionManagement.registerScript("chrome://extensions/content/ext-foobar.js");
Line 165: Line 197:
  ExtensionManagement.registerSchema("chrome://extensions/content/schemas/foobar.json");
  ExtensionManagement.registerSchema("chrome://extensions/content/schemas/foobar.json");


Firefox desktop APIs are registered in [https://dxr.mozilla.org/mozilla-central/source/browser/components/nsBrowserGlue.js nsBrowserGlue.js]:
Firefox desktop APIs were registered in [https://dxr.mozilla.org/mozilla-central/source/browser/components/nsBrowserGlue.js nsBrowserGlue.js]:


  ExtensionManagement.registerScript("chrome://browser/content/ext-bazquux.js");
  ExtensionManagement.registerScript("chrome://browser/content/ext-bazquux.js");
   
   
  ExtensionManagement.registerSchema("chrome://browser/content/schemas/bazquux.json");
  ExtensionManagement.registerSchema("chrome://browser/content/schemas/bazquux.json");
=== Permission strings ===
The strings for permissions can be found in [https://dxr.mozilla.org/mozilla-central/source/browser/locales/en-US/chrome/browser/browser.properties browser.properties].
If you add an API that requires permissions, then you'll need to make sure the corresponding permission strings are also landed.
49

edits