Files
2026-01-20 21:53:59 +03:30

93 lines
2.7 KiB
JavaScript

import {App} from './app.js';
// ---------- Storage Sync ---------------------------------
export class Sync {
static init(pref) {
// not for storage.managed
if (pref.managed) { return; }
// Firefox 101 (2022-05-31), Chrome 73
browser.storage.sync.onChanged.addListener(e => this.onChanged(e));
}
static async onChanged(changes) {
const pref = await browser.storage.local.get();
this.getSync(pref);
}
static async get(pref) {
// check storage.managed
await this.getManaged(pref);
// check storage.sync
await this.getSync(pref);
}
// https://bugzilla.mozilla.org/show_bug.cgi?id=1868153
// On Firefox storage.managed returns undefined if not found
static async getManaged(pref) {
const result = await browser.storage.managed.get().catch(() => {});
if (!Array.isArray(result?.data) || !result.data[0]) {
// storage.managed not found, clean up
if (Object.hasOwn(pref, 'managed')) {
delete pref.managed;
await browser.storage.local.remove('managed');
}
return;
}
// get default pref
const db = App.getDefaultPref();
// revert pref to default values
Object.keys(db).forEach(i => pref[i] = db[i]);
// set data from storage.managed
Object.keys(result).forEach(i => Object.hasOwn(pref, i) && (pref[i] = result[i]));
// set pref.managed to use in options.js, popup.js
pref.managed = true;
// no sync for storage.managed
pref.sync = false;
// --- update database
await browser.storage.local.set(pref);
}
static hasOldData(obj) {
// FP v3 OR FP v7, null value causes an error
return Object.hasOwn(obj, 'settings') || Object.values(obj).some(i => i && Object.hasOwn(i, 'address'));
}
static async getSync(pref) {
if (!pref.sync) { return; }
if (pref.managed) { return; }
const syncPref = await browser.storage.sync.get();
// check sync from old version 3-7
// (local has no data OR has old data) AND sync has old data
if ((!Object.keys(pref)[0] || this.hasOldData(pref)) && this.hasOldData(syncPref)) {
// set sync data to pref, to migrate next in background.js
Object.keys(syncPref).forEach(i => pref[i] = syncPref[i]);
return;
}
// convert object to array & filter proxies
const data = Object.values(syncPref).filter(i => Object.hasOwn(i, 'hostname'));
const obj = {};
if (data[0] && !App.equal(pref.data, data)) {
obj.data = data;
pref.data = data;
}
App.syncProperties.forEach(i => {
if (Object.hasOwn(syncPref, i)) {
obj[i] = syncPref[i];
pref[i] = syncPref[i];
}
});
// update saved pref
Object.keys(obj)[0] && await browser.storage.local.set(obj);
}
}