From ed08ef1a6df1713a0e00ccd656f4bb4ed44647a4 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Mon, 6 Sep 2021 16:45:36 +0200 Subject: generate Chromium unique key automatically in `build.sh' --- build.sh | 25 +++++++++++++------------ common/signing.js | 16 ++++++++-------- manifest.json | 4 ++-- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/build.sh b/build.sh index 0659ed1..66f709c 100755 --- a/build.sh +++ b/build.sh @@ -200,19 +200,20 @@ main() { GECKO_APPLICATIONS='' if [ "$BROWSER" = "chromium" ]; then + CHROMIUM_KEY="$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64)" + echo "chromium key is" $CHROMIUM_KEY + CHROMIUM_KEY="chromium-key-dummy-file-$CHROMIUM_KEY" + CHROMIUM_KEY=$(echo $CHROMIUM_KEY | tr / -); + touch $BUILDDIR/$CHROMIUM_KEY + CHROMIUM_KEY="\n\ -\n\ - // WARNING!!!\n\ - // EACH USER SHOULD REPLACE \"key\" WITH A UNIQUE VALUE!!!\n\ - // OTHERWISE, SECURITY CAN BE TRIVIALLY COMPROMISED!\n\ - //\n\ - // A unique key can be generated with:\n\ - // $ ssh-keygen -f /path/to/new/key.pem -t rsa -b 1024\n\ - //\n\ - // Only relevant to users of chrome-based browsers.\n\ - // Users of Firefox forks are safe.\n\ -\n\ - \"key\": \"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcnNhAAAAAwEAAQAAAIEA+0GT5WNmRRo8e5tL9+BmNtY6aBPwLIgbPnLShYBMSR40iYwLTsccrkwBXb3bs1o4p6q5WJugI8Lsia+GXZc/XHGFkq7D1aWiTxlJLs8z0JC2TQ2/yatYmBMchogYGeeUfP7aI7JJZwpATts+VhIvgga/4FYj+DijMIEpwdckqFEAAAII4Dh7HOA4exwAAAAHc3NoLXJzYQAAAIEA+0GT5WNmRRo8e5tL9+BmNtY6aBPwLIgbPnLShYBMSR40iYwLTsccrkwBXb3bs1o4p6q5WJugI8Lsia+GXZc/XHGFkq7D1aWiTxlJLs8z0JC2TQ2/yatYmBMchogYGeeUfP7aI7JJZwpATts+VhIvgga/4FYj+DijMIEpwdckqFEAAAADAQABAAAAgEHB5/MhEKMFOs8e1cMJ97ZiWubiUPlWpcqyQmauLUj1nspg3JTBh8AWJEVkaxuFgU5gYCHQmRjC6yUdywyziOEkFA4r/WpX4WmbIe+GQHRHhitLN0dgF8N6/fVNOoa5StTdfZqyl23pVXyepoDNjrJFKyupqPMmpwfH5lGr9RwBAAAAQG76HflB/5j8P2YgIYX6dQT4Ei0SqiIjNVy7jFJUQDKSJg/PYkedE02JZJBJPcMYxEJUxXtMgq+upamNILfkmY0AAABBAP4v0O5dqjy16xDDFzb4DPNAcw5Za9KJaXKVkUuKXMNZOKTR0RC/upjNTmttY980RKdIx5zA25dO8cx563bSDIsAAABBAP0MaOpBiai/eRmLqhlthHODa+Mur6W3uc9PyhWhgDBjLNMR/doaYeyfVKxtIiN3a+HkN++G+vbokRweQv++bhMAAAANdXJ6QGxvY2FsaG9zdAECAwQFBg==\"," + // WARNING!!!\n\ + // EACH USER SHOULD REPLACE DUMMY FILE's VALUE WITH A UNIQUE ONE!!!\n\ + // OTHERWISE, SECURITY CAN BE TRIVIALLY COMPROMISED!\n\ + // Only relevant to users of chrome-based browsers.\n\ + // Users of Firefox forks are safe.\n\ + \"$CHROMIUM_KEY\"\ +" else GECKO_APPLICATIONS="\n\ \"applications\": {\n\ diff --git a/common/signing.js b/common/signing.js index 2171714..1904bcd 100644 --- a/common/signing.js +++ b/common/signing.js @@ -10,7 +10,7 @@ * IMPORTS_START * IMPORT sha256 * IMPORT browser - * IMPORT is_chrome + * IMPORT is_mozilla * IMPORTS_END */ @@ -30,18 +30,18 @@ * * The secret shared between execution contexts has to be available * synchronously. Under Mozilla, this is the extension's per-session id. Under - * Chromium, this is the key that resides in the manifest. - * - * An idea to (under Chromium) instead store the secret in a file fetched - * synchronously using XMLHttpRequest is being considered. + * Chromium, this is a dummy web-accessible-resource name that resides in the + * manifest and is supposed to be constructed by each user using a unique value + * (this is done automatically by `build.sh'). */ function get_secret() { - if (is_chrome) - return browser.runtime.getManifest().key.substring(0, 50); - else + if (is_mozilla) return browser.runtime.getURL("dummy"); + + return chrome.runtime.getManifest().web_accessible_resources + .map(r => /^chromium-key-dummy-file-(.*)/.exec(r)).filter(r => r)[0][1]; } function extract_signed(signature, signed_data) diff --git a/manifest.json b/manifest.json index bd963fe..ce2577e 100644 --- a/manifest.json +++ b/manifest.json @@ -4,7 +4,7 @@ "manifest_version": 2, "name": "Hachette", "short_name": "Hachette", - "version": "0.0.1",_CHROMIUM_KEY_ + "version": "0.0.1", "author": "various", "description": "Control your \"Web\" browsing.",_GECKO_APPLICATIONS_ "icons":{ @@ -42,7 +42,7 @@ "page": "html/options.html", "open_in_tab": true }, - "web_accessible_resources": [ + "web_accessible_resources": [_CHROMIUM_KEY_ ], "background": { "persistent": true, -- cgit v1.2.3 From 704f2da0673dc714f72b9bb82f6bf648795d4335 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Mon, 6 Sep 2021 20:45:50 +0200 Subject: re-enable sanitizing of data: URLs and also sanitize intrinsics on non-HTML pages where CSP doesn't work --- content/freezer.js | 64 -------------------------------------------- content/main.js | 78 +++++++++++++++++++++++++++++++++++++++++++++--------- copyright | 5 ---- 3 files changed, 65 insertions(+), 82 deletions(-) delete mode 100644 content/freezer.js diff --git a/content/freezer.js b/content/freezer.js deleted file mode 100644 index 0ea362e..0000000 --- a/content/freezer.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Helper functions for blocking scripts in pages, based off NoScript's lib/DocumentFreezer.js - * - * Copyright (C) 2005-2021 Giorgio Maone - https://maone.net - * Copyright (C) 2021 jahoti - * Redistribution terms are gathered in the `copyright' file. - */ - -const loaderAttributes = ["href", "src", "data"]; -const jsOrDataUrlRx = /^(?:data:(?:[^,;]*ml|unknown-content-type)|javascript:)/i; - -function sanitize_attributes(element) { - if (element._frozen) - return; - let fa = []; - let loaders = []; - let attributes = element.attributes || []; - - for (let a of attributes) { - let name = a.localName.toLowerCase(); - if (loaderAttributes.includes(name)) - if (jsOrDataUrlRx.test(a.value)) - loaders.push(a); - - else if (name.startsWith("on")) { - console.debug("Removing", a, element.outerHTML); - fa.push(a.cloneNode()); - a.value = ""; - element[name] = null; - } - } - if (loaders.length) { - for (let a of loaders) { - fa.push(a.cloneNode()); - a.value = "javascript://frozen"; - } - if ("contentWindow" in element) - element.replaceWith(element = element.cloneNode(true)); - - } - if (fa.length) - element._frozenAttributes = fa; - element._frozen = true; -} - -function mozilla_suppress_scripts(e) { - if (document.readyState === 'complete') { - removeEventListener('beforescriptexecute', blockExecute, true); - console.log('Script suppressor has detached.'); - return; - } - console.log("script event", e); - if (e.isTrusted && !e.target._hachette_payload) { - e.preventDefault(); - console.log('Suppressed script', e.target); - } -}; - -/* - * EXPORTS_START - * EXPORT mozilla_suppress_scripts - * EXPORT sanitize_attributes - * EXPORTS_END - */ diff --git a/content/main.js b/content/main.js index b2cc9ed..a183913 100644 --- a/content/main.js +++ b/content/main.js @@ -13,7 +13,6 @@ * IMPORT sign_data * IMPORT gen_nonce * IMPORT is_privileged_url - * IMPORT mozilla_suppress_scripts * IMPORT is_chrome * IMPORT is_mozilla * IMPORT start_activity_info_server @@ -132,10 +131,18 @@ function finish_waiting(waiting) function _wait_for_head(doc, detached_html, callback) { const waiting = {doc, detached_html, callback, observers: []}; - if (try_body_started(waiting)) - return; - waiting.observers = [make_body_start_observer(detached_html, waiting)]; + /* + * For XML and SVG documents, instead of waiting for `', we wait + * for the entire document to finish loading. + */ + if (doc instanceof HTMLDocument) { + if (try_body_started(waiting)) + return; + + waiting.observers = [make_body_start_observer(detached_html, waiting)]; + } + waiting.loaded_cb = () => finish_waiting(waiting); doc.addEventListener("DOMContentLoaded", waiting.loaded_cb); } @@ -200,32 +207,72 @@ function desanitize_script(script, policy) delete script.hachette_blocked_type; } -function apply_hachette_csp_rules(doc, policy) +function apply_hachette_csp_rules(doc, head, policy) { const meta = doc.createElement("meta"); meta.setAttribute("http-equiv", "Content-Security-Policy"); meta.setAttribute("content", csp_rule(policy.nonce)); - doc.head.append(meta); + head.append(meta); /* CSP is already in effect, we can remove the now. */ meta.remove(); } +function sanitize_urls(element) +{ + for (const attribute of [...element.attributes]) { + if (/^(href|src|data)$/i.test(attribute.localName) && + /^data:([^,;]*ml|unknown-content-type)/i.test(attribute.value)) + block_attribute(element, attribute.localName); + } +} + +function start_data_urls_sanitizing(doc) +{ + doc.querySelectorAll("*[href], *[src], *[data]").forEach(sanitize_urls); + const mutation_handler = m => m.addedNodes.forEach(sanitize_urls); + const mo = new MutationObserver(ms => ms.forEach(mutation_handler)); + mo.observe(doc, {childList: true, subtree: true}); +} + +function apply_intrinsics_sanitizing(root_element) +{ + for (const subelem of root_element.querySelectorAll("*")) { + [...subelem.attributes] + .filter(a => /^on/i.test(a.localName)) + .filter(a => /^javascript:/i.test(a.value)) + .forEach(a => block_attribute(subelem, a.localName)); + } +} + async function sanitize_document(doc, policy) { + /* + * Blocking of scripts that are in the DOM from the beginning. Needed for + * Mozilla, harmless on Chromium. + * Note that at least in SVG documents the `src' attr on ``; + ``; const doctype_decl = /^(\s*"']*>)?/i.exec(decoded)[0]; decoded = doctype_decl + dummy_script + decoded.substring(doctype_decl.length); diff --git a/common/ajax.js b/common/ajax.js index 8082bbe..7269a8a 100644 --- a/common/ajax.js +++ b/common/ajax.js @@ -1,6 +1,7 @@ /** - * part of Hachette - * Wrapping XMLHttpRequest into a Promise. + * This file is part of Haketilo. + * + * Function: Wrapping XMLHttpRequest into a Promise. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/connection_types.js b/common/connection_types.js index 88c6964..3e9df56 100644 --- a/common/connection_types.js +++ b/common/connection_types.js @@ -1,5 +1,7 @@ /** - * Hachette background scripts message connection types "enum" + * This file is part of Haketilo. + * + * Function: Define an "enum" of message connection types. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/lock.js b/common/lock.js index 822ad1b..6cf0835 100644 --- a/common/lock.js +++ b/common/lock.js @@ -1,5 +1,7 @@ /** - * Hachette lock (aka binary semaphore aka mutex) + * This file is part of Haketilo. + * + * Function: Implement a lock (aka binary semaphore aka mutex). * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/message_server.js b/common/message_server.js index ea40487..c8c6696 100644 --- a/common/message_server.js +++ b/common/message_server.js @@ -1,5 +1,7 @@ /** - * Hachette message server + * This file is part of Haketilo. + * + * Function: Message server. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/misc.js b/common/misc.js index 6cded84..9ffb7ff 100644 --- a/common/misc.js +++ b/common/misc.js @@ -1,5 +1,7 @@ /** - * Hachette miscellaneous operations refactored to a separate file + * This file is part of Haketilo. + * + * Function: Miscellaneous operations refactored to a separate file. * * Copyright (C) 2021 Wojtek Kosior * Copyright (C) 2021 jahoti diff --git a/common/observable.js b/common/observable.js index 02f1c1b..ab3b444 100644 --- a/common/observable.js +++ b/common/observable.js @@ -1,6 +1,7 @@ /** - * part of Hachette - * Facilitate listening to events + * This file is part of Haketilo. + * + * Function: Facilitate listening to (internal, self-generated) events. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/once.js b/common/once.js index 098b43f..93e842f 100644 --- a/common/once.js +++ b/common/once.js @@ -1,5 +1,8 @@ /** - * Hachette feature initialization promise + * This file is part of Haketilo. + * + * Function: Wrap APIs that depend on some asynchronous initialization into + * promises. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/patterns.js b/common/patterns.js index ae29fcd..625be05 100644 --- a/common/patterns.js +++ b/common/patterns.js @@ -1,5 +1,7 @@ /** - * Hachette operations on page url patterns + * This file is part of Haketilo. + * + * Function: Operations on page URL patterns. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/sanitize_JSON.js b/common/sanitize_JSON.js index 8b86d2d..4cf1ef4 100644 --- a/common/sanitize_JSON.js +++ b/common/sanitize_JSON.js @@ -1,6 +1,7 @@ /** - * part of Hachette - * Powerful, full-blown format enforcer for externally-obtained JSON + * This file is part of Haketilo. + * + * Function: Powerful, full-blown format enforcer for externally-obtained JSON. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/settings_query.js b/common/settings_query.js index b54e580..7e1315e 100644 --- a/common/settings_query.js +++ b/common/settings_query.js @@ -1,5 +1,7 @@ /** - * Hachette querying page settings with regard to wildcard records + * This file is part of Haketilo. + * + * Function: Querying page settings. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/signing.js b/common/signing.js index 1904bcd..11cd442 100644 --- a/common/signing.js +++ b/common/signing.js @@ -1,6 +1,7 @@ /** - * part of Hachette - * Functions related to "signing" of data, refactored to a separate file. + * This file is part of Haketilo. + * + * Functions: Operations related to "signing" of data. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. @@ -16,7 +17,7 @@ /* * In order to make certain data synchronously accessible in certain contexts, - * hachette smuggles it in string form in places like cookies, URLs and headers. + * Haketilo smuggles it in string form in places like cookies, URLs and headers. * When using the smuggled data, we first need to make sure it isn't spoofed. * For that, we use this pseudo-signing mechanism. * diff --git a/common/storage_client.js b/common/storage_client.js index 2b2f495..ef4a0b8 100644 --- a/common/storage_client.js +++ b/common/storage_client.js @@ -1,5 +1,7 @@ /** - * Hachette storage through connection (client side) + * This file is part of Haketilo. + * + * Function: Storage through messages (client side). * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/storage_light.js b/common/storage_light.js index 067bf0c..32e3b1f 100644 --- a/common/storage_light.js +++ b/common/storage_light.js @@ -1,6 +1,7 @@ /** - * part of Hachette - * Storage manager, lighter than the previous one. + * This file is part of Haketilo. + * + * Function: Storage manager, lighter than the previous one. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/storage_raw.js b/common/storage_raw.js index 4c02ee4..e354b6b 100644 --- a/common/storage_raw.js +++ b/common/storage_raw.js @@ -1,6 +1,7 @@ /** - * part of Hachette - * Basic wrappers for storage API functions. + * This file is part of Haketilo. + * + * Function: Basic wrappers for storage API functions. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/common/stored_types.js b/common/stored_types.js index bfceba6..a693b1c 100644 --- a/common/stored_types.js +++ b/common/stored_types.js @@ -1,5 +1,7 @@ /** - * Hachette stored item types "enum" + * This file is part of Haketilo. + * + * Function: Define an "enum" of stored item types. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/content/activity_info_server.js b/content/activity_info_server.js index 1b69703..d1dfe36 100644 --- a/content/activity_info_server.js +++ b/content/activity_info_server.js @@ -1,7 +1,8 @@ /** - * part of Hachette - * Informing about activities performed by content script (script injection, - * script blocking). + * This file is part of Haketilo. + * + * Function: Informing the popup about what happens in the content script + * (script injection, script blocking, etc.). * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/content/main.js b/content/main.js index 6478ea0..cec9943 100644 --- a/content/main.js +++ b/content/main.js @@ -1,5 +1,7 @@ /** - * Hachette main content script run in all frames + * This file is part of Haketilo. + * + * Function: Main content script that runs in all frames. * * Copyright (C) 2021 Wojtek Kosior * Copyright (C) 2021 jahoti @@ -33,7 +35,7 @@ function extract_cookie_policy(cookie, min_time) let policy = null; const extracted_signatures = []; - for (const match of cookie.matchAll(/hachette-(\w*)=([^;]*)/g)) { + for (const match of cookie.matchAll(/haketilo-(\w*)=([^;]*)/g)) { const new_result = extract_signed(...match.slice(1, 3)); if (new_result.fail) continue; @@ -60,7 +62,7 @@ function extract_url_policy(url, min_time) const [base_url, payload, anchor] = /^([^#]*)#?([^#]*)(#?.*)$/.exec(url).splice(1, 4); - const match = /^hachette_([^_]+)_(.*)$/.exec(payload); + const match = /^haketilo_([^_]+)_(.*)$/.exec(payload); if (!match) return [null, url]; @@ -83,7 +85,7 @@ function employ_nonhttp_policy(policy) policy.nonce = gen_nonce(); const [base_url, target] = /^([^#]*)(#?.*)$/.exec(policy.url).slice(1, 3); const encoded_policy = encodeURIComponent(JSON.stringify(policy)); - const payload = "hachette_" + + const payload = "haketilo_" + sign_data(encoded_policy, new Date().getTime()).join("_"); const resulting_url = `${base_url}#${payload}${target}`; location.href = resulting_url; @@ -187,7 +189,7 @@ function sanitize_meta(meta) function sanitize_script(script) { - script.hachette_blocked_type = script.getAttribute("type"); + script.haketilo_blocked_type = script.getAttribute("type"); script.type = "text/plain"; } @@ -197,12 +199,12 @@ function sanitize_script(script) */ function desanitize_script(script) { - script.setAttribute("type", script.hachette_blocked_type); + script.setAttribute("type", script.haketilo_blocked_type); - if ([null, undefined].includes(script.hachette_blocked_type)) + if ([null, undefined].includes(script.haketilo_blocked_type)) script.removeAttribute("type"); - delete script.hachette_blocked_type; + delete script.haketilo_blocked_type; } const bad_url_reg = /^data:([^,;]*ml|unknown-content-type)/i; @@ -235,7 +237,7 @@ function start_data_urls_sanitizing(doc) */ function prevent_script_execution(event) { - if (!event.target._hachette_payload) + if (!event.target.haketilo_payload) event.preventDefault(); } @@ -336,7 +338,7 @@ if (!is_privileged_url(document.URL)) { let signatures; [policy, signatures] = extract_cookie_policy(document.cookie, min_time); for (const signature of signatures) - document.cookie = `hachette-${signature}=; Max-Age=-1;`; + document.cookie = `haketilo-${signature}=; Max-Age=-1;`; } else { const scheme = /^([^:]*)/.exec(document.URL)[1]; const known_scheme = ["file", "ftp"].includes(scheme); diff --git a/content/page_actions.js b/content/page_actions.js index 040b4ab..db7c352 100644 --- a/content/page_actions.js +++ b/content/page_actions.js @@ -1,5 +1,7 @@ /** - * Hachette handling of page actions in content scripts + * This file is part of Haketilo. + * + * Function: Handle page actions in a content script. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. @@ -60,7 +62,7 @@ function add_script(script_text) let script = document.createElement("script"); script.textContent = script_text; script.setAttribute("nonce", nonce); - script._hachette_payload = true; + script.haketilo_payload = true; document.body.appendChild(script); report_script(script_text); diff --git a/content/repo_query.js b/content/repo_query.js index 3708108..637282c 100644 --- a/content/repo_query.js +++ b/content/repo_query.js @@ -1,6 +1,7 @@ /** - * part of Hachette - * Getting available content for site from remote repositories. + * This file is part of Haketilo. + * + * Function: Getting available content for site from remote repositories. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/copyright b/copyright index 4c37eb3..fe2aed7 100644 --- a/copyright +++ b/copyright @@ -1,5 +1,5 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: Hachette +Upstream-Name: Haketilo Source: https://git.koszko.org/browser-extension/ Files: * diff --git a/html/DOM_helpers.js b/html/DOM_helpers.js index 01e2be9..4fe118d 100644 --- a/html/DOM_helpers.js +++ b/html/DOM_helpers.js @@ -1,5 +1,7 @@ /** - * Hachette operations on DOM elements + * This file is part of Haketilo. + * + * Function: Operations on DOM elements. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/html/MOZILLA_scrollbar_fix.css b/html/MOZILLA_scrollbar_fix.css index 5feb7c3..cdbd5c6 100644 --- a/html/MOZILLA_scrollbar_fix.css +++ b/html/MOZILLA_scrollbar_fix.css @@ -1,6 +1,8 @@ /** - * Hachette - * Hacky fix for vertical scrollbar width being included in child's width. + * This file is part of Haketilo. + * + * Function: Hacky fix for vertical scrollbar width being included in child's + * width. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/html/back_button.css b/html/back_button.css index 1ddc5da..b83e834 100644 --- a/html/back_button.css +++ b/html/back_button.css @@ -1,6 +1,7 @@ /** - * part of Hachette - * Style for a "back" button with a CSS arrow image. + * This file is part of Haketilo. + * + * Function: Style for a "back" button with a CSS arrow image. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/html/base.css b/html/base.css index df52f7c..517a5c1 100644 --- a/html/base.css +++ b/html/base.css @@ -1,5 +1,7 @@ /** - * Hachette base styles + * This file is part of Haketilo. + * + * Function: Base styles. * * Copyright (C) 2021 Wojtek Kosior * Copyright (C) 2021 Nicholas Johnson diff --git a/html/default_blocking_policy.js b/html/default_blocking_policy.js index 2f49bac..b6458f3 100644 --- a/html/default_blocking_policy.js +++ b/html/default_blocking_policy.js @@ -1,6 +1,7 @@ /** - * part of Hachette - * Default policy dialog logic. + * This file is part of Haketilo. + * + * Function: Logic for the dialog of default policy selection. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/html/display-panel.html b/html/display-panel.html index 3ed1b7a..ee9e767 100644 --- a/html/display-panel.html +++ b/html/display-panel.html @@ -1,12 +1,16 @@ - Hachette - page settings + Haketilo - page settings @@ -331,7 +335,7 @@ diff --git a/html/display-panel.js b/html/display-panel.js index 84c922f..c078850 100644 --- a/html/display-panel.js +++ b/html/display-panel.js @@ -1,5 +1,7 @@ /** - * Hachette display panel logic + * This file is part of Haketilo. + * + * Function: Popup logic. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/html/import_frame.js b/html/import_frame.js index c0eb2f0..ae6fab4 100644 --- a/html/import_frame.js +++ b/html/import_frame.js @@ -1,5 +1,7 @@ /** - * Hachette HTML import frame script + * This file is part of Haketilo. + * + * Function: Logic for the settings import frame. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/html/options.html b/html/options.html index 54ab9e8..2e8317c 100644 --- a/html/options.html +++ b/html/options.html @@ -1,12 +1,16 @@ - Hachette options + Haketilo options diff --git a/html/options_main.js b/html/options_main.js index 27ab0ec..f8faf9b 100644 --- a/html/options_main.js +++ b/html/options_main.js @@ -1,5 +1,7 @@ /** - * Hachette HTML options page main script + * This file is part of Haketilo. + * + * Function: Settings page logic. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/icons/hachette.svg b/icons/hachette.svg deleted file mode 100644 index 6e8948d..0000000 --- a/icons/hachette.svg +++ /dev/null @@ -1,127 +0,0 @@ - - - Hatchet - - - - - - - - - - - - image/svg+xml - - Hatchet - - - David Lyons - - - - - dlyons - - - - 2017-05 - - - hatchet - ax - wood - - - Hatchet - - - - - - - - - - - - - - - - - - - - - - diff --git a/icons/hachette128.png b/icons/hachette128.png deleted file mode 100644 index 18816e9..0000000 Binary files a/icons/hachette128.png and /dev/null differ diff --git a/icons/hachette16.png b/icons/hachette16.png deleted file mode 100644 index 182ede5..0000000 Binary files a/icons/hachette16.png and /dev/null differ diff --git a/icons/hachette32.png b/icons/hachette32.png deleted file mode 100644 index ffaa84b..0000000 Binary files a/icons/hachette32.png and /dev/null differ diff --git a/icons/hachette48.png b/icons/hachette48.png deleted file mode 100644 index 1ffcd38..0000000 Binary files a/icons/hachette48.png and /dev/null differ diff --git a/icons/hachette64.png b/icons/hachette64.png deleted file mode 100644 index a02abb0..0000000 Binary files a/icons/hachette64.png and /dev/null differ diff --git a/icons/haketilo.svg b/icons/haketilo.svg new file mode 100644 index 0000000..6e8948d --- /dev/null +++ b/icons/haketilo.svg @@ -0,0 +1,127 @@ + + + Hatchet + + + + + + + + + + + + image/svg+xml + + Hatchet + + + David Lyons + + + + + dlyons + + + + 2017-05 + + + hatchet + ax + wood + + + Hatchet + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/haketilo128.png b/icons/haketilo128.png new file mode 100644 index 0000000..18816e9 Binary files /dev/null and b/icons/haketilo128.png differ diff --git a/icons/haketilo16.png b/icons/haketilo16.png new file mode 100644 index 0000000..182ede5 Binary files /dev/null and b/icons/haketilo16.png differ diff --git a/icons/haketilo32.png b/icons/haketilo32.png new file mode 100644 index 0000000..ffaa84b Binary files /dev/null and b/icons/haketilo32.png differ diff --git a/icons/haketilo48.png b/icons/haketilo48.png new file mode 100644 index 0000000..1ffcd38 Binary files /dev/null and b/icons/haketilo48.png differ diff --git a/icons/haketilo64.png b/icons/haketilo64.png new file mode 100644 index 0000000..a02abb0 Binary files /dev/null and b/icons/haketilo64.png differ diff --git a/manifest.json b/manifest.json index ce2577e..9d34732 100644 --- a/manifest.json +++ b/manifest.json @@ -1,18 +1,20 @@ +// This is the manifest file of Haketilo. +// // Copyright (C) 2021 Wojtek Kosior // Redistribution terms are gathered in the `copyright' file. { "manifest_version": 2, - "name": "Hachette", - "short_name": "Hachette", + "name": "Haketilo", + "short_name": "Haketilo", "version": "0.0.1", "author": "various", "description": "Control your \"Web\" browsing.",_GECKO_APPLICATIONS_ "icons":{ - "128": "icons/hachette128.png", - "64": "icons/hachette64.png", - "48": "icons/hachette48.png", - "32": "icons/hachette32.png", - "16": "icons/hachette16.png" + "128": "icons/haketilo128.png", + "64": "icons/haketilo64.png", + "48": "icons/haketilo48.png", + "32": "icons/haketilo32.png", + "16": "icons/haketilo16.png" }, "permissions": [ "contextMenus", @@ -29,13 +31,13 @@ "browser_action": { "browser_style": true, "default_icon": { - "128": "icons/hachette128.png", - "64": "icons/hachette64.png", - "48": "icons/hachette48.png", - "32": "icons/hachette32.png", - "16": "icons/hachette16.png" + "128": "icons/haketilo128.png", + "64": "icons/haketilo64.png", + "48": "icons/haketilo48.png", + "32": "icons/haketilo32.png", + "16": "icons/haketilo16.png" }, - "default_title": "Hachette", + "default_title": "Haketilo", "default_popup": "html/display-panel.html" }, "options_ui": { diff --git a/re-generate_icons.sh b/re-generate_icons.sh index ba0c28a..e557ad0 100755 --- a/re-generate_icons.sh +++ b/re-generate_icons.sh @@ -4,5 +4,5 @@ # Redistribution terms are gathered in the `copyright' file. for SIZE in 128 64 48 32 16; do - inkscape -z -e icons/hachette$SIZE.png -w $SIZE -h $SIZE icons/hachette.svg + inkscape -z -e icons/haketilo$SIZE.png -w $SIZE -h $SIZE icons/haketilo.svg done -- cgit v1.2.3 From 212b5c8ef94c16019201a5da94f5247b30f14a9b Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Tue, 14 Sep 2021 19:28:54 +0200 Subject: use default settings that only contain a demo script (the rest is available through Hydrilla) --- copyright | 2 +- default_settings.json | 51 +-------------------------------------------------- 2 files changed, 2 insertions(+), 51 deletions(-) diff --git a/copyright b/copyright index fe2aed7..de411e0 100644 --- a/copyright +++ b/copyright @@ -6,7 +6,7 @@ Files: * Copyright: 2021 Wojtek Kosior License: GPL-3+-javascript or Alicense-1.0 -Files: *.sh +Files: *.sh default_settings.json Copyright: 2021 Wojtek Kosior 2021 jahoti License: CC0 diff --git a/default_settings.json b/default_settings.json index 44fbca0..89c59cf 100644 --- a/default_settings.json +++ b/default_settings.json @@ -1,50 +1 @@ -[ - { - "sbandcamp": { - "text": "/*\n\tCopyright © 2021 jahoti (jahoti@tilde.team)\n\t\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\t\n\t http://www.apache.org/licenses/LICENSE-2.0\n\t\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n\nvar div, player, playerBox = document.querySelector('.inline_player');\nplayerBox.innerHTML = '';\n\nfor (var track of JSON.parse(document.querySelector('[data-tralbum]').dataset.tralbum).trackinfo) {\n\tdiv = document.createElement('div');\n\tplayer = document.createElement('audio');\n\t\n\tdiv.innerText = track.title + ': ';\n\tplayer.src = track.file['mp3-128']; // Is this always available?\n\tdiv.append(player);\n\tplayerBox.append(div);\n}" - } - }, - { - "sopencores": { - "text":"let data = JSON.parse(document.getElementById(\"__NEXT_DATA__\").textContent);\nlet sections = {};\nfor (let h1 of document.getElementsByClassName(\"cMJCrc\")) {\n let ul = document.createElement(\"ul\");\n if (h1.nextElementSibling !== null)\n\th1.parentNode.insertBefore(ul, h1.nextElementSibling);\n else\n\th1.parentNode.appendChild(ul);\n\n sections[h1.children[1].firstChild.textContent] = ul;\n}\n\nfor (let prop of data.props.pageProps.list) {\n let ul = sections[prop.category];\n if (ul === undefined) {\n\tconsole.log(`unknown category \"${prop.category}\" for project \"${prop.title}\"`);\n\tcontinue;\n }\n\n let li = document.createElement(\"li\");\n let a = document.createElement(\"a\");\n a.setAttribute(\"href\", \"/projects/\" + prop.slug);\n a.textContent = prop.title;\n\n li.appendChild(a);\n ul.appendChild(li);\n}\n" - } - }, - { - "ssumofus (sign petition)": { - "text": "/*\n\tCopyright © 2021 jahoti (jahoti@tilde.team)\n\t\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\t\n\t http://www.apache.org/licenses/LICENSE-2.0\n\t\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n\nfunction submitFormItem() {\n\tvar name, val, queryString = '', xhr = new content.XMLHttpRequest();\n\tfor (var formItem of this.querySelectorAll('select, input:not([type=\"radio\"]):not([type=\"checkbox\"])' +\n\t\t':not([type=\"submit\"]):not([type=\"reset\"])')) {\n\t\tqueryString += (queryString && '&') + formItem.name + '=' + encodeURIComponent(formItem.value);\n\t}\n\t\n\txhr.onreadystatechange = function () {\n\t\tif (this.readyState === 4) {\n\t\t\tif (this.status === 200) location.href = JSON.parse(this.responseText).follow_up_url;\n\t\t\telse if (this.status === 422) {\n\t\t\t\tvar failMessage = [], response = JSON.parse(this.responseText);\n\t\t\t\tfor (field in response.errors) for (error of response.errors[field]) {\n\t\t\t\t\tfailMessage.push('Field \"' + field + '\" ' + error);\n\t\t\t\t}\n\t\t\t\talert(failMessage.join('\\n'));\n\t\t\t}\n\t\t\telse alert('Submission failed: response code ' + this.status);\n\t\t}\n\t}\n\t\n\txhr.open('POST', this.action, true); // Manually add the domain, as it's not properly handled in extensions\n\txhr.setRequestHeader('X-CSRF-Token', csrf);\n\txhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n\txhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n\txhr.send(queryString);\n\treturn false;\n}\n\n// Apply CSS as necessary\nif (notice = document.querySelector('#petition-bar-main > span')) notice.style.display = 'none'; // Hide the totally mistaken (even without this extension) anti-anti-JS warning\ndocument.querySelector('.script-dependent').style.display = 'block';\ndocument.querySelector('.button-wrapper').style.position = 'static'; // Stop the \"submit\" button obscuring the form\n\n\n\ncsrf = document.querySelector('meta[name=\"csrf-token\"]').content\nfor (var button of document.querySelectorAll('button[type=\"submit\"].button.action-form__submit-button')) button.form.onsubmit = submitFormItem;" - } - }, - { - "sworldcat (library holdings)": { - "text": "/*\n\tCopyright © 2021 jahoti (jahoti@tilde.team)\n\t\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\t\n\t http://www.apache.org/licenses/LICENSE-2.0\n\t\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n\nvar pathParts = location.pathname.split('/'), itemRef = pathParts[pathParts.length - 1];\n\n// Generate a function which, when invoked, loads the catalog holdings starting at i (one-indexed) focused on loc\nfunction generateGoTo(i, set_loc) {\n\treturn function () {\n\t\t; // If this is a new search, \"set_loc\" won't be set; set it\n\t\tvar xhr = new content.XMLHttpRequest(), loc = set_loc || encodeURIComponent(locInput.value);\n\t\txhr.onreadystatechange = function () {\n\t\t\tif (this.readyState === 4) {\n\t\t\t\tif (this.status === 200) {\n\t\t\t\t\tretrieved.innerHTML = this.responseText;\n\t\t\t\t\t\n\t\t\t\t\tvar i, node = document.getElementById('libslocator');\n\t\t\t\t\tnode.parentNode.removeChild(node);\n\t\t\t\t\tfor (node of retrieved.querySelectorAll('a[href^=\"javascript:findLibs(\\'\\', \"]')) {\n\t\t\t\t\t\ti = parseInt(node.href.split(',', 2)[1]);\n\t\t\t\t\t\tnode.onclick = generateGoTo(i, loc);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse alert('Search failed: response code ' + this.status);\n\t\t\t}\n\t\t}\n\t\t\n\t\txhr.open('GET', 'https://www.worldcat.org/wcpa/servlet/org.oclc.lac.ui.ajax.ServiceServlet?wcoclcnum=' + itemRef + '&start_holding='\n\t\t\t\t+ i + '&serviceCommand=holdingsdata&loc=' + loc, true);\n\t\txhr.send();\n\t\treturn false; // Make sure the browser doesn't try to submit any holding form\n\t};\n}\n\n\nvar retriever = document.querySelector('.retrieving'), retrieved = document.getElementById('donelocator');\n\nvar locForm = document.createElement('form'), locLabel = document.createElement('label'), locInput = document.createElement('input'),\n\tlocSubmit = document.createElement('input');\n\nlocForm.appendChild(locLabel);\nlocForm.appendChild(locInput);\nlocForm.appendChild(locSubmit);\n\nlocInput.name = locLabel.htmlFor = 'cat_location';\nlocInput.type = 'text';\nlocInput.required = 'yes';\nlocLabel.innerText = 'Find copies closest to: ';\nlocSubmit.value = 'Go';\nlocSubmit.type = 'submit';\nlocForm.onsubmit = generateGoTo(1);\n\nretriever.parentNode.replaceChild(locForm, retriever);" - } - }, - { - "phttps://*.bandcamp.com/track/*": { - "components": ["s", "bandcamp"] - } - }, - { - "phttps://opencores.org/projects": { - "components": ["s", "opencores"] - } - }, - { - "phttps://actions.sumofus.org/a/*": { - "components": ["s", "sumofus (sign petition)"], - } - }, - { - "phttps://worldcat.org/title/**": { - "components": ["s", "worldcat (library holdings)"] - } - }, - { - "phttps://www.worldcat.org/title/**": { - "components": ["s", "worldcat (library holdings)"] - } - }, - { - "rhttps://api-demo.hachette-hydrilla.org": {} - } -] +[{"shaketilo demo script":{"url":"","hash":"","text":"/**\n * Haketilo demo script.\n *\n * Copyright (C) Wojtek Kosior\n * Available under the terms of Creative Commons Zero\n * \n */\n\nconst banner = document.createElement(\"h2\");\n\nbanner.textContent = \"Hoooray! Haketilo works :D\"\n\nbanner.setAttribute(\"style\", `\\\nmargin: 1em; \\\nborder-radius: 1em 0px; \\\nbackground-color: #474; \\\npadding: 10px 20px; \\\ncolor: #eee; \\\nbox-shadow: 0 6px 8px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19); \\\ndisplay: inline-block;\\\n`);\n\ndocument.body.prepend(banner);"}},{"bhaketilo demo bag":[["s","haketilo demo script"]]},{"phttps://hachette-hydrilla.org":{"components":["b","haketilo demo bag"],"allow":false}}] \ No newline at end of file -- cgit v1.2.3 From e9b6187e0c5eaa4ac5ee41aacb261ae2da208c8f Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Tue, 14 Sep 2021 19:29:34 +0200 Subject: bump version to 0.1 --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 9d34732..3caa6af 100644 --- a/manifest.json +++ b/manifest.json @@ -6,7 +6,7 @@ "manifest_version": 2, "name": "Haketilo", "short_name": "Haketilo", - "version": "0.0.1", + "version": "0.1", "author": "various", "description": "Control your \"Web\" browsing.",_GECKO_APPLICATIONS_ "icons":{ -- cgit v1.2.3 From 960363e7dd98a724246320e49c3fbaff9d68d1bd Mon Sep 17 00:00:00 2001 From: jahoti Date: Wed, 15 Sep 2021 00:00:00 +0000 Subject: Add default repository to default settings --- default_settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default_settings.json b/default_settings.json index 89c59cf..e7ea2c3 100644 --- a/default_settings.json +++ b/default_settings.json @@ -1 +1 @@ -[{"shaketilo demo script":{"url":"","hash":"","text":"/**\n * Haketilo demo script.\n *\n * Copyright (C) Wojtek Kosior\n * Available under the terms of Creative Commons Zero\n * \n */\n\nconst banner = document.createElement(\"h2\");\n\nbanner.textContent = \"Hoooray! Haketilo works :D\"\n\nbanner.setAttribute(\"style\", `\\\nmargin: 1em; \\\nborder-radius: 1em 0px; \\\nbackground-color: #474; \\\npadding: 10px 20px; \\\ncolor: #eee; \\\nbox-shadow: 0 6px 8px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19); \\\ndisplay: inline-block;\\\n`);\n\ndocument.body.prepend(banner);"}},{"bhaketilo demo bag":[["s","haketilo demo script"]]},{"phttps://hachette-hydrilla.org":{"components":["b","haketilo demo bag"],"allow":false}}] \ No newline at end of file +[{"shaketilo demo script":{"url":"","hash":"","text":"/**\n * Haketilo demo script.\n *\n * Copyright (C) Wojtek Kosior\n * Available under the terms of Creative Commons Zero\n * \n */\n\nconst banner = document.createElement(\"h2\");\n\nbanner.textContent = \"Hoooray! Haketilo works :D\"\n\nbanner.setAttribute(\"style\", `\\\nmargin: 1em; \\\nborder-radius: 1em 0px; \\\nbackground-color: #474; \\\npadding: 10px 20px; \\\ncolor: #eee; \\\nbox-shadow: 0 6px 8px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19); \\\ndisplay: inline-block;\\\n`);\n\ndocument.body.prepend(banner);"}},{"bhaketilo demo bag":[["s","haketilo demo script"]]},{"phttps://hachette-hydrilla.org":{"components":["b","haketilo demo bag"],"allow":false}},{"rhttps://api-demo.hachette-hydrilla.org":{}}] -- cgit v1.2.3