diff --git a/canvasblocker.xpi b/canvasblocker.xpi index 38f6ce5..695cec8 100644 Binary files a/canvasblocker.xpi and b/canvasblocker.xpi differ diff --git a/data/options.css b/data/options.css index b219665..389cb42 100644 --- a/data/options.css +++ b/data/options.css @@ -13,4 +13,8 @@ setting[pref-name="showCallingFile"]{ setting[pref-name="showCompleteCallingStack"]{ border-top: 0px transparent none; padding-bottom: 0.5em; +} +setting[pref-name="stackList"]{ + border-top: 0px transparent none; + padding-bottom: 0.5em; } \ No newline at end of file diff --git a/lib/lists.js b/lib/lists.js index 296ec1b..49592f0 100644 --- a/lib/lists.js +++ b/lib/lists.js @@ -69,6 +69,32 @@ Object.keys(lists).forEach(function(type){ updateList(type); }); +function updateStackList(){ + try { + var data = JSON.parse(prefs.stackList); + if (!Array.isArray(data)){ + data = [data]; + } + var list = data.filter(function(entry){ + return typeof entry === "object" && typeof entry.url === "string"; + }); + } + catch(e){ + var list = []; + } + list.match = function(stack){ + return this.some(function(stackRule){ + return stack.match(stackRule); + }); + }; + lists.stack = list; +} +lists.stack = []; +preferences.on("stackList", function(){ + updateStackList(); +}); +updateStackList(); + exports.get = function getList(type){ "use strict"; diff --git a/lib/main.js b/lib/main.js index 505f1e7..35426b2 100644 --- a/lib/main.js +++ b/lib/main.js @@ -18,8 +18,8 @@ const preferences = require("sdk/simple-prefs"); const prefs = preferences.prefs; - function checkURL(url){ - var match = sharedFunctions.checkURL(url, prefs.blockMode).match(/^(block|allow|fake|ask)(|Readout|Everything|Context)$/); + function check(callingStack, url){ + var match = sharedFunctions.check(callingStack, url, prefs.blockMode).match(/^(block|allow|fake|ask)(|Readout|Everything|Context)$/); if (match){ return { type: (match[2] === "Everything" || match[2] === "")? @@ -53,17 +53,17 @@ enumerable: true, configureable: false, get: function(){ - var status = checkURL(window.location); + var callingStack = sharedFunctions.errorToCallingStack(new Error()); + var status = check(callingStack, window.location); if (status.type.indexOf(changedFunction.type) !== -1){ - var callingStackMsg = sharedFunctions.errorToCallingStackMsg(new Error()); if (status.mode === "ask"){ - status.mode = ask(window, changedFunction.type, this, callingStackMsg); + status.mode = ask(window, changedFunction.type, this, callingStack); } switch (status.mode){ case "allow": return original; case "fake": - notify(window, callingStackMsg); + notify(window, callingStack); return changedFunction.fake || undef; //case "block": default: diff --git a/lib/sharedFunctions.js b/lib/sharedFunctions.js index cb2cb98..945658f 100644 --- a/lib/sharedFunctions.js +++ b/lib/sharedFunctions.js @@ -23,6 +23,14 @@ var _ = function(name, replace){ return str; }; +function check(stack, url, blockMode){ + if (prefs.enableStackList && checkStack(stack)){ + return "allow"; + } + else { + return checkURL(url, blockMode); + } +} function checkURL(url, blockMode){ "use strict"; @@ -67,6 +75,11 @@ function checkURL(url, blockMode){ return mode; } +function checkStack(stack){ + "use strict"; + + return lists.get("stack").match(stack); +} // Stack parsing function parseStackEntry(entry){ @@ -75,17 +88,32 @@ function parseStackEntry(entry){ var m = /@(.*):(\d*):(\d*)$/.exec(entry) || ["", entry, "--", "--"]; return { url: m[1], - line: m[2], - column: m[3], + line: parseInt(m[2], 10), + column: parseInt(m[3], 10), raw: entry }; } +function stackRuleMatch(stackEntry, stackRule){ + if (!stackEntry){ + return false; + } + if (stackEntry.url !== stackRule.url){ + return false; + } + if ((typeof stackRule.line) !== "undefined" && stackEntry.line !== stackRule.line){ + return false; + } + if ((typeof stackRule.column) !== "undefined" && stackEntry.column !== stackRule.column){ + return false; + } + return true; +} + // parse calling stack -function errorToCallingStackMsg(error){ +function errorToCallingStack(error){ "use strict"; - var msg = ""; var callers = error.stack.trim().split("\n"); //console.log(callers); var findme = callers.shift(); // Remove us from the stack @@ -96,20 +124,39 @@ function errorToCallingStackMsg(error){ var doubleStackStart = caller.search(findme) !== -1; inDoubleStack = inDoubleStack || doubleStackStart; return !inDoubleStack; - }); - msg += "\n\n" + _("sourceOutput") + ": "; - if (prefs.showCompleteCallingStack){ - msg += callers.reduce(function(stack, c){ - return stack + "\n\t" + _("stackEntryOutput", parseStackEntry(c)); - }, ""); - } - else{ - msg += _("stackEntryOutput", parseStackEntry(callers[0])); - } - - return msg; + }).map(parseStackEntry); + return { + toString: function(){ + var msg = ""; + msg += "\n\n" + _("sourceOutput") + ": "; + if (prefs.showCompleteCallingStack){ + msg += callers.reduce(function(stack, c){ + return stack + "\n\t" + _("stackEntryOutput", c); + }, ""); + } + else{ + msg += _("stackEntryOutput", callers[0]); + } + + return msg; + }, + match: function(stackRule){ + if (typeof stackRule.stackPosition !== "undefined"){ + var pos = stackRule.stackPosition; + if (pos < 0){ + pos += callers.length; + } + return stackRuleMatch(callers[pos], stackRule); + } + else { + return callers.some(function(stackEntry){ + return stackRuleMatch(stackEntry, stackRule); + }); + } + } + }; } -exports.checkURL = checkURL; +exports.check = check; exports.parseStackEntry = parseStackEntry; -exports.errorToCallingStackMsg = errorToCallingStackMsg; \ No newline at end of file +exports.errorToCallingStack = errorToCallingStack; \ No newline at end of file diff --git a/package.json b/package.json index 7f1cd9c..c68cf64 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,17 @@ "title": "Display complete calling stack", "type": "bool", "value": false + },{ + "name": "enableStackList", + "title": "Use script scoped white list", + "type": "bool", + "value": false + }, + { + "name": "stackList", + "title": "Script scoped white list", + "type": "string", + "value": "" } ], "main": "lib/main.js",