speed up setupLivePrefs
This commit is contained in:
parent
b7cfbe6e66
commit
adef93c3ed
38
js/dom.js
38
js/dom.js
|
@ -304,28 +304,17 @@ function scrollElementIntoView(element, {invalidMarginRatio = 0} = {}) {
|
||||||
* Accepts an array of pref names (values are fetched via prefs.get)
|
* Accepts an array of pref names (values are fetched via prefs.get)
|
||||||
* and establishes a two-way connection between the document elements and the actual prefs
|
* and establishes a two-way connection between the document elements and the actual prefs
|
||||||
*/
|
*/
|
||||||
function setupLivePrefs(ids = prefs.knownKeys.filter(id => $(`#${CSS.escape(id)}, [name=${CSS.escape(id)}]`))) {
|
function setupLivePrefs(ids) {
|
||||||
let forceUpdate = true;
|
let forceUpdate = true;
|
||||||
|
// getElementsByTagName is cached so it's much faster than calling querySelector for each id
|
||||||
|
ids = ids ? [...ids] : prefs.knownKeys.filter(id => id in document.getElementsByTagName('*'));
|
||||||
prefs.subscribe(ids, updateElement, {runNow: true});
|
prefs.subscribe(ids, updateElement, {runNow: true});
|
||||||
forceUpdate = false;
|
forceUpdate = false;
|
||||||
|
|
||||||
for (const id of ids) {
|
|
||||||
const elements = $$(`#${CSS.escape(id)}, [name=${CSS.escape(id)}]`);
|
|
||||||
for (const element of elements) {
|
|
||||||
element.addEventListener('change', onChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChange() {
|
function onChange() {
|
||||||
if (!this.checkValidity()) {
|
if (this.checkValidity() && (this.type !== 'radio' || this.checked)) {
|
||||||
return;
|
prefs.set(this.id || this.name, getValue(this));
|
||||||
}
|
}
|
||||||
if (this.type === 'radio' && !this.checked) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
prefs.set(this.id || this.name, getValue(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getValue(el) {
|
function getValue(el) {
|
||||||
const type = el.dataset.valueType || el.type;
|
const type = el.dataset.valueType || el.type;
|
||||||
return type === 'checkbox' ? el.checked :
|
return type === 'checkbox' ? el.checked :
|
||||||
|
@ -334,20 +323,16 @@ function setupLivePrefs(ids = prefs.knownKeys.filter(id => $(`#${CSS.escape(id)}
|
||||||
type === 'number' ? Number(el.value) :
|
type === 'number' ? Number(el.value) :
|
||||||
el.value;
|
el.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSame(el, oldValue, value) {
|
function isSame(el, oldValue, value) {
|
||||||
return oldValue === value ||
|
return el.type === 'radio' ? el.checked === (oldValue === value) :
|
||||||
typeof value === 'boolean' &&
|
el.localName === 'select' && typeof value === 'boolean' && oldValue === `${value}` ||
|
||||||
el.tagName === 'SELECT' &&
|
oldValue === value;
|
||||||
oldValue === `${value}` ||
|
|
||||||
el.type === 'radio' && (oldValue === value) === el.checked;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateElement(id, value) {
|
function updateElement(id, value) {
|
||||||
const els = $$(`#${CSS.escape(id)}, [name=${CSS.escape(id)}]`);
|
const byId = document.getElementById(id);
|
||||||
|
const els = byId ? [byId] : document.getElementsByName(id);
|
||||||
if (!els.length) {
|
if (!els.length) {
|
||||||
// FIXME: why do we unsub all ids when a single id is missing from the page
|
prefs.unsubscribe(id, updateElement);
|
||||||
prefs.unsubscribe(ids, updateElement);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const el of els) {
|
for (const el of els) {
|
||||||
|
@ -361,6 +346,7 @@ function setupLivePrefs(ids = prefs.knownKeys.filter(id => $(`#${CSS.escape(id)}
|
||||||
el.value = value;
|
el.value = value;
|
||||||
}
|
}
|
||||||
el.dispatchEvent(new Event('change', {bubbles: true}));
|
el.dispatchEvent(new Event('change', {bubbles: true}));
|
||||||
|
if (forceUpdate) el.on('change', onChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user