This commit is contained in:
Kevin R
2020-08-19 23:41:12 +02:00
parent b7e209bf15
commit 843aeed109
12 changed files with 11233 additions and 1 deletions

13
.editorconfig Normal file
View File

@@ -0,0 +1,13 @@
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100
[*.md]
trim_trailing_whitespace = false

8
.gitignore vendored
View File

@@ -17,4 +17,10 @@ yarn-debug.log*
yarn-error.log*
# WebStorm
.idea/
.idea/
node_modules
yarn.lock
distribution
coverage
size-plugin.json

6
.prettierrc Normal file
View File

@@ -0,0 +1,6 @@
{
"trailingComma": "all",
"tabWidth": 2,
"semi": false,
"singleQuote": true
}

10838
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

63
package.json Normal file
View File

@@ -0,0 +1,63 @@
{
"name": "clearurls",
"version": "1.19.0",
"description": "Remove tracking elements from URLs",
"main": "background/main.js",
"dependencies": {
"webext-options-sync": "^1.2.3",
"webextension-polyfill-ts": "^0.19.0"
},
"devDependencies": {
"@sindresorhus/tsconfig": "^0.7.0",
"@types/firefox-webext-browser": "^78.0.1",
"@types/jest": "^26.0.10",
"@types/node": "^14.6.0",
"copy-webpack-plugin": "^6.0.3",
"dot-json": "^1.2.0",
"jest": "^26.4.0",
"mockzilla-webextension": "^0.6.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.0.5",
"rimraf": "^3.0.2",
"size-plugin": "^2.0.1",
"terser-webpack-plugin": "^4.1.0",
"ts-jest": "^26.2.0",
"ts-loader": "^8.0.2",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
"tslint-config-standard": "^9.0.0",
"typescript": "^3.9.7",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12"
},
"scripts": {
"lint": "tslint -t codeFrame -c tslint.json 'source/**/*.{ts,tsx,js}' 'tests/**/*.{ts,tsx,js}'",
"test": "jest --coverage",
"test:prod": "run-s test lint build",
"clean": "rimraf distribution",
"build": "run-s clean && webpack --mode=production",
"watch": "webpack --mode=development --watch",
"version": "dot-json manifest.json version $VER"
},
"repository": {
"type": "git",
"url": "git@gitlab.com:KevinRoebert/ClearUrls.git"
},
"keywords": [
"tracking-protection",
"webextension",
"plugin",
"opensource",
"firefox addon",
"chrome addon",
"edge addon",
"browser extension",
"extension"
],
"author": "Kevin Röbert",
"license": "LGPL-3.0-or-later",
"bugs": {
"url": "https://github.com/KevinRoebert/ClearUrls/issues"
},
"homepage": "https://github.com/KevinRoebert/ClearUrls#readme"
}

View File

@@ -0,0 +1 @@
// import { browser } from 'webextension-polyfill-ts'

82
source/storage/storage.ts Normal file
View File

@@ -0,0 +1,82 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible for the storage.
*
* Note: this script also includes some code for backward-compatibility.
*/
import OptionsSync from 'webext-options-sync'
import { Utils } from '../utils/utils'
export default new OptionsSync({
defaults: {
rules: '{}',
rulesHash: '',
badgedStatus: true,
enabled: true,
totalCount: 0,
cleanedCount: 0,
rulesStatus: 'error',
loggingEnabled: false,
log: '',
logLimit: 100,
statisticsEnabled: true,
badgedColor: '#ffa500',
hashURL: 'https://kevinroebert.gitlab.io/ClearUrls/data/rules.minify.hash',
rulesURL: 'https://kevinroebert.gitlab.io/ClearUrls/data/data.minify.json',
contextMenuEnabled: true,
historyListenerEnabled: true,
localHostsSkippingEnabled: true,
allowReferralMarketingEnabled: false,
domainBlockingEnabled: true,
pingBlockingEnabled: true,
eTagFilteringEnabled: true,
watchDogErrorCount: 0,
requestTypes: '',
pingRequestTypes: '',
},
migrations: [
(savedOptions, defaults) => {
if (Utils.getBrowser() === 'Firefox') {
if (savedOptions.requestTypes === '') {
savedOptions.requestTypes = 'font,image,imageset,main_frame,media,object,object_subrequest,other,script,stylesheet,sub_frame,websocket,xml_dtd,xmlhttprequest,xslt'
}
if (savedOptions.pingRequestTypes === '') {
savedOptions.pingRequestTypes = 'ping,beacon'
}
} else {
if (savedOptions.requestTypes === '') {
savedOptions.requestTypes = 'main_frame,sub_frame,stylesheet,script,image,font,object,xmlhttprequest,ping,csp_report,media,websocket,other'
}
if (savedOptions.pingRequestTypes === '') {
savedOptions.pingRequestTypes = 'ping'
}
}
},
OptionsSync.migrations.removeUnused
],
logging: true,
storageName: 'clearurlsData',
})

