Better UX for overriding protocol-level permissions.
This commit is contained in:
parent
ddbd70416c
commit
55ccd14dfe
|
@ -175,11 +175,17 @@ addEventListener("unload", e => {
|
||||||
typesMap.clear();
|
typesMap.clear();
|
||||||
let policySites = UI.policy.sites;
|
let policySites = UI.policy.sites;
|
||||||
let domains = new Map();
|
let domains = new Map();
|
||||||
|
let protocols = new Set();
|
||||||
function urlToLabel(url) {
|
function urlToLabel(url) {
|
||||||
let origin = Sites.origin(url);
|
let origin = Sites.origin(url);
|
||||||
let match = policySites.match(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 (domains.has(origin)) {
|
||||||
if (justDomains) return domains.get(origin);
|
if (justDomains) return domains.get(origin);
|
||||||
} else {
|
} else {
|
||||||
|
@ -207,6 +213,7 @@ addEventListener("unload", e => {
|
||||||
if (!justDomains) {
|
if (!justDomains) {
|
||||||
for (let domain of domains.values()) sitesSet.add(domain);
|
for (let domain of domains.values()) sitesSet.add(domain);
|
||||||
}
|
}
|
||||||
|
for (let protocol of protocols) sitesSet.add(protocol);
|
||||||
let sites = [...sitesSet];
|
let sites = [...sitesSet];
|
||||||
for (let parsed of parsedSeen) {
|
for (let parsed of parsedSeen) {
|
||||||
sites.filter(s => parsed.label === s || domains.get(Sites.origin(parsed.url)) === s).forEach(m => {
|
sites.filter(s => parsed.label === s || domains.get(Sites.origin(parsed.url)) === s).forEach(m => {
|
||||||
|
|
|
@ -155,6 +155,10 @@ label.https-only {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preset label.preset.override {
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
[data-preset="UNTRUSTED"] .https-only, [data-preset="DEFAULT"] .https-only {
|
[data-preset="UNTRUSTED"] .https-only, [data-preset="DEFAULT"] .https-only {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
60
src/ui/ui.js
60
src/ui/ui.js
|
@ -174,6 +174,13 @@ var UI = (() => {
|
||||||
|
|
||||||
function compareBy(prop, a, b) {
|
function compareBy(prop, a, b) {
|
||||||
let x = a[prop], y = b[prop];
|
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;
|
return x > y ? 1 : x < y ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,10 +549,10 @@ var UI = (() => {
|
||||||
} else if (y === md) {
|
} else if (y === md) {
|
||||||
return 1;
|
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) {
|
if (this.mainSite) {
|
||||||
let mainLabel = "." + this.mainDomain;
|
let mainLabel = "." + this.mainDomain;
|
||||||
let topIdx = rows.findIndex(r => r._label === mainLabel);
|
let topIdx = rows.findIndex(r => r._label === mainLabel);
|
||||||
|
@ -563,7 +570,8 @@ var UI = (() => {
|
||||||
}
|
}
|
||||||
|
|
||||||
sorter(a, b) {
|
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() {
|
async tempTrustAll() {
|
||||||
|
@ -583,28 +591,36 @@ var UI = (() => {
|
||||||
|
|
||||||
createSiteRow(site, siteMatch, perms, contextMatch = null, sitesCount = this.sitesCount++) {
|
createSiteRow(site, siteMatch, perms, contextMatch = null, sitesCount = this.sitesCount++) {
|
||||||
debug("Creating row for site: %s, matching %s / %s, %o", site, siteMatch, contextMatch, perms);
|
debug("Creating row for site: %s, matching %s / %s, %o", site, siteMatch, contextMatch, perms);
|
||||||
|
let policy = UI.policy;
|
||||||
let row = this.rowTemplate.cloneNode(true);
|
let row = this.rowTemplate.cloneNode(true);
|
||||||
row.sitesCount = sitesCount;
|
row.sitesCount = sitesCount;
|
||||||
let url;
|
let url;
|
||||||
try {
|
try {
|
||||||
url = new URL(site);
|
url = new URL(site);
|
||||||
|
if (siteMatch !== site && siteMatch === url.protocol) {
|
||||||
|
perms = policy.DEFAULT;
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (/^(\w+:)\/*$/.test(site)) {
|
if (/^(\w+:)\/*$/.test(site)) {
|
||||||
url = {protocol: RegExp.$1, hostname: "", origin: site, pathname:""};
|
let hostname = "";
|
||||||
let hostname = Sites.toExternal(url.hostname);
|
url = {protocol: RegExp.$1, hostname, origin: site, pathname:""};
|
||||||
debug("Lonely %o", url, Sites.isSecureDomainKey(siteMatch) || !hostname && url.protocol === "https:");
|
debug("Lonely %o", url);
|
||||||
} else {
|
} else {
|
||||||
|
debug("Domain %s (%s)", site, siteMatch);
|
||||||
let protocol = Sites.isSecureDomainKey(site) ? "https:" : "http:";
|
let protocol = Sites.isSecureDomainKey(site) ? "https:" : "http:";
|
||||||
let hostname = Sites.toggleSecureDomainKey(site, false);
|
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 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;
|
siteMatch = site;
|
||||||
}
|
}
|
||||||
let secure = Sites.isSecureDomainKey(siteMatch);
|
let secure = Sites.isSecureDomainKey(siteMatch);
|
||||||
|
@ -654,8 +670,8 @@ var UI = (() => {
|
||||||
label.setAttribute("for", temp.id);
|
label.setAttribute("for", temp.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let policy = UI.policy;
|
|
||||||
|
|
||||||
|
let getPresetName = perms => {
|
||||||
let presetName = "CUSTOM";
|
let presetName = "CUSTOM";
|
||||||
for (let p of ["TRUSTED", "UNTRUSTED", "DEFAULT"]) {
|
for (let p of ["TRUSTED", "UNTRUSTED", "DEFAULT"]) {
|
||||||
let preset = policy[p];
|
let preset = policy[p];
|
||||||
|
@ -671,6 +687,28 @@ var UI = (() => {
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let tempFirst = true; // TODO: make it a preference
|
let tempFirst = true; // TODO: make it a preference
|
||||||
let unsafeMatch = keyStyle !== "secure" && keyStyle !== "full";
|
let unsafeMatch = keyStyle !== "secure" && keyStyle !== "full";
|
||||||
if (presetName === "DEFAULT" && (tempFirst || unsafeMatch)) {
|
if (presetName === "DEFAULT" && (tempFirst || unsafeMatch)) {
|
||||||
|
|
Loading…
Reference in New Issue