aboutsummaryrefslogtreecommitdiff
path: root/background/page_actions_server.js
diff options
context:
space:
mode:
authorWojtek Kosior <wk@koszkonutek-tmp.pl.eu.org>2021-05-12 16:00:09 +0200
committerWojtek Kosior <wk@koszkonutek-tmp.pl.eu.org>2021-05-12 16:00:09 +0200
commit7f368d46ea06164da025c1ac4ed9a65ad23b25ef (patch)
treee5b740ebcb3cdc58e9c87f25556c20d8bfdccadd /background/page_actions_server.js
parent89db6823fae5099816732c3cd2ba39700c1c4607 (diff)
downloadbrowser-extension-7f368d46ea06164da025c1ac4ed9a65ad23b25ef.tar.gz
browser-extension-7f368d46ea06164da025c1ac4ed9a65ad23b25ef.zip
stop using js modules
Diffstat (limited to 'background/page_actions_server.js')
-rw-r--r--background/page_actions_server.js149
1 files changed, 149 insertions, 0 deletions
diff --git a/background/page_actions_server.js b/background/page_actions_server.js
new file mode 100644
index 0000000..fbb672e
--- /dev/null
+++ b/background/page_actions_server.js
@@ -0,0 +1,149 @@
+/**
+* Myext serving of page actions to content scripts
+*
+* Copyright (C) 2021 Wojtek Kosior
+*
+* Dual-licensed under:
+* - 0BSD license
+* - GPLv3 or (at your option) any later version
+*/
+
+"use strict";
+
+(() => {
+ const get_storage = window.get_storage;
+ const TYPE_PREFIX = window.TYPE_PREFIX;
+ const CONNECTION_TYPE = window.CONNECTION_TYPE;
+ const browser = window.browser;
+ const listen_for_connection = window.listen_for_connection;
+ const url_item = window.url_item;
+ const sha256 = window.sha256;
+
+ var storage;
+ var handler;
+
+ function send_scripts(url, port)
+ {
+ let settings = storage.get(TYPE_PREFIX.PAGE, url_item(url));
+ if (settings === undefined)
+ return;
+
+ let components = settings.components;
+ let processed_bundles = new Set();
+
+ send_scripts_rec(components, port, processed_bundles);
+ }
+
+ // TODO: parallelize script fetching
+ async function send_scripts_rec(components, port, processed_bundles)
+ {
+ for (let [prefix, name] of components) {
+ if (prefix === TYPE_PREFIX.BUNDLE) {
+ if (processed_bundles.has(name)) {
+ console.log(`preventing recursive inclusion of bundle ${name}`);
+ continue;
+ }
+
+ var bundle = storage.get(TYPE_PREFIX.BUNDLE, name);
+
+ if (bundle === undefined) {
+ console.log(`no bundle in storage for key ${name}`);
+ continue;
+ }
+
+ processed_bundles.add(name);
+ await send_scripts_rec(bundle, port, processed_bundles);
+ processed_bundles.delete(name);
+ } else {
+ let script_text = await get_script_text(name);
+ if (script_text === undefined)
+ continue;
+
+ port.postMessage({inject : [script_text]});
+ }
+ }
+ }
+
+ async function get_script_text(script_name)
+ {
+ try {
+ let script_data = storage.get(TYPE_PREFIX.SCRIPT, script_name);
+ if (script_data === undefined) {
+ console.log(`missing data for ${script_name}`);
+ return;
+ }
+ let script_text = script_data.text;
+ if (!script_text)
+ script_text = await fetch_remote_script(script_data);
+ return script_text;
+ } catch (e) {
+ console.log(e);
+ }
+ }
+
+ function ajax_callback()
+ {
+ if (this.readyState == 4)
+ this.resolve_callback(this);
+ }
+
+ function initiate_ajax_request(resolve, method, url)
+ {
+ var xhttp = new XMLHttpRequest();
+ xhttp.resolve_callback = resolve;
+ xhttp.onreadystatechange = ajax_callback;
+ xhttp.open(method, url, true);
+ xhttp.send();
+ }
+
+ function make_ajax_request(method, url)
+ {
+ return new Promise((resolve, reject) =>
+ initiate_ajax_request(resolve, method, url));
+ }
+
+ async function fetch_remote_script(script_data)
+ {
+ try {
+ let xhttp = await make_ajax_request("GET", script_data.url);
+ if (xhttp.status === 200) {
+ let computed_hash = sha256(xhttp.responseText);
+ if (computed_hash !== script_data.hash) {
+ console.log(`Bad hash for ${script_data.url}\n got ${computed_hash} instead of ${script_data.hash}`);
+ return;
+ }
+ return xhttp.responseText;
+ } else {
+ console.log("script not fetched: " + script_data.url);
+ return;
+ }
+ } catch (e) {
+ console.log(e);
+ }
+ }
+
+ function handle_message(port, message, handler)
+ {
+ port.onMessage.removeListener(handler[0]);
+ let url = message.url;
+ console.log({url});
+ send_scripts(url, port);
+ }
+
+ function new_connection(port)
+ {
+ console.log("new page actions connection!");
+ let handler = [];
+ handler.push(m => handle_message(port, m, handler));
+ port.onMessage.addListener(handler[0]);
+ }
+
+ async function start()
+ {
+ storage = await get_storage();
+
+ listen_for_connection(CONNECTION_TYPE.PAGE_ACTIONS, new_connection);
+ }
+
+ window.start_page_actions_server = start;
+})();