0
source/test.json Normal file
View File

97
source/utils/utils.ts Normal file
View File

@@ -0,0 +1,97 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible for some tools.
*/
import { browser } from 'webextension-polyfill-ts'
// Needed by the sha256 method
const enc = new TextEncoder()
export class Utils {
/**
* Checks if the current browser runs on android.
*
* @returns Promise with true, iff the current browser runs on android otherwise false
*/
static async isAndroidOS() : Promise<boolean> {
return (await browser.runtime.getPlatformInfo()).os === 'android'
}
/**
* Returns the browser name.
*
* @returns the browser name
*/
static getBrowser() : string {
if (typeof InstallTrigger !== 'undefined') {
return 'Firefox'
}
return 'Chrome'
}
/**
* Decodes an URL, also one that is encoded multiple times.
*
* @see https://stackoverflow.com/a/38265168
*
* @param url - the url, that should be decoded
* @returns the decoded URL
*/
static decodeURL(url: string) : string {
let rtn = decodeURIComponent(url)
while (Utils.isEncodedURI(rtn)) {
rtn = decodeURIComponent(rtn)
}
return rtn
}
/**
* Returns true, iff the given URI is encoded
*
* @see https://stackoverflow.com/a/38265168
*
* @param uri - the URI to be checked
* @returns true, iff the given URI is encoded otherwise false
*/
static isEncodedURI(uri: string) : boolean {
return uri !== decodeURIComponent(uri || '')
}
/**
* This method calculates the SHA-256 hash as HEX string of the given message.
* This method uses the native hashing implementations of the SubtleCrypto interface which is supported by all browsers
* that implement the Web Cryptography API specification and is based on:
* https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
*
* @param message - message for which the hash should be calculated
* @returns SHA-256 of the given message
*/
static async sha256(message: string): Promise<string> {
const msgUint8 = enc.encode(message)
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8)
const hashArray = Array.from(new Uint8Array(hashBuffer))
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('')
}
}

12
tsconfig.json Normal file
View File

@@ -0,0 +1,12 @@
{
"extends": "@sindresorhus/tsconfig",
"compilerOptions": {
"target": "es6",
"jsx": "preserve",
"declaration": false,
"moduleResolution": "node",
"esModuleInterop": true
},
"include": ["source/**/*"]
}

32
tslint.json Normal file
View File

@@ -0,0 +1,32 @@
{
"extends": ["tslint-config-standard", "tslint-config-prettier", "tslint:latest"],
"rules": {
"jsx-wrap-multiline": false,
"trailing-comma": [
true,
{
"multiline": {
"objects": "always"
},
"singleline": "never"
}
],
"semicolon": [true, "never"],
"quotemark": [true, "single", "jsx-single", "avoid-escape"],
"variable-name": [true, "check-format", "allow-pascal-case", "allow-leading-underscore"],
"max-classes-per-file": [false, 1],
"interface-name": [true, "never-prefix"],
"no-submodule-imports": false,
"ordered-imports": [
true,
{
"import-sources-order": "lowercase-first",
"named-imports-order": "lowercase-last"
}
],
"no-object-literal-type-assertion": false,
"jsx-no-lambda": false,
"no-console": false
}
}

82
webpack.config.js Normal file
View File

@@ -0,0 +1,82 @@
const path = require('path')
const SizePlugin = require('size-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
devtool: 'source-map',
stats: 'errors-only',
entry: {
// target_path/target_file_name: full_source_path
'background/main': './source/background/main.ts',
},
output: {
path: path.join(__dirname, 'distribution'),
filename: '[name].js',
},
resolve: {
// Add '.ts' and '.tsx' as a resolvable extension.
extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js', '.json'],
alias: {
'webextension-polyfill-ts': path.resolve(
path.join(__dirname, 'node_modules', 'webextension-polyfill-ts'),
),
},
},
module: {
rules: [
// all files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'
{
test: /\.tsx?$/,
loader: 'ts-loader',
options: {
configFile: 'tsconfig.json',
},
exclude: /node_modules/,
},
{
test: /\.s[ac]ss$/i,
use: [
{
loader: 'file-loader',
options: {
name(resourcePath, resourceQuery) {
return resourcePath.replace(/.+source[\/\\]/, '').replace(/\.s[ac]ss$/i, '.css')
},
},
},
// Compiles Sass to CSS
'sass-loader',
],
},
],
},
plugins: [
new SizePlugin(),
new CopyWebpackPlugin({
patterns: [
{
from: '**/*',
context: 'source',
globOptions: {
ignore: ['**/*.js', '**/*.ts', '**/*.tsx', '**/*.scss'],
},
},
],
}),
],
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
mangle: false,
compress: false,
output: {
beautify: true,
indent_level: 2, // eslint-disable-line camelcase
},
},
}),
],
},
}