From 8976bd58b843c9ea156f99a22135f8b4e5f37576 Mon Sep 17 00:00:00 2001 From: tophf Date: Thu, 24 Aug 2017 16:30:13 +0300 Subject: [PATCH] inform when dysfunctional due to FF options --- _locales/en/messages.json | 8 ++++++++ background/background.js | 6 ++---- background/storage.js | 2 +- background/update.js | 2 +- js/dom.js | 27 +++++++++++++++++++++++++++ js/prefs.js | 5 ++++- manage/manage.js | 24 +++++++++++++++++++++++- msgbox/dysfunctional.css | 21 +++++++++++++++++++++ msgbox/dysfunctional.html | 9 +++++++++ msgbox/dysfunctional.js | 6 ++++++ 10 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 msgbox/dysfunctional.css create mode 100644 msgbox/dysfunctional.html create mode 100644 msgbox/dysfunctional.js diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 09d94e64..a006ac76 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -135,6 +135,14 @@ "message": "Double-click to maximize/restore the height", "description": "Tooltip for the resize grip in style editor" }, + "dysfunctional": { + "message": "Stylus cannot function because Firefox is either in private mode or is applying its website cookies policy to IndexedDB storage used by Stylus, which erroneously marks the secure moz-extension:// origin as insecure even though WebExtensions aren't websites and Stylus doesn't use cookies.\n\n1. Open Firefox options\n2. Go to 'Privacy & Security'\n3. Set 'History' mode to 'Use custom settings'\n4. Click 'Exceptions'\n5. Paste our manifest URL and click 'Allow'\n6. Click 'Save settings'\n7. Uncheck 'Always use private browsing mode'\n\nThe actual manifest URL is shown below.\nYou can also find it on about:debugging page.", + "description": "Displayed in Firefox when its settings make Stylus dysfunctional" + }, + "dysfunctionalBackgroundConnection": { + "message": "Cannot function properly because of a known bug in this version of Firefox: chrome.extension.getBackgroundPage() doesn't return a valid result", + "description": "Displayed in style manager when unable to connect to the background page" + }, "genericDisabledLabel": { "message": "Disabled", "description": "Used in various lists/options to indicate that something is disabled" diff --git a/background/background.js b/background/background.js index 44e09795..3e800ec6 100644 --- a/background/background.js +++ b/background/background.js @@ -5,10 +5,8 @@ var browserCommands, contextMenus; // ************************************************************************* -// preload the DB and report errors -dbExec().catch((...args) => { - args.forEach(arg => 'message' in arg && console.error(arg.message)); -}); +// preload the DB +tryCatch(getStyles); // ************************************************************************* // register all listeners diff --git a/background/storage.js b/background/storage.js index c0e1ce3a..9b105357 100644 --- a/background/storage.js +++ b/background/storage.js @@ -59,7 +59,7 @@ function dbExec(method, data) { } }, onerror(event) { - console.warn(event.target.errorCode); + console.warn(event.target.error || event.target.errorCode); reject(event); }, onupgradeneeded(event) { diff --git a/background/update.js b/background/update.js index 04f368f5..69f12d3f 100644 --- a/background/update.js +++ b/background/update.js @@ -18,7 +18,7 @@ var updater = { ERROR_MD5: 'error: MD5 is invalid', ERROR_JSON: 'error: JSON is invalid', - lastUpdateTime: parseInt(localStorage.lastUpdateTime) || Date.now(), + lastUpdateTime: parseInt(tryCatch(() => localStorage.lastUpdateTime)) || Date.now(), checkAllStyles({observer = () => {}, save = true, ignoreDigest} = {}) { updater.resetInterval(); diff --git a/js/dom.js b/js/dom.js index 07ad5ccf..cbfc2d98 100644 --- a/js/dom.js +++ b/js/dom.js @@ -39,6 +39,7 @@ for (const type of [NodeList, NamedNodeMap, HTMLCollection, HTMLAllCollection]) // add favicon in Firefox // eslint-disable-next-line no-unused-expressions navigator.userAgent.includes('Firefox') && setTimeout(() => { + dieOnDysfunction(); const iconset = ['', 'light/'][prefs.get('iconset')] || ''; for (const size of [38, 32, 19, 16]) { document.head.appendChild($element({ @@ -173,3 +174,29 @@ function retranslateCSS(selectorToMessageMap) { } } } + + +function dieOnDysfunction() { + function die() { + location.href = '/msgbox/dysfunctional.html'; + throw 0; + } + (() => { + try { + return indexedDB; + } catch (e) { + die(); + } + })(); + Object.assign(indexedDB.open('test'), { + onerror: die, + onupgradeneeded: indexedDB.deleteDatabase('test'), + }); + // TODO: fallback to sendMessage in FF since private windows can't get bg page + chrome.windows.getCurrent(wnd => wnd.incognito && die()); + // check if privacy settings were fixed but the extension wasn't reloaded + const bg = chrome.extension.getBackgroundPage(); + if (bg && !(bg.cachedStyles || {}).list) { + chrome.runtime.reload(); + } +} diff --git a/js/prefs.js b/js/prefs.js index 6b75b1fa..184363df 100644 --- a/js/prefs.js +++ b/js/prefs.js @@ -74,6 +74,9 @@ var prefs = new function Prefs() { specific: new Map(), }; + // FF may think localStorage is a cookie or that it's not secure + const localStorage = tryCatch(() => localStorage) ? window.localStorage : {}; + // coalesce multiple pref changes in broadcast let broadcastPrefs = {}; @@ -203,7 +206,7 @@ var prefs = new function Prefs() { } }; - getSync().get('settings', ({settings}) => importFromSync(settings)); + getSync().get('settings', ({settings} = {}) => importFromSync(settings)); chrome.storage.onChanged.addListener((changes, area) => { if (area === 'sync' && 'settings' in changes) { diff --git a/manage/manage.js b/manage/manage.js index 54e5c668..01340355 100644 --- a/manage/manage.js +++ b/manage/manage.js @@ -35,7 +35,8 @@ Promise.all([ }); if (FIREFOX) { - // TODO: remove when this bug is fixed in FF + // TODO: remove when these bugs are fixed in FF + dieOnNullBackground(); retranslateCSS({ '.disabled h2::after': '__MSG_genericDisabledLabel__', @@ -538,3 +539,24 @@ function usePrefsDuringPageLoad() { startObserver(); onDOMready().then(() => observer.disconnect()); } + + +function dieOnNullBackground() { + if (BG) { + return; + } + chrome.runtime.sendMessage({method: 'healthCheck'}, health => { + if (health && !chrome.extension.getBackgroundPage()) { + onDOMready().then(() => { + chrome.runtime.sendMessage({method: 'getStyles'}, showStyles); + messageBox({ + title: 'Stylus', + className: 'danger center', + contents: t('dysfunctionalBackgroundConnection'), + onshow: () => $('#message-box-close-icon').remove(), + }); + document.documentElement.style.pointerEvents = 'none'; + }); + } + }); +} diff --git a/msgbox/dysfunctional.css b/msgbox/dysfunctional.css new file mode 100644 index 00000000..bad05b62 --- /dev/null +++ b/msgbox/dysfunctional.css @@ -0,0 +1,21 @@ +html { + height: 100vh; + min-height: 450px; + display: flex; + align-items: center; + justify-content: center; + white-space: pre-wrap; + background-color: #555; + box-sizing: border-box; + border: 2vw solid black; +} + +body { + margin: 2em; + color: white; + max-width: 600px; +} + +div { + color: antiquewhite; +} diff --git a/msgbox/dysfunctional.html b/msgbox/dysfunctional.html new file mode 100644 index 00000000..7944f05d --- /dev/null +++ b/msgbox/dysfunctional.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/msgbox/dysfunctional.js b/msgbox/dysfunctional.js new file mode 100644 index 00000000..1a06bf5e --- /dev/null +++ b/msgbox/dysfunctional.js @@ -0,0 +1,6 @@ +'use strict'; + +document.body.textContent = + chrome.i18n.getMessage('dysfunctional'); +document.body.appendChild(document.createElement('div')).textContent = + chrome.runtime.getURL('manifest.json');