From 54b1f218e0fae4bad335ad64e26bacaa933d0f87 Mon Sep 17 00:00:00 2001 From: tophf Date: Fri, 14 Aug 2020 15:16:01 +0300 Subject: [PATCH] Enhance: promisify `chrome` into `browser`, drop `promisify` (#866) * promisify `chrome` into `browser` * comment * comment * comment * Add: a naive browser polyfill * Fix: polyfill doesn't detect content script env correctly Co-authored-by: eight04 --- background/background.js | 4 +- background/content-scripts.js | 4 +- background/db-chrome-storage.js | 49 ++++++++---------------- background/navigator-util.js | 5 +-- background/token-manager.js | 8 ++-- background/usercss-helper.js | 7 ++-- edit.html | 1 - edit/edit.js | 4 +- edit/global-search.js | 18 ++++----- edit/regexp-tester.js | 4 +- install-usercss.html | 1 - install-usercss/install-usercss.js | 10 ++--- js/messaging.js | 41 +++++++------------- js/msg.js | 24 ++++++------ js/polyfill.js | 60 ++++++++++++++++++++++++++++-- js/prefs.js | 11 +++--- js/promisify.js | 22 ----------- js/storage-util.js | 15 +++++--- manage.html | 1 - manifest.json | 2 - options.html | 1 - popup.html | 1 - popup/search-results.js | 22 ++++------- 23 files changed, 153 insertions(+), 162 deletions(-) delete mode 100644 js/promisify.js diff --git a/background/background.js b/background/background.js index 6d6ea071..77034880 100644 --- a/background/background.js +++ b/background/background.js @@ -1,7 +1,7 @@ /* global download prefs openURL FIREFOX CHROME URLS ignoreChromeError usercssHelper styleManager msg navigatorUtil workerUtil contentScripts sync - findExistingTab createTab activateTab isTabReplaceable getActiveTab + findExistingTab activateTab isTabReplaceable getActiveTab tabManager */ 'use strict'; @@ -336,7 +336,7 @@ function openManage({options = false, search} = {}) { if (isTabReplaceable(tab, url)) { return activateTab(tab, {url}); } - return createTab({url}); + return browser.tabs.create({url}); }); }); } diff --git a/background/content-scripts.js b/background/content-scripts.js index 4be73294..dfd744f2 100644 --- a/background/content-scripts.js +++ b/background/content-scripts.js @@ -1,4 +1,4 @@ -/* global msg queryTabs ignoreChromeError URLS */ +/* global msg ignoreChromeError URLS */ /* exported contentScripts */ 'use strict'; @@ -55,7 +55,7 @@ const contentScripts = (() => { } function injectToAllTabs() { - return queryTabs({}).then(tabs => { + return browser.tabs.query({}).then(tabs => { for (const tab of tabs) { // skip unloaded/discarded/chrome tabs if (!tab.width || tab.discarded || !URLS.supported(tab.url)) continue; diff --git a/background/db-chrome-storage.js b/background/db-chrome-storage.js index 46cfadb1..01e38262 100644 --- a/background/db-chrome-storage.js +++ b/background/db-chrome-storage.js @@ -1,46 +1,29 @@ -/* global promisify */ +/* global chromeLocal */ /* exported createChromeStorageDB */ 'use strict'; function createChromeStorageDB() { - const get = promisify(chrome.storage.local.get.bind(chrome.storage.local)); - const set = promisify(chrome.storage.local.set.bind(chrome.storage.local)); - const remove = promisify(chrome.storage.local.remove.bind(chrome.storage.local)); - let INC; const PREFIX = 'style-'; const METHODS = { // FIXME: we don't use this method at all. Should we remove this? - get: id => get(PREFIX + id) - .then(result => result[PREFIX + id]), - put: obj => Promise.resolve() - .then(() => { - if (!obj.id) { - return prepareInc() - .then(() => { - // FIXME: should we clone the object? - obj.id = INC++; - }); - } - }) - .then(() => set({[PREFIX + obj.id]: obj})) - .then(() => obj.id), + get: id => chromeLocal.getValue(PREFIX + id), + put: obj => + // FIXME: should we clone the object? + Promise.resolve(!obj.id && prepareInc().then(() => Object.assign(obj, {id: INC++}))) + .then(() => chromeLocal.setValue(PREFIX + obj.id, obj)) + .then(() => obj.id), putMany: items => prepareInc() - .then(() => { - for (const item of items) { - if (!item.id) { - item.id = INC++; - } - } - return set(items.reduce((obj, curr) => { - obj[PREFIX + curr.id] = curr; - return obj; - }, {})); - }) + .then(() => + chromeLocal.set(items.reduce((data, item) => { + if (!item.id) item.id = INC++; + data[PREFIX + item.id] = item; + return data; + }, {}))) .then(() => items.map(i => i.id)), - delete: id => remove(PREFIX + id), - getAll: () => get(null) + delete: id => chromeLocal.remove(PREFIX + id), + getAll: () => chromeLocal.get() .then(result => { const output = []; for (const key in result) { @@ -69,7 +52,7 @@ function createChromeStorageDB() { function prepareInc() { if (INC) return Promise.resolve(); - return get(null).then(result => { + return chromeLocal.get().then(result => { INC = 1; for (const key in result) { if (key.startsWith(PREFIX)) { diff --git a/background/navigator-util.js b/background/navigator-util.js index ab08dffa..67fdc1e7 100644 --- a/background/navigator-util.js +++ b/background/navigator-util.js @@ -1,4 +1,4 @@ -/* global promisify CHROME URLS */ +/* global CHROME URLS */ /* exported navigatorUtil */ 'use strict'; @@ -6,7 +6,6 @@ const navigatorUtil = (() => { const handler = { urlChange: null }; - const tabGet = promisify(chrome.tabs.get.bind(chrome.tabs)); return extendNative({onUrlChange}); function onUrlChange(fn) { @@ -48,7 +47,7 @@ const navigatorUtil = (() => { ) { return Promise.resolve(); } - return tabGet(data.tabId) + return browser.tabs.get(data.tabId) .then(tab => { if (tab.url === 'chrome://newtab/') { data.url = tab.url; diff --git a/background/token-manager.js b/background/token-manager.js index 0b0fd3e0..8be21874 100644 --- a/background/token-manager.js +++ b/background/token-manager.js @@ -1,9 +1,11 @@ -/* global chromeLocal promisify FIREFOX */ +/* global chromeLocal promisifyChrome FIREFOX */ /* exported tokenManager */ 'use strict'; const tokenManager = (() => { - const launchWebAuthFlow = promisify(chrome.identity.launchWebAuthFlow.bind(chrome.identity)); + promisifyChrome({ + identity: ['launchWebAuthFlow'], + }); const AUTH = { dropbox: { flow: 'token', @@ -158,7 +160,7 @@ const tokenManager = (() => { Object.assign(query, provider.authQuery); } const url = `${provider.authURL}?${stringifyQuery(query)}`; - return launchWebAuthFlow({ + return browser.identity.launchWebAuthFlow({ url, interactive }) diff --git a/background/usercss-helper.js b/background/usercss-helper.js index ea083ae9..3f6081f6 100644 --- a/background/usercss-helper.js +++ b/background/usercss-helper.js @@ -1,8 +1,7 @@ -/* global API_METHODS usercss styleManager deepCopy openURL download URLS getTab */ -/* exports usercssHelper */ +/* global API_METHODS usercss styleManager deepCopy openURL download URLS */ +/* exported usercssHelper */ 'use strict'; -// eslint-disable-next-line no-unused-vars const usercssHelper = (() => { const installCodeCache = {}; const clearInstallCode = url => delete installCodeCache[url]; @@ -46,7 +45,7 @@ const usercssHelper = (() => { openInstallerPage(tabId, url, {code, inTab} = {}) { const newUrl = `${URLS.installUsercss}?updateUrl=${encodeURIComponent(url)}`; if (inTab) { - getTab(tabId).then(tab => + browser.tabs.get(tabId).then(tab => openURL({ url: `${newUrl}&tabId=${tabId}`, active: tab.active, diff --git a/edit.html b/edit.html index 72a2c45c..12614c99 100644 --- a/edit.html +++ b/edit.html @@ -64,7 +64,6 @@ - diff --git a/edit/edit.js b/edit/edit.js index 4c5d098d..7d3b49d4 100644 --- a/edit/edit.js +++ b/edit/edit.js @@ -1,5 +1,5 @@ /* global CodeMirror onDOMready prefs setupLivePrefs $ $$ $create t tHTML - createSourceEditor queryTabs sessionStorageHash getOwnTab FIREFOX API tryCatch + createSourceEditor sessionStorageHash getOwnTab FIREFOX API tryCatch closeCurrentTab messageBox debounce workerUtil initBeautifyButton ignoreChromeError moveFocus msg createSectionsEditor rerouteHotkeys CODEMIRROR_THEMES */ @@ -226,7 +226,7 @@ function preinit() { }).observe(document, {subtree: true, childList: true}); if (chrome.windows) { - queryTabs({currentWindow: true}).then(tabs => { + browser.tabs.query({currentWindow: true}).then(tabs => { const windowId = tabs[0].windowId; if (prefs.get('openEditInWindow')) { if ( diff --git a/edit/global-search.js b/edit/global-search.js index 349b8ac1..ad46a4cc 100644 --- a/edit/global-search.js +++ b/edit/global-search.js @@ -1,4 +1,4 @@ -/* global CodeMirror focusAccessibility colorMimicry editor +/* global CodeMirror focusAccessibility colorMimicry editor chromeLocal onDOMready $ $$ $create t debounce tryRegExp stringAsRegExp template */ 'use strict'; @@ -915,7 +915,7 @@ onDOMready().then(() => { function readStorage() { - chrome.storage.local.get('editor', ({editor = {}}) => { + chromeLocal.getValue('editor').then((editor = {}) => { state.find = editor.find || ''; state.replace = editor.replace || ''; state.icase = editor.icase || state.icase; @@ -924,14 +924,12 @@ onDOMready().then(() => { function writeStorage() { - chrome.storage.local.get('editor', ({editor}) => - chrome.storage.local.set({ - editor: Object.assign(editor || {}, { - find: state.find, - replace: state.replace, - icase: state.icase, - }) - })); + chromeLocal.getValue('editor').then((editor = {}) => + chromeLocal.setValue('editor', Object.assign(editor, { + find: state.find, + replace: state.replace, + icase: state.icase, + }))); } diff --git a/edit/regexp-tester.js b/edit/regexp-tester.js index 590714d3..8f001102 100644 --- a/edit/regexp-tester.js +++ b/edit/regexp-tester.js @@ -1,4 +1,4 @@ -/* global showHelp $ $create tryRegExp queryTabs URLS t template openURL */ +/* global showHelp $ $create tryRegExp URLS t template openURL */ /* exported regExpTester */ 'use strict'; @@ -66,7 +66,7 @@ const regExpTester = (() => { return rxData; }); const getMatchInfo = m => m && {text: m[0], pos: m.index}; - queryTabs({}).then(tabs => { + browser.tabs.query({}).then(tabs => { const supported = tabs.map(tab => tab.url) .filter(url => URLS.supported(url)); const unique = [...new Set(supported).values()]; diff --git a/install-usercss.html b/install-usercss.html index d168a346..9083ad31 100644 --- a/install-usercss.html +++ b/install-usercss.html @@ -10,7 +10,6 @@ - diff --git a/install-usercss/install-usercss.js b/install-usercss/install-usercss.js index c4417571..82bb8b73 100644 --- a/install-usercss/install-usercss.js +++ b/install-usercss/install-usercss.js @@ -394,13 +394,9 @@ } }); port.onDisconnect.addListener(() => { - chrome.tabs.get(tabId, tab => { - if (chrome.runtime.lastError) { - closeCurrentTab(); - } else if (tab.url === initialUrl) { - location.reload(); - } - }); + browser.tabs.get(tabId) + .then(tab => tab.url === initialUrl && location.reload()) + .catch(closeCurrentTab); }); return ({timer = true} = {}) => new Promise((resolve, reject) => { const id = performance.now(); diff --git a/js/messaging.js b/js/messaging.js index 82f009a5..642b20dc 100644 --- a/js/messaging.js +++ b/js/messaging.js @@ -1,7 +1,7 @@ /* exported getTab getActiveTab onTabReady stringAsRegExp openURL ignoreChromeError getStyleWithNoCode tryRegExp sessionStorageHash download deepEqual closeCurrentTab capitalize CHROME_HAS_BORDER_BUG */ -/* global promisify */ +/* global promisifyChrome */ 'use strict'; const CHROME = Boolean(chrome.app) && parseInt(navigator.userAgent.match(/Chrom\w+\/(\d+)|$/)[1]); @@ -93,33 +93,20 @@ if (IS_BG) { // Object.defineProperty(window, 'localStorage', {value: {}}); // Object.defineProperty(window, 'sessionStorage', {value: {}}); -const createTab = promisify(chrome.tabs.create.bind(chrome.tabs)); -const queryTabs = promisify(chrome.tabs.query.bind(chrome.tabs)); -const updateTab = promisify(chrome.tabs.update.bind(chrome.tabs)); -const moveTabs = promisify(chrome.tabs.move.bind(chrome.tabs)); - -// Android doesn't have chrome.windows -const updateWindow = chrome.windows && promisify(chrome.windows.update.bind(chrome.windows)); -const createWindow = chrome.windows && promisify(chrome.windows.create.bind(chrome.windows)); +promisifyChrome({ + tabs: ['create', 'get', 'getCurrent', 'move', 'query', 'update'], + windows: ['create', 'update'], // Android doesn't have chrome.windows +}); // FF57+ supports openerTabId, but not in Android // (detecting FF57 by the feature it added, not navigator.ua which may be spoofed in about:config) const openerTabIdSupported = (!FIREFOX || window.AbortController) && chrome.windows != null; -function getTab(id) { - return new Promise(resolve => - chrome.tabs.get(id, tab => - !chrome.runtime.lastError && resolve(tab))); -} - - function getOwnTab() { - return new Promise(resolve => - chrome.tabs.getCurrent(tab => resolve(tab))); + return browser.tabs.getCurrent(); } - function getActiveTab() { - return queryTabs({currentWindow: true, active: true}) + return browser.tabs.query({currentWindow: true, active: true}) .then(tabs => tabs[0]); } @@ -140,7 +127,7 @@ function urlToMatchPattern(url, ignoreSearch) { function findExistingTab({url, currentWindow, ignoreHash = true, ignoreSearch = false}) { url = new URL(url); - return queryTabs({url: urlToMatchPattern(url, ignoreSearch), currentWindow}) + return browser.tabs.query({url: urlToMatchPattern(url, ignoreSearch), currentWindow}) // FIXME: is tab.url always normalized? .then(tabs => tabs.find(matchTab)); @@ -191,8 +178,8 @@ function openURL({ url: url !== tab.url && url.includes('#') ? url : undefined, }); } - if (newWindow && createWindow) { - return createWindow(Object.assign({url}, windowPosition)) + if (newWindow && browser.windows) { + return browser.windows.create(Object.assign({url}, windowPosition)) .then(wnd => wnd.tabs[0]); } return getActiveTab().then((activeTab = {url: ''}) => @@ -205,7 +192,7 @@ function openURL({ if (id != null && !openerTab.incognito && openerTabIdSupported) { options.openerTabId = id; } - return createTab(options); + return browser.tabs.create(options); } } @@ -232,9 +219,9 @@ function activateTab(tab, {url, index, openerTabId} = {}) { options.openerTabId = openerTabId; } return Promise.all([ - updateTab(tab.id, options), - updateWindow && updateWindow(tab.windowId, {focused: true}), - index != null && moveTabs(tab.id, {index}) + browser.tabs.update(tab.id, options), + browser.windows && browser.windows.update(tab.windowId, {focused: true}), + index != null && browser.tabs.move(tab.id, {index}) ]) .then(() => tab); } diff --git a/js/msg.js b/js/msg.js index f7e6bafd..d52438e4 100644 --- a/js/msg.js +++ b/js/msg.js @@ -1,12 +1,12 @@ -/* global promisify deepCopy */ +/* global promisifyChrome deepCopy */ // deepCopy is only used if the script is executed in extension pages. 'use strict'; self.msg = self.INJECTED === 1 ? self.msg : (() => { - const runtimeSend = promisify(chrome.runtime.sendMessage.bind(chrome.runtime)); - const tabSend = chrome.tabs && promisify(chrome.tabs.sendMessage.bind(chrome.tabs)); - const tabQuery = chrome.tabs && promisify(chrome.tabs.query.bind(chrome.tabs)); - + promisifyChrome({ + runtime: ['sendMessage'], + tabs: ['sendMessage', 'query'], + }); const isBg = chrome.extension.getBackgroundPage && chrome.extension.getBackgroundPage() === window; if (isBg) { window._msg = { @@ -49,19 +49,21 @@ self.msg = self.INJECTED === 1 ? self.msg : (() => { } } if (chrome.runtime.getBackgroundPage) { - return promisify(chrome.runtime.getBackgroundPage.bind(chrome.runtime))() - .catch(() => null); + promisifyChrome({ + runtime: ['getBackgroundPage'], + }); + return browser.runtime.getBackgroundPage().catch(() => null); } return Promise.resolve(null); } function send(data, target = 'extension') { const message = {data, target}; - return runtimeSend(message).then(unwrapData); + return browser.runtime.sendMessage(message).then(unwrapData); } function sendTab(tabId, data, options, target = 'tab') { - return tabSend(tabId, {data, target}, options) + return browser.tabs.sendMessage(tabId, {data, target}, options) .then(unwrapData); } @@ -99,7 +101,7 @@ self.msg = self.INJECTED === 1 ? self.msg : (() => { } function broadcastTab(data, filter, options, ignoreExtension = false, target = 'tab') { - return tabQuery({}) + return browser.tabs.query({}) // TODO: send to activated tabs first? .then(tabs => { const requests = []; @@ -123,7 +125,7 @@ self.msg = self.INJECTED === 1 ? self.msg : (() => { const message = {data: dataObj, target}; if (tab && tab.id) { requests.push( - tabSend(tab.id, message, options) + browser.tabs.sendMessage(tab.id, message, options) .then(unwrapData) .catch(ignoreError) ); diff --git a/js/polyfill.js b/js/polyfill.js index 2b95b10d..3b22c96d 100644 --- a/js/polyfill.js +++ b/js/polyfill.js @@ -3,6 +3,8 @@ // eslint-disable-next-line no-unused-expressions self.INJECTED !== 1 && (() => { + // this part runs in workers, content scripts, our extension pages + if (!Object.entries) { Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]]); } @@ -10,9 +12,38 @@ self.INJECTED !== 1 && (() => { Object.values = obj => Object.keys(obj).map(k => obj[k]); } - // the above was shared by content scripts and workers, - // the rest is only needed for our extension pages - if (!self.chrome || !self.chrome.tabs) return; + // don't use self.chrome. It is undefined in Firefox + if (typeof chrome !== 'object') return; + // the rest is for content scripts and our extension pages + + self.browser = polyfillBrowser(); + + /* Promisifies the specified `chrome` methods into `browser`. + The definitions is an object like this: { + 'storage.sync': ['get', 'set'], // if deeper than one level, combine the path via `.` + windows: ['create', 'update'], // items and sub-objects will only be created if present in `chrome` + } */ + self.promisifyChrome = definitions => { + for (const [scopeName, methods] of Object.entries(definitions)) { + const path = scopeName.split('.'); + const src = path.reduce((obj, p) => obj && obj[p], chrome); + if (!src) continue; + const dst = path.reduce((obj, p) => obj[p] || (obj[p] = {}), browser); + for (const name of methods) { + const fn = src[name]; + if (!fn || dst[name] && !dst[name].isTrap) continue; + dst[name] = (...args) => new Promise((resolve, reject) => + fn.call(src, ...args, (...results) => + chrome.runtime.lastError ? + reject(chrome.runtime.lastError) : + resolve(results.length <= 1 ? results[0] : results))); + // a couple of callbacks have 2 parameters (we don't use those methods, but just in case) + } + } + }; + + if (!chrome.tabs) return; + // the rest is for our extension pages if (typeof document === 'object') { const ELEMENT_METH = { @@ -75,4 +106,27 @@ self.INJECTED !== 1 && (() => { } catch (err) { Object.defineProperty(self, 'sessionStorage', {value: {}}); } + + function polyfillBrowser() { + if (typeof browser === 'object' && browser.runtime) { + return browser; + } + return createTrap(chrome, null); + + function createTrap(base, parent) { + const target = typeof base === 'function' ? () => {} : {}; + target.isTrap = true; + return new Proxy(target, { + get: (target, prop) => { + if (target[prop]) return target[prop]; + if (base[prop] && (typeof base[prop] === 'object' || typeof base[prop] === 'function')) { + target[prop] = createTrap(base[prop], base); + return target[prop]; + } + return base[prop]; + }, + apply: (target, thisArg, args) => base.apply(parent, args) + }); + } + } })(); diff --git a/js/prefs.js b/js/prefs.js index de4aed43..52e2ad7a 100644 --- a/js/prefs.js +++ b/js/prefs.js @@ -1,4 +1,4 @@ -/* global promisify */ +/* global promisifyChrome */ 'use strict'; self.prefs = self.INJECTED === 1 ? self.prefs : (() => { @@ -107,10 +107,11 @@ self.prefs = self.INJECTED === 1 ? self.prefs : (() => { specific: new Map(), }; - const syncSet = promisify(chrome.storage.sync.set.bind(chrome.storage.sync)); - const syncGet = promisify(chrome.storage.sync.get.bind(chrome.storage.sync)); + promisifyChrome({ + 'storage.sync': ['get', 'set'], + }); - const initializing = syncGet('settings') + const initializing = browser.storage.sync.get('settings') .then(result => { if (result.settings) { setAll(result.settings, true); @@ -237,7 +238,7 @@ self.prefs = self.INJECTED === 1 ? self.prefs : (() => { return new Promise((resolve, reject) => { setTimeout(() => { timer = null; - syncSet({settings: values}) + browser.storage.sync.set({settings: values}) .then(resolve, reject); }); }); diff --git a/js/promisify.js b/js/promisify.js deleted file mode 100644 index 89605a37..00000000 --- a/js/promisify.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; -/* -Convert chrome APIs into promises. Example: - - const storageSyncGet = promisify(chrome.storage.sync.get.bind(chrome.storage.sync)); - storageSyncGet(['key']).then(result => {...}); - -*/ -self.promisify = self.INJECTED === 1 ? self.promisify : fn => - (...args) => - new Promise((resolve, reject) => { - fn(...args, (...result) => { - if (chrome.runtime.lastError) { - reject(chrome.runtime.lastError); - return; - } - resolve( - result.length === 0 ? undefined : - result.length === 1 ? result[0] : result - ); - }); - }); diff --git a/js/storage-util.js b/js/storage-util.js index 044ba56a..2e966523 100644 --- a/js/storage-util.js +++ b/js/storage-util.js @@ -1,7 +1,12 @@ -/* global loadScript tryJSONparse */ +/* global loadScript tryJSONparse promisifyChrome */ /* exported chromeLocal chromeSync */ 'use strict'; +promisifyChrome({ + 'storage.local': ['get', 'remove', 'set'], + 'storage.sync': ['get', 'remove', 'set'], +}); + const [chromeLocal, chromeSync] = (() => { return [ createWrapper('local'), @@ -9,11 +14,11 @@ const [chromeLocal, chromeSync] = (() => { ]; function createWrapper(name) { - const storage = chrome.storage[name]; + const storage = browser.storage[name]; const wrapper = { - get: data => new Promise(resolve => storage.get(data, resolve)), - set: data => new Promise(resolve => storage.set(data, () => resolve(data))), - remove: data => new Promise(resolve => storage.remove(data, resolve)), + get: storage.get.bind(storage), + set: data => storage.set(data).then(() => data), + remove: storage.remove.bind(storage), /** * @param {String} key diff --git a/manage.html b/manage.html index 76e0c7ce..d168af14 100644 --- a/manage.html +++ b/manage.html @@ -147,7 +147,6 @@ - diff --git a/manifest.json b/manifest.json index 5ad60993..89a62be7 100644 --- a/manifest.json +++ b/manifest.json @@ -26,7 +26,6 @@ "background": { "scripts": [ "js/polyfill.js", - "js/promisify.js", "js/messaging.js", "js/msg.js", "js/storage-util.js", @@ -77,7 +76,6 @@ "match_about_blank": true, "js": [ "js/polyfill.js", - "js/promisify.js", "js/msg.js", "js/prefs.js", "content/style-injector.js", diff --git a/options.html b/options.html index 0a02e415..6ea9a78b 100644 --- a/options.html +++ b/options.html @@ -21,7 +21,6 @@ - diff --git a/popup.html b/popup.html index fd80f988..41cd7852 100644 --- a/popup.html +++ b/popup.html @@ -179,7 +179,6 @@ - diff --git a/popup/search-results.js b/popup/search-results.js index c22a7ae7..d46982ac 100755 --- a/popup/search-results.js +++ b/popup/search-results.js @@ -1,6 +1,6 @@ /* global tabURL handleEvent $ $$ prefs template FIREFOX chromeLocal debounce $create t API tWordBreak formatDate tryCatch tryJSONparse LZString - ignoreChromeError download */ + promisifyChrome download */ 'use strict'; window.addEventListener('showStyles:done', function _() { @@ -88,6 +88,9 @@ window.addEventListener('showStyles:done', function _() { return; function init() { + promisifyChrome({ + 'storage.local': ['getBytesInUse'], // FF doesn't implement it + }); setTimeout(() => document.body.classList.add(BODY_CLASS)); $('#find-styles-inline-group').classList.add('hidden'); @@ -711,7 +714,7 @@ window.addEventListener('showStyles:done', function _() { return chromeLocal.loadLZStringScript().then(() => tryJSONparse(LZString.decompressFromUTF16(item.payload))); } else if (item) { - chrome.storage.local.remove(key); + chromeLocal.remove(key); } }); } @@ -742,16 +745,8 @@ window.addEventListener('showStyles:done', function _() { function cleanupCache() { chromeLocal.remove(CACHE_CLEANUP_NEEDED); - if (chrome.storage.local.getBytesInUse) { - chrome.storage.local.getBytesInUse(null, size => { - if (size > CACHE_SIZE) { - chrome.storage.local.get(null, cleanupCacheInternal); - } - ignoreChromeError(); - }); - } else { - chrome.storage.local.get(null, cleanupCacheInternal); - } + Promise.resolve(!browser.storage.local.getBytesInUse ? 1e99 : browser.storage.local.getBytesInUse()) + .then(size => size > CACHE_SIZE && chromeLocal.get().then(cleanupCacheInternal)); } function cleanupCacheInternal(storage) { @@ -764,9 +759,8 @@ window.addEventListener('showStyles:done', function _() { sortedByTime.slice(0, sortedByTime.length / 2); const toRemove = expired.length ? expired : sortedByTime; if (toRemove.length) { - chrome.storage.local.remove(toRemove.map(item => item.key), ignoreChromeError); + chromeLocal.remove(toRemove.map(item => item.key)); } - ignoreChromeError(); } //endregion