Compare commits

..

No commits in common. 'master' and '0.9.0.1' have entirely different histories.

@ -1,29 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Browser (please complete the following information):**
- OS: [e.g. MacOS, Linux]
- Browser [e.g. Firefox]
- Version [e.g. 80.0.1]
**Additional context**
Add any other context about the problem here.

@ -1,17 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

2
.gitignore vendored

@ -1 +1 @@
dist/build/
dist/

@ -1,20 +0,0 @@
{
"browser": true,
"devel": true,
"eqeqeq": true,
"esversion": 8,
"globals": {
"browser": false,
"self": false,
"chrome": false,
"log": false,
"webext": false,
"vAPI": false,
"µMatrix": false
},
"laxbreak": true,
"strict": "global",
"undef": true,
"unused": true,
"validthis": true
}

@ -3,13 +3,12 @@ env:
matrix:
- BROWSER=chromium EXT=zip
- BROWSER=firefox EXT=xpi
script: "./tools/make-${BROWSER}.sh ${TRAVIS_TAG}"
script: ./tools/make-${BROWSER}.sh all
deploy:
provider: releases
prerelease: true
api_key:
secure: eQgPAHH6PKu2dLK+NafxwLl66t0cyW5x5NZFquOwsNMal5nsfof7lyXj2F0Q0vUpGeI21MOipBI8UGv5oXPoiXnr0fhEbEBz65C9vypK61WkDCQVGVeZVNGQwSXUm6gD2EzpPgTCIs52+7dKCDJ3stXzdimOiOTYs4WMNKKarFM=
file: dist/build/uMatrix_${TRAVIS_TAG}.${BROWSER}.${EXT}
file: dist/build/uMatrix.${BROWSER}.${EXT}
skip_cleanup: true
on:
repo: gorhill/uMatrix

@ -1,4 +1,16 @@
### Submitting issues
# Submitting issues
Submit on <https://github.com/geekprojects/nuTensor/issues>.
**Must read:** [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html).
### IMPORTANT
1. When you file an issue, your **responsibility** is to provide **ALL** the exact steps needed for me to reproduce an issue.
1. Ideally, never should I have to _guess_ how to reproduce an issue.
- Hence this is why very detailed steps must be very carefully written down **the first time** the issue is filed.
- Never assume an important step is "obvious".
1. Every single step, in order, must be provided, with **ALL** relevant details.
1. Screenshots are nice, but use common sense: I can't cut and paste important text information from screenshots.
- Regarding screenshots: common sense, common sense, common sense. Too much of a thing can easily end up as noise.
1. Open source quality software comes from contributors carefully **crafting** code: conversely, issues must also be carefully **crafted**.
- In other words: you benefit from the carefully crafted code, return the favor by **carefully** crafting issues/bug reports.
1. If your mindset is that your time is more precious than that of my time, refrain from filing issues.

