diff --git a/js/dom.js b/js/dom.js index f3785cbc..a2601fc1 100644 --- a/js/dom.js +++ b/js/dom.js @@ -299,7 +299,6 @@ function setupLivePrefs(ids = prefs.knownKeys.filter(id => $(`#${CSS.escape(id)} for (const id of ids) { const elements = $$(`#${CSS.escape(id)}, [name=${CSS.escape(id)}]`); for (const element of elements) { - updateElement({id, elements: [element], force: true}); element.addEventListener('change', onChange); } } @@ -311,33 +310,45 @@ function setupLivePrefs(ids = prefs.knownKeys.filter(id => $(`#${CSS.escape(id)} if (this.type === 'radio' && !this.checked) { return; } - prefs.set(this.id || this.name, this[getPropName(this)]); + prefs.set(this.id || this.name, getValue(this)); } - function getPropName(el) { + function getValue(el) { const type = el.dataset.valueType || el.type; - return type === 'checkbox' ? 'checked' - : type === 'number' ? 'valueAsNumber' : - 'value'; + return type === 'checkbox' ? el.checked : + // https://stackoverflow.com/questions/18062069/why-does-valueasnumber-return-nan-as-a-value + // valueAsNumber is not applicable for input[text/radio] or select + type === 'number' ? Number(el.value) : + el.value; } - function isSame(el, propName, value) { - return el[propName] === value || + function isSame(el, oldValue, value) { + return oldValue === value || typeof value === 'boolean' && el.tagName === 'SELECT' && - el[propName] === `${value}`; + oldValue === `${value}` || + el.type === 'radio' && (oldValue === value) === el.checked; } function updateElement(id, value) { - const el = $('#' + id); - if (el) { - const prop = getPropName(el); - if (!isSame(el, prop, value) || forceUpdate) { - el[prop] = value; + const els = $$(`#${CSS.escape(id)}, [name=${CSS.escape(id)}]`); + if (!els.length) { + // FIXME: why do we unsub all ids when a single id is missing from the page + prefs.unsubscribe(ids, updateElement); + return; + } + for (const el of els) { + const oldValue = getValue(el); + if (!isSame(el, oldValue, value) || forceUpdate) { + if (el.type === 'radio') { + el.checked = value === oldValue; + } else if (el.type === 'checkbox') { + el.checked = value; + } else { + el.value = value; + } el.dispatchEvent(new Event('change', {bubbles: true})); } - } else { - prefs.unsubscribe(ids, updateElement); } } } diff --git a/options.html b/options.html index 72b1d291..a6170f82 100644 --- a/options.html +++ b/options.html @@ -61,7 +61,7 @@