diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 4dd24b8..84a6ad9 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -24,6 +24,14 @@ "message": "\n \u00B7 {api}", "description": "" }, + "browserAction_status_on": { + "message": "CanvasBlocker on", + "description": "" + }, + "browserAction_status_off": { + "message": "CanvasBlocker off", + "description": "" + }, "more": { "message": "more", diff --git a/browserAction/browserAction.css b/browserAction/browserAction.css index d2288e1..af18fe2 100644 --- a/browserAction/browserAction.css +++ b/browserAction/browserAction.css @@ -19,4 +19,27 @@ div { .action.search { padding-left: calc(0.5em + 19px + 0.25em); +} + +#addonStatus { + border: none; + display: block; + margin: 5px auto; + width: 40px; + min-width: 0; + height: 40px; + background: none; + background-position: 50%; + background-size: 100%; + cursor: pointer; +} + +#addonStatus.unknown { + background-image: radial-gradient(black, rgba(0, 0, 0, 0), transparent);; +} +#addonStatus.off { + background-image: url(../icons/browserAction-whitelisted.svg); +} +#addonStatus.on { + background-image: url(../icons/browserAction-notPrinted.svg); } \ No newline at end of file diff --git a/browserAction/browserAction.html b/browserAction/browserAction.html index 8e30844..da628c5 100644 --- a/browserAction/browserAction.html +++ b/browserAction/browserAction.html @@ -7,6 +7,7 @@ +
@@ -14,6 +15,7 @@ + diff --git a/browserAction/browserAction.js b/browserAction/browserAction.js index 583725e..78c9d7f 100644 --- a/browserAction/browserAction.js +++ b/browserAction/browserAction.js @@ -7,55 +7,99 @@ const extension = require("../lib/extension"); const logging = require("../lib/logging"); const settings = require("../lib/settings"); + const settingContainers = require("../lib/settingContainers"); + const lists = require("../lib/lists"); require("../lib/theme").init(); logging.message("Opened browser action"); - settings.onloaded(function(){ - const actions = document.getElementById("actions"); + + browser.tabs.query({active: true}).then(async function([currentTab]){ + function isWhitelisted(url){ + if (!(url instanceof URL)){ + url = new URL(url); + } + return lists.get("white").match(url) || + settings.get("blockMode", url).startsWith("allow"); + } - [ - { - label: "settings", - icon: browser.extension.getURL("icons/pageAction-showOptions.svg"), - action: function(){ - if (browser.runtime && browser.runtime.openOptionsPage){ - browser.runtime.openOptionsPage(); - } - else { - window.open(browser.extension.getURL("options/options.html"), "_blank"); - } + const currentURL = new URL(currentTab.url); + const addonStatus = document.getElementById("addonStatus"); + addonStatus.addEventListener("click", async function(){ + if (isWhitelisted(currentURL)){ + settingContainers.resetUrlValue("blockMode", currentURL); + if (settings.get("blockMode").startsWith("allow")){ + settings.set("blockMode", "fake", currentURL.host); } - }, - { - label: "faq", - icon: browser.extension.getURL("icons/browserAction-faq.svg"), - action: function(){ - window.open("https://canvasblocker.kkapsner.de/faq/", "_blank"); + const entries = lists.get("white").filter(e => e.match(currentURL)).map(e => e.value); + await Promise.all([ + lists.removeFrom("white", entries), + lists.removeFrom("sessionWhite", entries) + ]); + } + else { + settings.set("blockMode", "allow", currentURL.hostname); + } + update(); + }); + function update(){ + if (isWhitelisted(currentURL)){ + addonStatus.className = "off"; + addonStatus.title = extension.getTranslation("browserAction_status_off"); + } + else { + addonStatus.className = "on"; + addonStatus.title = extension.getTranslation("browserAction_status_on"); + } + } + return settings.onloaded(update); + }).catch(function(){}); + + const actionDefinitions = [ + { + label: "settings", + icon: browser.extension.getURL("icons/pageAction-showOptions.svg"), + action: function(){ + if (browser.runtime && browser.runtime.openOptionsPage){ + browser.runtime.openOptionsPage(); } - }, - { - label: "test", - advanced: true, - icon: browser.extension.getURL("icons/browserAction-test.svg"), - action: function(){ - window.open("https://canvasblocker.kkapsner.de/test", "_blank"); + else { + window.open(browser.extension.getURL("options/options.html"), "_blank"); } - }, - { - label: "review", - icon: browser.extension.getURL("icons/browserAction-review.svg"), - action: function(){ - window.open("https://addons.mozilla.org/firefox/addon/canvasblocker/reviews/", "_blank"); - } - }, - { - label: "reportIssue", - icon: browser.extension.getURL("icons/browserAction-reportIssue.svg"), - action: function(){ - window.open("https://github.com/kkapsner/CanvasBlocker/issues", "_blank"); - } - }, - ].forEach(function(action){ + } + }, + { + label: "faq", + icon: browser.extension.getURL("icons/browserAction-faq.svg"), + action: function(){ + window.open("https://canvasblocker.kkapsner.de/faq/", "_blank"); + } + }, + { + label: "test", + advanced: true, + icon: browser.extension.getURL("icons/browserAction-test.svg"), + action: function(){ + window.open("https://canvasblocker.kkapsner.de/test", "_blank"); + } + }, + { + label: "review", + icon: browser.extension.getURL("icons/browserAction-review.svg"), + action: function(){ + window.open("https://addons.mozilla.org/firefox/addon/canvasblocker/reviews/", "_blank"); + } + }, + { + label: "reportIssue", + icon: browser.extension.getURL("icons/browserAction-reportIssue.svg"), + action: function(){ + window.open("https://github.com/kkapsner/CanvasBlocker/issues", "_blank"); + } + }, + ]; + settings.onloaded(async function(){ + const actions = document.getElementById("actions"); + actionDefinitions.forEach(function(action){ logging.verbose("Action", action); if (action.advanced && !settings.displayAdvancedSettings){ logging.verbose("Hiding advanced action"); @@ -66,16 +110,23 @@ const icon = document.createElement("span"); icon.className = "icon"; - icon.style.maskImage = "url(" + action.icon + ")"; + function setIcon(url){ + icon.style.maskImage = "url(" + url + ")"; + } + setIcon(action.icon); actionButton.appendChild(icon); - actionButton.appendChild( - document.createTextNode( - extension.getTranslation("browserAction_" + action.label) || action.label - ) - ); - actionButton.addEventListener("click", action.action); + const textNode = document.createTextNode(""); + function setLabel(label){ + textNode.nodeValue = extension.getTranslation("browserAction_" + label) || label; + } + setLabel(action.label); + + actionButton.appendChild(textNode); + actionButton.addEventListener("click", function(){ + action.action.call(this, {setIcon, setLabel}); + }); actions.appendChild(actionButton); }); diff --git a/lib/lists.js b/lib/lists.js index 29ac9e2..9411076 100644 --- a/lib/lists.js +++ b/lib/lists.js @@ -36,6 +36,7 @@ regExp = new RegExp(entry, "i"); } return { + value: entry, match: function(url){ if (domain){ return (url.hostname || "").match(regExp); @@ -119,9 +120,23 @@ await settings.set(type + "List", oldValue + (oldValue? ",": "") + entry); return updateList(type); }; + scope.removeFrom = async function removeFromList(type, entry){ + const oldValue = settings[type + "List"]; + const filter = entry.forEach? v => entry.indexOf(v) === -1: v => v !== entry; + await settings.set( + type + "List", + oldValue + .split(",") + .map(v => v.replace(/^\s+|\s+$/, "")) + .filter(filter) + .join(",") + ); + return updateList(type); + }; scope.update = updateList; scope.updateAll = function updateAllLists(){ updateList("white"); + updateList("sessionWhite"); updateList("ignore"); updateList("black"); updateStackList(settings.stackList); diff --git a/lib/settingContainers.js b/lib/settingContainers.js index 360caa4..15cb645 100644 --- a/lib/settingContainers.js +++ b/lib/settingContainers.js @@ -48,18 +48,17 @@ }; scope.resetUrlValue = function(name, url){ let urlContainerValue = scope.urlContainer.get(); - const matching = urlContainerValue.filter(function(urlSetting){ + urlContainerValue.filter(function(urlSetting){ return urlSetting.match(url); - }); - if (matching.length){ - delete matching[0][name]; - if (Object.keys(matching[0]).every(function(key){return key === "url";})){ + }).forEach(function(match){ + delete match[name]; + if (Object.keys(match).every(function(key){return key === "url";})){ urlContainerValue = urlContainerValue.filter(function(urlSetting){ - return urlSetting !== matching[0]; + return urlSetting !== match; }); } - scope.urlContainer.set(urlContainerValue); - } + }); + scope.urlContainer.set(urlContainerValue); }; function processHideContainer(settingDefinition){ diff --git a/releaseNotes.txt b/releaseNotes.txt index e862284..2a66932 100644 --- a/releaseNotes.txt +++ b/releaseNotes.txt @@ -7,6 +7,7 @@ Version 1.6: new features: - try to not break tabs when updating - setting to postpone updates until browser restart or extension is reloaded + - added status button in browser action to see and set the whitelist status fixes: - fix message canvasBlocker-unload