Change: move setupLivePrefs to dom.js. Remove prefs.js dependencies

This commit is contained in:
eight 2018-10-04 17:46:45 +08:00
parent dd2b8ed091
commit 10f9449144
2 changed files with 71 additions and 57 deletions

View File

@ -392,3 +392,55 @@ function moveFocus(rootElement, step) {
}
}
}
// 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
function setupLivePrefs(
IDs = Object.getOwnPropertyNames(prefs.defaults)
.filter(id => $('#' + id))
) {
for (const id of IDs) {
const element = $('#' + id);
updateElement({id, element, force: true});
element.addEventListener('change', onChange);
}
prefs.subscribe(IDs, (id, value) => updateElement({id, value}));
function onChange() {
const value = getInputValue(this);
if (prefs.get(this.id) !== value) {
prefs.set(this.id, value);
}
}
function updateElement({
id,
value = prefs.get(id),
element = $('#' + id),
force,
}) {
if (!element) {
prefs.unsubscribe(IDs, updateElement);
return;
}
setInputValue(element, value, force);
}
function getInputValue(input) {
if (input.type === 'checkbox') {
return input.checked;
}
if (input.type === 'number') {
return Number(input.value);
}
return input.value;
}
function setInputValue(input, value, force = false) {
if (force || getInputValue(input) !== value) {
if (input.type === 'checkbox') {
input.checked = value;
} else {
input.value = value;
}
input.dispatchEvent(new Event('change', {bubbles: true, cancelable: true}));
}
}
}

View File

@ -113,6 +113,8 @@ var prefs = (() => {
initializing.then(() => setAll(changes.settings.newValue, true));
});
let timer;
// coalesce multiple pref changes in broadcast
// let changes = {};
@ -217,11 +219,10 @@ var prefs = (() => {
}
values[key] = value;
emitChange(key, value);
if (synced) {
if (synced || timer) {
return;
}
// changes[key] = value;
debounce(syncPrefs);
timer = setTimeout(syncPrefs);
}
function emitChange(key, value) {
@ -241,6 +242,7 @@ var prefs = (() => {
function syncPrefs() {
// FIXME: we always set the entire object? Ideally, this should only use `changes`.
chrome.storage.sync.set({settings: values});
timer = null;
}
function equal(a, b) {
@ -263,7 +265,7 @@ var prefs = (() => {
}
function contextDeleteMissing() {
return CHROME && (
return /Chrome\/\d+/.test(navigator.userAgent) && (
// detect browsers without Delete by looking at the end of UA string
/Vivaldi\/[\d.]+$/.test(navigator.userAgent) ||
// Chrome and co.
@ -272,57 +274,17 @@ var prefs = (() => {
!Array.from(navigator.plugins).some(p => p.name === 'Shockwave Flash')
);
}
function deepCopy(obj) {
if (!obj || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
return obj.map(deepCopy);
}
return Object.keys(obj).reduce((output, key) => {
output[key] = deepCopy(obj[key]);
return output;
}, {});
}
})();
// 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
function setupLivePrefs(
IDs = Object.getOwnPropertyNames(prefs.defaults)
.filter(id => $('#' + id))
) {
for (const id of IDs) {
const element = $('#' + id);
updateElement({id, element, force: true});
element.addEventListener('change', onChange);
}
prefs.subscribe(IDs, (id, value) => updateElement({id, value}));
function onChange() {
const value = getInputValue(this);
if (prefs.get(this.id) !== value) {
prefs.set(this.id, value);
}
}
function updateElement({
id,
value = prefs.get(id),
element = $('#' + id),
force,
}) {
if (!element) {
prefs.unsubscribe(IDs, updateElement);
return;
}
setInputValue(element, value, force);
}
function getInputValue(input) {
if (input.type === 'checkbox') {
return input.checked;
}
if (input.type === 'number') {
return Number(input.value);
}
return input.value;
}
function setInputValue(input, value, force = false) {
if (force || getInputValue(input) !== value) {
if (input.type === 'checkbox') {
input.checked = value;
} else {
input.value = value;
}
input.dispatchEvent(new Event('change', {bubbles: true, cancelable: true}));
}
}
}