aboutsummaryrefslogtreecommitdiff
path: root/setup.cfg
diff options
context:
space:
mode:
Diffstat (limited to 'setup.cfg')
-rw-r--r--setup.cfg5
1 files changed, 3 insertions, 2 deletions
diff --git a/setup.cfg b/setup.cfg
index 6ca397f..bca97bf 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -24,7 +24,7 @@ classifiers =
zip_safe = False
package_dir =
= src
-packages = find:
+packages = find_namespace:
include_package_data = True
python_requires = >= 3.7
install_requires =
@@ -36,7 +36,8 @@ hydrilla.builder = locales/*/LC_MESSAGES/hydrilla-messages.mo
[options.extras_require]
test = pytest
-setup = setuptools_scm
+setup = setuptools_scm; babel
+spdx = reuse
[options.packages.find]
where = src
i ol:first-of-type, .markdown-body ol li>:first-child, .markdown-body ol li ul:first-of-type, .markdown-body ol li ol:first-of-type { margin-top: 0px; } .markdown-body ul li p:last-of-type, .markdown-body ol li p:last-of-type { margin-bottom: 0; } .markdown-body ul ul, .markdown-body ul ol, .markdown-body ol ol, .markdown-body ol ul { margin-bottom: 0; } .markdown-body dl { padding: 0; } .markdown-body dl dt { font-size: 14px; font-weight: bold; font-style: italic; padding: 0; margin: 15px 0 5px; } .markdown-body dl dt:first-child { padding: 0; } .markdown-body dl dt>:first-child { margin-top: 0px; } .markdown-body dl dt>:last-child { margin-bottom: 0px; } .markdown-body dl dd { margin: 0 0 15px; padding: 0 15px; } .markdown-body dl dd>:first-child { margin-top: 0px; } .markdown-body dl dd>:last-child { margin-bottom: 0px; } .markdown-body blockquote { border-left: 4px solid #DDD; padding: 0 15px; color: #777; } .markdown-body blockquote>:first-child { margin-top: 0px; } .markdown-body blockquote>:last-child { margin-bottom: 0px; } .markdown-body table th { font-weight: bold; } .markdown-body table th, .markdown-body table td { border: 1px solid #ccc; padding: 6px 13px; } .markdown-body table tr { border-top: 1px solid #ccc; background-color: #fff; } .markdown-body table tr:nth-child(2n) { background-color: #f8f8f8; } .markdown-body img { max-width: 100%; -moz-box-sizing: border-box; box-sizing: border-box; } .markdown-body span.frame { display: block; overflow: hidden; } .markdown-body span.frame>span { border: 1px solid #ddd; display: block; float: left; overflow: hidden; margin: 13px 0 0; padding: 7px; width: auto; } .markdown-body span.frame span img { display: block; float: left; } .markdown-body span.frame span span { clear: both; color: #333; display: block; padding: 5px 0 0; } .markdown-body span.align-center { display: block; overflow: hidden; clear: both; } .markdown-body span.align-center>span { display: block; overflow: hidden; margin: 13px auto 0; text-align: center; } .markdown-body span.align-center span img { margin: 0 auto; text-align: center; } .markdown-body span.align-right { display: block; overflow: hidden; clear: both; } .markdown-body span.align-right>span { display: block; overflow: hidden; margin: 13px 0 0; text-align: right; } .markdown-body span.align-right span img { margin: 0; text-align: right; } .markdown-body span.float-left { display: block; margin-right: 13px; overflow: hidden; float: left; } .markdown-body span.float-left span { margin: 13px 0 0; } .markdown-body span.float-right { display: block; margin-left: 13px; overflow: hidden; float: right; } .markdown-body span.float-right>span { display: block; overflow: hidden; margin: 13px auto 0; text-align: right; } .markdown-body code, .markdown-body tt { margin: 0 2px; padding: 0px 5px; border: 1px solid #eaeaea; background-color: #f8f8f8; border-radius: 3px; } .markdown-body code { white-space: nowrap; } .markdown-body pre>code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent; } .markdown-body .highlight pre, .markdown-body pre { background-color: #f8f8f8; border: 1px solid #ccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-radius: 3px; } .markdown-body pre code, .markdown-body pre tt { margin: 0; padding: 0; background-color: transparent; border: none; } pre { line-height: 125%; } td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight { background: #ffffff; } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */

Haketilo - Make The Web Great Again!

This WebExtension's goal is to allow replacing javascript served by websites with scripts specified by user. If you know NoScript or Greasemonkey, Haketilo is an extension that overlaps with functionalities and use-cases of both. It is also correct to consider it a response to a call made in RMS' "The JavaScript Trap".

Targeted browsers

Currently we support Chromium (versions 90+, older might also work but are untested), Firefox (versions 60+) and their derivatives.

Building

There're currently 2 ways to build Haketilo.

1. Simple stupid way - build.sh script

