From 6c46d285939f42ba95866ab3ae5fda7930ce34b8 Mon Sep 17 00:00:00 2001 From: kkapsner Date: Tue, 8 Sep 2015 11:41:33 +0200 Subject: [PATCH] Reintroduced ask modes. --- lib/askForPermission.js | 120 ++++++++++++++++++++++++++++++++++++++++ lib/main.js | 8 ++- package.json | 46 +++++++++++++-- 3 files changed, 168 insertions(+), 6 deletions(-) create mode 100644 lib/askForPermission.js diff --git a/lib/askForPermission.js b/lib/askForPermission.js new file mode 100644 index 0000000..248cbed --- /dev/null +++ b/lib/askForPermission.js @@ -0,0 +1,120 @@ +/* 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"; + + const _ = require("sdk/l10n").get; + const preferences = require("sdk/simple-prefs"); + const prefs = preferences.prefs; + + // Check canvas appearance + function canvasAppearance(window, context){ + var oldBorder = false; + var canvas = false; + var inDOM = null; + if (context){ + if (context.nodeName === "CANVAS"){ + canvas = context; + } + else if ( + context instanceof window.CanvasRenderingContext2D || + context instanceof window.WebGLRenderingContext + ){ + canvas = context.canvas; + } + } + if (canvas){ + oldBorder = canvas.style.border; + canvas.style.border = "2px solid red"; + inDOM = canvas.ownerDocument.contains(canvas); + } + return { + canvas: canvas, + askCategory: canvas? (inDOM? "visible": "invisible"): "nocanvas", + get text(){ + var text = canvas? (this.visible? "visible": "invisible"): "nocanvas"; + Object.defineProperty(this, "text", {value: text}); + return text; + }, + inDom: inDOM, + get visible(){ + var visible = inDOM; + if (inDOM){ + canvas.scrollIntoView(); + var rect = canvas.getBoundingClientRect(); + var foundEl = window.document.elementFromPoint(rect.left + rect.width / 2, rect.top + rect.height / 2); + visible = (foundEl === canvas); + } + Object.defineProperty(this, "visible", {value: visible}); + return visible; + }, + reset: function(){ + if (canvas){ + canvas.style.border = oldBorder; + } + } + }; + } + + var modes = new WeakMap(); + function getAskMode(window, type){ + var mode = modes.get(window); + if (mode){ + return mode[type]; + } + else { + mode = { + context: { + askText: { + visible: _("askForVisiblePermission"), + invisible: _("askForInvisiblePermission"), + nocanvas: _("askForPermission") + }, + askStatus: { + alreadyAsked: {}, + answer: {} + } + }, + readout: { + askText: { + visible: _("askForVisibleReadoutPermission"), + invisible: _("askForInvisibleReadoutPermission"), + nocanvas: _("askForReadoutPermission") + }, + askStatus: { + alreadyAsked: {}, + answer: {} + } + } + }; + modes.set(window, mode); + return mode[type]; + } + } + + exports.ask = function(window, type, canvas, callingStackMsg){ + var answer; + var askMode = getAskMode(window, type); + var askStatus = askMode.askStatus; + var appearance = canvasAppearance(window, canvas); + if (prefs.askOnlyOnce && askStatus.alreadyAsked[appearance.askCategory]){ + // already asked + appearance.reset(); + return askStatus.answer[appearance.askCategory]; + } + else { + // asking + var msg = _(askMode.askText[appearance.text]); + if (prefs.showCallingFile){ + msg += callingStackMsg; + } + answer = window.confirm(msg)? "allow": "block"; + askStatus.alreadyAsked[appearance.text] = true; + askStatus.answer[appearance.text] = answer; + appearance.reset(); + return answer; + } + }; +}()); \ No newline at end of file diff --git a/lib/main.js b/lib/main.js index 1b700e3..505f1e7 100644 --- a/lib/main.js +++ b/lib/main.js @@ -1,4 +1,4 @@ -/* global console */ +/* 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/. */ @@ -7,6 +7,7 @@ require("./stylePreferencePane"); const {changedFunctions} = require("./modifiedAPI"); const {notify} = require("./notifications"); + const {ask} = require("./askForPermission"); const lists = require("./lists"); const sharedFunctions = require("./sharedFunctions"); @@ -18,7 +19,7 @@ const prefs = preferences.prefs; function checkURL(url){ - var match = sharedFunctions.checkURL(url, prefs.blockMode).match(/^(block|allow|fake)(|Readout|Everything|Context)$/); + var match = sharedFunctions.checkURL(url, prefs.blockMode).match(/^(block|allow|fake|ask)(|Readout|Everything|Context)$/); if (match){ return { type: (match[2] === "Everything" || match[2] === "")? @@ -55,6 +56,9 @@ var status = checkURL(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); + } switch (status.mode){ case "allow": return original; diff --git a/package.json b/package.json index ca2c601..50846de 100644 --- a/package.json +++ b/package.json @@ -22,10 +22,6 @@ "type": "menulist", "value": "fakeReadout", "options": [ - { - "value": "blockEverything", - "label": "block everything" - }, { "value": "blockReadout", "label": "block readout API" @@ -34,12 +30,42 @@ "value": "fakeReadout", "label": "fake readout API" }, + { + "value": "askReadout", + "label": "ask for readout API permission" + }, + { + "value": "", + "label": "" + }, + { + "value": "blockEverything", + "label": "block everything" + }, + { + "value": "block", + "label": "allow only white list" + }, + { + "value": "ask", + "label": "ask for permission" + }, + { + "value": "allow", + "label": "block only black list" + }, { "value": "allowEverything", "label": "allow everything" } ] }, + { + "name": "askOnlyOnce", + "title": "Ask only once", + "type": "bool", + "value": true + }, { "name": "showNotifications", "title": "Show notifications", @@ -51,6 +77,18 @@ "title": "Ignore list", "type": "string", "value": "" + }, + { + "name": "showCallingFile", + "title": "Display calling file", + "type": "bool", + "value": false + }, + { + "name": "showCompleteCallingStack", + "title": "Display complete calling stack", + "type": "bool", + "value": false } ], "main": "lib/main.js",