mirror of
https://gitlab.com/KevinRoebert/ClearUrls
synced 2025-12-17 14:45:37 +07:00
init 2
This commit is contained in:
44
__tests__/utils/CircularBuffer.ts
Normal file
44
__tests__/utils/CircularBuffer.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import CircularBuffer from '../../source/utils/CircularBuffer'
|
||||
|
||||
describe('CircularBuffer', () => {
|
||||
let capacity: number
|
||||
let buffer: CircularBuffer<string>
|
||||
|
||||
beforeEach(() => {
|
||||
capacity = 10
|
||||
buffer = new CircularBuffer<string>(capacity)
|
||||
})
|
||||
|
||||
it('should creates a buffer with the specified capacity', () => {
|
||||
expect(buffer.capacity).toBe(capacity)
|
||||
})
|
||||
|
||||
it('should add item to the buffer', () => {
|
||||
expect(buffer.size).toBe(0)
|
||||
buffer.enqueue('foo')
|
||||
expect(buffer.size).toBe(1)
|
||||
})
|
||||
|
||||
it('should remove oldest item if the buffer is full on adding new items', () => {
|
||||
buffer = new CircularBuffer<string>(2)
|
||||
buffer.enqueue('foo1')
|
||||
buffer.enqueue('foo2')
|
||||
buffer.enqueue('foo3')
|
||||
buffer.enqueue('foo4')
|
||||
expect(buffer.toArray()).toEqual(['foo3', 'foo4'])
|
||||
})
|
||||
|
||||
|
||||
it('should return the current size via the size() getter', () => {
|
||||
buffer.enqueue('foo')
|
||||
expect(buffer.size).toBe(1)
|
||||
})
|
||||
|
||||
it('should return true if buffer is empty', () => {
|
||||
expect(buffer.isEmpty()).toBe(true)
|
||||
})
|
||||
|
||||
it('should throw exception on illegal argument', () => {
|
||||
expect(() => new CircularBuffer<any>(0)).toThrow('The capacity must be > 0')
|
||||
})
|
||||
})
|
||||
4
jest.config.js
Normal file
4
jest.config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
};
|
||||
23
source/log/Log.ts
Normal file
23
source/log/Log.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import CircularBuffer from '../utils/CircularBuffer'
|
||||
import LogEntry from './LogEntry'
|
||||
|
||||
export default class Log extends CircularBuffer<LogEntry> {
|
||||
public constructor(capacity: number) {
|
||||
super(capacity)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Log object from the given string.
|
||||
*
|
||||
* @param enc - the encoded log
|
||||
* @returns a log object
|
||||
*/
|
||||
// public static from(enc: string) : Log {}
|
||||
|
||||
/**
|
||||
* Returns this log as string.
|
||||
*
|
||||
* @returns the log as string
|
||||
*/
|
||||
// public toString() : string {}
|
||||
}
|
||||
37
source/log/LogEntry.ts
Normal file
37
source/log/LogEntry.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import Rule from '../rules/rule'
|
||||
|
||||
export default class LogEntry {
|
||||
private _before: string
|
||||
private _after: string
|
||||
private _rule: Rule
|
||||
private _timestamp: number
|
||||
private _runtime: number
|
||||
|
||||
constructor(before: string, after: string, rule: Rule, timestamp: number = Date.now(), runtime: number) {
|
||||
this._before = before
|
||||
this._after = after
|
||||
this._rule = rule
|
||||
this._timestamp = timestamp
|
||||
this._runtime = runtime
|
||||
}
|
||||
|
||||
get before() : string {
|
||||
return this._before
|
||||
}
|
||||
|
||||
get after() : string {
|
||||
return this._after
|
||||
}
|
||||
|
||||
get rule() : Rule {
|
||||
return this._rule
|
||||
}
|
||||
|
||||
get timestamp() : number {
|
||||
return this._timestamp
|
||||
}
|
||||
|
||||
get runtime() : number {
|
||||
return this._runtime
|
||||
}
|
||||
}
|
||||
@@ -51,18 +51,7 @@
|
||||
],
|
||||
"background": {
|
||||
"scripts": [
|
||||
"browser-polyfill.js",
|
||||
"core_js/message_handler.js",
|
||||
"external_js/ip-range-check.js",
|
||||
"core_js/tools.js",
|
||||
"core_js/badgedHandler.js",
|
||||
"core_js/pureCleaning.js",
|
||||
"core_js/context_menu.js",
|
||||
"core_js/historyListener.js",
|
||||
"clearurls.js",
|
||||
"core_js/storage.js",
|
||||
"core_js/watchdog.js",
|
||||
"core_js/eTagFilter.js"
|
||||
"background/main.js"
|
||||
]
|
||||
},
|
||||
"content_scripts": [
|
||||
@@ -264,7 +253,7 @@
|
||||
"*://*.google.cat/*"
|
||||
],
|
||||
"js": [
|
||||
"core_js/google_link_fix.js"
|
||||
"scripts/googleLinkFix.js"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
@@ -276,7 +265,7 @@
|
||||
"*://*.ya.ru/*"
|
||||
],
|
||||
"js": [
|
||||
"core_js/yandex_link_fix.js"
|
||||
"scripts/yandexLinkFix.js"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
}
|
||||
11
source/rules/rule.ts
Normal file
11
source/rules/rule.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export default class Rule {
|
||||
private _rule: RegExp
|
||||
|
||||
constructor(rule: RegExp) {
|
||||
this._rule = rule
|
||||
}
|
||||
|
||||
get value() : RegExp {
|
||||
return this._rule
|
||||
}
|
||||
}
|
||||
67
source/scripts/googleLinkFix.js
Normal file
67
source/scripts/googleLinkFix.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
* Based on:
|
||||
* Remove Google Redirection
|
||||
* https://github.com/kodango/Remove-Google-Redirection/blob/master/extension/chrome/remove-google-redirection.user.js
|
||||
* Copyright (c) 2017 kodango
|
||||
* MIT License: https://github.com/kodango/Remove-Google-Redirection/blob/master/LICENSE
|
||||
*/
|
||||
(function (window) {
|
||||
"use strict";
|
||||
|
||||
function injectFunction() {
|
||||
let ele = document.createElement('script');
|
||||
let s = document.getElementsByTagName('script')[0];
|
||||
|
||||
ele.type = 'text/javascript';
|
||||
ele.textContent = "Object.defineProperty(window, 'rwt', {" +
|
||||
" value: function() { return true; }," +
|
||||
" writable: false," +
|
||||
" configurable: false" +
|
||||
"});";
|
||||
|
||||
s.parentNode.insertBefore(ele, s);
|
||||
}
|
||||
|
||||
/*
|
||||
* The main entry
|
||||
*/
|
||||
function main()
|
||||
{
|
||||
injectFunction();
|
||||
|
||||
document.addEventListener('mouseover', function (event) {
|
||||
let a = event.target, depth = 1;
|
||||
|
||||
while (a && a.tagName !== 'A' && depth-- > 0) {
|
||||
a = a.parentNode;
|
||||
}
|
||||
|
||||
if (a && a.tagName === 'A') {
|
||||
try {
|
||||
a.removeAttribute('data-cthref');
|
||||
delete a.dataset.cthref;
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
main();
|
||||
})(window);
|
||||
66
source/scripts/yandexLinkFix.js
Normal file
66
source/scripts/yandexLinkFix.js
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*
|
||||
* Based on:
|
||||
* Remove Google Redirection
|
||||
* https://github.com/kodango/Remove-Google-Redirection/blob/master/extension/chrome/remove-google-redirection.user.js
|
||||
* Copyright (c) 2017 kodango
|
||||
* MIT License: https://github.com/kodango/Remove-Google-Redirection/blob/master/LICENSE
|
||||
*/
|
||||
(function (window) {
|
||||
"use strict";
|
||||
|
||||
function injectFunction() {
|
||||
let ele = document.createElement('script');
|
||||
let s = document.getElementsByTagName('script')[0];
|
||||
|
||||
ele.type = 'text/javascript';
|
||||
ele.textContent = "Object.defineProperty(window, '_borschik', {" +
|
||||
" value: function() { return false; }," +
|
||||
" writable: false," +
|
||||
" configurable: false" +
|
||||
"});";
|
||||
|
||||
s.parentNode.insertBefore(ele, s);
|
||||
}
|
||||
|
||||
/*
|
||||
* The main entry
|
||||
*/
|
||||
function main() {
|
||||
injectFunction();
|
||||
|
||||
document.addEventListener('mouseover', function (event) {
|
||||
let a = event.target, depth = 1;
|
||||
|
||||
while (a && a.tagName !== 'A' && depth-- > 0) {
|
||||
a = a.parentNode;
|
||||
}
|
||||
|
||||
if (a && a.tagName === 'A') {
|
||||
try {
|
||||
a.removeAttribute('data-counter');
|
||||
delete a.dataset.cthref;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
main();
|
||||
})(window);
|
||||
@@ -26,9 +26,11 @@
|
||||
import OptionsSync from 'webext-options-sync'
|
||||
import { Utils } from '../utils/utils'
|
||||
|
||||
export default new OptionsSync({
|
||||
/**
|
||||
* Saves all options in sync storage.
|
||||
*/
|
||||
export const syncStorage = new OptionsSync({
|
||||
defaults: {
|
||||
rules: '{}',
|
||||
rulesHash: '',
|
||||
badgedStatus: true,
|
||||
enabled: true,
|
||||
@@ -36,7 +38,6 @@ export default new OptionsSync({
|
||||
cleanedCount: 0,
|
||||
rulesStatus: 'error',
|
||||
loggingEnabled: false,
|
||||
log: '',
|
||||
logLimit: 100,
|
||||
statisticsEnabled: true,
|
||||
badgedColor: '#ffa500',
|
||||
@@ -54,23 +55,24 @@ export default new OptionsSync({
|
||||
pingRequestTypes: '',
|
||||
},
|
||||
migrations: [
|
||||
(savedOptions, defaults) => {
|
||||
|
||||
// Secound param is normaly "defaults", but currently not used
|
||||
(savedOptions, _) => {
|
||||
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'
|
||||
savedOptions.requestTypes = Object.values(FirefoxRequestTypes).join(',')
|
||||
}
|
||||
|
||||
if (savedOptions.pingRequestTypes === '') {
|
||||
savedOptions.pingRequestTypes = 'ping,beacon'
|
||||
savedOptions.pingRequestTypes = Object.values(FirefoxPingRequestTypes).join(',')
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (savedOptions.requestTypes === '') {
|
||||
savedOptions.requestTypes = 'main_frame,sub_frame,stylesheet,script,image,font,object,xmlhttprequest,ping,csp_report,media,websocket,other'
|
||||
savedOptions.requestTypes = Object.values(ChromeRequestTypes).join(',')
|
||||
}
|
||||
|
||||
if (savedOptions.pingRequestTypes === '') {
|
||||
savedOptions.pingRequestTypes = 'ping'
|
||||
savedOptions.pingRequestTypes = Object.values(ChromePingRequestTypes).join(',')
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -79,4 +81,71 @@ export default new OptionsSync({
|
||||
],
|
||||
logging: true,
|
||||
storageName: 'clearurlsData',
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Saves rules and logs on local storage.
|
||||
*/
|
||||
/* export class LocalStorage {
|
||||
private _rules: {}
|
||||
private _log: Log
|
||||
|
||||
public constructor() {
|
||||
this._rules = {}
|
||||
this._log = new Log()
|
||||
}
|
||||
} */
|
||||
|
||||
/**
|
||||
* Models the supported request types of Firefox.
|
||||
*/
|
||||
export enum FirefoxRequestTypes {
|
||||
FONT = 'font',
|
||||
IMAGE = 'image',
|
||||
IMAGESET = 'imageset',
|
||||
MAIN_FRAME = 'main_frame',
|
||||
MEDIA = 'media',
|
||||
OBJECT = 'object',
|
||||
OBJECT_SUBREQUEST = 'object_subrequest',
|
||||
OTHER = 'other',
|
||||
SCRIPT = 'script',
|
||||
STYLESHEET = 'stylesheet',
|
||||
SUB_FRAME = 'sub_frame',
|
||||
WEBSOCKET = 'websocket',
|
||||
XML_DTD = 'xml_dtd',
|
||||
XMLHTTPREQUEST = 'xmlhttprequest',
|
||||
XSLT = 'xslt',
|
||||
}
|
||||
|
||||
/**
|
||||
* Models the supported ping request types of Firefox.
|
||||
*/
|
||||
export enum FirefoxPingRequestTypes {
|
||||
PING = 'ping',
|
||||
BEACON = 'beacon',
|
||||
}
|
||||
|
||||
/**
|
||||
* Models the supported request types of Chrome.
|
||||
*/
|
||||
export enum ChromeRequestTypes {
|
||||
MAIN_FRAME = 'main_frame',
|
||||
SUB_FRAME = 'sub_frame',
|
||||
STYLESHEET = 'stylesheet',
|
||||
SCRIPT = 'script',
|
||||
IMAGE = 'image',
|
||||
FONT = 'font',
|
||||
OBJECT = 'object',
|
||||
XMLHTTPREQUEST = 'xmlhttprequest',
|
||||
CSP_REPORT = 'csp_report',
|
||||
MEDIA = 'media',
|
||||
WEBSOCKET = 'websocket',
|
||||
OTHER = 'other',
|
||||
}
|
||||
|
||||
/**
|
||||
* Models the supported ping request types of Chrome.
|
||||
*/
|
||||
export enum ChromePingRequestTypes {
|
||||
PING = 'ping',
|
||||
}
|
||||
63
source/utils/CircularBuffer.ts
Normal file
63
source/utils/CircularBuffer.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
export default class CircularBuffer<T> {
|
||||
private buffer: T[]
|
||||
public readonly capacity: number
|
||||
|
||||
/**
|
||||
* Create a new circular buffer, that removes the oldes elements if the capacity is reached.
|
||||
*
|
||||
* @param capacity - the capacity of this queue
|
||||
* @throws error if the capacity is <= 0
|
||||
*/
|
||||
public constructor(capacity: number) {
|
||||
if (capacity <= 0) {
|
||||
throw new Error('The capacity must be > 0')
|
||||
}
|
||||
|
||||
this.capacity = capacity
|
||||
this.buffer = []
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the buffer is empty.
|
||||
*
|
||||
* @returns true if the buffer is empty otherwise false
|
||||
*/
|
||||
public isEmpty() : boolean {
|
||||
return this.buffer.length === 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the buffer is full.
|
||||
*
|
||||
* @returns true if the buffer is full otherwise false
|
||||
*/
|
||||
public isFull() : boolean {
|
||||
return this.buffer.length === this.capacity
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues an item.
|
||||
*
|
||||
* @param item - item that should be enqueued
|
||||
*/
|
||||
public enqueue(item: T) : void {
|
||||
if (this.isFull()) {
|
||||
this.buffer.shift()
|
||||
}
|
||||
|
||||
this.buffer.push(item)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the buffer in a fresh array.
|
||||
*
|
||||
* @returns the buffer
|
||||
*/
|
||||
public toArray() : T[] {
|
||||
return [...this.buffer]
|
||||
}
|
||||
|
||||
get size() : number {
|
||||
return this.buffer.length
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@
|
||||
*/
|
||||
import { browser } from 'webextension-polyfill-ts'
|
||||
|
||||
declare const InstallTrigger: any
|
||||
|
||||
export class Utils {
|
||||
// Needed by the sha256 method
|
||||
static enc = new TextEncoder()
|
||||
|
||||
@@ -8,7 +8,7 @@ module.exports = {
|
||||
stats: 'errors-only',
|
||||
entry: {
|
||||
// target_path/target_file_name: full_source_path
|
||||
'background/main': './source/background/main.ts',
|
||||
'background/main': './source/background/main.ts'
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, 'distribution'),
|
||||
@@ -62,6 +62,25 @@ module.exports = {
|
||||
ignore: ['**/*.js', '**/*.ts', '**/*.tsx', '**/*.scss'],
|
||||
},
|
||||
},
|
||||
{
|
||||
from: '_locales/**/*'
|
||||
},
|
||||
{
|
||||
from: 'img/*'
|
||||
},
|
||||
{
|
||||
from: 'fonts/*'
|
||||
},
|
||||
{
|
||||
from: 'css/*'
|
||||
},
|
||||
{
|
||||
from: 'html/*'
|
||||
},
|
||||
{
|
||||
from: 'scripts/*',
|
||||
context: 'source'
|
||||
}
|
||||
],
|
||||
}),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user