You only need a POSIX-compliant environment for this (shell, awk, etc.). It is a viable option if you don't need to run the automated test suite. From project's root directory, using a POSIX shell, you type either:

./build.sh mozilla # to build for Firefox-based browsers

or:

./build.sh chromium # to build for Chromium-based browsers

The unpacked extension shall be generated under ./mozilla-unpacked/ or ./chromium-unpacked/, respectively. You can then load it into your browser as a temporary extension or pack it into an xpi/crx/zip archive manually, e.g.:

7z a -tzip haketilo.xpi -w mozilla-unpacked/.

2. configure-based build

This method assumes you have not only a POSIX environment but also a working Make tool and the zip command. From project's root directory, run the shell commands:

./configure --host=mozilla # or analogically with --host=chromium
make

This would generate the unpacked extension under ./mozilla-unpacked/ and its zipped version under ./mozilla_build.zip (which you can rename to .xpi if you want).

You can also perform an out-of-source build, for example:

mkdir /tmp/haketilo-build && cd /tmp/haketilo-build
/path/to/haketilo/sources/configure --host=chromium
make all # will generate both ./mozilla-build.zip and ./chromium-build.zip

Testing

Requirements

Configuring

Note: like building, testing can be performed out-of-source; this can be useful when testing under multiple browsers simultaneously

Running tests requires you to pass some additional information to configure. Relevant options are:

option name explanation
BROWSER_BINARY Path to the browser's binary executable. Under many scenarios the browser executable in PATH is a shell wrapper around the actual binary. Selenium will refuse to work with that and instead requires the binary to be passed (e.g. /usr/lib/abrowser/abrowser instead of /usr/bin/abrowser
CLEAN_PROFILE Path to a directory with browser profile that is "clean", i.e. has all extensions disabled. This is to mitigate the fact that some browsers pick up globally-installed extensions when creating a new profile for testing and these could interfere with our automated tests. This option can currently be skipped because all tests written so far run the browser in safe mode.
DRIVER Selenium driver command (e.g. geckodriver).
PYTHON Python 3 command. The interpreter spawned with this command is expected to have Pytest and Selenium in its import path.

Options can be specified to configure using the following notations (can be mixed):

./configure --host=mozilla --browser-binary=/usr/local/lib/icecat/icecat
./configure --host mozilla --browser-binary /usr/local/lib/icecat/icecat
./configure HOST=mozilla BROWSER_BINARY=/usr/local/lib/icecat/icecat

configure will try to guess the proper values for options that were not given. To help with this, you can (in some cases) give your actual browser name to --host, for example:

$ ./configure --host=abrowser
Guessing SRCDIR: /home/urz/haketilo-development/browser-extension
Guessing BROWSER_BINARY: /usr/lib/abrowser/abrowser
Guessing DRIVER: /usr/bin/geckodriver
Guessing PYTHON: /usr/bin/python3
Guessing DESTDIR: /usr/share/mozilla/extensions/
$

This may or may not work, depending on the underlying operating system and how the tools were installed.

Running

After configuring, the entire test suite can be run with:

make test

Alternatively, it is possible to run Pytest directly to have some fine-grained control over which tests are run, e.g.:

# Generate the necessary certificates and pytest.ini. This is done automatically
# when running `make test`.
make test-prepare

# Optionally prevent Python from clobbering source directories with .pyc files.
# `make test` rule does the same.
#export PYTHONPYCACHEPREFIX="$(pwd)/test__pycache__"

# Optionally stop Firefox from spawning window(s) during test.
#export MOZ_HEADLESS=whatever

# Run all popup tests with high verbosity.
python3 -m pytest -vv -k popup

As of Haketilo 2.0 some tests may spuriously fail. This is the result of it being notoriously difficult to avoid some weirdnesses when driving Firefox using Selenium. To make sure a failed test is not the result of some more serious bug, you might want to rerun the test suite.

Setting up an environment for manual testing

The automated tests are run with browser's all network requests going through a Python proxy. The proxy allows us to mock websites that are then navigated to in the browser. At times you might want to replicate this test environment while playing manually with the browser. A poor man's approach is to add something like:

from time import sleep
sleep(100000)

inside one of the test functions and then run that test function from Pytest (with MOZ_HEADLESS unset!). This might make sense when debugging some particular test case. For general experiments we have instead provided convenience targets make test-environment and make test-environment-with-haketilo. Running any of those will spawn a browser window together with a Python shell where driver variable will hold Selenium driver object controlling that browser. In case of the test-environment-with-haketilo target the browser will additionally appear with Haketilo loaded into it.

Copying

All copyright information is gathered in the copyright file which follows the format of debian/copyright file. License notices are also present in all text files of the extension.

In general, this entire extension is available under the terms of GPLv3+ with various additional licenses and permissions for particular files.

I, Wojtek Kosior, thereby promise not to sue for violation of this program's licenses. 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.

More documentation

See our wiki for information.

Contributing

Development happens on our Redmine instance.

Alternatively, you can write to koszko@koszko.org.