2020-11-06 17:52:14 -05:00
( function ( global , factory ) {
2020-01-04 20:45:00 -05:00
if ( typeof define === "function" && define . amd ) {
define ( "webextension-polyfill" , [ "module" ] , factory ) ;
} else if ( typeof exports !== "undefined" ) {
factory ( module ) ;
} else {
var mod = {
2020-11-06 17:52:14 -05:00
exports : { } ,
2020-01-04 20:45:00 -05:00
} ;
factory ( mod ) ;
global . browser = mod . exports ;
}
} ) (
typeof globalThis !== "undefined"
? globalThis
: typeof self !== "undefined"
? self
: this ,
2020-11-06 17:52:14 -05:00
function ( module ) {
2020-01-04 20:45:00 -05:00
/* webextension-polyfill - v0.6.0 - Mon Dec 23 2019 12:32:53 */
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
/ * T h i s S o u r c e C o d e F o r m i s s u b j e c t t o t h e t e r m s o f t h e M o z i l l a P u b l i c
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
"use strict" ;
if (
typeof browser === "undefined" ||
Object . getPrototypeOf ( browser ) !== Object . prototype
) {
const CHROME _SEND _MESSAGE _CALLBACK _NO _RESPONSE _MESSAGE =
"The message port closed before a response was received." ;
const SEND _RESPONSE _DEPRECATION _WARNING =
"Returning a Promise is the preferred way to send a reply from an onMessage/onMessageExternal listener, as the sendResponse will be removed from the specs (See https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage)" ; // Wrapping the bulk of this polyfill in a one-time-use function is a minor
// optimization for Firefox. Since Spidermonkey does not fully parse the
// contents of a function until the first time it's called, and since it will
// never actually need to be called, this allows the polyfill to be included
// in Firefox nearly for free.
2020-11-06 17:52:14 -05:00
const wrapAPIs = ( extensionAPIs ) => {
2020-01-04 20:45:00 -05:00
// NOTE: apiMetadata is associated to the content of the api-metadata.json file
// at build time by replacing the following "include" with the content of the
// JSON file.
const apiMetadata = {
alarms : {
clear : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
clearAll : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
get : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getAll : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
bookmarks : {
create : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
get : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getChildren : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getRecent : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getSubTree : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getTree : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
move : {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
remove : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removeTree : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
search : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
update : {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
browserAction : {
disable : {
minArgs : 0 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
2020-01-04 20:45:00 -05:00
} ,
enable : {
minArgs : 0 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
2020-01-04 20:45:00 -05:00
} ,
getBadgeBackgroundColor : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getBadgeText : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getPopup : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getTitle : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
openPopup : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
setBadgeBackgroundColor : {
minArgs : 1 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
2020-01-04 20:45:00 -05:00
} ,
setBadgeText : {
minArgs : 1 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
2020-01-04 20:45:00 -05:00
} ,
setIcon : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
setPopup : {
minArgs : 1 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
2020-01-04 20:45:00 -05:00
} ,
setTitle : {
minArgs : 1 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
} ,
2020-01-04 20:45:00 -05:00
} ,
browsingData : {
remove : {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
removeCache : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removeCookies : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removeDownloads : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removeFormData : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removeHistory : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removeLocalStorage : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removePasswords : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removePluginData : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
settings : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
commands : {
getAll : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
contextMenus : {
remove : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removeAll : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
update : {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
cookies : {
get : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getAll : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getAllCookieStores : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
remove : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
set : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
devtools : {
inspectedWindow : {
eval : {
minArgs : 1 ,
maxArgs : 2 ,
2020-11-06 17:52:14 -05:00
singleCallbackArg : false ,
} ,
2020-01-04 20:45:00 -05:00
} ,
panels : {
create : {
minArgs : 3 ,
maxArgs : 3 ,
2020-11-06 17:52:14 -05:00
singleCallbackArg : true ,
} ,
} ,
2020-01-04 20:45:00 -05:00
} ,
downloads : {
cancel : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
download : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
erase : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getFileIcon : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
open : {
minArgs : 1 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
2020-01-04 20:45:00 -05:00
} ,
pause : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removeFile : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
resume : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
search : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
show : {
minArgs : 1 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
} ,
2020-01-04 20:45:00 -05:00
} ,
extension : {
isAllowedFileSchemeAccess : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
isAllowedIncognitoAccess : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
history : {
addUrl : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
deleteAll : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
deleteRange : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
deleteUrl : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getVisits : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
search : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
i18n : {
detectLanguage : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getAcceptLanguages : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
identity : {
launchWebAuthFlow : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
idle : {
queryState : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
management : {
get : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getAll : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
getSelf : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
setEnabled : {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
uninstallSelf : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
notifications : {
clear : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
create : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
getAll : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
getPermissionLevel : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
update : {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
pageAction : {
getPopup : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getTitle : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
hide : {
minArgs : 1 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
2020-01-04 20:45:00 -05:00
} ,
setIcon : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
setPopup : {
minArgs : 1 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
2020-01-04 20:45:00 -05:00
} ,
setTitle : {
minArgs : 1 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
2020-01-04 20:45:00 -05:00
} ,
show : {
minArgs : 1 ,
maxArgs : 1 ,
2020-11-06 17:52:14 -05:00
fallbackToNoCallback : true ,
} ,
2020-01-04 20:45:00 -05:00
} ,
permissions : {
contains : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getAll : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
remove : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
request : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
runtime : {
getBackgroundPage : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
getPlatformInfo : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
openOptionsPage : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
requestUpdateCheck : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
sendMessage : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 3 ,
2020-01-04 20:45:00 -05:00
} ,
sendNativeMessage : {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
setUninstallURL : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
sessions : {
getDevices : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getRecentlyClosed : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
restore : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
storage : {
local : {
clear : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
get : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getBytesInUse : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
remove : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
set : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
managed : {
get : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getBytesInUse : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
sync : {
clear : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
get : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getBytesInUse : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
remove : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
set : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
} ,
2020-01-04 20:45:00 -05:00
} ,
tabs : {
captureVisibleTab : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
create : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
detectLanguage : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
discard : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
duplicate : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
executeScript : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
get : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getCurrent : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
2020-01-04 20:45:00 -05:00
} ,
getZoom : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getZoomSettings : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
highlight : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
insertCSS : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
move : {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
query : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
reload : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
remove : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
removeCSS : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
sendMessage : {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 3 ,
2020-01-04 20:45:00 -05:00
} ,
setZoom : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
setZoomSettings : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
update : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
topSites : {
get : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
webNavigation : {
getAllFrames : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getFrame : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
webRequest : {
handlerBehaviorChanged : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 0 ,
} ,
2020-01-04 20:45:00 -05:00
} ,
windows : {
create : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
get : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
2020-01-04 20:45:00 -05:00
} ,
getAll : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getCurrent : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
getLastFocused : {
minArgs : 0 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
remove : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
update : {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 2 ,
} ,
} ,
2020-01-04 20:45:00 -05:00
} ;
if ( Object . keys ( apiMetadata ) . length === 0 ) {
throw new Error (
"api-metadata.json has not been included in browser-polyfill"
) ;
}
/ * *
* A WeakMap subclass which creates and stores a value for any key which does
* not exist when accessed , but behaves exactly as an ordinary WeakMap
* otherwise .
*
* @ param { function } createItem
* A function which will be called in order to create the value for any
* key which does not exist , the first time it is accessed . The
* function receives , as its only argument , the key being created .
* /
class DefaultWeakMap extends WeakMap {
constructor ( createItem , items = undefined ) {
super ( items ) ;
this . createItem = createItem ;
}
get ( key ) {
if ( ! this . has ( key ) ) {
this . set ( key , this . createItem ( key ) ) ;
}
return super . get ( key ) ;
}
}
/ * *
* Returns true if the given object is an object with a ` then ` method , and can
* therefore be assumed to behave as a Promise .
*
* @ param { * } value The value to test .
* @ returns { boolean } True if the value is thenable .
* /
2020-11-06 17:52:14 -05:00
const isThenable = ( value ) => {
2020-01-04 20:45:00 -05:00
return (
value &&
typeof value === "object" &&
typeof value . then === "function"
) ;
} ;
/ * *
* Creates and returns a function which , when called , will resolve or reject
* the given promise based on how it is called :
*
* - If , when called , ` chrome.runtime.lastError ` contains a non - null object ,
* the promise is rejected with that value .
* - If the function is called with exactly one argument , the promise is
* resolved to that value .
* - Otherwise , the promise is resolved to an array containing all of the
* function ' s arguments .
*
* @ param { object } promise
* An object containing the resolution and rejection functions of a
* promise .
* @ param { function } promise . resolve
* The promise ' s resolution function .
* @ param { function } promise . rejection
* The promise ' s rejection function .
* @ param { object } metadata
* Metadata about the wrapped method which has created the callback .
* @ param { integer } metadata . maxResolvedArgs
* The maximum number of arguments which may be passed to the
* callback created by the wrapped async function .
*
* @ returns { function }
* The generated callback function .
* /
const makeCallback = ( promise , metadata ) => {
return ( ... callbackArgs ) => {
if ( extensionAPIs . runtime . lastError ) {
promise . reject ( extensionAPIs . runtime . lastError ) ;
} else if (
metadata . singleCallbackArg ||
( callbackArgs . length <= 1 && metadata . singleCallbackArg !== false )
) {
promise . resolve ( callbackArgs [ 0 ] ) ;
} else {
promise . resolve ( callbackArgs ) ;
}
} ;
} ;
2020-11-06 17:52:14 -05:00
const pluralizeArguments = ( numArgs ) =>
2020-01-04 20:45:00 -05:00
numArgs == 1 ? "argument" : "arguments" ;
/ * *
* Creates a wrapper function for a method with the given name and metadata .
*
* @ param { string } name
* The name of the method which is being wrapped .
* @ param { object } metadata
* Metadata about the method being wrapped .
* @ param { integer } metadata . minArgs
* The minimum number of arguments which must be passed to the
* function . If called with fewer than this number of arguments , the
* wrapper will raise an exception .
* @ param { integer } metadata . maxArgs
* The maximum number of arguments which may be passed to the
* function . If called with more than this number of arguments , the
* wrapper will raise an exception .
* @ param { integer } metadata . maxResolvedArgs
* The maximum number of arguments which may be passed to the
* callback created by the wrapped async function .
*
* @ returns { function ( object , ... * ) }
* The generated wrapper function .
* /
const wrapAsyncFunction = ( name , metadata ) => {
return function asyncFunctionWrapper ( target , ... args ) {
if ( args . length < metadata . minArgs ) {
throw new Error (
` Expected at least ${ metadata . minArgs } ${ pluralizeArguments (
metadata . minArgs
) } for $ { name } ( ) , got $ { args . length } `
) ;
}
if ( args . length > metadata . maxArgs ) {
throw new Error (
` Expected at most ${ metadata . maxArgs } ${ pluralizeArguments (
metadata . maxArgs
) } for $ { name } ( ) , got $ { args . length } `
) ;
}
return new Promise ( ( resolve , reject ) => {
if ( metadata . fallbackToNoCallback ) {
// This API method has currently no callback on Chrome, but it return a promise on Firefox,
// and so the polyfill will try to call it with a callback first, and it will fallback
// to not passing the callback if the first call fails.
try {
target [ name ] (
... args ,
makeCallback (
{
resolve ,
2020-11-06 17:52:14 -05:00
reject ,
2020-01-04 20:45:00 -05:00
} ,
metadata
)
) ;
} catch ( cbError ) {
console . warn (
` ${ name } API method doesn't seem to support the callback parameter, ` +
"falling back to call it without a callback: " ,
cbError
) ;
target [ name ] ( ... args ) ; // Update the API method metadata, so that the next API calls will not try to
// use the unsupported callback anymore.
metadata . fallbackToNoCallback = false ;
metadata . noCallback = true ;
resolve ( ) ;
}
} else if ( metadata . noCallback ) {
target [ name ] ( ... args ) ;
resolve ( ) ;
} else {
target [ name ] (
... args ,
makeCallback (
{
resolve ,
2020-11-06 17:52:14 -05:00
reject ,
2020-01-04 20:45:00 -05:00
} ,
metadata
)
) ;
}
} ) ;
} ;
} ;
/ * *
* Wraps an existing method of the target object , so that calls to it are
* intercepted by the given wrapper function . The wrapper function receives ,
* as its first argument , the original ` target ` object , followed by each of
* the arguments passed to the original method .
*
* @ param { object } target
* The original target object that the wrapped method belongs to .
* @ param { function } method
* The method being wrapped . This is used as the target of the Proxy
* object which is created to wrap the method .
* @ param { function } wrapper
* The wrapper function which is called in place of a direct invocation
* of the wrapped method .
*
* @ returns { Proxy < function > }
* A Proxy object for the given method , which invokes the given wrapper
* method in its place .
* /
const wrapMethod = ( target , method , wrapper ) => {
return new Proxy ( method , {
apply ( targetMethod , thisObj , args ) {
return wrapper . call ( thisObj , target , ... args ) ;
2020-11-06 17:52:14 -05:00
} ,
2020-01-04 20:45:00 -05:00
} ) ;
} ;
let hasOwnProperty = Function . call . bind (
Object . prototype . hasOwnProperty
) ;
/ * *
* Wraps an object in a Proxy which intercepts and wraps certain methods
* based on the given ` wrappers ` and ` metadata ` objects .
*
* @ param { object } target
* The target object to wrap .
*
* @ param { object } [ wrappers = { } ]
* An object tree containing wrapper functions for special cases . Any
* function present in this object tree is called in place of the
* method in the same location in the ` target ` object tree . These
* wrapper methods are invoked as described in { @ see wrapMethod } .
*
* @ param { object } [ metadata = { } ]
* An object tree containing metadata used to automatically generate
* Promise - based wrapper functions for asynchronous . Any function in
* the ` target ` object tree which has a corresponding metadata object
* in the same location in the ` metadata ` tree is replaced with an
* automatically - generated wrapper function , as described in
* { @ see wrapAsyncFunction }
*
* @ returns { Proxy < object > }
* /
const wrapObject = ( target , wrappers = { } , metadata = { } ) => {
let cache = Object . create ( null ) ;
let handlers = {
has ( proxyTarget , prop ) {
return prop in target || prop in cache ;
} ,
get ( proxyTarget , prop , receiver ) {
if ( prop in cache ) {
return cache [ prop ] ;
}
if ( ! ( prop in target ) ) {
return undefined ;
}
let value = target [ prop ] ;
if ( typeof value === "function" ) {
// This is a method on the underlying object. Check if we need to do
// any wrapping.
if ( typeof wrappers [ prop ] === "function" ) {
// We have a special-case wrapper for this method.
value = wrapMethod ( target , target [ prop ] , wrappers [ prop ] ) ;
} else if ( hasOwnProperty ( metadata , prop ) ) {
// This is an async method that we have metadata for. Create a
// Promise wrapper for it.
let wrapper = wrapAsyncFunction ( prop , metadata [ prop ] ) ;
value = wrapMethod ( target , target [ prop ] , wrapper ) ;
} else {
// This is a method that we don't know or care about. Return the
// original method, bound to the underlying object.
value = value . bind ( target ) ;
}
} else if (
typeof value === "object" &&
value !== null &&
( hasOwnProperty ( wrappers , prop ) ||
hasOwnProperty ( metadata , prop ) )
) {
// This is an object that we need to do some wrapping for the children
// of. Create a sub-object wrapper for it with the appropriate child
// metadata.
value = wrapObject ( value , wrappers [ prop ] , metadata [ prop ] ) ;
} else if ( hasOwnProperty ( metadata , "*" ) ) {
// Wrap all properties in * namespace.
value = wrapObject ( value , wrappers [ prop ] , metadata [ "*" ] ) ;
} else {
// We don't need to do any wrapping for this property,
// so just forward all access to the underlying object.
Object . defineProperty ( cache , prop , {
configurable : true ,
enumerable : true ,
get ( ) {
return target [ prop ] ;
} ,
set ( value ) {
target [ prop ] = value ;
2020-11-06 17:52:14 -05:00
} ,
2020-01-04 20:45:00 -05:00
} ) ;
return value ;
}
cache [ prop ] = value ;
return value ;
} ,
set ( proxyTarget , prop , value , receiver ) {
if ( prop in cache ) {
cache [ prop ] = value ;
} else {
target [ prop ] = value ;
}
return true ;
} ,
defineProperty ( proxyTarget , prop , desc ) {
return Reflect . defineProperty ( cache , prop , desc ) ;
} ,
deleteProperty ( proxyTarget , prop ) {
return Reflect . deleteProperty ( cache , prop ) ;
2020-11-06 17:52:14 -05:00
} ,
2020-01-04 20:45:00 -05:00
} ; // Per contract of the Proxy API, the "get" proxy handler must return the
// original value of the target if that value is declared read-only and
// non-configurable. For this reason, we create an object with the
// prototype set to `target` instead of using `target` directly.
// Otherwise we cannot return a custom object for APIs that
// are declared read-only and non-configurable, such as `chrome.devtools`.
//
// The proxy handlers themselves will still use the original `target`
// instead of the `proxyTarget`, so that the methods and properties are
// dereferenced via the original targets.
let proxyTarget = Object . create ( target ) ;
return new Proxy ( proxyTarget , handlers ) ;
} ;
/ * *
* Creates a set of wrapper functions for an event object , which handles
* wrapping of listener functions that those messages are passed .
*
* A single wrapper is created for each listener function , and stored in a
* map . Subsequent calls to ` addListener ` , ` hasListener ` , or ` removeListener `
* retrieve the original wrapper , so that attempts to remove a
* previously - added listener work as expected .
*
* @ param { DefaultWeakMap < function , function > } wrapperMap
* A DefaultWeakMap object which will create the appropriate wrapper
* for a given listener function when one does not exist , and retrieve
* an existing one when it does .
*
* @ returns { object }
* /
2020-11-06 17:52:14 -05:00
const wrapEvent = ( wrapperMap ) => ( {
2020-01-04 20:45:00 -05:00
addListener ( target , listener , ... args ) {
target . addListener ( wrapperMap . get ( listener ) , ... args ) ;
} ,
hasListener ( target , listener ) {
return target . hasListener ( wrapperMap . get ( listener ) ) ;
} ,
removeListener ( target , listener ) {
target . removeListener ( wrapperMap . get ( listener ) ) ;
2020-11-06 17:52:14 -05:00
} ,
2020-01-04 20:45:00 -05:00
} ) ; // Keep track if the deprecation warning has been logged at least once.
let loggedSendResponseDeprecationWarning = false ;
2020-11-06 17:52:14 -05:00
const onMessageWrappers = new DefaultWeakMap ( ( listener ) => {
2020-01-04 20:45:00 -05:00
if ( typeof listener !== "function" ) {
return listener ;
}
/ * *
* Wraps a message listener function so that it may send responses based on
* its return value , rather than by returning a sentinel value and calling a
* callback . If the listener function returns a Promise , the response is
* sent when the promise either resolves or rejects .
*
* @ param { * } message
* The message sent by the other end of the channel .
* @ param { object } sender
* Details about the sender of the message .
* @ param { function ( * ) } sendResponse
* A callback which , when called with an arbitrary argument , sends
* that value as a response .
* @ returns { boolean }
* True if the wrapped listener returned a Promise , which will later
* yield a response . False otherwise .
* /
return function onMessage ( message , sender , sendResponse ) {
let didCallSendResponse = false ;
let wrappedSendResponse ;
2020-11-06 17:52:14 -05:00
let sendResponsePromise = new Promise ( ( resolve ) => {
wrappedSendResponse = function ( response ) {
2020-01-04 20:45:00 -05:00
if ( ! loggedSendResponseDeprecationWarning ) {
console . warn (
SEND _RESPONSE _DEPRECATION _WARNING ,
new Error ( ) . stack
) ;
loggedSendResponseDeprecationWarning = true ;
}
didCallSendResponse = true ;
resolve ( response ) ;
} ;
} ) ;
let result ;
try {
result = listener ( message , sender , wrappedSendResponse ) ;
} catch ( err ) {
result = Promise . reject ( err ) ;
}
const isResultThenable = result !== true && isThenable ( result ) ; // If the listener didn't returned true or a Promise, or called
// wrappedSendResponse synchronously, we can exit earlier
// because there will be no response sent from this listener.
if ( result !== true && ! isResultThenable && ! didCallSendResponse ) {
return false ;
} // A small helper to send the message if the promise resolves
// and an error if the promise rejects (a wrapped sendMessage has
// to translate the message into a resolved promise or a rejected
// promise).
2020-11-06 17:52:14 -05:00
const sendPromisedResult = ( promise ) => {
2020-01-04 20:45:00 -05:00
promise
. then (
2020-11-06 17:52:14 -05:00
( msg ) => {
2020-01-04 20:45:00 -05:00
// send the message value.
sendResponse ( msg ) ;
} ,
2020-11-06 17:52:14 -05:00
( error ) => {
2020-01-04 20:45:00 -05:00
// Send a JSON representation of the error if the rejected value
// is an instance of error, or the object itself otherwise.
let message ;
if (
error &&
( error instanceof Error ||
typeof error . message === "string" )
) {
message = error . message ;
} else {
message = "An unexpected error occurred" ;
}
sendResponse ( {
_ _mozWebExtensionPolyfillReject _ _ : true ,
2020-11-06 17:52:14 -05:00
message ,
2020-01-04 20:45:00 -05:00
} ) ;
}
)
2020-11-06 17:52:14 -05:00
. catch ( ( err ) => {
2020-01-04 20:45:00 -05:00
// Print an error on the console if unable to send the response.
console . error ( "Failed to send onMessage rejected reply" , err ) ;
} ) ;
} ; // If the listener returned a Promise, send the resolved value as a
// result, otherwise wait the promise related to the wrappedSendResponse
// callback to resolve and send it as a response.
if ( isResultThenable ) {
sendPromisedResult ( result ) ;
} else {
sendPromisedResult ( sendResponsePromise ) ;
} // Let Chrome know that the listener is replying.
return true ;
} ;
} ) ;
const wrappedSendMessageCallback = ( { reject , resolve } , reply ) => {
if ( extensionAPIs . runtime . lastError ) {
// Detect when none of the listeners replied to the sendMessage call and resolve
// the promise to undefined as in Firefox.
// See https://github.com/mozilla/webextension-polyfill/issues/130
if (
extensionAPIs . runtime . lastError . message ===
CHROME _SEND _MESSAGE _CALLBACK _NO _RESPONSE _MESSAGE
) {
resolve ( ) ;
} else {
reject ( extensionAPIs . runtime . lastError ) ;
}
} else if ( reply && reply . _ _mozWebExtensionPolyfillReject _ _ ) {
// Convert back the JSON representation of the error into
// an Error instance.
reject ( new Error ( reply . message ) ) ;
} else {
resolve ( reply ) ;
}
} ;
const wrappedSendMessage = (
name ,
metadata ,
apiNamespaceObj ,
... args
) => {
if ( args . length < metadata . minArgs ) {
throw new Error (
` Expected at least ${ metadata . minArgs } ${ pluralizeArguments (
metadata . minArgs
) } for $ { name } ( ) , got $ { args . length } `
) ;
}
if ( args . length > metadata . maxArgs ) {
throw new Error (
` Expected at most ${ metadata . maxArgs } ${ pluralizeArguments (
metadata . maxArgs
) } for $ { name } ( ) , got $ { args . length } `
) ;
}
return new Promise ( ( resolve , reject ) => {
const wrappedCb = wrappedSendMessageCallback . bind ( null , {
resolve ,
2020-11-06 17:52:14 -05:00
reject ,
2020-01-04 20:45:00 -05:00
} ) ;
args . push ( wrappedCb ) ;
apiNamespaceObj . sendMessage ( ... args ) ;
} ) ;
} ;
const staticWrappers = {
runtime : {
onMessage : wrapEvent ( onMessageWrappers ) ,
onMessageExternal : wrapEvent ( onMessageWrappers ) ,
sendMessage : wrappedSendMessage . bind ( null , "sendMessage" , {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 3 ,
} ) ,
2020-01-04 20:45:00 -05:00
} ,
tabs : {
sendMessage : wrappedSendMessage . bind ( null , "sendMessage" , {
minArgs : 2 ,
2020-11-06 17:52:14 -05:00
maxArgs : 3 ,
} ) ,
} ,
2020-01-04 20:45:00 -05:00
} ;
const settingMetadata = {
clear : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
get : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
2020-01-04 20:45:00 -05:00
} ,
set : {
minArgs : 1 ,
2020-11-06 17:52:14 -05:00
maxArgs : 1 ,
} ,
2020-01-04 20:45:00 -05:00
} ;
apiMetadata . privacy = {
network : {
2020-11-06 17:52:14 -05:00
"*" : settingMetadata ,
2020-01-04 20:45:00 -05:00
} ,
services : {
2020-11-06 17:52:14 -05:00
"*" : settingMetadata ,
2020-01-04 20:45:00 -05:00
} ,
websites : {
2020-11-06 17:52:14 -05:00
"*" : settingMetadata ,
} ,
2020-01-04 20:45:00 -05:00
} ;
return wrapObject ( extensionAPIs , staticWrappers , apiMetadata ) ;
} ;
if (
typeof chrome != "object" ||
! chrome ||
! chrome . runtime ||
! chrome . runtime . id
) {
throw new Error (
"This script should only be loaded in a browser extension."
) ;
} // The build process adds a UMD wrapper around this file, which makes the
// `module` variable available.
module . exports = wrapAPIs ( chrome ) ;
} else {
module . exports = browser ;
}
}
) ;
//# sourceMappingURL=browser-polyfill.js.map