Remove legacy extensions and other outdated content (#1364)

This commit is contained in:
rebloor 2023-03-22 21:05:37 +13:00 коммит произвёл GitHub
Родитель 12df85a38d
Коммит 9be398f48e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 1 добавлений и 1392 удалений

Просмотреть файл

@ -228,21 +228,6 @@ The Firefox extension environment is highly compatible with chromium-based exten
<!-- END: Two Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
### Update a legacy Firefox extension
If you have a [legacy Firefox extension](/documentation/develop/porting-a-legacy-firefox-extension/), you can still find out how to get it up and running on the latest version of Firefox. Check out the porting information for the [Add-on SDK](/documentation/develop/comparison-with-the-add-on-sdk/) and [XUL/XPCOM](/documentation/develop/comparison-with-xul-xpcom-extensions/) based extensions.
{% endcapture %}
{% include modules/one-column.liquid,
content: content
%}
<!-- END: Single Column Body Module -->
</section>
<!-- END: Page section container -->

Просмотреть файл

@ -1,512 +0,0 @@
---
layout: sidebar
title: Comparison with the Add-on SDK
permalink: /documentation/develop/comparison-with-the-add-on-sdk/
topic: Develop
tags: [addon-sdk, addonsdk, porting, webextensions]
contributors:
[
rebloor,
mdnwebdocs-bot,
wbamberg,
LoveIsGrief,
freaktechnik,
hellosct1,
andrewtruongmoz,
smile4ever,
Leif-AMO,
kumar303,
Sebastianz,
Rob--W,
]
last_updated_by: rebloor
date: 2019-03-20 08:08:55
---
<!-- Page Hero Banner -->
{% capture page_hero_banner_content %}
# Comparison with the Add-on SDK
This article is a technical comparison of the Add-on SDK and WebExtensions technology. It's intended to help orient people who have an add-on that uses the SDK, and who are planning to port it to use WebExtension APIs.
::: note alert
Support for extensions using XUL/XPCOM or the Add-on SDK was removed in Firefox 57, released November 2017. As there is no supported version of Firefox enabling these technologies, this page will be removed by December 2020.
:::
If you're planning to port an [overlay extension](https://developer.mozilla.org/Add-ons/Overlay_Extensions) or a [bootstrapped extension](https://developer.mozilla.org/docs/Mozilla/Add-ons/Bootstrapped_extensions), see [Comparison with XUL/XPCOM extensions](/documentation/develop/comparison-with-xul-xpcom-extensions).
{% endcapture %}
{% include modules/page-hero.liquid,
content: page_hero_banner_content
%}
<!-- Content with Table of Contents Module -->
{% capture content_with_toc %}
The basic structure and concepts of the Add-on SDK are shared by WebExtensions. Both technologies include:
- [manifest files](#manifest-files) defining metadata for the extension and some aspects of its behavior.
- [persistent scripts](#persistent-scripts) that get access to a set of privileged JavaScript APIs and that stay loaded for as long as the extension itself is enabled.
- [content scripts](#content-scripts) that can be injected into web pages, and that can communicate with persistent scripts using an asynchronous messaging API.
- [the ability to add specific UI elements](#ui-elements), such as buttons, to the browser. Buttons in turn can have popups that are defined using HTML, JavaScript, and CSS.
- [a set of privileged JavaScript APIs](#javascript-apis) for interacting with the web or with the browser.
- [a command-line tool](#command-line-tool) that developers can use to test their extensions.
Beyond these broad similarities, there are a lot of differences in the details, and these are summarised in the following sections.
{% endcapture %}
{% include modules/column-w-toc.liquid,
id: "intro"
content: content_with_toc
%}
<!-- END: Content with Table of Contents -->
<!-- Single Column Body Module -->
{% capture content %}
## Manifest files
In both technologies you have a JSON manifest file in the extension's root directory. In the SDK this is called [`package.json`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Tools/package_json), while in WebExtensions it's called [`manifest.json`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json). Both files contain basic metadata such as the extension's name, description, and icons.
However, `manifest.json` includes many keys that define parts of the extension's capabilities and behavior, which in the SDK are more often defined in code. For example:
{% capture table %}
| Feature | Add-on SDK | WebExtensions |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Content scripts matching URL patterns | [`page-mod`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/page-mod) API | [`content-scripts`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts) key |
| Toolbar buttons | [`ui/button/action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_button_action) API | [`browser_action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) key |
| Access privileged APIs | `require()` function | [`permissions`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) key |
{% endcapture %}
{% include modules/table.liquid,
content: table
%}
This makes developing extensions with WebExtension APIs more declarative and less programmatic, compared with SDK add-ons.
With the SDK you'll typically use [`jpm init`](https://developer.mozilla.org/Add-ons/SDK/Tools/jpm#jpm_init) to create a new `package.json`. The WebExtensions technology doesn't have an equivalent of `jpm init`, so you'll probably write the manifest from scratch or copy and adapt an existing one.
- [Learn more about `manifest.json`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json)
{% endcapture %}
{% include modules/one-column.liquid,
id: "manifest-files"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Persistent scripts
Both technologies have the concept of persistent scripts that stay loaded for the extension's lifetime, have access to privileged APIs, and can communicate with other parts of the extension such as content scripts.
In the SDK this script is by default called `index.js`, and it can [load other scripts using the module loader](https://developer.mozilla.org/Add-ons/SDK/Guides/Module_structure_of_the_SDK#Local_Modules).
With WebExtensions, these scripts are called "[background scripts](https://developer.mozilla.org/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts)". You can define a set of scripts using the [`background`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/background) manifest key, and they will all be loaded into the same document, which is a hidden, auto-generated, blank HTML page. You can also define your own custom document using the `background` key.
An important difference is that background scripts get a [`window`](https://developer.mozilla.org/docs/Web/API/Window) global, with all the DOM objects you'd expect to be present on a window. This makes writing extensions more like writing web pages, with direct access to all the normal Web APIs like [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest) or [`IndexedDB`](https://developer.mozilla.org/docs/Web/API/IndexedDB_API).
Also note that by default, extensions have a [Content Security Policy](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy) applied to them. You can specify your own policy, but the default policy, among other things, disallows potentially unsafe practices such as the use of [`eval()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/eval).
### Learn more
- [Background scripts for extensions](https://developer.mozilla.org/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts)
{% endcapture %}
{% include modules/one-column.liquid,
id: "persistent-scripts"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Content scripts
In both the Add-on SDK and WebExtensions, persistent scripts can't directly access the content of web pages. Instead, extensions can attach content scripts to web pages. These scripts:
- do get direct access to web content
- don't have access to privileged APIs
- can communicate with the persistent scripts using a messaging API.
In both technologies, there are two ways to attach scripts: you can automatically attach a set of scripts to pages whose URL matches a given pattern, or you can programmatically attach a script to the page hosted by a given tab. The way to do this is different in each technology, though:
{% capture table %}
| Operation | Add-on SDK | WebExtensions |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Attach scripts to pages matching URL pattern | [`page-mod`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/page-mod) API | [`content-scripts`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts) key |
| Content scripts matching URL patterns | [`tab.attach()`](https://developer.mozilla.org/Add-ons/SDK/High-Level_APIs/tabs#Run_scripts_in_a_tab) | [`tabs.executeScript()`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/tabs/executeScript) |
{% endcapture %}
{% include modules/table.liquid,
content: table
%}
The match patterns used for URLs are different:
- [SDK match patterns](https://developer.mozilla.org/Add-ons/SDK/Low-Level_APIs/util_match-pattern)
- [WebExtension match patterns](https://developer.mozilla.org/Add-ons/WebExtensions/match_patterns)
In both technologies you can pass options to control when the script runs and whether it will be attached to subframes. WebExtensions don't include an equivalent of `contentScriptOptions`, though, so to pass configuration options to a content script in an extension, you would either have to send them in a message or store them in [`storage.local`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/storage/local).
In both technologies, content scripts can communicate with persistent scripts using an asynchronous messaging API:
{% capture table %}
| Operation | Add-on SDK | WebExtensions |
| --------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Send message | [`port.emit()`](<https://developer.mozilla.org/Add-ons/SDK/Guides/Content_Scripts/port#emit()>) | [`runtime.sendMessage()`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage) / [`tabs.sendMessage()`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/tabs/sendMessage) |
| Receive message | [`port.on()`](<https://developer.mozilla.org/Add-ons/SDK/Guides/Content_Scripts/port#on()>) | [`runtime.onMessage`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage) |
{% endcapture %}
{% include modules/table.liquid,
content: table
%}
- [Communicating with persistent scripts in the SDK](https://developer.mozilla.org/Add-ons/SDK/Guides/Content_Scripts#Communicating_with_the_add-on)
- [Communicating with persistent scripts in WebExtensions](https://developer.mozilla.org/Add-ons/WebExtensions/Content_scripts#Communicating_with_background_scripts)
In both cases, content scripts can communicate with scripts loaded by the page using [`window.postMessage`](https://developer.mozilla.org/docs/Web/API/Window/postMessage) and [`window.addEventListener`](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener).
In both technologies, have access to the page they're injected into, but get "a clean view of the DOM", meaning that they don't get to see modifications made to the DOM by scripts loaded by the page.
In the SDK, content scripts can [share objects with page scripts](https://developer.mozilla.org/Add-ons/SDK/Guides/Content_Scripts/Interacting_with_page_scripts#Sharing_objects_with_page_scripts), using techniques like `unsafeWindow` and [`createObjectIn`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.createObjectIn). With WebExtensions, the `unsafeWindow` is available via [`wrappedJSObject`](https://developer.mozilla.org/Add-ons/WebExtensions/Content_scripts#Accessing_page_script_objects_from_content_scripts) instead. All the export helper functions are available, too.
### Learn more
- [Content scripts for WebExtensions](https://developer.mozilla.org/Add-ons/WebExtensions/Content_scripts)
{% endcapture %}
{% include modules/one-column.liquid,
id: "content-scripts"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## UI elements
Both technologies provide APIs to create a UI for your extension. UI options for WebExtensions are more limited.
{% capture table %}
| UI Element | Add-on SDK | WebExtensions |
| ------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Button | [`ui/button/action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_button_action) | [`browser_action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) / [`page_action`](https://developer.mozilla.org/Add-ons/WebExtensions/manifest.json/page_action) |
| Toggle button | [`ui/button/toggle`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_button_toggle) | [`browser_action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) / [`page_action`](https://developer.mozilla.org/Add-ons/WebExtensions/manifest.json/page_action) |
| Toolbar | [`ui/toolbar`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_toolbar) | None |
| Sidebar | [`ui/sidebar`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_sidebar) | `sidebar_action` |
| Panel | [`panel`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/panel) | `browser_action` / `page_action` [popup](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Popups) |
| Context menu | [`context-menu`](https://developer.mozilla.org/docs/Archive/Add-ons/Add-on_SDK/High-Level_APIs/context-menu) | [`contextMenus`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/contextMenus) |
{% endcapture %}
{% include modules/table.liquid,
content: table
%}
### Panels and popups
Panels and [popups](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Popups) are both transient dialogs specified using HTML, CSS, and JavaScript.
Unlike panels, popups are always attached to a button (either a browser action or a page action) and can't be displayed programmatically: they are only shown when the user clicks the button.
Also unlike panels, popup scripts get access to all the same APIs that background scripts do. They can even get direct access to the background page, via [`runtime.getBackgroundPage()`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getBackgroundPage).
{% endcapture %}
{% include modules/one-column.liquid,
id: "ui-elements"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Settings
The Add-on SDK and WebExtensions both have some support for settings (sometimes also called options or preferences).
With the SDK you can define preferences using a `preferences` key in `package.json`. The user can see and change these preferences in the extension's entry in the Add-ons Manager. The extension in turn can listen for changes using the [`simple-prefs`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/simple-prefs) API.
With WebExtensions, you will have to implement your own UI for presenting settings, and your own code for persisting them for your extension. You do this by writing an HTML file that presents the settings UI, which can include a script for persisting the settings. The script gets access to all the WebExtensions APIs, and it's generally expected that you should use the [`storage`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/storage) API to persist settings.
You then assign the HTML file's URL to the [`options_ui`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/options_ui) key in `manifest.json`. Your settings page then appears in the extension's entry in the Add-ons Manager. The options page can also be programmatically opened with an API call to [`browser.runtime.openOptionsPage`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/openOptionsPage).
Note that WebExtensions does not provide an equivalent of the SDK's [`preferences/service`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/preferences_service) API, which provides general access to browser settings. However, you can change some browser settings using the [`privacy`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/privacy) and [`browserSettings`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings) APIs.
### Learn more
- [Introduction to options pages](https://developer.mozilla.org/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Options_pages)
- [An example extension that has an options page](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)
{% endcapture %}
{% include modules/one-column.liquid,
id: "settings"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Internationlization
The Add-on SDK and WebExtensions both include tools for localizing user-visible text. They offer mostly similar functionality:
{% capture table %}
| Feature | Add-on SDK | WebExtensions |
| -------------------------- | ---------- | ------------- |
| Strings in add-on scripts | Yes | Yes |
| Strings in content scripts | No | Yes |
| Strings in HTML | Yes | No |
| Strings in CSS | No | Yes |
| Title & description | Yes | Yes |
| Plural forms | Yes | No |
| Placeholders | Yes | Yes |
{% endcapture %}
{% include modules/table.liquid,
content: table
%}
In both systems, you supply localized strings as a collection of files, one for each locale.
To retrieve localized strings in extension code, there's a JavaScript API - [`l10n`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/l10n) in the SDK and [`i18n`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/i18n) in WebExtensions - that returns a localized string given an ID.
WebExtensions don't have direct support for localizing strings appearing in HTML, so you have to do this yourself, using JavaScript to retrieve localized strings and to replace the HTML with the localized version.
### Learn more
- [Extensions Internationalization guide](https://developer.mozilla.org/Add-ons/WebExtensions/Internationalization)
- [Example internationalized extension](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)
- [Example script for an extension using WebExtensions to translate HTML in the SDK style](https://gist.github.com/freaktechnik/4a72bc0711d9bc82cf3b075bcc292953)
{% endcapture %}
{% include modules/one-column.liquid,
id: "internationalization"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Command-line tool
The Add-on SDK comes with a command-line tool, [`jpm`](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Tools/jpm), that you can use for testing and packaging extensions. There's an equivalent tool for WebExtensions, called [`web-ext`](/documentation/develop/getting-started-with-web-ext). web-ext doesn't yet support all the same commands that jpm does, but it has the basics: [`run`](/documentation/develop/web-ext-command-reference#web-ext-run), [`build`](/documentation/develop/web-ext-command-reference#web-ext-build), and [`sign`](/documentation/develop/web-ext-command-reference#web-ext-sign).
It's also now possible to install (and reload) SDK add-ons and extensions built with WebExtension APIs in Firefox from their source directory, without needing to package them as an XPI. See [Temporary Installation in Firefox](/documentation/develop/temporary-installation-in-firefox).
### Learn more
- [web-ext tutorial](/documentation/develop/getting-started-with-web-ext)
- [web-ext reference](/documentation/develop/web-ext-command-reference)
- [Temporary installation in Firefox](/documentation/develop/temporary-installation-in-firefox)
{% endcapture %}
{% include modules/one-column.liquid,
id: "command-line-tool"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## JavaScript APIs
In both the SDK and WebExtensions, the main power of the extension comes from a set of dedicated JavaScript APIs. For most of the SDK high-level APIs, there is a WebExtensions equivalent.
One big limitation of WebExtensions compared with the SDK is that SDK add-ons can use `require("chrome")` to get access to the full range of XPCOM APIs in Firefox. This is not possible with WebExtensions.
To access privileged APIs in the SDK, you use `require()`:
```js
var tabs = require("sdk/tabs");
tabs.open("https://developer.mozilla.org/");
```
With WebExtensions most APIs are made available already, with no need to import them:
```js
browser.tabs.create({ "url": "https://developer.mozilla.org/" });
```
For some WebExtension APIs, you need to ask permission first, using the [`permissions`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) `manifest.json` key. In the example below, the extension will need to ask for the "`tabs`" permission if they want access to the tab's URL:
**manifest.json:**
```json
...
"permissions": [
"tabs"
]
...
```
**background script:**
```js
function logUrl(tabs) {
console.log(tabs[0].url);
}
var querying = browser.tabs.query({
active: true,
currentWindow: true
});
querying.then(logUrl);
```
### Add-on SDK => WebExtensions
The tables in this section list every SDK API and describe what the equivalent WebExtensions API would be, if there is one implemented in the current Developer Edition.
The first table covers high-level SDK APIs, the second covers low-level APIs.
#### High-level APIs
{% capture table %}
| Add-on SDK | WebExtensions |
| ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [addon-page](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/addon-page) | Use [`tabs.create()`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/tabs/create) to load pages packaged with your add-on into normal browser tabs. |
| [base64](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/base64) | [`window.atob()` and `btoa()`](https://developer.mozilla.org/docs/Web/API/WindowBase64) |
| [clipboard](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/clipboard) | [`document.execCommand`](https://developer.mozilla.org/docs/Web/API/Document/execCommand) without using `select()` and similar in the background page. |
| [context-menu](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/context-menu) | [`contextMenus`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/contextMenus) |
| [hotkeys](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/hotkeys) | [`commands`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/commands) |
| [indexed-db](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/indexed-db) | [`window.indexedDB`](https://developer.mozilla.org/docs/Web/API/IndexedDB_API) |
| [l10n](https://developer.mozilla.org/docs/Archive/Add-ons/Add-on_SDK/High-Level_APIs/l10n) | [`i18n`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/i18n) |
| [notifications](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/notifications) | [`notifications`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/notifications) |
| [page-mod](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/page-mod) | [`content_scripts`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts) |
| [page-worker](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/page-worker) | Porting isn't complete and being treated in [Bug 1318532](https://bugzilla.mozilla.org/show_bug.cgi?id=1318532) <br/><br/> Workarounds (that might require `webrequestBlocking` to access all webpages [[example](https://stackoverflow.com/questions/15532791/getting-around-x-frame-options-deny-in-a-chrome-extension)]): <br/><br/> - Use the background page <br/> - load remote iframes into the background page <br/> - make an [AJAX](https://developer.mozilla.org/docs/AJAX) call to get static information from the page |
| /[panel](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/panel) | See [UI elements](#ui-elements) above. |
|/ [passwords](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/passwords) | [Experimental logins API](https://github.com/web-ext-experiments/logins) |
| [private-browsing](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/private-browsing) | [`Tab.incognito`](https://developer.mozilla.org/Add-ons/WebExtensions/API/Tabs/Tab) and [`Window.incognito`](https://developer.mozilla.org/Add-ons/WebExtensions/API/windows/Window). |
| [querystring](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/querystring) | [`window.URLSearchParams`](https://developer.mozilla.org/docs/Web/API/URLSearchParams) |
| [request](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/request) | [`window.fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API) or [`window.XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest) |
| [selection](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/selection) | Use a content script that sends the selection data to the add-on. Alternatively, if you can use a contextmenu on a selection, the selection is contained in `selectionText` (see [`contextMenus.OnClickData`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/contextMenus/OnClickData)). |
| [self](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/self) | [`runtime.getManifest()`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getManifest) and [`extension.getURL()`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/extension/getURL) for `data.url()` |
| [simple-prefs](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/simple-prefs) | [`storage`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/storage) and [`options_ui`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/options_ui) |
| [simple-storage](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/simple-storage) | [`storage`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/storage) |
| [system](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/system) | Partly provided by [`runtime`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime). |
| [tabs](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/tabs) | [`tabs`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/tabs) |
| [timers](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/timers) | [`alarms`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/alarms) |
| [ui](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/ui) | See [UI elements](#ui-elements) above. |
| [url](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/url) | [`window.URL`](https://developer.mozilla.org/docs/Web/API/Window/URL) |
| [widget](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/widget) | None |
| [windows](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/High-Level_APIs/windows) | [`windows`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/windows) |
{% endcapture %}
{% include modules/table.liquid,
content: table
%}
#### Low-level APIs
{% capture table %}
| Add-on SDK | WebExtensions |
| -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [loader](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/_loader) | None |
| [chrome](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/chrome) | None |
| [console/plain-text](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/console_plain-text) | None |
| [console/traceback](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/console_traceback) | None |
| [content/content](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/content_content) | None |
| [content/loader](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/content_loader) | None |
| [content/mod](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/content_mod) | None |
| [content/symbiont](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/content_symbiont) | None |
| [content/worker](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/content_worker) | None |
| [core/heritage](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/core_heritage) | None |
| [core/namespace](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/core_namespace) | None |
| [core/promise](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/core_promise) | [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise) |
| [dev/panel](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/dev_panel) | [`devtools.panels`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/devtools.panels) |
| [event/core](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/event_core) | None |
| [event/target](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/event_target) | None |
| [frame/hidden-frame](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/frame_hidden-frame) | None |
| [frame/utils](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/frame_utils) | None |
| [fs/path](https://developer.mozilla.org/docs/Archive/Add-ons/Add-on_SDK/Low-Level_APIs/fs_path) | None |
| [io/byte-streams](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/io_byte-streams) | None |
| [io/file](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/io_file) | None |
| [io/text-streams](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/io_text-streams) | None |
| [lang/functional](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/lang_functional) | None |
| [lang/type](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/lang_type) | None |
| [loader/cuddlefish](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/loader_cuddlefish) | None |
| [loader/sandbox](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/loader_sandbox) | None |
| [net/url](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/net_url) | None |
| [net/xhr](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/net_xhr) | [`window.fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API) or [`window.XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest) |
| [places/bookmarks](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/places_bookmarks) | [`bookmarks`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks) |
| [places/favicon](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/places_favicon) | None |
| [places/history](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/places_history) | [`history`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/history) |
| [platform/xpcom](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/platform_xpcom) | None |
| [preferences/event-target](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/preferences_event-target) | None |
| [preferences/service](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/preferences_service) | Limited support via the [`privacy`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/privacy) and [`browserSettings`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings) APIs. |
| [remote/child](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/remote_child) | None |
| [remote/parent](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/remote_parent) | None |
| [stylesheet/style](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/stylesheet_style) | None |
| [stylesheet/utils](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/stylesheet_utils) | None |
| [system/child_process](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/system_child_process) | [`runtime.connectNative`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/connectNative) |
| [system/environment](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/system_environment) | None |
| [system/events](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/system_events) | None |
| [system/runtime](https://developer.mozilla.org/docs/Archive/Add-ons/Add-on_SDK/Low-Level_APIs/system_runtime) | Partially provided by [`runtime.getPlatformInfo`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getPlatformInfo) |
| [system/xul-app](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/system_xul-app) | Partially provided by [`runtime.getBrowserInfo`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getBrowserInfo) |
| [tabs/utils](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/tabs_utils) | None |
| [ui/button/action](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_button_action) | [`browser_action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) / [`page_action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action) |
| [ui/button/toggle](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_button_toggle) | [`browser_action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) / [`page_action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action) |
| [ui/frame](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_frame) | None |
| [ui/id](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_id) | None |
| [ui/sidebar](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_sidebar) | [`sidebarAction`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction) |
| [ui/toolbar](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/ui_toolbar) | None |
| [util/array](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/util_array) | None |
| [util/collection](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/util_collection) | None |
| [util/deprecate](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/util_deprecate) | None |
| [util/list](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/util_list) | None |
| [util/match-pattern](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/util_match-pattern) | None |
| [util/object](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/util_object) | None |
| [util/uuid](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/util_uuid) | None |
| [window/utils](https://developer.mozilla.org/docs/Mozilla/Add-ons/SDK/Low-Level_APIs/window_utils) | None |
{% endcapture %}
{% include modules/table.liquid,
content: table
%}
{% endcapture %}
{% include modules/one-column.liquid,
id: "javascript-apis"
content: content
%}
<!-- END: Single Column Body Module -->

Просмотреть файл

@ -1,291 +0,0 @@
---
layout: sidebar
title: Comparison with XUL/XPCOM extensions
permalink: /documentation/develop/comparison-with-xul-xpcom-extensions/
topic: Develop
tags: [webextensions]
contributors:
[
rebloor,
mdnwebdocs-bot,
hellosct1,
suterj,
wbamberg,
xricson,
Rob--W,
andrewtruongmoz,
Leif-AMO,
]
last_updated_by: rebloor
date: 2019-03-20 08:11:36
---
<!-- Page Hero Banner -->
{% capture page_hero_banner_content %}
# Comparison with XUL/XPCOM extensions
This article is a technical comparison between the WebExtensions technology and "classic" extensions developed using direct XUL manipulation and direct access to XPCOM. It's intended to help orient people who maintain an add-on like this, and who are planning to port it to use WebExtension APIs.
::: note alert
Support for extensions using XUL/XPCOM or the Add-on SDK was removed in Firefox 57, released November 2017. As there is no supported version of Firefox enabling these technologies, this page will be removed by December 2020.
:::
This article covers both [overlay extension](https://developer.mozilla.org/Add-ons/Overlay_Extensions) and [bootstrapped extensions](https://developer.mozilla.org/docs/Mozilla/Add-ons/Bootstrapped_extensions), but not extensions developed using the Add-on SDK. For the Add-on SDK, please see [Comparison with the Add-on SDK](/documentation/develop/comparison-with-the-add-on-sdk).
{% endcapture %}
{% include modules/page-hero.liquid,
content: page_hero_banner_content
%}
<!-- Content with Table of Contents Module -->
{% capture content_with_toc %}
At a very basic level, XUL/XPCOM extensions are similar to extensions developed with WebExtensions. They both include:
- manifest files defining metadata for the extension and some aspects of its behavior.
- JavaScript code that gets access to a set of privileged JavaScript APIs and that stays loaded for as long as the extension itself is enabled.
- the ability to add specific UI elements, such as buttons, to the browser.
Beyond that, though, the systems are very different. In particular:
- Compared with XUL/XPCOM extensions, WebExtensions provide much more limited options for the extension's UI, and a much more limited set of privileged JavaScript APIs.
- WebExtensions can only access web content by injecting separate scripts into web pages and communicating with them using a messaging API (note, though, that this is also true of XUL/XPCOM extensions that expect to work with multiprocess Firefox).
{% endcapture %}
{% include modules/column-w-toc.liquid,
id: "intro"
content: content_with_toc
%}
<!-- END: Content with Table of Contents -->
<!-- Single Column Body Module -->
{% capture content %}
## Manifest
XUL/XPCOM extensions have two manifest files:
- the [`install.rdf`](https://developer.mozilla.org/Add-ons/Install_Manifests) contains metadata about the extension such as its name, icons, and so on
- the [`chrome.manifest`](https://developer.mozilla.org/docs/Chrome_Registration), that tells Firefox where it can find the components of the extension, including XUL overlays for the extension's interface, scripts for its behavior, and files containing localized strings.
WebExtensions have a single manifest file called [`manifest.json`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json), that has a similar purpose. You use it to specify the extension's name, description, icons, and so on, as well as to specify any buttons it adds to Firefox and to list scripts it needs to run. To get an overview of the components of an extension developed using WebExtension APIs, and how they are specified in manifest.json, see ["Anatomy of an extension"](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension).
### Learn more
- [`manifest.json` documentation](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json)
- [Anatomy of a extension](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension)
{% endcapture %}
{% include modules/one-column.liquid,
id: "manifest"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## UI
XUL/XPCOM extensions can build their UI by directly manipulating the XUL used to specify the browser's own UI. They do this either using overlays or, in the case of bootstrapped/restartless extensions, using JavaScript to modify the XUL document. They can not only add any elements to the browser's UI, they can also modify or remove existing elements. They can also use APIs like [`CustomizableUI.jsm`](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/CustomizableUI.jsm) to build their UI.
Extensions built with WebExtension APIs don't get this kind of direct access. Instead, a combination of `manifest.json` keys and JavaScript APIs enable them to add a limited set of UI components to the browser. The available components are:
{% capture table %}
| Name | Description | Specified using |
| -------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Browser action | Button in the browser toolbar, with an optional popup panel. | [`browser_action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action) manifest key <br/> [`browserAction`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/browserAction) API |
| Page action | Button in the URL bar, with an optional popup panel. | [`page_action`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action) manifest key <br/> [`pageAction`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/pageAction) API |
| Commands | Keyboard shortcuts. | [`commands`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/commands) manifest key <br/> [`commands`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/commands) API |
| Context menu | Adds items and submenus to the browser's context menu. | [`contextMenus`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/contextMenus) API |
{% endcapture %}
{% include modules/table.liquid,
content: table
%}
{% endcapture %}
{% include modules/one-column.liquid,
id: "ui"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Privileged APIs
Both XUL/XPCOM extensions and extensions built with WebExtension APIs can contain scripts that stay loaded for as long as the extension itself is enabled, and that have access to a set of privileged APIs. However, XUL/XPCOM extensions get access to a much wider range of APIs.
The scripts packaged with XUL/XPCOM extensions get access to the full set of [XPCOM API](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface) and [JavaScript code modules](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules) through the [`Components`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components_object) object. They also get direct access to the browser's internals through globals like [`gBrowser`](https://developer.mozilla.org/docs/Mozilla/Tech/XUL/tabbrowser).
The equivalent WebExtension scripts are called [background script](https://developer.mozilla.org/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts), and they get access to a much smaller set of high-level JavaScript APIs. To see all the privileged APIs available to background scripts, see the [summary API page](https://developer.mozilla.org/Add-ons/WebExtensions/API). Background scripts also get a [`window`](https://developer.mozilla.org/docs/Web/API/Window) global, with all the DOM objects that are available in a normal web page.
There are vastly more APIs available to XUL/XPCOM extensions than are available to WebExtensions, and for many XUL/XPCOM APIs, there isn't a WebExtensions substitute. The table below lists every API in the popular [`Services.jsm`](https://developer.mozilla.org/docs/Mozilla/JavaScript_code_modules/Services.jsm) module, describe what the equivalent WebExtensions API would be, if there is one.
You'll see that many APIs have no WebExtensions equivalent yet. However, we are intending to extend the WebExtension APIs to support the needs of add-on developers, so if you have ideas, we'd love to hear them. You can reach us on the [dev-addons mailing list](https://mail.mozilla.org/listinfo/dev-addons) or [Add-ons](https://mzl.la/2u8ZGbg) channel on [Matrix](https://wiki.mozilla.org/Matrix).
{% capture table %}
| Services.jsm API | WebExtensions equivalent |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `nsIAndroidBridge` | None |
| [`nsIXULAppInfo`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIXULAppInfo) <br/> [`nsIXULRuntime`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIXULRuntime) | None |
| [`nsIAppShellService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIAppShellService) | None |
| [`nsIBlocklistService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIBlocklistService) | None |
| [`nsICacheService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICacheService) | None |
| `nsICacheStorageService` | None |
| [`nsIClipboard`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboard) | Partial: see the [`clipboard`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/clipboard) API, and [Interacting with the clipboard](https://developer.mozilla.org/Add-ons/WebExtensions/Interact_with_the_clipboard). |
| [`nsIConsoleService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleService) | [`window.console`](https://developer.mozilla.org/docs/Web/API/Console) |
| [`nsIContentPrefService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIContentPrefService) | None |
| [`nsICookieManager2`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICookieManager2) | [`cookies`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/cookies) |
| [`nsIMessageSender`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIMessageSender) | [Content scripts](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Content_scripts) |
| [`CrashManager.jsm`](http://dxr.mozilla.org/mozilla-central/source/toolkit/components/crashes/CrashManager.jsm) | None |
| [`nsIDirectoryService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDirectoryService) <br/> [`nsIProperties`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProperties) | None |
| [`nsIDOMStorageManager`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMStorageManager) | None |
| `nsIDOMRequestService` | None |
| [`nsIDownloadManager`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDownloadManager) | [`downloads`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/downloads) |
| [`nsIDroppedLinkHandler`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDroppedLinkHandler) | None |
| [`nsIEventListenerService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIEventListenerService) | None |
| [`nsIEffectiveTLDService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIEffectiveTLDService) | None |
| [`nsIFocusManager`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFocusManager) | None |
| [`nsIIOService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIIOService) <br/> `nsIIOService2` | None |
| [`nsILocaleService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocaleService) | [`i18n`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/i18n) |
| [`nsILoginManager`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILoginManager) | None |
| `nsIWinMetroUtils` | None |
| [`nsIMessageBroadcaster`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIMessageBroadcaster) <br/> [`nsIFrameScriptLoader`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcessScriptLoader) | [Content scripts](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Content_scripts) |
| [`nsIObserverService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIObserverService) | None |
| [`nsIPermissionManager`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPermissionManager) | None |
| [`nsIMessageBroadcaster`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIMessageBroadcaster) <br/> [`nsIProcessScriptLoader`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcessScriptLoader) | [Content scripts](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Content_scripts) |
| [`nsIPrefBranch`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPrefBranch) <br/> [`nsIPrefBranch2`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPrefBranch2) <br/> [`nsIPrefService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPrefService) | See [Settings](https://developer.mozilla.org/Add-ons/WebExtensions/Comparison_with_XUL_XPCOM_extensions#Settings). |
| [`nsIPromptService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService) | None |
| [`mozIJSSubScriptLoader`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/mozIJSSubScriptLoader) | None |
| `nsIScriptSecurityManager` | None |
| [`nsIBrowserSearchService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIBrowserSearchService) | None |
| [`nsIAppStartup`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIAppStartup) | None |
| [`mozIStorageService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/mozIStorageService) | [`storage`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/storage) |
| [`nsIStringBundleService`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIStringBundleService) | [`i18n`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/i18n) |
| [`nsIPropertyBag2`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPropertyBag2) | None |
| [`nsITelemetry`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsITelemetry) | None |
| [`nsIThreadManager`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIThreadManager) | None |
| [`nsIURIFixup`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIURIFixup) | None |
| [`nsIURLFormatter`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIURLFormatter) | None |
| [`nsIVersionComparator`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIVersionComparator) | None |
| [`nsIWindowMediator`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWindowMediator) | None |
| [`nsIWindowWatcher`](https://developer.mozilla.org/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWindowWatcher) | None |
{% endcapture %}
{% include modules/table.liquid,
content: table
%}
### Learn more
- [JavaScript APIs available for extensions](https://developer.mozilla.org/Add-ons/WebExtensions/API)
- [Background scripts for extensions](https://developer.mozilla.org/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts)
{% endcapture %}
{% include modules/one-column.liquid,
id: "privileged-apis"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Interacting with web content
Historically, XUL/XPCOM extensions have been able to get direct access to web content. For example, they can directly access and modify the page DOM using [`gBrowser`](https://developer.mozilla.org/docs/Mozilla/Tech/XUL/tabbrowser):
```js
gBrowser.contentWindow.document.querySelector("h1").innerHTML = "yadda yadda";
```
However, this is only possible in single-process Firefox. In [multiprocess Firefox](https://developer.mozilla.org/docs/Mozilla/Firefox/Multiprocess_Firefox), web content and extension code run in different processes, so this direct access is no longer possible, and extensions which rely on it will break. Multiprocess Firefox is coming soon, and multiprocess compatibility will be a necessity.
XUL/XPCOM extensions can still interact with web content in multiprocess Firefox by [refactoring the code that accesses web content into separate scripts called frame scripts, and using the message manager to communicate with these scripts](https://developer.mozilla.org/Add-ons/Working_with_multiprocess_Firefox). But this is complex and can involve deep changes to the extension's code.
WebExtensions are multiprocess-compatible by default: code that interacts with web content is factored into separate scripts called [content scripts](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Content_scripts), that can communicate with the rest of the extension using a messaging API.
### Learn more
- [Content scripts for extensions](https://developer.mozilla.org/Add-ons/WebExtensions/Content_scripts)
{% endcapture %}
{% include modules/one-column.liquid,
id: "interacting-with-web-content"
content: content
%}
<!-- Single Column Body Module -->
{% capture content %}
## Localization
In a XUL/XPCOM extension you handle localization by supplying DTD or properties for each supported language, and referring to them using locale statements inside the `chrome.manifest`. You can then include localized strings in UI elements or in code.
The general approach with WebExtensions is similar, but the details are all different. With WebExtensions you supply localized strings as a collection of JSON files, one for each locale.
To retrieve localized strings in extension code, use the [`i18n`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/i18n) API.
WebExtensions don't have direct support for localizing strings appearing in HTML, so you have to do this yourself, using JavaScript to retrieve localized strings and to replace the HTML with the localized version.
### Learn more
- [Extensions Internationalization guide.](https://developer.mozilla.org/Add-ons/WebExtensions/Internationalization)
- [Example internationalized extension.](https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n)
{% endcapture %}
{% include modules/one-column.liquid,
id: "localization"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Settings
XUL/XPCOM extensions typically store settings using the [XPCOM preferences service](https://developer.mozilla.org/Add-ons/Code_snippets/Preferences) or the [inline options](https://developer.mozilla.org/docs/Mozilla/Add-ons/Inline_Options) system.
With WebExtensions you write an HTML file that presents the settings UI, which can include a script for persisting the settings for your extension. The script gets access to all the WebExtensions APIs, and it's generally expected that you should use the [`storage`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/storage) API to persist settings.
You then assign the HTML file's URL to the [`options_ui`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/options_ui) key in `manifest.json`. Your settings page then appears in the extension's entry in the Add-ons Manager. The options page can also be programmatically opened with an API call to [`browser.runtime.openOptionsPage`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/openOptionsPage).
Note that WebExtensions does not give you access to the [Preferences API](https://developer.mozilla.org/docs/Mozilla/Tech/Preferences_API), so you can't directly get or set the browser's own preferences.
Some browser-specific preferences can however still be controlled through the [`browser.browserSettings`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings) or [`browser.privacy`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/privacy) API.
### Learn more
- [Introduction to options pages](https://developer.mozilla.org/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Options_pages)
- [An example extension that has an options page](https://github.com/mdn/webextensions-examples/tree/master/favourite-colour)
{% endcapture %}
{% include modules/one-column.liquid,
id: "settings"
content: content
%}
<!-- END: Single Column Body Module -->

Просмотреть файл

@ -1,268 +0,0 @@
---
layout: sidebar
title: Developing extensions for Firefox for Android (Fennec)
permalink: /documentation/develop/developing-extensions-for-firefox-for-android-fennec/
topic: Develop
tags: [add-ons, beginner, guide, mobile, webextensions]
contributors:
[caitmuenster, rebloor, juraj, mdnwebdocs-bot, ExE-Boss, Ding-Fan, andrewtruongmoz]
last_updated_by: caitmuenster
date: 2020-09-15
---
{% capture page_hero_banner_content %}
# Developing extensions for Firefox for Android version 68 and earlier
Legacy guide to developing extensions for Firefox for Android version 68 and earlier ("Fennec")
{% endcapture %}
{% include modules/page-hero.liquid,
content: page_hero_banner_content
%}
<!-- END: Page Hero Banner -->
<!-- Content with Table of Contents Module -->
{% capture content_with_toc %}
::: note alert
This article discusses developing extensions for Firefox for Android for version 68 or earlier (codenamed "Fennec"). Fennec is no longer supported and has been replaced by a new, reimagined mobile browsing experience (codenamed "Fenix"). For more information about developing extensions for Fenix, please see [this article](/documentation/develop/developing-extensions-for-firefox-for-android/).
:::
You'll approach the coding of an extension for Firefox for Android in the same way as you would for a desktop extension; using a text editor or tool of your choice to write the code. However, when you want to test and debug your extension you need to follow a different process, this article walks you through that process.
Using [web-ext](/documentation/develop/getting-started-with-web-ext/) in your extension development is recommended. Follow the set up and debugging processes described here, but use [`web-ext run`](/documentation/develop/web-ext-command-reference#web-ext-run) to execute your extension on Firefox for Android. Among other advantages, using [web-ext](/documentation/develop/getting-started-with-web-ext/) automatically restarts your extension on Firefox for Android when you make edits. Also, you can take advantage of [`web-ext lint`](/documentation/develop/web-ext-command-reference/#web-ext-lint), which performs a check to determine if any of the permissions, manifest keys, and web extension APIs youre using are incompatible with Firefox for Android.
However, instructions are provided for the steps you need to take should you choose not to use [web-ext](/documentation/develop/getting-started-with-web-ext/).
## Set up your computer and Android emulator or device
Complete some one-off setup tasks on your computer and Android device.
On your development computer:
- To test on your computer by running Firefox for Android in the Android emulator and in Firefox for Android running on a device:
- Install [Android Studio](https://developer.android.com/studio/index.html).
- Use the Android Studio [SDK Manager](https://developer.android.com/studio/intro/update.html#sdk-manager) or the [sdkmanager](https://developer.android.com/studio/command-line/sdkmanager.html) command-line tool to install the [Android Platform Tools](https://developer.android.com/studio/releases/platform-tools.html).
- To test in Firefox for Android running on a device only:
- Download and extract the [standalone Android SDK Platform-Tools package](https://developer.android.com/studio/releases/platform-tools.html) to a suitable location on your computer.
- On Windows, Mac, or Linux: Add the location into which you extracted the tools package to your operating systems `PATH` environment variable.
- Alternatively, on Mac or Linux: Link the binary to `/usr/local/bin` using `sudo ln -s /<extract folder>/platform-tools/adb /usr/local/bin`.
On your device or Android emulator:
- Install [Firefox for Android](https://play.google.com/store/apps/details?id=org.mozilla.firefox&referrer=utm_source%3Dmozilla%26utm_medium%3DReferral%26utm_campaign%3Dmozilla-org) and, if you wish to test the latest features, [Firefox for Android Beta](https://play.google.com/store/apps/details?id=org.mozilla.firefox_beta) or [Firefox Nightly for Developers](https://play.google.com/store/apps/details?id=org.mozilla.fennec_aurora).
- (If you're using [web-ext](/documentation/develop/getting-started-with-web-ext/), you can skip this step.) Open Firefox for Android and turn off signing by browsing to `about:config` then locating and setting `xpinstall.signatures.required` to `false`.
<article class="module-content grid-x grid-padding-x">
<div class="cell small-6">
![about:config screenshot](/assets/img/documentation/develop/set_xpinstall.png)
</div>
</article>
If you are using a device:
- [Enable Android USB debugging on the device](https://developer.android.com/studio/run/device.html). You need to follow step 2 only, but note that you may have to [enable the developer options](https://developer.android.com/studio/debug/dev-options.html) if you do not see them on your device.
- Attach your device to the development computer using a USB cable and on the device, when prompted, allow USB debugging for the connection.
(If you're using [web-ext](/documentation/develop/getting-started-with-web-ext/), you can skip this step.) On your development computer:
- Open a command shell.
- Run `adb devices` <br/>
You should see output similar to: <br/>
`List of devices attached` <br/>
`51800F220F01564 device` <br/>
Where the hex string is your devices (or emulators) code. This means adb has found your device (or emulator).
{% endcapture %}
{% include modules/column-w-toc.liquid,
id: "set-up-your-computer-and-android-emulator-or-device"
content: content_with_toc
%}
<!-- Single Column Body Module -->
{% capture content %}
## Check for Firefox for Android compatibility
Before running your extension on Firefox for Android, consider using [`web-ext lint`](/documentation/develop/web-ext-command-reference#web-ext-lint). Lint performs a check to determine if any of the permissions, manifest keys, and web extension APIs youre using are incompatible with Firefox for Android. Lint relies on your extensions `manifest.json` file including `strict_min_version`, it then reports on the features that are not supported by the minimum version you have set.
In the lint report:
- incompatible permissions are identified by `PERMISSION_FIREFOX_ANDROID_UNSUPPORTED_BY_MIN_VERSION`,
- incompatible manifest keys are identified by `KEY_FIREFOX_ANDROID_UNSUPPORTED_BY_MIN_VERSION`, and
- incompatible APIs are identified by `ANDROID_INCOMPATIBLE_API`
similar to this:
![linter screenshot](/assets/img/documentation/develop/linter_output2.png)
::: note alert
Lint does not report on APIs that are not implemented by Firefox or Firefox for Android.
:::
When setting `strict_min_version`, unless youre targeting a specific version of Firefox, choose the most recent version of Firefox you expect your extension to be compatible with. For example, you can reasonably expect that most installations of Firefox for Android will be the current or previous version. So, if the current version is 66, consider setting 65 is the minimum version:
```json
"browser_specific_settings": {
"gecko": {
"strict_min_version": "65.0"
}
}
```
{% endcapture %}
{% include modules/one-column.liquid,
id: "check-for-firefox-for-android-compatibility"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Install and run your extension in Firefox for Android
If youre using web-ext, follow the [Testing in Firefox for Android](/documentation/develop/getting-started-with-web-ext#testing-in-firefox-for-android) instructions.
If the extension is not signed, ensure that you've included an application ID using the [browser_specific_settings](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings) key in the `manifest.json`:
```json
"browser_specific_settings": {
"gecko": {
"id": "borderify@example.com"
}
}
```
Otherwise, [zip the content of your extension into an xpi file](/documentation/publish/package-your-extension) named to match the application ID, for example, `borderify@example.com.xpi`.
You now have two options for transferring and running your extension: using adb or a website.
### Transfer your extension using adb
On your computer, execute `/path/to/adb push /path/to/<extension file name>.xpi /mnt/sdcard/`, which will transfer the extensions xpi file to your attached emulator or device.
On your Android device or in the emulator, open Firefox for Android and browse to `file:///mnt/sdcard`:
<article class="module-content grid-x grid-padding-x">
<div class="cell small-6">
![xpi file on memory card](/assets/img/documentation/develop/xpi-file-on-memory-card.png)
</div>
</article>
Tap on `<extension file name>.xpi` to install it. You will get a warning about the extension being blocked, tap ALLOW:
<article class="module-content grid-x grid-padding-x">
<div class="cell small-6">
![Blocked add-on message](/assets/img/documentation/develop/blocked-add-on-message.png)
</div>
</article>
An additional warning will tell you the extension is unverified, tap INSTALL:
<article class="module-content grid-x grid-padding-x">
<div class="cell small-6">
![Unverified add-on message](/assets/img/documentation/develop/unverified-add-on-messages.png)
</div>
</article>
Your extension will start running (in this case a copy of the [borderify](https://developer.mozilla.org/Add-ons/WebExtensions/Examples#borderify) example extension):
<article class="module-content grid-x grid-padding-x">
<div class="cell small-6">
![Borderify sample extension in action](/assets/img/documentation/develop/borderify-in-action.png)
</div>
</article>
### Transfer your extension via a website
Upload your xpi file to your website and make it accessible over HTTP. Browse to the file and download it. Follow the installation instructions, which will be similar to those for an extension transferred using adb.
{% endcapture %}
{% include modules/one-column.liquid,
id: "install-and-run-your-extension-in-firefox-for-android"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Debug your extension
You can debug your extension in the web developer tools and view any `manifest.json` validation messages using `adb logcat`. To make use of these features, first set up Firefox remote debugging [over USB](https://developer.mozilla.org/docs/Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE#Enable_remote_debugging_in_Firefox_for_Android) or [Wi-Fi](https://developer.mozilla.org/docs/Tools/Remote_Debugging/Debugging_Firefox_for_Android_over_Wifi).
### Using web development tools to debug your extension
With your device connected over USB or Wi-Fi, open `about:debugging` and enable the device connection.
![Enable USB Devices](/assets/img/documentation/develop/enable-device-connection.png)
Your device is listed in the left-hand column, click **Connect**.
![Connect to device](/assets/img/documentation/develop/connect-to-device.png)
If prompted, allow the incoming connection on your Android device. Now start your extension on the Android device. Note, the following instructions assume you are using `web-ext run`. Click your device in the left-hand column and scroll down to find **Processes** in the list of active features in the browser.
![Locate processes](/assets/img/documentation/develop/locate-processes.png)
Click **Inspect** next to **Main Process**. The web developer toolbox displays in **Debugger**.
For much of the debugging work, it's useful to be able to view **Console** with **Inspector** or **Debugger**. You do this using the [split console](https://developer.mozilla.org/docs/Tools/Web_Console/Split_console), press `esc` to activate this mode.
Load a page in which your extension exercises. Now you can access any of the JavaScript in your extension.
![Device debugging](/assets/img/documentation/develop/on-device-debugging.png)
::: note
Unlike desktop Firefox, where content scripts are debugged in context of the page in which they run, you debug and view the console messages from content scripts in Firefox for Android together with background scripts in the Toolbox.
:::
In the **Debugger** you can set breakpoints, step through code, modify the extension's state, and do [everything else you'd expect to be able to do in a debugger](https://developer.mozilla.org/docs/Tools/Debugger). Any messages logged by your code display in **Console**.
To inspect the popup's HTML and CSS, use **Inspector**. First, click the page select icon (![Device debugging](/assets/img/documentation/develop/page-selector.png)) to open the HTML document you want to inspect. You can [review and modify the document's HTML and CSS in **Inspector**](https://developer.mozilla.org/docs/Tools/Page_Inspector), as you would with any webpage.
For more details on using the web developer tools, see [Firefox Developer Tools](https://developer.mozilla.org/docs/Tools).
### Viewing manifest validation messages using the console
In addition to the console messages output through WebIDE, there may also be messages relating to the validation of the extensions `manifest.json` files. These messages can be viewed using the adb logcat command. To avoid receiving other, unrelated messages, you can pipe the output through grep, filtering by the extensions ID, for example:
```shell
/path/to/adb logcat | grep borderify@example.com
```
This will give output similar to this:
```shell
I/Gecko (30440): 1496056181889 addons.xpi WARN Addon with ID borderify@example.com already installed, older version will be disabled
```
If your add-on fails to run, check these messages as they may provide information explaining why.
{% endcapture %}
{% include modules/one-column.liquid,
id: "debug-your-extension"
content: content
%}
<!-- END: Single Column Body Module -->

Просмотреть файл

@ -27,15 +27,7 @@ Learn more about developing extensions for Firefox for Android
{% capture content_with_toc %}
::: note alert
In August 2020, Mozilla launched a new, reimagined Firefox for Android experience (codenamed "Fenix"). The browser for Android has been rebuilt from the ground up using [GeckoView](https://mozilla.github.io/geckoview/), Mozilla's mobile browsing engine.
Currently only a limited number of [Recommended Extensions](https://support.mozilla.org/kb/recommended-extensions-program?utm_source=extensionworkshop.com&utm_medium=dev-article&utm_content=developing-extensions-for-firefox-for-android) are supported on the release channel. However, we are continuously working on increasing support, taking into account usage and feedback to ensure we are making the most of our available resources. We will post updates to [The Add-ons Blog](https://blog.mozilla.org/addons/category/mobile?utm_source=extensionworkshop.com&utm_medium=dev-article&utm_content=developing-extensions-for-firefox-for-android)) as plans solidify each quarter.
If you are interested in Firefox for Android 68 and earlier (Fennec), please visit [this article](/documentation/develop/developing-extensions-for-firefox-for-android-fennec/).
:::
You'll approach the coding of an extension for Firefox for Android in the same way as you would for a desktop extension; using a text editor or tool of your choice to write the code. However, when you want to test and debug your extension you need to follow a different process, this article walks you through that process.
You approach the coding of an extension for Firefox for Android in the same way as you would for a desktop extension; using a text editor or tool of your choice to write the code. However, when you want to test and debug your extension you need to follow a different process, this article walks you through that process.
{% endcapture %}
{% include modules/column-w-toc.liquid,

Просмотреть файл

@ -1,173 +0,0 @@
---
layout: sidebar
title: Porting a legacy Firefox extension
permalink: /documentation/develop/porting-a-legacy-firefox-extension/
topic: Develop
tags: [webextensions]
contributors:
[
mdnwebdocs-bot,
rebloor,
caitmuenster,
wbamberg,
ExE-Boss,
TheV360,
atsay,
andrewtruongmoz,
Dietrich,
david_ross,
cricciuto,
Croydon,
]
last_updated_by: mdnwebdocs-bot
date: 2019-03-18 18:32:18
---
<!-- Page Hero Banner -->
{% capture page_hero_banner_content %}
# Porting a legacy Firefox extension
If you have developed a Firefox extension using XUL/XPCOM or the Add-on SDK, this page will help you migrate your extension to use [WebExtensions](/documentation/develop/about-the-webextensions-api) APIs. The standard to build extensions for Firefox is to use WebExtensions APIs. It will be the only type of extension supported in Firefox by the end of November 2017 with the release of [Firefox 57](https://wiki.mozilla.org/RapidRelease/Calendar).
::: note alert
Support for extensions using XUL/XPCOM or the Add-on SDK was removed in Firefox 57, released November 2017. As there is no supported version of Firefox enabling these technologies, this page will be removed by December 2020.
:::
{% endcapture %}
{% include modules/page-hero.liquid,
content: page_hero_banner_content
%}
<!-- END: Page Hero Banner -->
<!-- Content with Table of Contents Module -->
{% capture content_with_toc %}
## Quick start
1. Get an idea of the main things you'll have to change in your extension:
- Familiarize yourself with the [WebExtension format and structure](https://developer.mozilla.org/Add-ons/WebExtensions/Anatomy_of_a_WebExtension), and [build a basic example](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension#Writing_the_extension).
- If your extension is based on XUL and XPCOM, whether it's an [overlay extension](https://developer.mozilla.org/Add-ons/Overlay_Extensions) or a [bootstrapped extension](https://developer.mozilla.org/docs/Mozilla/Add-ons/Bootstrapped_extensions), see [Comparison with XUL/XPCOM extensions](/documentation/develop/comparison-with-xul-xpcom-extensions) to find out how WebExtensions can correspond with the legacy APIs you're using.
- If your extension is based on the Add-on SDK, see [Comparison with the Add-on SDK](/documentation/develop/comparison-with-the-add-on-sdk) to find out how WebExtensions can correspond with the legacy SDK APIs you're using.
2. Rewrite your extension code. See below for migration paths for different types of extensions. From Firefox 51 onwards, you can embed an extension built using WebExtension APIs in a bootstrapped extension or an SDK add-on, and can thus port a legacy extension a piece at a time, and have a working extension at each step. See [Embedded WebExtensions](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Embedded_WebExtensions) for more information.
3. When you're ready to submit the WebExtension version of your extension to AMO... wait a minute... are you truly ready? Because of the extensions permissions model, you cannot revert from WebExtensions back to using a legacy extension format. So test _thoroughly_, because this is a permanent one-way trip. Also, see the hybrid example below. If you're not ready, you can embed your WebExtension in a legacy extension container, which allows you to test your extension migration but still go back if needed in an emergency.
4. When you're _really_ ready to submit the WebExtension version of your extension to AMO, first port your old add-on ID to the new WebExtension `manifest.json` file. Your extension must have the same ID as previous versions. Copy the value in the "`id`" field from your `package.json` file into the `id` field in the [`browser_specific_settings`](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings) section of the WebExtension `manifest.json` file. Then you can submit your extension update to AMO as your normally would.
::: note
Note that this is a one-way conversion: You **cannot** update an extension using WebExtensions to use a legacy technology. This means that you must be sure that you are ready to commit to using WebExtension APIs before you submit the updated add-on to AMO.
:::
{% endcapture %}
{% include modules/column-w-toc.liquid,
id: "quick-start"
content: content_with_toc
%}
<!-- END: Content with Table of Contents -->
<!-- Single Column Body Module -->
{% capture content %}
## Migration paths
### SDK Extensions
Here is the comparison chart showing [SDK APIs and their WebExtensions format counterparts](/documentation/develop/comparison-with-the-add-on-sdk). If you don't see the APIs you need to port to use WebExtensions APIs, look below to learn how to request APIs and also how to implement them.
### XUL/XPCOM Extensions
Here is the comparison chart showing [XUL/XPCOM APIs and their WebExtensions format counterparts](/documentation/develop/comparison-with-xul-xpcom-extensions). If you don't see the APIs you need to port to use WebExtension APIs, look below to learn how to request APIs and also how to implement them.
{% endcapture %}
{% include modules/one-column.liquid,
id: "migration-paths"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Don't see the WebExtensions APIs you need?
**Develop WebExtension APIs for Firefox** - If you're experienced with Mozilla infrastructure and would like to develop WebExtensions APIs directly for Firefox, here is a list of [approved APIs](https://mzl.la/2dVs5Ys) that you can start contributing to.
**Experiment with new WebExtension APIs** - If you want to prototype and tinker with WebExtensions APIs without having to build Firefox, [WebExtensions Experiments](http://webextensions-experiments.readthedocs.io/en/latest/index.html) is for you!
**Request a new WebExtensions API** - If you want to request a new WebExtensions API, please read [this page](https://wiki.mozilla.org/WebExtensions/NewAPIs).
{% endcapture %}
{% include modules/one-column.liquid,
id: "dont-see-the-webextensions-apis-you-need"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Tools
- [web-ext](/documentation/develop/getting-started-with-web-ext) is a command line tool designed to speed up various parts of the extension development process, making development faster and easier.
- [WebExtensions Helper](https://github.com/mi-g/weh) speeds up browser extension development by providing utilities for WebExtensions-based (Firefox, Chrome, Opera and Edge) extensions
- [Chrome Extension generator](https://github.com/yeoman/generator-chrome-extension) creates everything you need to get started with extension development. You can choose Browser UI (Browser,Page Action, Omnibox) type and select permissions you need.
- [Extensionizr](http://extensionizr.com/) is a wizard that helps you create a basic extension
- [Chrome Boilerplate](https://github.com/mahemoff/chrome-boilerplate) is boilerplate code for Chrome WebExtension.
- [Skeleton Chrome Extension](https://github.com/sitepoint/ChromeSkel_a) is an extension bootstrap and template
{% endcapture %}
{% include modules/one-column.liquid,
id: "tools"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Documentation
- [WebExtensions Project Page](https://wiki.mozilla.org/Add-ons/developer/communication) on the Mozilla Wiki
- [How-to guides](/documentation/develop) covering common extension developer cases, like [intercepting web requests](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Intercept_HTTP_requests) and [adding a button to the toolbar](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar)
- [Comparison with the Add-on SDK](/documentation/develop/comparison-with-the-add-on-sdk)
- [Comparison with XUL/XPCOM extensions](/documentation/develop/comparison-with-xul-xpcom-extensions)
- [Browser compatibility table](https://developer.mozilla.org/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs) for all WebExtensions APIs
- [Examples of extensions](https://developer.mozilla.org/Add-ons/WebExtensions/Examples)
{% endcapture %}
{% include modules/one-column.liquid,
id: "documentation"
content: content
%}
<!-- END: Single Column Body Module -->
<!-- Single Column Body Module -->
{% capture content %}
## Contact
You can use the links [here](https://developer.mozilla.org/docs/Mozilla/Add-ons#Contact_us) to get help, keep up to date with news around add-ons, and give us feedback.
{% endcapture %}
{% include modules/one-column.liquid,
id: "contact"
content: content
%}
<!-- END: Single Column Body Module -->

Просмотреть файл

@ -403,32 +403,6 @@
}
]
},
{
"title": "Developing extensions for Firefox for Android (Fennec)",
"url": "/documentation/develop/developing-extensions-for-firefox-for-android-fennec/",
"subpageitems": [
{
"title": "Set up your computer and Android emulator or device",
"id": "set-up-your-computer-and-android-emulator-or-device"
},
{
"title": "Set up your computer and Android emulator or device",
"id": "set-up-your-computer-and-android-emulator-or-device"
},
{
"title": "Check for Firefox for Android compatibility",
"id": "check-for-firefox-for-android-compatibility"
},
{
"title": "Install and run your extension in Firefox for Android",
"id": "install-and-run-your-extension-in-firefox-for-android"
},
{
"title": "Debug your extension",
"id": "debug-your-extension"
}
]
},
{
"title": "GeckoView Extensions (Android library)",
"url": "https://github.com/mozilla/geckoview"
@ -445,104 +419,6 @@
{
"title": "Porting a Google Chrome Extension",
"url": "/documentation/develop/porting-a-google-chrome-extension/"
},
{
"title": "Porting a legacy Firefox extension",
"url": "/documentation/develop/porting-a-legacy-firefox-extension/",
"subpageitems": [
{
"title": "Quick start",
"id": "quick-start"
},
{
"title": "Migration paths",
"id": "migration-paths"
},
{
"title": "Don't see the WebExtensions APIs you need?",
"id": "dont-see-the-webextensions-apis-you-need"
},
{
"title": "Tools",
"id": "tools"
},
{
"title": "Documentation",
"id": "documentation"
},
{
"title": "Contact",
"id": "contact"
}
]
},
{
"title": "Comparison with the Add-on SDK",
"url": "/documentation/develop/comparison-with-the-add-on-sdk/",
"subpageitems": [
{
"title": "Manifest files",
"id": "manifest-files"
},
{
"title": "Persistent scripts",
"id": "persistent-scripts"
},
{
"title": "Content scripts",
"id": "content-scripts"
},
{
"title": "UI elements",
"id": "ui-elements"
},
{
"title": "Settings",
"id": "settings"
},
{
"title": "Internationalization",
"id": "internationalization"
},
{
"title": "Command-line tool",
"id": "command-line-tool"
},
{
"title": "JavaScript APIs",
"id": "javascript-apis"
}
]
},
{
"title": "Comparison with XUL/XPCOM extensions",
"url": "/documentation/develop/comparison-with-xul-xpcom-extensions/",
"subpageitems": [
{
"title": "Manifest",
"id": "manifest"
},
{
"title": "UI",
"id": "ui"
},
{
"title": "Privileged APIs",
"id": "privileged-apis"
},
{
"title": "Interacting with web content",
"id": "interacting-with-web-content"
},
{
"title": "Localization",
"id": "localization"
},
{
"title": "Settings",
"id": "settings"
}
]
}
]
},