Modern browsers can add new functionality to sites and the browser itself through script-based extensions. This document specifies an API set that allows developers to create interoperable extensions for browsers that support the API set, as well as the packaging format to be used for such extensions.
This specification is not actively maintained. Issues previously filed against it can be read on github. A public archived mailing list was also available, but was reserved for high level discussions, and was not appropriate for specific comments about this document.
Work on this document is governed by the charter of the Browser Extension CG, which includes among other things the Communication, Decision, and Contribution policies of this community group.
Implementation of the technologies discussed and tentatively specified in this Community Group is ongoing and none of the original contributors have expressed opposition to this work. However, due to various circumstances, the level of participation has dropped below the level at which productive discussion is possible, and activity in this group has stopped as a result.
The specifications have therefore not been maintained in a while, and are out of date.
In the meanwhile, a new “WebExtensions Community Group”, with similar objectives but much more active participation, has sprung up. People interested in this topic are encouraged to join that group.
Because browsers supported different add-on models, extension authors wound up creating divergent codebases and delivering different browser-specific add-ons. This Community Group's goal is to make browser extension code much more interoperable across browsers by specifying common extension interfaces and well-defined browser behavior. This will allow extension authors to greatly reduce or eliminate the rework necessary to create extensions that target different browsers.
The goal for these core APIs is to provide functionality that extension authors need for:
Need to resolve ID issue before we can address messaging ('passing data')
GitHub Issues 14 & 17
Browser extensions are authored primarily with JavaScript. In addition to the usual JavaScript Web APIs, additional APIs are available exclusively to extensions via the browser
object. However, the specific APIs that are available to an extension from the browser
object are dependent upon:
Browser extension pages and their corresponding scripts are executed in one of the following contexts. The manifest declarations required to create each specific type of page are described below.
Some browser extension API require a specific manifest key or specific permission. If the key or permission are not declared or not granted, the object will not be available for scripting. These requirements are summarized in the table below. If manifest keys that are not defined in this specification are specified, other browsers MAY elect to ignore those additional keys.
API object | Execution Context | Required Declaration | ||
---|---|---|---|---|
Background page,Event page,Popup page,Options page,Custom page | Content script page | Internet-hosted web page | Manifest key | |
browserAction |
Y1 | "browser_action"1 | ||
contextMenus |
Y | "permissions":["context_menus"] | ||
extension |
Y | Y | ||
i18n |
Y | Y | "default_lang" : "<lang>"4 | |
pageAction |
Y1 | "page_action"1 | ||
runtime |
Y | Y | Y3 | “externally_connectable”:[...] 2 |
tabs |
Y | "permissions":["tabs","activeTab"] | ||
webNavigation |
Y | "permissions":["webNavigation"] | ||
webRequest |
Y | "permissions":["webRequest"] | ||
windows |
Y |
browserAction
or pageAction
is allowed at the same time, not both
"externally_connectable"
in the manifest. However, an extension will only receive messages sent from hosted web pages if this key is declared. The "externally_connectable"
declaration will block messages from other extensions, unless the allowed extension ID is declared in the "ids"
list.
runtime.sendMessage
to communicate with extensions MUST be explicitly specify the hosting site's domain in the manifest under the "externally_connectable" key.
browser.i18n
object does not require a manifest permission declaration. However, the manifest does require a value (default_locale
) that is necessary and cannot be specified by the extension author in script code.
This specification uses WebIDL [[WEBIDL]] to describe the Browser Extensions API.
Exposed
To express the aforementioned conditional situations in which certain APIs are made available due to context, the following contexts are used:
CheckAnyPermissions
To express the aforementioned conditional situations in which certain APIs are made available due to expressed manifest keys or permissions, the new WebIDL extended attribute "CheckAnyPermissions"
is used.
API object | CheckAnyPermissions Value | Manifest Key or Value |
browser | "browserExt" | N/A |
browser.browserAction | "browserExtBrowserAction" | "browserAction":[...] |
browser.contextMenu | "browserExtContextMenus" | "permissions":["contextMenus"] |
browser.extension | "browserExt" | |
i18n | "browserExt" | "default_language": "<code>" |
pageAction | "browserExtPageAction" | "pageAction":[...] |
runtime | "browserExt" | |
tabs | "browserExtTabs" | "permissions":["tabs"] or "permissions":["activeTab"] |
webNavigation | "browserExtWebNavigation" | "permissions":["webNavigation"] |
webRequest | "browserExtWebRequest" | "permissions":["webRequest"] |
windows | "browserExt" |
browser.i18n
In this example, the i18n
API should be made available to both browser host scripts (background, event, popup, options, etc.) and content scripts. Use of this API does not require a manifest permission declaration. Additionally, however, the manifest does require a value (default_locale
) that is necessary and cannot be specified by the extension author in script code. This is expressed as a BrowserExtManifest
dictionary.
NOTE: To avoid naming conflicts with WebIDL definitions elsewhere in this document, the Example below has an underscore ("_") appended to end of interface names. In the actual definitions elsewhere in this document, the underscore character is not used.
browser.i18n
object.
[NoInterfaceObject] interface BrowserExtI18n_ { DOMString getMessage_(DOMString messageName, sequence<DOMString?> substitutions); };
[NoInterfaceObject, Exposed=(Window,ContentScript)] interface BrowserExtI18nAPI_ { readonly attribute BrowserExtI18n_ i18n; };
i18n
object to the browser.*
object.
Browser implements BrowserExtI18nAPI_;
"default_locale": "en"
partial dictionary BrowserExtManifest_ { DOMString? defaultLocaleValue; };
Use of some JavaScript APIs such as eval()
are restricted due to CSP. If an explicit policy is not specified, the default policy is applied. The default CSP is discussed in the specification [[CSP3]] . If the browser extension author specifies a new CSP, it will override the default CSP. Refer to the CSP Overview section for more information about the availability of these APIs. The Cross-domain Privileges and Content and Background Script Communication sections provide details about API usage by content scripts.
eval()
and inline script execution are not allowedbrowser
object
The core Browser Extension API objects are accessible from the browser
object. Their availability varies, depending on conditions outlined in the API Availability section.
This API is available in Window context (background, event, popup, options and custom pages), Content Script context, and Internet-hosted web page context.
A description of the special WebIDL syntax considerations for browser extensions are defined elsewhere in this document.
[CheckAnyPermissions_browserExt_] interface BrowserExtGlobal { readonly attribute Browser browser; }; Window implements BrowserExtGlobal; [NoInterfaceObject] interface Browser { }; dictionary BrowserExtIcon { DOMString path; DOMString size; }; typedef sequence<BrowserExtIcon> BrowserExtIconArray; dictionary BrowserExtDeveloper { DOMString name; DOMString? url; }; dictionary BrowserExtBrowserOrPageAction { BrowserExtIcon? defaultIcon; DOMString? defaultPopup; DOMString? defaultTitle; }; dictionary BrowserExtKeyValue { DOMString key; DOMString? value; }; dictionary BrowserExtBrowserSpecificSettings { DOMString browserName; sequence<BrowserExtKeyValue> keyValue; }; dictionary BrowserExtBackroundOrEvent { DOMString? page; boolean persistent; sequence<DOMString>? scripts; }; dictionary BrowserExtContentScripts { boolean allFrames; sequence<DOMString>? css; sequence<DOMString>? excludeMatches; sequence<DOMString>? js; sequence<DOMString> matches; DOMString? runAt; }; dictionary BrowserExtManifest { BrowserExtBackroundOrEvent? background; BrowserExtBrowserOrPageAction? browserAction; BrowserExtBrowserSpecificSettings? browserSpecificSettings; BrowserExtContentScripts? contentScripts; DOMString? contentSecurityPolicy; DOMString? defaultLocale; DOMString? description; BrowserExtDeveloper? developer; BrowserExtIconArray? icons; DOMString? manifestVersion; DOMString name; DOMString? optionsPage; BrowserExtBrowserOrPageAction? pageAction; sequence<DOMString>? permissions; sequence<DOMString>? requiredKeys; DOMString? version; sequence<DOMString> webAccessibleResources; };
browser
object that provides access to all if the child core objects (e.g. browser.browserAction
, browser.contextMenus
, etc.) and their associated APIs.Browser implements BrowserExtBrowserActionAPI
) that add the corresponding core objects to the browser>
object.BrowserAction
or PageAction
buttons displayed in the browser UI.BrowserExtIcon
objects.BrowserAction
or PageAction
.BrowserExtIcon
image, if one was specified in the manifest.json
file, or null
if none is provided. manifest.json
file, or null
if none is provided.manifest.json
file, or null
if none is provided.manifest.json
settings for long-running or inter-tab scripts.manifest.json
file."background": {}
key and associated children in the manifest.json
file."browser_action": {}
key and associated children in the manifest.json
file."browser_specific_settings": {}
key and associated children in the manifest.json
file."content_scripts": {}
key and associated children in the manifest.json
file."content_security_policy"
key/value pair in the manifest.json
file."default_locale"
key/value pair in the manifest.json
file."description"
key/value pair in the manifest.json
file."developer": {}
key and associated children in the manifest.json
file."icons": {}
key and associated children in the manifest.json
file."manifest_version"
key/value pair in the manifest.json
file."name"
key/value pair in the manifest.json
file."options_page"
key/value pair in the manifest.json
file."page_action": {}
key and associated children in the manifest.json
file."permissions": {}
key and associated children in the manifest.json
file."required_keys": []
key and associated children in the manifest.json
file."version"
key/value pair in the manifest.json
file."web_accesible_resources": {}
key/value pair in the manifest.json
file.browserAction
objectbrowserAction
object adds an always-visible button to the browser application, usually near the top of the browser application UI in the toolbar area. An extension that declares a browserAction
cannot have a pageAction
, and vice-versa.
"browser_action"
and "default_title"
keys are required. The other keys are optional.
"browser_action": { // Required "default_icon": {...}, // Same format as "icons" "default_popup": "Page URL", // Optional "default_title": "Title string" // Required }
This API is available in Window context (background, event, popup, options and custom pages).
A description of the special WebIDL syntax considerations for browser extensions are defined elsewhere in this document.
dictionary BrowserExtBrowserActionDefaults { BrowserExtIconArray? defaultIcon; DOMString? defaultPopup; DOMString? defaultTitle; }; partial dictionary BrowserExtManifest { BrowserExtBrowserActionDefaults? browserActionDefaults; }; typedef sequence<byte> BrowserExtColorArray; dictionary BrowserExtTabIdDetails { long tabId; }; dictionary BrowserExtBadgeColorArrayTabId { BrowserExtColorArray color; long tabId; }; dictionary BrowserExtBadgePathTabId { DOMString path; long tabId; }; dictionary BrowserExtBadgeTextTabId { long tabId; DOMString text; }; dictionary BrowserExtBadgeTabIdPopup { DOMString popupHTMLFileName; long tabId; }; callback BrowserExtBrowserActionOnClickedCallback = void (BrowserExtTabsTab tab); [NoInterfaceObject] interface BrowserExtBrowserAction { void disable(long tabId); void enable(long tabId); Promise<BrowserExtColorArray> getBadgeBackgroundColor(BrowserExtTabIdDetails details); Promise<DOMString?> getBadgeText(BrowserExtTabIdDetails details); Promise<DOMString?> getPopup(BrowserExtTabIdDetails details); BrowserExtEvent onClicked(BrowserExtBrowserActionOnClickedCallback callback); void setBadgeBackgroundColor(BrowserExtBadgeColorArrayTabId details); void setBadgeText(BrowserExtBadgeTextTabId details); Promise<void> setIcon(BrowserExtBadgePathTabId details); void setPopup(BrowserExtBadgeTabIdPopup details); }; [NoInterfaceObject, Exposed=Window, CheckAnyPermissions_browserExtBrowserAction_] interface BrowserExtBrowserActionAPI { readonly attribute BrowserExtBrowserAction browserAction; }; Browser implements BrowserExtBrowserActionAPI;
manifest.json
file.manifest.json
file. manifest.json
file.manifest.json
file.manifest.json
file.browser.browserAction
methods. The object encapsulates the information needed to execute the associated method.browser.getBadgeBackgroundColor
methods.browserAction.setIcon()
method. browserAction.setBadgeText()
method. browserAction.setPopup()
method.browserAction.onClicked()
event.browser.browserAction
object.browser.browserAction
object.browser.browserAction
object.contextMenus
object
The contextMenus
object allows additional entries to be added to the browser's context menu. The menu will be selectively be shown for various browser UI elements (browser action or page action button) or page elements (frame, image, link, page, selection, etc.).
A "contextMenus"
entry MUST be declared in the "permissions"
key. The icon keys are optional.
"permissions": [ // Required "contextMenus" // Required ], // Required "icons": { // Optional "<size>":"<name.png>" // Optional, size 16 recommended } // Optional
This API is available in Window context (background, event, popup, options and custom pages).
A description of the special WebIDL syntax considerations for browser extensions are defined elsewhere in this document.
enum BrowserExtContextType { "all", "audio", "browser_action", "editable", "frame", "image", "link", "page", "page_action", "selection", "video" }; enum BrowserExtItemType { "checkbox","normal","radio","separator" }; dictionary BrowserExtContextMenuCreateDetails { boolean checked; sequence<ContextType>? contexts; sequence<DOMString>? documentUrlPatterns; boolean enabled; DOMString? id; Function onclick; (long or DOMString?) parentId; sequence<DOMString>? targetUrlPatterns; DOMString? title; DOMString? type; }; dictionary BrowserExtContextMenuUpdateDetails { boolean checked; sequence<BrowserExtContextType>? contexts; sequence<DOMString>? documentUrlPatterns; boolean enabled; Function onclick; long parentId; sequence<DOMString>? targetUrlPatterns; DOMString? title; ItemType? type; }; dictionary BrowserExtContextMenuOnClickedDetails { boolean checked; boolean editable; long frameId; DOMString? frameUrl; DOMString? linkUrl; DOMString? mediaType; (long or DOMString) menuItemId; DOMString? pageUrl; (long or DOMString?) parentMenuItemId; DOMString? selectionText; DOMString? srcUrl; boolean wasChecked; }; callback BrowserExtContextMenuOnClickedCallback = void (BrowserExtContextMenuOnClickedDetails details, BrowserExtTabsTab tab); [NoInterfaceObject] interface BrowserExtContextMenus { Promise<long> create(BrowserExtContextMenuCreateDetails details); BrowserExtEvent onClicked(BrowserExtContextMenuOnClickedCallback callback); Promise<void> remove((long or DOMString) itemId); Promise<void> removeAll(); Promise<void> update((long or DOMString) itemId, BrowserExtContextMenuUpdateDetails details); }; [NoInterfaceObject, Exposed=Window, CheckAnyPermissions_browserExtContextMenus_] interface BrowserExtContextMenusAPI { readonly attribute BrowserExtContextMenus contextMenus; }; Browser implements BrowserExtContextMenusAPI;
browser.contextMenus
object.browser.contextMenus
object.browser.contextMenus
object.browser.contextMenus
object.i18n
object
The i81n
object provides a way to access strings that have been localized into supported languages.
When providing localized strings, you MUST specify a default locale using a two-character code. Codes can be found at RFC1766 or IETF BCP47. When localizing manifest strings, the following syntax is used.
"default_locale" : "<twoCharLocaleCode>", // Required "name" : "__MSG_<yourCustomNameStringIdentifier>__", "description" : "__MSG_<yourCustomDescriptionStringIdentifier>__",For example
"default_locale" : "en", // English "name" : "__MSG_MySampleExtension__", "description" : "__MSG_MySampleExensionDecription__",
Each supported locale MUST have its own messages.json
file stored in the folder _locales/<twoCharLocaleCode>
. The two-character codes used for directory names here the same as are used in the mainfest.json
to specify default_locale
.
Locale codes used in file/directory names and returned by the API, contrary to common standards, are in the form:
<language>[_<region>]
Which is to say, a two-letter language code, optionally followed by an underscore and a two-letter region code. Locale codes are matched such that an exact match is used if available, falling back to the least-specific, closest match. Therefore, for "en_US", the following locales would be chosen, in order of preference:
Strings are localized by pre-processing messages, replacing |$[a-zA-Z0-9@_]+$|
tokens with the value of their replacements. Later, it processes the resulting string for |$[0-9]|
replacements.
Any number of sequential |$|s are permitted, and are replaced with that number minus 1. Instances of |$|
followed by any number of sequential digits is also permitted, but a localized string which provides more than 9 substitutions are ignored.
Locale messages in the form __MSG_<message name>_
are automatically replaced with the appropriate localized message in CSS files and certain manifest.json string values.
Specifically, the replacements are done according to the regular expression __MSG_([A-Za-z0-9@_]+?)__
, meaning that the first occurrence of __ terminates the message name immediately.
CSS files are pre-processed as a raw text stream, with no considerations for CSS syntax.
manifest.json
values are processed after the JSON has been parsed, and the results are always treated as literal strings. The following manifest keys are processed for localization messges:
It is possible for a translated string to contain substrings that will not be translated or will be replaced with variable content. For example
"messageExample": { "message": "You clicked $URL$.", "description": "Tells the user which link they clicked.", "placeholders": { "url" : { "content" : "$1" "example" : "https://www.w3.org" }
The placeholder name
("url" in the above example) is used to represent the placeholder in the substitution string (e.g. "url" becomes $URL$). It is case insensitive and can contain the same characters as a message string name.
The "content"
item defines the content of the placeholder. This can be a hardcoded string, such as "My placeholder", but it can also include values obtained from a i18n.getMessage() call.
The optional "example"
item is intended to help translators by showing them an example of how the placeholder would appear to end users, allowing them to make the best choice when localizing the file.
This API is available in Window context (background, event, popup, options and custom pages) and Content Script context.
A description of the special WebIDL syntax considerations for browser extensions are defined elsewhere in this document.
[NoInterfaceObject] interface BrowserExtI18n { DOMString getMessage(DOMString messageName, sequence<DOMString?>? substitutions); }; [NoInterfaceObject, Exposed=(Window,ContentScript), CheckAnyPermissions_browserExt_] interface BrowserExtI18nAPI { readonly attribute BrowserExtI18n i18n; }; Browser implements BrowserExtI18nAPI; partial dictionary BrowserExtManifest { DOMString? defaultLocaleValue; };
browser.i18n
object.browser.i18n
object.manifest.json
if the extension contains the _locales directory, and must be absent otherwise. It identifies a subdirectory of _locales, and this subdirectory will be used to find the default strings for your extension.pageAction
object
The pageAction
object adds a button to the browser application, usually within the address bar. This button typically appears only when the extension has detected that it can perform an action on the current page for the active tab. An extension that declares a browserAction
cannot have a pageAction
, and vice-versa.
The "page_action"
and "default_title"
keys are required. The other keys are optional.
"page_action": { // Required "default_icon": {...}, // Same format as "icons" "default_popup": "Page URL", // Optional "default_title": "Title string" // Required }
This API is available in Window context (background, event, popup, options and custom pages).
A description of the special WebIDL syntax considerations for browser extensions are defined elsewhere in this document.
dictionary BrowserExtPageActionDefaults { BrowserExtIconArray? defaultIcon; DOMString? defaultPopup; DOMString? defaultTitle; }; partial dictionary BrowserExtManifest { BrowserExtPageActionDefaults? pageActionDefaults; }; dictionary BrowserExtBadgePath { DOMString path; }; callback BrowserExtPageActionOnClickedCallback = void (BrowserExtTabsTab tab); interface BrowserExtPageAction { Promise<DOMString?> getPopup(BrowserExtTabIdDetails details); Promise<DOMString?> getTitle(BrowserExtTabIdDetails details); void hide(long tabId); BrowserExtEvent onClicked(BrowserExtPageActionOnClickedCallback callback); Promise<void> setIcon(BrowserExtBadgePath path); void setPopup(BrowserExtBadgePathTabId details); void setTitle(BrowserExtBadgeTextTabId details); void show(long tabId); }; [NoInterfaceObject, Exposed=Window, CheckAnyPermissions_browserExtPageAction_] interface BrowserExtPageActionAPI { readonly attribute BrowserExtPageAction pageAction; }; Browser implements BrowserExtPageActionAPI;
manifest.json
filemanifest.json
file. manifest.json
file.manifest.json
file.manifest.json
file.pageAction.setIcon()
method.pageAction.onClicked()
event.browser.pageAction
object.browser.pageAction
object.browser.pageAction
object.runtime
object
The runtime
object is used to send and receive messages across contexts, as well as access extension-level information such as the id, manifest, and absolute path to resources.
There are no additional manifest entries required for an extension to use this object. However, an extension will only receive messages sent from hosted web pages if the “externally_connectable” key is declared. Also, an extension will block messages from other extensions by specifying only approved extensions. Note that if this key is used to allow web pages to send messages, unless "ids" : ["*"]
is specified, all messages from other extensions will be blocked. URLs in the "matches"
array MUST include a top-level domain. This list does not affect content scripts.
"externally_connectable" : [ "ids":[...], // Identifiers for other extensions that are allowed to send messages "matches":[...] // URL patterns for hosted web pages allowed to send messages ]
This API is available in Window context (background, event, popup, options and custom pages), Content Script context, and Internet-hosted web page context.
A description of the special WebIDL syntax considerations for browser extensions are defined elsewhere in this document.
enum BrowserExtRuntimeOnInstalledReason {"browser_update", "extension_install", "extension_update"}; dictionary BrowserExtRuntimeOnInstalledDetails { BrowserExtRuntimeOnInstalledReason reason; DOMString? previousVersion; DOMString? id; }; dictionary BrowserExtRuntimePort { Function disconnect; DOMString name; object onDisconnect; object onMessage; Function postMessage; BrowserExtRuntimeMessageSender? sender; }; dictionary BrowserExtRuntimeMessageSender { DOMString? id; long frameId; BrowserExtTabsTab? tab; DOMString? url; }; callback BrowserExtRuntimeOnConnectCallback = void (BrowserExtRuntimePort port); callback BrowserExtRuntimeOnInstalledCallback = void (BrowserExtRuntimeOnInstalledDetails details); callback BrowserExtRuntimeOnMessageCallback = void (optional any message, BrowserExtRuntimeMessageSender sender, BrowserExtRuntimeSendResponseCallback callback); [NoInterfaceObject] interface BrowserExtBrowserRuntime { object getManifest(); DOMString getURL(DOMString path); attribute DOMString id; void onConnect(BrowserExtRuntimeOnConnectCallback callback); void onInstalled(BrowserExtRuntimeOnInstalledCallback callback); void onMessage(BrowserExtRuntimeOnMessageCallback callback); Promise<any> sendMessage(optional DOMString extensionId, any message); attribute BrowserExtRuntimePort Port; attribute BrowserExtRuntimeMessageSender MessageSender; }; [NoInterfaceObject, Exposed=Window, CheckAnyPermissions_browserExt_] interface BrowserExtRuntimeAPI { readonly attribute BrowserExtRuntime runtime; }; Browser implements BrowserExtRuntimeAPI;
runtime.onInstalled
event is being dispatched.runtime.onInstalled
event is fired.runtime.OnInstalledReason
value stating the reason that this event is being dispatched.reason
value is update.
runtime.connect()
or tabs.connect()
call that created it. If this port is connected to a native application, its name is the name of the native application.addListener()
and removeListener()
functions common to all events in browser extensions. Listener functions will be called when the other end has called Port.disconnect(). This event will only be fired once for each port. The listener function will be passed the Port object. If the port was disconnected due to an error, then the Port argument will contain an error property giving more information about the error.addListener()
and removeListener()
functions common to all events in browser extensions. Listener functions will be called when the other end has sent this port a message. The listener will be passed the JSON object that the other end sent.onConnect
or onConnectExternal
listeners.tabs.Tab
which opened the connection. This property will only be present when the connection was opened from a tab (including content scripts).browser.runtime
object.manifest.json
file, serialized to a JSON object.manifest.json
to a resource packaged with the browser extension, return a fully-qualified URL.browser.runtime
object.browser.runtime
object.tabs
object
The tabs
object is used to access metadata about a tab, such as its title, or to access the current content within the tab itself.
The "tabs"
permission is required to use this object. Refer to the activeTab
permission section for more information about accessing these APIs.
{ "permissions": [ // Required "tabs" // Either "tabs" or "activeTab" is required "activeTab" // Either "tabs" or "activeTab" is required ] // Required }
This API is available in Window context (background, event, popup, options and custom pages).
A description of the special WebIDL syntax considerations for browser extensions are defined elsewhere in this document.
enum BrowserExtTabMutedReasonDetails { "user", "capture", "extension" }; enum BrowserExtRunAt { "document_end", "document_idle", "document_start" }; enum BrowserExtTabStatus { "complete", "loading" }; enum BrowserExtWindowTypes { "app", "normal", "panel", "popup" }; enum BrowserExtTabsCaptureVisibleTabFormat { "jpeg", "png" }; dictionary BrowserExtTabsTab { boolean active; boolean audible; DOMString? favIconUrl; boolean highlighted; long height; long id; boolean incognito; long index; TabMutedDetails? mutedDetails; long openerTabId; boolean pinned; DOMString? sessionId; DOMString? status; DOMString? title; DOMString? url; long width; long windowId; }; dictionary BrowserExtTabMutedDetails { DOMString? extensionId; boolean muted; TabMutedReasonDetails? reason; }; dictionary BrowserExtTabConnectDetails { long frameId; DOMString? name; }; dictionary BrowserExtTabCreateDetails { boolean active; long index; long openerTabId; boolean pinned; DOMString? url; long windowId; }; dictionary BrowserExtTabScriptAndCSSDetails { boolean allFrames; DOMString? code; DOMString? file; long frameId; boolean matchAboutBlank; BrowserExtRunAt? runAt; }; dictionary BrowserExtTabsCaptureVisibleTabDetails { BrowserExtTabsCaptureVisibleTabFormat imageCaptureFormat; long jpegQuality; }; dictionary BrowserExtTabQueryDetails { boolean active; boolean audible; boolean currentWindow; boolean highlighted; long index; boolean lastFocusedWindow; boolean muted; boolean pinned; TabStatus? status; DOMString? title; (DOMString? or sequence<DOMString>?) url; long windowId; WindowType? windowType; }; dictionary BrowserExtTabReloadDetails { boolean bypassCache; }; dictionary BrowserExtTabSendMessageDetails { long frameId; }; dictionary BrowserExtTabUpdateDetails { boolean active; boolean highlighted; boolean muted; long openerTabId; boolean pinned; DOMString? url; }; dictionary BrowserExtTabIdWindowId { long tabId; long windowId; }; dictionary BrowserExtTabsWindowIdIsWindowClosing { boolean isWindowClosing; long windowId; }; dictionary BrowserExtTabsOnUpdatedChangeDetails { boolean audible; DOMString? favIconUrl; TabMutedDetails? mutedDetails; boolean pinned; DOMString? status; DOMString? title; DOMString? url; }; callback BrowserExtTabsOnActivatedCallback = void (BrowserExtTabIdWindowId activeDetails); callback BrowserExtTabsOnCreatedCallback = void (BrowserExtTabTab tab); callback BrowserExtTabsOnRemovedCallback = void (long tabId, BrowserExtTabsWindowIdIsWindowClosing removeDetails); callback BrowserExtTabsOnUpdatedCallback = void (long tabId, BrowserExtTabsOnUpdatedChangeDetails details, BrowserExtTabsTab tab); [NoInterfaceObject] interface BrowserExtBrowserTabs { Promise<DOMString> captureVisibleTab(long windowId, BrowserExtTabsCaptureVisibleTabDetails details); RuntimePort connect(long tabId, BrowserExtTabConnectDetails details); Promise<BrowserExtTabsTab> create(BrowserExtTabCreateDetails details); void executeScript(long tabId, BrowserExtTabScriptAndCSSDetails details); Promise<BrowserExtTabsTab> get(long tabId); Promise<BrowserExtTabsTab> getCurrent(); void insertCSS(long tabId, BrowserExtTabScriptAndCSSDetails details); void onActivated(BrowserExtTabsOnActivatedCallback callback); void onCreated(BrowserExtTabsOnCreatedCallback callback); void onRemoved(BrowserExtTabsOnRemovedCallback callback); void onUpdated(BrowserExtTabsOnUpdatedCallback callback); Promise<BrowserExtTabsTab> query(BrowserExtTabQueryDetails queryDetails); Promise<void> reload(BrowserExtTabReloadDetails details); Promise<void> remove((long or sequence<long>) tabIds); Promise<any> sendMessage(long tabId, any message, optional BrowserExtTabSendMessageOptions details); Promise<BrowserExtTabsTab> update(optional long tabId, BrowserExtTabUpdateDetails details); }; [NoInterfaceObject, Exposed=Window, CheckAnyPermissions_browserExtTabs_] interface BrowserExtTabsAPI { readonly attribute BrowserExtTabs tabs; }; Browser implements BrowserExtTabsAPI;
tabs.mutedInfo
will contain the ID of the extension responsible."document_idle"
.interactive
. The DOM has finished loading, but resources such as scripts and images may still be loading.complete
. The document and all its resources have finished loading.loading
. The DOM is still loading.tabs.TAB_ID_NONE
for browser windows that don't host content tabs (for example, devtools windows).sessions
API.tabs.connect()
method.runtime.onConnect
event listeners in content scripts belonging to this extension and running in the specified tab.tabs.create()
method.tabs.executeScript()
and tab.insertCSS()
methods.tabs.captureVisibleTab()
method.tabs.query()
method.windows.WINDOW_ID_CURRENT
for the current window.tabs.reload()
method.tabs.sendMessage()
method.tabs.update()
method.tabs.onActivated()
callback.tabs.onRemoved()
callback.tabs.onUpdated()
callback.tabs.onActivated()
event.tabs.onCreated()
event.tabs.onRemoved()
event.tabs.onUpdated()
event.browser.tabs
object.tabs.Tab
object. This is an asynchronous function that returns a Promise.tabs.Tab
containing information about the tab that this script is running in. You can call this function in contexts where there is a browser tab, such as an options page. If you call it from a background script or a popup, it will return undefined. This is an asynchronous function that returns a Promise.tabs.onUpdated
events to be notified when a URL is set.tabs.onUpdated
events to be notified when a URL is set.BrowserExtTabUpdateDetails
are not modified.
This is an asynchronous function that returns a Promise.browser.tabs
object.browser.tabs
object.webNavigation
object
The webNavigation
object is used to monitor events related to networking requests.
The "webNavigation"
permission is required to use this object.
{ "permissions": [ // Required "webNavigation" // Required ] // Required }
This API is available in Window context (background, event, popup, options and custom pages).
A description of the special WebIDL syntax considerations for browser extensions are defined elsewhere in this document.
enum BrowserExtTransitionType { "link", "typed" }; dictionary BrowserExtWebNavigationOnBeforeNavigateDetails { long frameId; long parentFrameId; long tabId; double timeStamp; DOMString url; }; dictionary BrowserExtWebNavigationOnCommittedDetails { long frameId; long processId; long tabId; double timeStamp; TransitionType transitionType; DOMString url; }; dictionary BrowserExtWebNavigationOnCompletedDetails { long frameId; long processId; long tabId; double timeStamp; DOMString url; }; dictionary BrowserExtWebNavigationOnDOMContentLoadedDetails { long frameId; long processId; long tabId; double timeStamp; DOMString url; }; dictionary BrowserExtWebNavigationOnErrorOccurredDetails { DOMString error; long frameId; long tabId; double timeStamp; DOMString url; }; dictionary BrowserExtWebNavigationOnReferenceFragmentUpdatedDetails { long frameId; long processId; long tabId; double timeStamp; BrowserExtTransitionType transitionType; DOMString url; }; callback BrowserExtWebNavigationOnBeforeNavigateCallback = void (BrowserExtWebNavigationOnBeforeNavigateDetails details); callback BrowserExtWebNavigationOnCommittedCallback = void (BrowserExtWebNavigationOnCommittedDetails details); callback BrowserExtWebNavigationOnCompletedCallback = void (BrowserExtWebNavigationOnCompletedDetails details); callback BrowserExtWebNavigationOnDOMContentLoadedCallback = void (BrowserExtWebNavigationOnDOMContentLoadedDetails details); callback BrowserExtWebNavigationOnErrorOccurredCallback = void (BrowserExtWebNavigationOnErrorOccurredDetails details); callback BrowserExtWebNavigationOnReferenceFragmentUpdated = void (BrowserExtWebNavigationOnReferenceFragmentUpdatedDetails details); [NoInterfaceObject] interface BrowserExtBrowserWebNavigation { void onBeforeNavigate(BrowserExtWebNavigationOnBeforeNavigateCallback callback); void onCommitted(BrowserExtWebNavigationOnCommittedCallback callback); void onCompleted(BrowserExtWebNavigationOnCompletedCallback callback); void onDOMContentLoaded(BrowserExtWebNavigationOnDOMContentLoadedCallback callback); void onErrorOccurred(BrowserExtWebNavigationOnErrorOccurredCallback callback); void onReferenceFragmentUpdated(BrowserExtWebNavigationOnReferenceFragmentUpdated callback); }; [NoInterfaceObject, Exposed=Window, CheckAnyPermissions_browserExtWebNavigation_] interface BrowserExtWebNavigationAPI { readonly attribute BrowserExtWebNavigation webNavigation; }; Browser implements BrowserExtWebNavigationAPI;
webNavigation.onBeforeNavigate
callback.webNavigation.onCommitted
callback.webNavigation.onCompleted
callback.webNavigation.onDOMContentLoaded
callback.webNavigation.onErrorOccurred
callback.webNavigation.onReferenceFragmentUpdated
callback.webNavigation.onBeforeNavigate
callback.webNavigation.onCommittedCallback
callback.webNavigation.onCompletedCallback
callback.webNavigation.onDOMContentLoadedCallback
callback.webNavigation.onErrorOccurredCallback
callback.webNavigation.onReferenceFragmentUpdated
callback.browser.webNavigation
object.DOMContentLoaded
event is fired in the page. At this point the document is loaded and parsed, and the DOM is fully constructed, but linked resources such as images, stylesheets and subframes may not yet be loaded.browser.webNavigation
object.browser.webNavigation
object.webRequest
object
The webRequest
object is used to modify or cancel networking requests.
The "webRequest"
permission is required to use this object.
{ "permissions": [ // Required "webRequest" // Required "webRequestBlocking" // Optional "<URL pattern>" // Optional, e.g. "*://*.w3.org/" ] // Required }
This API is available in Window context (background, event, popup, options and custom pages).
A description of the special WebIDL syntax considerations for browser extensions are defined elsewhere in this document.
enum BrowserExtResourceType { "font", "image", "main_frame", "object", "other", "ping", "script", "stylesheet", "sub_frame", "xmlhttprequest" }; dictionary BrowserExtWebRequestUploadDetails { any bytes; DOMString? file; }; dictionary BrowserExtWebRequestRequestBody { DOMString? error; object? formData; sequence<BrowserExtWebRequestUploadData>? rawData; }; dictionary BrowserExtWebRequestHttpHeader { DOMString keyName; any value; }; dictionary BrowserExtWebRequestHttpHeaders { sequence<BrowserExtWebRequestHttpHeader> data; }; dictionary BrowserExtWebRequestOnBeforeRequestDetails { long frameId; DOMString method; long parentFrameId; BrowserExtWebRequestRequestBody? requestBody; DOMString requestId; long tabId; double timeStamp; BrowserExtResourceType type; DOMString url; }; dictionary BrowserExtWebRequestOnBeforeSendHeadersDetails { long frameId; DOMString method; long parentFrameId; BrowserExtWebRequestHttpHeaders? requestHeaders; DOMString requestId; long tabId; double timeStamp; BrowserExtResourceType type; DOMString url; }; dictionary BrowserExtWebRequestOnCompletedDetails { long frameId; boolean fromCache; DOMString method; long parentFrameId; DOMString requestId; BrowserExtWebRequestHttpHeaders? responseHeaders; DOMString? serverIP; long statusCode; DOMString statusLine; long tabId; double timeStamp; BrowserExtResourceType type; DOMString url; }; dictionary BrowserExtWebRequestOnHeadersReceivedDetails { long frameId; DOMString method; long parentFrameId; DOMString requestId; BrowserExtWebRequestHttpHeaders? responseHeaders; long statusCode; DOMString statusLine; long tabId; double timeStamp; BrowserExtResourceType type; DOMString url; }; dictionary BrowserExtWebRequestOnSendHeadersDetails { long frameId; DOMString method; long parentFrameId; BrowserExtWebRequestHttpHeaders? requestHeaders; DOMString requestId; long tabId; double timeStamp; BrowserExtResourceType type; DOMString url; }; callback BrowserExtWebRequestOnBeforeRequestCallback = void (BrowserExtWebRequestOnBeforeRequestDetails details); callback BrowserExtWebRequestOnBeforeSendHeadersCallback = void (BrowserExtWebRequestOnBeforeSendHeadersDetails details); callback BrowserExtWebRequestOnCompletedCallback = void (BrowserExtWebRequestOnCompletedDetails details); callback BrowserExtWebRequestOnHeadersReceivedCallback = void (BrowserExtWebRequestOnHeadersReceivedDetails details); callback BrowserExtWebRequestOnSendHeadersCallback = void (BrowserExtWebRequestOnSendHeadersDetails details); [NoInterfaceObject] interface BrowserExtBrowserWebRequest { void onBeforeRequest(BrowserExtWebRequestOnBeforeRequestCallback callback); void onBeforeSendHeaders(BrowserExtWebRequestOnBeforeSendHeadersCallback callback); void onCompleted(BrowserExtWebRequestOnCompletedCallback callback); void onHeadersReceived(BrowserExtWebRequestOnHeadersReceivedCallback callback); void onSendHeaders(Function callback); }; [NoInterfaceObject, Exposed=Window, CheckAnyPermissions_browserExtWebRequest_] interface BrowserExtWebRequestAPI { readonly attribute BrowserExtWebRequest webRequest; }; Browser implements BrowserWebRequestAPI;
browser.webRequest
events for font requests.browser.webRequest
events for image requests.browser.webRequest
events for main frame requests.browser.webRequest
events for object requests.browser.webRequest
events for requests of a type not declared here.browser.webRequest
events for ping requests.browser.webRequest
events for script requests.browser.webRequest
events for stylesheet requests.browser.webRequest
events for subframe requests.browser.webRequest
events for xmlhttprequest requests.webRequest.onBeforeRequestCallback
callback.webRequest.onBeforeSendHeadersCallback
callback.webRequest.onCompletedCallback
callback.webRequest.onHeadersReceivedCallback
callback.webRequest.onSendHeadersCallback
callback.browser.webRequest
object.browser.webRequest
object.browser.webRequest
object.windows
object
The windows
object is used to access the UI windows managed by the browser.
There are no additional manifest entries required for an extension to use this object.
This API is available in Window context (background, event, popup, options and custom pages).
A description of the special WebIDL syntax considerations for browser extensions are defined elsewhere in this document.
enum BrowserExtWindowsWindowType { "detached_panel", "normal", "panel", "popup" }; enum BrowserExtWindowsWindowState { "docked", "fullscreen", "maximized", "minimized", "normal" }; dictionary BrowserExtCreateWindowDetails { boolean focused; long height; boolean incognito; long left; BrowserExtWindowsWindowState? state; long tabId; long top; (DOMString? or sequence<DOMString>?) url; long width; BrowserExtWindowsWindowType? windowType; }; dictionary BrowserExtGetWindowDetails { boolean populate; sequence<BrowserExtWindowsWindowType>? windowTypes; }; dictionary BrowserExtWindowUpdateDetails { boolean drawAttention; boolean focused; long height; long left; long top; long width; BrowserExtWindowState? windowState; }; dictionary BrowserExtWindowsWindow { boolean alwaysOnTop; boolean focused; long height; long id; boolean incognito; long left; sequence<BrowserExtTabsTab>? tabs; long top; DOMString? sessionId; BrowserExtWindowsWindowState? state; long width; BrowserExtWindowsWindowType? windowType; }; callback BrowserExtWindowsOnFocusChangedCallback = void (long windowId); [NoInterfaceObject] interface BrowserExtWindows { Promise<BrowserExtWindowsWindow> create(CreateWindowDetails details); Promise<BrowserExtWindowsWindow> get(long windowId, optional BrowserExtGetWindowDetails details); Promise<sequence<BrowserExtWindowsWindow>> getAll(optional BrowserExtGetWindowDetail details); Promise<BrowserExtWindowsWindow> getCurrent(optional BrowserExtGetWindowDetail details); Promise<BrowserExtWindowsWindow> getLastFocused(optional BrowserExtGetWindowDetail details); void onFocusChanged(BrowserExtWindowsOnFocusChangedCallback callback); Promise<BrowserExtWindowsWindow> update(long windowId, optional BrowserExtWindowUpdateDetails details); }; [NoInterfaceObject, Exposed=Window, CheckAnyPermissions_browserExt_] interface BrowserExtWindowsAPI { readonly attribute BrowserExtWindows windows; }; Browser implements BrowserExtWindowsAPI;
windows.Window
object will have a tabs property that contains a list of tabs.Tab
objects representing the tabs open in the window. The Tab objects only contain the url, title and favIconUrl properties if the extension's manifest file includes the "tabs" permission.BrowserExtWindowsWindowType
tabs.Tab
objects representing the current tabs in the window.browser.windows.onFocusChanged
callback.browser.windows
object.windows.WINDOW_ID_NONE
if all browser windows have lost focus.browser.windows
object.browser.windows
object.Native Messaging is covered in another specification. Refer to the Native Messaging for Browser Extensions specification [[browserext-native]] for more information.
Extension events are similar to DOM Events [DOM4]. However, extension events are dispatched only to objects in the relevant extension scope (background, event, options, content, etc.). Script in the extension scope can observe events by calling addListener()
.
[NoInterfaceObject, Exposed=(Window,ContentScript), CheckAnyPermissions_browserExt_] interface BrowserExtEvent { void addListener(Function callback); void removeListener(Function callback); boolean hasListener(Function callback); boolean hasListeners(); };
Message strings are used in the manifest.json
file as well browser.i18n.getMessage()
.
Predefined messages are accessed in the same way as other messages. The syntax for standard messages is:
__MSG_extensionName__
Predefined messages use exactly the same syntax, except with @@ before the message name. For example:
__MSG_@@ui_locale__
The following table shows the different available predefined messages:
Message name | Description |
@@extension_id | The extension or app ID; you might use this string to construct URLs for resources inside the extension. Even unlocalized extensions can use this message. Note that you can't use this message in a manifest file. |
@@ui_locale | The current locale; you might use this string to construct locale-specific URLs. |
@@bidi_dir | The text direction for the current locale, either "ltr" for left-to-right languages such as English or "rtl" for right-to-left languages such as Arabic. |
@@bidi_reversed_dir | If the @@bidi_dir is "ltr", then this is "rtl"; otherwise, it's "ltr". |
@@bidi_start_edge | If the @@bidi_dir is "ltr", then this is "left"; otherwise, it's "right". |
@@bidi_end_edge | If the @@bidi_dir is "ltr", then this is "right"; otherwise, it's "left". |
Standards-compliant browsers are expected to ignore "//" comments. Disregarding comments, the manifest.json file format for browser extensions is expected to be fully JSON compliant. Malformed JSON files are not supported. If manifest keys that are not defined in this specification are specified, other browsers MAY ignore those keys.
The full list of supported manifest keys is provided below:
Key | Required | Details |
---|---|---|
"name" | Required | The name of the extension. |
"version" | Required | A string representation of a number |
"default_locale" | Required if extension uses locales. Not allowed if extension does not use locales | See Message Strings and browser.i18n for more information about the use of locales and localized resources. |
"description" | Optional | Describes the capabilities of the extension. |
"icons" : { | Optional | A list of pairs of pixel dimensions and JPEG filenames. These are typically used to display visuals for the extension in browser management UI for extensions. Browsers MAY require specific sizes. For example,"icons":{ would be used for a small JPEG with height of 16 pixels and width of 16 pixels (small.jpg), and a second JPEG 32x32 pixels in size (medium.jpg). |
"developer": { | Optional | Includes subkeys for "name" and "url" that provide information about the entity that authored the extension, typically a company or programmer name. The "url" subkey SHOULD refer to the company/programmer site, not a description of the extension. |
"browser_action" | Optional Note that some browsers only permit "browser_action" or "page_action" , but not both at the same time | See browser.browserAction for more information about the subkeys for "browser_action" . |
"page_action" | Optional Note that some browsers only permit "browser_action" or "page_action" , but not both at the same time | See browser.pageAction for more information about the subkeys for "page_action" . |
"browser_specific_settings":{ | Optional | Describes specific values that MAY be considered by a browser. For example, a particular extension may require version 42 or greater of the Gecko browser in order to work properly:"browser_specific_settings":{ |
"background" : { | Optional If "background" is specified, "persistent" is required.Other subkeys are optional | Automatically loads a page or script and begins execution, regardless of the page being viewed in a tab. |
"content_scripts" : { | Optional | Automatically adds scripts (from the "js" subkey list) or CSS (from the "css" subkey list) to each page within a tab.If all_frames is false , the string patterns from matches and exclude_matches are used accordingly to determine which page content is modified or excluded.Valid values for "run_at" are "document_start", "document_end" and "document_idle" . |
"content_security_policy" | Optional | A string representation of the new policy to override the default policy. See Content Security Policy (CSP) for more information. |
"options_page" | Optional | The page within the extension that allows extension users to modify settings or options for the extension. |
"manifest_version" | Optional | This is not used |
"required_keys":[...] | Optional | See the required_keys key section for more information about this key. |
"web_accessible_resources":[...] | Optional | Resources listed here may be accessed by Internet-hosted site pages. |
"externally_connectable": [ | Optional | Other extensions or Internet-hosted site pages may send messages to this extension if their extension ID ("ids" ) or page URL pattern ("matches" ) are specified. |
"permissions" : { | Optional | Each subkey must be specified in order to use the associated API.
<url-pattern> allow additional permissions for URLs that match those patterns. See Permissions URL patterns for more information.
|
The "permissions"
key may include match patterns that follow the structure <scheme>://<host>/<path>
, such as "*://*.w3.org/*"
. The special
pattern "<all_urls>"
is also permitted. The match patterns identify a group of URLs for which the extension is requesting extra privileges:
tabs.executeScript
into pages from those originswebRequest
API for those originsactiveTab
permission The "activeTab"
permission enables the use of browser.tabs
API only if the user has actively initiated an action such as the browserAction
. The browser.tabs
API can be used until the tab is navigated to another page or closed.
Passive background-only extensions cannot use the browser.tabs
API unless both the "tabs"
permission and a URL pattern (e.g. "<all_urls>"
or "http://*"
or "*://&.w3.org/*"
) are explicitly declared in manifest.json
.
required_keys
keyThis key is optional, but if it is specified, it provides a list of strings representing manifest keys that MUST be supported. If the browser loading the extension does not support the specified key, the browser MUST reject the manifest and not load the extension.
// Standards-compliant browsers are expected to ignore "//" comments. Disregarding comments, // the manifest.json file format for browser extensions is expected to be fully JSON compliant. // Malformed JSON files are not supported. // // Other manifest keys that are well-formed JSON but are not listed here MUST be ignored. // // Note that some fields marked as Optional here are required by vendor-specific distribution Stores. { "name": "The Name of Your Extension", // Required "version": "Your Extension Version", // Required "default_locale": "en", // Required if locales are used. Otherwise, not allowed "description": "Description for Your Extension", "icons": {...}, "developer": { "name": "Your Name or Company", "url": "Company Website" } // Note: Some browsers require an extension to use either browser_action or page_action, but not both simultaneously "browser_action": { "default_icon": {...}, // Same format as "icons" "default_popup": "Page URL", "default_title": "Title string" }, "page_action": {...}, // Same format as "browser_action" "browser_specific_settings": { "<browser_name>": { // Examples "gecko","opera","edge" "<key>": "<value>" // Examples "strict_min_version": "42.0", "id": "addon@example.com" } }, "background": { "page": "Page URL", // Only one of "page" or "scripts" is supported, but not both simultaneously "scripts": [], // Only one of "page" or "scripts" is supported, but not both simultaneously "persistent": false // Required if "background" is specified }, "content_scripts": { "all_frames": false, "css": [], "exclude_matches": [], "js": [], "matches": [], "run_at" : "document_start" // Also "document_end", "document_idle" } "content_security_policy": "<policy-string>", "options_page": "Page URL", // Optional "manifest_version": 2, // Not used "required_keys": [], // If a browser does not recognize a key in this list, it MUST // reject the manifest (e.g. "sidebar_action") // FEEDBACK: Rename to "required_capabilities" "permissions": { "activeTab", "contextMenus", "tabs", "webNavigation", "webRequest", "webRequestBlocking", "<url-pattern>" // Examples "http://*/*", "<all_urls>" }, "web_accessible_resources": [...] "externally_connectable" : [ "ids":[...], // Identifiers for other extensions that are allowed to send messages "matches":[...] // URL patterns for hosted web pages allowed to send messages ] }
browserext://
protocol
To access resources within the extension, such as browserext://<ext_id>/options.html
, the browserext://
protocol is used.
Each extension has an extension ID that follows the browserext://
protocol. For example
browserext://MyExtension_c1wakc4j0nefm/options.html
browserext://dfcijpibodeoenkablikbkiobbdnkfki/options.html
The algorithms that generate these IDs are different for each browser. To access these resources, do not hardcode the ID generated by a particular browser. Instead, use the runtime.getURL()
method to convert a relative file name or path to the absolute name or path, which includes the extension ID.
Content Security Policy (CSP) is intended to prevent inadvertant execution of malicious code. The default CSP for web content is discussed in the specification [[CSP3]] . For extensions, the default CSP is
"script-src 'self'; object-src 'self';"
This means:
<script>
and <object>
resources that are included in the extension package may be accessed
If the extension must access additional script libraries such as jQuery, copies of the .js files must be included in the extension package.
Alternatively, an extension may loosen the restriction and allow a remote file to be accessed. In this case, the origin for the hosted .js file may be specified in the "content_security_policy"
key in manifest.json
. For example:
"content_security_policy" : "script-src 'self' https://*.jquery.com; object-src 'self'"
The following are restricted by default:
eval("script_goes_here;");
window.setTimeout("script_goes_here;", t);
var f = new Function("script_goes_here;");
To enable the use of these evaluators, the CSP may be modified to include 'unsafe-eval'
as follows:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';"
Inline <script>
tags and inline event handlers (e.g. <div onclick="script_goes_here;">
) are silently ignored. To enable the use of inline script, a SHA256 hash of the entire tag may be added to the "content_security_policy"
key in manifest.json
. For example, replace <hash_goes_here>
with the actual hash in the following:
"content_security_policy" : "script-src 'self' 'sha256-<hash_goes_here>'; object-src 'self'"
Content scripts get the same cross-domain privileges as the rest of the extension. So if the extension has requested cross-domain access for a domain using the permissions key in manifest.json
, then its content scripts get access that domain as well.
Although content scripts can't directly use most of the extension APIs, they can communicate with the extension's background scripts using the messaging APIs, and can therefore indirectly access all the same APIs that the background scripts can.
Browsers vendors MAY choose to implement WebDriver support in their browsers to allow for the automated testing of browser extensions. To implement this support, the browser MUST support:
In addition to the endpoints defined in the WebDriver specification [[webdriver]], support for browser extensions requires these additional endpoints.
Method | URI Template | Command |
---|---|---|
POST | /session/{sessionId}/browserext | Install Browser Extensions |
DELETE | /session/{sessionId}/browserextextensionId} | Uninstall a Browser Extension |
GET | /session/{sessionId}/browserexts | Get Browser Extensions |
GET | /session/{sessionId}/browserext/{extensionId}/actions | Get Browser Extension Actions |
POST | /session/{sessionId}/browserext/{extensionId}/action/ | Take Browser Extension Action |
GET | /session/{sessionId}/element/{element id}/browserext/contextMenuItems | Get Browser Extension Context Menu Items |
POST | /session/{sessionId}/element/{element id}/browserext/contextMenuItem/{menuitemId} | Select Browser Extension Context Menu Item |
GET | /session/{sessionId}/browserext/permissionPrompt | Get Browser Extension Permission Prompt Text |
POST | /session/{sessionId}/browserext/permissionPrompt/{promptId}/action/{promptAction} | Take Browser Extension Permission Prompt Action |
In addition to the codes defined in the Handling Errors section of the WebDriver specification [[webdriver]], support for browser extensions requires support the following additional error codes:
Error Code | HTTP Status | JSON Error Code | Description |
---|---|---|---|
no such extension path | 400 | no such extension path |
The filepath specified does not point to a valid browser extension on disk. |
extension not installable | 400 | extension not installable |
The specified extension could not be installed for some reason, e.g. its manifest.json is malformed or missing |
no such browser extension | 400 | no such browser extension |
There is no available browser extension on the current page with the given type. |
no such browser extension action | 400 | no such browser action |
A request to take a browser extension action could not be satisfied because there is no browser extension action with the given id. |
no such browser extension context menu item | 400 | no such browser extension context menu item |
A request to select an extension context menu item could not be completed because there is no matching extension context menu item for the given element. |
no such browser extension permission prompt | 400 | no such browser extension permission prompt |
A request to obtain the permission prompt information could not be completed because there is no permission prompt at this time or the requested prompt was not available. |
no such browser extension permission prompt action | 400 | no such browser extension permission prompt action |
A request to take the specified action could not be completed because the action was not available. |
In addition to the Capabilities defined in the WebDriver specification [[webdriver]], support for browser extensions requires the following additional entry on the server capabilities JSON object:
enabledBrowserExtensions
"
manifest.json
file. Subfolders containing manifest.json
files will not be searched.
No browser extension will be installed or pre-loaded during a WebDriver session unless it is explicitly specified in the enabledBrowserExtensions
array. Browser extensions loaded during the session will not be available to other active instances of the browser that are not part of the WebDriver session. When the session ends, the array of browser extensions are unloaded and uninstalled.
Users interact with extensions through several means. First there are actions embedded in the UI of the browser, which can do something directly or open a popup. If the extension uses a popup, it can contain any html content. Finally, extensions can add items to the browser's context menu. WebDriver needs to be able to emulate user actions for all three of these controls in order to completely emulate user interaction.
In addition to the commands defined in the WebDriver specification [[webdriver]], support support for browser extensions requires the following additional commands.
installBrowserExtensions()
HTTP Method | Path Template | Notes |
---|---|---|
POST | /session/{sessionId}/browserext |
This command installs any number of specified extensions from disk at runtime
The value of the extensionPaths
property MUST be an array of absolute paths which point to the location of browser extension files. The path MUST point to either a single file appropriate for a specific brower (e.g. .crx) or a folder which contains the extension source files. If a folder is specified, the folder itself MUST contain a manifest.json
file. Subfolders containing manifest.json
files will not be searched.
If any of the absolute paths specified in the extensionPaths
property are invalid, a
no such extension path
status code MUST be returned.
If the installation of any extensions specified in the extensionPaths
property fail, an
extension not installable
status code MUST be returned.
uninstallBrowserExtensions()
HTTP Method | Path Template | Notes |
---|---|---|
DELETE | /session/{sessionId}/browserext/{extensionId} |
This command uninstalls an extension in a specified browsing session.
If the extensionId specified does not correspond to a browser extension in the current sesssion, a
no such browser extension
status code MUST be returned.
getBrowserExtensions()
HTTP Method | Path Template | Notes |
---|---|---|
GET | /session/{sessionId}/browserexts |
This command returns a list of all browser extensions available to the current browsing session.
Let extension be a new JSON Object.
Set the property id
on extension to a
string which is unique for each browser extension.
Set the property name
on extension to a
string which corresponds to the browser extension's "name"
entry in manifest.json
.
getBrowserExtActions()
HTTP Method | Path Template | Notes |
---|---|---|
GET | /session/{sessionId}/browserext/{extensionId}/actions |
This command returns a list of browser extension actions available for a particular browser extension. Note that this can change from page to page. It MUST return a list of objects which describes the available browser extension actions using the following algorithm for each action:
Let action be a new JSON Object.
Set the property type
on action to a
string which represents the type of browser extension action
Set the property actionTitle
on action to the
mouseover text for the action.
Set the property icon
on action to the
filename of the icon file or an empty string if none is displayed. If the
icon is dynamically generated, the current icon MUST be returned as a
lossless PNG image encoded using Base64.
If the action supports the badgeText
property,
set the property badgeText
on action to the
badge text displayed over the action or an empty string if none is present.
Return success
with data action
getBrowserExtensions()
command.
If the id specified does not correspond to a browser extension in the current sesssion, a
no such browser extension
status code MUST be returned.
takeBrowserExtAction()
HTTP Method | Path Template | Notes |
---|---|---|
POST | /session/{sessionId}/browserext/action/{browserExtActionId} |
This command causes a browser extension action to be activated. Depending on the extensionActionType
specified, this
will have one of several effects:
extensionActionType | Effect |
---|---|
browserAction |
This extensionActionType causes a browserAction to be activated,
as if the user had clicked the browser extension's browserAction icon in the browser's chrome.
Depending on the browser extension, this may cause a popup to be opened.
|
pageAction |
This extensionActionType causes a pageAction to be activated,
as if the user had clicked the browser extension's pageAction icon in the browser's address bar.
Depending on the browser extension, this may cause a popup to be opened.
|
enable |
This extensionActionType causes the specified extension to be enabled,
as if the user had turned the extension on from the browser's management UI. If the extension
is already enabled, this command has no effect.
|
disable |
This extensionActionType causes the specified extension to be disabled,
as if the user had turned the extension off from the browser's management UI. If the extension
is already disabled, this command has no effect.
|
getBrowserExtensions()
command.
If the extensionId specified does not correspond to a browser extension in the current sesssion, a
no such browser extension
status code MUST be returned.
getBrowserExtensionActions()
command. This value
SHOULD be one of the following: "pageAction
",
"browserAction
", "enable
", or "disable
"
If the type specified does not correspond to a browser extension action available in the browser/on the current page, a
no such browser extension action
status code MUST be returned.
getBrowserExtContextMenuItems()
HTTP Method | Path Template | Notes |
---|---|---|
GET | /session/{sessionId}/element/{elementId}/browserext/contexMenuItems |
This command opens a context menu for a given element. It MUST return a list of objects which describes the available context menu items using the following algorithm for each menu item:
Let menuitem be a new JSON Object.
Set the property id
on menuitem to a
string which is unique for the current session.
Set the property menuItemTitle
on menuitem to the
text that is displayed in the UI.
Set the property icon
on menuitem to the
filename of the icon file or an empty string if none is displayed.
If the icon is set because of the type of the context menu item (such as
a radio button or checkbox), the icon
property MUST be set
to a string which is consistent for all icons of that type and status
(e.g. checked), including across sessions.
Set the property parent
on menuitem to the
id of the item's parent or an empty string if the menuitem does not have
a parent.
Set the property itemType
on menuitem to a string value identifying the control type.
String Value | Description |
---|---|
checkbox
|
A checkbox element |
normal
|
A standard menuItem element (text label) |
radio
|
A radio element. Within a radio group, only one menuItem will have a value of true
|
separator
|
A horizontal line separator, typically used between groups of related items such as radio groups |
Set the property itemChecked
on menuitem to a boolean value indicating
state of the item according to the following table. This applies only to items of itemType checkbox
or radio
. Within a radio group, only one menuItem will have a value of true
.
Boolean Value | Description |
---|---|
true
|
Selected |
false
|
Not selected |
Return success
with data menuitem
After this command has been run, the context menu MUST remain open until the next command that dismisses it (e.g. clicking, navigation) has been run.
selectBrowserExtContextMenuItem()
HTTP Method | Path Template | Notes |
---|---|---|
POST | /session/{sessionId}/element/{elementId}/browserext/contextMenuItem/{menuitemId} |
This command causes a context menu item to be selected. This MUST have the same effect as a user clicking or tapping the item in the open context menu. If the menu item is a parent of other menu items, this command MAY open a submenu, but MUST NOT have any other effect.
This command MUST be executed even if there is no context menu open.
getBrowserExtContextMenuItems()
command.
If no context menu is currently open, a
no such extension context menu item
status code MUST be returned.
getBrowserExtPermissionPrompt()
HTTP Method | Path Template | Notes |
---|---|---|
GET | /session/{sessionId}/browserext/permissionPrompt |
Upon installation of a browser extension, a browser MAY notify the user of potential privacy-related capabilities of the extension. For example, if an extension's manifest.json
requests the "tabs"
or "webNavigation"
permission, the browser MAY request user confirmation of these permissions. This command returns a JSON object that includes the names of permissions which require user confirmation and other information about the prompt. A similar prompt MAY also occur if an extension has been updated and the newer version requires additional permisisons. If there is no prompt at the time this API is called, the error "no such browser extension permission prompt" is returned.
promptId
to a string which is unique for each time a prompt is displayed.promptMessageText
to a string which represents the text shown to the user, localized to the default locale specified in manifest.json
.promptDefaultLocale
to the default locale code specified in manifest.json
. If locales are not used by the extension, the property SHOULD be omitted, but MAY return an empty string ("").promptRequestingUrl
to a string representing the relevant URL. Strings returned here are the same strings defined in the "permissions": [ ]
section of manisfest.json
. If a URL is not applicable to the prompt, the property SHOULD be omitted but MAY also return an empty string ("").promptPermissions
to an array of strings which correspond to requested permissions. Strings returned here are the same strings defined in the "permissions": [ ]
section of manisfest.json
. If permissions are not applicable to the prompt, the property SHOULD be omitted, but MAY include an empty array ([]) or an array of empty strings ([""]). promptActions
to an array of strings which correspond to possible actions the user could take. The actions allow
and deny
are required. Other optional values MAY be returned, but the behavior is not prescribed in this specification.promptAction | Required | Description |
---|---|---|
allow
|
Required | Allows the extension to use or access the capabilities or sites |
deny
|
Required |
Denies extension's use of the requested capabilities or sites. The browser implementation of deny is not prescribed in this specification, and MAY result in the cancellation of the extension's installation.
|
dismiss
|
Optional |
Some browsers MAY provide the user with an option to close a prompt without taking an accept or deny action. The browser implementation of dismiss is not prescribed in this specification, and MAY result in the cancellation of the extension's installation.
|
{custom}
|
Optional |
Some browsers MAY provide additional options not prescribed in this table. For example, alwaysAllow , allowOnce or allowForThisSiteOnly may be presented in a permission prompt. The browser implementation for these custom actions is not prescribed in this specification.
|
takeBrowserExtPermissionPromptAction()
HTTP Method | Path Template | Notes |
---|---|---|
POST | /session/{sessionId}/browserext/permissionPrompt/{promptId}/action/{promptAction} |
Performs the action specified by promptAction
. If there is no prompt at the time this API is called, or if the requested promptId
is not available, the error "no such browser extension permission prompt" is returned. If the requested promptAction
is not available, the error "no such browser extension permission prompt action" is returned.
Browser extensions MAY be distributed and subsequently loaded as individual files or via a container, such as a *.zip archive. Regardless of the packaging format, these containers MUST contain the following:
Browser vendors MAY require that extension packages include a digital signature. The signature MAY indicate the source of the extension, such as a distribution store or the extension's publisher. This aspect of packaging varies by browser, and browser implementers MAY enforce different requirements.
Many thanks to the members of the Browser Extension Community Group for their detailed feedback on this specification. Thanks to the members of the Browser Testing and Tools Working Group for their recommendations and feedback on WebDriver support.
Some sections are reproduced from MDN: