diff --git a/package.json b/package.json index 5532f6c..b79a4f8 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "update-version": "VERSION=$(utc-version); echo $VERSION; dot-json distribution/manifest.json version $VERSION" }, "dependencies": { - "dom-loaded": "^1.0.1", "element-ready": "^4.0.0", "localforage": "^1.7.2", "select-dom": "^5.0.0", @@ -23,31 +22,31 @@ "webextension-polyfill": "^0.4.0" }, "devDependencies": { - "@babel/core": "^7.2.2", + "@babel/core": "^7.4.5", "@babel/plugin-syntax-dynamic-import": "^7.2.0", - "@babel/plugin-transform-modules-commonjs": "^7.2.0", - "@babel/register": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.4.4", + "@babel/register": "^7.4.4", "@wext/shipit": "^0.2.0", "ava": "^2.0.0", - "babel-eslint": "^10.0.1", - "babel-loader": "^8.0.5", - "copy-webpack-plugin": "^5.0.0", + "babel-eslint": "^10.0.2", + "babel-loader": "^8.0.6", + "copy-webpack-plugin": "^5.0.3", "cross-env": "^5.2.0", "dot-json": "^1.1.0", "eslint": "^6.0.1", "eslint-config-standard": "^12.0.0", - "eslint-plugin-import": "^2.14.0", + "eslint-plugin-import": "^2.18.0", "eslint-plugin-node": "^9.0.0", - "eslint-plugin-promise": "^4.0.0", + "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.0", "npm-run-all": "^4.1.5", "stylelint": "^10.0.0", - "stylelint-config-standard": "^18.2.0", - "terser-webpack-plugin": "^1.2.1", + "stylelint-config-standard": "^18.3.0", + "terser-webpack-plugin": "^1.3.0", "utc-version": "^2.0.0", - "webpack": "^4.28.4", - "webpack-chrome-extension-reloader": "^1.0.0", - "webpack-cli": "^3.2.1" + "webpack": "^4.35.0", + "webpack-chrome-extension-reloader": "^1.3.0", + "webpack-cli": "^3.3.5" }, "ava": { "files": [ diff --git a/source/background.js b/source/background.js index d657e1e..b1e13d7 100644 --- a/source/background.js +++ b/source/background.js @@ -1,6 +1,7 @@ import localforage from 'localforage' import { isEmpty } from './libs/utils' import { renderBadge } from './libs/browser' +import optionsStorage from './libs/storage' localforage.setDriver([localforage.INDEXEDDB, localforage.WEBSQL]) @@ -35,8 +36,14 @@ browser.runtime.onMessage.addListener(async (message, sender) => { } if (message.action === 'content') { - renderBadge(site.length.toString() || '', sender.tab.id) + await renderBadge(site.length.toString() || '', sender.tab.id) // await browser.tabs.insertCSS(sender.tab.id, { file: 'content.css' }) + + const { enableContent } = await optionsStorage.getAll(); + + if (!enableContent) { + return + } } return Promise.all(site.map(async name => ((await entitiesStore.getItem(name)) || {name}))) diff --git a/source/content.js b/source/content.js index ceb5186..05f3b8c 100644 --- a/source/content.js +++ b/source/content.js @@ -1,7 +1,7 @@ import 'webext-dynamic-content-scripts' import select from 'select-dom' +import elementReady from 'element-ready' -import { safeElementReady } from './libs/document' import {isEmpty, renderText} from './libs/utils' // Add globals for easier debugging @@ -17,7 +17,9 @@ async function init () { return } - await safeElementReady('body') + await elementReady('body', { + stopOnDomReady: false + }) document.documentElement.classList.add('qui-possede-les-medias') const box = document.createElement('div') diff --git a/source/libs/browser.js b/source/libs/browser.js index bff42a2..7fd3d9e 100644 --- a/source/libs/browser.js +++ b/source/libs/browser.js @@ -1,3 +1,26 @@ -export const renderBadge = (text, tabId) => { - browser.browserAction.setBadgeText({text, tabId}) +export const renderBadge = async (text, tabId) => { + try { + return browser.browserAction.setBadgeText({text, tabId}) + } catch (error) { + console.log(error) + return false + } +} + +export const queryPermission = async (permission) => { + try { + return browser.permissions.contains({permissions: [permission]}) + } catch (error) { + console.log(error) + return false + } +} + +export const requestPermission = async (permission) => { + try { + return browser.permissions.request({permissions: [permission]}) + } catch (error) { + console.log(error) + return false + } } diff --git a/source/libs/document.js b/source/libs/document.js deleted file mode 100644 index e917094..0000000 --- a/source/libs/document.js +++ /dev/null @@ -1,17 +0,0 @@ -import domLoaded from 'dom-loaded' -import elementReady from 'element-ready' - -/** - * Automatically stops checking for an element to appear once the DOM is ready. - * - * @license MIT Sindre Sorhus - */ -export const safeElementReady = selector => { - const waiting = elementReady(selector) - - // Don't check ad-infinitum - domLoaded.then(() => requestAnimationFrame(() => waiting.cancel())) - - // If cancelled, return null like a regular select() would - return waiting.catch(() => null) -} diff --git a/source/libs/storage.js b/source/libs/storage.js new file mode 100644 index 0000000..99d675d --- /dev/null +++ b/source/libs/storage.js @@ -0,0 +1,7 @@ +import OptionsSync from 'webext-options-sync' + +export default new OptionsSync({ + defaults: { + enableContent: true + } +}) diff --git a/source/options.html b/source/options.html index ce0a26d..78778ee 100644 --- a/source/options.html +++ b/source/options.html @@ -9,12 +9,14 @@
diff --git a/source/options.js b/source/options.js index e531dea..2677c45 100644 --- a/source/options.js +++ b/source/options.js @@ -1,3 +1,30 @@ -import OptionsSync from 'webext-options-sync'; +import optionsStorage from './libs/storage' +import { requestPermission } from './libs/browser' -new OptionsSync().syncForm('#options-form'); +optionsStorage.syncForm('#options-form') + +for (const inputElement of document.querySelectorAll('#options-form [name]')) { + inputElement.addEventListener('change', () => { + // `webext-options-sync` debounces syncing to 100ms, so send updates sometime after that + setTimeout(() => { + browser.runtime.sendMessage('update') + }, 200) + }) + + if (inputElement.dataset.requestPermission) { + inputElement.parentElement.addEventListener('click', async event => { + if (event.target !== inputElement) { + return + } + + if (inputElement.checked) { + inputElement.checked = await requestPermission(inputElement.dataset.requestPermission) + + // Programatically changing input value does not trigger input events, so save options manually + optionsStorage.set({ + [inputElement.name]: inputElement.checked + }) + } + }) + } +} diff --git a/webpack.config.js b/webpack.config.js index 71ed229..f849c70 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,7 +9,8 @@ module.exports = (env, argv) => ({ entry: { 'content-script': './source/content', background: './source/background', - popup: './source/popup' + popup: './source/popup', + options: './source/options' }, output: { path: path.join(__dirname, 'distribution'),