mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-10 09:07:54 +01:00
Work toward modernizing code base: promisification
Swathes of code have been converted to use Promises/async/await. Related commits: -022951547c
-3224d9b5cc
-26235d80d0
-0051f3b5c7
-eec53c0154
-915687fddb
-55cc0c6997
-e27328f931
This commit is contained in:
parent
5f60c31f77
commit
58620fb051
2 changed files with 156 additions and 310 deletions
|
@ -39,17 +39,6 @@ vAPI.cantWebsocket =
|
|||
browser.webRequest.ResourceType instanceof Object === false ||
|
||||
browser.webRequest.ResourceType.WEBSOCKET !== 'websocket';
|
||||
|
||||
vAPI.lastError = function() {
|
||||
return browser.runtime.lastError;
|
||||
};
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/875
|
||||
// https://code.google.com/p/chromium/issues/detail?id=410868#c8
|
||||
// Must not leave `lastError` unchecked.
|
||||
vAPI.resetLastError = function() {
|
||||
void browser.runtime.lastError;
|
||||
};
|
||||
|
||||
vAPI.supportsUserStylesheets = vAPI.webextFlavor.soup.has('user_stylesheet');
|
||||
// The real actual webextFlavor value may not be set in stone, so listen
|
||||
// for possible future changes.
|
||||
|
@ -58,8 +47,6 @@ window.addEventListener('webextFlavor', function() {
|
|||
vAPI.webextFlavor.soup.has('user_stylesheet');
|
||||
}, { once: true });
|
||||
|
||||
const noopFunc = function(){};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
vAPI.app = {
|
||||
|
@ -111,20 +98,14 @@ vAPI.storage = webext.storage.local;
|
|||
// https://github.com/gorhill/uMatrix/issues/234
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy/network
|
||||
|
||||
// 2015-08-12: Wrapped Chrome API in try-catch statements. I had a fluke
|
||||
// event in which it appeared Chrome 46 decided to restart uBlock (for
|
||||
// unknown reasons) and again for unknown reasons the browser acted as if
|
||||
// uBlock did not declare the `privacy` permission in its manifest, putting
|
||||
// uBlock in a bad, non-functional state -- because call to `chrome.privacy`
|
||||
// API threw an exception.
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/2048
|
||||
// Do not mess up with existing settings if not assigning them stricter
|
||||
// values.
|
||||
|
||||
vAPI.browserSettings = (( ) => {
|
||||
// Not all platforms support `browser.privacy`.
|
||||
if ( browser.privacy instanceof Object === false ) { return; }
|
||||
const bp = webext.privacy;
|
||||
if ( bp instanceof Object === false ) { return; }
|
||||
|
||||
return {
|
||||
// Whether the WebRTC-related privacy API is crashy is an open question
|
||||
|
@ -181,75 +162,42 @@ vAPI.browserSettings = (( ) => {
|
|||
// crash.
|
||||
if ( this.webRTCSupported !== true ) { return; }
|
||||
|
||||
const bp = browser.privacy;
|
||||
const bpn = bp.network;
|
||||
|
||||
// Older version of Chromium do not support this setting, and is
|
||||
// marked as "deprecated" since Chromium 48.
|
||||
if ( typeof bpn.webRTCMultipleRoutesEnabled === 'object' ) {
|
||||
try {
|
||||
if ( setting ) {
|
||||
bpn.webRTCMultipleRoutesEnabled.clear({
|
||||
scope: 'regular'
|
||||
}, vAPI.resetLastError);
|
||||
} else {
|
||||
bpn.webRTCMultipleRoutesEnabled.set({
|
||||
value: false,
|
||||
scope: 'regular'
|
||||
}, vAPI.resetLastError);
|
||||
}
|
||||
} catch(ex) {
|
||||
console.error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
// This setting became available in Chromium 48.
|
||||
if ( typeof bpn.webRTCIPHandlingPolicy === 'object' ) {
|
||||
try {
|
||||
if ( setting ) {
|
||||
bpn.webRTCIPHandlingPolicy.clear({
|
||||
scope: 'regular'
|
||||
}, vAPI.resetLastError);
|
||||
} else {
|
||||
// https://github.com/uBlockOrigin/uAssets/issues/333#issuecomment-289426678
|
||||
// Leverage virtuous side-effect of strictest setting.
|
||||
// https://github.com/gorhill/uBlock/issues/3009
|
||||
// Firefox currently works differently, use
|
||||
// `default_public_interface_only` for now.
|
||||
bpn.webRTCIPHandlingPolicy.set({
|
||||
value: vAPI.webextFlavor.soup.has('chromium')
|
||||
? 'disable_non_proxied_udp'
|
||||
: 'default_public_interface_only',
|
||||
scope: 'regular'
|
||||
}, vAPI.resetLastError);
|
||||
}
|
||||
} catch(ex) {
|
||||
console.error(ex);
|
||||
}
|
||||
if ( setting ) {
|
||||
bpn.webRTCIPHandlingPolicy.clear({
|
||||
scope: 'regular',
|
||||
});
|
||||
} else {
|
||||
// https://github.com/uBlockOrigin/uAssets/issues/333#issuecomment-289426678
|
||||
// Leverage virtuous side-effect of strictest setting.
|
||||
// https://github.com/gorhill/uBlock/issues/3009
|
||||
// Firefox currently works differently, use
|
||||
// `default_public_interface_only` for now.
|
||||
bpn.webRTCIPHandlingPolicy.set({
|
||||
value: vAPI.webextFlavor.soup.has('chromium')
|
||||
? 'disable_non_proxied_udp'
|
||||
: 'default_public_interface_only',
|
||||
scope: 'regular',
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
set: function(details) {
|
||||
for ( const setting in details ) {
|
||||
if ( details.hasOwnProperty(setting) === false ) {
|
||||
continue;
|
||||
}
|
||||
if ( details.hasOwnProperty(setting) === false ) { continue; }
|
||||
switch ( setting ) {
|
||||
case 'prefetching':
|
||||
const enabled = !!details[setting];
|
||||
try {
|
||||
if ( enabled ) {
|
||||
browser.privacy.network.networkPredictionEnabled.clear({
|
||||
scope: 'regular'
|
||||
}, vAPI.resetLastError);
|
||||
} else {
|
||||
browser.privacy.network.networkPredictionEnabled.set({
|
||||
value: false,
|
||||
scope: 'regular'
|
||||
}, vAPI.resetLastError);
|
||||
}
|
||||
} catch(ex) {
|
||||
console.error(ex);
|
||||
if ( enabled ) {
|
||||
bp.network.networkPredictionEnabled.clear({
|
||||
scope: 'regular',
|
||||
});
|
||||
} else {
|
||||
bp.network.networkPredictionEnabled.set({
|
||||
value: false,
|
||||
scope: 'regular',
|
||||
});
|
||||
}
|
||||
if ( vAPI.prefetching instanceof Function ) {
|
||||
vAPI.prefetching(enabled);
|
||||
|
@ -257,19 +205,15 @@ vAPI.browserSettings = (( ) => {
|
|||
break;
|
||||
|
||||
case 'hyperlinkAuditing':
|
||||
try {
|
||||
if ( !!details[setting] ) {
|
||||
browser.privacy.websites.hyperlinkAuditingEnabled.clear({
|
||||
scope: 'regular'
|
||||
}, vAPI.resetLastError);
|
||||
} else {
|
||||
browser.privacy.websites.hyperlinkAuditingEnabled.set({
|
||||
value: false,
|
||||
scope: 'regular'
|
||||
}, vAPI.resetLastError);
|
||||
}
|
||||
} catch(ex) {
|
||||
console.error(ex);
|
||||
if ( !!details[setting] ) {
|
||||
bp.websites.hyperlinkAuditingEnabled.clear({
|
||||
scope: 'regular',
|
||||
});
|
||||
} else {
|
||||
bp.websites.hyperlinkAuditingEnabled.set({
|
||||
value: false,
|
||||
scope: 'regular',
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -595,21 +539,27 @@ vAPI.Tabs = class {
|
|||
vAPI.tabs.update(tabId, { url: targetURL });
|
||||
}
|
||||
|
||||
remove(tabId) {
|
||||
async remove(tabId) {
|
||||
tabId = toTabId(tabId);
|
||||
if ( tabId === 0 ) { return; }
|
||||
browser.tabs.remove(tabId, vAPI.resetLastError);
|
||||
try {
|
||||
await webext.tabs.remove(tabId);
|
||||
}
|
||||
catch (reason) {
|
||||
}
|
||||
}
|
||||
|
||||
reload(tabId, bypassCache = false) {
|
||||
async reload(tabId, bypassCache = false) {
|
||||
tabId = toTabId(tabId);
|
||||
if ( tabId === 0 ) { return; }
|
||||
|
||||
browser.tabs.reload(
|
||||
tabId,
|
||||
{ bypassCache: bypassCache === true },
|
||||
vAPI.resetLastError
|
||||
);
|
||||
try {
|
||||
await webext.tabs.reload(
|
||||
tabId,
|
||||
{ bypassCache: bypassCache === true }
|
||||
);
|
||||
}
|
||||
catch (reason) {
|
||||
}
|
||||
}
|
||||
|
||||
async select(tabId) {
|
||||
|
@ -861,7 +811,7 @@ vAPI.messaging = {
|
|||
listeners: new Map(),
|
||||
defaultHandler: null,
|
||||
PRIVILEGED_URL: vAPI.getURL(''),
|
||||
NOOPFUNC: noopFunc,
|
||||
NOOPFUNC: function(){},
|
||||
UNHANDLED: 'vAPI.messaging.notHandled',
|
||||
|
||||
listen: function(details) {
|
||||
|
@ -1256,10 +1206,7 @@ vAPI.contextMenu = browser.contextMenus && {
|
|||
_callback: null,
|
||||
_entries: [],
|
||||
_createEntry: function(entry) {
|
||||
browser.contextMenus.create(
|
||||
JSON.parse(JSON.stringify(entry)),
|
||||
vAPI.resetLastError
|
||||
);
|
||||
webext.menus.create(JSON.parse(JSON.stringify(entry)));
|
||||
},
|
||||
onMustUpdate: function() {},
|
||||
setEntries: function(entries, callback) {
|
||||
|
@ -1270,12 +1217,12 @@ vAPI.contextMenu = browser.contextMenus && {
|
|||
const newEntry = entries[i];
|
||||
if ( oldEntryId && newEntry ) {
|
||||
if ( newEntry.id !== oldEntryId ) {
|
||||
browser.contextMenus.remove(oldEntryId);
|
||||
webext.menus.remove(oldEntryId);
|
||||
this._createEntry(newEntry);
|
||||
this._entries[i] = newEntry.id;
|
||||
}
|
||||
} else if ( oldEntryId && !newEntry ) {
|
||||
browser.contextMenus.remove(oldEntryId);
|
||||
webext.menus.remove(oldEntryId);
|
||||
} else if ( !oldEntryId && newEntry ) {
|
||||
this._createEntry(newEntry);
|
||||
this._entries[i] = newEntry.id;
|
||||
|
@ -1287,10 +1234,10 @@ vAPI.contextMenu = browser.contextMenus && {
|
|||
return;
|
||||
}
|
||||
if ( n !== 0 && callback !== null ) {
|
||||
browser.contextMenus.onClicked.addListener(callback);
|
||||
webext.menus.onClicked.addListener(callback);
|
||||
this._callback = callback;
|
||||
} else if ( n === 0 && this._callback !== null ) {
|
||||
browser.contextMenus.onClicked.removeListener(this._callback);
|
||||
webext.menus.onClicked.removeListener(this._callback);
|
||||
this._callback = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,140 +24,108 @@
|
|||
// `webext` is a promisified api of `chrome`. Entries are added as
|
||||
// the promisification of uBO progress.
|
||||
|
||||
const webext = { // jshint ignore:line
|
||||
const webext = (( ) => { // jshint ignore:line
|
||||
// >>>>> start of private scope
|
||||
|
||||
const promisifyNoFail = function(thisArg, fnName, outFn = r => r) {
|
||||
const fn = thisArg[fnName];
|
||||
return function() {
|
||||
return new Promise(resolve => {
|
||||
fn.call(thisArg, ...arguments, function() {
|
||||
void chrome.runtime.lastError;
|
||||
resolve(outFn(...arguments));
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
const promisify = function(thisArg, fnName) {
|
||||
const fn = thisArg[fnName];
|
||||
return function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
fn.call(thisArg, ...arguments, function() {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve(...arguments);
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
const webext = {
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus
|
||||
menus: {
|
||||
create: function() {
|
||||
return chrome.contextMenus.create(...arguments, ( ) => {
|
||||
void chrome.runtime.lastError;
|
||||
});
|
||||
},
|
||||
onClicked: chrome.contextMenus.onClicked,
|
||||
remove: promisifyNoFail(chrome.contextMenus, 'remove'),
|
||||
},
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy
|
||||
privacy: {
|
||||
},
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage
|
||||
storage: {
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/local
|
||||
local: {
|
||||
clear: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.local.clear(( ) => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
get: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.local.get(...arguments, result => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
},
|
||||
getBytesInUse: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.local.getBytesInUse(...arguments, result => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
},
|
||||
remove: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.local.remove(...arguments, ( ) => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
set: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.local.set(...arguments, ( ) => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
clear: promisify(chrome.storage.local, 'clear'),
|
||||
get: promisify(chrome.storage.local, 'get'),
|
||||
getBytesInUse: promisify(chrome.storage.local, 'getBytesInUse'),
|
||||
remove: promisify(chrome.storage.local, 'remove'),
|
||||
set: promisify(chrome.storage.local, 'set'),
|
||||
},
|
||||
},
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs
|
||||
tabs: {
|
||||
get: function() {
|
||||
return new Promise(resolve => {
|
||||
chrome.tabs.get(...arguments, tab => {
|
||||
void chrome.runtime.lastError;
|
||||
resolve(tab instanceof Object ? tab : null);
|
||||
});
|
||||
});
|
||||
},
|
||||
executeScript: function() {
|
||||
return new Promise(resolve => {
|
||||
chrome.tabs.executeScript(...arguments, result => {
|
||||
void chrome.runtime.lastError;
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
},
|
||||
insertCSS: function() {
|
||||
return new Promise(resolve => {
|
||||
chrome.tabs.insertCSS(...arguments, ( ) => {
|
||||
void chrome.runtime.lastError;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
query: function() {
|
||||
return new Promise(resolve => {
|
||||
chrome.tabs.query(...arguments, tabs => {
|
||||
void chrome.runtime.lastError;
|
||||
resolve(Array.isArray(tabs) ? tabs : []);
|
||||
});
|
||||
});
|
||||
},
|
||||
update: function() {
|
||||
return new Promise(resolve => {
|
||||
chrome.tabs.update(...arguments, tab => {
|
||||
void chrome.runtime.lastError;
|
||||
resolve(tab instanceof Object ? tab : null);
|
||||
});
|
||||
});
|
||||
},
|
||||
get: promisifyNoFail(chrome.tabs, 'get', tab => tab instanceof Object ? tab : null),
|
||||
executeScript: promisifyNoFail(chrome.tabs, 'executeScript'),
|
||||
insertCSS: promisifyNoFail(chrome.tabs, 'insertCSS'),
|
||||
query: promisifyNoFail(chrome.tabs, 'query', tabs => Array.isArray(tabs) ? tabs : []),
|
||||
reload: promisifyNoFail(chrome.tabs, 'reload'),
|
||||
remove: promisifyNoFail(chrome.tabs, 'remove'),
|
||||
update: promisifyNoFail(chrome.tabs, 'update', tab => tab instanceof Object ? tab : null),
|
||||
},
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows
|
||||
windows: {
|
||||
get: function() {
|
||||
return new Promise(resolve => {
|
||||
chrome.windows.get(...arguments, win => {
|
||||
void chrome.runtime.lastError;
|
||||
resolve(win instanceof Object ? win : null);
|
||||
});
|
||||
});
|
||||
},
|
||||
create: function() {
|
||||
return new Promise(resolve => {
|
||||
chrome.windows.create(...arguments, win => {
|
||||
void chrome.runtime.lastError;
|
||||
resolve(win instanceof Object ? win : null);
|
||||
});
|
||||
});
|
||||
},
|
||||
update: function() {
|
||||
return new Promise(resolve => {
|
||||
chrome.windows.update(...arguments, win => {
|
||||
void chrome.runtime.lastError;
|
||||
resolve(win instanceof Object ? win : null);
|
||||
});
|
||||
});
|
||||
},
|
||||
get: promisifyNoFail(chrome.windows, 'get', win => win instanceof Object ? win : null),
|
||||
create: promisifyNoFail(chrome.windows, 'create', win => win instanceof Object ? win : null),
|
||||
update: promisifyNoFail(chrome.windows, 'update', win => win instanceof Object ? win : null),
|
||||
},
|
||||
};
|
||||
|
||||
// browser.privacy entries
|
||||
{
|
||||
const settings = [
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy/network
|
||||
[ 'network', 'networkPredictionEnabled' ],
|
||||
[ 'network', 'webRTCIPHandlingPolicy' ],
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy/websites
|
||||
[ 'websites', 'hyperlinkAuditingEnabled' ],
|
||||
];
|
||||
for ( const [ category, setting ] of settings ) {
|
||||
let categoryEntry = webext.privacy[category];
|
||||
if ( categoryEntry instanceof Object === false ) {
|
||||
categoryEntry = webext.privacy[category] = {};
|
||||
}
|
||||
const settingEntry = categoryEntry[setting] = {};
|
||||
const thisArg = chrome.privacy[category][setting];
|
||||
settingEntry.clear = promisifyNoFail(thisArg, 'clear');
|
||||
settingEntry.get = promisifyNoFail(thisArg, 'get');
|
||||
settingEntry.set = promisifyNoFail(thisArg, 'set');
|
||||
}
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/managed
|
||||
if ( chrome.storage.managed instanceof Object ) {
|
||||
webext.storage.managed = {
|
||||
get: promisify(chrome.storage.managed, 'get'),
|
||||
};
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/sync
|
||||
if ( chrome.storage.sync instanceof Object ) {
|
||||
webext.storage.sync = {
|
||||
|
@ -167,89 +135,20 @@ if ( chrome.storage.sync instanceof Object ) {
|
|||
MAX_WRITE_OPERATIONS_PER_HOUR: chrome.storage.sync.MAX_WRITE_OPERATIONS_PER_HOUR,
|
||||
MAX_WRITE_OPERATIONS_PER_MINUTE: chrome.storage.sync.MAX_WRITE_OPERATIONS_PER_MINUTE,
|
||||
|
||||
clear: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.sync.clear(( ) => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
get: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.sync.get(...arguments, result => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
},
|
||||
getBytesInUse: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.sync.getBytesInUse(...arguments, result => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
},
|
||||
remove: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.sync.remove(...arguments, ( ) => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
set: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.sync.set(...arguments, ( ) => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
clear: promisify(chrome.storage.sync, 'clear'),
|
||||
get: promisify(chrome.storage.sync, 'get'),
|
||||
getBytesInUse: promisify(chrome.storage.sync, 'getBytesInUse'),
|
||||
remove: promisify(chrome.storage.sync, 'remove'),
|
||||
set: promisify(chrome.storage.sync, 'set'),
|
||||
};
|
||||
}
|
||||
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=608854
|
||||
if ( chrome.tabs.removeCSS instanceof Function ) {
|
||||
webext.tabs.removeCSS = function() {
|
||||
return new Promise(resolve => {
|
||||
chrome.tabs.removeCSS(...arguments, ( ) => {
|
||||
void chrome.runtime.lastError;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
webext.tabs.removeCSS = promisifyNoFail(chrome.tabs, 'removeCSS');
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/managed
|
||||
if ( chrome.storage.managed instanceof Object ) {
|
||||
webext.storage.managed = {
|
||||
get: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.storage.local.get(...arguments, result => {
|
||||
const lastError = chrome.runtime.lastError;
|
||||
if ( lastError instanceof Object ) {
|
||||
return reject(lastError.message);
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
return webext;
|
||||
|
||||
// <<<<< end of private scope
|
||||
})();
|
||||
|
|
Loading…
Reference in a new issue