From b590eaa2f64ead3384eadc6fe58f6358aa1a0478 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 22 Dec 2021 16:39:34 +0100 Subject: reworked build system; added missing license notices --- html/display-panel.js | 590 -------------------------------------------------- 1 file changed, 590 deletions(-) delete mode 100644 html/display-panel.js (limited to 'html/display-panel.js') diff --git a/html/display-panel.js b/html/display-panel.js deleted file mode 100644 index d48d254..0000000 --- a/html/display-panel.js +++ /dev/null @@ -1,590 +0,0 @@ -/** - * This file is part of Haketilo. - * - * Function: Popup logic. - * - * Copyright (C) 2021 Wojtek Kosior - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * As additional permission under GNU GPL version 3 section 7, you - * may distribute forms of that code without the copy of the GNU - * GPL normally required by section 4, provided you include this - * license notice and, in case of non-source distribution, a URL - * through which recipients can access the Corresponding Source. - * If you modify file(s) with this exception, you may extend this - * exception to your version of the file(s), but you are not - * obligated to do so. If you do not wish to do so, delete this - * exception statement from your version. - * - * As a special exception to the GPL, any HTML file which merely - * makes function calls to this code, and for that purpose - * includes it by reference shall be deemed a separate work for - * copyright law purposes. If you modify this code, you may extend - * this exception to your version of the code, but you are not - * obligated to do so. If you do not wish to do so, delete this - * exception statement from your version. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * I, Wojtek Kosior, thereby promise not to sue for violation of this file's - * license. Although I request that you do not make use this code in a - * proprietary program, I am not going to enforce this in court. - */ - -/* - * IMPORTS_START - * IMPORT browser - * IMPORT is_chrome - * IMPORT is_mozilla - *** Using remote storage here seems inefficient, we only resort to that - *** temporarily, before all storage access gets reworked. - * IMPORT get_remote_storage - * IMPORT get_import_frame - * IMPORT init_default_policy_dialog - * IMPORT query_all - * IMPORT CONNECTION_TYPE - * IMPORT is_privileged_url - * IMPORT TYPE_PREFIX - * IMPORT nice_name - * IMPORT open_in_settings - * IMPORT each_url_pattern - * IMPORT by_id - * IMPORT clone_template - * IMPORTS_END - */ - -let storage; -let tab_url; - -/* Force popup 's reflow on stupid Firefox. */ -if (is_mozilla) { - const reflow_forcer = - () => document.documentElement.style.width = "-moz-fit-content"; - for (const radio of document.querySelectorAll('[name="current_view"]')) - radio.addEventListener("change", reflow_forcer); -} - -const show_queried_view_radio = by_id("show_queried_view_radio"); - -const tab_query = {currentWindow: true, active: true}; - -async function get_current_tab() -{ - /* Fix for fact that Chrome does not use promises here */ - const promise = is_chrome ? - new Promise((resolve, reject) => - browser.tabs.query(tab_query, tab => resolve(tab))) : - browser.tabs.query(tab_query); - - try { - return (await promise)[0]; - } catch(e) { - console.log(e); - } -} - -const page_url_heading = by_id("page_url_heading"); -const privileged_notice = by_id("privileged_notice"); -const page_state = by_id("page_state"); - -/* Helper functions to convert string into a list of one-letter 's. */ -function char_to_span(char, doc) -{ - const span = document.createElement("span"); - span.textContent = char; - return span; -} - -function to_spans(string, doc=document) -{ - return string.split("").map(c => char_to_span(c, doc)); -} - -async function show_page_activity_info() -{ - const tab = await get_current_tab(); - - if (tab === undefined) { - page_url_heading.textContent = "unknown page"; - return; - } - - tab_url = /^([^?#]*)/.exec(tab.url)[1]; - to_spans(tab_url).forEach(s => page_url_heading.append(s)); - if (is_privileged_url(tab_url)) { - privileged_notice.classList.remove("hide"); - return; - } - - populate_possible_patterns_list(tab_url); - page_state.classList.remove("hide"); - - try_to_connect(tab.id); -} - -const possible_patterns_list = by_id("possible_patterns"); -const known_patterns = new Map(); - -function add_pattern_to_list(pattern) -{ - const template = clone_template("pattern_entry"); - template.name.textContent = pattern; - - const settings_opener = () => open_in_settings(TYPE_PREFIX.PAGE, pattern); - template.button.addEventListener("click", settings_opener); - - known_patterns.set(pattern, template); - possible_patterns_list.append(template.entry); - - return template; -} - -function style_possible_pattern_entry(pattern, exists_in_settings) -{ - const [text, class_action] = exists_in_settings ? - ["Edit", "add"] : ["Add", "remove"]; - const entry_object = known_patterns.get(pattern); - - if (entry_object) { - entry_object.button.textContent = `${text} setting`; - entry_object.entry.classList[class_action]("matched_pattern"); - } -} - -function handle_page_change(change) -{ - style_possible_pattern_entry(change.item, change.new_val !== undefined); -} - -function populate_possible_patterns_list(url) -{ - for (const pattern of each_url_pattern(url)) - add_pattern_to_list(pattern); - - for (const [pattern, settings] of query_all(storage, url)) - style_possible_pattern_entry(pattern, true); - - storage.add_change_listener(handle_page_change, [TYPE_PREFIX.PAGE]); -} - -const connected_chbx = by_id("connected_chbx"); -const query_pattern_but = by_id("query_pattern"); - -var content_script_port; - -function try_to_connect(tab_id) -{ - /* This won't connect to iframes. We'll add support for them later */ - const connect_info = {name: CONNECTION_TYPE.ACTIVITY_INFO, frameId: 0}; - content_script_port = browser.tabs.connect(tab_id, connect_info); - - const disconnect_cb = () => handle_disconnect(tab_id, start_querying_repos); - content_script_port.onDisconnect.addListener(disconnect_cb); - content_script_port.onMessage.addListener(handle_activity_report); - - query_pattern_but.addEventListener("click", start_querying_repos); - - if (is_mozilla) - setTimeout(() => monitor_connecting(tab_id), 1000); -} - -function start_querying_repos() -{ - query_pattern_but.removeEventListener("click", start_querying_repos); - const repo_urls = storage.get_all_names(TYPE_PREFIX.REPO); - if (content_script_port) - content_script_port.postMessage([TYPE_PREFIX.URL, tab_url, repo_urls]); -} - -const loading_point = by_id("loading_point"); -const reload_notice = by_id("reload_notice"); - -function handle_disconnect(tab_id, button_cb) -{ - query_pattern_but.removeEventListener("click", button_cb); - content_script_port = null; - - if (is_chrome && !browser.runtime.lastError) - return; - - /* return if error was not during connection initialization */ - if (connected_chbx.checked) - return; - - loading_point.classList.toggle("camouflage"); - reload_notice.classList.remove("hide"); - - setTimeout(() => try_to_connect(tab_id), 1000); -} - -function monitor_connecting(tab_id) -{ - if (connected_chbx.checked) - return; - - if (content_script_port) - content_script_port.disconnect(); - else - return; - - loading_point.classList.toggle("camouflage"); - reload_notice.classList.remove("hide"); - try_to_connect(tab_id); -} - -const pattern_span = by_id("pattern"); -const view_pattern_but = by_id("view_pattern"); -const blocked_span = by_id("blocked"); -const payload_span = by_id("payload"); -const payload_buttons_div = by_id("payload_buttons"); -const view_payload_but = by_id("view_payload"); -const view_injected_but = by_id("view_injected"); -const container_for_injected = by_id("container_for_injected"); -const content_type_cell = by_id("content_type"); - -const queried_items = new Map(); - -let max_injected_script_id = 0; - -function handle_activity_report(message) -{ - connected_chbx.checked = true; - - const [type, data] = message; - - if (type === "settings") { - const settings = data; - - blocked_span.textContent = settings.allow ? "no" : "yes"; - - if (settings.pattern) { - pattern_span.textContent = pattern; - const settings_opener = - () => open_in_settings(TYPE_PREFIX.PAGE, settings.pattern); - view_pattern_but.classList.remove("hide"); - view_pattern_but.addEventListener("click", settings_opener); - } else { - pattern_span.textContent = "none"; - blocked_span.textContent = blocked_span.textContent + " (default)"; - } - - if (settings.payload) { - payload_span.textContent = nice_name(...settings.payload); - payload_buttons_div.classList.remove("hide"); - const settings_opener = () => open_in_settings(...settings.payload); - view_payload_but.addEventListener("click", settings_opener); - } else { - payload_span.textContent = "none"; - } - } - if (type === "script") { - const template = clone_template("injected_script"); - const chbx_id = `injected_script_${max_injected_script_id++}`; - template.chbx.id = chbx_id; - template.lbl.setAttribute("for", chbx_id); - template.script_contents.textContent = data; - container_for_injected.appendChild(template.div); - } - if (type === "is_html") { - if (!data) - content_type_cell.classList.remove("hide"); - } - if (type === "repo_query_action") { - const key = data.prefix + data.item; - const results = queried_items.get(key) || {}; - Object.assign(results, data.results); - queried_items.set(key, results); - - const action = data.prefix === TYPE_PREFIX.URL ? - show_query_result : record_fetched_install_dep; - - for (const [repo_url, result] of Object.entries(data.results)) - action(data.prefix, data.item, repo_url, result); - } -} - -const container_for_repo_responses = by_id("container_for_repo_responses"); - -const results_lists = new Map(); - -function create_results_list(url) -{ - const cloned_template = clone_template("multi_repos_query_result"); - cloned_template.url_span.textContent = url; - container_for_repo_responses.appendChild(cloned_template.div); - - cloned_template.by_repo = new Map(); - results_lists.set(url, cloned_template); - - return cloned_template; -} - -function create_result_item(list_object, repo_url, result) -{ - const cloned_template = clone_template("single_repo_query_result"); - cloned_template.repo_url.textContent = repo_url; - cloned_template.appended = null; - - list_object.ul.appendChild(cloned_template.li); - list_object.by_repo.set(repo_url, cloned_template); - - return cloned_template; -} - -function set_appended(result_item, element) -{ - if (result_item.appended) - result_item.appended.remove(); - result_item.appended = element; - result_item.li.appendChild(element); -} - -function show_message(result_item, text) -{ - const div = document.createElement("div"); - div.textContent = text; - set_appended(result_item, div); -} - -function showcb(text) -{ - return item => show_message(item, text); -} - -function unroll_chbx_first_checked(entry_object) -{ - if (!entry_object.chbx.checked) - return; - - entry_object.chbx.removeEventListener("change", entry_object.unroll_cb); - delete entry_object.unroll_cb; - - entry_object.unroll.innerHTML = "preview not implemented...
(consider contributing)"; -} - -let import_frame; -let install_target = null; - -function install_abort(error_state) -{ - import_frame.show_error(`Error: ${error_state}`); - install_target = null; -} - -/* - * Translate objects from the format in which they are sent by Hydrilla to the - * format in which they are stored in settings. - */ - -function translate_script(script_object, repo_url) -{ - return { - [TYPE_PREFIX.SCRIPT + script_object.name]: { - hash: script_object.sha256, - url: `${repo_url}/content/${script_object.location}` - } - }; -} - -function translate_bag(bag_object) -{ - return { - [TYPE_PREFIX.BAG + bag_object.name]: bag_object.components - }; -} - -const format_translators = { - [TYPE_PREFIX.BAG]: translate_bag, - [TYPE_PREFIX.SCRIPT]: translate_script -}; - -function install_check_ready() -{ - if (install_target.to_fetch.size > 0) - return; - - const page_key = [TYPE_PREFIX.PAGE + install_target.pattern]; - const to_install = [{[page_key]: {components: install_target.payload}}]; - - for (const key of install_target.fetched) { - const old_object = - queried_items.get(key)[install_target.repo_url].response; - const new_object = - format_translators[key[0]](old_object, install_target.repo_url); - to_install.push(new_object); - } - - import_frame.show_selection(to_install); -} - -const possible_errors = ["connection_error", "parse_error"]; - -function fetch_install_deps(components) -{ - const needed = [...components]; - const processed = new Set(); - - while (needed.length > 0) { - const [prefix, item] = needed.pop(); - const key = prefix + item; - processed.add(key); - const results = queried_items.get(key); - let relevant_result = null; - - if (results) - relevant_result = results[install_target.repo_url]; - - if (!relevant_result) { - content_script_port.postMessage([prefix, item, - [install_target.repo_url]]); - install_target.to_fetch.add(key); - continue; - } - - if (possible_errors.includes(relevant_result.state)) { - install_abort(relevant_result.state); - return false; - } - - install_target.fetched.add(key); - - if (prefix !== TYPE_PREFIX.BAG) - continue; - - for (const dependency of relevant_result.response.components) { - if (processed.has(dependency.join(''))) - continue; - needed.push(dependency); - } - } -} - -function record_fetched_install_dep(prefix, item, repo_url, result) -{ - const key = prefix + item; - - if (!install_target || repo_url !== install_target.repo_url || - !install_target.to_fetch.has(key)) - return; - - if (possible_errors.includes(result.state)) { - install_abort(result.state); - return; - } - - if (result.state !== "completed") - return; - - install_target.to_fetch.delete(key); - install_target.fetched.add(key); - - if (prefix === TYPE_PREFIX.BAG && - fetch_install_deps(result.response.components) === false) - return; - - install_check_ready(); -} - -function install_clicked(entry_object) -{ - import_frame.show_loading(); - - install_target = { - repo_url: entry_object.repo_url, - pattern: entry_object.match_object.pattern, - payload: entry_object.match_object.payload, - fetched: new Set(), - to_fetch: new Set() - }; - - fetch_install_deps([install_target.payload]); - - install_check_ready(); -} - -var max_query_result_id = 0; - -function show_query_successful_result(result_item, repo_url, result) -{ - if (result.length === 0) { - show_message(result_item, "No results :("); - return; - } - - const cloned_ul_template = clone_template("result_patterns_list"); - set_appended(result_item, cloned_ul_template.ul); - - for (const match of result) { - const entry_object = clone_template("query_match_li"); - - entry_object.pattern.textContent = match.pattern; - - cloned_ul_template.ul.appendChild(entry_object.li); - - if (!match.payload) { - entry_object.payload.textContent = "(none)"; - for (const key of ["chbx", "triangle", "unroll"]) - entry_object[key].remove(); - continue; - } - - entry_object.payload.textContent = nice_name(...match.payload); - - const install_cb = () => install_clicked(entry_object); - entry_object.btn.addEventListener("click", install_cb); - - const chbx_id = `query_result_${max_query_result_id++}`; - entry_object.chbx.id = chbx_id; - entry_object.lbl.setAttribute("for", chbx_id); - - entry_object.unroll_cb = () => unroll_chbx_first_checked(entry_object); - entry_object.chbx.addEventListener("change", entry_object.unroll_cb); - - entry_object.component_object = match.payload; - entry_object.match_object = match; - entry_object.repo_url = repo_url; - } -} - -function show_query_result(url_prefix, url, repo_url, result) -{ - const results_list_object = results_lists.get(url) || - create_results_list(url); - const result_item = results_list_object.by_repo.get(repo_url) || - create_result_item(results_list_object, repo_url, result); - - const completed_cb = - item => show_query_successful_result(item, repo_url, result.response); - const possible_actions = { - completed: completed_cb, - started: showcb("loading..."), - connection_error: showcb("Error when querying repository."), - parse_error: showcb("Bad data format received.") - }; - possible_actions[result.state](result_item, repo_url); -} - -by_id("settings_but") - .addEventListener("click", (e) => browser.runtime.openOptionsPage()); - -async function main() -{ - init_default_policy_dialog(); - - storage = await get_remote_storage(); - import_frame = await get_import_frame(); - import_frame.onclose = () => show_queried_view_radio.checked = true; - show_page_activity_info(); -} - -main(); -- cgit v1.2.3