diff --git a/_locales/de/messages.json b/_locales/de/messages.json index c247743..7072052 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -331,5 +331,38 @@ "showReleaseNotes_label": { "message": "Anzeigen", "description": "" + }, + + "logLevel_title": { + "message": "Aufzeichnungslevel", + "description": "" + }, + "logLevel_description": { + "message": "Für eine Fehlersuche ist eine detaillierte Aufzeichnung der Addon-Aktivitäten hilfreich. Mit diesem Parameter kann der Grad der Detailliertheit dieser Aufzeichnung eingestellt werden.", + "description": "" + }, + "logLevel_options.none": { + "message": "nichts", + "description": "" + }, + "logLevel_options.error": { + "message": "Fehler", + "description": "" + }, + "logLevel_options.warning": { + "message": "Warnungen", + "description": "" + }, + "logLevel_options.message": { + "message": "Nachrichten", + "description": "" + }, + "logLevel_options.notice": { + "message": "Notizen", + "description": "" + }, + "logLevel_options.verbose": { + "message": "ausführlich", + "description": "" } } \ No newline at end of file diff --git a/_locales/en/messages.json b/_locales/en/messages.json index eea8f2b..fc9a993 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -335,5 +335,38 @@ "showReleaseNotes_label": { "message": "Show", "description": "" + }, + + "logLevel_title": { + "message": "Logging level", + "description": "" + }, + "logLevel_description": { + "message": "To finde the cause for an error a detailed logging of the addon activities is helpful. This parameter controls the level of detail of the logging.", + "description": "" + }, + "logLevel_options.none": { + "message": "none", + "description": "" + }, + "logLevel_options.error": { + "message": "error", + "description": "" + }, + "logLevel_options.warning": { + "message": "warning", + "description": "" + }, + "logLevel_options.message": { + "message": "message", + "description": "" + }, + "logLevel_options.notice": { + "message": "notice", + "description": "" + }, + "logLevel_options.verbose": { + "message": "verbose", + "description": "" } } \ No newline at end of file diff --git a/lib/check.js b/lib/check.js index 290eaff..1aff384 100644 --- a/lib/check.js +++ b/lib/check.js @@ -20,6 +20,7 @@ const prefs = preferences.prefs; const {parseErrorStack} = require("./callingStack"); const {URL} = require("sdk/url"); + const logging = require("./logging"); scope.check = function check({url, errorStack}){ var match = checkBoth(errorStack, url, prefs.blockMode).match(/^(block|allow|fake|ask)(|Readout|Everything|Context|Input|Internal)$/); @@ -50,14 +51,18 @@ } function checkURL(url, blockMode){ + logging.message("check url %s for block mode %s", url, blockMode); url = new URL(url || "about:blank"); switch (url.protocol){ case "about:": if (url.href === "about:blank"){ + logging.message("use regular mode on about:blank"); break; } + logging.message("allow internal URLs"); return "allowInternal"; case "chrome:": + logging.message("allow internal URLs"); return "allowInternal"; } @@ -96,7 +101,7 @@ mode = "allow"; break; default: - // console.log("Unknown blocking mode (" + blockMode + "). Default to block everything."); + logging.warning("Unknown blocking mode (" + blockMode + "). Default to block everything."); } return mode; } diff --git a/lib/defaultSettings.js b/lib/defaultSettings.js index c459d48..adbdaa4 100644 --- a/lib/defaultSettings.js +++ b/lib/defaultSettings.js @@ -1,6 +1,7 @@ "use strict"; var settings = { + logLevel: 100, whiteList: "", blackList: "", blockMode: "fakeReadout", @@ -17,5 +18,6 @@ var settings = { showCallingFile: false, showCompleteCallingStack: false, enableStackList: false, - stackList: "" + stackList: "", + isStillDefault: true }; \ No newline at end of file diff --git a/lib/frame.js b/lib/frame.js index d11c656..a73e373 100644 --- a/lib/frame.js +++ b/lib/frame.js @@ -4,33 +4,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ (function(){ "use strict"; - function log(...args){ - function leftPad(str, char, pad){ - str = "" + str; - return char.repeat(pad - str.length) + str; - } - args.unshift("frame script:"); - var now = new Date(); - args.unshift( - now.getFullYear() + "-" + - leftPad(now.getMonth() + 1, "0", 2) + "-" + - leftPad(now.getDate(), "0", 2) + " " + - leftPad(now.getHours(), "0", 2) + ":" + - leftPad(now.getMinutes(), "0", 2) + ":" + - leftPad(now.getSeconds(), "0", 2) + "." + - leftPad(now.getMilliseconds(), "0", 3) - ); - console.log.apply(console, args); - } const {intercept} = require("./intercept.js"); const {ask} = require("./askForPermission.js"); const {check: originalCheck, checkStack: originalCheckStack} = require("./check.js"); + const {error, warning, message, notice, verbose, setPrefix: setLogPrefix} = require("./logging"); + setLogPrefix("frame script"); + // Variable to "unload" the script var enabled = true; - log("starting", location.href); + message("starting", location.href); function check(message){ if (enabled){ @@ -56,12 +41,12 @@ }); } - log("open port to background script"); + message("open port to background script"); var port = browser.runtime.connect(); var tabId; port.onMessage.addListener(function(data){ if (data.hasOwnProperty("tabId")){ - log("my tab id is", data.tabId); + notice("my tab id is", data.tabId); tabId = data.tabId; } }); @@ -89,16 +74,16 @@ catch (e){ // we are unable to read the location due to SOP // therefore we also can not intercept anything. - log("NOT intercepting window du to SOP", window); + warning("NOT intercepting window du to SOP", window); return false; } - log("intercepting window", window); + message("intercepting window", window); intercept( {subject: window}, {check, checkStack, ask: askWrapper, notify, prefs} ); - log("prepare to intercept (i)frames."); + message("prepare to intercept (i)frames."); [window.HTMLIFrameElement, window.HTMLFrameElement].forEach(function(constructor){ var oldContentWindowGetter = constructor.prototype.__lookupGetter__("contentWindow"); @@ -137,34 +122,34 @@ interceptWindow(window); - log("register listener for messages from background script"); + message("register listener for messages from background script"); browser.runtime.onMessage.addListener(function(data){ if (data["canvasBlocker-unload"]){ enabled = false; } if (data.hasOwnProperty("canvasBlocker-sendNotifications") && data["canvasBlocker-sendNotifications"] === tabId){ - log("sending notifications:", notifications); + notice("sending notifications:", notifications); browser.runtime.sendMessage({ sender: tabId, "canvasBlocker-notifications": notifications }); - log("notifications sent"); + notice("notifications sent"); } }); - log("load settings"); + message("load settings"); browser.storage.local.get().then(function(data){ Object.keys(data).forEach(function(key){ - log("loaded setting:", key, ":", data[key]); + notice("loaded setting:", key, ":", data[key]); settings[key] = data[key]; }); }); - log("register listener for settings changes"); + message("register listener for settings changes"); browser.storage.onChanged.addListener(function(change, area){ if (area === "local"){ Object.keys(change).forEach(function(key){ - log("setting changed:", key, ":", change[key].newValue); + notice("setting changed:", key, ":", change[key].newValue); settings[key] = change[key].newValue; }); } diff --git a/lib/logging.js b/lib/logging.js new file mode 100644 index 0000000..2f918f0 --- /dev/null +++ b/lib/logging.js @@ -0,0 +1,88 @@ +/* jslint moz: true */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +(function(){ + "use strict"; + + var scope; + if ((typeof exports) !== "undefined"){ + scope = exports; + } + else if (window.scope){ + window.scope.logging = {}; + scope = window.scope.logging; + } + else { + window.logging = {}; + scope = window.logging; + } + + var prefix = ""; + + function leftPad(str, char, pad){ + str = "" + str; + return char.repeat(pad - str.length) + str; + } + + var queue = []; + function performLog(level, args, date){ + if (!date){ + date = new Date(); + } + if (settings.isStillDefault){ + queue.push({level, args, date}); + } + else { + if (settings.logLevel >= level){ + if (prefix){ + args.unshift(prefix + ":"); + } + args.unshift( + "[" + + date.getFullYear() + "-" + + leftPad(date.getMonth() + 1, "0", 2) + "-" + + leftPad(date.getDate(), "0", 2) + " " + + leftPad(date.getHours(), "0", 2) + ":" + + leftPad(date.getMinutes(), "0", 2) + ":" + + leftPad(date.getSeconds(), "0", 2) + "." + + leftPad(date.getMilliseconds(), "0", 3) + + "]" + ); + console.log.apply(console, args); + } + } + } + + function error (...args){performLog( 1, args);} + function warning(...args){performLog( 25, args);} + function message(...args){performLog( 50, args);} + function notice (...args){performLog( 75, args);} + function verbose(...args){performLog(100, args);} + function metaLog(...args){performLog(999, args);} + + scope.setPrefix = function(newPrefix){ + if (!prefix){ + prefix = newPrefix; + } + else { + warning("logging prefix already set (%s) cannot be set to %s", prefix, newPrefix); + } + }; + scope.clearQueue = function(){ + if (queue.length){ + metaLog("clear logging queue"); + var tmp = queue; + queue = []; + tmp.forEach(function(item){ + performLog(item.level, item.args, item.date); + }); + metaLog("logging queue cleared"); + } + }; + scope.error = error; + scope.warning = warning; + scope.message = message; + scope.notice = notice; + scope.verbose = verbose; +}()); \ No newline at end of file diff --git a/lib/main.js b/lib/main.js index eae7403..abb2457 100644 --- a/lib/main.js +++ b/lib/main.js @@ -5,25 +5,25 @@ (function(){ "use strict"; - function log(...args){ - args.unshift("main script:"); - args.unshift(new Date()); - console.log.apply(console, args); - } + const logging = require("./logging"); + const {error, warning, message, notice, verbose, } = logging; + logging.setPrefix("main script"); - log("start"); - log("loading storage"); + message("start"); + message("loading storage"); browser.storage.local.get().then(function(data){ Object.keys(data).forEach(function(key){ settings[key] = data[key]; }); + settings.isStillDefault = false; + logging.clearQueue(); return settings; }).then(function(settings){ - log("everything loaded"); + notice("everything loaded"); const lists = require("./lists"); lists.updateAll(); - log("build persistent storage"); + notice("build persistent storage"); var persistentRnd = Object.create(null); try { let storedData = JSON.parse(settings.persistentRndStorage); @@ -41,8 +41,8 @@ catch(e){} function updateContentScripts(){ - log("update content scripts"); - log("build settings blob"); + message("update content scripts"); + notice("build settings blob"); var settingsBlob = new Blob( [ "var settings = " + JSON.stringify(settings) + ";", @@ -52,15 +52,15 @@ type: "text/javascript" } ); - log("TODO: register content scripts -> have to wait for the API to be released"); + warning("TODO: register content scripts -> have to wait for the API to be released"); } updateContentScripts(); - log("register non port message listener"); + message("register non port message listener"); browser.runtime.onMessage.addListener(function(data){ - log("got data without port", data); + notice("got data without port", data); if (data["canvasBlocker-new-domain-rnd"]){ - log("got new domain rnd"); + verbose("got new domain rnd", data["canvasBlocker-new-domain-rnd"]); data["canvasBlocker-set-domain-rnd"] = data["canvasBlocker-new-domain-rnd"]; persistentRnd[data["canvasBlocker-new-domain-rnd"].domain] = data["canvasBlocker-new-domain-rnd"].rnd; browser.storage.local.get("storePersistentRnd").then(function(prefs){ @@ -70,7 +70,7 @@ }); updateContentScripts(); } - log("pass the message to the tabs"); + notice("pass the message to the tabs"); browser.tabs.query({}).then(function(tabs){ tabs.forEach(function(tab){ browser.tabs.sendMessage(tab.id, data); @@ -78,10 +78,10 @@ }); }); - log("register port listener"); + message("register port listener"); browser.runtime.onConnect.addListener(function(port){ - log("got port", port); - log("send back the tab id", port.sender.tab.id); + notice("got port", port); + verbose("send back the tab id", port.sender.tab.id); port.postMessage({tabId: port.sender.tab.id}); var url = new URL(port.sender.url); port.onMessage.addListener(function(data){ @@ -96,22 +96,22 @@ browser.pageAction.show(port.sender.tab.id); } }) - log("got data", data, "from port", port); + verbose("got data", data, "from port", port); }); }); - log("register storage change event listener"); + message("register storage change event listener"); browser.storage.onChanged.addListener(function(change, area){ if (area === "local"){ - log("settings changed", change); - log("update settings object"); + notice("settings changed", change); + notice("update settings object"); Object.keys(change).forEach(function(key){ settings[key] = change[key].newValue; }); updateContentScripts(); if (change.hasOwnProperty("showNotifications") && !change.showNotifications.newValue){ - log("notifications were disabled -> hide all page actions"); + message("notifications were disabled -> hide all page actions"); browser.tabs.query({}).then(function(tabs){ tabs.forEach(function(tab){ browser.pageAction.hide(tab.id); @@ -134,7 +134,7 @@ }); }); - // log("TODO: register unload events - do not know how - there seems to be no way with a WebExtension"); + // warning("TODO: register unload events - do not know how - there seems to be no way with a WebExtension"); // old code // const {when: unload} = require("sdk/system/unload"); // unload(function(){ @@ -142,7 +142,7 @@ // }); browser.runtime.onInstalled.addListener(function(){ - log("CanvasBlocker installed"); + message("CanvasBlocker installed"); browser.storage.local.get("storageVersion").then(function(data){ if (data.storageVersion !== 0.1){ browser.storage.local.set({ @@ -152,5 +152,5 @@ }); }); - log("end"); + message("end"); }()); \ No newline at end of file diff --git a/manifest.json b/manifest.json index fc2bdf1..4ea4e2c 100644 --- a/manifest.json +++ b/manifest.json @@ -10,6 +10,7 @@ "scripts": [ "lib/defaultSettings.js", "lib/require.js", + "lib/logging.js", "lib/lists.js", "lib/main.js" ] @@ -22,6 +23,8 @@ "lib/defaultSettings.js", "lib/require.js", + "lib/logging.js", + "lib/modifiedAPI.js", "lib/randomSupplies.js", "lib/intercept.js", diff --git a/options/buildPrefInputs.js b/options/buildPrefInputs.js index b26222d..3ac783c 100644 --- a/options/buildPrefInputs.js +++ b/options/buildPrefInputs.js @@ -220,6 +220,38 @@ document.body.appendChild(table); "title": "Release notes", "type": "control", "label": "Show" + }, + { + "name": "logLevel", + "title": "logging level", + "type": "menulist", + "value": 1, + "options": [ + { + "value": 0, + "label": "none" + }, + { + "value": 1, + "label": "error" + }, + { + "value": 25, + "label": "warning" + }, + { + "value": 50, + "label": "message" + }, + { + "value": 75, + "label": "notice" + }, + { + "value": 100, + "label": "verbose" + } + ] } ].forEach(function(pref){ var html = '
__MSG_' + pref.name + '_title__
__MSG_' + pref.name + '_description__
'; @@ -235,9 +267,9 @@ document.body.appendChild(table); html += ''; break; case "menulist": - html += '' + + html += '' + pref.options.map(function(option){ - if (option.value){ + if (option.value !== ""){ return ''; } else { @@ -250,13 +282,13 @@ document.body.appendChild(table); html += '__MSG_' + pref.name + '_label__'; break; default: - console.log("Unknown preference type: " + pref.type); + logging.warning("Unknown preference type: " + pref.type); } html += "
"; var tr = document.createElement("tr"); tr.setting = pref; tr.className = "settingRow"; tr.innerHTML = html; - console.log(html); + logging.verbose(html); table.appendChild(tr); }); \ No newline at end of file diff --git a/options/options.html b/options/options.html index f0e51d0..8fe9c9b 100644 --- a/options/options.html +++ b/options/options.html @@ -7,6 +7,7 @@ + diff --git a/options/options.js b/options/options.js index 8f07654..0fde81b 100644 --- a/options/options.js +++ b/options/options.js @@ -1,7 +1,13 @@ +/* jslint moz: true */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ browser.storage.local.get().then(function(data){ Object.keys(data).forEach(function(key){ settings[key] = data[key]; }); + settings.isStillDefault = false; + logging.clearQueue(); return settings; }).then(function(settings){ function traverse(node, func){ @@ -10,6 +16,7 @@ browser.storage.local.get().then(function(data){ } // getting the translation of all the messages + message("transate all messages"); traverse(document.body, function(node){ if (node.nodeType == 3){ var lines = node.nodeValue.replace(/\b__MSG_(.+)__\b/g, function(m, key){ @@ -28,12 +35,14 @@ browser.storage.local.get().then(function(data){ } }); + message("register events to store changes in local storage"); Array.from(document.querySelectorAll("input.setting, select.setting")).forEach(function(input){ var storageName = input.dataset.storageName; if (input.type === "checkbox"){ input.checked = settings[storageName]; input.addEventListener("click", function(){ + message("changed setting", storageName, ":", this.checked); var value = this.checked; var obj = {}; obj[storageName] = value; @@ -44,9 +53,10 @@ browser.storage.local.get().then(function(data){ input.addEventListener("change", function(){ var value = this.value; - if (this.type === "number"){ + if (this.type === "number" || this.dataset.type === "number"){ value = parseFloat(value); } + message("changed setting", storageName, ":", value); var obj = {}; obj[storageName] = value; browser.storage.local.set(obj); @@ -56,6 +66,7 @@ browser.storage.local.get().then(function(data){ var callbacks = { showReleaseNotes: function(){ + verbose("open release notes"); window.open("../releaseNotes.txt", "_blank"); // would be nicer but is not supported in fennec // browser.windows.create({ @@ -64,7 +75,10 @@ browser.storage.local.get().then(function(data){ // }); }, clearPersistentRnd: function(){ + message("clear persistent rnd storage"); + notice("empty storage"); browser.storage.local.set({persistentRndStorage: ""}); + notice("send message to main script"); browser.runtime.sendMessage({"canvasBlocker-clear-domain-rnd": true}); } }; @@ -78,13 +92,14 @@ browser.storage.local.get().then(function(data){ }); function updateDisplay(){ + notice("update display"); document.querySelectorAll("tr.settingRow").forEach(function(row){ + verbose("evaluate display dependencies for", row.setting); var displayDependencies = row.setting.displayDependencies; if (displayDependencies){ row.classList[( (Array.isArray(displayDependencies)? displayDependencies: [displayDependencies]).some(function(displayDependency){ return Object.keys(displayDependency).every(function(key){ - console.log(key, displayDependency[key], settings[key]); return displayDependency[key].indexOf(settings[key]) !== -1; }); }) diff --git a/pageAction/pageAction.html b/pageAction/pageAction.html index af79f81..a313a6f 100644 --- a/pageAction/pageAction.html +++ b/pageAction/pageAction.html @@ -9,8 +9,9 @@ - + + diff --git a/pageAction/pageAction.js b/pageAction/pageAction.js index 46e5a7f..38b698d 100644 --- a/pageAction/pageAction.js +++ b/pageAction/pageAction.js @@ -1,38 +1,7 @@ -// console.log(window, browser, browser.runtime); -function modalPrompt(message, defaultValue){ - return new Promise(function(resolve, reject){ - document.body.innerHTML = ""; - document.body.appendChild(document.createTextNode(message)); - var input = document.createElement("input"); - input.value = defaultValue; - document.body.appendChild(input); - var button = document.createElement("button"); - button.textContent = "OK"; - button.addEventListener("click", function(){ - resolve(input.value); - }); - document.body.appendChild(button); - }); -} - -function log(...args){ - function leftPad(str, char, pad){ - str = "" + str; - return char.repeat(pad - str.length) + str; - } - args.unshift("page action script:"); - var now = new Date(); - args.unshift( - now.getFullYear() + "-" + - leftPad(now.getMonth() + 1, "0", 2) + "-" + - leftPad(now.getDate(), "0", 2) + " " + - leftPad(now.getHours(), "0", 2) + ":" + - leftPad(now.getMinutes(), "0", 2) + ":" + - leftPad(now.getSeconds(), "0", 2) + "." + - leftPad(now.getMilliseconds(), "0", 3) - ); - console.log.apply(console, args); -} +/* jslint moz: true */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ Promise.all([ browser.tabs.query({active: true, currentWindow: true}), @@ -42,7 +11,31 @@ Promise.all([ }); return settings; }) -]).then(function([tabs, settings]){ +]).then(function(values){ + "use strict"; + const [tabs, settings] = values; + + const {error, warning, message, notice, verbose, setPrefix: setLogPrefix} = require("./logging"); + setLogPrefix("page action script"); + + function modalPrompt(message, defaultValue){ + message("open modal prompt"); + return new Promise(function(resolve, reject){ + document.body.innerHTML = ""; + document.body.appendChild(document.createTextNode(message)); + var input = document.createElement("input"); + input.value = defaultValue; + document.body.appendChild(input); + var button = document.createElement("button"); + button.textContent = "OK"; + button.addEventListener("click", function(){ + resolve(input.value); + message("modal prompt closed with value", input.value); + }); + document.body.appendChild(button); + }); + } + if (!tabs.length){ throw new Error("noTabsFound"); } @@ -108,10 +101,10 @@ Promise.all([ var tab = tabs[0]; browser.runtime.onMessage.addListener(function(data){ if (Array.isArray(data["canvasBlocker-notifications"])){ - log("got notifications", data); + message("got notifications"); var ul = document.getElementById("prints"); data["canvasBlocker-notifications"].forEach(function(notification){ - console.log(notification); + verbose(notification); var url = new URL(notification.url); var li = document.createElement("li"); @@ -157,17 +150,17 @@ Promise.all([ }); } }); - log("clearing the display"); + notice("clearing the display"); var ul = document.getElementById("prints"); ul.innerHTML = ""; - log("request notifications from tab", tab.id); + message("request notifications from tab", tab.id); browser.tabs.sendMessage( tab.id, { "canvasBlocker-sendNotifications": tab.id } ); - log("waiting for notifications"); + notice("waiting for notifications"); }).catch(function(e){ console.error(e); }); \ No newline at end of file