diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index ef26193..cd0fb52 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -177,6 +177,9 @@ "EnforceForTab": { "message": "Enable restrictions for this tab" }, + "HighContrast": { + "message": "High contrast appearance" + }, "httpsOnly": { "message": "Match HTTPS content only" }, diff --git a/src/_locales/it/messages.json b/src/_locales/it/messages.json index 02e1299..202bcde 100644 --- a/src/_locales/it/messages.json +++ b/src/_locales/it/messages.json @@ -176,6 +176,9 @@ "EnforceForTab": { "message": "Attiva le restrizioni per questa scheda" }, + "HighContrast": { + "message": "Aspetto ad alto contrasto" + }, "httpsOnly": { "message": "Consenti solo contenuti veicolati tramite HTTPS" }, diff --git a/src/ui/options.html b/src/ui/options.html index 0a27286..6e2ad0e 100644 --- a/src/ui/options.html +++ b/src/ui/options.html @@ -14,7 +14,7 @@ - +

diff --git a/src/ui/options.js b/src/ui/options.js index 79e6cb7..31cf5c3 100644 --- a/src/ui/options.js +++ b/src/ui/options.js @@ -8,6 +8,9 @@ let version = browser.runtime.getManifest().version; document.querySelector("#version").textContent = _("Version", version); // simple general options + + let opt = UI.wireOption; + opt("global", o => { if (o) { policy.enforced = !o.checked; @@ -30,7 +33,6 @@ }); opt("xss"); - { let button = document.querySelector("#btn-reset"); button.onclick = async () => { @@ -173,29 +175,6 @@ // UTILITY FUNCTIONS - async function opt(name, storage = "sync", onchange) { - let input = document.querySelector(`#opt-${name}`); - if (!input) { - debug("Checkbox not found %s", name); - return; - } - if (typeof storage === "function") { - input.onchange = e => storage(input); - input.checked = storage(null); - } else { - let obj = UI[storage]; - if (!obj) log(storage); - input.checked = obj[name]; - if (onchange) onchange(input.checked); - input.onchange = async () => { - obj[name] = input.checked; - await UI.updateSettings({[storage]: obj}); - if (onchange) onchange(obj[name]); - } - } - } - - function updateRawPolicyEditor() { if (!UI.local.debug) return; diff --git a/src/ui/popup.html b/src/ui/popup.html index d988429..517b233 100644 --- a/src/ui/popup.html +++ b/src/ui/popup.html @@ -12,7 +12,7 @@ - +
__MSG_Close__ @@ -30,6 +30,12 @@ __MSG_RevokeTemp__
+
+ + + + +
diff --git a/src/ui/ui-hc.css b/src/ui/ui-hc.css index fd70e2a..e1c1944 100644 --- a/src/ui/ui-hc.css +++ b/src/ui/ui-hc.css @@ -61,3 +61,7 @@ tr.site { font-size: 12px !important; font-family: arial sans-serif !important; } + +#noscript-popup #high-contrast-chooser { + display: block; +} diff --git a/src/ui/ui.css b/src/ui/ui.css index 785190a..0d86ddc 100644 --- a/src/ui/ui.css +++ b/src/ui/ui.css @@ -409,3 +409,7 @@ legend { #presets .https-only { display: none; } + +#high-contrast-chooser { + display: none; +} diff --git a/src/ui/ui.js b/src/ui/ui.js index 6538ade..f721042 100644 --- a/src/ui/ui.js +++ b/src/ui/ui.js @@ -27,10 +27,10 @@ var UI = (() => { } await include(scripts); - detectHighContrast(); + let inited = new Promise(resolve => { - let listener = m => { + let listener = async m => { if (m.type === "settings") { UI.policy = new Policy(m.policy); UI.snapshot = UI.policy.snapshot; @@ -44,6 +44,7 @@ var UI = (() => { } resolve(); if (UI.onSettings) UI.onSettings(); + await HighContrast.init(); } }; browser.runtime.onMessage.addListener(listener); @@ -98,22 +99,74 @@ var UI = (() => { async openSiteInfo(domain) { let url = `/ui/siteInfo.html#${encodeURIComponent(domain)};${UI.tabId}`; browser.tabs.create({url}); + }, + + wireOption(name, storage = "sync", onchange) { + let input = document.querySelector(`#opt-${name}`); + if (!input) { + debug("Checkbox not found %s", name); + return; + } + if (typeof storage === "function") { + input.onchange = e => storage(input); + input.checked = storage(null); + } else { + let obj = UI[storage]; + if (!obj) log(storage); + input.checked = obj[name]; + if (onchange) onchange(input.checked); + input.onchange = async () => { + obj[name] = input.checked; + await UI.updateSettings({[storage]: obj}); + if (onchange) onchange(obj[name]); + } + } + return input; + } + }; + + var HighContrast = { + css: null, + async init() { + this.widget = UI.wireOption("highContrast", "local", value => { + UI.highContrast = value; + this.toggle(); + }); + await this.toggle(); + }, + async toggle() { + let hc = "highContrast" in UI ? UI.highContrast : await this.detect(); + if (hc) { + if (this.css) { + document.documentElement.appendChild(this.css); + } else { + this.css = await include("/ui/ui-hc.css") + } + } else if (this.css) { + this.css.remove(); + } + document.documentElement.classList.toggle("hc", hc); + if (this.widget) { + this.widget.checked = hc; + } + }, + + detect() { + if ("highContrast" in UI.local) { + UI.highContrast = UI.local.highContrast; + } else { + // auto-detect + let canary = document.createElement("input"); + canary.className="https-only"; + canary.style.display = "none"; + document.body.appendChild(canary); + UI.highContrast = window.getComputedStyle(canary).backgroundImage === "none"; + canary.parentNode.removeChild(canary); + } + return UI.highContrast; } }; - function detectHighContrast() { - // detect high contrast - let canary = document.createElement("input"); - canary.className="https-only"; - canary.style.display = "none"; - document.body.appendChild(canary); - if (UI.highContrast = window.getComputedStyle(canary).backgroundImage === "none") { - include("/ui/ui-hc.css"); - document.documentElement.classList.toggle("hc"); - } - canary.parentNode.removeChild(canary); - } - function fireOnChange(sitesUI, data) { if (UI.isDirty(true)) { UI.updateSettings({policy: UI.policy});