aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--background/page_info_server.js9
-rw-r--r--background/policy_injector.js65
-rwxr-xr-xbuild.sh6
-rw-r--r--common/message_server.js (renamed from background/message_server.js)0
-rw-r--r--common/misc.js97
-rw-r--r--content/freezer.js2
-rw-r--r--content/main.js31
-rw-r--r--content/page_actions.js1
-rw-r--r--copyright9
-rw-r--r--html/options_main.js25
-rw-r--r--icons/hachette.svg110
-rw-r--r--icons/hachette128.pngbin0 -> 6031 bytes
-rw-r--r--icons/hachette16.pngbin0 -> 752 bytes
-rw-r--r--icons/hachette32.pngbin0 -> 1358 bytes
-rw-r--r--icons/hachette48.pngbin0 -> 2154 bytes
-rw-r--r--icons/hachette64.pngbin0 -> 2908 bytes
-rw-r--r--manifest.json12
-rwxr-xr-xre-generate_icons.sh8
18 files changed, 184 insertions, 191 deletions
diff --git a/background/page_info_server.js b/background/page_info_server.js
index 49919fd..6f02750 100644
--- a/background/page_info_server.js
+++ b/background/page_info_server.js
@@ -40,11 +40,6 @@ async function handle_subscription(connection_data, message)
connection_data.port.postMessage(["new_url", query_all(url)]);
}
-function remove_storage_listener(cb)
-{
- storage.remove_change_listener(cb);
-}
-
function new_connection(port)
{
console.log("new page info connection!");
@@ -59,7 +54,9 @@ function new_connection(port)
storage.add_change_listener(_handle_change);
port.onMessage.addListener(m => handle_subscription(connection_data, m));
- port.onDisconnect.addListener(() => remove_storage_listener(handle_change));
+ port.onDisconnect.addListener(
+ () => storage.remove_change_listener(_handle_change)
+ );
}
async function start_page_info_server()
diff --git a/background/policy_injector.js b/background/policy_injector.js
index 8301c3f..01da094 100644
--- a/background/policy_injector.js
+++ b/background/policy_injector.js
@@ -15,8 +15,9 @@
* IMPORT is_mozilla
* IMPORT gen_unique
* IMPORT gen_nonce
+ * IMPORT is_privileged_url
* IMPORT url_item
- * IMPORT url_extract_policy
+ * IMPORT url_extract_target
* IMPORT sign_policy
* IMPORT get_query_best
* IMPORT csp_rule
@@ -39,27 +40,24 @@ function is_csp_header(header)
return !!csp_header_names[header.name.toLowerCase()];
}
-function is_our_header(header, rule)
-{
- return header.value === rule
-}
-
function url_inject(details)
{
- const targets = url_extract_policy(details.url);
- if (targets.current) {
+ if (is_privileged_url(details.url))
return;
- } else if (targets.policy) {
- /* Redirect; update policy */
- targets.target = targets.target2;
- delete targets.target2
- }
+
+ const targets = url_extract_target(details.url);
+ if (targets.current)
+ return;
+
+ /* Redirect; update policy */
+ if (targets.policy)
+ targets.target = "";
let [pattern, settings] = query_best(targets.base_url);
+ /* Defaults */
if (!pattern)
- /* Defaults */
settings = {};
-
+
const policy = encodeURIComponent(
JSON.stringify({
allow: settings.allow,
@@ -67,39 +65,40 @@ function url_inject(details)
base_url: targets.base_url
})
);
-
- let redirect_url = targets.base_url;
- redirect_url += '#' + sign_policy(policy, new Date()) + policy;
- if (targets.target)
- redirect_url += targets.target;
- if (targets.target2)
- redirect_url += targets.target2;
-
- return {redirectUrl: redirect_url};
+
+ return {
+ redirectUrl: [
+ targets.base_url,
+ '#', sign_policy(policy, new Date()), policy,
+ targets.target,
+ targets.target2
+ ].join("")
+ };
}
-function inject(details)
+function headers_inject(details)
{
- const targets = url_extract_policy(details.url);
+ const targets = url_extract_target(details.url);
+ /* Block mis-/unsigned requests */
if (!targets.current)
- /* Block mis-/unsigned requests */
return {cancel: true};
const rule = csp_rule(targets.policy.nonce);
var headers = details.responseHeaders;
+ /*
+ * Chrome doesn't have the buggy behavior of caching headers
+ * we injected. Firefox does and we have to remove it there.
+ */
if (!targets.policy.allow || is_mozilla)
- /*
- * Chrome doesn't have the buggy behavior of caching headers
- * we injected. Firefox does and we have to remove it there.
- */
headers = headers.filter(h => !is_csp_header(h));
- if (!targets.policy.allow)
+ if (!targets.policy.allow) {
headers.push({
name : header_name,
value : rule
});
+ }
return {responseHeaders: headers};
}
@@ -123,7 +122,7 @@ async function start_policy_injector()
);
browser.webRequest.onHeadersReceived.addListener(
- inject,
+ headers_inject,
{
urls: ["<all_urls>"],
types: ["main_frame", "sub_frame"]
diff --git a/build.sh b/build.sh
index e954ce8..60c1863 100755
--- a/build.sh
+++ b/build.sh
@@ -194,7 +194,7 @@ set_browser() {
main() {
set_browser "$1"
-
+
# placate importers of these, as they are exported by the yet-to-be-created exports_init.js
EXPORTS__browser=exports_init.js
EXPORTS__is_chrome=exports_init.js
@@ -299,7 +299,9 @@ $(map_get EXPORTCODES $FILEKEY)
echo "window.killtheweb={is_mozilla: true, browser: this.browser};" > $BUILDDIR/exports_init.js
fi
- cp -r icons/ copyright licenses/ $BUILDDIR
+ cp -r copyright licenses/ $BUILDDIR
+ mkdir $BUILDDIR/icons
+ cp icons/*.png $BUILDDIR/icons
}
main "$@"
diff --git a/background/message_server.js b/common/message_server.js
index ea40487..ea40487 100644
--- a/background/message_server.js
+++ b/common/message_server.js
diff --git a/common/misc.js b/common/misc.js
index b78dbb9..a59ec14 100644
--- a/common/misc.js
+++ b/common/misc.js
@@ -27,6 +27,23 @@ function gen_nonce()
* generating unique, per-site value that can be computed synchronously
* and is impossible to guess for a malicious website
*/
+
+/* Uint8toHex is a separate function not exported as (a) it's useful and (b) it will be used in crypto.subtle-based digests */
+function Uint8toHex(data)
+{
+ let returnValue = '';
+ for (let byte of data)
+ returnValue += ('00' + byte.toString(16)).slice(-2);
+ return returnValue;
+}
+
+function gen_nonce(length) // Default 16
+{
+ let randomData = new Uint8Array(length || 16);
+ crypto.getRandomValues(randomData);
+ return Uint8toHex(randomData);
+}
+
function gen_unique(url)
{
return sha256(get_secure_salt() + url);
@@ -52,24 +69,51 @@ function url_item(url)
}
/*
- * Assume a url like: https://example.com/green?illuminati=confirmed#tinky#winky
+ * Assume a url like:
+ * https://example.com/green?illuminati=confirmed#<injected-policy>#winky
* This function will make it into an object like:
* {
- * "base_url" : "https://example.com/green?illuminati=confirmed",
- * "target" : "#tinky",
- * "target2" : "#winky"
+ * "base_url": "https://example.com/green?illuminati=confirmed",
+ * "target": "#<injected-policy>",
+ * "target2": "#winky",
+ * "policy": <injected-policy-as-js-object>,
+ * "current": <boolean-indicating-whether-policy-url-matches>
* }
* In case url doesn't have 2 #'s, target2 and target can be set to undefined.
*/
function url_extract_target(url)
{
- let url_re = /^([^#]*)((#[^#]*)(#.*)?)?$/;
- let match = url_re.exec(url);
- return {
- base_url : match[1],
- target : match[3],
- target2 : match[4]
+ const url_re = /^([^#]*)((#[^#]*)(#.*)?)?$/;
+ const match = url_re.exec(url);
+ const targets = {
+ base_url: match[1],
+ target: match[3] || "",
+ target2: match[4] || ""
};
+ if (!targets.target)
+ return targets;
+
+ /* %7B -> { */
+ const index = targets.target.indexOf('%7B');
+ if (index === -1)
+ return targets;
+
+ const now = new Date();
+ const sig = targets.target.substring(1, index);
+ const policy = targets.target.substring(index);
+ if (sig !== sign_policy(policy, now) &&
+ sig !== sign_policy(policy, now, -1))
+ return targets;
+
+ try {
+ targets.policy = JSON.parse(decodeURIComponent(policy));
+ targets.current = targets.policy.base_url === targets.base_url;
+ } catch (e) {
+ /* This should not be reached - it's our self-produced valid JSON. */
+ console.log("Unexpected internal error - invalid JSON smuggled!", e);
+ }
+
+ return targets;
}
/* csp rule that blocks all scripts except for those injected by us */
@@ -110,45 +154,12 @@ function sign_policy(policy, now, hours_offset) {
return gen_unique(time + policy);
}
-/* Extract any policy present in the URL */
-function url_extract_policy(url)
-{
- const targets = url_extract_target(url);
- if (!targets.target)
- return targets;
-
- /* %7B -> { */
- const index = targets.target.indexOf('%7B');
- if (index === -1)
- return targets;
-
- const now = new Date();
- const sig = targets.target.substring(1, index);
- const policy = targets.target.substring(index);
- if (
- sig !== sign_policy(policy, now) &&
- sig !== sign_policy(policy, now, -1) &&
- sig !== sign_policy(policy, now, 1)
- )
- return targets;
-
- try {
- targets.policy = JSON.parse(decodeURIComponent(policy));
- targets.current = targets.policy.base_url === targets.base_url;
- } catch (e) {
- /* TODO what should happen here? */
- }
-
- return targets;
-}
-
/*
* EXPORTS_START
* EXPORT gen_nonce
* EXPORT gen_unique
* EXPORT url_item
* EXPORT url_extract_target
- * EXPORT url_extract_policy
* EXPORT sign_policy
* EXPORT csp_rule
* EXPORT nice_name
diff --git a/content/freezer.js b/content/freezer.js
index 8e543a6..9dbc95e 100644
--- a/content/freezer.js
+++ b/content/freezer.js
@@ -49,7 +49,7 @@ function mozilla_suppress_scripts(e) {
console.log('Script suppressor has detached.');
return;
}
- else if (e.isTrusted) { // Prevent blocking of injected scripts
+ if (e.isTrusted && !e.target._hachette_payload) {
e.preventDefault();
console.log('Suppressed script', e.target);
}
diff --git a/content/main.js b/content/main.js
index 826019a..8f8375e 100644
--- a/content/main.js
+++ b/content/main.js
@@ -11,7 +11,6 @@
* IMPORT handle_page_actions
* IMPORT url_item
* IMPORT url_extract_target
- * IMPORT url_extract_policy
* IMPORT gen_unique
* IMPORT gen_nonce
* IMPORT csp_rule
@@ -27,14 +26,16 @@
/*
* Due to some technical limitations the chosen method of whitelisting sites
* is to smuggle whitelist indicator in page's url as a "magical" string
- * after '#'. Right now this is not needed in HTTP(s) pages where native
- * script blocking happens through CSP header injection but is needed for
- * protocols like ftp:// and file://.
+ * after '#'. Right now this is only supplemental in HTTP(s) pages where
+ * blocking of native scripts also happens through CSP header injection but is
+ * necessary for protocols like ftp:// and file://.
*
* The code that actually injects the magical string into ftp:// and file://
* urls has not yet been added to the extension.
*/
+var nonce = undefined;
+
function handle_mutation(mutations, observer)
{
if (document.readyState === 'complete') {
@@ -58,9 +59,8 @@ function block_nodes_recursively(node)
function block_node(node)
{
/*
- * Modifying <script> element doesn't always prevent its
- * execution in some Mozilla browsers. Additional blocking
- * through CSP meta tag injection is required.
+ * Modifying <script> element doesn't always prevent its execution in some
+ * Mozilla browsers. This is Chromium-specific code.
*/
if (node.tagName === "SCRIPT") {
block_script(node);
@@ -99,21 +99,20 @@ function inject_csp(head)
}
if (!is_privileged_url(document.URL)) {
- const targets = url_extract_policy(document.URL);
+ const targets = url_extract_target(document.URL);
if (targets.policy) {
- if (targets.target2 !== undefined)
+ if (targets.target2)
window.location.href = targets.base_url + targets.target2;
else
history.replaceState(null, "", targets.base_url);
}
-
- targets.policy = targets.current ? targets.policy : {};
-
- const nonce = targets.policy.nonce || gen_nonce();
- start_activity_info_server();
+
+ const policy = targets.current ? targets.policy : {};
+
+ nonce = policy.nonce || gen_nonce();
handle_page_actions(nonce);
- if (!targets.policy.allow) {
+ if (!policy.allow) {
block_nodes_recursively(document.documentElement);
if (is_chrome) {
@@ -128,4 +127,6 @@ if (!is_privileged_url(document.URL)) {
if (is_mozilla)
addEventListener('beforescriptexecute', mozilla_suppress_scripts, true);
}
+
+ start_activity_info_server();
}
diff --git a/content/page_actions.js b/content/page_actions.js
index 07fd1bc..aff56b8 100644
--- a/content/page_actions.js
+++ b/content/page_actions.js
@@ -50,6 +50,7 @@ function add_script(script_text)
let script = document.createElement("script");
script.textContent = script_text;
script.setAttribute("nonce", nonce);
+ script._hachette_payload = true;
document.body.appendChild(script);
report_script(script_text);
diff --git a/copyright b/copyright
index 98b8ae8..36340e4 100644
--- a/copyright
+++ b/copyright
@@ -6,15 +6,16 @@ Files: *
Copyright: 2021 Wojtek Kosior <koszko@koszko.org>
License: GPL-3+-javascript or Alicense-1.0
-Files: build.sh
+Files: re-generate_icons.sh build.sh
Copyright: 2021 Wojtek Kosior <koszko@koszko.org>
+ 2021 jahoti <jahoti@tilde.team>
License: CC0
-Files: icons/hachette.svg
+Files: icons/*
Copyright: 2017 David Lyons <https://openclipart.org/artist/davidblyons>
-License: CC0
+License: CC0 or CC-BY-SA-4.0
-Files: manifest.json background/policy_injector.js common/misc.js content/main.js
+Files: background/policy_injector.js common/misc.js content/main.js
Copyright: 2021 Wojtek Kosior <koszko@koszko.org>
2021 jahoti <jahoti@tilde.team>
License: GPL-3+-javascript or Alicense-1.0
diff --git a/html/options_main.js b/html/options_main.js
index cf4c9b1..e1e6cbe 100644
--- a/html/options_main.js
+++ b/html/options_main.js
@@ -11,7 +11,6 @@
* IMPORT TYPE_PREFIX
* IMPORT TYPE_NAME
* IMPORT list_prefixes
- * IMPORT url_extract_target
* IMPORT nice_name
* IMPORTS_END
*/
@@ -633,7 +632,7 @@ function hide_import_window()
/*
* Reset file <input>. Without this, a second attempt to import the same
- * file would result in "change" event on happening on <input> element.
+ * file would result in "change" event not happening on <input> element.
*/
file_opener_form.reset();
}
@@ -685,26 +684,26 @@ function initialize_import_facility()
*
* We don't need to worry about the state of the page (e.g. some editing being
* in progress) in jump_to_item() - this function is called at the beginning,
- * before callbacks are assigned to buttons, so it is safe to assume lists are
- * initialized with items and page is in its virgin state with regard to
- * everything else.
+ * together with callbacks being assigned to buttons, so it is safe to assume
+ * lists are initialized with items and page is in its virgin state with regard
+ * to everything else.
*/
function jump_to_item(url_with_item)
{
- const parsed_url = url_extract_target(url_with_item);
-
- if (parsed_url.target === undefined)
+ const [dummy1, base_url, dummy2, target] =
+ /^([^#]*)(#(.*))?$/i.exec(url_with_item);
+ if (target === undefined)
return;
- const prefix = parsed_url.target.substring(1, 2);
+ const prefix = target.substring(0, 1);
if (!list_prefixes.includes(prefix)) {
- history.replaceState(null, "", parsed_url.base_url);
+ history.replaceState(null, "", base_url);
return;
}
by_id(`show_${TYPE_NAME[prefix]}s`).checked = true;
- edit_item(prefix, decodeURIComponent(parsed_url.target.substring(2)));
+ edit_item(prefix, decodeURIComponent(target.substring(1)));
}
async function main()
@@ -718,8 +717,6 @@ async function main()
add_radio_li(prefix, item);
}
- jump_to_item(document.URL);
-
let name = TYPE_NAME[prefix];
let add_but = by_id(`add_${name}_but`);
@@ -746,6 +743,8 @@ async function main()
cancel_components_but.addEventListener("click", cancel_components);
}
+ jump_to_item(document.URL);
+
initialize_import_facility();
storage.add_change_listener(handle_change);
diff --git a/icons/hachette.svg b/icons/hachette.svg
index c139490..6e8948d 100644
--- a/icons/hachette.svg
+++ b/icons/hachette.svg
@@ -5,60 +5,36 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- id="svg8"
+ width="128"
+ height="128"
+ viewBox="0 -0.6 33.866668 33.866666"
version="1.1"
- viewBox="0 -0.6 72.202661 171.30905"
- height="647.46729"
- width="272.89194"
- sodipodi:docname="hatchet.svg"
- inkscape:version="0.92.1 r15371">
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1366"
- inkscape:window-height="709"
- id="namedview21"
- showgrid="false"
- inkscape:zoom="0.67493758"
- inkscape:cx="136.44597"
- inkscape:cy="323.73364"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg8" />
+ id="svg8">
<title
id="title1418">Hatchet</title>
<defs
id="defs2">
<filter
- height="1.5078459"
- y="-0.25392297"
- width="2.5625174"
- x="-0.78125864"
+ style="color-interpolation-filters:sRGB"
id="filter994"
- style="color-interpolation-filters:sRGB">
+ x="-0.78125864"
+ width="2.5625174"
+ y="-0.25392297"
+ height="1.5078459">
<feGaussianBlur
- id="feGaussianBlur996"
- stdDeviation="1.7304741" />
+ stdDeviation="1.7304741"
+ id="feGaussianBlur996" />
</filter>
<filter
- height="1.0656563"
- y="-0.032828163"
- width="1.8736273"
- x="-0.43681362"
+ style="color-interpolation-filters:sRGB"
id="filter1401"
- style="color-interpolation-filters:sRGB">
+ x="-0.43681362"
+ width="1.8736273"
+ y="-0.032828163"
+ height="1.0656563">
<feGaussianBlur
- id="feGaussianBlur1403"
- stdDeviation="2.2606587" />
+ stdDeviation="2.2606587"
+ id="feGaussianBlur1403" />
</filter>
</defs>
<metadata
@@ -110,52 +86,42 @@
</rdf:RDF>
</metadata>
<g
+ transform="matrix(0.18053177,-0.14666587,0.14666587,0.18053177,-0.67884005,5.998568)"
id="g4514">
<path
- inkscape:connector-curvature="0"
- id="rect7"
+ style="fill:#d38d5f;stroke-width:0.23824416"
d="M 7.30405,153.7586 C 20.54927,112.215 15.59359,34.229537 16.31646,33.113187 c 0.87975,-1.35862 11.98736,-0.3859 11.70824,-0.21673 0.17326,45.22237 7.01132,84.510963 -0.71993,131.991763 l -9.29885,-5.88681 z"
- style="fill:#d38d5f;stroke-width:0.23824416" />
+ id="rect7" />
<path
- inkscape:connector-curvature="0"
- id="rect9"
+ style="stroke-width:0.27389684"
d="m 63.328435,18.175599 c 0,0 -18.017818,8.640905 -27.631388,12.644707 -3.823279,1.592294 -7.11998,3.047871 -9.996289,4.376476 -11.35319,0.247708 -19.4479991,0.01005 -19.8799245,1.450041 l 0.01602,16.049149 c 0.1225108,1.704999 8.9933655,2.136989 19.9713905,3.333131 6.538886,4.233937 13.307605,8.532834 17.153475,10.714075 9.058079,5.13742 18.504813,7.823295 18.504813,7.823295 0,0 5.056977,-21.237215 4.911847,-31.707625 C 66.23324,32.388436 63.328435,18.175599 63.328435,18.175599 Z"
- style="stroke-width:0.27389684" />
+ id="rect9" />
<path
- sodipodi:nodetypes="cscccsc"
- inkscape:connector-curvature="0"
- style="opacity:0.45500004;fill:#ffffff;stroke-width:0.26458335"
+ id="path35"
d="m 63.328435,18.175599 c 0,0 2.905055,14.268926 3.050195,24.739336 0.14513,10.47041 -4.912098,31.651538 -4.912098,31.651538 -11.67798,-3.788669 -16.221256,-6.527691 -16.221256,-6.527691 0,0 7.434244,-7.591907 9.174294,-22.366997 1.1592,-16.80443 -4.045711,-21.40711 -4.045711,-21.40711 3.905919,-1.879065 11.01257,-5.216217 12.954576,-6.089076 z"
- id="path35" />
+ style="opacity:0.45500004;fill:#ffffff;stroke-width:0.26458335" />
<path
- sodipodi:nodetypes="cscccscc"
- inkscape:connector-curvature="0"
- id="path1427"
+ style="opacity:0.45500004;fill:#ffffff;stroke-width:0.26458335"
d="m 63.208938,17.51176 c 0,0 3.024552,14.932765 3.169692,25.403175 0.14513,10.47041 -4.912098,31.621519 -4.912098,31.621519 -1.568463,-0.523507 -1.541936,-0.491688 -1.541936,-0.491688 0,0 5.456154,-26.034461 5.211644,-30.225191 -0.0315,-4.2355 -1.218109,-20.314453 -3.453104,-24.783592 0,0 0.723943,-0.407792 1.645299,-0.860384 z"
- style="opacity:0.45500004;fill:#ffffff;stroke-width:0.26458335" />
+ id="path1427" />
<path
- inkscape:connector-curvature="0"
- id="path1407"
+ style="fill:#784421;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 7.30405,153.7586 10.40103,5.0627 c 0,0 9.14195,5.35641 9.55606,6.02467 0.41411,0.66827 -4.66818,-0.88342 -7.90926,-2.11367 -3.24108,-1.23026 -8.21159,-4.9245 -10.36004,-6.6929 -2.14844,-1.76841 -1.68779,-2.2808 -1.68779,-2.2808 z"
- style="fill:#784421;stroke:none;stroke-width:0.26458335px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ id="path1407" />
<path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- style="opacity:0.3;fill:#2b1100;stroke-width:0.20724197"
+ id="path999"
d="M 7.30405,153.7586 C 17.372688,112.40594 21.015256,78.343761 17.898744,32.568697 l 3.350934,-0.138515 c 0.131707,45.014525 3.851339,79.911868 -2.025736,127.174438 z"
- id="path999" />
+ style="opacity:0.3;fill:#2b1100;stroke-width:0.20724197" />
<path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="rect4493"
+ style="opacity:1;fill:#1a1a1a;stroke:none;stroke-width:0.1832249"
d="m 37.364038,35.560531 9.400174,-5.992052 c 4.831746,9.986754 3.508267,19.973509 -0.303231,29.960263 l -9.096943,-5.992051 z"
- style="opacity:1;fill:#1a1a1a;stroke:none;stroke-width:0.1832249" />
+ id="rect4493" />
<rect
- y="38.224262"
- x="23.754957"
- height="15.338916"
- width="7.4658442"
+ style="opacity:1;fill:#1a1a1a;stroke:none;stroke-width:0.37082145"
id="rect4504"
- style="opacity:1;fill:#1a1a1a;stroke:none;stroke-width:0.37082145" />
+ width="7.4658442"
+ height="15.338916"
+ x="23.754957"
+ y="38.224262" />
</g>
</svg>
diff --git a/icons/hachette128.png b/icons/hachette128.png
new file mode 100644
index 0000000..18816e9
--- /dev/null
+++ b/icons/hachette128.png
Binary files differ
diff --git a/icons/hachette16.png b/icons/hachette16.png
new file mode 100644
index 0000000..182ede5
--- /dev/null
+++ b/icons/hachette16.png
Binary files differ
diff --git a/icons/hachette32.png b/icons/hachette32.png
new file mode 100644
index 0000000..ffaa84b
--- /dev/null
+++ b/icons/hachette32.png
Binary files differ
diff --git a/icons/hachette48.png b/icons/hachette48.png
new file mode 100644
index 0000000..1ffcd38
--- /dev/null
+++ b/icons/hachette48.png
Binary files differ
diff --git a/icons/hachette64.png b/icons/hachette64.png
new file mode 100644
index 0000000..a02abb0
--- /dev/null
+++ b/icons/hachette64.png
Binary files differ
diff --git a/manifest.json b/manifest.json
index 14b6aa2..328b27f 100644
--- a/manifest.json
+++ b/manifest.json
@@ -8,7 +8,11 @@
"author": "various",
"description": "Kill the web&js",_GECKO_APPLICATIONS_
"icons":{
- "64": "icons/hachette.svg"
+ "128": "icons/hachette128.png",
+ "64": "icons/hachette64.png",
+ "48": "icons/hachette48.png",
+ "32": "icons/hachette32.png",
+ "16": "icons/hachette16.png"
},
"permissions": [
"contextMenus",
@@ -24,7 +28,11 @@
"browser_action": {
"browser_style": true,
"default_icon": {
- "64": "icons/hachette.svg"
+ "128": "icons/hachette128.png",
+ "64": "icons/hachette64.png",
+ "48": "icons/hachette48.png",
+ "32": "icons/hachette32.png",
+ "16": "icons/hachette16.png"
},
"default_title": "Hachette",
"default_popup": "html/display-panel.html"
diff --git a/re-generate_icons.sh b/re-generate_icons.sh
new file mode 100755
index 0000000..ba0c28a
--- /dev/null
+++ b/re-generate_icons.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# Copyright (C) 2021 Wojtek Kosior
+# 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
+done