summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhackademix2018-10-06 01:16:25 +0200
committerhackademix2018-10-06 02:11:49 +0200
commit55ccd14dfe85351d722ed1de5966426d7b54c523 (patch)
treeb3b8e7df761799c8c131772d26908a817db84041 /src
parentddbd70416c1a0f54ad11e0ea71693e91b965639e (diff)
downloadnoscript-55ccd14dfe85351d722ed1de5966426d7b54c523.tar.gz
noscript-55ccd14dfe85351d722ed1de5966426d7b54c523.tar.xz
noscript-55ccd14dfe85351d722ed1de5966426d7b54c523.zip
Better UX for overriding protocol-level permissions.
Diffstat (limited to 'src')
-rw-r--r--src/ui/popup.js11
-rw-r--r--src/ui/ui.css4
-rw-r--r--src/ui/ui.js82
3 files changed, 73 insertions, 24 deletions
diff --git a/src/ui/popup.js b/src/ui/popup.js
index aed981b..1f79b55 100644
--- a/src/ui/popup.js
+++ b/src/ui/popup.js
@@ -175,11 +175,17 @@ addEventListener("unload", e => {
typesMap.clear();
let policySites = UI.policy.sites;
let domains = new Map();
-
+ let protocols = new Set();
function urlToLabel(url) {
let origin = Sites.origin(url);
let match = policySites.match(url);
- if (match) return match;
+ if (match) {
+ if (match === url.protocol) {
+ protocols.add(match);
+ } else {
+ return match;
+ }
+ }
if (domains.has(origin)) {
if (justDomains) return domains.get(origin);
} else {
@@ -207,6 +213,7 @@ addEventListener("unload", e => {
if (!justDomains) {
for (let domain of domains.values()) sitesSet.add(domain);
}
+ for (let protocol of protocols) sitesSet.add(protocol);
let sites = [...sitesSet];
for (let parsed of parsedSeen) {
sites.filter(s => parsed.label === s || domains.get(Sites.origin(parsed.url)) === s).forEach(m => {
diff --git a/src/ui/ui.css b/src/ui/ui.css
index 0d86ddc..f59646a 100644
--- a/src/ui/ui.css
+++ b/src/ui/ui.css
@@ -155,6 +155,10 @@ label.https-only {
display: none;
}
+.preset label.preset.override {
+ color: #555;
+}
+
[data-preset="UNTRUSTED"] .https-only, [data-preset="DEFAULT"] .https-only {
visibility: hidden;
}
diff --git a/src/ui/ui.js b/src/ui/ui.js
index 4a9c7c8..73f1dc5 100644
--- a/src/ui/ui.js
+++ b/src/ui/ui.js
@@ -174,6 +174,13 @@ var UI = (() => {
function compareBy(prop, a, b) {
let x = a[prop], y = b[prop];
+ if (x.endsWith(":")) {
+ if (!y.endsWith(":")) {
+ return this.mainDomain ? 1 : -1;
+ }
+ } else if (y.endsWith(":")) {
+ return this.mainDomain ? -1 : 1;
+ }
return x > y ? 1 : x < y ? -1 : 0;
}
@@ -542,10 +549,10 @@ var UI = (() => {
} else if (y === md) {
return 1;
}
- return wrappedCompare(a, b);
+ return wrappedCompare.call(this, a, b);
}
}
- let rows = [...this.allSiteRows()].sort(sorter);
+ let rows = [...this.allSiteRows()].sort(sorter.bind(this));
if (this.mainSite) {
let mainLabel = "." + this.mainDomain;
let topIdx = rows.findIndex(r => r._label === mainLabel);
@@ -563,7 +570,8 @@ var UI = (() => {
}
sorter(a, b) {
- return compareBy("domain", a, b) || compareBy("_label", a, b);
+ let cb = compareBy.bind(this);
+ return cb("domain", a, b) || cb("_label", a, b);
}
async tempTrustAll() {
@@ -583,28 +591,36 @@ var UI = (() => {
createSiteRow(site, siteMatch, perms, contextMatch = null, sitesCount = this.sitesCount++) {
debug("Creating row for site: %s, matching %s / %s, %o", site, siteMatch, contextMatch, perms);
-
+ let policy = UI.policy;
let row = this.rowTemplate.cloneNode(true);
row.sitesCount = sitesCount;
let url;
try {
url = new URL(site);
+ if (siteMatch !== site && siteMatch === url.protocol) {
+ perms = policy.DEFAULT;
+ }
} catch (e) {
if (/^(\w+:)\/*$/.test(site)) {
- url = {protocol: RegExp.$1, hostname: "", origin: site, pathname:""};
- let hostname = Sites.toExternal(url.hostname);
- debug("Lonely %o", url, Sites.isSecureDomainKey(siteMatch) || !hostname && url.protocol === "https:");
+ let hostname = "";
+ url = {protocol: RegExp.$1, hostname, origin: site, pathname:""};
+ debug("Lonely %o", url);
} else {
+ debug("Domain %s (%s)", site, siteMatch);
let protocol = Sites.isSecureDomainKey(site) ? "https:" : "http:";
let hostname = Sites.toggleSecureDomainKey(site, false);
- url = {protocol, hostname, origin: `${protocol}://${site}`, pathname: "/"};
+ url = {protocol, hostname, origin: `${protocol}//${site}`, pathname: "/"};
}
}
let hostname = Sites.toExternal(url.hostname);
- let domain = tld.getDomain(hostname);
+ let overrideDefault = url.protocol && site !== url.protocol ?
+ policy.get(url.protocol, contextMatch) : null;
+ if (overrideDefault && !overrideDefault.siteMatch) overrideDefault = null;
- if (!siteMatch) {
+ let domain = tld.getDomain(hostname);
+ let disableDefault = false;
+ if (!siteMatch || siteMatch === url.protocol && site !== siteMatch) {
siteMatch = site;
}
let secure = Sites.isSecureDomainKey(siteMatch);
@@ -654,23 +670,45 @@ var UI = (() => {
label.setAttribute("for", temp.id);
}
}
- let policy = UI.policy;
- let presetName = "CUSTOM";
- for (let p of ["TRUSTED", "UNTRUSTED", "DEFAULT"]) {
- let preset = policy[p];
- switch (perms) {
- case preset:
- presetName = p;
- break;
- case preset.tempTwin:
- presetName = `T_${p}`;
- if (!presetName in UI.presets) {
+ let getPresetName = perms => {
+ let presetName = "CUSTOM";
+ for (let p of ["TRUSTED", "UNTRUSTED", "DEFAULT"]) {
+ let preset = policy[p];
+ switch (perms) {
+ case preset:
presetName = p;
+ break;
+ case preset.tempTwin:
+ presetName = `T_${p}`;
+ if (!presetName in UI.presets) {
+ presetName = p;
+ }
+ break;
+ }
+ }
+ return presetName;
+ }
+
+ let presetName = getPresetName(perms);
+ if (overrideDefault) {
+ let overrideName = getPresetName(overrideDefault.perms);
+ if (overrideName) {
+ let override = row.querySelector(`.presets input[value="${overrideName}"]`);
+ if (override) {
+ let def = row.querySelector(`.presets input[value="DEFAULT"]`);
+ if (def && def !== override) {
+ let label = def.nextElementSibling;
+ label.title = def.title = `${override.title} (${overrideDefault.siteMatch})`;
+ label.textContent = override.nextElementSibling.textContent + "*";
+ label.classList.toggle("override", true);
+ def.dataset.override = overrideName;
+ def.style.backgroundImage = window.getComputedStyle(override, null).backgroundImage;
}
- break;
}
+ }
}
+
let tempFirst = true; // TODO: make it a preference
let unsafeMatch = keyStyle !== "secure" && keyStyle !== "full";
if (presetName === "DEFAULT" && (tempFirst || unsafeMatch)) {