/** * This file is part of Haketilo. * * Function: Show details of how Haketilo handled given page, drive popup. * * Copyright (C) 2021,2022 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 <https://www.gnu.org/licenses/>. * * I, Wojtek Kosior, thereby promise not to sue for violation of this file's * license. Although I request that you do not make use of this code in a * proprietary program, I am not going to enforce this in court. */ #FROM common/browser.js IMPORT browser #FROM common/misc.js IMPORT is_privileged_url #FROM html/DOM_helpers.js IMPORT by_id #FROM html/repo_query.js IMPORT RepoQueryView const tab_query = {currentWindow: true, active: true}; async function get_current_tab() { #IF CHROMIUM const callback = (cb) => browser.tabs.query(tab_query, tab => cb(tab)); const promise = new Promise(callback); #ELIF MOZILLA const promise = browser.tabs.query(tab_query); #ENDIF try { return (await promise)[0]; } catch(e) { console.log("Haketilo:", e); } } async function get_page_info(tab_id) { return browser.tabs.sendMessage(tab_id, ["page_info"]); } function show_page_info(page_info) { by_id("loading_info").remove(); by_id("info_form").classList.remove("hide"); by_id("page_url").innerText = page_info.url; if (page_info.privileged) { by_id("privileged_page_info").classList.remove("hide"); } else { by_id("unprivileged_page_info").classList.remove("hide"); by_id("scripts_blocked").innerText = page_info.allow ? "no" : "yes"; let payload_text = "None"; if (page_info.payload) { if ("error" in page_info) { let long_msg = true; if (page_info.error.haketilo_error_type === "missing") payload_text = `None (error: resource with id '${page_info.error.id}' missing from the database)`; else if (page_info.error.haketilo_error_type === "circular") payload_text = `None (error: circular dependency of resource with id '${page_info.error.id}' on itself)`; else if (page_info.error.haketilo_error_type === "db") payload_text = `None (error: failure reading Haketilo internal database)`; else if (page_info.error.haketilo_error_type === "other") payload_text = `None (error: unknown failure occured)`; else long_msg = false; if (long_msg) by_id("injected_payload").classList.add("long_msg"); } else { payload_text = page_info.payload.identifier; } } by_id("injected_payload").innerText = payload_text; const scripts_fate = page_info.allow ? "allowed" : "blocked"; let mapping_text, long_msg = true; if (page_info.mapping === "~allow") { mapping_text = `None (scripts ${scripts_fate} by a rule)`; } else if ("error" in page_info && page_info.error.haketilo_error_type === "deciding_policy") { mapping_text = `None (error occured when determining policy)`; } else if (page_info.mapping) { mapping_text = page_info.mapping; long_msg = false; } else { mapping_text = `None (scripts ${scripts_fate} by default policy)`; } by_id("mapping_used").innerText = mapping_text; if (long_msg) by_id("mapping_used").classList.add("long_msg"); } } function repo_query_showing(show) { for (const [id, i] of [["repo_query", 0], ["page_info", 1]]) by_id(`${id}_container`).classList[["add", "remove"][show ^ i]]("hide"); } function prepare_repo_query_view(tab, page_info) { const repo_query_view = new RepoQueryView(tab, () => repo_query_showing(true), () => repo_query_showing(false)); by_id("repo_query_container").prepend(repo_query_view.main_div); let search_cb = () => repo_query_view.show(page_info.url); search_cb = repo_query_view.when_hidden(search_cb); by_id("search_resources_but").addEventListener("click", search_cb); by_id("search_resources_but").classList.remove("hide"); } async function main() { const settings_opener = (e) => browser.runtime.openOptionsPage(); by_id("settings_but").addEventListener("click", settings_opener); try { var tab = await get_current_tab(); var tab_id = tab.id; if (is_privileged_url(tab.url)) var page_info = {privileged: true, url: tab.url}; else var page_info = await get_page_info(tab_id); } catch(e) { console.error("Haketilo:", e); } if (page_info) { show_page_info(page_info); if (!page_info.privileged) prepare_repo_query_view(tab, page_info); } else { by_id("loading_info").innerText = "Page info not avaialable. Try reloading the page."; } } main();