From 6eb5a95705f0db3060ab7ba0c86870344f3c2ebc Mon Sep 17 00:00:00 2001 From: relrelb Date: Tue, 9 Mar 2021 21:51:03 +0200 Subject: [PATCH] web: Add common.js --- web/packages/extension/js/common.js | 69 +++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 web/packages/extension/js/common.js diff --git a/web/packages/extension/js/common.js b/web/packages/extension/js/common.js new file mode 100644 index 000000000..a7de9aa3d --- /dev/null +++ b/web/packages/extension/js/common.js @@ -0,0 +1,69 @@ +import * as utils from "./utils"; + +function camelize(string) { + return string.replace(/[^a-z\d](.)/gi, (_, char) => char.toUpperCase()); +} + +function getBooleanElements() { + const elements = {}; + for (const option of document.getElementsByClassName("option")) { + const [checkbox] = option.getElementsByTagName("input"); + if (checkbox.type !== "checkbox") { + continue; + } + const [label] = option.getElementsByTagName("label"); + const key = camelize(checkbox.id); + elements[key] = { option, checkbox, label }; + } + return elements; +} + +export async function bindBooleanOptions(onChange) { + const elements = getBooleanElements(); + + // Bind initial values. + const options = await utils.getOptions(Object.keys(elements)); + for (const [key, value] of Object.entries(options)) { + elements[key].checkbox.checked = value; + } + + for (const [key, { checkbox, label }] of Object.entries(elements)) { + // TODO: click/change/input? + checkbox.addEventListener("click", () => { + const value = checkbox.checked; + options[key] = value; + utils.storage.sync.set({ [key]: value }); + }); + + label.textContent = utils.i18n.getMessage(`settings_${checkbox.id}`); + + // Prevent transition on load. + // Method from https://stackoverflow.com/questions/11131875. + label.classList.add("notransition"); + label.offsetHeight; // Trigger a reflow, flushing the CSS changes. + label.classList.remove("notransition"); + } + + // Listen for future changes. + utils.storage.onChanged.addListener((changes, namespace) => { + if (namespace !== "sync") { + return; + } + + for (const [key, option] of Object.entries(changes)) { + if (!elements[key]) { + continue; + } + elements[key].checkbox.checked = option.newValue; + options[key] = option.newValue; + } + + if (onChange) { + onChange(options); + } + }); + + if (onChange) { + onChange(options); + } +}