From fb9c808cdaa46833c0cbd7f6c918d6b61aec1aca Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 21 Jul 2021 17:40:04 +0200 Subject: remove unused variables --- background/storage.js | 4 ---- 1 file changed, 4 deletions(-) (limited to 'background') diff --git a/background/storage.js b/background/storage.js index 7229a2d..682f933 100644 --- a/background/storage.js +++ b/background/storage.js @@ -101,10 +101,6 @@ async function list(prefix) return {map, prefix, name, listeners : new Set(), lock : make_lock()}; } -var pages; -var bags; -var scripts; - var list_by_prefix = {}; async function init() -- cgit v1.2.3 From 5c68551800e477db41ae6fe3a318b2ff2d7a9cb1 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 21 Jul 2021 17:42:21 +0200 Subject: store repository URLs in settings --- background/storage_server.js | 12 ++++++------ common/storage_client.js | 17 +++-------------- common/stored_types.js | 3 +++ html/options.html | 18 ++++++++++++++++++ html/options_main.js | 33 ++++++++++++++++++++++++++++----- 5 files changed, 58 insertions(+), 25 deletions(-) (limited to 'background') diff --git a/background/storage_server.js b/background/storage_server.js index 554aff2..2252eb5 100644 --- a/background/storage_server.js +++ b/background/storage_server.js @@ -9,7 +9,7 @@ * IMPORTS_START * IMPORT listen_for_connection * IMPORT get_storage - * IMPORT TYPE_PREFIX + * IMPORT list_prefixes * IMPORT CONNECTION_TYPE * IMPORTS_END */ @@ -38,11 +38,11 @@ function new_connection(port) { console.log("new remote storage connection!"); - port.postMessage({ - [TYPE_PREFIX.SCRIPT] : storage.get_all(TYPE_PREFIX.SCRIPT), - [TYPE_PREFIX.BAG] : storage.get_all(TYPE_PREFIX.BAG), - [TYPE_PREFIX.PAGE] : storage.get_all(TYPE_PREFIX.PAGE) - }); + const message = {}; + for (const prefix of list_prefixes) + message[prefix] = storage.get_all(prefix); + + port.postMessage(message); let handle_change = change => port.postMessage(change); diff --git a/common/storage_client.js b/common/storage_client.js index 4849a65..2b2f495 100644 --- a/common/storage_client.js +++ b/common/storage_client.js @@ -8,7 +8,6 @@ /* * IMPORTS_START * IMPORT CONNECTION_TYPE - * IMPORT TYPE_PREFIX * IMPORT list_prefixes * IMPORT make_once * IMPORT browser @@ -47,20 +46,10 @@ function handle_message(message) 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 = {}; -const list_by_prefix = { - [TYPE_PREFIX.SCRIPT] : scripts, - [TYPE_PREFIX.BAG] : bags, - [TYPE_PREFIX.PAGE] : pages -}; +for (const prefix of list_prefixes) + list_by_prefix[prefix] = {prefix, listeners : new Set()}; var resolve_init; diff --git a/common/stored_types.js b/common/stored_types.js index a6f1f2f..304842b 100644 --- a/common/stored_types.js +++ b/common/stored_types.js @@ -14,6 +14,7 @@ */ const TYPE_PREFIX = { + REPO: "r", PAGE : "p", BAG : "b", SCRIPT : "s", @@ -21,12 +22,14 @@ const TYPE_PREFIX = { }; const TYPE_NAME = { + [TYPE_PREFIX.REPO] : "repo", [TYPE_PREFIX.PAGE] : "page", [TYPE_PREFIX.BAG] : "bag", [TYPE_PREFIX.SCRIPT] : "script" } const list_prefixes = [ + TYPE_PREFIX.REPO, TYPE_PREFIX.PAGE, TYPE_PREFIX.BAG, TYPE_PREFIX.SCRIPT diff --git a/html/options.html b/html/options.html index bfb9e52..a10b919 100644 --- a/html/options.html +++ b/html/options.html @@ -33,12 +33,14 @@ } /* tabbed view */ + #show_repos:not(:checked) ~ #repos, #show_pages:not(:checked) ~ #pages, #show_bags:not(:checked) ~ #bags, #show_scripts:not(:checked) ~ #scripts { display: none; } + #show_repos:checked ~ #repos_lbl, #show_pages:checked ~ #pages_lbl, #show_bags:checked ~ #bags_lbl, #show_scripts:checked ~ #scripts_lbl { @@ -124,9 +126,12 @@ + + +
+
    +
  • + + +
    + + +
  • +
+ +
+
  • diff --git a/html/options_main.js b/html/options_main.js index e1e6cbe..026b9ba 100644 --- a/html/options_main.js +++ b/html/options_main.js @@ -38,7 +38,7 @@ function item_li_id(prefix, item) return `li_${prefix}_${item}`; } -/* Insert into list of bags/pages/scripts */ +/* Insert into list of bags/pages/scripts/repos */ function add_li(prefix, item, at_the_end=false) { let ul = ul_by_prefix[prefix]; @@ -58,6 +58,8 @@ function add_li(prefix, item, at_the_end=false) let export_button = remove_button.nextElementSibling; export_button.addEventListener("click", () => export_item(prefix, item)); + if (prefix === TYPE_PREFIX.REPO) + export_button.remove(); if (!at_the_end) { for (let element of ul.ul.children) { @@ -89,7 +91,7 @@ function radio_li_id(prefix, item) function add_chbx_li(prefix, name) { - if (prefix === TYPE_PREFIX.PAGE) + if (![TYPE_PREFIX.BAG, TYPE_PREFIX.SCRIPT].includes(prefix)) return; let li = chbx_component_li_template.cloneNode(true); @@ -109,7 +111,7 @@ var radio_component_none_li = by_id("radio_component_none_li"); function add_radio_li(prefix, name) { - if (prefix === TYPE_PREFIX.PAGE) + if (![TYPE_PREFIX.BAG, TYPE_PREFIX.SCRIPT].includes(prefix)) return; let li = radio_component_li_template.cloneNode(true); @@ -125,6 +127,18 @@ function add_radio_li(prefix, name) radio_components_ul.insertBefore(li, radio_component_none_li); } +/* Used to reset edited repo. */ +function reset_work_repo_li(ul, item, _) +{ + ul.work_name_input.value = maybe_string(item); +} + +/* Used to get repo data for saving */ +function work_repo_li_data(ul) +{ + return [ul.work_name_input.value, {}]; +} + const page_payload_span = by_id("page_payload"); function set_page_components(components) @@ -461,6 +475,15 @@ const UL_STATE = { }; const ul_by_prefix = { + [TYPE_PREFIX.REPO] : { + ul : by_id("repos_ul"), + work_li : by_id("work_repo_li"), + work_name_input : by_id("repo_url_field"), + reset_work_li : reset_work_repo_li, + get_work_li_data : work_repo_li_data, + state : UL_STATE.IDLE, + edited_item : undefined, + }, [TYPE_PREFIX.PAGE] : { ul : by_id("pages_ul"), work_li : by_id("work_page_li"), @@ -727,7 +750,7 @@ async function main() discard_but.addEventListener("click", () => cancel_work(prefix)); save_but.addEventListener("click", () => save_work(prefix)); - if (prefix === TYPE_PREFIX.SCRIPT) + if ([TYPE_PREFIX.REPO, TYPE_PREFIX.SCRIPT].includes(prefix)) continue; let ul = ul_by_prefix[prefix]; @@ -772,7 +795,7 @@ function handle_change(change) let uls_creators = [[ul.ul, item_li_id]]; - if (change.prefix !== TYPE_PREFIX.PAGE) { + if ([TYPE_PREFIX.BAG, TYPE_PREFIX.SCRIPT].includes(change.prefix)) { uls_creators.push([chbx_components_ul, chbx_li_id]); uls_creators.push([radio_components_ul, radio_li_id]); } -- cgit v1.2.3 From c483ae19e110ef5c1e539883a38fbc79b3dd4e4e Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 21 Jul 2021 22:00:20 +0200 Subject: add ability to query page content from repo and display it in the popup --- background/page_actions_server.js | 27 ++----------- common/ajax.js | 39 +++++++++++++++++++ content/activity_info_server.js | 23 +++++++++++ content/main.js | 3 ++ content/repo_query.js | 80 +++++++++++++++++++++++++++++++++++++++ html/display-panel.html | 23 ++++++++--- html/display-panel.js | 35 +++++++++++++++-- 7 files changed, 197 insertions(+), 33 deletions(-) create mode 100644 common/ajax.js create mode 100644 content/repo_query.js (limited to 'background') diff --git a/background/page_actions_server.js b/background/page_actions_server.js index c6800a0..a7a44c1 100644 --- a/background/page_actions_server.js +++ b/background/page_actions_server.js @@ -14,6 +14,7 @@ * IMPORT listen_for_connection * IMPORT sha256 * IMPORT get_query_best + * IMPORT make_ajax_request * IMPORTS_END */ @@ -23,9 +24,10 @@ var handler; function send_actions(url, port) { - let [pattern, settings] = query_best(url); + const [pattern, settings] = query_best(url); + const repos = storage.get_all(TYPE_PREFIX.REPO); - port.postMessage(["settings", [pattern, settings]]); + port.postMessage(["settings", [pattern, settings, repos]]); if (settings === undefined) return; @@ -85,27 +87,6 @@ async function get_script_text(script_name) } } -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 { diff --git a/common/ajax.js b/common/ajax.js new file mode 100644 index 0000000..8082bbe --- /dev/null +++ b/common/ajax.js @@ -0,0 +1,39 @@ +/** + * part of Hachette + * Wrapping XMLHttpRequest into a Promise. + * + * Copyright (C) 2021 Wojtek Kosior + * Redistribution terms are gathered in the `copyright' file. + */ + +function ajax_callback() +{ + if (this.readyState == 4) + this.resolve_callback(this); +} + +function initiate_ajax_request(resolve, reject, method, url) +{ + const xhttp = new XMLHttpRequest(); + xhttp.resolve_callback = resolve; + xhttp.onreadystatechange = ajax_callback; + xhttp.open(method, url, true); + try { + xhttp.send(); + } catch(e) { + console.log(e); + setTimeout(reject, 0); + } +} + +function make_ajax_request(method, url) +{ + return new Promise((resolve, reject) => + initiate_ajax_request(resolve, reject, method, url)); +} + +/* + * EXPORTS_START + * EXPORT make_ajax_request + * EXPORTS_END + */ diff --git a/content/activity_info_server.js b/content/activity_info_server.js index 8435377..a1384e9 100644 --- a/content/activity_info_server.js +++ b/content/activity_info_server.js @@ -11,6 +11,8 @@ * IMPORTS_START * IMPORT listen_for_connection * IMPORT CONNECTION_TYPE + * IMPORT set_repo_query_repos + * IMPORT set_repo_query_callback * IMPORTS_END */ @@ -33,9 +35,22 @@ function report_script(script_data) function report_settings(settings) { + const [pattern, settings_data, repos] = settings; + set_repo_query_repos(repos); + report_activity("settings", settings); } +function report_repo_query_result(result) +{ + report_activity("repo_query_result", result); +} + +function trigger_repo_query() +{ + set_repo_query_callback(report_repo_query_result); +} + function new_connection(port) { console.log("new activity info connection!"); @@ -44,6 +59,14 @@ function new_connection(port) for (const activity of activities) port.postMessage(activity); + + /* + * So far the only thing we expect to receive is repo query order. Once more + * possibilities arrive, we will need to complicate this listener. + */ + port.onMessage.addListener(trigger_repo_query); + + port.onDisconnect.addListener(() => ports.delete(port)); } function start_activity_info_server() diff --git a/content/main.js b/content/main.js index 8f8375e..437a32b 100644 --- a/content/main.js +++ b/content/main.js @@ -20,6 +20,7 @@ * IMPORT is_chrome * IMPORT is_mozilla * IMPORT start_activity_info_server + * IMPORT set_repo_query_url * IMPORTS_END */ @@ -129,4 +130,6 @@ if (!is_privileged_url(document.URL)) { } start_activity_info_server(); + + set_repo_query_url(document.URL); } diff --git a/content/repo_query.js b/content/repo_query.js new file mode 100644 index 0000000..b8c8ed9 --- /dev/null +++ b/content/repo_query.js @@ -0,0 +1,80 @@ +/** + * part of Hachette + * Getting available content for site from remote repositories. + * + * Copyright (C) 2021 Wojtek Kosior + * Redistribution terms are gathered in the `copyright' file. + */ + +/* + * IMPORTS_START + * IMPORT make_ajax_request + * IMPORTS_END + */ + +var query_started = false; + +var url = undefined; +var repos = undefined; +var callback = undefined; + +async function query(repo) +{ + const [repo_url, data] = repo; + + let response = "Query failed"; + const query_url = `${repo_url}/query?n=${encodeURIComponent(url)}`; + + try { + let xhttp = await make_ajax_request("GET", query_url); + if (xhttp.status === 200) + response = xhttp.responseText; + console.log(xhttp); + } catch (e) { + console.log(e); + } + + callback([repo_url, response]); +} + +function start_query() +{ + if (query_started || !url || !repos || !callback) + return; + + query_started = true; + + console.log(`about to query ${url} from ${repos}`); + + for (const repo of repos) + query(repo); +} + +function set_repo_query_url(_url) +{ + url = _url; + + start_query(); +} + +function set_repo_query_repos(_repos) +{ + repos = _repos; + + start_query(); +} + +function set_repo_query_callback(_callback) +{ + callback = _callback; + + start_query(); +} + +/* + * EXPORTS_START + * EXPORT set_repo_query_url + * EXPORT set_repo_query_repos + * EXPORT set_repo_query_callback + * EXPORTS_END + */ diff --git a/html/display-panel.html b/html/display-panel.html index 9b6d619..d8d7f5d 100644 --- a/html/display-panel.html +++ b/html/display-panel.html @@ -21,6 +21,14 @@ display: none; } + .show_hide_next2:not(:checked)+* { + display: none; + } + + .show_hide_next2:checked+*+* { + display: none; + } + .hide { display: none; } @@ -34,10 +42,6 @@ #container_for_injected>#none_injected:not(:last-child) { display: none; } - - input#connected_chbx:checked+div+h3 { - display: none; - } @@ -65,12 +69,19 @@
      - +

      Matched pattern: ... + +
      +

      Queried from repositories

      +
      +

      diff --git a/html/display-panel.js b/html/display-panel.js index 650c234..1693182 100644 --- a/html/display-panel.js +++ b/html/display-panel.js @@ -144,6 +144,7 @@ function handle_page_info(message) } const connected_chbx = by_id("connected_chbx"); +const query_pattern_but = by_id("query_pattern"); function try_to_connect(tab_id) { @@ -151,21 +152,35 @@ function try_to_connect(tab_id) const connect_info = {name: CONNECTION_TYPE.ACTIVITY_INFO, frameId: 0}; const port = browser.tabs.connect(tab_id, connect_info); - port.onDisconnect.addListener(port => handle_disconnect(tab_id)); + const button_cb = (e) => start_querying_repos(port); + + port.onDisconnect.addListener(port => handle_disconnect(tab_id, button_cb)); port.onMessage.addListener(handle_activity_report); + query_pattern_but.addEventListener("click", button_cb); + if (is_mozilla) setTimeout(() => monitor_connecting(port, tab_id), 1000); } +const query_started_chbx = by_id("query_started_chbx"); + +function start_querying_repos(port) +{ + port.postMessage("dummy (trigger repo querying)"); + query_started_chbx.checked = true; +} + const loading_chbx = by_id("loading_chbx"); -function handle_disconnect(tab_id) +function handle_disconnect(tab_id, button_cb) { + query_pattern_but.removeEventListener("click", button_cb); + if (is_chrome && !browser.runtime.lastError) return; - /* return if there was no connection initialization failure */ + /* return if error was not during connection initialization */ if (connected_chbx.checked) return; @@ -189,6 +204,7 @@ const blocked_span = by_id("blocked"); const payload_span = by_id("payload"); const view_payload_but = by_id("view_payload"); const container_for_injected = by_id("container_for_injected"); +const container_for_repo_responses = by_id("container_for_repo_responses"); function handle_activity_report(message) { @@ -197,7 +213,7 @@ function handle_activity_report(message) const [type, data] = message; if (type === "settings") { - let [pattern, settings] = data; + let [pattern, settings, repos] = data; settings = settings || {}; blocked_span.textContent = settings.allow ? "no" : "yes"; @@ -231,6 +247,17 @@ function handle_activity_report(message) container_for_injected.appendChild(h4); container_for_injected.appendChild(pre); } + if (type === "repo_query_result") { + const [repo_url, response_text] = data; + + const h4 = document.createElement("h4"); + const pre = document.createElement("pre"); + h4.textContent = repo_url; + pre.textContent = response_text; + + container_for_repo_responses.appendChild(h4); + container_for_repo_responses.appendChild(pre); + } } by_id("settings_but") -- cgit v1.2.3 From d42dadca04bd2c40cfe836b3f2bbe0ffbf176eda Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 23 Jul 2021 17:32:31 +0200 Subject: extract observables implementation from storage.js --- background/storage.js | 24 ++++++++++-------------- common/observable.js | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 14 deletions(-) create mode 100644 common/observable.js (limited to 'background') diff --git a/background/storage.js b/background/storage.js index 682f933..c2160b0 100644 --- a/background/storage.js +++ b/background/storage.js @@ -16,6 +16,7 @@ * IMPORT make_once * IMPORT browser * IMPORT is_chrome + * IMPORT observables * IMPORTS_END */ @@ -98,7 +99,8 @@ async function list(prefix) for (let item of await get_list_var(name)) map.set(item, await get(prefix + item)); - return {map, prefix, name, listeners : new Set(), lock : make_lock()}; + return {map, prefix, name, observable: observables.make(), + lock: make_lock()}; } var list_by_prefix = {}; @@ -121,7 +123,7 @@ exports.add_change_listener = function (cb, prefixes=list_prefixes) prefixes = [prefixes]; for (let prefix of prefixes) - list_by_prefix[prefix].listeners.add(cb); + observables.subscribe(list_by_prefix[prefix].observable, cb); } exports.remove_change_listener = function (cb, prefixes=list_prefixes) @@ -130,13 +132,7 @@ exports.remove_change_listener = function (cb, prefixes=list_prefixes) prefixes = [prefixes]; for (let prefix of prefixes) - list_by_prefix[prefix].listeners.delete(cb); -} - -function broadcast_change(change, list) -{ - for (let listener_callback of list.listeners) - listener_callback(change); + observables.unsubscribe(list_by_prefix[prefix].observable, cb); } /* Prepare some hepler functions to get elements of a list */ @@ -198,7 +194,7 @@ async function _set_item(item, value, list) new_val : value }; - broadcast_change(change, list); + observables.broadcast(list.observable, change); return old_val; } @@ -236,7 +232,7 @@ async function _remove_item(item, list) new_val : undefined }; - broadcast_change(change, list); + observables.broadcast(list.observable, change); return old_val; } @@ -282,7 +278,7 @@ async function _replace_item(old_item, new_item, list, new_val=undefined) new_val : undefined }; - broadcast_change(change, list); + observables.broadcast(list.observable, change); list.map.set(new_item, new_val); @@ -290,7 +286,7 @@ async function _replace_item(old_item, new_item, list, new_val=undefined) change.old_val = undefined; change.new_val = new_val; - broadcast_change(change, list); + observables.broadcast(list.observable, change); return old_val; } @@ -375,7 +371,7 @@ exports.clear = async function () for (let [item, val] of list_entries_it(list)) { change.item = item; change.old_val = val; - broadcast_change(change, list); + observables.broadcast(list.observable, change); } list.map = new Map(); diff --git a/common/observable.js b/common/observable.js new file mode 100644 index 0000000..1fb0b0a --- /dev/null +++ b/common/observable.js @@ -0,0 +1,36 @@ +/** + * part of Hachette + * Facilitate listening to events + * + * Copyright (C) 2021 Wojtek Kosior + * Redistribution terms are gathered in the `copyright' file. + */ + +function make() +{ + return new Set(); +} + +function subscribe(observable, cb) +{ + observable.add(cb); +} + +function unsubscribe(observable, cb) +{ + observable.delete(cb); +} + +function broadcast(observable, event) +{ + for (const callback of observable) + callback(event); +} + +const observables = {make, subscribe, unsubscribe, broadcast}; + +/* + * EXPORTS_START + * EXPORT observables + * EXPORTS_END + */ -- cgit v1.2.3 From 5957fbeeb47bb2c519d34ae4d2eada2433dd1e09 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 4 Aug 2021 22:01:01 +0200 Subject: make settings_query.js use storage object passed as an argument --- background/page_actions_server.js | 6 ++-- background/page_info_server.js | 6 ++-- background/policy_injector.js | 6 ++-- background/settings_query.js | 65 --------------------------------------- common/settings_query.js | 52 +++++++++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 77 deletions(-) delete mode 100644 background/settings_query.js create mode 100644 common/settings_query.js (limited to 'background') diff --git a/background/page_actions_server.js b/background/page_actions_server.js index a7a44c1..58a0073 100644 --- a/background/page_actions_server.js +++ b/background/page_actions_server.js @@ -13,18 +13,17 @@ * IMPORT browser * IMPORT listen_for_connection * IMPORT sha256 - * IMPORT get_query_best + * IMPORT query_best * IMPORT make_ajax_request * IMPORTS_END */ var storage; -var query_best; var handler; function send_actions(url, port) { - const [pattern, settings] = query_best(url); + const [pattern, settings] = query_best(storage, url); const repos = storage.get_all(TYPE_PREFIX.REPO); port.postMessage(["settings", [pattern, settings, repos]]); @@ -126,7 +125,6 @@ function new_connection(port) async function start_page_actions_server() { storage = await get_storage(); - query_best = await get_query_best(); listen_for_connection(CONNECTION_TYPE.PAGE_ACTIONS, new_connection); } diff --git a/background/page_info_server.js b/background/page_info_server.js index 6f02750..e915011 100644 --- a/background/page_info_server.js +++ b/background/page_info_server.js @@ -10,7 +10,7 @@ * IMPORTS_START * IMPORT listen_for_connection * IMPORT get_storage - * IMPORT get_query_all + * IMPORT query_all * IMPORT TYPE_PREFIX * IMPORT CONNECTION_TYPE * IMPORT url_matches @@ -18,7 +18,6 @@ */ var storage; -var query_all; function handle_change(connection_data, change) { @@ -37,7 +36,7 @@ async function handle_subscription(connection_data, message) } connection_data.subscribed.add(url); - connection_data.port.postMessage(["new_url", query_all(url)]); + connection_data.port.postMessage(["new_url", query_all(storage, url)]); } function new_connection(port) @@ -62,7 +61,6 @@ function new_connection(port) 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); } diff --git a/background/policy_injector.js b/background/policy_injector.js index 01da094..b3d85e8 100644 --- a/background/policy_injector.js +++ b/background/policy_injector.js @@ -19,13 +19,12 @@ * IMPORT url_item * IMPORT url_extract_target * IMPORT sign_policy - * IMPORT get_query_best + * IMPORT query_best * IMPORT csp_rule * IMPORTS_END */ var storage; -var query_best; const csp_header_names = { "content-security-policy" : true, @@ -53,7 +52,7 @@ function url_inject(details) if (targets.policy) targets.target = ""; - let [pattern, settings] = query_best(targets.base_url); + let [pattern, settings] = query_best(storage, targets.base_url); /* Defaults */ if (!pattern) settings = {}; @@ -106,7 +105,6 @@ function headers_inject(details) async function start_policy_injector() { storage = await get_storage(); - query_best = await get_query_best(); let extra_opts = ["blocking", "responseHeaders"]; if (is_chrome) diff --git a/background/settings_query.js b/background/settings_query.js deleted file mode 100644 index d0d9511..0000000 --- a/background/settings_query.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Hachette querying page settings with regard to wildcard records - * - * Copyright (C) 2021 Wojtek Kosior - * Redistribution terms are gathered in the `copyright' file. - */ - -/* - * IMPORTS_START - * IMPORT make_once - * IMPORT get_storage - * IMPORT TYPE_PREFIX - * IMPORT for_each_possible_pattern - * IMPORTS_END - */ - -var storage; - -async function init(fun) -{ - storage = await get_storage(); - - return fun; -} - -function check_pattern(pattern, multiple, matched) -{ - const settings = storage.get(TYPE_PREFIX.PAGE, pattern); - - if (settings === undefined) - return; - - matched.push([pattern, settings]); - - if (!multiple) - return false; -} - -function query(url, multiple) -{ - const matched = []; - for_each_possible_pattern(url, p => check_pattern(p, multiple, matched)); - - return multiple ? matched : (matched[0] || [undefined, undefined]); -} - -function query_best(url) -{ - return query(url, false); -} - -function query_all(url) -{ - return query(url, true); -} - -const get_query_best = make_once(() => init(query_best)); -const get_query_all = make_once(() => init(query_all)); - -/* - * EXPORTS_START - * EXPORT get_query_best - * EXPORT get_query_all - * EXPORTS_END - */ diff --git a/common/settings_query.js b/common/settings_query.js new file mode 100644 index 0000000..e85ae63 --- /dev/null +++ b/common/settings_query.js @@ -0,0 +1,52 @@ +/** + * Hachette querying page settings with regard to wildcard records + * + * Copyright (C) 2021 Wojtek Kosior + * Redistribution terms are gathered in the `copyright' file. + */ + +/* + * IMPORTS_START + * IMPORT TYPE_PREFIX + * IMPORT for_each_possible_pattern + * IMPORTS_END + */ + +function check_pattern(storage, pattern, multiple, matched) +{ + const settings = storage.get(TYPE_PREFIX.PAGE, pattern); + + if (settings === undefined) + return; + + matched.push([pattern, settings]); + + if (!multiple) + return false; +} + +function query(storage, url, multiple) +{ + const matched = []; + const cb = p => check_pattern(storage, p, multiple, matched); + for_each_possible_pattern(url, cb); + + return multiple ? matched : (matched[0] || [undefined, undefined]); +} + +function query_best(storage, url) +{ + return query(storage, url, false); +} + +function query_all(storage, url) +{ + return query(storage, url, true); +} + +/* + * EXPORTS_START + * EXPORT query_best + * EXPORT query_all + * EXPORTS_END + */ -- cgit v1.2.3 From 792fbe187bdffca4a748e88d66ea29f8936ae5c8 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 6 Aug 2021 17:17:45 +0200 Subject: Facilitate installation of scripts from the repository This commit includes: * removal of page_info_server * running of storage client in popup context * extraction of some common CSS to a separate file * extraction of scripts import view to a separate file * addition of a facility to conveniently clone complex structures from DOM (in DOM_helpers.js) * addition of hydrilla repo url to default settings * other minor changes and of course changes related to the actual installation of scripts from the repo --- background/main.js | 2 - background/page_info_server.js | 72 -------- build.sh | 1 + common/connection_types.js | 3 +- common/misc.js | 14 ++ common/sanitize_JSON.js | 2 +- common/stored_types.js | 4 +- content/activity_info_server.js | 32 +++- content/main.js | 3 - content/repo_query.js | 111 ++++++++---- copyright | 4 +- default_settings.json | 3 + html/DOM_helpers.js | 41 +++++ html/base.css | 44 +++++ html/display-panel.html | 123 +++++++------ html/display-panel.js | 392 ++++++++++++++++++++++++++++++++++------ html/import_frame.html | 27 +++ html/import_frame.js | 163 +++++++++++++++++ html/options.html | 47 +---- html/options_main.js | 160 +++------------- 20 files changed, 830 insertions(+), 418 deletions(-) delete mode 100644 background/page_info_server.js create mode 100644 html/DOM_helpers.js create mode 100644 html/base.css create mode 100644 html/import_frame.html create mode 100644 html/import_frame.js (limited to 'background') diff --git a/background/main.js b/background/main.js index ffa814e..7c50fd5 100644 --- a/background/main.js +++ b/background/main.js @@ -12,7 +12,6 @@ * IMPORT start_storage_server * IMPORT start_page_actions_server * IMPORT start_policy_injector - * IMPORT start_page_info_server * IMPORT browser * IMPORTS_END */ @@ -20,7 +19,6 @@ start_storage_server(); start_page_actions_server(); start_policy_injector(); -start_page_info_server(); async function init_ext(install_details) { diff --git a/background/page_info_server.js b/background/page_info_server.js deleted file mode 100644 index e915011..0000000 --- a/background/page_info_server.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * 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 query_all - * IMPORT TYPE_PREFIX - * IMPORT CONNECTION_TYPE - * IMPORT url_matches - * IMPORTS_END - */ - -var storage; - -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(storage, url)]); -} - -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( - () => storage.remove_change_listener(_handle_change) - ); -} - -async function start_page_info_server() -{ - storage = await get_storage(); - - listen_for_connection(CONNECTION_TYPE.PAGE_INFO, new_connection); -} - -/* - * EXPORTS_START - * EXPORT start_page_info_server - * EXPORTS_END - */ diff --git a/build.sh b/build.sh index d940176..675dc2c 100755 --- a/build.sh +++ b/build.sh @@ -273,6 +273,7 @@ $(map_get EXPORTCODES $FILEKEY) fi cp -r copyright licenses/ $BUILDDIR + cp html/*.css $BUILDDIR/html mkdir $BUILDDIR/icons cp icons/*.png $BUILDDIR/icons } diff --git a/common/connection_types.js b/common/connection_types.js index 41bde75..88c6964 100644 --- a/common/connection_types.js +++ b/common/connection_types.js @@ -13,8 +13,7 @@ const CONNECTION_TYPE = { REMOTE_STORAGE : "0", PAGE_ACTIONS : "1", - PAGE_INFO : "2", - ACTIVITY_INFO : "3" + ACTIVITY_INFO : "2" }; /* diff --git a/common/misc.js b/common/misc.js index a59ec14..7158d32 100644 --- a/common/misc.js +++ b/common/misc.js @@ -12,6 +12,7 @@ * IMPORT browser * IMPORT is_chrome * IMPORT TYPE_NAME + * IMPORT TYPE_PREFIX * IMPORTS_END */ @@ -154,6 +155,18 @@ function sign_policy(policy, now, hours_offset) { return gen_unique(time + policy); } +/* Regexes and objest to use as/in schemas for parse_json_with_schema(). */ +const nonempty_string_matcher = /.+/; + +const matchers = { + sha256: /^[0-9a-f]{64}$/, + nonempty_string: nonempty_string_matcher, + component: [ + new RegExp(`^[${TYPE_PREFIX.SCRIPT}${TYPE_PREFIX.BAG}]$`), + nonempty_string_matcher + ] +}; + /* * EXPORTS_START * EXPORT gen_nonce @@ -165,5 +178,6 @@ function sign_policy(policy, now, hours_offset) { * EXPORT nice_name * EXPORT open_in_settings * EXPORT is_privileged_url + * EXPORT matchers * EXPORTS_END */ diff --git a/common/sanitize_JSON.js b/common/sanitize_JSON.js index 8268d3e..8b86d2d 100644 --- a/common/sanitize_JSON.js +++ b/common/sanitize_JSON.js @@ -37,7 +37,7 @@ function sanitize_unknown(schema, item) let _default = undefined; if (!Array.isArray(schema) || schema[1] === "matchentry" || - schema.length < 2 || !["ordefault", "or"].includes(schema)) + schema.length < 2 || !["ordefault", "or"].includes(schema[1])) return sanitize_unknown_no_alternatives(schema, item); if ((schema.length & 1) !== 1) { diff --git a/common/stored_types.js b/common/stored_types.js index 304842b..bfceba6 100644 --- a/common/stored_types.js +++ b/common/stored_types.js @@ -18,7 +18,9 @@ const TYPE_PREFIX = { PAGE : "p", BAG : "b", SCRIPT : "s", - VAR : "_" + VAR : "_", + /* Url prefix is not used in stored settings. */ + URL : "u" }; const TYPE_NAME = { diff --git a/content/activity_info_server.js b/content/activity_info_server.js index a1384e9..81a25fb 100644 --- a/content/activity_info_server.js +++ b/content/activity_info_server.js @@ -11,14 +11,20 @@ * IMPORTS_START * IMPORT listen_for_connection * IMPORT CONNECTION_TYPE - * IMPORT set_repo_query_repos - * IMPORT set_repo_query_callback + * IMPORT repo_query + * IMPORT subscribe_repo_query_results + * IMPORT unsubscribe_repo_query_results * IMPORTS_END */ var activities = []; var ports = new Set(); +function report_activity_oneshot(name, data, port) +{ + port.postMessage([name, data]); +} + function report_activity(name, data) { const activity = [name, data]; @@ -35,20 +41,23 @@ function report_script(script_data) function report_settings(settings) { - const [pattern, settings_data, repos] = settings; - set_repo_query_repos(repos); - report_activity("settings", settings); } -function report_repo_query_result(result) +function report_repo_query_action(update, port) { - report_activity("repo_query_result", result); + report_activity_oneshot("repo_query_action", update, port); } -function trigger_repo_query() +function trigger_repo_query(query_specifier) { - set_repo_query_callback(report_repo_query_result); + repo_query(...query_specifier); +} + +function handle_disconnect(port, report_action) +{ + ports.delete(port) + unsubscribe_repo_query_results(report_action); } function new_connection(port) @@ -60,13 +69,16 @@ function new_connection(port) for (const activity of activities) port.postMessage(activity); + const report_action = u => report_repo_query_action(u, port); + subscribe_repo_query_results(report_action); + /* * So far the only thing we expect to receive is repo query order. Once more * possibilities arrive, we will need to complicate this listener. */ port.onMessage.addListener(trigger_repo_query); - port.onDisconnect.addListener(() => ports.delete(port)); + port.onDisconnect.addListener(() => handle_disconnect(port, report_action)); } function start_activity_info_server() diff --git a/content/main.js b/content/main.js index 437a32b..8f8375e 100644 --- a/content/main.js +++ b/content/main.js @@ -20,7 +20,6 @@ * IMPORT is_chrome * IMPORT is_mozilla * IMPORT start_activity_info_server - * IMPORT set_repo_query_url * IMPORTS_END */ @@ -130,6 +129,4 @@ if (!is_privileged_url(document.URL)) { } start_activity_info_server(); - - set_repo_query_url(document.URL); } diff --git a/content/repo_query.js b/content/repo_query.js index b8c8ed9..3708108 100644 --- a/content/repo_query.js +++ b/content/repo_query.js @@ -9,72 +9,105 @@ /* * IMPORTS_START * IMPORT make_ajax_request + * IMPORT observables + * IMPORT TYPE_PREFIX + * IMPORT parse_json_with_schema + * IMPORT matchers * IMPORTS_END */ -var query_started = false; +const paths = { + [TYPE_PREFIX.PAGE]: "/pattern", + [TYPE_PREFIX.BAG]: "/bag", + [TYPE_PREFIX.SCRIPT]: "/script", + [TYPE_PREFIX.URL]: "/query" +}; -var url = undefined; -var repos = undefined; -var callback = undefined; +const queried_items = new Map(); +const observable = observables.make(); -async function query(repo) +function repo_query(prefix, item, repo_urls) { - const [repo_url, data] = repo; + const key = prefix + item; - let response = "Query failed"; - const query_url = `${repo_url}/query?n=${encodeURIComponent(url)}`; + const results = queried_items.get(key) || {}; + queried_items.set(key, results); - try { - let xhttp = await make_ajax_request("GET", query_url); - if (xhttp.status === 200) - response = xhttp.responseText; - console.log(xhttp); - } catch (e) { - console.log(e); - } + for (const repo_url of repo_urls) + perform_query_against(key, repo_url, results); +} - callback([repo_url, response]); +const page_schema = { + pattern: matchers.nonempty_string, + payload: ["optional", matchers.component, "default", undefined] +}; +const bag_schema = { + name: matchers.nonempty_string, + components: ["optional", [matchers.component, "repeat"], "default", []] +}; +const script_schema = { + name: matchers.nonempty_string, + location: matchers.nonempty_string, + sha256: matchers.sha256, +}; +const search_result_schema = [page_schema, "repeat"]; + +const schemas = { + [TYPE_PREFIX.PAGE]: page_schema, + [TYPE_PREFIX.BAG]: bag_schema, + [TYPE_PREFIX.SCRIPT]: script_schema, + [TYPE_PREFIX.URL]: search_result_schema } -function start_query() +async function perform_query_against(key, repo_url, results) { - if (query_started || !url || !repos || !callback) + if (results[repo_url] !== undefined) return; - query_started = true; + const prefix = key[0]; + const item = key.substring(1); + const result = {state: "started"}; + results[repo_url] = result; - console.log(`about to query ${url} from ${repos}`); + const broadcast_msg = {prefix, item, results: {[repo_url]: result}}; + observables.broadcast(observable, broadcast_msg); - for (const repo of repos) - query(repo); -} + let state = "connection_error"; + const query_url = + `${repo_url}${paths[prefix]}?n=${encodeURIComponent(item)}`; -function set_repo_query_url(_url) -{ - url = _url; + try { + let xhttp = await make_ajax_request("GET", query_url); + if (xhttp.status === 200) { + state = "parse_error"; + result.response = + parse_json_with_schema(schemas[prefix], xhttp.responseText); + state = "completed"; + } + } catch (e) { + console.log(e); + } - start_query(); + result.state = state; + observables.broadcast(observable, broadcast_msg); } -function set_repo_query_repos(_repos) +function subscribe_repo_query_results(cb) { - repos = _repos; - - start_query(); + observables.subscribe(observable, cb); + for (const [key, results] of queried_items.entries()) + cb({prefix: key[0], item: key.substring(1), results}); } -function set_repo_query_callback(_callback) +function unsubscribe_repo_query_results(cb) { - callback = _callback; - - start_query(); + observables.unsubscribe(observable, cb); } /* * EXPORTS_START - * EXPORT set_repo_query_url - * EXPORT set_repo_query_repos - * EXPORT set_repo_query_callback + * EXPORT repo_query + * EXPORT subscribe_repo_query_results + * EXPORT unsubscribe_repo_query_results * EXPORTS_END */ diff --git a/copyright b/copyright index 96de092..05a16aa 100644 --- a/copyright +++ b/copyright @@ -20,11 +20,11 @@ Copyright: 2021 Wojtek Kosior 2021 jahoti License: GPL-3+-javascript or Alicense-1.0 -Files: README.txt copyright +Files: *.html README.txt copyright Copyright: 2021 Wojtek Kosior License: GPL-3+ or Alicense-1.0 or CC-BY-SA-4.0 -Files: *.html +Files: html/base.css Copyright: 2021 Wojtek Kosior 2021 Nicholas Johnson License: GPL-3+ or Alicense-1.0 or CC-BY-SA-4.0 diff --git a/default_settings.json b/default_settings.json index 8656381..14856fe 100644 --- a/default_settings.json +++ b/default_settings.json @@ -43,5 +43,8 @@ "phttps://www.worldcat.org/title/**": { "components": ["s", "worldcat (library holdings)"] } + }, + { + "rhttps://hydrilla.koszko.org": {} } ] diff --git a/html/DOM_helpers.js b/html/DOM_helpers.js new file mode 100644 index 0000000..2bff966 --- /dev/null +++ b/html/DOM_helpers.js @@ -0,0 +1,41 @@ +/** + * Hachette operations on DOM elements + * + * Copyright (C) 2021 Wojtek Kosior + * Redistribution terms are gathered in the `copyright' file. + */ + +function by_id(id) +{ + return document.getElementById(id); +} + +function clone_template(template_id) +{ + const clone = document.getElementById(template_id).cloneNode(true); + const result_object = {}; + const to_process = [clone]; + + while (to_process.length > 0) { + const element = to_process.pop(); + const template_key = element.getAttribute("data-template"); + + if (template_key) + result_object[template_key] = element; + + element.removeAttribute("id"); + element.removeAttribute("template_key"); + + for (const child of element.children) + to_process.push(child); + } + + return result_object; +} + +/* + * EXPORTS_START + * EXPORT by_id + * EXPORT clone_template + * EXPORTS_END + */ diff --git a/html/base.css b/html/base.css new file mode 100644 index 0000000..2256833 --- /dev/null +++ b/html/base.css @@ -0,0 +1,44 @@ +/** + * Hachette base styles + * + * Copyright (C) 2021 Wojtek Kosior + * Copyright (C) 2021 Nicholas Johnson + * Redistribution terms are gathered in the `copyright' file. + */ + +input[type="checkbox"], input[type="radio"], .hide { + display: none; +} + +.show_next:not(:checked)+* { + display: none; +} + +.show_hide_next2:not(:checked)+* { + display: none; +} + +.show_hide_next2:checked+*+* { + display: none; +} + +button, .button { + background-color: #4CAF50; + border: none; + border-radius: 8px; + color: white; + text-align: center; + text-decoration: none; + display: inline-block; + padding: 6px 12px; + margin: 2px 0px; +} + +button.slimbutton, .button.slimbutton { + padding: 2px 4px; + margin: 0; +} + +button:hover, .button:hover { + box-shadow: 0 6px 8px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19); +} diff --git a/html/display-panel.html b/html/display-panel.html index d8d7f5d..1b9c77b 100644 --- a/html/display-panel.html +++ b/html/display-panel.html @@ -7,35 +7,25 @@ Hachette - page settings + @@ -118,11 +98,6 @@

    • -
    • - - - -
    @@ -243,25 +218,7 @@ diff --git a/html/options_main.js b/html/options_main.js index 6aed8bb..830c860 100644 --- a/html/options_main.js +++ b/html/options_main.js @@ -13,26 +13,23 @@ * IMPORT list_prefixes * IMPORT nice_name * IMPORT parse_json_with_schema + * IMPORT by_id + * IMPORT matchers + * IMPORT get_import_frame * IMPORTS_END */ var storage; -function by_id(id) -{ - return document.getElementById(id); -} const item_li_template = by_id("item_li_template"); const bag_component_li_template = by_id("bag_component_li_template"); const chbx_component_li_template = by_id("chbx_component_li_template"); const radio_component_li_template = by_id("radio_component_li_template"); -const import_li_template = by_id("import_li_template"); /* Make sure they are later cloned without id. */ item_li_template.removeAttribute("id"); bag_component_li_template.removeAttribute("id"); chbx_component_li_template.removeAttribute("id"); radio_component_li_template.removeAttribute("id"); -import_li_template.removeAttribute("id"); function item_li_id(prefix, item) { @@ -224,7 +221,6 @@ function reset_work_bag_li(ul, item, components) ul.work_li.insertBefore(bag_components_ul, old_components_ul); ul.work_li.removeChild(old_components_ul); - console.log("bag components", components); add_bag_components(components); } @@ -519,12 +515,6 @@ const ul_by_prefix = { } } -const import_window = by_id("import_window"); -const import_loading_radio = by_id("import_loading_radio"); -const import_failed_radio = by_id("import_failed_radio"); -const import_selection_radio = by_id("import_selection_radio"); -const bad_file_errormsg = by_id("bad_file_errormsg"); - /* * Newer browsers could utilise `text' method of File objects. * Older ones require FileReader. @@ -545,31 +535,30 @@ function read_file(file) _read_file(file, resolve, reject)); } -const url_regex = /^[a-z0-9]+:\/\/[^/]+\.[^/]{2}(\/[^?#]*)?$/; -const sha256_regex = /^[0-9a-f]{64}$/; -const component_schema = [ - new RegExp(`^[${TYPE_PREFIX.SCRIPT}${TYPE_PREFIX.BAG}]$`), - /.+/ -]; +const url_regex = /^[a-z0-9]+:\/\/[^/]+\.[^/]{2,}(\/[^?#]*)?$/; +const empty_regex = /^$/; const settings_schema = [ [{}, "matchentry", "minentries", 1, new RegExp(`^${TYPE_PREFIX.SCRIPT}`), { /* script data */ - "url": ["optional", url_regex], - "sha256": ["optional", sha256_regex], + "url": ["optional", url_regex, "or", empty_regex], + "sha256": ["optional", matchers.sha256, "or", empty_regex], "text": ["optional", "string"] }, new RegExp(`^${TYPE_PREFIX.BAG}`), [ "optional", - [component_schema, "repeat"], + [matchers.component, "repeat"], "default", undefined ], new RegExp(`^${TYPE_PREFIX.PAGE}`), { /* page data */ - "components": ["optional", component_schema] + "components": ["optional", matchers.component] }], "repeat" -] +]; + +const import_window = by_id("import_window"); +let import_frame; async function import_from_file(event) { @@ -578,86 +567,17 @@ async function import_from_file(event) return; import_window.classList.remove("hide"); - import_loading_radio.checked = true; - - let result = undefined; + import_frame.show_loading(); try { - result = parse_json_with_schema(settings_schema, - await read_file(files[0])); + const file = await read_file(files[0]); + var result = parse_json_with_schema(settings_schema, file); } catch(e) { - bad_file_errormsg.textContent = "" + e; - import_failed_radio.checked = true; + import_frame.show_error("Bad file :(", "" + e); return; } - populate_import_list(result); - import_selection_radio.checked = true; -} - -function import_li_id(prefix, item) -{ - return `ili_${prefix}_${item}`; -} - -let import_ul = by_id("import_ul"); -let import_chbxs_colliding = undefined; -let settings_import_map = undefined; - -function populate_import_list(settings) -{ - let old_children = import_ul.children; - while (old_children[0] !== undefined) - import_ul.removeChild(old_children[0]); - - import_chbxs_colliding = []; - settings_import_map = new Map(); - - for (let setting of settings) { - let [key, value] = Object.entries(setting)[0]; - let prefix = key[0]; - let name = key.substring(1); - add_import_li(prefix, name); - settings_import_map.set(key, value); - } -} - -function add_import_li(prefix, name) -{ - let li = import_li_template.cloneNode(true); - let name_span = li.firstElementChild; - let chbx = name_span.nextElementSibling; - let warning_span = chbx.nextElementSibling; - - li.setAttribute("data-prefix", prefix); - li.setAttribute("data-name", name); - li.id = import_li_id(prefix, name); - name_span.textContent = nice_name(prefix, name); - - if (storage.get(prefix, name) !== undefined) { - import_chbxs_colliding.push(chbx); - warning_span.textContent = "(will overwrite existing setting!)"; - } - - import_ul.appendChild(li); -} - -function check_all_imports() -{ - for (let li of import_ul.children) - li.firstElementChild.nextElementSibling.checked = true; -} - -function uncheck_all_imports() -{ - for (let li of import_ul.children) - li.firstElementChild.nextElementSibling.checked = false; -} - -function uncheck_colliding_imports() -{ - for (let chbx of import_chbxs_colliding) - chbx.checked = false; + import_frame.show_selection(result); } const file_opener_form = by_id("file_opener_form"); @@ -665,9 +585,6 @@ const file_opener_form = by_id("file_opener_form"); function hide_import_window() { import_window.classList.add("hide"); - /* Let GC free some memory */ - import_chbxs_colliding = undefined; - settings_import_map = undefined; /* * Reset file . Without this, a second attempt to import the same @@ -676,43 +593,16 @@ function hide_import_window() file_opener_form.reset(); } -function commit_import() -{ - for (let li of import_ul.children) { - let chbx = li.firstElementChild.nextElementSibling; - - if (!chbx.checked) - continue; - - let prefix = li.getAttribute("data-prefix"); - let name = li.getAttribute("data-name"); - let key = prefix + name; - let value = settings_import_map.get(key); - storage.set(prefix, name, value); - } - - hide_import_window(); -} - -function initialize_import_facility() +async function initialize_import_facility() { let import_but = by_id("import_but"); let file_opener = by_id("file_opener"); - let import_failok_but = by_id("import_failok_but"); - let check_all_import_but = by_id("check_all_import_but"); - let uncheck_all_import_but = by_id("uncheck_all_import_but"); - let uncheck_existing_import_but = by_id("uncheck_existing_import_but"); - let commit_import_but = by_id("commit_import_but"); - let cancel_import_but = by_id("cancel_import_but"); + import_but.addEventListener("click", () => file_opener.click()); file_opener.addEventListener("change", import_from_file); - import_failok_but.addEventListener("click", hide_import_window); - check_all_import_but.addEventListener("click", check_all_imports); - uncheck_all_import_but.addEventListener("click", uncheck_all_imports); - uncheck_colliding_import_but - .addEventListener("click", uncheck_colliding_imports); - commit_import_but.addEventListener("click", commit_import); - cancel_import_but.addEventListener("click", hide_import_window); + + import_frame = await get_import_frame(); + import_frame.onclose = hide_import_window; } /* @@ -784,9 +674,9 @@ async function main() jump_to_item(document.URL); - initialize_import_facility(); - storage.add_change_listener(handle_change); + + await initialize_import_facility(); } function handle_change(change) -- cgit v1.2.3