@ -1,23 +1,34 @@
## nuTensor
## uMatrix<br>[<img src="https://travis-ci.org/gorhill/uMatrix.svg?branch=master" height="16">](https://travis-ci.org/gorhill/uMatrix)
Definitely for advanced users.
This is a fork of the now-discontinued [uMatrix](https://github.com/gorhill/uMatrix).
My focus will be on keeping it working on Firefox for now. I'll do my best to keep it working, but sadly no guarantees. Help will always be welcome!
Forked and refactored from [HTTP Switchboard](https://github.com/gorhill/httpswitchboard).
***
Install [manually](https://github.com/gorhill/uMatrix/blob/master/doc/README.md) the [latest release](https://github.com/gorhill/uMatrix/releases), or install from:
- [Firefox AMO](https://addons.mozilla.org/firefox/addon/umatrix/)
- [Chrome store](https://chrome.google.com/webstore/detail/µmatrix/ogfcmafjalglgifnmanfmnieipoejdcf)
- [Opera store](https://addons.opera.com/en-gb/extensions/details/umatrix/)
Forked and refactored from [uMatrix](https://github.com/gorhill/uMatrix).
You may contribute with translation work:
- For in-app strings, on Crowdin: [uMatrix on Crowdin](https://crowdin.com/project/umatrix).
- For [description](https://github.com/gorhill/uMatrix/tree/master/doc/description) (to be used in AMO, Chrome store, etc.), submit a pull request. [Reference description is here](https://github.com/gorhill/uMatrix/blob/master/doc/description/description.en_US.txt) (feel free to improve as you wish, I am not a writer).
[HTTP Switchboard's documentation](https://github.com/gorhill/httpswitchboard/wiki) is still relevant, except for [uMatrix's differences with HTTP Switchboard](https://github.com/gorhill/uMatrix/wiki/Changes-from-HTTP-Switchboard).
You may contribute with documentation: [uMatrix's wiki](https://github.com/gorhill/uMatrix/wiki).
## Warnings
#### Regarding broken sites
nuTensor does not guarantee that sites will work fine: it is for advanced users who can figure how to un-break sites, because essentially nuTensor is a firewall which works in relaxed block-all/allow-exceptionally mode out of the box: it is not unexpected that sites will break.
uMatrix does not guarantee that sites will work fine: it is for advanced users who can figure how to un-break sites, because essentially uMatrix is a firewall which works in relaxed block-all/allow-exceptionally mode out of the box: it is not unexpected that sites will break.
**So this means do not file issues to report broken sites when the sites are broken because uMatrix does its job as expected.** I will close any such issue without further comment.
I expect there will be community driven efforts for users to help each others. If uMatrix had a home, I would probably set up a forum, but I do not plan for such thing, I really just want to code, not manage web sites. If you need help to un-break a site when using uMatrix, you can try [Wilders Security](http://www.wilderssecurity.com/threads/umatrix-the-http-switchboard-successor.369601/), where you are likely to receive help if needed, whether by me or other users.
**So this means do not file issues to report broken sites when the sites are broken because nuTensor does its job as expected.** I will close any such issue without further comment.
uMatrix can be set to work in [allow-all/block-exceptionally](https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views#the-allow-allblock-exceptionally-approach) mode with a single click on the `all` cell in the global scope `*`, if you prefer to work this way. This will of course break less sites, but you would then lose all the benefits which comes with block-all/allow-exceptionally mode -- though you will still benefit from the 62,000+ blacklisted hostnames by default.
**Using nuTensor logger is key to un-break sites:** the logger will show you all that nuTensor does internally.
## License

@ -1,88 +0,0 @@
{
"assets.json": {
"content": "internal",
"updateAfter": 13,
"contentURL": [
"https://raw.githubusercontent.com/geekprojects/nuTensor/master/assets/assets.json",
"assets/assets.json"
]
},
"public_suffix_list.dat": {
"content": "internal",
"updateAfter": 19,
"contentURL": [
"https://publicsuffix.org/list/public_suffix_list.dat",
"assets/thirdparties/publicsuffix.org/list/public_suffix_list.dat",
"assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat"
]
},
"malware-0": {
"content": "filters",
"title": "Malware Domain List",
"contentURL": [
"https://www.malwaredomainlist.com/hostslist/hosts.txt",
"assets/thirdparties/www.malwaredomainlist.com/hostslist/hosts.txt"
]
},
"malware-1": {
"content": "filters",
"title": "Malware domains",
"contentURL": [
"https://mirror.cedia.org.ec/malwaredomains/justdomains",
"https://mirror1.malwaredomains.com/files/justdomains",
"assets/thirdparties/mirror1.malwaredomains.com/files/justdomains",
"assets/thirdparties/mirror1.malwaredomains.com/files/justdomains.txt"
],
"supportURL": "http://www.malwaredomains.com/"
},
"dpollock-0": {
"content": "filters",
"updateAfter": 11,
"title": "Dan Pollocks hosts file",
"contentURL": [
"https://someonewhocares.org/hosts/hosts",
"assets/thirdparties/someonewhocares.org/hosts/hosts.txt"
],
"supportURL": "https://someonewhocares.org/hosts/"
},
"hphosts": {
"content": "filters",
"updateAfter": 11,
"title": "hpHosts Ad and tracking servers",
"contentURL": [
"https://hosts-file.net/.%5Cad_servers.txt",
"assets/thirdparties/hosts-file.net/ad_servers.txt"
],
"supportURL": "https://hosts-file.net/"
},
"mvps-0": {
"content": "filters",
"updateAfter": 11,
"title": "MVPS HOSTS",
"contentURL": [
"https://winhelp2002.mvps.org/hosts.txt",
"assets/thirdparties/winhelp2002.mvps.org/hosts.txt"
],
"supportURL": "https://winhelp2002.mvps.org/"
},
"plowe-0": {
"content": "filters",
"updateAfter": 13,
"title": "Peter Lowes Ad and tracking server list",
"contentURL": [
"https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=1&mimetype=plaintext",
"assets/thirdparties/pgl.yoyo.org/as/serverlist",
"assets/thirdparties/pgl.yoyo.org/as/serverlist.txt"
],
"supportURL": "https://pgl.yoyo.org/adservers/"
},
"recipes_en-0": {
"content": "recipes",
"title": "Ruleset recipes for English websites",
"contentURL": [
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/recipes/recipes_en.txt",
"assets/umatrix/recipes_en.txt"
],
"lang": "en"
}
}

@ -0,0 +1,13 @@
4a3dedc1e913ac1dbb316606a4b5306d assets/umatrix/hosts-files.json
188ce926323d816ae9d7d5ebbb567862 assets/umatrix/blacklist.txt
1beb3b4b6458f6d3988b91cd981a97f0 assets/thirdparties/mirror1.malwaredomains.com/files/immortal_domains.txt
7f0443f3dcc9abfd47cfbc95ce824ddb assets/thirdparties/mirror1.malwaredomains.com/files/README.md
82711967354d935f4646014ee1d7c6a0 assets/thirdparties/mirror1.malwaredomains.com/files/justdomains
597f052c40b71ecd029eedd5752633aa assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat
ccdb144db937e5f11e3ee7055b512831 assets/thirdparties/someonewhocares.org/hosts/hosts
83b2f4bc3c79f554f4eee5de018d2a89 assets/thirdparties/winhelp2002.mvps.org/hosts.txt
042419405031f0fcfac3735bf4f05e21 assets/thirdparties/www.malwaredomainlist.com/hostslist/README.md
ceb0394086d4e23b440cf3e186eea60c assets/thirdparties/www.malwaredomainlist.com/hostslist/hosts.txt
bd6b77760ea831b8961f1b69550511d9 assets/thirdparties/hosts-file.net/ad-servers
5663bfec7aea394ba4e1533950cb69b8 assets/thirdparties/pgl.yoyo.org/as/serverlist
5b8e13b618c68293430913029118781a assets/thirdparties/pgl.yoyo.org/as/README.md

File diff suppressed because it is too large Load Diff

@ -0,0 +1,3 @@
<http://www.malwaredomains.com/?page_id=1508>:
"This malware block lists provided here are for free for noncommercial use as part of the fight against malware."

@ -0,0 +1,4 @@
<http://pgl.yoyo.org/as/index.php>:
Site does encourage use of the list, and nowhere could I find terms and
conditions to use the list. Assuming it can be used freely.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,3 @@
<http://www.malwaredomainlist.com/>:
"Our list can be used for free by anyone. Feel free to use it."

@ -0,0 +1,61 @@
# Blacklist maintained by HTTP Switchboard
# For those domain names which are not found in other blacklists
2mdn.net # "2mdn.net is a domain used by Doubleclick which is an advertising company..."
aad73c550c.se # Related to adrotator.se which is itself blacklisted
acxiom-online.com # Wikipedia: "Acxiom Corporation is a marketing technology and services company".
adextent.com # "We are an advertising technology company - we build technologies that improve ads performance"
adgear.com # "AdGear is an online advertising technologies company based in Montreal, Canada"
adnxs.com # "Adnxs.com is run by AppNexus, a company that provides technology, data and analytics to help companies buy and sell online display advertising" (Ref.: http://www.theguardian.com/technology/2012/apr/23/adnxs-tracking-trackers-cookies-web-monitoring)
adobetag.com # "Adobe Announces Adobe Tag Manager for the Online Marketing Suite"
aimatch.com # "Ad Server, SAS® Intelligent Advertising for Publishers"
analytics.edgesuite.net
atedra.com # "Atedra est un réseau de publicité Internet francophone au Canada"
axf8.net # https://www.eff.org/deeplinks/2013/06/third-party-resources-nsa-leaks
betrad.com # "Evidon: Home | Online Marketing Intelligence, Web Analytics, Privacy" (which also publishes "Ghostery" add-on..)
bizographics.com # "Business Audience Marketing"
bkrtx.com
# "Imagine Having The Power To Turn Abandoning Visitors Into Customers"
# "The BounceX software is tracking all the cursor movements of every visitor in real-time" (yikes!)
bounceexchange.com
clicktale.com # "See absolutely everything your visitors do on your webpage ... See their every mouse move, click and keystroke"
clicktale.net # Redirect to `clicktale.com`
crosspixel.net # (cookies, localStorage) "leading provider of high performance audience data and information for the real-time advertising industry"
crsspxl.com # Related to crosspixel.net
datarating.com # see https://github.com/gorhill/httpswitchboard/issues/343
displaymarketplace.com
erovinmo.com # No info whatsoever from site itself can be found = naughty corner. Ironically spotted at "http://www.technologyreview.com/news/519336/bruce-schneier-nsa-spying-is-making-us-less-safe/" (also: http://www.mywot.com/en/scorecard/erovinmo.com)
exelator.com # "domain used by eXelate Media which is an advertising company that is part of a network of sites, cookies, and other technologies used to track you" (Ref.: http://www.donottrackplus.com/trackers/exelator.com.php)
everestjs.net # related to `everesttech.net`
everesttech.net # "search engine marketing (SEM) solutions", pixel image on the page, looks like tracking to me. Spotted @ `http://www.homedepot.ca/` (search worked fine when blocking this hostname)
eyereturn.com # "eyeReturn Marketing is the only end-to-end digital advertising platform in the market"
gigya.com # "The tools you need to connect with consumers, harness rich data, and make marketing relevant"
inmuiads.info #
janrainbackplane.com # "Easily visualize, segment and update customer profiles to enable true personalized marketing"
krxd.net # https://www.eff.org/deeplinks/2013/06/third-party-resources-nsa-leaks
lijit.com # "We provide online advertising services, audience analytics"
llnwd.net # http://en.wikipedia.org/wiki/Limelight_Networks
lduhtrp.net
mathtag.com # "domain used by MediaMath to place cookies, on behalf of its customers, on the computers of visitors to our selected customer's websites and who may view our customer's display advertisements"
mxpnl.com #
moatads.com # https://www.eff.org/deeplinks/2013/06/third-party-resources-nsa-leaks
mookie1.com # "Specializing in online digital advertising, search marketing"
msads.net # Sounds like ads, and no home web page...
omtrdc.net # Redirect to Omniture
outbrain.com # https://www.eff.org/deeplinks/2013/06/third-party-resources-nsa-leaks
panoramtech.net # As seen in a screenshot at http://arstechnica.com/security/2014/01/malware-vendors-buy-chrome-extensions-to-send-adware-filled-updates/
parsely.com # http://en.wikipedia.org/wiki/Parse.ly
peer39.net # https://www.eff.org/deeplinks/2013/06/third-party-resources-nsa-leaks
pub2srv.com # "This url is used by ad network Propeller Ads Media for ad serving"
servebom.com # no home page, seen as 'tracking.servebom.com': good enough for this list
# These have "tracking" in domain name...
tracking.tomsguide.com
tracking.tomshardware.com
tracking.tomshardware.co.uk
wunderloop.net # https://www.eff.org/deeplinks/2013/06/third-party-resources-nsa-leaks
yceml.net

@ -0,0 +1,30 @@
{
"mirror1.malwaredomains.com/files/immortal_domains.txt": {
"title": "Long-lived malware domains",
"homeURL": "http://dns-bh.sagadc.org/immortal_domains.txt"
},
"mirror1.malwaredomains.com/files/justdomains": {
"title": "Malware domains",
"homeURL": "http://malwaredomains.lehigh.edu/files/justdomains"
},
"pgl.yoyo.org/as/serverlist": {
"title": "Peter Lowes Ad server list",
"homeURL": "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=1&mimetype=plaintext"
},
"www.malwaredomainlist.com/hostslist/hosts.txt": {
"title": "Malware Domain List",
"homeURL": "http://www.malwaredomainlist.com/hostslist/hosts.txt"
},
"hosts-file.net/ad-servers": {
"title": "hpHostss Ad and tracking servers",
"homeURL": "http://hosts-file.net/.%5Cad_servers.txt"
},
"someonewhocares.org/hosts/hosts": {
"title": "Dan Pollocks hosts file",
"homeURL": "http://someonewhocares.org/hosts/hosts"
},
"winhelp2002.mvps.org/hosts.txt": {
"title": "MVPS HOSTS",
"homeURL": "http://winhelp2002.mvps.org/hosts.txt"
}
}

@ -1,192 +0,0 @@
#!/usr/bin/env python3
import datetime
import json
import jwt
import os
import re
import requests
import shutil
import subprocess
import sys
import tempfile
import time
import zipfile
from distutils.version import StrictVersion
from string import Template
# - Download target (raw) uMatrix.chromium.zip from GitHub
# - This is referred to as "raw" package
# - This will fail if not a dev build
# - Upload uMatrix.chromium.zip to Chrome store
# - Publish uMatrix.chromium.zip to Chrome store
# Find path to project root
projdir = os.path.split(os.path.abspath(__file__))[0]
while not os.path.isdir(os.path.join(projdir, '.git')):
projdir = os.path.normpath(os.path.join(projdir, '..'))
# We need a version string to work with
if len(sys.argv) >= 2 and sys.argv[1]:
version = sys.argv[1]
else:
version = input('Github release version: ')
version.strip()
if not re.search('^\d+\.\d+\.\d+(b|rc)\d+$', version):
print('Error: Invalid version string.')
exit(1)
cs_extension_id = 'eckgcipdkhcfghnmincccnhpdmnbefki'
tmpdir = tempfile.TemporaryDirectory()
raw_zip_filename = 'uMatrix_'+ version + '.chromium.zip'
raw_zip_filepath = os.path.join(tmpdir.name, raw_zip_filename)
github_owner = 'gorhill'
github_repo = 'uMatrix'
# Load/save auth secrets
# The build directory is excluded from git
ubo_secrets = dict()
ubo_secrets_filename = os.path.join(projdir, 'dist', 'build', 'ubo_secrets')
if os.path.isfile(ubo_secrets_filename):
with open(ubo_secrets_filename) as f:
ubo_secrets = json.load(f)
def input_secret(prompt, token):
if token in ubo_secrets:
prompt += ''
prompt += ': '
value = input(prompt).strip()
if len(value) == 0:
if token not in ubo_secrets:
print('Token error:', token)
exit(1)
value = ubo_secrets[token]
elif token not in ubo_secrets or value != ubo_secrets[token]:
ubo_secrets[token] = value
exists = os.path.isfile(ubo_secrets_filename)
with open(ubo_secrets_filename, 'w') as f:
json.dump(ubo_secrets, f, indent=2)
if not exists:
os.chmod(ubo_secrets_filename, 0o600)
return value
# GitHub API token
github_token = input_secret('Github token', 'github_token')
github_auth = 'token ' + github_token
#
# Get metadata from GitHub about the release
#
# https://developer.github.com/v3/repos/releases/#get-a-single-release
print('Downloading release info from GitHub...')
release_info_url = 'https://api.github.com/repos/{0}/{1}/releases/tags/{2}'.format(github_owner, github_repo, version)
headers = { 'Authorization': github_auth, }
response = requests.get(release_info_url, headers=headers)
if response.status_code != 200:
print('Error: Release not found: {0}'.format(response.status_code))
exit(1)
release_info = response.json()
#
# Extract URL to raw package from metadata
#
# Find url for uMatrix.chromium.zip
raw_zip_url = ''
for asset in release_info['assets']:
if asset['name'] == raw_zip_filename:
raw_zip_url = asset['url']
if len(raw_zip_url) == 0:
print('Error: Release asset URL not found')
exit(1)
#
# Download raw package from GitHub
#
# https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
print('Downloading raw zip package from GitHub...')
headers = {
'Authorization': github_auth,
'Accept': 'application/octet-stream',
}
response = requests.get(raw_zip_url, headers=headers)
# Redirections are transparently handled:
# http://docs.python-requests.org/en/master/user/quickstart/#redirection-and-history
if response.status_code != 200:
print('Error: Downloading raw package failed -- server error {0}'.format(response.status_code))
exit(1)
with open(raw_zip_filepath, 'wb') as f:
f.write(response.content)
print('Downloaded raw package saved as {0}'.format(raw_zip_filepath))
#
# Upload to Chrome store
#
# Auth tokens
cs_id = input_secret('Chrome store id', 'cs_id')
cs_secret = input_secret('Chrome store secret', 'cs_secret')
cs_refresh = input_secret('Chrome store refresh token', 'cs_refresh')
print('Uploading to Chrome store...')
with open(raw_zip_filepath, 'rb') as f:
print('Generating access token...')
auth_url = 'https://accounts.google.com/o/oauth2/token'
auth_payload = {
'client_id': cs_id,
'client_secret': cs_secret,
'grant_type': 'refresh_token',
'refresh_token': cs_refresh,
}
auth_response = requests.post(auth_url, data=auth_payload)
if auth_response.status_code != 200:
print('Error: Auth failed -- server error {0}'.format(auth_response.status_code))
print(auth_response.text)
exit(1)
response_dict = auth_response.json()
if 'access_token' not in response_dict:
print('Error: Auth failed -- no access token')
exit(1)
# Prepare access token
cs_auth = 'Bearer ' + response_dict['access_token']
headers = {
'Authorization': cs_auth,
'x-goog-api-version': '2',
}
# Upload
print('Uploading package...')
upload_url = 'https://www.googleapis.com/upload/chromewebstore/v1.1/items/{0}'.format(cs_extension_id)
upload_response = requests.put(upload_url, headers=headers, data=f)
f.close()
if upload_response.status_code != 200:
print('Upload failed -- server error {0}'.format(upload_response.status_code))
print(upload_response.text)
exit(1)
response_dict = upload_response.json();
if 'uploadState' not in response_dict or response_dict['uploadState'] != 'SUCCESS':
print('Upload failed -- server error {0}'.format(response_dict['uploadState']))
exit(1)
print('Upload succeeded.')
# Publish
print('Publishing package...')
publish_url = 'https://www.googleapis.com/chromewebstore/v1.1/items/{0}/publish'.format(cs_extension_id)
headers = {
'Authorization': cs_auth,
'x-goog-api-version': '2',
'Content-Length': '0',
}
publish_response = requests.post(publish_url, headers=headers)
if publish_response.status_code != 200:
print('Error: Chrome store publishing failed -- server error {0}'.format(publish_response.status_code))
exit(1)
response_dict = publish_response.json();
if 'status' not in response_dict or response_dict['status'][0] != 'OK':
print('Publishing failed -- server error {0}'.format(response_dict['status']))
exit(1)
print('Publishing succeeded.')
print('All done.')

@ -1,321 +0,0 @@
#!/usr/bin/env python3
import datetime
import json
import jwt
import os
import re
import requests
import shutil
import subprocess
import sys
import tempfile
import time
import zipfile
from distutils.version import LooseVersion
from string import Template
# - Download target (raw) nuTensor.firefox.xpi from GitHub
# - This is referred to as "raw" package
# - This will fail if not a dev build
# - Modify raw package to make it self-hosted
# - This is referred to as "unsigned" package
# - Ask AMO to sign nuTensor.firefox.xpi
# - Generate JWT to be used for communication with server
# - Upload unsigned package to AMO
# - Wait for a valid download URL for signed package
# - Download signed package as nuTensor.firefox.signed.xpi
# - This is referred to as "signed" package
# - Upload nuTensor.firefox.signed.xpi to GitHub
# - Remove nuTensor.firefox.xpi from GitHub
# - Modify updates.json to point to new version
# - Commit changes to repo
# Find path to project root
projdir = os.path.split(os.path.abspath(__file__))[0]
while not os.path.isdir(os.path.join(projdir, '.git')):
projdir = os.path.normpath(os.path.join(projdir, '..'))
# Check that found project root is valid
version_filepath = os.path.join(projdir, 'dist', 'version')
if not os.path.isfile(version_filepath):
print('Version file not found.')
exit(1)
# We need a version string to work with
if len(sys.argv) >= 2 and sys.argv[1]:
tag_version = sys.argv[1]
else:
tag_version = input('Github release version: ')
tag_version.strip()
match = re.search('^(\d+\.\d+\.\d+)(?:(b|rc)(\d+))?$', tag_version)
if not match:
print('Error: Invalid version string.')
exit(1)
ext_version = match.group(1);
if match.group(2):
revision = int(match.group(3))
if match.group(2) == 'rc':
revision += 100;
ext_version += '.' + str(revision)
extension_id = 'nuTensor@geekprojects.com'
tmpdir = tempfile.TemporaryDirectory()
raw_xpi_filename = 'nuTensor_' + tag_version + '.firefox.xpi'
raw_xpi_filepath = os.path.join(tmpdir.name, raw_xpi_filename)
unsigned_xpi_filepath = os.path.join(tmpdir.name, 'nuTensor.firefox.unsigned.xpi')
signed_xpi_filename = 'nuTensor_' + tag_version + '.firefox.signed.xpi'
signed_xpi_filepath = os.path.join(tmpdir.name, signed_xpi_filename)
github_owner = 'geekprojects'
github_repo = 'nuTensor'
# Load/save auth secrets
# The build directory is excluded from git
ubo_secrets = dict()
ubo_secrets_filename = os.path.join(projdir, 'dist', 'build', 'ubo_secrets')
if os.path.isfile(ubo_secrets_filename):
with open(ubo_secrets_filename) as f:
ubo_secrets = json.load(f)
def input_secret(prompt, token):
if token in ubo_secrets:
prompt += ''
prompt += ': '
value = input(prompt).strip()
if len(value) == 0:
if token not in ubo_secrets:
print('Token error:', token)
exit(1)
value = ubo_secrets[token]
elif token not in ubo_secrets or value != ubo_secrets[token]:
ubo_secrets[token] = value
exists = os.path.isfile(ubo_secrets_filename)
with open(ubo_secrets_filename, 'w') as f:
json.dump(ubo_secrets, f, indent=2)
if not exists:
os.chmod(ubo_secrets_filename, 0o600)
return value
# GitHub API token
github_token = input_secret('Github token', 'github_token')
github_auth = 'token ' + github_token
#
# Get metadata from GitHub about the release
#
# https://developer.github.com/v3/repos/releases/#get-a-single-release
print('Downloading release info from GitHub...')
release_info_url = 'https://api.github.com/repos/{0}/{1}/releases/tags/{2}'.format(github_owner, github_repo, tag_version)
headers = { 'Authorization': github_auth, }
response = requests.get(release_info_url, headers=headers)
if response.status_code != 200:
print('Error: Release not found: {0}'.format(response.status_code))
exit(1)
release_info = response.json()
#
# Extract URL to raw package from metadata
#
# Find url for nuTensor.firefox.xpi
raw_xpi_url = ''
for asset in release_info['assets']:
if asset['name'] == signed_xpi_filename:
print('Error: Found existing signed self-hosted package.')
exit(1)
if asset['name'] == raw_xpi_filename:
raw_xpi_url = asset['url']
if len(raw_xpi_url) == 0:
print('Error: Release asset URL not found')
exit(1)
#
# Download raw package from GitHub
#
# https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
print('Downloading raw xpi package from GitHub...')
headers = {
'Authorization': github_auth,
'Accept': 'application/octet-stream',
}
response = requests.get(raw_xpi_url, headers=headers)
# Redirections are transparently handled:
# http://docs.python-requests.org/en/master/user/quickstart/#redirection-and-history
if response.status_code != 200:
print('Error: Downloading raw package failed -- server error {0}'.format(response.status_code))
exit(1)
with open(raw_xpi_filepath, 'wb') as f:
f.write(response.content)
print('Downloaded raw package saved as {0}'.format(raw_xpi_filepath))
#
# Convert the package to a self-hosted one: add `update_url` to the manifest
#
print('Converting raw xpi package into self-hosted xpi package...')
with zipfile.ZipFile(raw_xpi_filepath, 'r') as zipin:
with zipfile.ZipFile(unsigned_xpi_filepath, 'w') as zipout:
for item in zipin.infolist():
data = zipin.read(item.filename)
if item.filename == 'manifest.json':
manifest = json.loads(bytes.decode(data))
manifest['browser_specific_settings']['gecko']['update_url'] = 'https://raw.githubusercontent.com/{0}/{1}/master/dist/firefox/updates.json'.format(github_owner, github_repo)
data = json.dumps(manifest, indent=2, separators=(',', ': '), sort_keys=True).encode()
zipout.writestr(item, data)
#
# Ask AMO to sign the self-hosted package
# - https://developer.mozilla.org/en-US/Add-ons/Distribution#Distributing_your_add-on
# - https://pyjwt.readthedocs.io/en/latest/usage.html
# - https://addons-server.readthedocs.io/en/latest/topics/api/auth.html
# - https://addons-server.readthedocs.io/en/latest/topics/api/signing.html
#
amo_api_key = ''
amo_secret = ''
def get_jwt_auth():
global amo_api_key
if amo_api_key == '':
amo_api_key = input_secret('AMO API key', 'amo_api_key')
global amo_secret
if amo_secret == '':
amo_secret = input_secret('AMO API secret', 'amo_secret')
amo_nonce = os.urandom(8).hex()
jwt_payload = {
'iss': amo_api_key,
'jti': amo_nonce,
'iat': datetime.datetime.utcnow(),
'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=15),
}
return 'JWT ' + jwt.encode(jwt_payload, amo_secret).decode()
print('Ask AMO to sign self-hosted xpi package...')
with open(unsigned_xpi_filepath, 'rb') as f:
# https://blog.mozilla.org/addons/2019/11/11/security-improvements-in-amo-upload-tools/
# "We recommend allowing up to 15 minutes."
interval = 60 # check every 60 seconds
countdown = 15 * 60 / interval # for at most 15 minutes
headers = { 'Authorization': get_jwt_auth(), }
data = { 'channel': 'unlisted' }
files = { 'upload': f, }
signing_url = 'https://addons.mozilla.org/api/v3/addons/{0}/versions/{1}/'.format(extension_id, ext_version)
print('Submitting package to be signed...')
response = requests.put(signing_url, headers=headers, data=data, files=files)
if response.status_code != 202:
print('Error: Creating new version failed -- server error {0}'.format(response.status_code))
print(response.text)
exit(1)
print('Request for signing self-hosted xpi package succeeded.')
signing_request_response = response.json();
f.close()
print('Waiting for AMO to process the request to sign the self-hosted xpi package...')
# Wait for signed package to be ready
signing_check_url = signing_request_response['url']
while True:
sys.stdout.write('.')
sys.stdout.flush()
time.sleep(interval)
countdown -= 1
if countdown <= 0:
print('Error: AMO signing timed out')
exit(1)
headers = { 'Authorization': get_jwt_auth(), }
response = requests.get(signing_check_url, headers=headers)
if response.status_code != 200:
print('Error: AMO signing failed -- server error {0}'.format(response.status_code))
print(response.text)
exit(1)
signing_check_response = response.json()
if not signing_check_response['processed']:
continue
if not signing_check_response['valid']:
print('Error: AMO validation failed')
print(response.text)
exit(1)
if not signing_check_response['files'] or len(signing_check_response['files']) == 0:
continue
if not signing_check_response['files'][0]['signed']:
continue
if not signing_check_response['files'][0]['download_url']:
print('Error: AMO signing failed')
print(response.text)
exit(1)
print('\r')
print('Self-hosted xpi package successfully signed.')
download_url = signing_check_response['files'][0]['download_url']
print('Downloading signed self-hosted xpi package from {0}...'.format(download_url))
response = requests.get(download_url, headers=headers)
if response.status_code != 200:
print('Error: Download signed package failed -- server error {0}'.format(response.status_code))
print(response.text)
exit(1)
with open(signed_xpi_filepath, 'wb') as f:
f.write(response.content)
f.close()
print('Signed self-hosted xpi package downloaded.')
break
#
# Upload signed package to GitHub
#
# https://developer.github.com/v3/repos/releases/#upload-a-release-asset
print('Uploading signed self-hosted xpi package to GitHub...')
with open(signed_xpi_filepath, 'rb') as f:
url = release_info['upload_url'].replace('{?name,label}', '?name=' + signed_xpi_filename)
headers = {
'Authorization': github_auth,
'Content-Type': 'application/zip',
}
response = requests.post(url, headers=headers, data=f.read())
if response.status_code != 201:
print('Error: Upload signed package failed -- server error: {0}'.format(response.status_code))
exit(1)
#
# Remove raw package from GitHub
#
# https://developer.github.com/v3/repos/releases/#delete-a-release-asset
print('Remove raw xpi package from GitHub...')
headers = { 'Authorization': github_auth, }
response = requests.delete(raw_xpi_url, headers=headers)
if response.status_code != 204:
print('Error: Deletion of raw package failed -- server error: {0}'.format(response.status_code))
#
# Update updates.json to point to new package -- but only if just-signed
# package is higher version than current one.
#
print('Update GitHub to point to newly signed self-hosted xpi package...')
updates_json_filepath = os.path.join(projdir, 'dist', 'firefox', 'updates.json')
with open(updates_json_filepath) as f:
updates_json = json.load(f)
f.close()
previous_version = updates_json['addons'][extension_id]['updates'][0]['version']
if LooseVersion(ext_version) > LooseVersion(previous_version):
with open(os.path.join(projdir, 'dist', 'firefox', 'updates.template.json')) as f:
template_json = Template(f.read())
f.close()
updates_json = template_json.substitute(ext_version=ext_version, tag_version=tag_version)
with open(updates_json_filepath, 'w') as f:
f.write(updates_json)
f.close()
# Automatically git add/commit if needed.
# - Stage the changed file
r = subprocess.run(['git', 'status', '-s', updates_json_filepath], stdout=subprocess.PIPE)
rout = bytes.decode(r.stdout).strip()
if len(rout) >= 2 and rout[1] == 'M':
subprocess.run(['git', 'add', updates_json_filepath])
# - Commit the staged file
r = subprocess.run(['git', 'status', '-s', updates_json_filepath], stdout=subprocess.PIPE)
rout = bytes.decode(r.stdout).strip()
if len(rout) >= 2 and rout[0] == 'M':
subprocess.run(['git', 'commit', '-m', 'Make Firefox dev build auto-update', updates_json_filepath])
subprocess.run(['git', 'push', 'origin', 'HEAD'])
print('All done.')

@ -1,14 +0,0 @@
{
"addons": {
"nuTensor@geekprojects.com": {
"updates": [
{
"version": "1.4.1.6",
"browser_specific_settings": { "gecko": { "strict_min_version": "56" } },
"update_info_url": "https://github.com/geekprojects/nuTensor/releases/tag/1.4.1b6",
"update_link": "https://github.com/geekprojects/nuTensor/releases/download/1.4.1b6/nuTensor_1.4.1b6.firefox.signed.xpi"
}
]
}
}
}

@ -1,14 +0,0 @@
{
"addons": {
"nuTensor@geekprojects.com": {
"updates": [
{
"version": "$ext_version",
"browser_specific_settings": { "gecko": { "strict_min_version": "56" } },
"update_info_url": "https://github.com/geekprojects/nuTensor/releases/tag/$tag_version",
"update_link": "https://github.com/geekprojects/nuTensor/releases/download/$tag_version/nuTensor_$tag_version.firefox.signed.xpi"
}
]
}
}
}

1
dist/version vendored

@ -1 +0,0 @@
1.5.0.0

@ -1,39 +0,0 @@
## Building nuTensor
### Requirements
Tools:
* bash
* python 3
You will need both this nuTensor and the nuAssets repositories. These should both be placed in the same directory:
```
git clone https://github.com/geekprojects/nuAssets.git
git clone https://github.com/geekprojects/nuTensor.git
cd nuTensor
```
### Packaging
You can now run the scripts that package everything up.
These are bash scripts. They have only been tested on Linux and MacOS.
#### For Firefox
```
tools/make-firefox.sh all
```
#### For Chrome/Chromium (Not yet tested)
```
tools/make-chromium.sh all
```
#### For Opera (Not yet tested)
```
tools/make-opera.sh
```
The installation package should now be found in dist/build/
### Installing
Follow the instructions in [README.md](README.md) to install it.

@ -1,8 +1,8 @@
### This is uMatrix's manifesto
### This is µMatrix's manifesto
1. The **user decides** what web content is acceptable or not in their browser.
That is all.
The purpose of _uMatrix_ is to give the user the means for informed
The purpose of _µMatrix_ is to give the user the means for informed
consent and informed dissent.

@ -2,16 +2,16 @@
#### Chromium
- Download and unzip `nuTensor.chromium.zip` ([latest release desirable](https://github.com/geekprojects/nuTensor/releases)).
- Rename the unzipped directory to `nuTensor`
- When you later update manually, replace the **content** of the `nuTensor` folder with the **content** of the latest zipped version.
- Download and unzip `uMatrix.chromium.zip` ([latest release desirable](https://github.com/gorhill/uMatrix/releases)).
- Rename the unzipped directory to `umatrix`
- When you later update manually, replace the **content** of the `umatrix` folder with the **content** of the latest zipped version.
- This will ensure that all the extension settings will be preserved
- As long as the extension loads **from same folder path from which it was originally installed**, all your settings will be preserved.
- Go to chromium/chrome *Extensions*.
- Click to check *Developer mode*.
- Click *Load unpacked extension...*.
- In the file selector dialog:
- Select the directory `nuTensor` which was created above.
- Select the directory `umatrix` which was created above.
- Click *Open*.
The extension will now be available in your chromium/chromium-based browser.
@ -22,16 +22,16 @@ Remember that you have to update manually also. For some users, updating manuall
#### Firefox
Although nuTensor is a restartless addon, I found that **installing** a newer version over an older one often will glitch the installation. These steps always worked fine:
Although uMatrix is a restartless addon, I found that **installing** a newer version over an older one often will glitch the installation. These steps always worked fine:
- Download `nuTensor.firefox.xpi` ([latest release desirable](https://github.com/geekprojects/nuTensor/releases)).
- Uninstall current nuTensor if already installed
- Download `uMatrix.firefox.xpi` ([latest release desirable](https://github.com/gorhill/uMatrix/releases)).
- Uninstall current uMatrix if already installed
- Quit Firefox completely
- Launch Firefox
- Drag and drop the previously downloaded `nuTensor.firefox.xpi` into Firefox
- Drag and drop the previously downloaded `uMatrix.firefox.xpi` into Firefox
nuTensor settings are kept intact even after you uninstall the addon.
uMatrix settings are kept intact even after you uninstall the addon.
On Linux, the settings are saved in a SQlite file located at `~/.mozilla/firefox/[profile name]/extension-data/nuTensor.sqlite`.
On Linux, the settings are saved in a SQlite file located at `~/.mozilla/firefox/[profile name]/extension-data/umatrix.sqlite`.
On Windows, the settings are saved in a SQlite file located at `%APPDATA%\Mozilla\Firefox\Profiles\[profile name]\extension-data\nuTensor.sqlite`.
On Windows, the settings are saved in a SQlite file located at `%APPDATA%\Mozilla\Firefox\Profiles\[profile name]\extension-data\umatrix.sqlite`.

@ -4,7 +4,9 @@ uMatrix gibt dir volle Kontrolle darüber, womit sich dein Browser verbindet, we
Voreingestellt arbeitet uMatrix in einem gelockerten "blockiere alles/erlaube ausnahmsweise"-Modus, was dazu führt, dass viele Webseiten, die Skripte von Drittseiten benötigen, "kaputt" sein werden. Mit zwei Klicks kannst du aber dafür sorgen, dass uMatrix in einem "erlaube alles/blockiere ausnahmsweise"-Modus arbeitet, der normalerweise Webseiten nicht kaputt macht. Details dazu auf https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views for more details on this topic.
* Sieh ALLE Verbindungen, ob fehlgeschlagen oder erfolgreich, je nachdem ob du sie blockiert oder erlaubt hast (deine Entscheidung).
Die Behauptung: "Chromium-basierte Browser können nicht zuverlässig Javascript blockieren" ist ein reiner Mythos, siehe dazu: https://github.com/gorhill/httpswitchboard/wiki/Blocking-javascript-execution-reliably-in-Chromium-based-browsers. Kurz: Doch, Javascript kann sehr wohl zuverlässig in Chromium blockiert werden.
* Sehe ALLE Verbindungen, ob fehlgeschlagen oder erfolgreich, je nachdem ob du sie blockiert oder erlaubt hast (deine Entscheidung).
* Erlaube/blockiere mit einem Klick eine oder mehrere Arten von Verbindungsanfragen deines Browsers je nach Ziel und Datentyp (eine blockierte Anfrage wird NIE deinen Browser verlassen).
@ -52,6 +54,20 @@ Noch unvollständige Dokumentation: https://github.com/gorhill/uMatrix/wiki
=====
FEEDBACK:
Bei allen Fragen und Problemen bitte auf "Feedback geben" klicken, um mir die Gelegenheit zu einer Antwort zu geben. Ich kann auf Bewertungen nicht direkt antworten, aber ich werde dir sehr gern direkt im Feedback-Bereich Antwort geben.
=====
FEHLER, PROBLEME, VORSCHLÄGE:
https://github.com/gorhill/uMatrix/issues
Du bist sehr willkommen, deine Ansichten zu offenen Problemen, Vorschlägen und Argumenten zu präsentieren, um mir bei der Entscheidung zu helfen, wie ich diese Erweiterung noch besser machen kann.
Leichte Bedienbarkeit ist das vorrangige Ziel. Ich habe Benutzer erlebt, die bei der Firefox-Erweiterung NoScript aufgegeben haben, weil es ihnen zu viele Steine in den Weg legte. Anstatt diese Benutzer wegen ihrer verbesserungswürdigen Sicherheitsgewohnheiten zu kritisieren, kritisiere ich stattdessen die Entwickler. Dieses Projekt ist ein zaghafter Versuch, die Gründe anzugehen, die dazu führen, dass Benutzer bezüglich grundlegender Sicherheitsmaßnahmen aufgeben.
Diese Erweiterung ist auch nützlich, um zu verstehen, was eine Webseite in deinem Browser macht, oft ohne dein Wissen. Du bist voll in der Lage zu sehen und darüber zu entscheiden, mit wem eine Webseite kommuniziert, und diese Kommunikation auf bestimmte Klassen von Objekten zu beschränken.
Die Zahl, die im Symbol der Erweiterung auftaucht, entspricht der Gesamtzahl der einzelnen versuchten Anfragen der Webseite (ob erfolgreich oder nicht, ist abhängig davon, ob du sie erlaubt oder verboten hast).
@ -72,8 +88,6 @@ Diese Erweiterung ist auch nützlich, um das Surfen zu beschleunigen, indem z.B.
=====
FEHLER, PROBLEME: https://github.com/gorhill/uMatrix/issues
QUELLCODE: https://github.com/gorhill/uMatrix (GPLv3)
ÄNDERUNGSPROTOKOLL: https://github.com/gorhill/uMatrix/releases

@ -0,0 +1,93 @@
µMatrix: A point-and-click matrix-based firewall, with many privacy-enhancing tools. For advanced users.
µMatrix put you in full control of where your browser is allowed to connect, what type of data it is allowed to download, and what it is allowed to execute. Nobody else decides for you: You choose. You are in full control of your privacy.
Out of the box, µMatrix works in relax block-all/allow-exceptionally mode, meaning web sites which require 3rd-party scripts are likely to be "broken". With two clicks, µMatrix can be set to work in allow-all/block-exceptionally mode, which generally will not break web sites. See https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views for more details on this topic.
Regarding the myth that "Chromium-based browsers can't reliably block javascript", see: https://github.com/gorhill/httpswitchboard/wiki/Blocking-javascript-execution-reliably-in-Chromium-based-browsers. Summary: Yes, javascript can be blocked reliably in Chromium.
* See ALL the remote connections, failed or attempted, depending on whether they were blocked or allowed (you decide).
* A single-click to whitelist/blacklist one or multiple classes of requests according to the destination and type of data (a blocked request will NEVER leave your browser).
* Efficient blacklisting: cookies won't leave your browser, javascript won't execute, plugins won't play, tracking pixels won't download, etc.
* You do not have to solely rely on just one particular curated blacklist (arguably with many missing entries) outside which nothing else can be blocked: You are in full control.
* Ease of use: µMatrix lets you easily whitelist/blacklist net requests which originate from within a web page according to a point-and-click matrix:
- domain names (left column)
* from very specific
* to very generic
- type of requests (top row)
* cookies
* CSS-related resources (stylesheets and web fonts)
* images
* plugins
* scripts
* XHR (requests made by scripts)
* frames
* others
You can blacklist/whitelist a single cell, an entire row, a group of rows, an entire column, or the whole matrix with just one click.
µMatrix's filtering engine uses precedence logic to evaluate what is blocked/allowed according to which cells are blacklisted/whitelisted. For example, this allows you to whitelist a whole page with one click, without having to repeatedly whitelist whatever new data appear on the page.
All rules are scoped. For example, you can block `facebook.com` and `facebook.net` everywhere except when visiting a page on `www.facebook.com`. This way Facebook won't be able to build a profile of your browsing habits.
The goal of this extension is to make the allowing or blocking of web sites, wholly or partly, as straightforward as possible, so as to encourage users to care about their privacy.
The extension comes with 3rd-party hosts files totaling over 58,000 distinct hostnames (lists can be selectively disabled/enabled according to your choice).
Ultimately, you can choose however you browse the net:
* Blacklist all by default, and whitelist as needed (default mode).
* Whitelist all by default, and blacklist as needed.
Either way, you still benefit from the preset blacklists so that at least you get basic protection from trackers, malware sites, etc. Or you can disable all of these preset blacklists.
Your choice.
Randomly assembled documentation: https://github.com/gorhill/uMatrix/wiki
=====
FEEDBACK:
For any question/issue you might have, use the "Send Feedback" button on the right, in order for me to be able to answer readily. I can't answer directly to reviews, but I will be more than happy to answer you directly in the feedback section.
=====
BUGS, ISSUES, SUGEGSTIONS:
https://github.com/gorhill/uMatrix/issues
You are very welcomed to contribute your views on open issues and suggestions, various arguments for/against help me in deciding what is needed to improve the extension.
Ease of use is the primary goal. I've seen users give up on Firefox's NoScript because it gets too much in the way according to them, so rather than blame these users for poor security habits, I prefer to blame developers and this project is a tentative to address the issues which cause some users to give up on basic security.
This extension is also useful to understand what the web page in your browser is doing, often without your knowledge. You have full ability to see and decide with whom a web page communicates, and to restrict these communications to specific classes of objects within the web page.
The number which appear in the extension icon correspond to the total number of distinct requests attempted (successfully or not depending on whether these were allowed or blocked) by the web page.
Simply click on the appropriate entry in the matrix in order to white-, black- or graylist a component. Graylisting means the blocked or allowed status will be inherited from another cell with higher precedence in the matrix.
Red square = effectively blacklisted, i.e. requests are prevented from reaching their intended destination:
* Dark red square: the domain name and/or type of request is specifically blacklisted.
* Faded red square: the blacklist status is inherited because the entry is graylisted.
Green square = effectively whitelisted, i.e. requests are allowed to reach their intended destination:
* Dark green square: the domain name and/or type of request is specifically whitelisted.
* Faded green square: the whitelist status is inherited because the entry is graylisted.
The top-left cell in the matrix, the "all" cell, represents the default global setting, which allows you to choose whether allowing or blocking everything is the default behavior. Some prefer to allow everything while blocking exceptionally. My personal preference is of course the reverse, blocking everything and allowing exceptionally.
This extension is also useful if you wish to speed up your browsing, by globally blocking all requests for images as an example.
=====
SOURCE CODE: https://github.com/gorhill/uMatrix (GPLv3)
CHANGE LOG: https://github.com/gorhill/uMatrix/releases

@ -0,0 +1,81 @@
uMatrix: A point-and-click matrix-based firewall, with many privacy-enhancing tools. For advanced users.
*For advanced users.*
uMatrix put you in full control of where your browser is allowed to connect, what type of data it is allowed to download, and what it is allowed to execute. Nobody else decides for you: You choose. You are in full control of your privacy.
Out of the box, uMatrix works in relax block-all/allow-exceptionally mode, meaning web sites which require 3rd-party scripts are likely to be "broken". With two clicks, uMatrix can be set to work in allow-all/block-exceptionally mode, which generally will not break web sites. See https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views for more details on this topic.
* See ALL the remote connections, failed or attempted, depending on whether they were blocked or allowed (you decide).
* A single-click to whitelist/blacklist one or multiple classes of requests according to the destination and type of data (a blocked request will NEVER leave your browser).
* Efficient blacklisting: cookies won't leave your browser, javascript won't execute, plugins won't play, tracking pixels won't download, etc.
* You do not have to solely rely on just one particular curated blacklist (arguably with many missing entries) outside which nothing else can be blocked: You are in full control.
* Ease of use: uMatrix lets you easily whitelist/blacklist net requests which originate from within a web page according to a point-and-click matrix:
- domain names (left column)
* from very specific
* to very generic
- type of requests (top row)
* cookies
* CSS-related resources (stylesheets and web fonts)
* images
* plugins
* scripts
* XHR (requests made by scripts)
* frames
* others
You can blacklist/whitelist a single cell, an entire row, a group of rows, an entire column, or the whole matrix with just one click.
uMatrix's filtering engine uses precedence logic to evaluate what is blocked/allowed according to which cells are blacklisted/whitelisted. For example, this allows you to whitelist a whole page with one click, without having to repeatedly whitelist whatever new data appear on the page.
All rules are scoped. For example, you can block `facebook.com` and `facebook.net` everywhere except when visiting a page on `www.facebook.com`. This way Facebook won't be able to build a profile of your browsing habits.
The goal of this extension is to make the allowing or blocking of web sites, wholly or partly, as straightforward as possible, so as to encourage users to care about their privacy.
The extension comes with 3rd-party hosts files totaling over 62,000 distinct hostnames (lists can be selectively disabled/enabled according to your choice).
Ultimately, you can choose however you browse the net:
* Blacklist all by default, and whitelist as needed (default mode).
* Whitelist all by default, and blacklist as needed.
Either way, you still benefit from the preset blacklists so that at least you get basic protection from trackers, malware sites, etc. Or you can disable all of these preset blacklists.
Your choice.
Randomly assembled documentation: https://github.com/gorhill/uMatrix/wiki (it needs work)
=====
This extension is also useful to understand what the web page in your browser is doing, often without your knowledge. You have full ability to see and decide with whom a web page communicates, and to restrict these communications to specific classes of objects within the web page.
The number which appear in the extension icon correspond to the total number of distinct requests attempted (successfully or not depending on whether these were allowed or blocked) by the web page.
Simply click on the appropriate entry in the matrix in order to white-, black- or graylist a component. Graylisting means the blocked or allowed status will be inherited from another cell with higher precedence in the matrix.
Red square = effectively blacklisted, i.e. requests are prevented from reaching their intended destination:
* Dark red square: the domain name and/or type of request is specifically blacklisted.
* Faded red square: the blacklist status is inherited because the entry is graylisted.
Green square = effectively whitelisted, i.e. requests are allowed to reach their intended destination:
* Dark green square: the domain name and/or type of request is specifically whitelisted.
* Faded green square: the whitelist status is inherited because the entry is graylisted.
The top-left cell in the matrix, the "all" cell, represents the default global setting, which allows you to choose whether allowing or blocking everything is the default behavior. Some prefer to allow everything while blocking exceptionally. My personal preference is of course the reverse, blocking everything and allowing exceptionally.
This extension is also useful if you wish to speed up your browsing, by globally blocking all requests for images as an example.
=====
BUGS, ISSUES: https://github.com/gorhill/uMatrix/issues
SOURCE CODE: https://github.com/gorhill/uMatrix (GPLv3)
CHANGE LOG: https://github.com/gorhill/uMatrix/releases

@ -1,12 +1,12 @@
uMatrix: Un cortafuegos matricial ajustable mediante clics, con varias herramientas para mejorar su privacidad.
µMatrix: Un cortafuegos matricial ajustable mediante clics, con varias herramientas para mejorar su privacidad. Para usuarios avanzados.
*Para usuarios avanzados*
µMatrix le proporciona control total sobre su navegador, permitiendo decidir que conexiones se establecen, que tipo de datos se descargan y que códigos se ejecutan. Nadie más decide por usted: Usted escoge. Usted está en control total de su privacidad.
uMatrix le proporciona control total sobre su navegador, permitiéndole decidir que conexiones se establecen, que tipo de datos se descargan y que códigos se ejecutan. Nadie más decide: usted escoge. Usted está en control total de su privacidad.
Por defecto, µMatrix funciona en modo relajado "bloquear todo/permitir excepcionalmente". Esto significa que los sitios que requieren scripts de terceros, posiblemente se muestren con problemas. Con solo dos clics, puede configurar µMatrix para funcionar en modo "permitir todo/bloquear excepcionalmente", lo que hará que usualmente los sitios web se muestren sin problema. Para más detalles sobre el tema consulte https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views (en inglés).
Por defecto, uMatrix funciona en modo relajado "bloquear todo/permitir excepcionalmente". Esto significa que los sitios que requieren scripts de terceros, posiblemente se muestren con problemas. Con solo dos clics, puede configurar uMatrix para funcionar en modo "permitir todo/bloquear excepcionalmente", lo que hará que usualmente los sitios web se muestren sin problema. Para más detalles sobre el tema, consulte https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views (en inglés).
En cuanto al mito de que los navegadores basados en Chromium no pueden bloquear JavaScript de manera adecuada, vea: https://github.com/gorhill/httpswitchboard/wiki/Blocking-javascript-execution-reliably-in-Chromium-based-browsers (en inglés). En resumen: Si, JavaScript puede ser bloqueado de forma segura en Chromium.
* Examine TODAS las conexiones remotas, fallidas o intentadas, según fueron bloqueadas o permitidas (usted decide).
* Examine todas las conexiones remotas, fallidas o intentadas, según fueron bloqueadas o permitidas (usted decide).
* Con un solo clic añada a su lista de permitidos o a su lista negra, uno o varios tipos de peticiones, según el destino y el tipo de datos (una petición bloqueada NUNCA saldrá del navegador).
@ -14,7 +14,7 @@ Por defecto, uMatrix funciona en modo relajado "bloquear todo/permitir excepcion
* No tiene que depender de una sola lista de filtros (probablemente con muchas omisiones) fuera de la cual nada pueda ser bloqueado: usted controla todo.
* Facilidad de uso: uMatrix le permite agregar fácilmente las peticiones de red que se originen desde una página web a una lista de permitidos/lista negra, mediante clics en la matriz:
* Facilidad de uso: µMatrix le permite agregar fácilmente las peticiones de red que se originen desde una página web a una lista de permitidos/lista negra, mediante clics en la matriz:
- nombres de dominio (columna izquierda)
* de muy específico
@ -32,13 +32,13 @@ Por defecto, uMatrix funciona en modo relajado "bloquear todo/permitir excepcion
Puede agregar a la lista negra/lista de permitidos una única celda, una fila completa, un grupo de filas, una columna o toda la matriz, todo con solo un clic.
El motor de filtrado de uMatrix usa lógica de precedencia para evaluar que bloquea o permite, en dependencia de las celdas en lista de permitidos o lista negra. Por ejemplo, puede agregar toda una página a la lista de permitidos con un clic, sin que sea necesario agregar nuevos elementos que puedan aparecer luego en dicha página uno a uno.
El motor de filtrado de µMatrix usa lógica de precedencia para evaluar que bloquea o permite, en dependencia de las celdas en lista de permitidos o lista negra. Por ejemplo, puede agregar toda una página a la lista de permitidos con un clic, sin que sea necesario agregar nuevos elementos que puedan aparecer luego en dicha página uno a uno.
Todas las reglas se definen para un ámbito. Puede, por ejemplo, bloquear elementos de `facebook.com` y `facebook.net` dondequiera, excepto cuando esté navegando en una página en el sitio`www.facebook.com`. De esta forma, Facebook se verá imposibilitado de crear o reunir un perfil sobre sus hábitos de navegación web.
El objetivo de esta extensión es hacer todo el proceso de permitir o bloquear sitios web tan simple como sea posible, de manera tal que los usuarios se sientan alentados a preocuparse por su privacidad.
La extensión hace uso de ficheros hosts mantenidos por terceros, con más de 62,000 nombres de dominios diferentes (las listas pueden ser habilitadas/deshabilitadas según su deseo).
La extensión hace uso de ficheros hosts mantenidos por terceros, con más de 58 000 nombres de dominios diferentes (las listas pueden ser habilitadas/deshabilitadas según su deseo).
Al final, usted decide de que manera navegar por la red:
@ -50,10 +50,24 @@ En cualquier modo, siempre se beneficiará de los filtros ya configurados, que l
Usted elige.
Documentación miscelánea reunida: https://github.com/gorhill/uMatrix/wiki (incompleta)
Documentación miscelánea reunida: https://github.com/gorhill/uMatrix/wiki
=====
OPINIONES:
Para una una pronta respuesta sobre preguntas o problemas que puedan surgir, use la sección de "OPINIONES", a la derecha. No me es posible responder directamente a los comentarios y revisiones en foros, pero estaré más que feliz de darle una respuesta directa en la sección de Opiniones.
=====
ERRORES, PROBLEMAS, SUGERENCIAS:
https://github.com/gorhill/uMatrix/issues
Es bienvenido a contribuir con sus puntos de vista, sugerencias y argumentos a favor o en contra sobre cualquier tema abierto, que me ayuden a decidir que se necesita para hacer esta extensión mejor.
La facilidad de uso es el objetivo primario. He visto a usuarios desistir en el uso de la extensión NoScript para Firefox porque, según ellos, interfiere demasiado. Así que en vez de culpar a los usuarios acerca de sus pobres hábitos en temas relativos a su privacidad, he preferido culpar a los programadores, intentando resolver mediante este proyecto los problemas que hacen que los usuarios cesen de preocuparse sobre aspectos básicos de su seguridad.
Esta extensión también es útil para entender que hace una página web abierta por el navegador, muchas veces sin su conocimiento. Usted será totalmente capaz de decidir con quien se comunica una página web, y restringir dicha comunicación a determinados tipos de objetos dentro de la página.
El número que aparece en el ícono de la extensión se corresponde con el número total de peticiones diferentes hechas por la página web (ya sea que tuvieron éxito o no, de acuerdo a si fueron bloqueadas o permitidas).
@ -74,8 +88,6 @@ Esta extensión también puede ser útil si desea aumentar la velocidad de naveg
=====
ERRORES, PROBLEMAS: https://github.com/gorhill/uMatrix/issues
CÓDIGO FUENTE: https://github.com/gorhill/uMatrix (GPLv3)
REGISTRO DE CAMBIOS: https://github.com/gorhill/uMatrix/releases

@ -1,20 +1,20 @@
uMatrix : Un parefeu matriciel configurable à la volée, avec de nombreux outils d'amélioration de la vie privée en ligne. Pour utilisateurs avancés.
µMatrix : Un parefeu matriciel configurable à la volée, avec de nombreux outils d'amélioration de la vie privée en ligne. Pour utilisateurs avancés.
*Pour utilisateurs avancés*
µMatrix vous donne les pleins pouvoirs sur votre navigateur. Vous contrôlez où il se connecte, ce qu'il télécharge, et ce qu'il exécute. Personne d'autre que vous ne prendra de décisions. Vous avez toutes les cartes en main pour protéger votre confidentialité.
uMatrix vous donne les pleins pouvoirs sur votre navigateur. Vous contrôlez où il se connecte, ce qu'il télécharge, et ce qu'il exécute. Personne d'autre ne décidera pour vous. Vous avez toutes les cartes en main pour protéger votre confidentialité.
Après installation, µMatrix fonctionne en mode "Blocage total/Permissions exceptionnelles", ce qui veut dire que les sites Web ayant besoin de contenus tiers sont susceptibles de ne pas fonctionner correctement. En deux clics, µMatrix peut fonctionner en mode "Autorisation totale/Blocage exceptionnel", qui en principe n'empêchera pas les sites Web de fonctionner. Pour plus d'informations sur ce sujet, consultez cette page en Anglais : https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views .
Après installation, uMatrix fonctionne en mode "Blocage total/Permissions exceptionnelles", ce qui veut dire que les sites Web ayant besoin de contenus tiers sont susceptibles de ne pas fonctionner correctement. En deux clics, uMatrix peut fonctionner en mode "Autorisation totale/Blocage exceptionnel", ce qui en principe n'empêchera pas les sites Web de fonctionner. Pour plus d'informations sur ce sujet, consultez cette page en Anglais : https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views .
En ce qui concerne le mythe disant que "les navigateurs basés sur Chromium ne peuvent bloquer du Javascript en toute fiabilité", consultez cette page en Anglais : https://github.com/gorhill/httpswitchboard/wiki/Blocking-javascript-execution-reliably-in-Chromium-based-browsers . Pour résumer ce qui y est dit : Si, le Javascript peut être bloqué en toute confiance au sein d'un navigateur basé sur Chromium.
* Consultez TOUTES les tentatives de connexions distantes, échouées ou réussies, selon qu'elles soient bloquées ou autorisées (c'est vous qui décidez).
* Consultez TOUTES les tentatives de connexions distantes, échouées ou réussies, selon qu'elles soient bloquées ou autorisées (c'est vous qui le décidez).
* En un clic, vous pouvez mettre en liste blanche/noire une ou plusieurs sorte(s) de requête(s) d'après la destination et le type des données (sachant qu'une requête bloquée ne "partira" JAMAIS de votre navigateur).
* En un clic, vous pouvez mettre en liste blanche/noire une ou plusieurs sorte(s) de requête(s) d'après la destination et le type des données (sachant qu'une requête bloquée ne "s'en ira" JAMAIS de votre navigateur).
* Blocage efficace : Les cookies ne partiront pas de votre navigateur, le code JavaScript ne sera pas exécuté, les plugins ne démarreront pas, les pixels de pistage ne seront pas téléchargés, etc.
* Vous n'avez pas à vous reposer sur une unique liste prédéfinie de blocage (dans laquelle il manquerait beaucoup d'éléments), avec la possibilité de cumuler l'emploi de plusieurs listes de ce genre, vous avez entièrement le contrôle.
* Vous n'avez pas à vous reposer que sur une seule liste prédéfinie de blocage (dans laquelle il manquerait beaucoup d'éléments), en ayant la possibilité de cumuler l'emploi de plusieurs listes de ce genre, vous avez entièrement le contrôle.
* Facilité d'utilisation : uMatrix vous laisse aisément mettre en liste blanche/noire des requêtes réseau provenant d'une page Web, d'après une matrice qui vous permet de manipuler en quelques clics de souris :
* Facilité d'utilisation : µMatrix vous laisse aisément mettre en liste blanche/noire des requêtes réseau provenant d'une page Web, d'après une matrice qui vous permet de manipuler en quelques clics de souris :
- Les noms de domaine (colonne de gauche)
* de très spécifique
@ -32,28 +32,42 @@ Après installation, uMatrix fonctionne en mode "Blocage total/Permissions excep
En un clic, vous pouvez mettre en liste noire/blanche une simple cellule, une ligne entière, un ensemble de lignes, une colonne entière, ou toute la matrice.
Le moteur de filtrage de uMatrix utilise une logique de priorité pour évaluer ce qui doit être bloqué/autorisé d'après l'état des cellules (liste noire/blanche). Par exemple, cela vous permet de mettre en liste blanche toute une page Web en un clic, sans avoir à mettre en liste blanche de manière répétitive toute nouvelle donnée apparaissant sur la page.
Le moteur de filtrage de µMatrix utilise une logique de priorité pour évaluer ce qui doit être bloqué/autorisé d'après l'état des cellules (liste noire/blanche). Par exemple, cela vous permet de mettre en liste blanche toute une page Web en un clic, sans avoir à mettre en liste blanche de manière répétitive toute nouvelle donnée apparaissant sur la page.
Toutes les règles sont contextualisées. Par exemple, vous pouvez bloquer "facebook.com" et "facebook.net" partout sauf lorsque vous visitez une page sur "www.facebook.com". Ainsi Facebook ne pourrait pas définir un profil de vous en se basant sur vos habitudes de navigation.
Le but de cette extension est de rendre l'autorisation/le refus de sites Web, en totalité ou partiellement, aussi direct(e) que possible, pour encourager les utilisateurs à se préoccuper de leur confidentialité.
L'extension fournit des listes prédéfinies de blocage totalisant plus de 62 000 noms de domaine différents, sachant que chacune de ces listes peut être désactivée/activé selon votre choix.
L'extension fournit des listes prédéfinies de blocage totalisant plus de 58 000 noms de domaine différents, sachant que chacune de ces listes peut être désactivée/activé selon votre choix.
Enfin, vous pouvez choisir comment surfer sur le Net :
* Tout mettre en liste noire, et accorder des permissions exceptionnelles si besoin est (il s'agit du mode par défaut).
* Tout mettre en liste blanche, et bloquer si nécessaire.
* Tout mettre en liste blanche, et bloquer exceptionnellement si nécessaire.
De toute manière, vous bénéficierez toujours des listes de règles prédéfinis pour avoir une protection décente contre les pisteurs, les sites Web malveillants, etc. Ou vous pouvez désactiver tout cela.
Encore une fois, c'est votre choix.
Retrouvez ici en langue anglaise de la documentation rassemblée aléatoirement sur l'extension : https://github.com/gorhill/uMatrix/wiki (page en construction).
Retrouvez ici en langue anglaise de la documentation rassemblée aléatoirement sur l'extension : https://github.com/gorhill/uMatrix/wiki .
=====
RETOURS :
Quelque soit le doute/problème rencontré, n'hésitez pas à me contacter. Je ne peux pas répondre directement aux avis des utilisateurs sur Chrome/Opera Web Store, mais je serais ravi de vous répondre directement dans la section adéquate.
=====
PROBLÈMES & SUGGESTIONS :
https://github.com/gorhill/uMatrix/issues .
Vous êtes plus que bienvenus pour rapporter des soucis et des suggestions, divers arguments de type pour ou contre m'aideront à décider ce qu'il faut améliorer dans l'extension.
Le but premier c'est la facilité d'utilisation. J'ai déjà vu des utilisateurs jeter l'éponge au sujet de l'extension NoScript parce qu'elle leur a paru trop contraignante, alors plutôt que de les blâmer pour de piètres habitudes de sécurité, je préfère en vouloir aux développeurs et ce projet est une tentative de rectifier ces erreurs qui ont entrainé l'abandon des bonnes habitudes de sécurité chez certaines personnes.
Cette extension est également utile pour comprendre ce qu'effectue en coulisses une page Web dans votre navigateur. Vous pouvez parfaitement voir et décider avec quoi une page Web communique, et restreindre ces différentes communications.
Le nombre qui apparait sur l'icône de l'extension correspond au nombre total de requêtes distinctes tentées (et réussies ou non selon qu'elles ont été autorisées/refusées) par la page Web.
@ -74,8 +88,6 @@ Cette extension est aussi utile si vous souhaitez accélérer votre navigation,
=====
PROBLÈMES (Page en Anglais) : https://github.com/gorhill/uMatrix/issues
CODE SOURCE (Licence GPLv3, page en Anglais) : https://github.com/gorhill/uMatrix .
JOURNAL DES CHANGEMENTS (Page en Anglais) : https://github.com/gorhill/umatrix/releases .

@ -1,81 +1,93 @@
uMatrix格子状のマトリクスで管理するファイヤウォール。様々なプライバシー強化ツールを兼ね備えます。
µMatrix: A point-and-click matrix-based firewall, with many privacy-enhancing tools. For advanced users.
* 上級ユーザー向けです *
µMatrix put you in full control of where your browser is allowed to connect, what type of data it is allowed to download, and what it is allowed to execute. Nobody else decides for you: You choose. You are in full control of your privacy.
uMatrix を使うと、ブラウザーがどこと通信して良いのか、どの種類のデータをダウンロードするのか、何を実行して良いのかを決定することができます。誰か他の人があなたの代わりに決めてくれることはありません。自分のプライバシーを自分で制御するのです。
Out of the box, µMatrix works in relax block-all/allow-exceptionally mode, meaning web sites which require 3rd-party scripts are likely to be "broken". With two clicks, µMatrix can be set to work in allow-all/block-exceptionally mode, which generally will not break web sites. See https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views for more details on this topic.
初期設定では、uMatrix は安心できる「すべてブロック・必要なら許可」の設定になっています。つまり、サードパーティーのスクリプトを必要とするウェブサイトは“壊れる”ことが多いでしょう。2クリックで、「すべて許可・必要ならブロック」の設定に変えることもでき、この場合、ウェブサイトを壊すことはほとんどありません。より詳しくは https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views を見て下さい。
Regarding the myth that "Chromium-based browsers can't reliably block javascript", see: https://github.com/gorhill/httpswitchboard/wiki/Blocking-javascript-execution-reliably-in-Chromium-based-browsers. Summary: Yes, javascript can be blocked reliably in Chromium.
* あなたが選んだブロック/許可の結果による“すべての”リクエストの失敗/実施の状況を確認できます。
* See ALL the remote connections, failed or attempted, depending on whether they were blocked or allowed (you decide).
* ワンクリックで、接続先やデータの種類に応じてリクエストを許可/ブロックすることができます。ブロックされたリクエストがブラウザーから外に出ることは決してありません。
* A single-click to whitelist/blacklist one or multiple classes of requests according to the destination and type of data (a blocked request will NEVER leave your browser).
* 効率的なブラックリストCookie はブラウザーの外には出ず、JavaScript もプラグインも実行されず、追跡ピクセルがダウンロードされることもありません。
* Efficient blacklisting: cookies won't leave your browser, javascript won't execute, plugins won't play, tracking pixels won't download, etc.
* リストにないとブロックしてくれない(そして多くの漏れがあるであろう)ブラックリストだけに頼る必要はありません。自分で制御できるのです。
* You do not have to solely rely on just one particular curated blacklist (arguably with many missing entries) outside which nothing else can be blocked: You are in full control.
* 使い勝手の良さuMatrix では、ウェブページが発したリクエストを、マトリクスをクリックすることで簡単に許可/ブロックすることができます。
* Ease of use: µMatrix lets you easily whitelist/blacklist net requests which originate from within a web page according to a point-and-click matrix:
- ドメイン名(左の列)
* 具体的なドメインから
* 汎用的なドメインまで 選ぶことができます
- domain names (left column)
* from very specific
* to very generic
- リクエストの種類(先頭の行)
* Cookie
* CSS 関連のリソース(スタイルシートと Web フォント)
* 画像
* メディア
* スクリプト
* XHR(スクリプトにより生成されるリクエスト)
* フレーム
* その他
- type of requests (top row)
* cookies
* CSS-related resources (stylesheets and web fonts)
* images
* plugins
* scripts
* XHR (requests made by scripts)
* frames
* others
ワンクリックで、特定のセル、特定のドメイン、グループ化されたドメイン、特定のリクエストの種類、そしてマトリクス全体を許可/ブロックできます。
You can blacklist/whitelist a single cell, an entire row, a group of rows, an entire column, or the whole matrix with just one click.
uMatrix のフィルタリングエンジンは、どのセルが許可/ブロックされているかによって、優先順位に基づくロジックでリクエストを処理します。これにより、例えば、あるページ全体をワンクリックで許可しておけば、このページに新しいリクエストが見つかるたびに許可を追加する必要がなくなります。
µMatrix's filtering engine uses precedence logic to evaluate what is blocked/allowed according to which cells are blacklisted/whitelisted. For example, this allows you to whitelist a whole page with one click, without having to repeatedly whitelist whatever new data appear on the page.
それぞれのルールには有効範囲があります。例えば、www.facebook.com にアクセスしていない時だけ facebook.com と facebook.net をブロックすることができます。これにより、Facebook が、あなたのブラウジング習慣からあなたの人物像を作成することを防ぎます。
All rules are scoped. For example, you can block `facebook.com` and `facebook.net` everywhere except when visiting a page on `www.facebook.com`. This way Facebook won't be able to build a profile of your browsing habits.
この拡張機能の最終目標は、ユーザーが自身のプライバシーに気を配れるよう、可能な限り簡潔に、ウェブサイトを包括的あるいは部分的に許可/ブロックできるようにすることです。
The goal of this extension is to make the allowing or blocking of web sites, wholly or partly, as straightforward as possible, so as to encourage users to care about their privacy.
この拡張機能には、合計 62,000 件以上のホスト名からなるサードパーティーのホストファイルが含まれます。これらのファイルは好みに応じてオンオフすることができます。
The extension comes with 3rd-party hosts files totaling over 58,000 distinct hostnames (lists can be selectively disabled/enabled according to your choice).
まとめると、あなたはネットをブラウジングする方法を次のように選ぶことができます。
Ultimately, you can choose however you browse the net:
* はじめはすべてブロック、必要に応じて許可していく(初期設定)
* Blacklist all by default, and whitelist as needed (default mode).
* はじめはすべて許可、必要に応じてブロックしていく
* Whitelist all by default, and blacklist as needed.
どちらの方法でも、組み込みのホストファイルのおかげで、トラッカーやマルウェアサイトなどに対する基礎的な保護を得ることができます。もしくはこれらをすべて無効にすることもできます。
Either way, you still benefit from the preset blacklists so that at least you get basic protection from trackers, malware sites, etc. Or you can disable all of these preset blacklists.
決めるのはあなたです。
Your choice.
ドキュメント: https://github.com/gorhill/uMatrix/wiki
Randomly assembled documentation: https://github.com/gorhill/uMatrix/wiki
=====
この拡張機能のもう一つの使い道は、知識なしでも、ブラウザーの中でウェブページが何をしているか理解することです。あなたはウェブページがどこと通信するのかをすべて見た上で決断し、ウェブページ中の特定の種類の通信を制限できます。
FEEDBACK:
拡張機能アイコンに表示される数値は、ウェブページによっていくつのリクエストが試みられたかの総数(許可/ブロック合わせて)を示します。
For any question/issue you might have, use the "Send Feedback" button on the right, in order for me to be able to answer readily. I can't answer directly to reviews, but I will be more than happy to answer you directly in the feedback section.
マトリクスの適切なセルをクリックして、許可/ブロック/グレーのいずれにするかを決めます。“グレー”では、マトリクス内のより優先度の高いセルからブロック/許可の状態を引き継ぎます。
=====
赤いセル は事実上ブロックされている状態であり、リクエストは接続先に届きません。
* 濃い赤:そのドメイン名とリクエスト種類の組み合わせは、明示的にブロックされています。
* 淡い赤:セルが“グレー”状態のため、ブロック状態が引き継がれました。
BUGS, ISSUES, SUGEGSTIONS:
緑のセル は事実上許可されている状態であり、リクエストは接続先に届きます。
* 濃い緑:そのドメイン名とリクエスト種類の組み合わせは、明示的に許可されています。
* 淡い緑:セルが“グレー”状態のため、許可が引き継がれました。
https://github.com/gorhill/uMatrix/issues
マトリクスの一番左上にある「すべて」のセルはデフォルトのグローバル設定を示し、「すべてを許可」と「すべてをブロック」のどちらをデフォルトにするかを選ぶことができます。人によっては、すべてを許可した上で必要に応じてブロックすることを好むでしょう。私の個人的な設定はもちろんその逆、すべてをブロックした上で必要なものを許可します。
You are very welcomed to contribute your views on open issues and suggestions, various arguments for/against help me in deciding what is needed to improve the extension.
この拡張機能は、例えば画像の読み込みをすべてブロックすることで、ブラウジングスピードを上げるのにも役立ちます。
Ease of use is the primary goal. I've seen users give up on Firefox's NoScript because it gets too much in the way according to them, so rather than blame these users for poor security habits, I prefer to blame developers and this project is a tentative to address the issues which cause some users to give up on basic security.
=====
This extension is also useful to understand what the web page in your browser is doing, often without your knowledge. You have full ability to see and decide with whom a web page communicates, and to restrict these communications to specific classes of objects within the web page.
The number which appear in the extension icon correspond to the total number of distinct requests attempted (successfully or not depending on whether these were allowed or blocked) by the web page.
Simply click on the appropriate entry in the matrix in order to white-, black- or graylist a component. Graylisting means the blocked or allowed status will be inherited from another cell with higher precedence in the matrix.
Red square = effectively blacklisted, i.e. requests are prevented from reaching their intended destination:
* Dark red square: the domain name and/or type of request is specifically blacklisted.
* Faded red square: the blacklist status is inherited because the entry is graylisted.
バグ・問題報告: https://github.com/gorhill/uMatrix/issues
Green square = effectively whitelisted, i.e. requests are allowed to reach their intended destination:
* Dark green square: the domain name and/or type of request is specifically whitelisted.
* Faded green square: the whitelist status is inherited because the entry is graylisted.
The top-left cell in the matrix, the "all" cell, represents the default global setting, which allows you to choose whether allowing or blocking everything is the default behavior. Some prefer to allow everything while blocking exceptionally. My personal preference is of course the reverse, blocking everything and allowing exceptionally.
This extension is also useful if you wish to speed up your browsing, by globally blocking all requests for images as an example.
=====
ソースコード: https://github.com/gorhill/uMatrix (GPLv3)
SOURCE CODE: https://github.com/gorhill/uMatrix (GPLv3)
更新履歴: https://github.com/gorhill/uMatrix/releases
CHANGE LOG: https://github.com/gorhill/uMatrix/releases

@ -1,81 +1,93 @@
uMatrix: een contextafhankelijke en matrix-gebaseerde firewall, met vele functies ter verbetering van uw privacy.
µMatrix: A point-and-click matrix-based firewall, with many privacy-enhancing tools. For advanced users.
*Voor gevorderde gebruikers.*
µMatrix put you in full control of where your browser is allowed to connect, what type of data it is allowed to download, and what it is allowed to execute. Nobody else decides for you: You choose. You are in full control of your privacy.
uMatrix geeft volledige controle over welke verbindingen uw browser mag maken, welk type gegevens de browser mag downloaden, en wat erin mag worden uitgevoerd. Niemand anders beslist het: het is uw keuze. U hebt de volledige controle over uw privacy.
Out of the box, µMatrix works in relax block-all/allow-exceptionally mode, meaning web sites which require 3rd-party scripts are likely to be "broken". With two clicks, µMatrix can be set to work in allow-all/block-exceptionally mode, which generally will not break web sites. See https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views for more details on this topic.
Direct na installatie werkt uMatrix in de modus alles-blokkeren/bij-uitzondering-blokkeren, wat inhoudt dat websites die scripts van derden nodig hebben waarschijnlijk niet goed worden weergegeven. Met twee muisklikken kan uMatrix worden ingesteld om in de modus alles-toestaan/bij-uitzondering-blokkeren te werken, waarmee websites doorgaans wel goed worden weergegeven. Zie https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views voor meer details over dit onderwerp.
Regarding the myth that "Chromium-based browsers can't reliably block javascript", see: https://github.com/gorhill/httpswitchboard/wiki/Blocking-javascript-execution-reliably-in-Chromium-based-browsers. Summary: Yes, javascript can be blocked reliably in Chromium.
* Bekijk ALLE externe verbindingen, mislukte of gepoogde, afhankelijk van of deze werden geblokkeerd of toegestaan (u beslist).
* See ALL the remote connections, failed or attempted, depending on whether they were blocked or allowed (you decide).
* Eén muisklik voor het whitelisten/blacklisten van een of meer aanvraagklassen volgens de bestemming en het type gegevens (een geblokkeerde aanvraag zal uw browser NOOIT verlaten).
* A single-click to whitelist/blacklist one or multiple classes of requests according to the destination and type of data (a blocked request will NEVER leave your browser).
* Efficiënt blacklisten: cookies verlaten uw browser niet, JavaScript wordt niet uitgevoerd, plug-ins worden niet afgespeeld, trackingpixels worden niet gedownload, etc.
* Efficient blacklisting: cookies won't leave your browser, javascript won't execute, plugins won't play, tracking pixels won't download, etc.
* U hoeft niet slechts op één bepaalde beheerde blacklist (betwistbaar met veel ontbrekende vermeldingen) te vertrouwen waarbuiten niets anders kan worden geblokkeerd: u hebt de volledige controle.
* You do not have to solely rely on just one particular curated blacklist (arguably with many missing entries) outside which nothing else can be blocked: You are in full control.
* Gebruikersgemak: met uMatrix kunt u eenvoudig netwerkaanvragen die van een webpagina afkomstig zijn whitelisten/blacklisten, volgens een matrix via aanwijzen en klikken:
* Ease of use: µMatrix lets you easily whitelist/blacklist net requests which originate from within a web page according to a point-and-click matrix:
- domeinnamen (linkerkolom)
* van zeer specifieke
* tot zeer algemene
- domain names (left column)
* from very specific
* to very generic
- type aanvragen (bovenste rij)
- type of requests (top row)
* cookies
* CSS-gerelateerde bronnen (stijlbladen en weblettertypen)
* afbeeldingen
* plug-ins
* CSS-related resources (stylesheets and web fonts)
* images
* plugins
* scripts
* XHR (aanvragen door scripts)
* XHR (requests made by scripts)
* frames
* overig
* others
Met slechts één klik kunt u een enkele cel, een hele rij, een groep rijen, een hele kolom, of de hele matrix blacklisten/whitelisten.
You can blacklist/whitelist a single cell, an entire row, a group of rows, an entire column, or the whole matrix with just one click.
De filterengine van uMatrix gebruikt voorrangslogica voor het evalueren van wat er volgens de cellen die zijn geblacklist/gewhitelist is geblokkeerd/toegestaan. Hierdoor kunt u bijvoorbeeld met één klik een hele pagina whitelisten, zonder dat u dat herhaaldelijk moet doen bij nieuwe gegevens die op de pagina verschijnen.
µMatrix's filtering engine uses precedence logic to evaluate what is blocked/allowed according to which cells are blacklisted/whitelisted. For example, this allows you to whitelist a whole page with one click, without having to repeatedly whitelist whatever new data appear on the page.
Alle regels worden aan een bereik gerelateerd. U kunt bijvoorbeeld facebook.com en facebook.net overal blokkeren, behalve wanneer u een pagina op www.facebook.com bezoekt. Op deze manier zal Facebook geen profiel van uw surfgedrag kunnen opbouwen.
All rules are scoped. For example, you can block `facebook.com` and `facebook.net` everywhere except when visiting a page on `www.facebook.com`. This way Facebook won't be able to build a profile of your browsing habits.
Het doel van deze extensie is om het toestaan of blokkeren van websites, geheel of gedeeltelijk, zo overzichtelijk mogelijk te maken en daarmee gebruikers aan te moedigen om op hun privacy te letten.
The goal of this extension is to make the allowing or blocking of web sites, wholly or partly, as straightforward as possible, so as to encourage users to care about their privacy.
Standaard bevat de extensie hosts-bestanden van derden met meer dan 62.000 afzonderlijke hostnamen (lijsten kunnen naar keuze selectief worden in- en uitgeschakeld).
The extension comes with 3rd-party hosts files totaling over 58,000 distinct hostnames (lists can be selectively disabled/enabled according to your choice).
Uiteindelijk kunt u kiezen hoe u op het internet wilt surfen:
Ultimately, you can choose however you browse the net:
* Alles standaard blacklisten, en whitelisten wanneer nodig (standaardmodus).
* Blacklist all by default, and whitelist as needed (default mode).
* Alles standaard whitelisten, en blacklisten wanneer nodig.
* Whitelist all by default, and blacklist as needed.
In beide gevallen heb u voordeel van de vooraf geleverde blacklists, zodat u op zijn minst basisbescherming krijgt tegen trackers, malwaresites, etc. U kunt al deze vooraf geleverde blacklists ook uitschakelen.
Either way, you still benefit from the preset blacklists so that at least you get basic protection from trackers, malware sites, etc. Or you can disable all of these preset blacklists.
Uw keuze.
Your choice.
Willekeurig samengestelde documentatie: https://github.com/gorhill/uMatrix/wiki
Randomly assembled documentation: https://github.com/gorhill/uMatrix/wiki
=====
Deze extensie is ook bruikbaar om te begrijpen wat de webpagina in uw browser doet, vaak zonder uw medeweten. U hebt de volledige mogelijkheid om te zien en te beslissen waarmee een webpagina communiceert, en deze communicatie tot bepaalde objectklassen binnen dezelfde pagina te beperken.
FEEDBACK:
Het getal dat in het pictogram van de extensie verschijnt, komt overeen met het totale aantal afzonderlijke geprobeerde aanvragen (geslaagd of niet, afhankelijk van of deze werden toegestaan of geblokkeerd) door de webpagina.
For any question/issue you might have, use the "Send Feedback" button on the right, in order for me to be able to answer readily. I can't answer directly to reviews, but I will be more than happy to answer you directly in the feedback section.
Klik eenvoudig op de juiste vermelding in de matrix om een onderdeel te white-, black- of graylisten. Graylisten houdt in dat de status geblokkeerd of toegestaan van een andere cel met hogere voorrang in de matrix wordt overgenomen.
=====
Rood vierkant = effectief geblacklist, m.a.w. aanvragen richting hun bedoelde eindbestemming worden voorkomen:
* Donkerrood vierkant: de domeinnaam en/of het type aanvraag is specifiek geblacklist.
* Vaalrood vierkant: de blacklist-status is overgenomen, omdat de vermelding is gegraylist.
BUGS, ISSUES, SUGEGSTIONS:
Groen vierkant = effectief gewhitelist, m.a.w. aanvragen mogen hun bedoelde eindbestemming bereiken:
* Donkergroen vierkant: de domeinnaam en/of het type aanvraag is specifiek gewhitelist.
* Vaalgroen vierkant: de whitelist-status is overgenomen, omdat de vermelding is gegraylist.
https://github.com/gorhill/uMatrix/issues
De cel in de linkerbovenhoek van de matrix, de cel alle, vertegenwoordigt de algemene standaardinstelling waarmee u kunt kiezen of alles toestaan of blokkeren het standaardgedrag is. Sommige gebruikers geven de voorkeur aan alles toestaan en bij uitzondering blokkeren. Mijn persoonlijke voorkeur is natuurlijk het omgekeerde, alles blokkeren en bij uitzondering toestaan.
You are very welcomed to contribute your views on open issues and suggestions, various arguments for/against help me in deciding what is needed to improve the extension.
Deze extensie is ook nuttig als u het browsen wilt versnellen, bijvoorbeeld door alle aanvragen voor afbeeldingen overal te blokkeren.
Ease of use is the primary goal. I've seen users give up on Firefox's NoScript because it gets too much in the way according to them, so rather than blame these users for poor security habits, I prefer to blame developers and this project is a tentative to address the issues which cause some users to give up on basic security.
=====
This extension is also useful to understand what the web page in your browser is doing, often without your knowledge. You have full ability to see and decide with whom a web page communicates, and to restrict these communications to specific classes of objects within the web page.
The number which appear in the extension icon correspond to the total number of distinct requests attempted (successfully or not depending on whether these were allowed or blocked) by the web page.
Simply click on the appropriate entry in the matrix in order to white-, black- or graylist a component. Graylisting means the blocked or allowed status will be inherited from another cell with higher precedence in the matrix.
Red square = effectively blacklisted, i.e. requests are prevented from reaching their intended destination:
* Dark red square: the domain name and/or type of request is specifically blacklisted.
* Faded red square: the blacklist status is inherited because the entry is graylisted.
BUGS, PROBLEMEN: https://github.com/gorhill/uMatrix/issues
Green square = effectively whitelisted, i.e. requests are allowed to reach their intended destination:
* Dark green square: the domain name and/or type of request is specifically whitelisted.
* Faded green square: the whitelist status is inherited because the entry is graylisted.
The top-left cell in the matrix, the "all" cell, represents the default global setting, which allows you to choose whether allowing or blocking everything is the default behavior. Some prefer to allow everything while blocking exceptionally. My personal preference is of course the reverse, blocking everything and allowing exceptionally.
This extension is also useful if you wish to speed up your browsing, by globally blocking all requests for images as an example.
=====
BRONCODE: https://github.com/gorhill/uMatrix (GPLv3)
SOURCE CODE: https://github.com/gorhill/uMatrix (GPLv3)
CHANGELOG: https://github.com/gorhill/uMatrix/releases
CHANGE LOG: https://github.com/gorhill/uMatrix/releases

@ -1,10 +1,10 @@
uMatrix: Matris tabanlı işaret et ve tıkla güvenlik duvarıdır, birçok gizlilik arttırıcı aracıyla birlikte gelir.
µMatrix: Matris tabanlı işaret et ve tıkla güvenlik duvarıdır, birçok gizlilik arttırıcı aracıyla birlikte gelir. İleri düzey kullanıcılar için.
*İleri düzey kullanıcılar için.*
µMatrix tarayıcınızın nereye bağlanabileceği, ne tür veri indirebileceği ve yürütebileceği konusunda tam denetimi size verir. Kimse sizin yerinize karar vermez: Siz seçersiniz. Gizliliğinizin tam denetimi sizdedir.
uMatrix tarayıcınızın nereye bağlanabileceği, ne tür veri indirebileceği ve yürütebileceği konusunda tam denetimi size verir. Kimse sizin yerinize karar vermez: Siz seçersiniz. Gizliliğinizin tam denetimi sizdedir.
µMatrix tümünü engelle/istisnalara izin ver modunda çalışır, bunun anlamı 3. taraf betiklere ihtiyaç duyan web sitelerinin muhtemelen "bozuk" olabileceğidir. İki tıklama ile µMatrix genelde siteleri bozmayacak tümüne izin ver/istisnaları engelle moduna ayarlanabilir. Bu konu hakkında daha ayrıntılı bilgi almak için https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views bağlantısına bakın.
uMatrix tümünü engelle/istisnalara izin ver modunda çalışır, bunun anlamı 3. taraf betiklere ihtiyaç duyan web sitelerinin muhtemelen "bozuk" olabileceğidir. İki tıklama ile uMatrix genelde siteleri bozmayacak tümüne izin ver/istisnaları engelle moduna ayarlanabilir. Bu konu hakkında daha ayrıntılı bilgi almak için https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views bağlantısına bakın.
"Chromium-tabanlı tarayıcılarda güvenilir biçimde JavaScript'ler engellenemez" efsanesiyle ilgili olarak, bakınız: https://github.com/gorhill/httpswitchboard/wiki/Blocking-javascript-execution-reliably-in-Chromium-based-browsers. Sonuç: Evet, JavaScript güvenilir biçimde Chromium'da engellenebilir.
* Engellendiğine veya izin verildiğine (sizin seçiminiz) bağlı olarak başarısız veya denenmiş TÜM uzak bağlantıları görün.
@ -14,7 +14,7 @@ uMatrix tümünü engelle/istisnalara izin ver modunda çalışır, bunun anlam
* Belirli kara listelere bağlı (birçok eksiği bulunan) kalmak zorunda değilsiniz: Tüm denetim sizde.
* Kullanımı kolay: uMatrix işaret et ve tıkla matrisiyle bir web sitesinden kaynaklanan istekleri kolaylıkla beyaz/kara listeye almanızı sağlar:
* Kullanımı kolay: µMatrix işaret et ve tıkla matrisiyle bir web sitesinden kaynaklanan istekleri kolaylıkla beyaz/kara listeye almanızı sağlar:
- alan adları (sol sütun)
* özelden
@ -32,13 +32,13 @@ uMatrix tümünü engelle/istisnalara izin ver modunda çalışır, bunun anlam
Tek hücreyi, tüm satırı, satır gruplarını, tüm sütunu veya tüm matrisi bir tek tıklama ile kara/beyaz listeye alabilirsiniz.
uMatrix'in süzgeç motoru hangi hücrelerin kara/beyaz listede bulunduğuna göre öncelik mantığını kullanarak nelerin engelleneceğine veya nelere izin verileceğine karar verir. Örneğin, bu şekilde sayfada beliren yeni veri türlerine sürekli izin vermenize gerek kalmadan tüm sayfayı beyaz listeye almanıza izin verir.
µMatrix'in süzgeç motoru hangi hücrelerin kara/beyaz listede bulunduğuna göre öncelik mantığını kullanarak nelerin engelleneceğine veya nelere izin verileceğine karar verir. Örneğin, bu şekilde sayfada beliren yeni veri türlerine sürekli izin vermenize gerek kalmadan tüm sayfayı beyaz listeye almanıza izin verir.
Tüm kurallar kapsamlıdır. Örneğin, `facebook.com` ve `facebook.net` sitelerini `www.facebook.com`dışındaki sitelerde engelleyebilirsiniz. Bu şekilde Facebook gezinti alışkanlıklarınızla ilgili profil oluşturamayacaktır.
Bu eklentinin en basit olarak amacı web sitelerine izin vererek veya engelleyerek, tümden veya kısmi olarak, kullanıcıların kendi gizliliklerine dikkat etmelerini teşvik etmektir.
Bu eklenti 3. taraf alan dosyalarıyla toplamda 62.000'nin üzerinde farklı alan adıyla birlikte gelir (listeler seçime bağlı olarak etkinleştirilebilir veya devre dışı bırakılabilir).
Bu eklenti 3. taraf alan dosyalarıyla toplamda 58.000'nin üzerinde farklı alan adıyla birlikte gelir (listeler seçiminize bağlı olarak etkinleştirilebilir veya devre dışı bırakılabilir).
Sonuçta, internette nasıl gezmek istediğinizi seçebilirsiniz:
@ -50,10 +50,24 @@ Her halükarda, önceden ayarlanmış kara listelerden faydalanarak izleyiciler,
Sizin seçiminiz.
Rastgele toplanmış belgeler: https://github.com/gorhill/uMatrix/wiki (çalışma gerektiriyor)
Rastgele toplanmış belgeler: https://github.com/gorhill/uMatrix/wiki
=====
GERİ BİLDİRİM:
Herhangi bir sorunuz veya sorununuz varsa çabucak cevap verebilmem için sağdaki "Geri Bildirim Gönder" düğmesini kullanın. Yorumlara doğrudan cevap veremiyorum fakat geri bildirim bölümünden seve seve cevap vereceğim.
=====
HATALAR, SORUNLAR, ÖNERİLER:
https://github.com/gorhill/uMatrix/issues
Eklentiyi geliştirmek için açık sorunlara ve önerilere, karar vermem için çeşitli argümanlar üzerine görüşlerinizi bekliyorum.
Kullanım kolaylığı birincil hedeftir. Firefox'un NoScript eklentisi çok uğraş gerektirdiği için bu eklentiyi kullanmaktan vazgeçen kullanıcılar gördüm. Bu kullanıcıları zayıf güvenlik alışkanlıkları olduğu için suçlamak yerine, bu sorunları çözmedikleri için geliştiricileri suçlamayı yeğelerim. Bu proje bazı kullanıcıların temel güvenliklerinden vazgeçmeleri sorununu deneme düzeyinde çözmeyi amaçlar.
Ayrıca bu eklenti bir web sayfasının bilginiz dışında tarayıcınızda ne yapmaya çalıştığını anlamanıza yardımcı olur. Web sayfasının neyle iletişim kurduğunu görmenizi ve web sayfasında kurulan bu iletişimin belirli öğe sınıflarına kısıtlanması üzerine karar vermenizi sağlar.
Eklenti simgesinde görünen sayı web sitesi tarafından girişimde bulunulmuş farklı istek sayısının toplamıdır (izin verilip verilmediğine göre başarılı veya değil).
@ -74,8 +88,6 @@ Bu eklenti ayrıca gezinti hızınızı da arttırmak istiyorsanız kullanışl
=====
HATALAR, SORUNLAR: https://github.com/gorhill/uMatrix/issues
KAYNAK KODU: https://github.com/gorhill/uMatrix (GPLv3)
DEĞİŞİM GÜNLÜĞÜ: https://github.com/gorhill/uMatrix/releases

@ -1,20 +1,20 @@
uMatrix: A point-and-click matrix-based firewall, with many privacy-enhancing tools.
µMatrix: A point-and-click matrix-based firewall, with many privacy-enhancing tools. For advanced users.
*For advanced users.*
µMatrix put you in full control of where your browser is allowed to connect, what type of data it is allowed to download, and what it is allowed to execute. Nobody else decides for you: You choose. You are in full control of your privacy.
uMatrix put you in full control of where your browser is allowed to connect, what type of data it is allowed to download, and what it is allowed to execute. Nobody else decides for you: You choose. You are in full control of your privacy.
Out of the box, µMatrix works in relax block-all/allow-exceptionally mode, meaning web sites which require 3rd-party scripts are likely to be "broken". With two clicks, µMatrix can be set to work in allow-all/block-exceptionally mode, which generally will not break web sites. See https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views for more details on this topic.
Out of the box, uMatrix works in relax block-all/allow-exceptionally mode, meaning web sites which require 3rd-party scripts are likely to be "broken". With two clicks, uMatrix can be set to work in allow-all/block-exceptionally mode, which generally will not break web sites. See https://github.com/gorhill/httpswitchboard/wiki/How-to-use-HTTP-Switchboard:-Two-opposing-views for more details on this topic.
Regarding the myth that "Chromium-based browsers can't reliably block JavaScript", see: https://github.com/gorhill/httpswitchboard/wiki/Blocking-javascript-execution-reliably-in-Chromium-based-browsers. Summary: Yes, JavaScript can be blocked reliably in Chromium.
* See ALL the remote connections, failed or attempted, depending on whether they were blocked or allowed (you decide).
* A single-click to whitelist/blacklist one or multiple classes of requests according to the destination and type of data (a blocked request will NEVER leave your browser).
* Efficient blacklisting: cookies won't leave your browser, JavaScript won't execute, media won't play, tracking pixels won't download, etc.
* Efficient blacklisting: cookies won't leave your browser, JavaScript won't execute, plugins won't play, tracking pixels won't download, etc.
* You do not have to solely rely on just one particular curated blacklist (arguably with many missing entries) outside which nothing else can be blocked: You are in full control.
* Ease of use: uMatrix lets you easily whitelist/blacklist net requests which originate from within a web page according to a point-and-click matrix:
* Ease of use: µMatrix lets you easily whitelist/blacklist net requests which originate from within a web page according to a point-and-click matrix:
- domain names (left column)
* from very specific
@ -22,23 +22,23 @@ Out of the box, uMatrix works in relax block-all/allow-exceptionally mode, meani
- type of requests (top row)
* cookies
* css (stylesheets and web fonts)
* CSS-related resources (stylesheets and web fonts)
* images
* media
* plugins
* scripts
* xhr (requests made by scripts)
* XHR (requests made by scripts)
* frames
* others
You can blacklist/whitelist a single cell, an entire row, a group of rows, an entire column, or the whole matrix with just one click.
uMatrix's filtering engine uses precedence logic to evaluate what is blocked/allowed according to which cells are blacklisted/whitelisted. For example, this allows you to whitelist a whole page with one click, without having to repeatedly whitelist whatever new data appear on the page.
µMatrix's filtering engine uses precedence logic to evaluate what is blocked/allowed according to which cells are blacklisted/whitelisted. For example, this allows you to whitelist a whole page with one click, without having to repeatedly whitelist whatever new data appear on the page.
All rules are scoped. For example, you can block `facebook.com` and `facebook.net` everywhere except when visiting a page on `www.facebook.com`. This way Facebook won't be able to build a profile of your browsing habits.
The goal of this extension is to make the allowing or blocking of web sites, wholly or partly, as straightforward as possible, so as to encourage users to care about their privacy.
The extension comes with 3rd-party hosts files totaling over 62,000 distinct hostnames (lists can be selectively disabled/enabled according to your choice).
The extension comes with 3rd-party hosts files totaling over 58,000 distinct hostnames (lists can be selectively disabled/enabled according to your choice).
Ultimately, you can choose however you browse the net:
@ -54,9 +54,23 @@ Randomly assembled documentation: https://github.com/gorhill/uMatrix/wiki
=====
FEEDBACK:
For any question/issue you might have, use the "Send Feedback" button on the right, in order for me to be able to answer readily. I can't answer directly to reviews, but I will be more than happy to answer you directly in the feedback section.
=====
BUGS, ISSUES, SUGGESTIONS:
https://github.com/gorhill/uMatrix/issues
You are very welcomed to contribute your views on open issues and suggestions, various arguments for/against help me in deciding what is needed to improve the extension.
Ease of use is the primary goal. I've seen users give up on Firefox's NoScript because it gets too much in the way according to them, so rather than blame these users for poor security habits, I prefer to blame developers and this project is a tentative to address the issues which cause some users to give up on basic security.
This extension is also useful to understand what the web page in your browser is doing, often without your knowledge. You have full ability to see and decide with whom a web page communicates, and to restrict these communications to specific classes of objects within the web page.
The number which appears in the extension icon correspond to the total number of distinct requests blocked by the extension.
The number which appear in the extension icon correspond to the total number of distinct requests attempted (successfully or not depending on whether these were allowed or blocked) by the web page.
Simply click on the appropriate entry in the matrix in order to white-, black- or graylist a component. Graylisting means the blocked or allowed status will be inherited from another cell with higher precedence in the matrix.
@ -74,8 +88,6 @@ This extension is also useful if you wish to speed up your browsing, by globally
=====
BUGS, ISSUES: https://github.com/uBlockOrigin/uMatrix-issues/issues
SOURCE CODE: https://github.com/gorhill/uMatrix (GPLv3)
CHANGE LOG: https://github.com/gorhill/uMatrix/releases

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

@ -1,8 +1,8 @@
{
"manifest_version": 2,
"name": "nuTensor",
"short_name": "nuTensor",
"version": "1.3.3.8",
"name": "uMatrix",
"short_name": "uMatrix",
"version": "0.9.0.1",
"description": "__MSG_extShortDesc__",
"icons": {
"16": "img/icon_16.png",
@ -12,44 +12,76 @@
"default_icon": {
"19": "img/browsericons/icon19-19.png"
},
"default_title": "nuTensor",
"default_title": "uMatrix",
"default_popup": "popup.html"
},
"author": "Raymond Hill",
"background": {
"page": "background.html"
},
"commands": {
"revert-all": {
"description": "__MSG_commandRevertAll__",
"suggested_key": {
"default": "Alt+Q",
"mac": "Command+Shift+Q"
}
},
"whitelist-all": {
"description": "__MSG_commandWhitelistAll__",
"suggested_key": {
"default": "Alt+A",
"mac": "Command+Shift+A"
}
},
"whitelist-page-domain": {
"description": "__MSG_commandWhitelistPageDomain__",
"suggested_key": {
"default": "Alt+W",
"mac": "Command+Shift+W"
}
},
"open-dashboard": {
"description": "__MSG_commandOpenDashboard__",
"suggested_key": {
"default": "Alt+S",
"mac": "Command+Shift+S"
}
}
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["/js/vapi.js", "/js/vapi-client.js", "/js/contentscript-start.js"],
"js": ["js/vapi-client.js", "js/contentscript-start.js"],
"run_at": "document_start",
"all_frames": true
},
{
"matches": ["http://*/*", "https://*/*"],
"js": ["/js/contentscript.js"],
"js": ["js/contentscript-end.js"],
"run_at": "document_end",
"all_frames": true
}
],
"default_locale": "en",
"homepage_url": "https://github.com/geekprojects/nuTensor",
"minimum_chrome_version": "45.0",
"options_ui": {
"page": "dashboard.html",
"open_in_tab": true
},
"homepage_url": "https://github.com/gorhill/uMatrix/wiki",
"minimum_chrome_version": "22.0",
"options_page": "dashboard.html",
"permissions": [
"browsingData",
"contentSettings",
"cookies",
"privacy",
"storage",
"tabs",
"unlimitedStorage",
"webNavigation",
"webRequest",
"webRequestBlocking",
"<all_urls>"
"http://*/*",
"https://*/*"
],
"web_accessible_resources": [
"css/fonts/Roboto_Condensed/RobotoCondensed-Regular.ttf",
"css/noop.css"
]
}

@ -0,0 +1,9 @@
<!DOCTYPE html>
<head>
<script src="js/vapi-client.js"></script>
<script src="js/options_ui.js"></script>
<title></title>
</head>
<body>
</body>
</html>

@ -1,7 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2019-present Raymond Hill
µBlock - a browser extension to block requests.
Copyright (C) 2015 The µBlock authors
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
@ -19,19 +19,27 @@
Home: https://github.com/gorhill/uBlock
*/
/* global CodeMirror */
/******************************************************************************/
(function() {
/******************************************************************************/
'use strict';
CodeMirror.defineMode('raw-settings', function() {
return {
token: function(stream) {
if ( stream.sol() ) {
stream.match(/\s*\S+/);
return 'keyword';
}
stream.skipToEnd();
return null;
}
};
var messager = vAPI.messaging.channel('_open');
messager.send({
what: 'gotoURL',
details: {
url: 'dashboard.html',
select: true,
index: -1
}
});
window.close();
/******************************************************************************/
})();
/******************************************************************************/

File diff suppressed because it is too large Load Diff

@ -1,308 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2019-present Raymond Hill
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uBlock
*/
// For non-background page
'use strict';
/******************************************************************************/
// Direct messaging connection ability
(( ) => {
// >>>>>>>> start of private namespace
if (
typeof vAPI !== 'object' ||
vAPI.messaging instanceof Object === false ||
vAPI.MessagingConnection instanceof Function
) {
return;
}
const listeners = new Set();
const connections = new Map();
vAPI.MessagingConnection = class {
constructor(handler, details) {
this.messaging = vAPI.messaging;
this.handler = handler;
this.id = details.id;
this.to = details.to;
this.toToken = details.toToken;
this.from = details.from;
this.fromToken = details.fromToken;
this.checkTimer = undefined;
// On Firefox it appears ports are not automatically disconnected
// when navigating to another page.
const ctor = vAPI.MessagingConnection;
if ( ctor.pagehide !== undefined ) { return; }
ctor.pagehide = ( ) => {
for ( const connection of connections.values() ) {
connection.disconnect();
connection.handler(
connection.toDetails('connectionBroken')
);
}
};
window.addEventListener('pagehide', ctor.pagehide);
}
toDetails(what, payload) {
return {
what: what,
id: this.id,
from: this.from,
fromToken: this.fromToken,
to: this.to,
toToken: this.toToken,
payload: payload
};
}
disconnect() {
if ( this.checkTimer !== undefined ) {
clearTimeout(this.checkTimer);
this.checkTimer = undefined;
}
connections.delete(this.id);
const port = this.messaging.getPort();
if ( port === null ) { return; }
port.postMessage({
channel: 'vapi',
msg: this.toDetails('connectionBroken'),
});
}
checkAsync() {
if ( this.checkTimer !== undefined ) {
clearTimeout(this.checkTimer);
}
this.checkTimer = vAPI.setTimeout(
( ) => { this.check(); },
499
);
}
check() {
this.checkTimer = undefined;
if ( connections.has(this.id) === false ) { return; }
const port = this.messaging.getPort();
if ( port === null ) { return; }
port.postMessage({
channel: 'vapi',
msg: this.toDetails('connectionCheck'),
});
this.checkAsync();
}
receive(details) {
switch ( details.what ) {
case 'connectionAccepted':
this.toToken = details.toToken;
this.handler(details);
this.checkAsync();
break;
case 'connectionBroken':
connections.delete(this.id);
this.handler(details);
break;
case 'connectionMessage':
this.handler(details);
this.checkAsync();
break;
case 'connectionCheck':
const port = this.messaging.getPort();
if ( port === null ) { return; }
if ( connections.has(this.id) ) {
this.checkAsync();
} else {
details.what = 'connectionBroken';
port.postMessage({ channel: 'vapi', msg: details });
}
break;
case 'connectionRefused':
connections.delete(this.id);
this.handler(details);
break;
}
}
send(payload) {
const port = this.messaging.getPort();
if ( port === null ) { return; }
port.postMessage({
channel: 'vapi',
msg: this.toDetails('connectionMessage', payload),
});
}
static addListener(listener) {
listeners.add(listener);
}
static async connectTo(from, to, handler) {
const port = vAPI.messaging.getPort();
if ( port === null ) { return; }
const connection = new vAPI.MessagingConnection(handler, {
id: `${from}-${to}-${vAPI.sessionId}`,
to: to,
from: from,
fromToken: port.name
});
connections.set(connection.id, connection);
port.postMessage({
channel: 'vapi',
msg: {
what: 'connectionRequested',
id: connection.id,
from: from,
fromToken: port.name,
to: to,
}
});
return connection.id;
}
static disconnectFrom(connectionId) {
const connection = connections.get(connectionId);
if ( connection === undefined ) { return; }
connection.disconnect();
}
static sendTo(connectionId, payload) {
const connection = connections.get(connectionId);
if ( connection === undefined ) { return; }
connection.send(payload);
}
static canDestroyPort() {
return listeners.length === 0 && connections.size === 0;
}
static mustDestroyPort() {
if ( connections.size === 0 ) { return; }
for ( const connection of connections.values() ) {
connection.receive({ what: 'connectionBroken' });
}
connections.clear();
}
static canProcessMessage(details) {
if ( details.channel !== 'vapi' ) { return; }
switch ( details.msg.what ) {
case 'connectionAccepted':
case 'connectionBroken':
case 'connectionCheck':
case 'connectionMessage':
case 'connectionRefused': {
const connection = connections.get(details.msg.id);
if ( connection === undefined ) { break; }
connection.receive(details.msg);
return true;
}
case 'connectionRequested':
if ( listeners.length === 0 ) { return; }
const port = vAPI.messaging.getPort();
if ( port === null ) { break; }
let listener, result;
for ( listener of listeners ) {
result = listener(details.msg);
if ( result !== undefined ) { break; }
}
if ( result === undefined ) { break; }
if ( result === true ) {
details.msg.what = 'connectionAccepted';
details.msg.toToken = port.name;
const connection = new vAPI.MessagingConnection(
listener,
details.msg
);
connections.set(connection.id, connection);
} else {
details.msg.what = 'connectionRefused';
}
port.postMessage(details);
return true;
default:
break;
}
}
};
vAPI.messaging.extensions.push(vAPI.MessagingConnection);
// <<<<<<<< end of private namespace
})();
/******************************************************************************/
// Broadcast listening ability
(( ) => {
// >>>>>>>> start of private namespace
if (
typeof vAPI !== 'object' ||
vAPI.messaging instanceof Object === false ||
vAPI.broadcastListener instanceof Object
) {
return;
}
const listeners = new Set();
vAPI.broadcastListener = {
add: function(listener) {
listeners.add(listener);
vAPI.messaging.getPort();
},
remove: function(listener) {
listeners.delete(listener);
},
canDestroyPort() {
return listeners.size === 0;
},
mustDestroyPort() {
listeners.clear();
},
canProcessMessage(details) {
if ( details.broadcast === false ) { return; }
for ( const listener of listeners ) {
listener(details.msg);
}
},
};
vAPI.messaging.extensions.push(vAPI.broadcastListener);
// <<<<<<<< end of private namespace
})();
/******************************************************************************/
/*******************************************************************************
DO NOT:
- Remove the following code
- Add code beyond the following code
Reason:
- https://github.com/gorhill/uBlock/pull/3721
- uBO never uses the return value from injected content scripts
**/
void 0;

@ -1,8 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2014-2015 The uBlock Origin authors
Copyright (C) 2014-present Raymond Hill
µBlock - a browser extension to block requests.
Copyright (C) 2014 The µBlock authors
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
@ -20,249 +19,173 @@
Home: https://github.com/gorhill/uBlock
*/
// For non-background page
// For non background pages
/******************************************************************************/
(function(self) {
'use strict';
/******************************************************************************/
var vAPI = self.vAPI = self.vAPI || {};
var chrome = self.chrome;
// https://github.com/chrisaljoudi/uBlock/issues/456
// Skip if already injected.
// Already injected?
if ( vAPI.vapiClientInjected ) {
//console.debug('vapi-client.js already injected: skipping.');
return;
}
vAPI.vapiClientInjected = true;
// >>>>>>>> start of HUGE-IF-BLOCK
if (
typeof vAPI === 'object' &&
vAPI.randomToken instanceof Function === false
) {
vAPI.sessionId = String.fromCharCode(Date.now() % 25 + 97) +
Math.random().toString(36).slice(2);
vAPI.chrome = true;
/******************************************************************************/
/******************************************************************************/
vAPI.randomToken = function() {
const now = Date.now();
return String.fromCharCode(now % 26 + 97) +
Math.floor((1 + Math.random()) * now).toString(36);
};
vAPI.sessionId = vAPI.randomToken();
vAPI.setTimeout = vAPI.setTimeout || self.setTimeout.bind(self);
vAPI.shutdown = (function() {
var jobs = [];
/******************************************************************************/
var add = function(job) {
jobs.push(job);
};
vAPI.shutdown = {
jobs: [],
add: function(job) {
this.jobs.push(job);
},
exec: function() {
// Shutdown asynchronously, to ensure shutdown jobs are called from
// the top context.
self.requestIdleCallback(( ) => {
const jobs = this.jobs.slice();
this.jobs.length = 0;
while ( jobs.length !== 0 ) {
(jobs.pop())();
}
});
},
remove: function(job) {
let pos;
while ( (pos = this.jobs.indexOf(job)) !== -1 ) {
this.jobs.splice(pos, 1);
var exec = function() {
//console.debug('Shutting down...');
var job;
while ( job = jobs.pop() ) {
job();
}
}
};
};
return {
add: add,
exec: exec
};
})();
/******************************************************************************/
vAPI.messaging = {
port: null,
portTimer: null,
portTimerDelay: 10000,
extended: undefined,
extensions: [],
msgIdGenerator: 1,
pending: new Map(),
shuttingDown: false,
shutdown: function() {
this.shuttingDown = true;
this.destroyPort();
},
var messagingConnector = function(response) {
if ( !response ) {
return;
}
// https://github.com/uBlockOrigin/uBlock-issues/issues/403
// Spurious disconnection can happen, so do not consider such events
// as world-ending, i.e. stay around. Except for embedded frames.
var channels = vAPI.messaging.channels;
var channel, listener;
disconnectListener: function() {
this.port = null;
if ( window !== window.top ) {
vAPI.shutdown.exec();
}
},
disconnectListenerBound: null,
messageListener: function(details) {
if ( details instanceof Object === false ) { return; }
// Response to specific message previously sent
if ( details.msgId !== undefined ) {
const resolver = this.pending.get(details.msgId);
if ( resolver !== undefined ) {
this.pending.delete(details.msgId);
resolver(details.msg);
return;
if ( response.broadcast === true && !response.channelName ) {
for ( channel in channels ) {
if ( channels.hasOwnProperty(channel) === false ) {
continue;
}
listener = channels[channel].listener;
if ( typeof listener === 'function' ) {
listener(response.msg);
}
}
return;
}
// Unhandled messages
this.extensions.every(ext => ext.canProcessMessage(details) !== true);
},
messageListenerBound: null,
canDestroyPort: function() {
return this.pending.size === 0 &&
(
this.extensions.length === 0 ||
this.extensions.every(e => e.canDestroyPort())
);
},
if ( response.requestId ) {
listener = vAPI.messaging.listeners[response.requestId];
delete vAPI.messaging.listeners[response.requestId];
delete response.requestId;
}
mustDestroyPort: function() {
if ( this.extensions.length === 0 ) { return; }
this.extensions.forEach(e => e.mustDestroyPort());
this.extensions.length = 0;
},
if ( !listener ) {
channel = channels[response.channelName];
listener = channel && channel.listener;
}
portPoller: function() {
this.portTimer = null;
if ( this.port !== null && this.canDestroyPort() ) {
return this.destroyPort();
}
this.portTimer = vAPI.setTimeout(this.portPollerBound, this.portTimerDelay);
this.portTimerDelay = Math.min(this.portTimerDelay * 2, 60 * 60 * 1000);
},
portPollerBound: null,
if ( typeof listener === 'function' ) {
listener(response.msg);
}
};
destroyPort: function() {
if ( this.portTimer !== null ) {
clearTimeout(this.portTimer);
this.portTimer = null;
}
const port = this.port;
if ( port !== null ) {
port.disconnect();
port.onMessage.removeListener(this.messageListenerBound);
port.onDisconnect.removeListener(this.disconnectListenerBound);
this.port = null;
}
this.mustDestroyPort();
// service pending callbacks
if ( this.pending.size !== 0 ) {
const pending = this.pending;
this.pending = new Map();
for ( const resolver of pending.values() ) {
resolver();
}
}
},
/******************************************************************************/
createPort: function() {
if ( this.shuttingDown ) { return null; }
if ( this.messageListenerBound === null ) {
this.messageListenerBound = this.messageListener.bind(this);
this.disconnectListenerBound = this.disconnectListener.bind(this);
this.portPollerBound = this.portPoller.bind(this);
}
try {
this.port = browser.runtime.connect({name: vAPI.sessionId}) || null;
} catch (ex) {
this.port = null;
}
// Not having a valid port at this point means the main process is
// not available: no point keeping the content scripts alive.
if ( this.port === null ) {
vAPI.shutdown.exec();
return null;
}
this.port.onMessage.addListener(this.messageListenerBound);
this.port.onDisconnect.addListener(this.disconnectListenerBound);
this.portTimerDelay = 10000;
if ( this.portTimer === null ) {
this.portTimer = vAPI.setTimeout(
this.portPollerBound,
this.portTimerDelay
);
}
return this.port;
},
vAPI.messaging = {
port: null,
channels: {},
listeners: {},
requestId: 1,
getPort: function() {
return this.port !== null ? this.port : this.createPort();
setup: function() {
this.port = chrome.runtime.connect({name: vAPI.sessionId});
this.port.onMessage.addListener(messagingConnector);
},
send: function(channel, msg) {
// Too large a gap between the last request and the last response means
// the main process is no longer reachable: memory leaks and bad
// performance become a risk -- especially for long-lived, dynamic
// pages. Guard against this.
if ( this.pending.size > 50 ) {
vAPI.shutdown.exec();
}
const port = this.getPort();
if ( port === null ) {
return Promise.resolve();
close: function() {
if ( this.port === null ) {
return;
}
const msgId = this.msgIdGenerator++;
const promise = new Promise(resolve => {
this.pending.set(msgId, resolve);
});
port.postMessage({ channel, msgId, msg });
return promise;
this.port.disconnect();
this.port.onMessage.removeListener(messagingConnector);
this.port = null;
this.channels = {};
this.listeners = {};
},
// Dynamically extend capabilities.
extend: function() {
if ( this.extended === undefined ) {
this.extended = vAPI.messaging.send('vapi', {
what: 'extendClient'
}).then(( ) => {
return self.vAPI instanceof Object &&
this.extensions.length !== 0;
}).catch(( ) => {
});
channel: function(channelName, callback) {
if ( !channelName ) {
return;
}
return this.extended;
},
};
vAPI.shutdown.add(( ) => {
vAPI.messaging.shutdown();
window.vAPI = undefined;
});
this.channels[channelName] = {
channelName: channelName,
listener: typeof callback === 'function' ? callback : null,
send: function(message, callback) {
if ( vAPI.messaging.port === null ) {
vAPI.messaging.setup();
}
message = {
channelName: this.channelName,
msg: message
};
if ( callback ) {
message.requestId = vAPI.messaging.requestId++;
vAPI.messaging.listeners[message.requestId] = callback;
}
vAPI.messaging.port.postMessage(message);
},
close: function() {
delete vAPI.messaging.channels[this.channelName];
if ( Object.keys(vAPI.messaging.channels).length === 0 ) {
vAPI.messaging.close();
}
}
};
return this.channels[channelName];
}
};
/******************************************************************************/
/******************************************************************************/
// No need to have vAPI client linger around after shutdown if
// we are not a top window (because element picker can still
// be injected in top window).
if ( window !== window.top ) {
vAPI.shutdown.add(function() {
vAPI = null;
});
}
// <<<<<<<< end of HUGE-IF-BLOCK
/******************************************************************************/
/*******************************************************************************
vAPI.setTimeout = vAPI.setTimeout || function(callback, delay) {
setTimeout(function() { callback(); }, delay);
};
DO NOT:
- Remove the following code
- Add code beyond the following code
Reason:
- https://github.com/gorhill/uBlock/pull/3721
- uBO never uses the return value from injected content scripts
/******************************************************************************/
**/
})(this);
void 0;
/******************************************************************************/

@ -1,7 +1,7 @@
/*******************************************************************************
uMatrix - a browser extension to black/white list requests.
Copyright (C) 2014-present The uMatrix/uBlock Origin authors
µMatrix - a browser extension to block requests.
Copyright (C) 2014 The µBlock authors
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
@ -21,200 +21,64 @@
// For background page or non-background pages
'use strict';
/* global self */
/******************************************************************************/
/******************************************************************************/
vAPI.T0 = Date.now();
/******************************************************************************/
(function() {
vAPI.setTimeout = vAPI.setTimeout || self.setTimeout.bind(self);
'use strict';
/******************************************************************************/
vAPI.webextFlavor = {
major: 0,
soup: new Set()
};
var vAPI = self.vAPI = self.vAPI || {};
var chrome = self.chrome;
(( ) => {
const ua = navigator.userAgent;
const flavor = vAPI.webextFlavor;
const soup = flavor.soup;
const dispatch = function() {
window.dispatchEvent(new CustomEvent('webextFlavor'));
};
/******************************************************************************/
// This is always true.
soup.add('ublock').add('webext');
// http://www.w3.org/International/questions/qa-scripts#directions
// Whether this is a dev build.
if ( /^\d+\.\d+\.\d+\D/.test(browser.runtime.getManifest().version) ) {
soup.add('devbuild');
}
var setScriptDirection = function(language) {
document.body.setAttribute(
'dir',
['ar', 'he', 'fa', 'ps', 'ur'].indexOf(language) !== -1 ? 'rtl' : 'ltr'
);
};
if ( /\bMobile\b/.test(ua) ) {
soup.add('mobile');
}
/******************************************************************************/
// Asynchronous
if (
browser instanceof Object &&
typeof browser.runtime.getBrowserInfo === 'function'
) {
browser.runtime.getBrowserInfo().then(info => {
flavor.major = parseInt(info.version, 10) || 60;
soup.add(info.vendor.toLowerCase())
.add(info.name.toLowerCase());
if ( soup.has('firefox') && flavor.major < 57 ) {
soup.delete('html_filtering');
}
dispatch();
});
if ( browser.runtime.getURL('').startsWith('moz-extension://') ) {
soup.add('mozilla')
.add('firefox')
.add('user_stylesheet')
.add('html_filtering');
flavor.major = 60;
}
vAPI.download = function(details) {
if ( !details.url ) {
return;
}
// Synchronous -- order of tests is important
let match;
if ( (match = /\bEdge\/(\d+)/.exec(ua)) !== null ) {
flavor.major = parseInt(match[1], 10) || 0;
soup.add('microsoft').add('edge');
} else if ( (match = /\bOPR\/(\d+)/.exec(ua)) !== null ) {
const reEx = /\bChrom(?:e|ium)\/([\d.]+)/;
if ( reEx.test(ua) ) { match = reEx.exec(ua); }
flavor.major = parseInt(match[1], 10) || 0;
soup.add('opera').add('chromium');
} else if ( (match = /\bChromium\/(\d+)/.exec(ua)) !== null ) {
flavor.major = parseInt(match[1], 10) || 0;
soup.add('chromium');
} else if ( (match = /\bChrome\/(\d+)/.exec(ua)) !== null ) {
flavor.major = parseInt(match[1], 10) || 0;
soup.add('google').add('chromium');
} else if ( (match = /\bSafari\/(\d+)/.exec(ua)) !== null ) {
flavor.major = parseInt(match[1], 10) || 0;
soup.add('apple').add('safari');
}
// https://github.com/gorhill/uBlock/issues/3588
if ( soup.has('chromium') && flavor.major >= 66 ) {
soup.add('user_stylesheet');
}
// Don't starve potential listeners
vAPI.setTimeout(dispatch, 97);
})();
/******************************************************************************/
{
const punycode = self.punycode;
const reCommonHostnameFromURL = /^https?:\/\/([0-9a-z_][0-9a-z._-]*[0-9a-z])\//;
const reAuthorityFromURI = /^(?:[^:\/?#]+:)?(\/\/[^\/?#]+)/;
const reHostFromNakedAuthority = /^[0-9a-z._-]+[0-9a-z]$/i;
const reHostFromAuthority = /^(?:[^@]*@)?([^:]+)(?::\d*)?$/;
const reIPv6FromAuthority = /^(?:[^@]*@)?(\[[0-9a-f:]+\])(?::\d*)?$/i;
const reMustNormalizeHostname = /[^0-9a-z._-]/;
vAPI.hostnameFromURI = function(uri) {
let matches = reCommonHostnameFromURL.exec(uri);
if ( matches !== null ) { return matches[1]; }
matches = reAuthorityFromURI.exec(uri);
if ( matches === null ) { return ''; }
const authority = matches[1].slice(2);
if ( reHostFromNakedAuthority.test(authority) ) {
return authority.toLowerCase();
}
matches = reHostFromAuthority.exec(authority);
if ( matches === null ) {
matches = reIPv6FromAuthority.exec(authority);
if ( matches === null ) { return ''; }
}
let hostname = matches[1];
while ( hostname.endsWith('.') ) {
hostname = hostname.slice(0, -1);
}
if ( reMustNormalizeHostname.test(hostname) ) {
hostname = punycode.toASCII(hostname.toLowerCase());
}
return hostname;
};
const reHostnameFromNetworkURL =
/^(?:http|ws|ftp)s?:\/\/([0-9a-z_][0-9a-z._-]*[0-9a-z])\//;
vAPI.hostnameFromNetworkURL = function(url) {
const matches = reHostnameFromNetworkURL.exec(url);
return matches !== null ? matches[1] : '';
};
const psl = self.publicSuffixList;
const reIPAddressNaive = /^\d+\.\d+\.\d+\.\d+$|^\[[\da-zA-Z:]+\]$/;
vAPI.domainFromHostname = function(hostname) {
return reIPAddressNaive.test(hostname)
? hostname
: psl.getDomain(hostname);
};
vAPI.domainFromURI = function(uri) {
return uri !== ''
? vAPI.domainFromHostname(vAPI.hostnameFromURI(uri))
: '';
};
}
/******************************************************************************/
vAPI.download = function(details) {
if ( !details.url ) { return; }
const a = document.createElement('a');
var a = document.createElement('a');
a.href = details.url;
a.setAttribute('download', details.filename || '');
a.setAttribute('type', 'text/plain');
a.dispatchEvent(new MouseEvent('click'));
};
/******************************************************************************/
vAPI.getURL = browser.runtime.getURL;
vAPI.insertHTML = function(node, html) {
node.innerHTML = html;
};
/******************************************************************************/
vAPI.i18n = browser.i18n.getMessage;
// http://www.w3.org/International/questions/qa-scripts#directions
document.body.setAttribute(
'dir',
['ar', 'he', 'fa', 'ps', 'ur'].indexOf(vAPI.i18n('@@ui_locale')) !== -1
? 'rtl'
: 'ltr'
);
vAPI.getURL = chrome.runtime.getURL;
/******************************************************************************/
// https://github.com/gorhill/uBlock/issues/3057
// - webNavigation.onCreatedNavigationTarget become broken on Firefox when we
// try to make the popup panel close itself using the original
// `window.open('', '_self').close()`.
vAPI.i18n = chrome.i18n.getMessage;
vAPI.closePopup = function() {
if ( vAPI.webextFlavor.soup.has('firefox') ) {
window.close();
return;
}
setScriptDirection(vAPI.i18n('@@ui_locale'));
/******************************************************************************/
// TODO: try to figure why this was used instead of a plain window.close().
// https://github.com/gorhill/uBlock/commit/b301ac031e0c2e9a99cb6f8953319d44e22f33d2#diff-bc664f26b9c453e0d43a9379e8135c6a
window.open('', '_self').close();
vAPI.closePopup = function() {
window.open('','_self').close();
};
/******************************************************************************/
@ -224,56 +88,14 @@ vAPI.closePopup = function() {
// This storage is optional, but it is nice to have, for a more polished user
// experience.
// https://github.com/gorhill/uBlock/issues/2824
// Use a dummy localStorage if for some reasons it's not available.
// https://github.com/gorhill/uMatrix/issues/840
// Always use a wrapper to seamlessly handle exceptions
vAPI.localStorage = {
clear: function() {
try {
window.localStorage.clear();
} catch(ex) {
}
},
getItem: function(key) {
try {
return window.localStorage.getItem(key);
} catch(ex) {
}
return null;
},
removeItem: function(key) {
try {
window.localStorage.removeItem(key);
} catch(ex) {
}
},
setItem: function(key, value) {
try {
window.localStorage.setItem(key, value);
} catch(ex) {
}
}
};
vAPI.localStorage = window.localStorage;
/******************************************************************************/
/*******************************************************************************
vAPI.setTimeout = vAPI.setTimeout || window.setTimeout.bind(window);
DO NOT:
- Remove the following code
- Add code beyond the following code
Reason:
- https://github.com/gorhill/uBlock/pull/3721
- uBO never uses the return value from injected content scripts
/******************************************************************************/
**/
})();
void 0;
/******************************************************************************/

@ -1,178 +0,0 @@
/*******************************************************************************
uMatrix - a browser extension to block requests.
Copyright (C) 2017-present Raymond Hill
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uMatrix
*/
// For background page
'use strict';
/******************************************************************************/
(( ) => {
// https://github.com/uBlockOrigin/uBlock-issues/issues/407
if ( vAPI.webextFlavor.soup.has('chromium') === false ) { return; }
const extToTypeMap = new Map([
['eot','font'],['otf','font'],['svg','font'],['ttf','font'],['woff','font'],['woff2','font'],
['mp3','media'],['mp4','media'],['webm','media'],
['gif','image'],['ico','image'],['jpeg','image'],['jpg','image'],['png','image'],['webp','image']
]);
const headerValue = (headers, name) => {
let i = headers.length;
while ( i-- ) {
if ( headers[i].name.toLowerCase() === name ) {
return headers[i].value.trim();
}
}
return '';
};
const parsedURL = new URL('https://www.example.org/');
// Extend base class to normalize as per platform.
vAPI.Net = class extends vAPI.Net {
constructor() {
super();
this.suspendedTabIds = new Set();
}
normalizeDetails(details) {
// Chromium 63+ supports the `initiator` property, which contains
// the URL of the origin from which the network request was made.
if (
typeof details.initiator === 'string' &&
details.initiator !== 'null'
) {
details.documentUrl = details.initiator;
}
let type = details.type;
if ( type === 'imageset' ) {
details.type = 'image';
return;
}
// The rest of the function code is to normalize type
if ( type !== 'other' ) { return; }
// Try to map known "extension" part of URL to request type.
parsedURL.href = details.url;
const path = parsedURL.pathname,
pos = path.indexOf('.', path.length - 6);
if ( pos !== -1 && (type = extToTypeMap.get(path.slice(pos + 1))) ) {
details.type = type;
return;
}
// Try to extract type from response headers if present.
if ( details.responseHeaders ) {
type = headerValue(details.responseHeaders, 'content-type');
if ( type.startsWith('font/') ) {
details.type = 'font';
return;
}
if ( type.startsWith('image/') ) {
details.type = 'image';
return;
}
if ( type.startsWith('audio/') || type.startsWith('video/') ) {
details.type = 'media';
return;
}
}
}
// https://www.reddit.com/r/uBlockOrigin/comments/9vcrk3/
// Some types can be mapped from 'other', thus include 'other' if and
// only if the caller is interested in at least one of those types.
denormalizeTypes(types) {
if ( types.length === 0 ) {
return Array.from(this.validTypes);
}
const out = new Set();
for ( const type of types ) {
if ( this.validTypes.has(type) ) {
out.add(type);
}
}
if ( out.has('other') === false ) {
for ( const type of extToTypeMap.values() ) {
if ( out.has(type) ) {
out.add('other');
break;
}
}
}
return Array.from(out);
}
suspendOneRequest(details) {
this.suspendedTabIds.add(details.tabId);
return { cancel: true };
}
unsuspendAllRequests() {
for ( const tabId of this.suspendedTabIds ) {
vAPI.tabs.reload(tabId);
}
this.suspendedTabIds.clear();
}
};
})();
/******************************************************************************/
// https://github.com/uBlockOrigin/uBlock-issues/issues/548
// Use `X-DNS-Prefetch-Control` to workaround Chromium's disregard of the
// setting "Predict network actions to improve page load performance".
vAPI.prefetching = (( ) => {
// https://github.com/uBlockOrigin/uBlock-issues/issues/407
if ( vAPI.webextFlavor.soup.has('chromium') === false ) { return; }
let listening = false;
const onHeadersReceived = function(details) {
details.responseHeaders.push({
name: 'X-DNS-Prefetch-Control',
value: 'off'
});
return { responseHeaders: details.responseHeaders };
};
return state => {
const wr = chrome.webRequest;
if ( state && listening ) {
wr.onHeadersReceived.removeListener(onHeadersReceived);
listening = false;
} else if ( !state && !listening ) {
wr.onHeadersReceived.addListener(
onHeadersReceived,
{
urls: [ 'http://*/*', 'https://*/*' ],
types: [ 'main_frame', 'sub_frame' ]
},
[ 'blocking', 'responseHeaders' ]
);
listening = true;
}
};
})();
/******************************************************************************/

@ -1,86 +0,0 @@
/*******************************************************************************
uMatrix - a browser extension to block requests.
Copyright (C) 2017-present Raymond Hill
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uBlock
*/
'use strict';
/* global HTMLDocument, XMLDocument */
// For background page, auxiliary pages, and content scripts.
/******************************************************************************/
if ( self.browser instanceof Object ) {
self.chrome = self.browser;
} else {
self.browser = self.chrome;
}
/******************************************************************************/
// https://bugzilla.mozilla.org/show_bug.cgi?id=1408996#c9
var vAPI = self.vAPI; // jshint ignore:line
// https://github.com/chrisaljoudi/uBlock/issues/464
// https://github.com/chrisaljoudi/uBlock/issues/1528
// A XMLDocument can be a valid HTML document.
// https://github.com/gorhill/uBlock/issues/1124
// Looks like `contentType` is on track to be standardized:
// https://dom.spec.whatwg.org/#concept-document-content-type
// https://forums.lanik.us/viewtopic.php?f=64&t=31522
// Skip text/plain documents.
if (
(
document instanceof HTMLDocument ||
document instanceof XMLDocument &&
document.createElement('div') instanceof HTMLDivElement
) &&
(
/^image\/|^text\/plain/.test(document.contentType || '') === false
) &&
(
self.vAPI instanceof Object === false || vAPI.nuTensor !== true
)
) {
vAPI = self.vAPI = { nuTensor: true };
}
/*******************************************************************************
DO NOT:
- Remove the following code
- Add code beyond the following code
Reason:
- https://github.com/gorhill/uBlock/pull/3721
- uMatrix never uses the return value from injected content scripts
**/
void 0;

@ -1,176 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2019-present Raymond Hill
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uBlock
*/
'use strict';
// `webext` is a promisified api of `chrome`. Entries are added as
// the promisification of uBO progress.
const webext = (( ) => { // jshint ignore:line
// >>>>> start of private scope
const noopFunc = ( ) => { };
const promisifyNoFail = function(thisArg, fnName, outFn = r => r) {
const fn = thisArg[fnName];
return function() {
return new Promise(resolve => {
fn.call(thisArg, ...arguments, function() {
if ( chrome.runtime.lastError instanceof Object ) {
void chrome.runtime.lastError.message;
}
resolve(outFn(...arguments));
});
});
};
};
const promisify = function(thisArg, fnName) {
const fn = thisArg[fnName];
return function() {
return new Promise((resolve, reject) => {
fn.call(thisArg, ...arguments, function() {
const lastError = chrome.runtime.lastError;
if ( lastError instanceof Object ) {
return reject(lastError.message);
}
resolve(...arguments);
});
});
};
};
const webext = {
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction
browserAction: {
setBadgeBackgroundColor: promisifyNoFail(chrome.browserAction, 'setBadgeBackgroundColor'),
setBadgeText: promisifyNoFail(chrome.browserAction, 'setBadgeText'),
setBadgeTextColor: noopFunc,
setIcon: promisifyNoFail(chrome.browserAction, 'setIcon'),
setTitle: promisifyNoFail(chrome.browserAction, 'setTitle'),
},
cookies: {
getAll: promisifyNoFail(chrome.cookies, 'getAll'),
remove: promisifyNoFail(chrome.cookies, 'remove'),
},
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus
/*
menus: {
create: function() {
return chrome.contextMenus.create(...arguments, ( ) => {
void chrome.runtime.lastError;
});
},
onClicked: chrome.contextMenus.onClicked,
remove: promisifyNoFail(chrome.contextMenus, 'remove'),
},
*/
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy
privacy: {
},
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage
storage: {
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/local
local: {
clear: promisify(chrome.storage.local, 'clear'),
get: promisify(chrome.storage.local, 'get'),
getBytesInUse: promisify(chrome.storage.local, 'getBytesInUse'),
remove: promisify(chrome.storage.local, 'remove'),
set: promisify(chrome.storage.local, 'set'),
},
},
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs
tabs: {
get: promisifyNoFail(chrome.tabs, 'get', tab => tab instanceof Object ? tab : null),
executeScript: promisifyNoFail(chrome.tabs, 'executeScript'),
insertCSS: promisifyNoFail(chrome.tabs, 'insertCSS'),
query: promisifyNoFail(chrome.tabs, 'query', tabs => Array.isArray(tabs) ? tabs : []),
reload: promisifyNoFail(chrome.tabs, 'reload'),
remove: promisifyNoFail(chrome.tabs, 'remove'),
update: promisifyNoFail(chrome.tabs, 'update', tab => tab instanceof Object ? tab : null),
},
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation
webNavigation: {
getFrame: promisify(chrome.webNavigation, 'getFrame'),
},
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows
windows: {
get: promisifyNoFail(chrome.windows, 'get', win => win instanceof Object ? win : null),
create: promisifyNoFail(chrome.windows, 'create', win => win instanceof Object ? win : null),
update: promisifyNoFail(chrome.windows, 'update', win => win instanceof Object ? win : null),
},
};
// browser.privacy entries
{
const settings = [
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy/network
[ 'network', 'networkPredictionEnabled' ],
[ 'network', 'webRTCIPHandlingPolicy' ],
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy/websites
[ 'websites', 'hyperlinkAuditingEnabled' ],
];
for ( const [ category, setting ] of settings ) {
let categoryEntry = webext.privacy[category];
if ( categoryEntry instanceof Object === false ) {
categoryEntry = webext.privacy[category] = {};
}
const settingEntry = categoryEntry[setting] = {};
const thisArg = chrome.privacy[category][setting];
settingEntry.clear = promisifyNoFail(thisArg, 'clear');
settingEntry.get = promisifyNoFail(thisArg, 'get');
settingEntry.set = promisifyNoFail(thisArg, 'set');
}
}
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/managed
if ( chrome.storage.managed instanceof Object ) {
webext.storage.managed = {
get: promisify(chrome.storage.managed, 'get'),
};
}
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage/sync
if ( chrome.storage.sync instanceof Object ) {
webext.storage.sync = {
QUOTA_BYTES: chrome.storage.sync.QUOTA_BYTES,
QUOTA_BYTES_PER_ITEM: chrome.storage.sync.QUOTA_BYTES_PER_ITEM,
MAX_ITEMS: chrome.storage.sync.MAX_ITEMS,
MAX_WRITE_OPERATIONS_PER_HOUR: chrome.storage.sync.MAX_WRITE_OPERATIONS_PER_HOUR,
MAX_WRITE_OPERATIONS_PER_MINUTE: chrome.storage.sync.MAX_WRITE_OPERATIONS_PER_MINUTE,
clear: promisify(chrome.storage.sync, 'clear'),
get: promisify(chrome.storage.sync, 'get'),
getBytesInUse: promisify(chrome.storage.sync, 'getBytesInUse'),
remove: promisify(chrome.storage.sync, 'remove'),
set: promisify(chrome.storage.sync, 'set'),
};
}
// https://bugs.chromium.org/p/chromium/issues/detail?id=608854
if ( chrome.tabs.removeCSS instanceof Function ) {
webext.tabs.removeCSS = promisifyNoFail(chrome.tabs, 'removeCSS');
}
return webext;
// <<<<< end of private scope
})();

@ -0,0 +1,156 @@
/*******************************************************************************
µBlock - a browser extension to block requests.
Copyright (C) 2014 The µBlock authors
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uMatrix
*/
/* global ADDON_UNINSTALL, APP_SHUTDOWN, APP_STARTUP */
/* exported startup, shutdown, install, uninstall */
'use strict';
/******************************************************************************/
// Accessing the context of the background page:
// var win = Services.appShell.hiddenDOMWindow.document.querySelector('iframe[src*=umatrix]').contentWindow;
let bgProcess;
let version;
const hostName = 'umatrix';
const restartListener = {
get messageManager() {
return Components.classes['@mozilla.org/parentprocessmessagemanager;1']
.getService(Components.interfaces.nsIMessageListenerManager);
},
receiveMessage: function() {
shutdown();
startup();
}
};
/******************************************************************************/
function startup(data, reason) {
if ( data !== undefined ) {
version = data.version;
}
let appShell = Components.classes['@mozilla.org/appshell/appShellService;1']
.getService(Components.interfaces.nsIAppShellService);
let onReady = function(e) {
if ( e ) {
this.removeEventListener(e.type, onReady);
}
let hiddenDoc = appShell.hiddenDOMWindow.document;
// https://github.com/gorhill/uBlock/issues/10
// Fixed by github.com/AlexVallat:
// https://github.com/chrisaljoudi/uBlock/issues/1149
// https://github.com/AlexVallat/uBlock/commit/e762a29d308caa46578cdc34a9be92c4ad5ecdd0
if ( hiddenDoc.readyState === 'loading' ) {
hiddenDoc.addEventListener('DOMContentLoaded', onReady);
return;
}
bgProcess = hiddenDoc.documentElement.appendChild(
hiddenDoc.createElementNS('http://www.w3.org/1999/xhtml', 'iframe')
);
bgProcess.setAttribute(
'src',
'chrome://' + hostName + '/content/background.html#' + version
);
restartListener.messageManager.addMessageListener(
hostName + '-restart',
restartListener
);
};
if ( reason !== APP_STARTUP ) {
onReady();
return;
}
let ww = Components.classes['@mozilla.org/embedcomp/window-watcher;1']
.getService(Components.interfaces.nsIWindowWatcher);
ww.registerNotification({
observe: function(win, topic) {
if ( topic !== 'domwindowopened' ) {
return;
}
try {
appShell.hiddenDOMWindow;
} catch (ex) {
return;
}
ww.unregisterNotification(this);
win.addEventListener('DOMContentLoaded', onReady);
}
});
}
/******************************************************************************/
function shutdown(data, reason) {
if ( reason === APP_SHUTDOWN ) {
return;
}
bgProcess.parentNode.removeChild(bgProcess);
if ( data === undefined ) {
return;
}
// Remove the restartObserver only when the extension is being disabled
restartListener.messageManager.removeMessageListener(
hostName + '-restart',
restartListener
);
}
/******************************************************************************/
function install() {
// https://bugzil.la/719376
Components.classes['@mozilla.org/intl/stringbundle;1']
.getService(Components.interfaces.nsIStringBundleService)
.flushBundles();
}
/******************************************************************************/
function uninstall(data, aReason) {
if ( aReason !== ADDON_UNINSTALL ) {
return;
}
// To cleanup vAPI.localStorage in vapi-common.js, aka
// "extensions.umatrix.*" in `about:config`.
Components.utils.import('resource://gre/modules/Services.jsm', null)
.Services.prefs
.getBranch('extensions.' + hostName + '.')
.deleteBranch('');
}
/******************************************************************************/

@ -0,0 +1 @@
content umatrix ./

@ -0,0 +1,258 @@
/*******************************************************************************
µBlock - a browser extension to block requests.
Copyright (C) 2014 The µBlock authors
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uMatrix
*/
'use strict';
/******************************************************************************/
this.EXPORTED_SYMBOLS = ['contentObserver', 'LocationChangeListener'];
const {interfaces: Ci, utils: Cu} = Components;
const {Services} = Cu.import('resource://gre/modules/Services.jsm', null);
const {XPCOMUtils} = Cu.import('resource://gre/modules/XPCOMUtils.jsm', null);
const hostName = Services.io.newURI(Components.stack.filename, null, null).host;
// Cu.import('resource://gre/modules/devtools/Console.jsm');
/******************************************************************************/
const getMessageManager = function(win) {
return win
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
};
/******************************************************************************/
const contentObserver = {
classDescription: 'content-policy for ' + hostName,
classID: Components.ID('{c84283d4-9975-41b7-b1a4-f106af56b51d}'),
contractID: '@' + hostName + '/content-policy;1',
ACCEPT: Ci.nsIContentPolicy.ACCEPT,
MAIN_FRAME: Ci.nsIContentPolicy.TYPE_DOCUMENT,
contentBaseURI: 'chrome://' + hostName + '/content/js/',
uniqueSandboxId: 1,
get componentRegistrar() {
return Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
},
get categoryManager() {
return Components.classes['@mozilla.org/categorymanager;1']
.getService(Ci.nsICategoryManager);
},
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIFactory,
Ci.nsIObserver,
Ci.nsIContentPolicy,
Ci.nsISupportsWeakReference
]),
createInstance: function(outer, iid) {
if ( outer ) {
throw Components.results.NS_ERROR_NO_AGGREGATION;
}
return this.QueryInterface(iid);
},
register: function() {
Services.obs.addObserver(this, 'document-element-inserted', true);
this.componentRegistrar.registerFactory(
this.classID,
this.classDescription,
this.contractID,
this
);
this.categoryManager.addCategoryEntry(
'content-policy',
this.contractID,
this.contractID,
false,
true
);
},
unregister: function() {
Services.obs.removeObserver(this, 'document-element-inserted');
this.componentRegistrar.unregisterFactory(this.classID, this);
this.categoryManager.deleteCategoryEntry(
'content-policy',
this.contractID,
false
);
},
// https://bugzil.la/612921
shouldLoad: function(type, location, origin, context) {
return this.ACCEPT;
},
initContentScripts: function(win, sandbox) {
let messager = getMessageManager(win);
let sandboxId = hostName + ':sb:' + this.uniqueSandboxId++;
if ( sandbox ) {
let sandboxName = [
win.location.href.slice(0, 100),
win.document.title.slice(0, 100)
].join(' | ');
sandbox = Cu.Sandbox([win], {
sandboxName: sandboxId + '[' + sandboxName + ']',
sandboxPrototype: win,
wantComponents: false,
wantXHRConstructor: false
});
sandbox.injectScript = function(script) {
Services.scriptloader.loadSubScript(script, sandbox);
};
}
else {
sandbox = win;
}
sandbox._sandboxId_ = sandboxId;
sandbox.sendAsyncMessage = messager.sendAsyncMessage;
sandbox.addMessageListener = function(callback) {
if ( sandbox._messageListener_ ) {
sandbox.removeMessageListener();
}
sandbox._messageListener_ = function(message) {
callback(message.data);
};
messager.addMessageListener(
sandbox._sandboxId_,
sandbox._messageListener_
);
messager.addMessageListener(
hostName + ':broadcast',
sandbox._messageListener_
);
};
sandbox.removeMessageListener = function() {
try {
messager.removeMessageListener(
sandbox._sandboxId_,
sandbox._messageListener_
);
messager.removeMessageListener(
hostName + ':broadcast',
sandbox._messageListener_
);
} catch (ex) {
// It throws sometimes, mostly when the popup closes
}
sandbox._messageListener_ = null;
};
return sandbox;
},
observe: function(doc) {
let win = doc.defaultView;
if ( !win ) {
return;
}
let loc = win.location;
if ( !loc ) {
return;
}
if ( loc.protocol !== 'http:' && loc.protocol !== 'https:' && loc.protocol !== 'file:' ) {
if ( loc.protocol === 'chrome:' && loc.host === hostName ) {
this.initContentScripts(win);
}
// What about data: and about:blank?
return;
}
let lss = Services.scriptloader.loadSubScript;
let sandbox = this.initContentScripts(win, true);
lss(this.contentBaseURI + 'vapi-client.js', sandbox);
lss(this.contentBaseURI + 'contentscript-start.js', sandbox);
let docReady = (e) => {
let doc = e.target;
doc.removeEventListener(e.type, docReady, true);
lss(this.contentBaseURI + 'contentscript-end.js', sandbox);
};
if ( doc.readyState === 'loading') {
doc.addEventListener('DOMContentLoaded', docReady, true);
} else {
docReady({ target: doc, type: 'DOMContentLoaded' });
}
}
};
/******************************************************************************/
const locationChangedMessageName = hostName + ':locationChanged';
const LocationChangeListener = function(docShell) {
if (docShell) {
docShell.QueryInterface(Ci.nsIInterfaceRequestor);
this.docShell = docShell.getInterface(Ci.nsIWebProgress);
this.messageManager = docShell.getInterface(Ci.nsIContentFrameMessageManager);
if (this.messageManager && typeof this.messageManager.sendAsyncMessage === 'function') {
this.docShell.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_LOCATION);
}
}
};
LocationChangeListener.prototype.QueryInterface = XPCOMUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]);
LocationChangeListener.prototype.onLocationChange = function(webProgress, request, location, flags) {
if ( !webProgress.isTopLevel ) {
return;
}
this.messageManager.sendAsyncMessage(locationChangedMessageName, {
url: location.asciiSpec,
flags: flags,
});
};
/******************************************************************************/
contentObserver.register();
/******************************************************************************/

@ -0,0 +1,65 @@
/*******************************************************************************
µBlock - a browser extension to block requests.
Copyright (C) 2014 The µBlock authors
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uMatrix
*/
/******************************************************************************/
var locationChangeListener; // Keep alive while frameScript is alive
(function() {
'use strict';
/******************************************************************************/
let {contentObserver, LocationChangeListener} = Components.utils.import(
Components.stack.filename.replace('Script', 'Module'),
null
);
let injectContentScripts = function(win) {
if ( !win || !win.document ) {
return;
}
contentObserver.observe(win.document);
if ( win.frames && win.frames.length ) {
let i = win.frames.length;
while ( i-- ) {
injectContentScripts(win.frames[i]);
}
}
};
let onLoadCompleted = function() {
removeMessageListener('umatrix-load-completed', onLoadCompleted);
injectContentScripts(content);
};
addMessageListener('umatrix-load-completed', onLoadCompleted);
locationChangeListener = new LocationChangeListener(docShell);
/******************************************************************************/
})();
/******************************************************************************/

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.mozilla.org/2004/em-rdf#">
<r:Description about="urn:mozilla:install-manifest">
<id>uMatrix@raymondhill.net</id>
<version>{version}</version>
<name>{name}</name>
<description>{description}</description>
<homepageURL>{homepage}</homepageURL>
<creator>{author}</creator>
<type>2</type>
<bootstrap>true</bootstrap>
<multiprocessCompatible>true</multiprocessCompatible>
<optionsType>2</optionsType>
{localized}
<!-- Firefox -->
<targetApplication>
<r:Description>
<id>{{ec8030f7-c20a-464f-9b0e-13a3a9e97384}}</id>
<minVersion>29.0</minVersion>
<maxVersion>40.0</maxVersion>
</r:Description>
</targetApplication>
</r:Description>
</r:RDF>

@ -1,69 +0,0 @@
{
"browser_specific_settings": {
"gecko": {
"id": "nuTensor@geekprojects.com",
"strict_min_version": "60.0"
}
},
"author": "Raymond Hill",
"background": {
"page": "background.html"
},
"browser_action": {
"browser_style": false,
"default_icon": {
"19": "img/browsericons/icon19-off.png"
},
"default_title": "nuTensor",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["/js/vapi.js", "/js/vapi-client.js", "/js/contentscript-start.js"],
"run_at": "document_start",
"all_frames": true
},
{
"matches": ["http://*/*", "https://*/*"],
"js": ["/js/contentscript.js"],
"run_at": "document_end",
"all_frames": true
}
],
"default_locale": "en",
"description": "__MSG_extShortDesc__",
"icons": {
"16": "img/icon_16.png",
"128": "img/icon_128.png"
},
"manifest_version": 2,
"name": "nuTensor",
"options_ui": {
"page":"dashboard.html",
"open_in_tab": true
},
"permissions": [
"browsingData",
"cookies",
"dns",
"privacy",
"storage",
"tabs",
"webNavigation",
"webRequest",
"webRequestBlocking",
"<all_urls>"
],
"short_name": "nuTensor",
"sidebar_action": {
"default_title": "__MSG_loggerPageName__",
"default_panel": "logger-ui.html",
"default_icon": {
"16": "img/icon_16.png",
"128": "img/icon_128.png"
},
"open_at_install": false
},
"version": "0.9.9"
}

@ -0,0 +1,9 @@
<?xml version="1.0" ?>
<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<setting type="control">
<vbox>
<button id="showDashboardButton"/>
<button id="showLoggerButton"/>
</vbox>
</setting>
</vbox>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,211 @@
/*******************************************************************************
µBlock - a browser extension to block requests.
Copyright (C) 2014 The µBlock authors
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uMatrix
*/
/* jshint boss: true, esnext: true */
/* global addMessageListener, removeMessageListener, sendAsyncMessage */
// For non background pages
/******************************************************************************/
(function(self) {
'use strict';
/******************************************************************************/
var vAPI = self.vAPI = self.vAPI || {};
vAPI.firefox = true;
vAPI.sessionId = String.fromCharCode(Date.now() % 25 + 97) +
Math.random().toString(36).slice(2);
/******************************************************************************/
vAPI.shutdown = (function() {
var jobs = [];
var add = function(job) {
jobs.push(job);
};
var exec = function() {
//console.debug('Shutting down...');
var job;
while ( job = jobs.pop() ) {
job();
}
};
return {
add: add,
exec: exec
};
})();
/******************************************************************************/
var messagingConnector = function(response) {
if ( !response ) {
return;
}
var channels = vAPI.messaging.channels;
var channel, listener;
if ( response.broadcast === true && !response.channelName ) {
for ( channel in channels ) {
if ( channels.hasOwnProperty(channel) === false ) {
continue;
}
listener = channels[channel].listener;
if ( typeof listener === 'function' ) {
listener(response.msg);
}
}
return;
}
if ( response.requestId ) {
listener = vAPI.messaging.listeners[response.requestId];
delete vAPI.messaging.listeners[response.requestId];
delete response.requestId;
}
if ( !listener ) {
channel = channels[response.channelName];
listener = channel && channel.listener;
}
if ( typeof listener === 'function' ) {
listener(response.msg);
}
};
/******************************************************************************/
vAPI.messaging = {
channels: {},
listeners: {},
requestId: 1,
setup: function() {
this.connector = function(msg) {
messagingConnector(JSON.parse(msg));
};
addMessageListener(this.connector);
this.channels.vAPI = {
listener: function(msg) {
if ( msg.cmd === 'injectScript' ) {
var details = msg.details;
if ( !details.allFrames && window !== window.top ) {
return;
}
self.injectScript(details.file);
}
}
};
},
close: function() {
if ( !this.connector ) {
return;
}
removeMessageListener();
this.connector = null;
this.channels = {};
this.listeners = {};
},
channel: function(channelName, callback) {
if ( !channelName ) {
return;
}
this.channels[channelName] = {
channelName: channelName,
listener: typeof callback === 'function' ? callback : null,
send: function(message, callback) {
if ( !vAPI.messaging.connector ) {
vAPI.messaging.setup();
}
message = {
channelName: self._sandboxId_ + '|' + this.channelName,
msg: message
};
if ( callback ) {
message.requestId = vAPI.messaging.requestId++;
vAPI.messaging.listeners[message.requestId] = callback;
}
sendAsyncMessage('umatrix:background', message);
},
close: function() {
delete vAPI.messaging.channels[this.channelName];
}
};
return this.channels[channelName];
},
toggleListener: function({type, persisted}) {
if ( !vAPI.messaging.connector ) {
return;
}
if ( type === 'pagehide' ) {
removeMessageListener();
return;
}
if ( persisted ) {
addMessageListener(vAPI.messaging.connector);
}
}
};
window.addEventListener('pagehide', vAPI.messaging.toggleListener, true);
window.addEventListener('pageshow', vAPI.messaging.toggleListener, true);
/******************************************************************************/
// No need to have vAPI client linger around after shutdown if
// we are not a top window (because element picker can still
// be injected in top window).
if ( window !== window.top ) {
// Can anything be done?
}
/******************************************************************************/
vAPI.setTimeout = vAPI.setTimeout || function(callback, delay) {
setTimeout(function() { callback(); }, delay);
};
/******************************************************************************/
})(this);
/******************************************************************************/

@ -0,0 +1,164 @@
/*******************************************************************************
µBlock - a browser extension to block requests.
Copyright (C) 2014 The µBlock authors
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uMatrix
*/
/* jshint esnext: true */
/* global sendAsyncMessage */
// For background page or non-background pages
/******************************************************************************/
(function() {
'use strict';
/******************************************************************************/
const {Services} = Components.utils.import(
'resource://gre/modules/Services.jsm',
null
);
self.vAPI = self.vAPI || {};
/******************************************************************************/
// http://www.w3.org/International/questions/qa-scripts#directions
var setScriptDirection = function(language) {
document.body.setAttribute(
'dir',
['ar', 'he', 'fa', 'ps', 'ur'].indexOf(language) !== -1 ? 'rtl' : 'ltr'
);
};
/******************************************************************************/
vAPI.download = function(details) {
if ( !details.url ) {
return;
}
var a = document.createElement('a');
a.href = details.url;
a.setAttribute('download', details.filename || '');
a.dispatchEvent(new MouseEvent('click'));
};
/******************************************************************************/
vAPI.insertHTML = (function() {
const parser = Components.classes['@mozilla.org/parserutils;1']
.getService(Components.interfaces.nsIParserUtils);
return function(node, html) {
while ( node.firstChild ) {
node.removeChild(node.firstChild);
}
node.appendChild(parser.parseFragment(
html,
parser.SanitizerAllowStyle,
false,
Services.io.newURI(document.baseURI, null, null),
document.documentElement
));
};
})();
/******************************************************************************/
vAPI.getURL = function(path) {
return 'chrome://' + location.host + '/content/' + path.replace(/^\/+/, '');
};
/******************************************************************************/
vAPI.i18n = (function() {
var stringBundle = Services.strings.createBundle(
'chrome://' + location.host + '/locale/messages.properties'
);
return function(s) {
try {
return stringBundle.GetStringFromName(s);
} catch (ex) {
return '';
}
};
})();
setScriptDirection(navigator.language);
/******************************************************************************/
vAPI.closePopup = function() {
sendAsyncMessage(location.host + ':closePopup');
};
/******************************************************************************/
// A localStorage-like object which should be accessible from the
// background page or auxiliary pages.
// This storage is optional, but it is nice to have, for a more polished user
// experience.
vAPI.localStorage = {
PB: Services.prefs.getBranch('extensions.' + location.host + '.'),
str: Components.classes['@mozilla.org/supports-string;1']
.createInstance(Components.interfaces.nsISupportsString),
getItem: function(key) {
try {
return this.PB.getComplexValue(
key,
Components.interfaces.nsISupportsString
).data;
} catch (ex) {
return null;
}
},
setItem: function(key, value) {
this.str.data = value;
this.PB.setComplexValue(
key,
Components.interfaces.nsISupportsString,
this.str
);
},
removeItem: function(key) {
this.PB.clearUserPref(key);
},
clear: function() {
this.PB.deleteBranch('');
}
};
/******************************************************************************/
vAPI.setTimeout = vAPI.setTimeout || function(callback, delay) {
setTimeout(function() { callback(); }, delay);
};
/******************************************************************************/
})();
/******************************************************************************/

@ -0,0 +1 @@
/* Firefox: no platform-specific code */

@ -1,263 +0,0 @@
/*******************************************************************************
uMatrix - a browser extension to block requests.
Copyright (C) 2017-present Raymond Hill
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uMatrix
*/
// For background page
'use strict';
/******************************************************************************/
(( ) => {
// https://github.com/uBlockOrigin/uBlock-issues/issues/407
if ( vAPI.webextFlavor.soup.has('firefox') === false ) { return; }
// https://github.com/gorhill/uBlock/issues/2950
// Firefox 56 does not normalize URLs to ASCII, uBO must do this itself.
// https://bugzilla.mozilla.org/show_bug.cgi?id=945240
const evalMustPunycode = ( ) => {
return vAPI.webextFlavor.soup.has('firefox') &&
vAPI.webextFlavor.major < 57;
};
let mustPunycode = evalMustPunycode();
// The real actual webextFlavor value may not be set in stone, so listen
// for possible future changes.
window.addEventListener('webextFlavor', ( ) => {
mustPunycode = evalMustPunycode();
}, { once: true });
const punycode = self.punycode;
const reAsciiHostname = /^https?:\/\/[0-9a-z_.:@-]+[/?#]/;
const parsedURL = new URL('about:blank');
// Related issues:
// - https://github.com/gorhill/uBlock/issues/1327
// - https://github.com/uBlockOrigin/uBlock-issues/issues/128
// - https://bugzilla.mozilla.org/show_bug.cgi?id=1503721
// Extend base class to normalize as per platform.
vAPI.Net = class extends vAPI.Net {
constructor() {
super();
this.pendingRequests = [];
this.cnames = new Map([ [ '', '' ] ]);
this.cnameIgnoreList = null;
this.cnameIgnore1stParty = true;
this.cnameIgnoreExceptions = true;
this.cnameIgnoreRootDocument = true;
this.cnameMaxTTL = 60;
this.cnameReplayFullURL = false;
this.cnameTimer = undefined;
this.canRevealCNAME = browser.dns instanceof Object;
}
setOptions(options) {
super.setOptions(options);
this.cnameIgnoreList = this.regexFromStrList(options.cnameIgnoreList);
this.cnameIgnore1stParty = options.cnameIgnore1stParty !== false;
this.cnameIgnoreExceptions = options.cnameIgnoreExceptions !== false;
this.cnameIgnoreRootDocument = options.cnameIgnoreRootDocument !== false;
this.cnameMaxTTL = options.cnameMaxTTL || 120;
this.cnameReplayFullURL = options.cnameReplayFullURL === true;
this.cnames.clear(); this.cnames.set('', '');
}
normalizeDetails(details) {
if ( mustPunycode && !reAsciiHostname.test(details.url) ) {
parsedURL.href = details.url;
details.url = details.url.replace(
parsedURL.hostname,
punycode.toASCII(parsedURL.hostname)
);
}
const type = details.type;
if ( type === 'imageset' ) {
details.type = 'image';
return;
}
// https://github.com/uBlockOrigin/uBlock-issues/issues/345
// Re-categorize an embedded object as a `sub_frame` if its
// content type is that of a HTML document.
if ( type === 'object' && Array.isArray(details.responseHeaders) ) {
for ( const header of details.responseHeaders ) {
if ( header.name.toLowerCase() === 'content-type' ) {
if ( header.value.startsWith('text/html') ) {
details.type = 'sub_frame';
}
break;
}
}
}
}
denormalizeTypes(types) {
if ( types.length === 0 ) {
return Array.from(this.validTypes);
}
const out = new Set();
for ( const type of types ) {
if ( this.validTypes.has(type) ) {
out.add(type);
}
if ( type === 'image' && this.validTypes.has('imageset') ) {
out.add('imageset');
}
if ( type === 'sub_frame' ) {
out.add('object');
}
}
return Array.from(out);
}
processCanonicalName(hn, cn, details) {
const hnBeg = details.url.indexOf(hn);
if ( hnBeg === -1 ) { return; }
const oldURL = details.url;
let newURL = oldURL.slice(0, hnBeg) + cn;
const hnEnd = hnBeg + hn.length;
if ( this.cnameReplayFullURL ) {
newURL += oldURL.slice(hnEnd);
} else {
const pathBeg = oldURL.indexOf('/', hnEnd);
if ( pathBeg !== -1 ) {
newURL += oldURL.slice(hnEnd, pathBeg + 1);
}
}
details.url = newURL;
details.aliasURL = oldURL;
return super.onBeforeSuspendableRequest(details);
}
recordCanonicalName(hn, record) {
let cname =
typeof record.canonicalName === 'string' &&
record.canonicalName !== hn
? record.canonicalName
: '';
if (
cname !== '' &&
this.cnameIgnore1stParty &&
vAPI.domainFromHostname(cname) === vAPI.domainFromHostname(hn)
) {
cname = '';
}
if (
cname !== '' &&
this.cnameIgnoreList !== null &&
this.cnameIgnoreList.test(cname)
) {
cname = '';
}
this.cnames.set(hn, cname);
if ( this.cnameTimer === undefined ) {
this.cnameTimer = self.setTimeout(
( ) => {
this.cnameTimer = undefined;
this.cnames.clear(); this.cnames.set('', '');
},
this.cnameMaxTTL * 60000
);
}
return cname;
}
regexFromStrList(list) {
if (
typeof list !== 'string' ||
list.length === 0 ||
list === 'unset' ||
browser.dns instanceof Object === false
) {
return null;
}
if ( list === '*' ) {
return /^./;
}
return new RegExp(
'(?:^|\.)(?:' +
list.trim()
.split(/\s+/)
.map(a => a.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
.join('|') +
')$'
);
}
onBeforeSuspendableRequest(details) {
const r = super.onBeforeSuspendableRequest(details);
if ( this.canRevealCNAME === false ) { return r; }
if ( r !== undefined ) {
if ( r.cancel === false ) { return; }
if (
r.cancel === true ||
r.redirectUrl !== undefined ||
this.cnameIgnoreExceptions
) {
return r;
}
}
if (
details.type === 'main_frame' &&
this.cnameIgnoreRootDocument
) {
return;
}
const hn = vAPI.hostnameFromNetworkURL(details.url);
const cname = this.cnames.get(hn);
if ( cname === '' ) { return; }
if ( cname !== undefined ) {
return this.processCanonicalName(hn, cname, details);
}
return browser.dns.resolve(hn, [ 'canonical_name' ]).then(
rec => {
const cname = this.recordCanonicalName(hn, rec);
if ( cname === '' ) { return; }
return this.processCanonicalName(hn, cname, details);
},
( ) => {
this.cnames.set(hn, '');
}
);
}
suspendOneRequest(details) {
const pending = {
details: Object.assign({}, details),
resolve: undefined,
promise: undefined
};
pending.promise = new Promise(resolve => {
pending.resolve = resolve;
});
this.pendingRequests.push(pending);
return pending.promise;
}
unsuspendAllRequests() {
const pendingRequests = this.pendingRequests;
this.pendingRequests = [];
for ( const entry of pendingRequests ) {
entry.resolve(this.onBeforeSuspendableRequest(entry.details));
}
}
canSuspend() {
return true;
}
};
})();
/******************************************************************************/

@ -1,24 +0,0 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2019-present Raymond Hill
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.
You should have received a copy of the GNU General Public License
along with this program. If not, see {http://www.gnu.org/licenses/}.
Home: https://github.com/gorhill/uBlock
*/
'use strict';
const webext = browser; // jshint ignore:line

@ -1,10 +0,0 @@
{
"sidebar_action": {
"default_title": "__MSG_loggerPageName__",
"default_panel": "logger-ui.html",
"default_icon": {
"16": "img/icon_16.png",
"128": "img/icon_128.png"
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,20 +1,16 @@
{
"extName": {
"message": "nuTensor",
"message": "uMatrix",
"description": ""
},
"extShortDesc": {
"message": "Point & click to forbid/allow any class of requests made by your browser. A fork of Raymond Hill's uMatrix.",
"message": "Point & click to forbid/allow any class of requests made by your browser. Use it to block scripts, iframes, ads, facebook, etc.",
"description": "this will be used as short description in web stores: MUST BE 132 characters OR LESS"
},
"dashboardPageName": {
"message": "nuTensor — Dashboard",
"message": "uMatrix — Dashboard",
"description": ""
},
"loggerPageName": {
"message": "nuTensor — Logger",
"description": "Title for the logger window"
},
"settingsPageName": {
"message": "Settings",
"description": "a tab in dashboard"
@ -32,11 +28,7 @@
"description": "a tab in dashboard"
},
"ubiquitousRulesPageName" : {
"message": "Assets",
"description": "a tab in dashboard"
},
"rawSettingsPageName": {
"message": "More",
"message": "Hosts files",
"description": "a tab in dashboard"
},
"aboutPageName": {
@ -61,10 +53,6 @@
"message": "image",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"mediaPrettyName": {
"message": "media",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"pluginPrettyName": {
"message": "plugin",
"description": "HAS TO FIT IN MATRIX HEADER!"
@ -73,8 +61,8 @@
"message": "script",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"fetchPrettyName": {
"message": "fetch",
"xhrPrettyName": {
"message": "XHR",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"framePrettyName": {
@ -91,28 +79,20 @@
"message": "No net traffic seen for this tab so far.",
"description": ""
},
"matrixLocalScopeTip" : {
"message": "Select a local scope to see/create rules which apply only in that scope",
"description": "Tool tip for the local scope button"
},
"matrixGlobalScopeTip" : {
"message": "Select the global scope to see/create rules which apply everywhere",
"description": "Tool tip for the global scope button"
},
"matrixMtxButtonTip" : {
"message": "Disable/enable matrix filtering for this scope",
"message": "Disable/enable matrix filtering for this scope.",
"description": "Tool tip for matrix button"
},
"matrixPersistButtonTip" : {
"message": "Save all temporary changes for this scope",
"message": "Save all temporary changes for this scope.",
"description": "Tool tip for the persist button"
},
"matrixRevertButtonTip" : {
"message": "Revert temporary changes for this scope",
"message": "Revert temporary changes for this scope.",
"description": "Tool tip for the revert local permission button"
},
"matrixReloadButton" : {
"message": "Reload the page. \nPress Shift to bypass the browser cache.",
"message": "Reload the page.",
"description": "Tool tip for the reload button"
},
"matrix1stPartyLabel" : {
@ -124,23 +104,15 @@
"description": "Appears in the metadata row of bottom-most group: **mind the limited width**"
},
"matrixSwitchNoMixedContent" : {
"message": "Forbid mixed content",
"message": "Strict HTTPS",
"description": "A menu entry in the matrix popup"
},
"matrixSwitchNoWorker" : {
"message": "Forbid web workers",
"matrixSwitchUASpoof" : {
"message": "User agent spoofing",
"description": "A menu entry in the matrix popup"
},
"matrixSwitchReferrerSpoof" : {
"message": "Spoof <code>Referer</code> header",
"description": "A menu entry in the matrix popup"
},
"matrixSwitchNoscriptSpoof" : {
"message": "Spoof <code><noscript></code> tags",
"description": "A menu entry in the matrix popup"
},
"matrixSwitchRevealCname" : {
"message": "Reveal canonical names",
"message": "Referrer spoofing",
"description": "A menu entry in the matrix popup"
},
"matrixRevertAllEntry" : {
@ -155,21 +127,9 @@
"message": "Go to dashboard",
"description": "A menu entry in the matrix popup"
},
"matrixNoTabFound" : {
"message": "No web page found",
"description": "Displays in place of matrix when no data is found for the current page"
},
"matrixRecipeImportTip" : {
"message": "Import rules",
"description": "Used as a tooltip for the recipe import button"
},
"matrixRecipeSaveTip" : {
"message": "Save rules",
"description": "Used as a tooltip for the recipe padlock button"
},
"statsPageTitle" : {
"message": "nuTensor &ndash; Statistics",
"message": "uMatrix &ndash; Statistics",
"description": ""
},
"statsPageGenericStats" : {
@ -185,7 +145,7 @@
"description": ""
},
"statsPageHyperlinkAuditingFoiled" : {
"message": "<a href='https://html.spec.whatwg.org/multipage/semantics.html#hyperlink-auditing'>Hyperlink auditing</a> attempts foiled: {{count}}",
"message": "<a href='http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing'>Hyperlink auditing</a> attempts foiled: {{count}}",
"description": ""
},
"statsPageCookiesRemoved" : {
@ -277,180 +237,38 @@
"description": "First part of Remember the last [n] HTTP requests per page"
},
"statsPageLogSizePrompt2" : {
"message": "HTTP requests <b>per page</b>",
"message": "HTTP requests <b>per page</b>.",
"description": "Second part of Remember the last [n] HTTP requests per page"
},
"statsPageLogSizeHelp" : {
"message": "<p>You can inspect details of the most recent raw HTTP requests which have been made by a web page (see below).</p><p>This is mostly useful to advanced users who want to investigate exactly what a web page has been doing. But logging these HTTP requests requires memory, and if you don't care about this technical information, then memory is being wasted.</p><p>Hence this field which lets you adjust the maximum number of the most recent HTTP requests which are to be logged for further inspection.</p><p>Enter &ldquo;<code>0</code>&rdquo; to turn off detailed logging (and consequently reduce the memory footprint of <i>nuTensor</i>).</p>",
"message": "<p>You can inspect details of the most recent raw HTTP requests which have been made by a web page (see below).</p><p>This is mostly useful to advanced users who want to investigate exactly what a web page has been doing. But logging these HTTP requests requires memory, and if you don't care about this technical information, then memory is being wasted.</p><p>Hence this field which lets you adjust the maximum number of the most recent HTTP requests which are to be logged for further inspection.</p><p>Enter &ldquo;<code>0</code>&rdquo; to turn off detailed logging (and consequently reduce the memory footprint of <i>uMatrix</i>).</p>",
"description": "To help user understand the purpose of the log size value"
},
"statsPageRefresh" : {
"message": "Refresh",
"description": ""
},
"logAll":{
"message":"All",
"description":"Appears in the logger's tab selector"
},
"logBehindTheScene":{
"message":"Tabless",
"description":"Pretty name for behind-the-scene network requests"
},
"loggerCurrentTab":{
"message":"Current tab",
"description":"Appears in the logger's tab selector"
},
"loggerReloadTip":{
"message":"Reload the tab content",
"description":"Tooltip for the reload button in the logger page"
},
"loggerFilterInputPlaceholder" : {
"message": "filter expression(s)",
"description": "Appears in the input filed where filter expressions are entered"
},
"loggerEntryCookieDeleted" : {
"message": "cookie deleted: {{value}}",
"description": "An entry for when a cookie is deleted"
},
"loggerEntryDeleteCookieError" : {
"message": "failed to delete cookie: {{value}}",
"description": "An entry for when the browser cache is cleared"
},
"loggerEntryBrowserCacheCleared" : {
"message": "browser cache cleared",
"description": "An entry for when a cookie can't be deleted"
},
"loggerEntryAssetUpdated" : {
"message": "asset updated: {{value}}",
"description": "An entry for when an asset was updated"
},
"loggerRowFiltererButtonTip":{
"message":"Toggle logger filtering",
"description":"Tooltip for the row filterer button in the logger page"
},
"logFilterPrompt":{
"message":"filter logger content",
"description": "Placeholder string for logger output filtering input field"
},
"loggerPopupPanelTip":{
"message":"Toggle the popup panel",
"description":"Tooltip for the popup panel button in the logger page"
},
"loggerInfoTip":{
"message":"uBlock Origin wiki: The logger",
"description":"Tooltip for the top-right info label in the logger page"
},
"loggerClearTip":{
"message":"Clear logger",
"description":"Tooltip for the eraser in the logger page; used to blank the content of the logger"
},
"loggerPauseTip":{
"message":"Pause logger (discard all incoming data)",
"description":"Tooltip for the pause button in the logger page"
},
"loggerUnpauseTip":{
"message":"Unpause logger",
"description":"Tooltip for the play button in the logger page"
},
"loggerRowFiltererBuiltinTip":{
"message":"Logger filtering options",
"description":"Tooltip for the button to bring up logger output filtering options"
},
"loggerRowFiltererBuiltinNot":{
"message":"Not",
"description":"A keyword in the built-in row filtering expression"
},
"loggerRowFiltererBuiltinBlocked":{
"message":"blocked",
"description":"A keyword in the built-in row filtering expression"
},
"loggerRowFiltererBuiltinInfo":{
"message":"info",
"description":"A keyword in the built-in row filtering expression"
},
"loggerRowFiltererBuiltin1p":{
"message":"1st-party",
"description":"A keyword in the built-in row filtering expression"
},
"loggerRowFiltererBuiltin3p":{
"message":"3rd-party",
"description":"A keyword in the built-in row filtering expression"
},
"loggerEntryDetailsHeader":{
"message":"Details",
"description":"Small header to identify the 'Details' pane for a specific logger entry"
},
"loggerEntryDetailsContext":{
"message":"Context",
"description":"Label to identify a context field (typically a hostname)"
},
"loggerEntryDetailsPartyness":{
"message":"Partyness",
"description":"Label to identify a field providing partyness information"
},
"loggerEntryDetailsType":{
"message":"Type",
"description":"Label to identify the type of an entry"
},
"loggerEntryDetailsURL":{
"message":"URL",
"description":"Label to identify the URL of an entry"
},
"loggerEntryRuleHeader":{
"message":"Rule",
"description":"Small header to identify the 'Rule' pane for a specific logger entry"
},
"loggerSettingDiscardPrompt":{
"message":"Logger entries which do not fulfill all three conditions below will be automatically discarded:",
"description":"Logger setting: A sentence to describe the purpose of the settings below"
},
"loggerSettingPerEntryMaxAge":{
"message":"Preserve entries from the last {{input}} minutes",
"description":"A logger setting"
},
"loggerSettingPerTabMaxLoads":{
"message":"Preserve at most {{input}} page loads per tab",
"description":"A logger setting"
},
"loggerSettingPerTabMaxEntries":{
"message":"Preserve at most {{input}} entries per tab",
"description":"A logger setting"
},
"loggerSettingPerEntryLineCount":{
"message":"Use {{input}} lines per entry in vertically expanded mode",
"description":"A logger setting"
},
"loggerExportFormatList":{
"message":"List",
"description":"Label for radio-button to pick export format"
},
"loggerExportFormatTable":{
"message":"Table",
"description":"Label for radio-button to pick export format"
},
"loggerExportEncodePlain":{
"message":"Plain",
"description":"Label for radio-button to pick export text format"
},
"loggerExportEncodeMarkdown":{
"message":"Markdown",
"description":"Label for radio-button to pick export text format"
},
"settingsPageTitle" : {
"message": "nuTensor &ndash; Settings",
"message": "uMatrix &ndash; Settings",
"description": ""
},
"settingsMatrixDisplayHeader" : {
"message": "Matrix",
"description": "header for matrix settings used in Settings page"
"message": "Appearance",
"description": ""
},
"settingsMatrixDisplayTextSizePrompt" : {
"message": "Text size:",
"description": ""
},
"settingsIconBadgeEnabled":{
"message":"Show the number of blocked resources on the icon",
"description":""
"settingsMatrixDisplayTextSizeNormal" : {
"message": "Normal",
"description": ""
},
"settingsMatrixDisplayTextSizeLarge" : {
"message": "Large",
"description": ""
},
"settingsMatrixDisplayColorBlind" : {
"message": "Color-blind friendly",
@ -460,53 +278,54 @@
"message": "Convenience",
"description": "English: Convenience"
},
"settingsDefaultScopeLevel" : {
"message": "Default scope level:",
"description": "Label for default scope level selector in Settings pane"
"settingsMatrixAutoReloadPrompt" : {
"message": "When the matrix is closed, smart reload these tabs:",
"description": ""
},
"settingsDefaultScopeLevel0" : {
"message": "Global",
"description": "Scope will be global"
"settingsMatrixAutoReloadNone" : {
"message": "None",
"description": ""
},
"settingsDefaultScopeLevel1" : {
"message": "Domain",
"description": "Scope will be base domain"
"settingsMatrixAutoReloadCurrent" : {
"message": "Current",
"description": ""
},
"settingsDefaultScopeLevel2" : {
"message": "Site",
"description": "Scope will be full hostname of site"
"settingsMatrixAutoReloadAll" : {
"message": "All",
"description": ""
},
"settingsCollapseBlocked" : {
"message": "Hide placeholder of blocked elements",
"description": "A setting in the dashboard's Settings pane"
"settingsMatrixAutoReloadInfo" : {
"message": "Whenever you make changes in the matrix which can affect the display and/or behavior of one or more pages, <i>uMatrix</i> will reload affected pages automatically when you close the matrix.",
"description": ""
},
"settingsCollapseBlacklisted" : {
"message": "Hide placeholder of blacklisted elements",
"description": "A setting in the dashboard's Settings pane: 'blacklisted' means 'for which there is a specific block rule', 'specific' means 'a rule for which the destination hostname is not `*`'"
"settingsSubframeColor" : {
"message": "Blocked frames:&ensp;Color",
"description": "English: Blocked frames:&ensp;Color"
},
"settingsNoscriptTagsSpoofed" : {
"message": "Spoof <code><noscript></code> tags when 1st-party scripts are blocked",
"description": "This appears in the Settings pane in the dashboard"
"settingsSubframeOpacity" : {
"message": "Opacity",
"description": "English: Opacity"
},
"settingsCloudStorageEnabled" : {
"message": "Enable cloud storage support",
"description": ""
"settingsIconBadgeEnabled":{
"message":"Show the number of distinct requests on the icon",
"description":"English: Show the number of distinct requests on the icon"
},
"settingsMatrixNoTooltips" : {
"message": "Disable tooltips",
"description": ""
"settingsCollapseBlocked" : {
"message": "Collapse placeholder of blocked elements",
"description": "English: Collapse placeholder of blocked elements"
},
"privacyPageTitle" : {
"message": "nuTensor &ndash; Privacy",
"message": "uMatrix &ndash; Privacy",
"description": ""
},
"privacyDeleteBlockedCookiesPrompt" : {
"message": "Delete blocked cookies",
"message": "Delete blocked cookies.",
"description": ""
},
"privacyDeleteBlockedCookiesHelp" : {
"message": "<p>Blacklisted cookies are not prevented by <i>nuTensor</i> from entering your browser. However they are prevented from leaving your browser, which is what really matters. Not blocking cookies before they enter your browser gives you the opportunity to be informed that a site tried to use cookies, and furthermore to inspect their contents if you wish.</p><p>Once these blacklisted cookies have been accounted for by <i>nuTensor</i>, they can be removed from your browser if you wish so.</p><p><b>Important note:</b> Extensions can make web requests during the course of their normal operation. These requests can result in cookies being created in the browser. If the hostname from where a cookie originate is not whitelisted, the cookie will be removed from the browser by <i>nuTensor</i> if this option is checked. So be sure that the hostname(s) with which an extension communicate is whitelisted.</p>",
"message": "<p>Blacklisted cookies are not prevented by <i>uMatrix</i> from entering your browser. However they are prevented from leaving your browser, which is what really matters. Not blocking cookies before they enter your browser gives you the opportunity to be informed that a site tried to use cookies, and furthermore to inspect their contents if you wish.</p><p>Once these blacklisted cookies have been accounted for by <i>uMatrix</i>, they can be removed from your browser if you wish so.</p><p><b>Important note:</b> Extensions can make web requests during the course of their normal operation. These requests can result in cookies being created in the browser. If the hostname from where a cookie originate is not whitelisted, the cookie will be removed from the browser by <i>uMatrix</i> if this option is checked. So be sure that the hostname(s) with which an extension communicate is whitelisted.</p>",
"description": ""
},
"privacyDeleteNonBlockedSessionCookiesPrompt1" : {
@ -514,7 +333,7 @@
"description": "First part of 'Delete non-blocked session cookies [n] minutes after the last time they have been used'"
},
"privacyDeleteNonBlockedSessionCookiesPrompt2" : {
"message": " minutes after the last time they have been used",
"message": " minutes after the last time they have been used.",
"description": "Second part of 'Delete non-blocked session cookies [n] minutes after the last time they have been used'"
},
"privacyDeleteNonBlockedSessionCookiesHelp" : {
@ -534,23 +353,23 @@
"description": "First part of 'Clear browser cache every [n] minutes'"
},
"privacyClearCachePrompt2" : {
"message": "minutes",
"message": "minutes.",
"description": "Second part of 'Clear browser cache every [n] minutes'"
},
"privacyClearCacheHelp" : {
"message": "<p>Some web sites are really bent on tracking you, so much that they will use not-so-nice tricks to work around whatever measures you take in order to not be tracked.</p><p>A few of these tricks rely<sup>[1, 2]</sup> on the <a href='https://en.wikipedia.org/wiki/Web_cache'>browser cache</a>, which content is often long lasting since rarely will users take the time to regularly clear their browser cache.</p><p>There is little inconvenience to clear the browser cache regularly (likelihood is that you won't notice when it happens), and the benefit is to prevent these obnoxious trackers from invading your privacy.</p><p>Check this option to have <i>nuTensor</i> do it for you, at the interval you wish.</p><p>[1] <a href='https://grepular.com/Preventing_Web_Tracking_via_the_Browser_Cache'>&ldquo;Preventing Web Tracking via the Browser Cache&rdquo;</a>\n[2] <a href='http://lucb1e.com/rp/cookielesscookies/'>&ldquo;Cookieless cookies&rdquo;</a></p>",
"message": "<p>Some web sites are really bent on tracking you, so much that they will use not-so-nice tricks to work around whatever measures you take in order to not be tracked.</p><p>A few of these tricks rely<sup style='font-size:smaller'>[1, 2]</sup> on the <a href='https://en.wikipedia.org/wiki/Web_cache'>browser cache</a>, which content is often long lasting since rarely will users take the time to regularly clear their browser cache.</p><p>There is little inconvenience to clear the browser cache regularly (likelihood is that you won't notice when it happens), and the benefit is to prevent these obnoxious trackers from invading your privacy.</p><p>Check this option to have <i>uMatrix</i> do it for you, at the interval you wish.</p><p style='font-size:smaller'>[1] <a href='https://grepular.com/Preventing_Web_Tracking_via_the_Browser_Cache'>&ldquo;Preventing Web Tracking via the Browser Cache&rdquo;</a><br>[2] <a href='http://lucb1e.com/rp/cookielesscookies/'>&ldquo;Cookieless cookies&rdquo;</a></p>",
"description": ""
},
"privacyProcessRefererPrompt" : {
"message": "Spoof <a href='https://en.wikipedia.org/wiki/HTTP_referer'>HTTP referrer</a> string of third-party requests",
"message": "Spoof <a href='https://en.wikipedia.org/wiki/HTTP_referer'>HTTP referrer</a> string of third-party requests.",
"description": ""
},
"privacyProcessRefererHelp" : {
"message": "From Wikipedia:<blockquote>HTTP referer is an HTTP header field that identifies the address of the webpage that linked to the resource being requested. ... <b>Because referer information can violate privacy, some web browsers allow the user to disable the sending of referer information.</b></blockquote>If this setting is checked, <i>nuTensor</i> will spoof the HTTP referrer information if the domain name of the HTTP referrer is third-party to the domain name of net request.",
"message": "<p>From Wikipedia:</p><blockquote>HTTP referer is an HTTP header field that identifies the address of the webpage that linked to the resource being requested. ... <b>Because referer information can violate privacy, some web browsers allow the user to disable the sending of referer information.</b></blockquote><p>If this setting is checked, <i>uMatrix</i> will spoof the HTTP referrer information if the domain name of the HTTP referrer is third-party to the domain name of net request.",
"description": ""
},
"privacyNoMixedContentPrompt" : {
"message": "Strict HTTPS: forbid mixed content",
"message": "Strict HTTPS: forbid mixed content.",
"description": ""
},
"privacyNoMixedContentHelp" : {
@ -558,13 +377,33 @@
"description": ""
},
"privacyProcessHyperlinkAuditingPrompt" : {
"message": "Block all <a href='https://html.spec.whatwg.org/multipage/semantics.html#hyperlink-auditing'>hyperlink auditing</a> attempts",
"message": "Block all <a href='http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing'>hyperlink auditing</a> attempts.",
"description": ""
},
"privacyProcessHyperlinkAuditingHelp" : {
"message": "<p>Hyperlink auditing is a mechanism which allow a party, <b>any party</b>, to be informed about which link a user clicked on a particular web page. It is essentially a tracking feature: it allows a web site, or any third-party to that web site, to be informed about which link you clicked on which one of its web pages. The sole purpose is to track your browsing activity.</p>",
"description": ""
},
"privacySpoofUserAgentPrompt1" : {
"message": "Spoof <a href='https://en.wikipedia.org/wiki/User_agent'>User-Agent</a> string by randomly picking a new one below every",
"description": "First part of UA-spoofing prompt"
},
"privacySpoofUserAgentPrompt2" : {
"message": "minutes.",
"description": "Second part"
},
"privacySpoofUserAgentHelp" : {
"message": "<a href='https://www.eff.org/deeplinks/2010/01/tracking-by-user-agent'>According to the <i>Electronic Frontier Foundation</i></a>: &ldquo;[...] your browser sends a &lsquo;User Agent&rsquo; header to the website saying precisely which operating system and web browser you are using. This information could help distinguish Internet users from one another because these versions differ, often considerably, from person to person. [...] <b>the User Agent string becomes a real privacy problem</b>.&rdquo;<p>This option allows you to address the privacy issue raised by the EFF.</p><p>You can supply your own list of user agent strings. One string per line. Blank lines and lines prefixed with &lsquo;#&rsquo; will be ignored.</p>",
"description": ""
},
"privacyBehindTheSceneHeader" : {
"message": "Behind-the-scene requests",
"description": ""
},
"privacyProcessBehindTheSceneHelp" : {
"message": "",
"description": ""
},
"userRulesPermanentHeader": {
@ -613,10 +452,6 @@
},
"assetsHostsSection" : {
"message": "Hosts files",
"description": "header to identify the hosts files section"
},
"hostsFilesPrompt" : {
"message": "All hostnames in a hosts file are loaded as blacklisted hostnames in the global scope.",
"description": ""
@ -638,7 +473,7 @@
"description": ""
},
"hostsFilesAutoUpdatePrompt":{
"message":"Auto-update assets",
"message":"Auto-update hosts files.",
"description":""
},
"hostsFilesUpdateNow":{
@ -650,7 +485,7 @@
"description":""
},
"hostsFilesExternalListsHint":{
"message":"Import external assets here: \nOne URL per line; invalid URLs will be silently ignored.",
"message":"One URL per line. Lines prefixed with &lsquo;#&rsquo; will be ignored. Invalid URLs will be silently ignored.",
"description":""
},
"hostsFilesExternalListsParse":{
@ -669,34 +504,10 @@
"message":"outdated",
"description":""
},
"assetsRecipesSection" : {
"message": "Ruleset recipes",
"description": "header to identify the ruleset files section"
},
"assetsRecipesSummary" : {
"message": "Ruleset recipes are imported from the popup panel <em>on demand</em>, i.e. <b>only</b> through user interaction.",
"description": ""
},
"assetsImportLabel" : {
"message": "Import...",
"description": ""
},
"assetsInlineHostsLabel": {
"message": "My hosts",
"description": ""
},
"assetsInlineRecipesLabel": {
"message": "My recipes",
"description": ""
},
"rawSettingsWarning" : {
"message": "Warning! Change these raw configuration settings at your own risk.",
"description": ""
},
"aboutChangelog" : {
"message": "<a href='https://github.com/geekprojects/nuTensor/releases'>Change log</a>",
"message": "<a href='https://github.com/gorhill/uMatrix/releases'>Change log</a>",
"description": ""
},
"aboutStorageUsed" : {
@ -704,11 +515,11 @@
"description": ""
},
"aboutDoc" : {
"message": "<a href='https://github.com/geekprojects/nuTensor/wiki'>Documentation</a>",
"message": "<a href='https://github.com/gorhill/uMatrix/wiki'>Documentation</a>",
"description": ""
},
"aboutPermissions" : {
"message": "<a href='https://github.com/geekprojects/nuTensor/wiki/Permissions'>Permissions</a>",
"message": "<a href='https://github.com/gorhill/httpswitchboard/wiki/Permissions'>Permissions</a>",
"description": ""
},
"aboutCode" : {
@ -716,8 +527,8 @@
"description": ""
},
"aboutIssues" : {
"message": "Issue tracker",
"description": "Text for a link to official issue tracker"
"message": "Bugs and issues",
"description": ""
},
"aboutContributors":{
"message":"Contributors",
@ -740,7 +551,7 @@
"description": ""
},
"aboutBackupButton" : {
"message": "Back up to file...",
"message": "Backup to file...",
"description": ""
},
"aboutBackupFilename" : {
@ -752,7 +563,7 @@
"description": ""
},
"aboutRestoreConfirm" : {
"message": "All your settings will be overwritten using data backed up on {{time}}, and nuTensor will restart.\n\nOverwrite all existing settings using backed up data?",
"message": "All your settings will be overwritten using data backed up on {{time}}, and uMatrix will restart.\n\nOverwrite all existing settings using backed up data?",
"description": "Message asking user to confirm restore"
},
"aboutRestoreError" : {
@ -772,18 +583,39 @@
"description": "Message asking user to confirm reset"
},
"loggerFilterInputPlaceholder" : {
"message": "filter expression(s)",
"description": "Appears in the input filed where filter expressions are entered"
},
"loggerEntryUserAgentSpoofing" : {
"message": "spoofing user agent with: {{value}}",
"description": "An entry for when a new user agent string is selected"
},
"loggerEntryCookieDeleted" : {
"message": "cookie deleted: {{value}}",
"description": "An entry for when a cookie is deleted"
},
"loggerEntryDeleteCookieError" : {
"message": "failed to delete cookie: {{value}}",
"description": "An entry for when the browser cache is cleared"
},
"loggerEntryBrowserCacheCleared" : {
"message": "browser cache cleared",
"description": "An entry for when a cookie can't be deleted"
},
"loggerEntryAssetUpdated" : {
"message": "asset updated: {{value}}",
"description": "An entry for when an asset was updated"
},
"mainBlockedPrompt1": {
"message": "nuTensor has prevented the following page from loading:",
"description": "English: nuTensor has prevented the following page from loading:"
"message": "uMatrix has prevented the following page from loading:",
"description": "English: uMatrix has prevented the following page from loading:"
},
"mainBlockedPrompt2": {
"message": "Because of the following rule",
"description": "English: Because of the following rule"
},
"mainBlockedNoParamsPrompt": {
"message": "without parameters",
"description": "label to be used for the parameter-less URL: https://cloud.githubusercontent.com/assets/585534/9832014/bfb1b8f0-593b-11e5-8a27-fba472a5529a.png"
},
"mainBlockedBack" : {
"message": "Go back",
"description": "English: Go back"
@ -844,42 +676,8 @@
"description":"Appears in Firefox's add-on preferences"
},
"cloudPush": {
"message": "Export to cloud storage",
"description": "tooltip"
},
"cloudPull": {
"message": "Import from cloud storage",
"description": "tooltip"
},
"cloudNoData": {
"message": "...\n...",
"description": ""
},
"cloudDeviceNamePrompt": {
"message": "This device name:",
"description": "used as a prompt for the user to provide a custom device name"
},
"genericSubmit": {
"message": "Submit",
"description": "for generic 'submit' buttons"
},
"genericRevert": {
"message": "Revert",
"description": "for generic 'revert' buttons"
},
"errorCantConnectTo":{
"message":"Network error: Unable to connect to {{url}}",
"description":""
},
"genericApplyChanges": {
"message": "Apply changes",
"description": "for generic 'Apply changes' buttons"
},
"genericCopyToClipboard":{
"message":"Copy to clipboard",
"description":"Label for buttons used to copy something to the clipboard"
}
}

@ -1,866 +0,0 @@
{
"extName": {
"message": "nuTensor",
"description": ""
},
"extShortDesc": {
"message": "Point & click to forbid/allow any class of requests made by your browser. Use it to block scripts, iframes, ads, facebook, etc.",
"description": "this will be used as short description in web stores: MUST BE 132 characters OR LESS"
},
"dashboardPageName": {
"message": "nuTensor — Panelo",
"description": ""
},
"loggerPageName": {
"message": "nuTensor — Logger",
"description": "Title for the logger window"
},
"settingsPageName": {
"message": "Agordoj",
"description": "a tab in dashboard"
},
"privacyPageName": {
"message": "Privateco",
"description": "a tab in dashboard"
},
"statsPageName": {
"message": "Statistics",
"description": "a tab in dashboard"
},
"userRulesPageName": {
"message": "Miaj reguloj",
"description": "a tab in dashboard"
},
"ubiquitousRulesPageName": {
"message": "Assets",
"description": "a tab in dashboard"
},
"rawSettingsPageName": {
"message": "More",
"description": "a tab in dashboard"
},
"aboutPageName": {
"message": "Pri",
"description": "a tab in dashboard"
},
"allPrettyName": {
"message": "all",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"cookiePrettyName": {
"message": "kuketo",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"cssPrettyName": {
"message": "css",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"imagePrettyName": {
"message": "bildo",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"mediaPrettyName": {
"message": "media",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"pluginPrettyName": {
"message": "kromaĵo",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"scriptPrettyName": {
"message": "skripto",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"fetchPrettyName": {
"message": "fetch",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"framePrettyName": {
"message": "kadro",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"otherPrettyName": {
"message": "alia",
"description": "HAS TO FIT IN MATRIX HEADER!"
},
"matrixNoNetTrafficPrompt": {
"message": "No net traffic seen for this tab so far.",
"description": ""
},
"matrixLocalScopeTip": {
"message": "Select a local scope to see/create rules which apply only in that scope",
"description": "Tool tip for the local scope button"
},
"matrixGlobalScopeTip": {
"message": "Select the global scope to see/create rules which apply everywhere",
"description": "Tool tip for the global scope button"
},
"matrixMtxButtonTip": {
"message": "Disable/enable matrix filtering for this scope",
"description": "Tool tip for matrix button"
},
"matrixPersistButtonTip": {
"message": "Save all temporary changes for this scope",
"description": "Tool tip for the persist button"
},
"matrixRevertButtonTip": {
"message": "Revert temporary changes for this scope",
"description": "Tool tip for the revert local permission button"
},
"matrixReloadButton": {
"message": "Reŝargi la paĝon.",
"description": "Tool tip for the reload button"
},
"matrix1stPartyLabel": {
"message": "1st-party",
"description": "1st-party"
},
"matrixBlacklistedHostnames": {
"message": "{{count}} blacklisted hostname(s)",
"description": "Appears in the metadata row of bottom-most group: **mind the limited width**"
},
"matrixSwitchNoMixedContent": {
"message": "Forbid mixed content",
"description": "A menu entry in the matrix popup"
},
"matrixSwitchNoWorker": {
"message": "Forbid web workers",
"description": "A menu entry in the matrix popup"
},
"matrixSwitchReferrerSpoof": {
"message": "Spoof <code>Referer</code> header",
"description": "A menu entry in the matrix popup"
},
"matrixSwitchNoscriptSpoof": {
"message": "Spoof <code><noscript></code> tags",
"description": "A menu entry in the matrix popup"
},
"matrixSwitchRevealCname": {
"message": "Reveal canonical names",
"description": "A menu entry in the matrix popup"
},
"matrixRevertAllEntry": {
"message": "Revert all temporary changes",
"description": "A menu entry in the matrix popup"
},
"matrixLoggerMenuEntry": {
"message": "Iri al protokolilo",
"description": "A menu entry in the matrix popup"
},
"matrixDashboardMenuEntry": {
"message": "Iri al panelo",
"description": "A menu entry in the matrix popup"
},
"matrixNoTabFound": {
"message": "No web page found",
"description": "Displays in place of matrix when no data is found for the current page"
},
"matrixRecipeImportTip": {
"message": "Import rules",
"description": "Used as a tooltip for the recipe import button"
},
"matrixRecipeSaveTip": {
"message": "Save rules",
"description": "Used as a tooltip for the recipe padlock button"
},
"statsPageTitle": {
"message": "nuTensor &ndash; Statistics",
"description": ""
},
"statsPageGenericStats": {
"message": "Generic statistics",
"description": ""
},
"statsPageCookieHeadersFoiled": {
"message": "<a href='https://en.wikipedia.org/wiki/HTTP_cookie'>HTTP cookie</a> headers foiled: {{count}}",
"description": ""
},
"statsPageRefererHeadersFoiled": {
"message": "<a href='https://en.wikipedia.org/wiki/HTTP_referer'>HTTP referer</a> headers foiled: {{count}}",
"description": ""
},
"statsPageHyperlinkAuditingFoiled": {
"message": "<a href='https://html.spec.whatwg.org/multipage/semantics.html#hyperlink-auditing'>Hyperlink auditing</a> attempts foiled: {{count}}",
"description": ""
},
"statsPageCookiesRemoved": {
"message": "Lokaj kuketoj forigitaj: {{count}}",
"description": ""
},
"statsPageLocalStoragesCleared": {
"message": "<a href='http://diveintohtml5.info/storage.html'>Lokaj konservadoj</a> malplenigitaj: {{count}}",
"description": ""
},
"statsPageBrowserCacheCleared": {
"message": "Browser caches cleared: {{count}}",
"description": ""
},
"statsPageDetailedStats": {
"message": "Detailed statistics",
"description": ""
},
"statsPageDetailedAllPages": {
"message": "All",
"description": ""
},
"statsPageDetailedBehindTheScenePage": {
"message": "Behind the scene",
"description": ""
},
"statsPageOverview": {
"message": "Superrigardo",
"description": ""
},
"statsPageRequests": {
"message": "Petoj",
"description": "header for the stat type column"
},
"statsPageAllowed": {
"message": "Allowed",
"description": "header for the allowed requests column"
},
"statsPageBlocked": {
"message": "Blocked",
"description": "header for the blocked requests column"
},
"statsPageAll": {
"message": "All",
"description": ""
},
"statsPagePages": {
"message": "Paĝoj",
"description": ""
},
"statsPageCookies": {
"message": "Kuketoj",
"description": ""
},
"statsPageCSS": {
"message": "CSS",
"description": ""
},
"statsPageImages": {
"message": "Bildoj",
"description": ""
},
"statsPagePlugins": {
"message": "Kromaĵoj",
"description": ""
},
"statsPageScripts": {
"message": "Skriptoj",
"description": ""
},
"statsPageXHRs": {
"message": "XHR-oj",
"description": ""
},
"statsPageFrames": {
"message": "Kadroj",
"description": ""
},
"statsPageOthers": {
"message": "Aliaj",
"description": ""
},
"statsPageDetailed": {
"message": "Protokolilo",
"description": ""
},
"statsPageLogSizePrompt1": {
"message": "Remember the last",
"description": "First part of Remember the last [n] HTTP requests per page"
},
"statsPageLogSizePrompt2": {
"message": "HTTP requests <b>per page</b>",
"description": "Second part of Remember the last [n] HTTP requests per page"
},
"statsPageLogSizeHelp": {
"message": "<p>You can inspect details of the most recent raw HTTP requests which have been made by a web page (see below).</p><p>This is mostly useful to advanced users who want to investigate exactly what a web page has been doing. But logging these HTTP requests requires memory, and if you don't care about this technical information, then memory is being wasted.</p><p>Hence this field which lets you adjust the maximum number of the most recent HTTP requests which are to be logged for further inspection.</p><p>Enter &ldquo;<code>0</code>&rdquo; to turn off detailed logging (and consequently reduce the memory footprint of <i>nuTensor</i>).</p>",
"description": "To help user understand the purpose of the log size value"
},
"statsPageRefresh": {
"message": "Aktualigi",
"description": ""
},
"logAll": {
"message": "All",
"description": "Appears in the logger's tab selector"
},
"logBehindTheScene": {
"message": "Tabless",
"description": "Pretty name for behind-the-scene network requests"
},
"loggerCurrentTab": {
"message": "Current tab",
"description": "Appears in the logger's tab selector"
},
"loggerReloadTip": {
"message": "Reload the tab content",
"description": "Tooltip for the reload button in the logger page"
},
"loggerFilterInputPlaceholder": {
"message": "filter expression(s)",
"description": "Appears in the input filed where filter expressions are entered"
},
"loggerEntryCookieDeleted": {
"message": "kuketo forigita: {{value}}",
"description": "An entry for when a cookie is deleted"
},
"loggerEntryDeleteCookieError": {
"message": "failed to delete cookie: {{value}}",
"description": "An entry for when the browser cache is cleared"
},
"loggerEntryBrowserCacheCleared": {
"message": "browser cache cleared",
"description": "An entry for when a cookie can't be deleted"
},
"loggerEntryAssetUpdated": {
"message": "asset updated: {{value}}",
"description": "An entry for when an asset was updated"
},
"loggerRowFiltererButtonTip": {
"message": "Toggle logger filtering",
"description": "Tooltip for the row filterer button in the logger page"
},
"logFilterPrompt": {
"message": "filter logger content",
"description": "Placeholder string for logger output filtering input field"
},
"loggerPopupPanelTip": {
"message": "Toggle the popup panel",
"description": "Tooltip for the popup panel button in the logger page"
},
"loggerInfoTip": {
"message": "uBlock Origin wiki: The logger",
"description": "Tooltip for the top-right info label in the logger page"
},
"loggerClearTip": {
"message": "Clear logger",
"description": "Tooltip for the eraser in the logger page; used to blank the content of the logger"
},
"loggerPauseTip": {
"message": "Pause logger (discard all incoming data)",
"description": "Tooltip for the pause button in the logger page"
},
"loggerUnpauseTip": {
"message": "Unpause logger",
"description": "Tooltip for the play button in the logger page"
},
"loggerRowFiltererBuiltinTip": {
"message": "Logger filtering options",
"description": "Tooltip for the button to bring up logger output filtering options"
},
"loggerRowFiltererBuiltinNot": {
"message": "Not",
"description": "A keyword in the built-in row filtering expression"
},
"loggerRowFiltererBuiltinBlocked": {
"message": "blocked",
"description": "A keyword in the built-in row filtering expression"
},
"loggerRowFiltererBuiltinInfo": {
"message": "info",
"description": "A keyword in the built-in row filtering expression"
},
"loggerRowFiltererBuiltin1p": {
"message": "1st-party",
"description": "A keyword in the built-in row filtering expression"
},
"loggerRowFiltererBuiltin3p": {
"message": "3rd-party",
"description": "A keyword in the built-in row filtering expression"
},
"loggerEntryDetailsHeader": {
"message": "Details",
"description": "Small header to identify the 'Details' pane for a specific logger entry"
},
"loggerEntryDetailsContext": {
"message": "Context",
"description": "Label to identify a context field (typically a hostname)"
},
"loggerEntryDetailsPartyness": {
"message": "Partyness",
"description": "Label to identify a field providing partyness information"
},
"loggerEntryDetailsType": {
"message": "Type",
"description": "Label to identify the type of an entry"
},
"loggerEntryDetailsURL": {
"message": "URL",
"description": "Label to identify the URL of an entry"
},
"loggerEntryRuleHeader": {
"message": "Rule",
"description": "Small header to identify the 'Rule' pane for a specific logger entry"
},
"loggerSettingDiscardPrompt": {
"message": "Logger entries which do not fulfill all three conditions below will be automatically discarded:",
"description": "Logger setting: A sentence to describe the purpose of the settings below"
},
"loggerSettingPerEntryMaxAge": {
"message": "Preserve entries from the last {{input}} minutes",
"description": "A logger setting"
},
"loggerSettingPerTabMaxLoads": {
"message": "Preserve at most {{input}} page loads per tab",
"description": "A logger setting"
},
"loggerSettingPerTabMaxEntries": {
"message": "Preserve at most {{input}} entries per tab",
"description": "A logger setting"
},
"loggerSettingPerEntryLineCount": {
"message": "Use {{input}} lines per entry in vertically expanded mode",
"description": "A logger setting"
},
"loggerExportFormatList": {
"message": "List",
"description": "Label for radio-button to pick export format"
},
"loggerExportFormatTable": {
"message": "Table",
"description": "Label for radio-button to pick export format"
},
"loggerExportEncodePlain": {
"message": "Plain",
"description": "Label for radio-button to pick export text format"
},
"loggerExportEncodeMarkdown": {
"message": "Markdown",
"description": "Label for radio-button to pick export text format"
},
"settingsPageTitle": {
"message": "nuTensor &ndash; Agordoj",
"description": ""
},
"settingsMatrixDisplayHeader": {
"message": "Apero",
"description": "header for matrix settings used in Settings page"
},
"settingsMatrixDisplayTextSizePrompt": {
"message": "Tekstogrando:",
"description": ""
},
"settingsIconBadgeEnabled": {
"message": "Show the number of blocked resources on the icon",
"description": ""
},
"settingsMatrixDisplayColorBlind": {
"message": "Afabla por kolorblinduloj",
"description": ""
},
"settingsMatrixConvenienceHeader": {
"message": "Komforto",
"description": "English: Convenience"
},
"settingsDefaultScopeLevel": {
"message": "Default scope level:",
"description": "Label for default scope level selector in Settings pane"
},
"settingsDefaultScopeLevel0": {
"message": "Global",
"description": "Scope will be global"
},
"settingsDefaultScopeLevel1": {
"message": "Domain",
"description": "Scope will be base domain"
},
"settingsDefaultScopeLevel2": {
"message": "Site",
"description": "Scope will be full hostname of site"
},
"settingsCollapseBlocked": {
"message": "Hide placeholder of blocked elements",
"description": "A setting in the dashboard's Settings pane"
},
"settingsCollapseBlacklisted": {
"message": "Hide placeholder of blacklisted elements",
"description": "A setting in the dashboard's Settings pane: 'blacklisted' means 'for which there is a specific block rule', 'specific' means 'a rule for which the destination hostname is not `*`'"
},
"settingsNoscriptTagsSpoofed": {
"message": "Spoof <code><noscript></code> tags when 1st-party scripts are blocked",
"description": "This appears in the Settings pane in the dashboard"
},
"settingsCloudStorageEnabled": {
"message": "Ŝalti subtenon por nuba konservado",
"description": ""
},
"settingsMatrixNoTooltips": {
"message": "Disable tooltips",
"description": ""
},
"privacyPageTitle": {
"message": "nuTensor &ndash; Privateco",
"description": ""
},
"privacyDeleteBlockedCookiesPrompt": {
"message": "Delete blocked cookies",
"description": ""
},
"privacyDeleteBlockedCookiesHelp": {
"message": "<p>Blacklisted cookies are not prevented by <i>nuTensor</i> from entering your browser. However they are prevented from leaving your browser, which is what really matters. Not blocking cookies before they enter your browser gives you the opportunity to be informed that a site tried to use cookies, and furthermore to inspect their contents if you wish.</p><p>Once these blacklisted cookies have been accounted for by <i>nuTensor</i>, they can be removed from your browser if you wish so.</p><p><b>Important note:</b> Extensions can make web requests during the course of their normal operation. These requests can result in cookies being created in the browser. If the hostname from where a cookie originate is not whitelisted, the cookie will be removed from the browser by <i>nuTensor</i> if this option is checked. So be sure that the hostname(s) with which an extension communicate is whitelisted.</p>",
"description": ""
},
"privacyDeleteNonBlockedSessionCookiesPrompt1": {
"message": "Delete non-blocked session cookies ",
"description": "First part of 'Delete non-blocked session cookies [n] minutes after the last time they have been used'"
},
"privacyDeleteNonBlockedSessionCookiesPrompt2": {
"message": " minutes after the last time they have been used",
"description": "Second part of 'Delete non-blocked session cookies [n] minutes after the last time they have been used'"
},
"privacyDeleteNonBlockedSessionCookiesHelp": {
"message": "<p><a href='http://www.w3.org/2001/tag/2010/09/ClientSideStorage.html'>W3C</a>: &ldquo;A session cookie ... is erased when you end the browser session. The session cookie is stored in temporary memory and is not retained after the browser is closed.&rdquo;</p><p>Except that this <a href='https://code.google.com/p/chromium/issues/detail?id=128513'>might not be happening</a> in some browsers. Also, to some, having to close the browser in order for the session cookies to clear might not be early enough.</p>",
"description": ""
},
"privacyDeleteBlockedLocalStoragePrompt": {
"message": "Delete <a href='https://en.wikipedia.org/wiki/Web_storage'>local storage</a> content set by blocked hostnames",
"description": ""
},
"privacyDeleteBlockedLocalStorageHelp": {
"message": "TODO",
"description": ""
},
"privacyClearCachePrompt1": {
"message": "Clear browser cache every",
"description": "First part of 'Clear browser cache every [n] minutes'"
},
"privacyClearCachePrompt2": {
"message": "minutoj.",
"description": "Second part of 'Clear browser cache every [n] minutes'"
},
"privacyClearCacheHelp": {
"message": "<p>Some web sites are really bent on tracking you, so much that they will use not-so-nice tricks to work around whatever measures you take in order to not be tracked.</p><p>A few of these tricks rely<sup>[1, 2]</sup> on the <a href='https://en.wikipedia.org/wiki/Web_cache'>browser cache</a>, which content is often long lasting since rarely will users take the time to regularly clear their browser cache.</p><p>There is little inconvenience to clear the browser cache regularly (likelihood is that you won't notice when it happens), and the benefit is to prevent these obnoxious trackers from invading your privacy.</p><p>Check this option to have <i>nuTensor</i> do it for you, at the interval you wish.</p><p>[1] <a href='https://grepular.com/Preventing_Web_Tracking_via_the_Browser_Cache'>&ldquo;Preventing Web Tracking via the Browser Cache&rdquo;</a>\n[2] <a href='http://lucb1e.com/rp/cookielesscookies/'>&ldquo;Cookieless cookies&rdquo;</a></p>",
"description": ""
},
"privacyProcessRefererPrompt": {
"message": "Spoof <a href='https://en.wikipedia.org/wiki/HTTP_referer'>HTTP referrer</a> string of third-party requests",
"description": ""
},
"privacyProcessRefererHelp": {
"message": "From Wikipedia:<blockquote>HTTP referer is an HTTP header field that identifies the address of the webpage that linked to the resource being requested. ... <b>Because referer information can violate privacy, some web browsers allow the user to disable the sending of referer information.</b></blockquote>If this setting is checked, <i>nuTensor</i> will spoof the HTTP referrer information if the domain name of the HTTP referrer is third-party to the domain name of net request.",
"description": ""
},
"privacyNoMixedContentPrompt": {
"message": "Strict HTTPS: forbid mixed content",
"description": ""
},
"privacyNoMixedContentHelp": {
"message": "<p>From <a href='https://developer.mozilla.org/en-US/docs/Security/MixedContent'>Mozilla Developer Network</a>:</p><blockquote>If [a] HTTPS page includes content retrieved through regular, cleartext HTTP, then the connection is only partially encrypted: the unencrypted content is accessible to sniffers and can be modified by man-in-the-middle attackers, and therefore the connection is not safeguarded anymore. When a webpage exhibits this behavior, it is called a mixed content page.</blockquote>",
"description": ""
},
"privacyProcessHyperlinkAuditingPrompt": {
"message": "Block all <a href='https://html.spec.whatwg.org/multipage/semantics.html#hyperlink-auditing'>hyperlink auditing</a> attempts",
"description": ""
},
"privacyProcessHyperlinkAuditingHelp": {
"message": "<p>Hyperlink auditing is a mechanism which allow a party, <b>any party</b>, to be informed about which link a user clicked on a particular web page. It is essentially a tracking feature: it allows a web site, or any third-party to that web site, to be informed about which link you clicked on which one of its web pages. The sole purpose is to track your browsing activity.</p>",
"description": ""
},
"userRulesPermanentHeader": {
"message": "Daŭraj reguloj",
"description": ""
},
"userRulesTemporaryHeader": {
"message": "Nedaŭraj reguloj",
"description": ""
},
"userRulesRevert": {
"message": "Malfari",
"description": "Will remove all temporary rules"
},
"userRulesCommit": {
"message": "Konservi",
"description": "Will save all temporary rules"
},
"userRulesEdit": {
"message": "Redakti",
"description": "Will enable manual-edit mode (textarea)"
},
"userRulesEditSave": {
"message": "Konservi",
"description": "Will save manually-edited content and exit manual-edit mode"
},
"userRulesEditDicard": {
"message": "Ignori",
"description": "Will discard manually-edited content and exit manual-edit mode"
},
"userRulesImport": {
"message": "Importi el dosiero...",
"description": ""
},
"userRulesExport": {
"message": "Eksporti al dosiero...",
"description": ""
},
"userRulesFormatHint": {
"message": "See this page for rule syntax.",
"description": ""
},
"userRulesDefaultFileName": {
"message": "miaj-umatrix-reguloj.txt",
"description": "default file name to use"
},
"assetsHostsSection": {
"message": "Hosts files",
"description": "header to identify the hosts files section"
},
"hostsFilesPrompt": {
"message": "All hostnames in a hosts file are loaded as blacklisted hostnames in the global scope.",
"description": ""
},
"hostsFilesStats": {
"message": "{{blockedHostnameCount}} distinct blocked hostnames from:",
"description": ""
},
"hostsFilesPerFileStats": {
"message": "{{used}} used out of {{total}}",
"description": ""
},
"hostsFilesLastUpdate": {
"message": "Lasta ĝisdatigo: {{ago}}",
"description": "English: Last update: {{ago}}, where 'ago' will be replaced with something like '2 days ago'"
},
"hostsFilesApplyChanges": {
"message": "Apliki ŝanĝojn",
"description": ""
},
"hostsFilesAutoUpdatePrompt": {
"message": "Auto-update assets",
"description": ""
},
"hostsFilesUpdateNow": {
"message": "Ĝisdatigi nun",
"description": ""
},
"hostsFilesPurgeAll": {
"message": "Malplenigi ĉiujn kaŝmemorojn",
"description": ""
},
"hostsFilesExternalListsHint": {
"message": "Import external assets here: \nOne URL per line; invalid URLs will be silently ignored.",
"description": ""
},
"hostsFilesExternalListsParse": {
"message": "Analizi",
"description": ""
},
"hostsFilesExternalListPurge": {
"message": "malplenigi kaŝmemoron",
"description": ""
},
"hostsFilesExternalListNew": {
"message": "nova versio disponebla",
"description": ""
},
"hostsFilesExternalListObsolete": {
"message": "neĝisdata",
"description": ""
},
"assetsRecipesSection": {
"message": "Ruleset recipes",
"description": "header to identify the ruleset files section"
},
"assetsRecipesSummary": {
"message": "Ruleset recipes are imported from the popup panel <em>on demand</em>, i.e. <b>only</b> through user interaction.",
"description": ""
},
"assetsImportLabel": {
"message": "Import...",
"description": ""
},
"assetsInlineHostsLabel": {
"message": "My hosts",
"description": ""
},
"assetsInlineRecipesLabel": {
"message": "My recipes",
"description": ""
},
"rawSettingsWarning": {
"message": "Warning! Change these raw configuration settings at your own risk.",
"description": ""
},
"aboutChangelog": {
"message": "<a href='https://github.com/geekprojects/nuTensor/releases'>Ŝanĝoprotokolo</a>",
"description": ""
},
"aboutStorageUsed": {
"message": "Storage used: {{storageUsed}} bytes",
"description": ""
},
"aboutDoc": {
"message": "<a href='https://github.com/geekprojects/nuTensor/wiki'>Documentation</a>",
"description": ""
},
"aboutPermissions": {
"message": "<a href='https://github.com/geekprojects/nuTensor/wiki/Permissions'>Permissions</a>",
"description": ""
},
"aboutCode": {
"message": "Fontkodo (GPLv3)",
"description": ""
},
"aboutIssues": {
"message": "Cimoj kaj problemoj",
"description": "Text for a link to official issue tracker"
},
"aboutContributors": {
"message": "Kontribuantoj",
"description": "English: Contributors"
},
"aboutCodeContributors": {
"message": "Kode:",
"description": ""
},
"aboutIssueContributors": {
"message": "Problemoj:",
"description": ""
},
"aboutTranslationContributors": {
"message": "Tradukoj:",
"description": ""
},
"aboutUserDataHeader": {
"message": "Viaj datumoj",
"description": ""
},
"aboutBackupButton": {
"message": "Savkopii al dosiero...",
"description": ""
},
"aboutBackupFilename": {
"message": "mia-umatrix-savkopio.txt",
"description": "default filename to use"
},
"aboutRestoreButton": {
"message": "Restore from file...",
"description": ""
},
"aboutRestoreConfirm": {
"message": "All your settings will be overwritten using data backed up on {{time}}, and nuTensor will restart.\n\nOverwrite all existing settings using backed up data?",
"description": "Message asking user to confirm restore"
},
"aboutRestoreError": {
"message": "The data could not be read or is invalid",
"description": ""
},
"aboutOr": {
"message": "... aŭ ...",
"description": "English: ... or ..."
},
"aboutResetButton": {
"message": "Reset to default settings",
"description": "English: Reset to default settings"
},
"aboutResetConfirm": {
"message": "Caution! this will remove all your custom settings. Are you sure you want to proceed?",
"description": "Message asking user to confirm reset"
},
"mainBlockedPrompt1": {
"message": "nuTensor has prevented the following page from loading:",
"description": "English: nuTensor has prevented the following page from loading:"
},
"mainBlockedPrompt2": {
"message": "Because of the following rule",
"description": "English: Because of the following rule"
},
"mainBlockedNoParamsPrompt": {
"message": "without parameters",
"description": "label to be used for the parameter-less URL: https://cloud.githubusercontent.com/assets/585534/9832014/bfb1b8f0-593b-11e5-8a27-fba472a5529a.png"
},
"mainBlockedBack": {
"message": "Reen",
"description": "English: Go back"
},
"mainBlockedClose": {
"message": "Fermi",
"description": "English: Close"
},
"commandRevertAll": {
"message": "Revert all temporary changes",
"description": ""
},
"commandWhitelistPageDomain": {
"message": "Temporarily whitelist page domain",
"description": ""
},
"commandWhitelistAll": {
"message": "Temporarily whitelist all",
"description": ""
},
"commandOpenDashboard": {
"message": "Malfermi la panelo",
"description": ""
},
"elapsedOneMinuteAgo": {
"message": "antaŭ 1 minuto",
"description": "English: a minute ago"
},
"elapsedManyMinutesAgo": {
"message": "antaŭ {{value}} minutoj",
"description": "English: {{value}} minutes ago"
},
"elapsedOneHourAgo": {
"message": "antaŭ 1 horo",
"description": "English: an hour ago"
},
"elapsedManyHoursAgo": {
"message": "antaŭ {{value}} horoj",
"description": "English: {{value}} hours ago"
},
"elapsedOneDayAgo": {
"message": "antaŭ 1 tago",
"description": "English: a day ago"
},
"elapsedManyDaysAgo": {
"message": "antaŭ {{value}} tagoj",
"description": "English: {{value}} days ago"
},
"showDashboardButton": {
"message": "Panelo",
"description": "Appears in Firefox's add-on preferences"
},
"showLoggerButton": {
"message": "Protokolilo",
"description": "Appears in Firefox's add-on preferences"
},
"cloudPush": {
"message": "Eksporti al nuba konservado",
"description": "tooltip"
},
"cloudPull": {
"message": "Importi el nuba konservado",
"description": "tooltip"
},
"cloudNoData": {
"message": "...\n...",
"description": ""
},
"cloudDeviceNamePrompt": {
"message": "Nomo de ĉi tiu aparato:",
"description": "used as a prompt for the user to provide a custom device name"
},
"genericSubmit": {
"message": "Sendi",
"description": "for generic 'submit' buttons"
},
"genericRevert": {
"message": "Malfari",
"description": "for generic 'revert' buttons"
},
"errorCantConnectTo": {
"message": "Reteraro: {{url}} ne konekteblas",
"description": ""
},
"genericApplyChanges": {
"message": "Apply changes",
"description": "for generic 'Apply changes' buttons"
},
"genericCopyToClipboard": {
"message": "Copy to clipboard",
"description": "Label for buttons used to copy something to the clipboard"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save