aboutsummaryrefslogtreecommitdiff
path: root/common/storage_client.js
diff options
context:
space:
mode:
Diffstat (limited to 'common/storage_client.js')
-rw-r--r--common/storage_client.js360
1 files changed, 183 insertions, 177 deletions
diff --git a/common/storage_client.js b/common/storage_client.js
index 1bc9a88..2bbddb6 100644
--- a/common/storage_client.js
+++ b/common/storage_client.js
@@ -5,182 +5,188 @@
* Redistribution terms are gathered in the `copyright' file.
*/
-"use strict";
-
-(() => {
- const CONNECTION_TYPE = window.CONNECTION_TYPE;
- const TYPE_PREFIX = window.TYPE_PREFIX;
- const list_prefixes = window.list_prefixes;
- const make_once = window.make_once;
- const browser = window.browser;
-
- var call_id = 0;
- var port;
- var calls_waiting = new Map();
-
- function set_call_callback(resolve, reject, func, args)
- {
- port.postMessage([call_id, func, args]);
- calls_waiting.set(call_id++, [resolve, reject]);
- }
-
- async function remote_call(func, args)
- {
- return new Promise((resolve, reject) =>
- set_call_callback(resolve, reject, func, args));
- }
-
- function handle_message(message)
- {
- let callbacks = calls_waiting.get(message.call_id);
- if (callbacks === undefined) {
- handle_change(message);
- return;
- }
-
- let [resolve, reject] = callbacks;
- calls_waiting.delete(message.call_id);
- if (message.error !== undefined)
- setTimeout(reject, 0, message.error);
- else
- setTimeout(resolve, 0, message.result);
- }
-
- function list(name, prefix)
- {
- return {prefix, name, listeners : new Set()};
- }
-
- var scripts = list("scripts", TYPE_PREFIX.SCRIPT);
- var bags = list("bags", TYPE_PREFIX.BAG);
- var pages = list("pages", TYPE_PREFIX.PAGE);
-
- const list_by_prefix = {
- [TYPE_PREFIX.SCRIPT] : scripts,
- [TYPE_PREFIX.BAG] : bags,
- [TYPE_PREFIX.PAGE] : pages
- };
-
- var resolve_init;
-
- function handle_first_message(message)
- {
- for (let prefix of Object.keys(message))
- list_by_prefix[prefix].map = new Map(message[prefix]);
-
- port.onMessage.removeListener(handle_first_message);
- port.onMessage.addListener(handle_message);
-
- resolve_init();
- }
-
- function handle_change(change)
- {
- let list = list_by_prefix[change.prefix];
-
- if (change.new_val === undefined)
- list.map.delete(change.item);
- else
- list.map.set(change.item, change.new_val);
-
- for (let listener_callback of list.listeners)
- listener_callback(change);
- }
-
- var exports = {};
-
- function start_connection(resolve)
- {
- resolve_init = resolve;
- port = browser.runtime.connect({name : CONNECTION_TYPE.REMOTE_STORAGE});
- port.onMessage.addListener(handle_first_message);
- }
-
- async function init() {
- await new Promise((resolve, reject) => start_connection(resolve));
- return exports;
- }
-
- for (let call_name of ["set", "remove", "replace", "clear"])
- exports [call_name] = (...args) => remote_call(call_name, args);
-
- // TODO: Much of the code below is copy-pasted from /background/storage.mjs.
- // This should later be refactored into a separate module
- // to avoid duplication.
-
- /*
- * Facilitate listening to changes
- */
-
- exports.add_change_listener = function (cb, prefixes=list_prefixes)
- {
- if (typeof(prefixes) === "string")
- prefixes = [prefixes];
-
- for (let prefix of prefixes)
- list_by_prefix[prefix].listeners.add(cb);
- }
-
- exports.remove_change_listener = function (cb, prefixes=list_prefixes)
- {
- if (typeof(prefixes) === "string")
- prefixes = [prefixes];
-
- for (let prefix of prefixes)
- list_by_prefix[prefix].listeners.delete(cb);
- }
-
- /* Prepare some hepler functions to get elements of a list */
-
- function list_items_it(list, with_values=false)
- {
- return with_values ? list.map.entries() : list.map.keys();
- }
-
- function list_entries_it(list)
- {
- return list_items_it(list, true);
- }
-
- function list_items(list, with_values=false)
- {
- let array = [];
-
- for (let item of list_items_it(list, with_values))
- array.push(item);
-
- return array;
- }
-
- function list_entries(list)
- {
- return list_items(list, true);
- }
-
- exports.get = function (prefix, item)
- {
- return list_by_prefix[prefix].map.get(item);
- }
-
- exports.get_all_names = function (prefix)
- {
- return list_items(list_by_prefix[prefix]);
- }
-
- exports.get_all_names_it = function (prefix)
- {
- return list_items_it(list_by_prefix[prefix]);
- }
-
- exports.get_all = function (prefix)
- {
- return list_entries(list_by_prefix[prefix]);
- }
+/*
+ * IMPORTS_START
+ * IMPORT CONNECTION_TYPE
+ * IMPORT TYPE_PREFIX
+ * IMPORT list_prefixes
+ * IMPORT make_once
+ * IMPORT browser
+ * IMPORTS_END
+ */
- exports.get_all_it = function (prefix)
- {
- return list_entries_it(list_by_prefix[prefix]);
- }
+var call_id = 0;
+var port;
+var calls_waiting = new Map();
+
+function set_call_callback(resolve, reject, func, args)
+{
+ port.postMessage([call_id, func, args]);
+ calls_waiting.set(call_id++, [resolve, reject]);
+}
+
+async function remote_call(func, args)
+{
+ return new Promise((resolve, reject) =>
+ set_call_callback(resolve, reject, func, args));
+}
+
+function handle_message(message)
+{
+ let callbacks = calls_waiting.get(message.call_id);
+ if (callbacks === undefined) {
+ handle_change(message);
+ return;
+ }
+
+ let [resolve, reject] = callbacks;
+ calls_waiting.delete(message.call_id);
+ if (message.error !== undefined)
+ setTimeout(reject, 0, message.error);
+ else
+ setTimeout(resolve, 0, message.result);
+}
+
+function list(name, prefix)
+{
+ return {prefix, name, listeners : new Set()};
+}
+
+var scripts = list("scripts", TYPE_PREFIX.SCRIPT);
+var bags = list("bags", TYPE_PREFIX.BAG);
+var pages = list("pages", TYPE_PREFIX.PAGE);
+
+const list_by_prefix = {
+ [TYPE_PREFIX.SCRIPT] : scripts,
+ [TYPE_PREFIX.BAG] : bags,
+ [TYPE_PREFIX.PAGE] : pages
+};
+
+var resolve_init;
+
+function handle_first_message(message)
+{
+ for (let prefix of Object.keys(message))
+ list_by_prefix[prefix].map = new Map(message[prefix]);
+
+ port.onMessage.removeListener(handle_first_message);
+ port.onMessage.addListener(handle_message);
+
+ resolve_init();
+}
+
+function handle_change(change)
+{
+ let list = list_by_prefix[change.prefix];
+
+ if (change.new_val === undefined)
+ list.map.delete(change.item);
+ else
+ list.map.set(change.item, change.new_val);
+
+ for (let listener_callback of list.listeners)
+ listener_callback(change);
+}
+
+var exports = {};
+
+function start_connection(resolve)
+{
+ resolve_init = resolve;
+ port = browser.runtime.connect({name : CONNECTION_TYPE.REMOTE_STORAGE});
+ port.onMessage.addListener(handle_first_message);
+}
+
+async function init() {
+ await new Promise((resolve, reject) => start_connection(resolve));
+ return exports;
+}
+
+for (let call_name of ["set", "remove", "replace", "clear"])
+ exports [call_name] = (...args) => remote_call(call_name, args);
+
+// TODO: Much of the code below is copy-pasted from /background/storage.mjs.
+// This should later be refactored into a separate module
+// to avoid duplication.
+
+/*
+ * Facilitate listening to changes
+ */
- window.get_storage = make_once(init);
-})();
+exports.add_change_listener = function (cb, prefixes=list_prefixes)
+{
+ if (typeof(prefixes) === "string")
+ prefixes = [prefixes];
+
+ for (let prefix of prefixes)
+ list_by_prefix[prefix].listeners.add(cb);
+}
+
+exports.remove_change_listener = function (cb, prefixes=list_prefixes)
+{
+ if (typeof(prefixes) === "string")
+ prefixes = [prefixes];
+
+ for (let prefix of prefixes)
+ list_by_prefix[prefix].listeners.delete(cb);
+}
+
+/* Prepare some hepler functions to get elements of a list */
+
+function list_items_it(list, with_values=false)
+{
+ return with_values ? list.map.entries() : list.map.keys();
+}
+
+function list_entries_it(list)
+{
+ return list_items_it(list, true);
+}
+
+function list_items(list, with_values=false)
+{
+ let array = [];
+
+ for (let item of list_items_it(list, with_values))
+ array.push(item);
+
+ return array;
+}
+
+function list_entries(list)
+{
+ return list_items(list, true);
+}
+
+exports.get = function (prefix, item)
+{
+ return list_by_prefix[prefix].map.get(item);
+}
+
+exports.get_all_names = function (prefix)
+{
+ return list_items(list_by_prefix[prefix]);
+}
+
+exports.get_all_names_it = function (prefix)
+{
+ return list_items_it(list_by_prefix[prefix]);
+}
+
+exports.get_all = function (prefix)
+{
+ return list_entries(list_by_prefix[prefix]);
+}
+
+exports.get_all_it = function (prefix)
+{
+ return list_entries_it(list_by_prefix[prefix]);
+}
+
+const get_remote_storage = make_once(init);
+
+/*
+ * EXPORTS_START
+ * EXPORT get_remote_storage
+ * EXPORTS_END
+ */