Add-on SDK との比較

この翻訳は不完全です。英語から この記事を翻訳 してください。

この記事では Add-on SDK と WebExtensions テクノロジーとの技術的な比較をします。これは SDK を使った Add-on を持っていて、 WebExtension APIs に移植しようとしている人を方向づけます。

overlay extensionbootstrapped extension を移植しようとしている場合、Comparison with XUL/XPCOM extensions を見てください。

Add-on SDK の基本構造やコンセプトは WebExtensions に共有されています。両方の技術は次のものを含んでいます:

これらは似ていますが、細かくは多くの違いがあり、下記の節に要約しています。

マニフェストファイル

両方の技術で、拡張機能のルートディレクトリーに JSON マニフェストファイルがあります。SDK では "package.json" と呼ばれ、WebExtensions では "manifest.json" と呼ばれます。どちらのファイルも拡張機能の名前や、説明、アイコンといった基本のメタデータを含んでいます。

しかし、"manifest.json" には拡張機能の能力やふるまいを定義するたくさんのキーがあり、 SDK ではコード内でもっと多く定義されています。 例えば:

機能 Add-on SDK WebExtensions
URL パターンにマッチしたコンテンツスクリプト page-mod API content_scripts キー
ツールバーボタン  ui/button/action API browser_action キー
アクセス権限 APIs require() 関数 permissions キー

これは WebExtension APIs の拡張機能の開発を、SDK アドオンと比較して、より宣言的でプログラム的ではないようにしています。

SDK では一般的に jpm init を使って新規の package.json を作ります。WebExtensions 技術は jpm init の同等品はないため、スクラッチで manifest を作るか既存のものをコピーして適応することになるでしょう。

永続的なスクリプト

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 既定では called "index.js", and it can load other scripts using the module loader.

With WebExtensions, these scripts are called "background scripts". You can define a set of scripts using the 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 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 or IndexedDB.

Also note that 既定では, extensions have a 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().

Learn more

コンテンツスクリプト

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:

Operation Add-on SDK WebExtensions
Attach scripts to pages matching URL pattern page-mod API content_scripts key
Attach scripts to pages hosted by a tab tab.attach() tabs.executeScript()

The match patterns used for URLs are different:

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.

In both technologies, content scripts can communicate with persistent scripts using an asynchronous messaging API:

Operation Add-on SDK WebExtensions
Send message port.emit() runtime.sendMessage() / tabs.sendMessage()
Receive message port.on() runtime.onMessage

In both cases, content scripts can communicate with scripts loaded by the page using window.postMessage and window.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, using techniques like unsafeWindow and createObjectIn. With WebExtensions, the unsafeWindow is available via wrappedJSObject instead. All the export helper functions are available, too.

Learn more

UI 要素

Both technologies provide APIs to create a UI for your extension. UI options for WebExtensions are more limited.

UI element Add-on SDK WebExtensions
Button ui/button/action browser_action / page_action
Toggle button ui/button/toggle browser_action / page_action
Toolbar ui/toolbar None
Sidebar ui/sidebar sidebar_action
Panel panel browser_action / page_action popup
Context menu context-menu contextMenus

Panels and popups

Panels and 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().

設定

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 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 API to persist settings.

You then assign the HTML file's URL to the 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.

Note that WebExtensions does not provide an equivalent of the SDK's preferences/service API, which provides general access to browser settings. However, you can change some browser settings using the privacy and browserSettings APIs.

Learn more

国際化

The Add-on SDK and WebExtensions both include tools for localizing user-visible text. They offer mostly similar functionality:

機能 Add-on SDK WebExtensions
Strings in add-on scripts はい はい
Strings in content scripts いいえ はい
Strings in HTML はい いいえ
Strings in CSS いいえ はい
Title & description はい はい
Plural forms はい いいえ
Placeholders はい はい

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 in the SDK and 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

コマンドラインツール

The Add-on SDK comes with a command-line tool, jpm, that you can use for testing and packaging extensions. There's an equivalent tool for WebExtensions, called web-ext. web-ext doesn't yet support all the same commands that jpm does, but it has the basics: run, build, and 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.

Learn more

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():

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:

browser.tabs.create({
  "url": "https://developer.mozilla.org/"
});

For some WebExtension APIs, you need to ask permission first, using the 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:

...

"permissions": [
    "tabs"
  ]

...

background script:

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

Add-on SDK WebExtensions
addon-page Use tabs.create() to load pages packaged with your add-on into normal browser tabs.
base64 window.atob() and btoa()
clipboard document.execCommand without using select() and similar in the background page.
context-menu contextMenus
hotkeys commands
indexed-db window.indexedDB
l10n i18n
notifications notifications
page-mod content_scripts
page-worker

Porting isn't complete and being treated in Bug 1318532

Workarounds (that might require webrequestBlocking to access all webpages [example]):

  • Use the background page
  • load remote iframes into the background page
  • make an ajax call to get static information from the page
panel See UI elements above.
passwords Experimental logins API
private-browsing Tab.incognito and Window.incognito.
querystring window.URLSearchParams
request window.fetch or window.XMLHttpRequest
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).
self runtime.getManifest() and extension.getURL() for data.url()
simple-prefs storage and options_ui
simple-storage storage
system Partly provided by runtime.
tabs tabs
timers alarms
ui See UI elements above.
url window.URL
widget None
windows windows

Low-level APIs

Add-on SDK WebExtensions
loader None
chrome None
console/plain-text None
console/traceback None
content/content None
content/loader None
content/mod None
content/symbiont None
content/worker None
core/heritage None
core/namespace None
core/promise Promise
dev/panel devtools.panels
event/core None
event/target None
frame/hidden-frame None
frame/utils None
fs/path None
io/byte-streams None
io/file None
io/text-streams None
lang/functional None
lang/type None
loader/cuddlefish None
loader/sandbox None
net/url None
net/xhr window.fetch or window.XMLHttpRequest
places/bookmarks bookmarks
places/favicon None
places/history history
platform/xpcom None
preferences/event-target None
preferences/service Limited support via the privacy and browserSettings APIs.
remote/child None
remote/parent None
stylesheet/style None
stylesheet/utils None
system/child_process runtime.connectNative
system/environment None
system/events None
system/runtime Partially provided by runtime.getPlatformInfo
system/xul-app Partially provided by runtime.getBrowserInfo
tabs/utils None
ui/button/action browser_action / page_action
ui/button/toggle browser_action / page_action
ui/frame None
ui/id None
ui/sidebar sidebarAction
ui/toolbar None
util/array None
util/collection None
util/deprecate None
util/list None
util/match-pattern None
util/object None
util/uuid None
window/utils None

ドキュメントのタグと貢献者

このページの貢献者: Uemmra3
最終更新者: Uemmra3,