2018-01-04 14:04:23 +00:00
|
|
|
/* global loadScript */
|
2018-01-01 17:02:49 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-var
|
2018-01-04 14:04:23 +00:00
|
|
|
var [chromeLocal, chromeSync] = (() => {
|
|
|
|
const native = 'sync' in chrome.storage &&
|
|
|
|
!chrome.runtime.id.includes('@temporary');
|
|
|
|
if (!native && BG !== window) {
|
|
|
|
setupOnChangeRelay();
|
|
|
|
}
|
|
|
|
return [
|
|
|
|
createWrapper('local'),
|
|
|
|
createWrapper('sync'),
|
|
|
|
];
|
2018-01-01 17:02:49 +00:00
|
|
|
|
2018-01-04 14:04:23 +00:00
|
|
|
function createWrapper(name) {
|
|
|
|
if (!native) createDummyStorage(name);
|
|
|
|
const storage = chrome.storage[name];
|
|
|
|
const wrapper = {
|
|
|
|
get: data => new Promise(resolve => storage.get(data, resolve)),
|
|
|
|
set: data => new Promise(resolve => storage.set(data, () => resolve(data))),
|
|
|
|
remove: data => new Promise(resolve => storage.remove(data, resolve)),
|
2018-01-01 17:02:49 +00:00
|
|
|
|
2018-01-04 14:04:23 +00:00
|
|
|
getValue: key => wrapper.get(key).then(data => data[key]),
|
|
|
|
setValue: (key, value) => wrapper.set({[key]: value}),
|
|
|
|
|
|
|
|
getLZValue: key => wrapper.getLZValues([key]).then(data => data[key]),
|
|
|
|
getLZValues: keys =>
|
|
|
|
Promise.all([
|
|
|
|
wrapper.get(keys),
|
|
|
|
loadLZStringScript(),
|
|
|
|
]).then(([data = {}, LZString]) => {
|
|
|
|
for (const key of keys) {
|
|
|
|
const value = data[key];
|
|
|
|
data[key] = value && tryJSONparse(LZString.decompressFromUTF16(value));
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}),
|
|
|
|
setLZValue: (key, value) =>
|
|
|
|
loadLZStringScript().then(LZString =>
|
|
|
|
wrapper.set({
|
|
|
|
[key]: LZString.compressToUTF16(JSON.stringify(value)),
|
|
|
|
})),
|
|
|
|
|
|
|
|
loadLZStringScript,
|
|
|
|
};
|
|
|
|
return wrapper;
|
2018-01-01 17:02:49 +00:00
|
|
|
}
|
|
|
|
|
2018-01-04 14:04:23 +00:00
|
|
|
function createDummyStorage(name) {
|
|
|
|
chrome.storage[name] = {
|
|
|
|
get: (data, cb) => API.dummyStorageGet({data, name}).then(cb),
|
|
|
|
set: (data, cb) => API.dummyStorageSet({data, name}).then(cb),
|
|
|
|
remove: (data, cb) => API.dummyStorageRemove({data, name}).then(cb),
|
|
|
|
};
|
2018-01-01 17:02:49 +00:00
|
|
|
}
|
|
|
|
|
2018-01-04 14:04:23 +00:00
|
|
|
function loadLZStringScript() {
|
|
|
|
return window.LZString ?
|
|
|
|
Promise.resolve(window.LZString) :
|
|
|
|
loadScript('/vendor/lz-string/lz-string-unsafe.js').then(() =>
|
|
|
|
(window.LZString = window.LZString || window.LZStringUnsafe));
|
2018-01-01 17:02:49 +00:00
|
|
|
}
|
|
|
|
|
2018-01-04 14:04:23 +00:00
|
|
|
function setupOnChangeRelay() {
|
|
|
|
const listeners = new Set();
|
|
|
|
const onMessage = msg => {
|
|
|
|
if (!msg.dummyStorageChanges) return;
|
|
|
|
for (const fn of listeners.values()) {
|
|
|
|
fn(msg.dummyStorageChanges, msg.dummyStorageName);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Object.assign(chrome.storage.onChanged, {
|
|
|
|
addListener(fn) {
|
|
|
|
if (!listeners.size) chrome.runtime.onMessage.addListener(onMessage);
|
|
|
|
listeners.add(fn);
|
|
|
|
},
|
|
|
|
hasListener: fn => listeners.has(fn),
|
|
|
|
removeListener(fn) {
|
|
|
|
listeners.delete(fn);
|
|
|
|
if (!listeners.size) chrome.runtime.onMessage.removeListener(onMessage);
|
|
|
|
}
|
|
|
|
});
|
2018-01-01 17:02:49 +00:00
|
|
|
}
|
2018-01-04 14:04:23 +00:00
|
|
|
})();
|