From 4432fb46bfb579faeea01c45e9e0f17d893a195b Mon Sep 17 00:00:00 2001 From: Kevin R Date: Thu, 20 Aug 2020 04:01:58 +0200 Subject: [PATCH] init 2 --- __tests__/utils/CircularBuffer.ts | 44 +++++++++++++ jest.config.js | 4 ++ source/log/Log.ts | 23 +++++++ source/log/LogEntry.ts | 37 +++++++++++ manifest.json => source/manifest.json | 17 +---- source/rules/rule.ts | 11 ++++ source/scripts/googleLinkFix.js | 67 ++++++++++++++++++++ source/scripts/yandexLinkFix.js | 66 +++++++++++++++++++ source/storage/storage.ts | 91 +++++++++++++++++++++++---- source/test.json | 0 source/utils/CircularBuffer.ts | 63 +++++++++++++++++++ source/utils/utils.ts | 2 + webpack.config.js | 21 ++++++- 13 files changed, 420 insertions(+), 26 deletions(-) create mode 100644 __tests__/utils/CircularBuffer.ts create mode 100644 jest.config.js create mode 100644 source/log/Log.ts create mode 100644 source/log/LogEntry.ts rename manifest.json => source/manifest.json (94%) create mode 100644 source/rules/rule.ts create mode 100644 source/scripts/googleLinkFix.js create mode 100644 source/scripts/yandexLinkFix.js delete mode 100644 source/test.json create mode 100644 source/utils/CircularBuffer.ts diff --git a/__tests__/utils/CircularBuffer.ts b/__tests__/utils/CircularBuffer.ts new file mode 100644 index 0000000..0c14bc6 --- /dev/null +++ b/__tests__/utils/CircularBuffer.ts @@ -0,0 +1,44 @@ +import CircularBuffer from '../../source/utils/CircularBuffer' + +describe('CircularBuffer', () => { + let capacity: number + let buffer: CircularBuffer + + beforeEach(() => { + capacity = 10 + buffer = new CircularBuffer(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(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(0)).toThrow('The capacity must be > 0') + }) +}) \ No newline at end of file diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..91a2d2c --- /dev/null +++ b/jest.config.js @@ -0,0 +1,4 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', +}; \ No newline at end of file diff --git a/source/log/Log.ts b/source/log/Log.ts new file mode 100644 index 0000000..740cc48 --- /dev/null +++ b/source/log/Log.ts @@ -0,0 +1,23 @@ +import CircularBuffer from '../utils/CircularBuffer' +import LogEntry from './LogEntry' + +export default class Log extends CircularBuffer { + 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 {} +} \ No newline at end of file diff --git a/source/log/LogEntry.ts b/source/log/LogEntry.ts new file mode 100644 index 0000000..98eadd6 --- /dev/null +++ b/source/log/LogEntry.ts @@ -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 + } +} \ No newline at end of file diff --git a/manifest.json b/source/manifest.json similarity index 94% rename from manifest.json rename to source/manifest.json index 2dccdae..5cc5084 100644 --- a/manifest.json +++ b/source/manifest.json @@ -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" } diff --git a/source/rules/rule.ts b/source/rules/rule.ts new file mode 100644 index 0000000..1cdf192 --- /dev/null +++ b/source/rules/rule.ts @@ -0,0 +1,11 @@ +export default class Rule { + private _rule: RegExp + + constructor(rule: RegExp) { + this._rule = rule + } + + get value() : RegExp { + return this._rule + } +} \ No newline at end of file diff --git a/source/scripts/googleLinkFix.js b/source/scripts/googleLinkFix.js new file mode 100644 index 0000000..8d967e3 --- /dev/null +++ b/source/scripts/googleLinkFix.js @@ -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 . +* +* 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); diff --git a/source/scripts/yandexLinkFix.js b/source/scripts/yandexLinkFix.js new file mode 100644 index 0000000..902d3e2 --- /dev/null +++ b/source/scripts/yandexLinkFix.js @@ -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 . +* +* 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); \ No newline at end of file diff --git a/source/storage/storage.ts b/source/storage/storage.ts index 9bafd62..e687ae6 100644 --- a/source/storage/storage.ts +++ b/source/storage/storage.ts @@ -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', -}) \ No newline at end of file +}) + +/** + * 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', +} \ No newline at end of file diff --git a/source/test.json b/source/test.json deleted file mode 100644 index e69de29..0000000 diff --git a/source/utils/CircularBuffer.ts b/source/utils/CircularBuffer.ts new file mode 100644 index 0000000..bb45dbe --- /dev/null +++ b/source/utils/CircularBuffer.ts @@ -0,0 +1,63 @@ +export default class CircularBuffer { + 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 + } +} \ No newline at end of file diff --git a/source/utils/utils.ts b/source/utils/utils.ts index 4deebc8..7f7a9c5 100644 --- a/source/utils/utils.ts +++ b/source/utils/utils.ts @@ -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() diff --git a/webpack.config.js b/webpack.config.js index 51f47ab..969e159 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -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' + } ], }), ],