diff options
author | hackademix | 2018-10-06 01:16:25 +0200 |
---|---|---|
committer | hackademix | 2018-10-06 02:11:49 +0200 |
commit | 55ccd14dfe85351d722ed1de5966426d7b54c523 (patch) | |
tree | b3b8e7df761799c8c131772d26908a817db84041 /src | |
parent | ddbd70416c1a0f54ad11e0ea71693e91b965639e (diff) | |
download | noscript-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.js | 11 | ||||
-rw-r--r-- | src/ui/ui.css | 4 | ||||
-rw-r--r-- | src/ui/ui.js | 82 |
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)) { |