summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/_locales/en/messages.json3
-rw-r--r--src/_locales/it/messages.json3
-rw-r--r--src/ui/options.html8
-rw-r--r--src/ui/options.js27
-rw-r--r--src/ui/popup.html8
-rw-r--r--src/ui/ui-hc.css4
-rw-r--r--src/ui/ui.css4
-rw-r--r--src/ui/ui.js83
8 files changed, 99 insertions, 41 deletions
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 @@
<script src="/common/locale.js"></script>
<script src="/ui/ui.js"></script>
</head>
-<body>
+<body id="noscript-options">
<div id="header">
<h1>__MSG_OptionsLong__</h1>
<div>
@@ -89,6 +89,12 @@
<label for="opt-showFullAddresses" id="lbl-showFullAddresses">__MSG_ShowFullAddresses__</label>
</span>
</div>
+ <div class="opt-group">
+ <span id="highContrast-opt">
+ <input type="checkbox" id="opt-highContrast">
+ <label for="opt-highContrast" id="lbl-highContrast">__MSG_HighContrast__</label>
+ </span>
+ </div>
</div>
<h3 class="flextabs__tab"><button class="flextabs__toggle">__MSG_SectionAdvanced__</button></h3>
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 @@
<script src="/ui/ui.js"></script>
</head>
-<body>
+<body id="noscript-popup">
<div id="main">
<div id="top">
<a aria-role="button" id="close" class="close icon">__MSG_Close__</a>
@@ -30,6 +30,12 @@
<a aria-role="button" id="revoke-temp" class="toggle icon">__MSG_RevokeTemp__</a>
</div>
<div id="message" class="hidden"></div>
+<div id="high-contrast-chooser" class="opt-group">
+ <span id="highContrast-opt">
+ <input type="checkbox" id="opt-highContrast">
+ <label for="opt-highContrast" id="lbl-highContrast">__MSG_HighContrast__</label>
+ </span>
+</div>
<div id="content"></div>
<div id="sites"></div>
<div id="buttons">
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,21 +99,73 @@ 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;
+ }
};
-
- 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");
+
+ 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;
}
- canary.parentNode.removeChild(canary);
- }
+ };
function fireOnChange(sitesUI, data) {
if (UI.isDirty(true)) {