diff options
Diffstat (limited to 'background')
-rw-r--r-- | background/main.js | 2 | ||||
-rw-r--r-- | background/page_actions_server.js | 16 | ||||
-rw-r--r-- | background/page_info_server.js | 77 | ||||
-rw-r--r-- | background/settings_query.js | 98 |
4 files changed, 103 insertions, 90 deletions
diff --git a/background/main.js b/background/main.js index 2fcdda3..da408f9 100644 --- a/background/main.js +++ b/background/main.js @@ -12,6 +12,7 @@ * IMPORT start_storage_server * IMPORT start_page_actions_server * IMPORT start_policy_injector + * IMPORT start_page_info_server * IMPORT browser * IMPORTS_END */ @@ -19,6 +20,7 @@ start_storage_server(); start_page_actions_server(); start_policy_injector(); +start_page_info_server(); async function init_myext(install_details) { diff --git a/background/page_actions_server.js b/background/page_actions_server.js index f9773f6..2d9c333 100644 --- a/background/page_actions_server.js +++ b/background/page_actions_server.js @@ -21,9 +21,12 @@ var storage; var query_best; var handler; -function send_scripts(url, port) +function send_actions(url, port) { let [pattern, settings] = query_best(url); + + port.postMessage(["settings", [pattern, settings]]); + if (settings === undefined) return; @@ -31,11 +34,11 @@ function send_scripts(url, port) let processed_bags = new Set(); if (components !== undefined) - send_scripts_rec([components], port, processed_bags); + send_scripts([components], port, processed_bags); } // TODO: parallelize script fetching -async function send_scripts_rec(components, port, processed_bags) +async function send_scripts(components, port, processed_bags) { for (let [prefix, name] of components) { if (prefix === TYPE_PREFIX.BAG) { @@ -52,14 +55,15 @@ async function send_scripts_rec(components, port, processed_bags) } processed_bags.add(name); - await send_scripts_rec(bag, port, processed_bags); + await send_scripts(bag, port, processed_bags); + processed_bags.delete(name); } else { let script_text = await get_script_text(name); if (script_text === undefined) continue; - port.postMessage({inject : [script_text]}); + port.postMessage(["inject", [script_text]]); } } } @@ -127,7 +131,7 @@ function handle_message(port, message, handler) port.onMessage.removeListener(handler[0]); let url = message.url; console.log({url}); - send_scripts(url, port); + send_actions(url, port); } function new_connection(port) diff --git a/background/page_info_server.js b/background/page_info_server.js new file mode 100644 index 0000000..49919fd --- /dev/null +++ b/background/page_info_server.js @@ -0,0 +1,77 @@ +/** + * part of Hachette + * Serving of storage data corresponding to requested urls (server side). + * + * Copyright (C) 2021 Wojtek Kosior + * Redistribution terms are gathered in the `copyright' file. + */ + +/* + * IMPORTS_START + * IMPORT listen_for_connection + * IMPORT get_storage + * IMPORT get_query_all + * IMPORT TYPE_PREFIX + * IMPORT CONNECTION_TYPE + * IMPORT url_matches + * IMPORTS_END + */ + +var storage; +var query_all; + +function handle_change(connection_data, change) +{ + if (change.prefix !== TYPE_PREFIX.PAGE) + return; + + connection_data.port.postMessage(["change", change]); +} + +async function handle_subscription(connection_data, message) +{ + const [action, url] = message; + if (action === "unsubscribe") { + connection_data.subscribed.delete(url); + return; + } + + connection_data.subscribed.add(url); + connection_data.port.postMessage(["new_url", query_all(url)]); +} + +function remove_storage_listener(cb) +{ + storage.remove_change_listener(cb); +} + +function new_connection(port) +{ + console.log("new page info connection!"); + + const connection_data = { + subscribed : new Set(), + port + }; + + let _handle_change = change => handle_change(connection_data, change); + + storage.add_change_listener(_handle_change); + + port.onMessage.addListener(m => handle_subscription(connection_data, m)); + port.onDisconnect.addListener(() => remove_storage_listener(handle_change)); +} + +async function start_page_info_server() +{ + storage = await get_storage(); + query_all = await get_query_all(); + + listen_for_connection(CONNECTION_TYPE.PAGE_INFO, new_connection); +} + +/* + * EXPORTS_START + * EXPORT start_page_info_server + * EXPORTS_END + */ diff --git a/background/settings_query.js b/background/settings_query.js index ce01b80..d509b09 100644 --- a/background/settings_query.js +++ b/background/settings_query.js @@ -10,13 +10,12 @@ * IMPORT make_once * IMPORT get_storage * IMPORT TYPE_PREFIX + * IMPORT for_each_possible_pattern * IMPORTS_END */ var storage; -var exports = {}; - async function init(fun) { storage = await get_storage(); @@ -24,94 +23,25 @@ async function init(fun) return fun; } -// TODO: also support urls with specified ports -function query(url, multiple) +function check_pattern(pattern, multiple, matched) { - let proto_re = "[a-zA-Z]*:\/\/"; - let domain_re = "[^/?#]+"; - let segments_re = "/[^?#]*"; - let query_re = "\\?[^#]*"; - - let url_regex = new RegExp(`\ -^\ -(${proto_re})\ -(${domain_re})\ -(${segments_re})?\ -(${query_re})?\ -#?.*\$\ -`); - - let regex_match = url_regex.exec(url); - if (regex_match === null) { - console.log("bad url format", url); - return multiple ? [] : [undefined, undefined]; - } - - let [_, proto, domain, segments, query] = regex_match; - - domain = domain.split("."); - let segments_trailing_dash = - segments && segments[segments.length - 1] === "/"; - segments = (segments || "").split("/").filter(s => s !== ""); - segments.unshift(""); - - let matched = []; + const settings = storage.get(TYPE_PREFIX.PAGE, pattern); - for (let d_slice = 0; d_slice < domain.length; d_slice++) { - let domain_part = domain.slice(d_slice).join("."); - let domain_wildcards = []; - if (d_slice === 0) - domain_wildcards.push(""); - if (d_slice === 1) - domain_wildcards.push("*."); - if (d_slice > 0) - domain_wildcards.push("**."); - domain_wildcards.push("***."); + if (settings === undefined) + return; - for (let domain_wildcard of domain_wildcards) { - let domain_pattern = domain_wildcard + domain_part; + matched.push([pattern, settings]); - for (let s_slice = segments.length; s_slice > 0; s_slice--) { - let segments_part = segments.slice(0, s_slice).join("/"); - let segments_wildcards = []; - if (s_slice === segments.length) { - if (segments_trailing_dash) - segments_wildcards.push("/"); - segments_wildcards.push(""); - } - if (s_slice === segments.length - 1) { - if (segments[s_slice] !== "*") - segments_wildcards.push("/*"); - } - if (s_slice < segments.length && - (segments[s_slice] !== "**" || - s_slice < segments.length - 1)) - segments_wildcards.push("/**"); - if (segments[s_slice] !== "***" || - s_slice < segments.length) - segments_wildcards.push("/***"); - - for (let segments_wildcard of segments_wildcards) { - let segments_pattern = - segments_part + segments_wildcard; - - let pattern = proto + domain_pattern + segments_pattern; - console.log("trying", pattern); - let settings = storage.get(TYPE_PREFIX.PAGE, pattern); - - if (settings === undefined) - continue; - - if (!multiple) - return [pattern, settings]; + if (!multiple) + return false; +} - matched.push([pattern, settings]); - } - } - } - } +function query(url, multiple) +{ + const matched = []; + for_each_possible_pattern(url, p => check_pattern(p, multiple, matched)); - return multiple ? matched : [undefined, undefined]; + return multiple ? matched : (matched[0] || [undefined, undefined]); } function query_best(url) |