зеркало из https://github.com/mozilla/gecko-dev.git
134 строки
6.7 KiB
ReStructuredText
134 строки
6.7 KiB
ReStructuredText
Background
|
|
==========
|
|
|
|
WebExtensions run in a sandboxed environment much like regular web content.
|
|
The purpose of extensions is to enhance the browser in a way that
|
|
regular content cannot -- WebExtensions APIs bridge this gap by exposing
|
|
browser features to extensions in a way preserves safety, reliability,
|
|
and performance.
|
|
The implementation of a WebExtension API runs with
|
|
`chrome privileges <https://developer.mozilla.org/en-US/docs/Security/Firefox_Security_Basics_For_Developers>`_.
|
|
Browser internals are accessed using
|
|
`XPCOM <https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM>`_
|
|
or `ChromeOnly WebIDL features <https://developer.mozilla.org/en-US/docs/Mozilla/WebIDL_bindings#ChromeOnly>`_.
|
|
|
|
The rest of this documentation covers how API implementations interact
|
|
with the implementation of WebExtensions.
|
|
To expose some browser feature to WebExtensions, the first step is
|
|
to design the API. Some high-level principles for API design
|
|
are documented on the Mozilla wiki:
|
|
|
|
- `Vision for WebExtensions <https://wiki.mozilla.org/WebExtensions/Vision>`_
|
|
- `API Policies <https://wiki.mozilla.org/WebExtensions/policy>`_
|
|
- `Process for creating new APIs <https://wiki.mozilla.org/WebExtensions/NewAPIs>`_
|
|
|
|
Javascript APIs
|
|
---------------
|
|
Many WebExtension APIs are accessed directly from extensions through
|
|
Javascript. Functions are the most common type of object to expose,
|
|
though some extensions expose properties of primitive Javascript types
|
|
(e.g., constants).
|
|
Regardless of the exact method by which something is exposed,
|
|
there are a few important considerations when designing part of an API
|
|
that is accessible from Javascript:
|
|
|
|
- **Namespace**:
|
|
Everything provided to extensions is exposed as part of a global object
|
|
called ``browser``. For compatibility with Google Chrome, many of these
|
|
features are also exposed on a global object called ``chrome``.
|
|
Functions and other objects are not exposed directly as properties on
|
|
``browser``, they are organized into *namespaces*, which appear as
|
|
properties on ``browser``. For example, the
|
|
`tabs API <https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs>`_
|
|
uses a namespace called ``tabs``, so all its functions and other
|
|
properties appear on the object ``browser.tabs``.
|
|
For a new API that provides features via Javascript, the usual practice
|
|
is to create a new namespace with a concise but descriptive name.
|
|
|
|
- **Environments**:
|
|
There are several different types of Javascript environments in which
|
|
extension code can execute: extension pages, content scripts, proxy
|
|
scripts, and devtools pages.
|
|
Extension pages include the background page, popups, and content pages
|
|
accessed via |getURL|_.
|
|
When creating a new Javascript feature the designer must choose
|
|
in which of these environments the feature will be available.
|
|
Most Javascript features are available in extension pages,
|
|
other environments have limited sets of API features available.
|
|
.. |getURL| replace:: ``browser.runtime.getURL()``
|
|
.. _getURL: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/runtime/getURL
|
|
|
|
- **Permissions**:
|
|
Many Javascript features are only present for extensions that
|
|
include an appropriate permission in the manifest.
|
|
The guidelines for when an API feature requires a permission are
|
|
described in (*citation needed*).
|
|
|
|
The specific types of features that can be exposed via Javascript are:
|
|
|
|
- **Functions**:
|
|
A function callable from Javascript is perhaps the most commonly
|
|
used feature in WebExtension APIs.
|
|
New API functions are asynchronous, returning a
|
|
`Promise <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise>`_. Even functions that do not return a result
|
|
use Promises so that errors can be indicated asynchronously
|
|
via a rejected Promise as opposed to a synchronously thrown Error.
|
|
This is due to the fact that extensions run in a child process and
|
|
many API functions require communication with the main process.
|
|
If an API function that needs to communicate in this way returned a
|
|
synchronous result, then all Javascript execution in the child
|
|
process would need to be paused until a response from the main process
|
|
was received. Even if a function could be implemented synchronously
|
|
within a child process, the standard practice is to make it
|
|
asynchronous so as not to constrain the implementation of the underlying
|
|
browser feature and make it impossible to move functionality out of the
|
|
child process.
|
|
Another consequence of functions using inter-process communication is
|
|
that the parameters to a function and its return value must all be
|
|
simple data types that can be sent between processes using the
|
|
`structured clone algorithm <https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm>`_.
|
|
|
|
- **Events**:
|
|
Events complement functions (which allow an extension to call into
|
|
an API) by allowing an event within the browser to invoke a callback
|
|
in the extension.
|
|
Any time an API requires an extension to pass a callback function that
|
|
gets invoked some arbitrary number of times, that API method should be
|
|
defined as an event.
|
|
|
|
Manifest Keys
|
|
-------------
|
|
In addition to providing functionality via Javascript, WebExtension APIs
|
|
can also take actions based on the contents of particular properties
|
|
in an extension's manifest (or even just the presence of a particular
|
|
property).
|
|
Manifest entries are used for features in which an extension specifies
|
|
some static information that is used when an extension is installed or
|
|
when it starts up (i.e., before it has the chance to run any code to use
|
|
a Javascript API).
|
|
An API may handle a manifest key and implement Javscript functionality,
|
|
see the
|
|
`browser action <https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/browserAction>`_
|
|
API for an example.
|
|
|
|
Other Considerations
|
|
--------------------
|
|
In addition to the guidelines outlined above,
|
|
there are some other considerations when designing and implementing
|
|
a WebExtension API:
|
|
|
|
- **Cleanup**: A badly written WebExtension should not be able to permanently
|
|
leak any resources. In particular, any action from an extension that
|
|
causes a resource to be allocated within the browser should be
|
|
automatically cleaned up when the extension is disabled or uninstalled.
|
|
This is described in more detail in the section on :ref:`lifecycle`.
|
|
|
|
- **Performance**: A new WebExtension API should not add any new overhead
|
|
to the browser when the API is not used. That is, the implementation
|
|
of the API should not be loaded at all unless it is actively used by
|
|
an extension. In addition, initialization should be delayed when
|
|
possible -- extensions ared started relatively early in the browser
|
|
startup process so any unnecessary work done during extension startup
|
|
contributes directly to sluggish browser startup.
|
|
|