From 138316a87da7c790a2fba0bd6b452ba60ab57df4 Mon Sep 17 00:00:00 2001 From: metastable-void Date: Mon, 26 Dec 2022 01:19:44 +0900 Subject: [PATCH 01/15] wip: user agent overrides --- docs/ua-list.json | 12 +++ src/background.ts | 2 +- src/modules/ChromiumReleaseService.ts | 39 ++++++++ src/overrides/UserAgentSettings.ts | 132 ++++++++++++++++++++++++++ src/{languages => overrides}/fetch.ts | 2 +- 5 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 docs/ua-list.json create mode 100644 src/overrides/UserAgentSettings.ts rename src/{languages => overrides}/fetch.ts (95%) diff --git a/docs/ua-list.json b/docs/ua-list.json new file mode 100644 index 00000000..7f75e218 --- /dev/null +++ b/docs/ua-list.json @@ -0,0 +1,12 @@ +[ + { + "name": "Latest Chrome", + "userAgent": "Mozilla/5.0 (%CHROME_UA_PLATFORM%) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%CHROME_RELEASE%.0.0.0 Safari/537.36", + "userAgentDataEnabled": true + }, + { + "name": "Googlebot", + "userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)", + "userAgentDataEnabled": true + } +] \ No newline at end of file diff --git a/src/background.ts b/src/background.ts index d26023e6..2bf48769 100644 --- a/src/background.ts +++ b/src/background.ts @@ -36,7 +36,7 @@ import './background/BackgroundContainerObservers'; import './background/BackgroundMenu'; import './background/BackgroundCookieAutoclean'; import './api/ApiDefinitions'; -import './languages/fetch'; +import './overrides/fetch'; import './languages/register-content-script'; // watchdog diff --git a/src/modules/ChromiumReleaseService.ts b/src/modules/ChromiumReleaseService.ts index f09850b5..a47414f6 100644 --- a/src/modules/ChromiumReleaseService.ts +++ b/src/modules/ChromiumReleaseService.ts @@ -21,6 +21,8 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ +import browser from 'webextension-polyfill'; + const JAN = 0; const FEB = 1; const MAR = 2; @@ -54,4 +56,41 @@ export class ChromiumReleaseService { public getLatestReleaseNumber(): number { return Math.floor((Date.now() - ChromiumReleaseService._ANCHOR_RELEASE_TIME) / ChromiumReleaseService._RELEASE_INTERVAL) + ChromiumReleaseService._ANCHOR_RELEASE_NUMBER; } + + private getOs(): string { + const userAgent = navigator.userAgent; + if (userAgent.includes('Windows')) { + return 'win'; + } else if (userAgent.includes('Macintosh')) { + return 'mac'; + } + return 'linux'; + } + + public getUserAgentPlatformString(): string { + const os = this.getOs(); + let platform = 'X11; Linux x86_64'; + switch (os) { + case 'win': { + platform = 'Windows NT 10.0; Win64; x64'; + break; + } + + case 'mac': { + platform = 'Macintosh; Intel Mac OS X 10_15_7'; + break; + } + } + return platform; + } + + /** + * Returns the supposed Chrome user agent string for the latest release on this platform. + * @returns The Chrome user agent string. + */ + public getUserAgentString(): string { + const platform = this.getUserAgentPlatformString(); + const releaseNumber = this.getLatestReleaseNumber(); + return `Mozilla/5.0 (${platform}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${releaseNumber}.0.0.0 Safari/537.36`; + } } diff --git a/src/overrides/UserAgentSettings.ts b/src/overrides/UserAgentSettings.ts new file mode 100644 index 00000000..6d866f12 --- /dev/null +++ b/src/overrides/UserAgentSettings.ts @@ -0,0 +1,132 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import { StorageItem, StorageArea } from "../frameworks/storage"; +import { EventSink } from "../frameworks/utils"; +import { OriginAttributes } from '../frameworks/tabGroups'; +import { ChromiumReleaseService } from "../modules/ChromiumReleaseService"; + +export type UserAgentPreset = 'default' | 'chrome' | 'googlebot' | 'custom'; + +type UserAgentParams = { + preset: UserAgentPreset; + userAgent?: string; +}; + +type StorageType = { + [cookieStoreId: string]: UserAgentParams; +}; + +export class UserAgentSettings { + private static readonly STORAGE_KEY = 'feature.uaOverrides.userAgentByContainer'; + private static readonly INSTANCE = new UserAgentSettings(); + + public static getInstance(): UserAgentSettings { + return UserAgentSettings.INSTANCE; + } + + private readonly _storage = new StorageItem(UserAgentSettings.STORAGE_KEY, {}, StorageArea.LOCAL); + private _value: StorageType = {}; + private readonly _chromeReleaseService = ChromiumReleaseService.getInstance(); + + public readonly onChanged = new EventSink(); + + private constructor() { + this._storage.observe((newValue) => { + this._value = newValue; + this.onChanged.dispatch(); + }, true); + } + + private originAttributesToKey(originAttributes: OriginAttributes): string { + return originAttributes.cookieStoreId; + } + + private save() { + this._storage.setValue(this._value).catch((e) => { + console.error(e); + }); + } + + public getValue(): StorageType { + return { + ... this._value, + }; + } + + public setUserAgent(originAttributes: OriginAttributes, preset: UserAgentPreset, userAgent?: string) { + const key = this.originAttributesToKey(originAttributes); + switch (preset) { + case 'default': { + delete this._value[key]; + break; + } + + case 'chrome': { + this._value[key] = { + preset: 'chrome', + }; + break; + } + + case 'googlebot': { + this._value[key] = { + preset: 'googlebot', + }; + break; + } + + default: { + this._value[key] = { + preset: 'custom', + userAgent, + }; + } + } + + this.save(); + } + + /** + * Returns the user agent string set for the given origin attributes. + * @param originAttributes + * @returns the user agent string, or empty string if not set + */ + public getUserAgent(originAttributes: OriginAttributes): string { + const key = this.originAttributesToKey(originAttributes); + const params = this._value[key]; + if (!params) { + return ''; + } + + switch (params.preset) { + case 'chrome': { + return this._chromeReleaseService.getUserAgentString(); + } + + case 'googlebot': { + return 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'; + } + } + + return params.userAgent || ''; + } +} diff --git a/src/languages/fetch.ts b/src/overrides/fetch.ts similarity index 95% rename from src/languages/fetch.ts rename to src/overrides/fetch.ts index db0c01f8..57bc2505 100644 --- a/src/languages/fetch.ts +++ b/src/overrides/fetch.ts @@ -21,7 +21,7 @@ import browser from 'webextension-polyfill'; import { OriginAttributes } from '../frameworks/tabGroups'; -import { LanguageSettings } from './LanguageSettings'; +import { LanguageSettings } from '../languages/LanguageSettings'; const languageSettings = LanguageSettings.getInstance(); From a5dfaeb4fd22ce0ca06f8d6a48f9a5817d195231 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Dec 2022 17:13:58 +0000 Subject: [PATCH 02/15] Bump eslint from 8.28.0 to 8.30.0 Bumps [eslint](https://github.com/eslint/eslint) from 8.28.0 to 8.30.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.28.0...v8.30.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 233 +++++++++++++++++++++++++++++++++++++++------- package.json | 2 +- 2 files changed, 199 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index aae963bf..d51201b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "container-tab-groups", - "version": "11.3.0", + "version": "11.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "container-tab-groups", - "version": "11.3.0", + "version": "11.4.0", "license": "GPL-3.0-or-later", "dependencies": { "webextension-polyfill": "^0.10.0" @@ -16,7 +16,7 @@ "@types/webextension-polyfill": "^0.9.2", "@typescript-eslint/eslint-plugin": "^5.46.1", "@typescript-eslint/parser": "^5.44.0", - "eslint": "^8.28.0", + "eslint": "^8.30.0", "ts-loader": "^9.4.1", "typedoc": "^0.23.23", "typescript": "<4.10.0", @@ -192,15 +192,15 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -249,9 +249,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1246,6 +1246,84 @@ } } }, + "node_modules/addons-linter/node_modules/eslint": { + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz", + "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.15.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/addons-linter/node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/addons-linter/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/addons-linter/node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -1268,6 +1346,18 @@ } } }, + "node_modules/addons-linter/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/addons-moz-compare": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/addons-moz-compare/-/addons-moz-compare-1.3.0.tgz", @@ -2584,13 +2674,13 @@ } }, "node_modules/eslint": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz", - "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==", + "version": "8.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", + "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -2609,7 +2699,7 @@ "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", @@ -3324,9 +3414,9 @@ } }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -7449,15 +7539,15 @@ "dev": true }, "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -7492,9 +7582,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -8215,6 +8305,73 @@ "yauzl": "2.10.0" } }, + "eslint": { + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz", + "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.15.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + } + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -8225,6 +8382,12 @@ "requires": { "whatwg-url": "^5.0.0" } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true } } }, @@ -9191,13 +9354,13 @@ "dev": true }, "eslint": { - "version": "8.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz", - "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==", + "version": "8.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", + "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -9216,7 +9379,7 @@ "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", @@ -9757,9 +9920,9 @@ } }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "requires": { "type-fest": "^0.20.2" diff --git a/package.json b/package.json index d05a0b3c..b33168f7 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "typedoc": "^0.23.23", "@typescript-eslint/eslint-plugin": "^5.46.1", "@typescript-eslint/parser": "^5.44.0", - "eslint": "^8.28.0", + "eslint": "^8.30.0", "typescript": "<4.10.0", "web-ext": "^7.4.0", "webpack": "^5.75.0", From 9be6a98d3d57875922a2e0b51a685e2dc8c59712 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Dec 2022 01:54:08 +0000 Subject: [PATCH 03/15] Bump ts-loader from 9.4.1 to 9.4.2 Bumps [ts-loader](https://github.com/TypeStrong/ts-loader) from 9.4.1 to 9.4.2. - [Release notes](https://github.com/TypeStrong/ts-loader/releases) - [Changelog](https://github.com/TypeStrong/ts-loader/blob/main/CHANGELOG.md) - [Commits](https://github.com/TypeStrong/ts-loader/compare/9.4.1...v9.4.2) --- updated-dependencies: - dependency-name: ts-loader dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d51201b9..a70eaf67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@typescript-eslint/eslint-plugin": "^5.46.1", "@typescript-eslint/parser": "^5.44.0", "eslint": "^8.30.0", - "ts-loader": "^9.4.1", + "ts-loader": "^9.4.2", "typedoc": "^0.23.23", "typescript": "<4.10.0", "web-ext": "^7.4.0", @@ -6581,9 +6581,9 @@ "peer": true }, "node_modules/ts-loader": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.1.tgz", - "integrity": "sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw==", + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", + "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", "dev": true, "dependencies": { "chalk": "^4.1.0", @@ -12302,9 +12302,9 @@ "peer": true }, "ts-loader": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.1.tgz", - "integrity": "sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw==", + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", + "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", "dev": true, "requires": { "chalk": "^4.1.0", diff --git a/package.json b/package.json index b33168f7..95dbfa8b 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "devDependencies": { "@types/node": "^18.11.17", "@types/webextension-polyfill": "^0.9.2", - "ts-loader": "^9.4.1", + "ts-loader": "^9.4.2", "typedoc": "^0.23.23", "@typescript-eslint/eslint-plugin": "^5.46.1", "@typescript-eslint/parser": "^5.44.0", From 67a545cfaa9bbc8464005307d319d7c32fe1ff0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Dec 2022 01:54:14 +0000 Subject: [PATCH 04/15] Bump @typescript-eslint/eslint-plugin from 5.46.1 to 5.47.1 Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.46.1 to 5.47.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.47.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 234 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 118 insertions(+), 118 deletions(-) diff --git a/package-lock.json b/package-lock.json index a70eaf67..564df818 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "devDependencies": { "@types/node": "^18.11.17", "@types/webextension-polyfill": "^0.9.2", - "@typescript-eslint/eslint-plugin": "^5.46.1", + "@typescript-eslint/eslint-plugin": "^5.47.1", "@typescript-eslint/parser": "^5.44.0", "eslint": "^8.30.0", "ts-loader": "^9.4.2", @@ -537,14 +537,14 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.1.tgz", - "integrity": "sha512-YpzNv3aayRBwjs4J3oz65eVLXc9xx0PDbIRisHj+dYhvBn02MjYOD96P8YGiWEIFBrojaUjxvkaUpakD82phsA==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.1.tgz", + "integrity": "sha512-r4RZ2Jl9kcQN7K/dcOT+J7NAimbiis4sSM9spvWimsBvDegMhKLA5vri2jG19PmIPbDjPeWzfUPQ2hjEzA4Nmg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.46.1", - "@typescript-eslint/type-utils": "5.46.1", - "@typescript-eslint/utils": "5.46.1", + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/type-utils": "5.47.1", + "@typescript-eslint/utils": "5.47.1", "debug": "^4.3.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", @@ -570,13 +570,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz", - "integrity": "sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", + "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.46.1", - "@typescript-eslint/visitor-keys": "5.46.1" + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -587,9 +587,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz", - "integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -600,12 +600,12 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz", - "integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/types": "5.47.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -661,13 +661,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.46.1.tgz", - "integrity": "sha512-V/zMyfI+jDmL1ADxfDxjZ0EMbtiVqj8LUGPAGyBkXXStWmCUErMpW873zEHsyguWCuq2iN4BrlWUkmuVj84yng==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.1.tgz", + "integrity": "sha512-/UKOeo8ee80A7/GJA427oIrBi/Gd4osk/3auBUg4Rn9EahFpevVV1mUK8hjyQD5lHPqX397x6CwOk5WGh1E/1w==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.46.1", - "@typescript-eslint/utils": "5.46.1", + "@typescript-eslint/typescript-estree": "5.47.1", + "@typescript-eslint/utils": "5.47.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -688,9 +688,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz", - "integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -701,13 +701,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz", - "integrity": "sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", + "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.46.1", - "@typescript-eslint/visitor-keys": "5.46.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -728,12 +728,12 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz", - "integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/types": "5.47.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -785,16 +785,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.1.tgz", - "integrity": "sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.1.tgz", + "integrity": "sha512-l90SdwqfmkuIVaREZ2ykEfCezepCLxzWMo5gVfcJsJCaT4jHT+QjgSkYhs5BMQmWqE9k3AtIfk4g211z/sTMVw==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.46.1", - "@typescript-eslint/types": "5.46.1", - "@typescript-eslint/typescript-estree": "5.46.1", + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/typescript-estree": "5.47.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -811,13 +811,13 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz", - "integrity": "sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", + "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.46.1", - "@typescript-eslint/visitor-keys": "5.46.1" + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -828,9 +828,9 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz", - "integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -841,13 +841,13 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz", - "integrity": "sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", + "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.46.1", - "@typescript-eslint/visitor-keys": "5.46.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -868,12 +868,12 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz", - "integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/types": "5.47.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -7827,14 +7827,14 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.1.tgz", - "integrity": "sha512-YpzNv3aayRBwjs4J3oz65eVLXc9xx0PDbIRisHj+dYhvBn02MjYOD96P8YGiWEIFBrojaUjxvkaUpakD82phsA==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.1.tgz", + "integrity": "sha512-r4RZ2Jl9kcQN7K/dcOT+J7NAimbiis4sSM9spvWimsBvDegMhKLA5vri2jG19PmIPbDjPeWzfUPQ2hjEzA4Nmg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.46.1", - "@typescript-eslint/type-utils": "5.46.1", - "@typescript-eslint/utils": "5.46.1", + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/type-utils": "5.47.1", + "@typescript-eslint/utils": "5.47.1", "debug": "^4.3.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", @@ -7844,28 +7844,28 @@ }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz", - "integrity": "sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", + "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.46.1", - "@typescript-eslint/visitor-keys": "5.46.1" + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1" } }, "@typescript-eslint/types": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz", - "integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", "dev": true }, "@typescript-eslint/visitor-keys": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz", - "integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", "dev": true, "requires": { - "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/types": "5.47.1", "eslint-visitor-keys": "^3.3.0" } } @@ -7894,31 +7894,31 @@ } }, "@typescript-eslint/type-utils": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.46.1.tgz", - "integrity": "sha512-V/zMyfI+jDmL1ADxfDxjZ0EMbtiVqj8LUGPAGyBkXXStWmCUErMpW873zEHsyguWCuq2iN4BrlWUkmuVj84yng==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.1.tgz", + "integrity": "sha512-/UKOeo8ee80A7/GJA427oIrBi/Gd4osk/3auBUg4Rn9EahFpevVV1mUK8hjyQD5lHPqX397x6CwOk5WGh1E/1w==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.46.1", - "@typescript-eslint/utils": "5.46.1", + "@typescript-eslint/typescript-estree": "5.47.1", + "@typescript-eslint/utils": "5.47.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, "dependencies": { "@typescript-eslint/types": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz", - "integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz", - "integrity": "sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", + "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.46.1", - "@typescript-eslint/visitor-keys": "5.46.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -7927,12 +7927,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz", - "integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", "dev": true, "requires": { - "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/types": "5.47.1", "eslint-visitor-keys": "^3.3.0" } } @@ -7960,45 +7960,45 @@ } }, "@typescript-eslint/utils": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.46.1.tgz", - "integrity": "sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.1.tgz", + "integrity": "sha512-l90SdwqfmkuIVaREZ2ykEfCezepCLxzWMo5gVfcJsJCaT4jHT+QjgSkYhs5BMQmWqE9k3AtIfk4g211z/sTMVw==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.46.1", - "@typescript-eslint/types": "5.46.1", - "@typescript-eslint/typescript-estree": "5.46.1", + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/typescript-estree": "5.47.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz", - "integrity": "sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", + "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.46.1", - "@typescript-eslint/visitor-keys": "5.46.1" + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1" } }, "@typescript-eslint/types": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.1.tgz", - "integrity": "sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz", - "integrity": "sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", + "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.46.1", - "@typescript-eslint/visitor-keys": "5.46.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -8007,12 +8007,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz", - "integrity": "sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", "dev": true, "requires": { - "@typescript-eslint/types": "5.46.1", + "@typescript-eslint/types": "5.47.1", "eslint-visitor-keys": "^3.3.0" } }, diff --git a/package.json b/package.json index 95dbfa8b..ed54a14b 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@types/webextension-polyfill": "^0.9.2", "ts-loader": "^9.4.2", "typedoc": "^0.23.23", - "@typescript-eslint/eslint-plugin": "^5.46.1", + "@typescript-eslint/eslint-plugin": "^5.47.1", "@typescript-eslint/parser": "^5.44.0", "eslint": "^8.30.0", "typescript": "<4.10.0", From 4cebacd3c8aa69c017fdfc471be21b5bbb07011f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Dec 2022 01:59:03 +0000 Subject: [PATCH 05/15] Bump @typescript-eslint/parser from 5.44.0 to 5.47.1 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.44.0 to 5.47.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.47.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 360 ++++++---------------------------------------- package.json | 2 +- 2 files changed, 41 insertions(+), 321 deletions(-) diff --git a/package-lock.json b/package-lock.json index 564df818..46262942 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@types/node": "^18.11.17", "@types/webextension-polyfill": "^0.9.2", "@typescript-eslint/eslint-plugin": "^5.47.1", - "@typescript-eslint/parser": "^5.44.0", + "@typescript-eslint/parser": "^5.47.1", "eslint": "^8.30.0", "ts-loader": "^9.4.2", "typedoc": "^0.23.23", @@ -569,62 +569,15 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/parser": { "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", - "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.1.tgz", + "integrity": "sha512-9Vb+KIv29r6GPu4EboWOnQM7T+UjpjXvjCPhNORlgm40a9Ia9bvaPJswvtae1gip2QEeVeGh6YquqAzEgoRAlw==", "dev": true, "dependencies": { + "@typescript-eslint/scope-manager": "5.47.1", "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.44.0.tgz", - "integrity": "sha512-H7LCqbZnKqkkgQHaKLGC6KUjt3pjJDx8ETDqmwncyb6PuoigYajyAwBGz08VU/l86dZWZgI4zm5k2VaKqayYyA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.44.0", - "@typescript-eslint/types": "5.44.0", - "@typescript-eslint/typescript-estree": "5.44.0", + "@typescript-eslint/typescript-estree": "5.47.1", "debug": "^4.3.4" }, "engines": { @@ -644,13 +597,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.44.0.tgz", - "integrity": "sha512-2pKml57KusI0LAhgLKae9kwWeITZ7IsZs77YxyNyIVOwQ1kToyXRaJLl+uDEXzMN5hnobKUOo2gKntK9H1YL8g==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", + "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.44.0", - "@typescript-eslint/visitor-keys": "5.44.0" + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -687,7 +640,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/types": { "version": "5.47.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", @@ -700,7 +653,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "5.47.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", @@ -727,63 +680,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.44.0.tgz", - "integrity": "sha512-Tp+zDnHmGk4qKR1l+Y1rBvpjpm5tGXX339eAlRBDg+kgZkz9Bw+pqi4dyseOZMsGuSH69fYfPJCBKBrbPCxYFQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.44.0.tgz", - "integrity": "sha512-M6Jr+RM7M5zeRj2maSfsZK2660HKAJawv4Ud0xT+yauyvgrsHu276VtXlKDFnEmhG+nVEd0fYZNXGoAgxwDWJw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.44.0", - "@typescript-eslint/visitor-keys": "5.44.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/@typescript-eslint/utils": { "version": "5.47.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.1.tgz", @@ -810,80 +706,6 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", - "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", - "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -907,12 +729,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.44.0.tgz", - "integrity": "sha512-a48tLG8/4m62gPFbJ27FxwCOqPKxsb8KC3HkmYoq2As/4YyjQl1jDbRr1s63+g4FS/iIehjmN3L5UjmKva1HzQ==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.44.0", + "@typescript-eslint/types": "5.47.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -7841,56 +7663,28 @@ "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", - "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1" - } - }, - "@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/parser": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.44.0.tgz", - "integrity": "sha512-H7LCqbZnKqkkgQHaKLGC6KUjt3pjJDx8ETDqmwncyb6PuoigYajyAwBGz08VU/l86dZWZgI4zm5k2VaKqayYyA==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.1.tgz", + "integrity": "sha512-9Vb+KIv29r6GPu4EboWOnQM7T+UjpjXvjCPhNORlgm40a9Ia9bvaPJswvtae1gip2QEeVeGh6YquqAzEgoRAlw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.44.0", - "@typescript-eslint/types": "5.44.0", - "@typescript-eslint/typescript-estree": "5.44.0", + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/typescript-estree": "5.47.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.44.0.tgz", - "integrity": "sha512-2pKml57KusI0LAhgLKae9kwWeITZ7IsZs77YxyNyIVOwQ1kToyXRaJLl+uDEXzMN5hnobKUOo2gKntK9H1YL8g==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", + "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.44.0", - "@typescript-eslint/visitor-keys": "5.44.0" + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1" } }, "@typescript-eslint/type-utils": { @@ -7903,55 +7697,22 @@ "@typescript-eslint/utils": "5.47.1", "debug": "^4.3.4", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", - "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/types": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.44.0.tgz", - "integrity": "sha512-Tp+zDnHmGk4qKR1l+Y1rBvpjpm5tGXX339eAlRBDg+kgZkz9Bw+pqi4dyseOZMsGuSH69fYfPJCBKBrbPCxYFQ==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.44.0.tgz", - "integrity": "sha512-M6Jr+RM7M5zeRj2maSfsZK2660HKAJawv4Ud0xT+yauyvgrsHu276VtXlKDFnEmhG+nVEd0fYZNXGoAgxwDWJw==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", + "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.44.0", - "@typescript-eslint/visitor-keys": "5.44.0", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -7975,47 +7736,6 @@ "semver": "^7.3.7" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", - "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1" - } - }, - "@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", - "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - } - }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -8035,12 +7755,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.44.0.tgz", - "integrity": "sha512-a48tLG8/4m62gPFbJ27FxwCOqPKxsb8KC3HkmYoq2As/4YyjQl1jDbRr1s63+g4FS/iIehjmN3L5UjmKva1HzQ==", + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", "dev": true, "requires": { - "@typescript-eslint/types": "5.44.0", + "@typescript-eslint/types": "5.47.1", "eslint-visitor-keys": "^3.3.0" } }, diff --git a/package.json b/package.json index ed54a14b..a5bd5b33 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "ts-loader": "^9.4.2", "typedoc": "^0.23.23", "@typescript-eslint/eslint-plugin": "^5.47.1", - "@typescript-eslint/parser": "^5.44.0", + "@typescript-eslint/parser": "^5.47.1", "eslint": "^8.30.0", "typescript": "<4.10.0", "web-ext": "^7.4.0", From 74e2e12523bb7aff099b463c11e6cc74560750a7 Mon Sep 17 00:00:00 2001 From: metastable-void Date: Wed, 28 Dec 2022 00:48:02 +0900 Subject: [PATCH 06/15] per-container overrides ui --- dist/_locales/en/messages.json | 20 +++ dist/components/container-overrides.css | 112 ++++++++++++ dist/components/container-sorter.css | 2 +- src/components/container-overrides.ts | 215 ++++++++++++++++++++++++ src/components/container-sorter.ts | 25 --- src/options/options.ts | 6 + src/overrides/UserAgentSettings.ts | 14 +- 7 files changed, 367 insertions(+), 27 deletions(-) create mode 100644 dist/components/container-overrides.css create mode 100644 src/components/container-overrides.ts diff --git a/dist/_locales/en/messages.json b/dist/_locales/en/messages.json index 872d221e..b291121d 100644 --- a/dist/_locales/en/messages.json +++ b/dist/_locales/en/messages.json @@ -506,5 +506,25 @@ "optionsHeadingContainerOverrides": { "message": "Per-container Overrides", "description": "Heading text of options page for container overrides." + }, + "optionsLabelUserAgent": { + "message": "User Agent", + "description": "Label text for user agent of a container." + }, + "userAgentDefault": { + "message": "Default", + "description": "Default user agent" + }, + "userAgentChrome": { + "message": "Chrome", + "description": "Chrome user agent" + }, + "userAgentGooglebot": { + "message": "Googlebot", + "description": "Googlebot user agent" + }, + "userAgentCustom": { + "message": "Custom", + "description": "Custom user agent" } } \ No newline at end of file diff --git a/dist/components/container-overrides.css b/dist/components/container-overrides.css new file mode 100644 index 00000000..ea7fa0e7 --- /dev/null +++ b/dist/components/container-overrides.css @@ -0,0 +1,112 @@ +/* -*- indent-tabs-mode: nil; tab-width: 2; -*- */ +/* vim: set ts=2 sw=2 et ai : */ + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +@import '/theme.css'; + +@namespace url(http://www.w3.org/1999/xhtml); + +#containers-wrapper { + inline-size: max-content; + max-inline-size: 100%; + display: block grid; + grid-template-columns: .5em 2em 1fr 8em auto auto .5em; + border-radius: .5em; + border: 1px solid var(--border-color); + margin-block: .5em; + box-sizing: border-box; +} + +#containers { + display: grid; + grid-column: 1 / -1; + grid-template-columns: subgrid; +} + +#containers-wrapper > .header { + display: block grid; + grid-column: 1 / -1; + grid-template-columns: subgrid; + align-items: end; + background-color: var(--hover-color); +} + +#containers-wrapper > .header > * { + text-align: center; + padding: .5em; +} + +#containers-wrapper > .header > :not(:first-child) { + border-inline-start: 1px solid var(--border-color); +} + +#containers-wrapper > .header > .header-container { + grid-column: 2 / 4; +} + +#containers-wrapper > .header > .header-user-agent { + grid-column: 5 / 7; +} + +.container { + display: block grid; + grid-column: 1 / -1; + grid-template-columns: subgrid; + border-block-start: 1px solid var(--border-color); +} + +.container::before, .container::after { + content: ''; + display: block; +} + +.container > .name { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding: .5em; +} + +.container :is(.languages, .user-agent-custom) { + inline-size: 100%; + min-inline-size: 0; + box-sizing: border-box; + margin: 0; + font: inherit; + border: none; + border-radius: 0; + padding: .5em; + color: inherit; + background-color: transparent; + align-self: stretch; +} + +.container > .user-agent { + display: block grid; + grid-template-columns: subgrid; + grid-column: 5 / 7; +} + +.container > .user-agent > .user-agent-select { + margin-inline: .5rem; + align-self: center; + margin-block: 0 !important; +} diff --git a/dist/components/container-sorter.css b/dist/components/container-sorter.css index cb0a4e8a..e354d5e1 100644 --- a/dist/components/container-sorter.css +++ b/dist/components/container-sorter.css @@ -27,7 +27,7 @@ inline-size: max-content; max-inline-size: 100%; display: block grid; - grid-template-columns: .5em 2em 1fr 2em 2em min-content auto .5em; + grid-template-columns: .5em 2em 1fr 2em 2em min-content .5em; border-radius: .5em; border: 1px solid var(--border-color); margin-block: .5em; diff --git a/src/components/container-overrides.ts b/src/components/container-overrides.ts new file mode 100644 index 00000000..a6e380e9 --- /dev/null +++ b/src/components/container-overrides.ts @@ -0,0 +1,215 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import browser from 'webextension-polyfill'; +import { UserContext } from "../frameworks/tabGroups"; +import { EventSink } from "../frameworks/utils"; +import { Uint32 } from "../frameworks/types"; +import { CookieAutocleanService } from '../cookies/CookieAutocleanService'; +import { LanguageSettings } from '../languages/LanguageSettings'; +import { UserAgentSettings, UserAgentPreset } from '../overrides/UserAgentSettings'; +import { config } from '../config/config'; + +export class ContainerOverridesElement extends HTMLElement { + private readonly _cookieAutocleanService = CookieAutocleanService.getInstance(); + private readonly _languageSettings = LanguageSettings.getInstance(); + private readonly _userAgentSettings = UserAgentSettings.getInstance(); + public readonly onChanged = new EventSink(); + + public constructor(userContexts: UserContext[]) { + super(); + this.attachShadow({ mode: 'open' }); + if (!this.shadowRoot) { + throw new Error('Shadow root is null'); + } + + const styleSheet = document.createElement('link'); + styleSheet.rel = 'stylesheet'; + styleSheet.href = '/components/container-overrides.css'; + this.shadowRoot.appendChild(styleSheet); + + const containersWrapperElement = document.createElement('div'); + containersWrapperElement.id = 'containers-wrapper'; + this.shadowRoot.appendChild(containersWrapperElement); + + const headerElement = document.createElement('div'); + headerElement.classList.add('header'); + containersWrapperElement.appendChild(headerElement); + + const headerContainerElement = document.createElement('div'); + headerContainerElement.classList.add('header-container'); + headerContainerElement.textContent = browser.i18n.getMessage('menuItemMain'); + headerElement.appendChild(headerContainerElement); + + const headerLanguagesElement = document.createElement('div'); + headerLanguagesElement.classList.add('header-languages'); + headerLanguagesElement.textContent = browser.i18n.getMessage('optionsLabelLanguages'); + headerElement.appendChild(headerLanguagesElement); + + const headerUserAgentElement = document.createElement('div'); + headerUserAgentElement.classList.add('header-user-agent'); + headerUserAgentElement.textContent = browser.i18n.getMessage('optionsLabelUserAgent'); + headerElement.appendChild(headerUserAgentElement); + + const containersElement = document.createElement('div'); + containersElement.id = 'containers'; + containersWrapperElement.appendChild(containersElement); + + this.setUserContexts(userContexts); + } + + private get containersElement(): HTMLDivElement { + const element = this.shadowRoot?.getElementById('containers'); + if (!element) { + throw new Error('Containers element is null'); + } + return element as HTMLDivElement; + } + + private createLanguageOptionsElement(userContext: UserContext): HTMLInputElement { + const originAttributes = userContext.toOriginAttributes(); + const languages = this._languageSettings.getLanguages(originAttributes); + const input = document.createElement('input'); + input.classList.add('languages'); + input.type = 'text'; + input.value = languages; + input.placeholder = navigator.languages.join(','); + input.addEventListener('change', () => { + this._languageSettings.setLanguages(originAttributes, input.value); + }); + this._languageSettings.onChanged.addListener(() => { + input.value = this._languageSettings.getLanguages(originAttributes); + }); + config['feature.languageOverrides'].observe((enabled) => { + input.disabled = !enabled; + }); + return input; + } + + private setUserAgentOptions(userContext: UserContext, select: HTMLSelectElement, input: HTMLInputElement, preset: UserAgentPreset, userAgent?: string) { + const originAttributes = userContext.toOriginAttributes(); + select.value = preset; + if (preset === 'custom') { + input.readOnly = false; + input.value = userAgent || navigator.userAgent; + // this._languageSettings.setUserAgent(originAttributes, userAgent); + } else { + input.readOnly = true; + input.value = this._userAgentSettings.getUserAgent(originAttributes) || navigator.userAgent; + } + } + + private handleUserAgentChange(userContext: UserContext, select: HTMLSelectElement, input: HTMLInputElement) { + const preset = select.value; + const userAgent = input.value.trim(); + this.setUserAgentOptions(userContext, select, input, preset as UserAgentPreset, userAgent); + const originAttributes = userContext.toOriginAttributes(); + this._userAgentSettings.setUserAgent(originAttributes, preset as UserAgentPreset, userAgent || undefined); + } + + private createUserAgentSelectElement(userContext: UserContext, input: HTMLInputElement): HTMLSelectElement { + const select = document.createElement('select'); + select.classList.add('user-agent-select'); + select.classList.add('browser-style'); + const options = { + 'default': 'userAgentDefault', + 'chrome': 'userAgentChrome', + 'googlebot': 'userAgentGooglebot', + 'custom': 'userAgentCustom', + }; + for (const [value, message] of Object.entries(options)) { + const option = document.createElement('option'); + option.value = value; + option.textContent = browser.i18n.getMessage(message); + select.appendChild(option); + } + select.addEventListener('change', () => { + this.handleUserAgentChange(userContext, select, input); + }); + return select; + } + + private createUserAgentOptionsElement(userContext: UserContext): HTMLDivElement { + const originAttributes = userContext.toOriginAttributes(); + const initialParams = this._userAgentSettings.getUserAgentParams(originAttributes); + const element = document.createElement('div'); + element.classList.add('user-agent'); + + const input = document.createElement('input'); + + const select = this.createUserAgentSelectElement(userContext, input); + element.appendChild(select); + + input.classList.add('user-agent-custom'); + input.type = 'text'; + input.placeholder = navigator.userAgent; + input.addEventListener('change', () => { + this.handleUserAgentChange(userContext, select, input); + }); + this._userAgentSettings.onChanged.addListener(() => { + const {preset, userAgent} = this._userAgentSettings.getUserAgentParams(originAttributes); + this.setUserAgentOptions(userContext, select, input, preset, userAgent); + }); + this.setUserAgentOptions(userContext, select, input, initialParams.preset, initialParams.userAgent); + element.appendChild(input); + + config['feature.uaOverrides'].observe((enabled) => { + select.disabled = !enabled; + input.disabled = !enabled; + }); + return element; + } + + private renderUserContext(userContext: UserContext): HTMLDivElement { + const element = document.createElement('div'); + element.classList.add('container'); + element.dataset.userContextId = userContext.id.toString(); + + const iconElement = document.createElement('div'); + iconElement.classList.add('icon'); + iconElement.style.mask = `url(${userContext.iconUrl}) center center / 75% no-repeat`; + iconElement.style.backgroundColor = userContext.colorCode; + element.appendChild(iconElement); + + const nameElement = document.createElement('div'); + nameElement.classList.add('name'); + nameElement.textContent = userContext.name; + element.appendChild(nameElement); + + const languageOptions = this.createLanguageOptionsElement(userContext); + element.appendChild(languageOptions); + + const userAgentOptions = this.createUserAgentOptionsElement(userContext); + element.appendChild(userAgentOptions); + + return element; + } + + public setUserContexts(userContexts: UserContext[]) { + const containersElement = this.containersElement; + containersElement.textContent = ''; + for (const userContext of userContexts) { + containersElement.appendChild(this.renderUserContext(userContext)); + } + } +} + +customElements.define('container-overrides', ContainerOverridesElement); diff --git a/src/components/container-sorter.ts b/src/components/container-sorter.ts index bb19af5b..065a874a 100644 --- a/src/components/container-sorter.ts +++ b/src/components/container-sorter.ts @@ -61,11 +61,6 @@ export class ContainerSorterElement extends HTMLElement { headerAutocleanElement.textContent = browser.i18n.getMessage('enableCookiesAutoclean'); headerElement.appendChild(headerAutocleanElement); - const headerLanguagesElement = document.createElement('div'); - headerLanguagesElement.classList.add('header-languages'); - headerLanguagesElement.textContent = browser.i18n.getMessage('optionsLabelLanguages'); - headerElement.appendChild(headerLanguagesElement); - const containersElement = document.createElement('div'); containersElement.id = 'containers'; containersWrapperElement.appendChild(containersElement); @@ -99,23 +94,6 @@ export class ContainerSorterElement extends HTMLElement { return options; } - private createLanguageOptionsElement(userContext: UserContext): HTMLInputElement { - const originAttributes = userContext.toOriginAttributes(); - const languages = this._languageSettings.getLanguages(originAttributes); - const input = document.createElement('input'); - input.classList.add('languages'); - input.type = 'text'; - input.value = languages; - input.placeholder = navigator.languages.join(','); - input.addEventListener('change', () => { - this._languageSettings.setLanguages(originAttributes, input.value); - }); - this._languageSettings.onChanged.addListener(() => { - input.value = this._languageSettings.getLanguages(originAttributes); - }); - return input; - } - private renderUserContext(userContext: UserContext, autocleanEnabled = false): HTMLDivElement { const element = document.createElement('div'); element.classList.add('container'); @@ -163,9 +141,6 @@ export class ContainerSorterElement extends HTMLElement { const options = this.createOptionsElement(userContext, autocleanEnabled); element.appendChild(options); - const languageOptions = this.createLanguageOptionsElement(userContext); - element.appendChild(languageOptions); - return element; } diff --git a/src/options/options.ts b/src/options/options.ts index f37cec53..ce77ab7d 100644 --- a/src/options/options.ts +++ b/src/options/options.ts @@ -25,6 +25,7 @@ import { UserContext } from '../frameworks/tabGroups'; import { UserContextSortingOrderStore } from '../userContexts/UserContextSortingOrderStore'; import { UserContextService } from '../userContexts/UserContextService'; import { CookieAutocleanService } from '../cookies/CookieAutocleanService'; +import { ContainerOverridesElement } from '../components/container-overrides'; interface HTMLFormInput extends HTMLElement { value: string; @@ -85,6 +86,7 @@ window.addEventListener('hashchange', () => { }); const paneContainers = document.querySelector('#optionsPanes > div[data-pane-name="containers"]'); +const paneContainerOverrides = document.querySelector('#optionsPanes > div[data-pane-name="container-overrides"]'); setTextContent('#link-containers', 'optionsHeadingContainerSortOrder'); setTextContent('#link-container-overrides', 'optionsHeadingContainerOverrides'); @@ -145,11 +147,15 @@ UserContext.getAll().then(async (userContexts) => { const containerSorter = new ContainerSorterElement(sortedUserContext, autocleanEnabledUserContextIds); paneContainers?.appendChild(containerSorter); + const containerOverrides = new ContainerOverridesElement(sortedUserContext); + paneContainerOverrides?.appendChild(containerOverrides); + const callback = async () => { const autocleanEnabledUserContextIds = await cookieAutocleanService.getAutocleanEnabledUserContexts(); const userContexts = (await UserContext.getAll()).map((userContext) => userContextService.fillDefaultValues(userContext)); const sortedUserContext = sortingOrderStore.sort(userContexts); containerSorter.setUserContexts(sortedUserContext, autocleanEnabledUserContextIds); + containerOverrides.setUserContexts(sortedUserContext); }; sortingOrderStore.onChanged.addListener(callback); diff --git a/src/overrides/UserAgentSettings.ts b/src/overrides/UserAgentSettings.ts index 6d866f12..73bd6c7c 100644 --- a/src/overrides/UserAgentSettings.ts +++ b/src/overrides/UserAgentSettings.ts @@ -26,7 +26,7 @@ import { ChromiumReleaseService } from "../modules/ChromiumReleaseService"; export type UserAgentPreset = 'default' | 'chrome' | 'googlebot' | 'custom'; -type UserAgentParams = { +export type UserAgentParams = { preset: UserAgentPreset; userAgent?: string; }; @@ -129,4 +129,16 @@ export class UserAgentSettings { return params.userAgent || ''; } + + public getUserAgentParams(originAttributes: OriginAttributes): UserAgentParams { + const key = this.originAttributesToKey(originAttributes); + const params = this._value[key]; + if (!params) { + return { + preset: 'default', + }; + } + + return params; + } } From 6c957cbcf97740aabc349f07c17c3e7b8f5deeb8 Mon Sep 17 00:00:00 2001 From: metastable-void Date: Thu, 29 Dec 2022 00:54:30 +0900 Subject: [PATCH 07/15] allow to disable language overrides --- src/languages/LanguageStore.ts | 6 +- src/languages/content.ts | 74 ++++++++++++++---------- src/languages/register-content-script.ts | 35 ++++++++++- 3 files changed, 79 insertions(+), 36 deletions(-) diff --git a/src/languages/LanguageStore.ts b/src/languages/LanguageStore.ts index 0bae9924..35a9d787 100644 --- a/src/languages/LanguageStore.ts +++ b/src/languages/LanguageStore.ts @@ -31,9 +31,9 @@ export class LanguageStore { .map((language) => language.trim()) .filter((language) => language.length > 0 && language.match(/^[a-z]{2,3}(?:-[a-z]{2})?$/i)); - if (languageParts.length < 1) { - return; - } + // if (languageParts.length < 1) { + // return; + // } this._languages.length = 0; this._languages.push(... languageParts); diff --git a/src/languages/content.ts b/src/languages/content.ts index 75611059..b2565ec8 100644 --- a/src/languages/content.ts +++ b/src/languages/content.ts @@ -49,39 +49,47 @@ const navigatorPrototypeWrapped = navigatorPrototype.wrappedJSObject; // const descriptors = Object.getOwnPropertyDescriptors(navigatorPrototypeWrapped); -// this is configurable, so deletable -delete navigatorPrototypeWrapped.languages; - -// navigator.languages is a getter, so we need to define it as a getter -Reflect.defineProperty(navigatorPrototypeWrapped, 'languages', { - configurable: true, - enumerable: true, - get: exportFunction(() => { - let languages = gLanguageStore.languageList; - if (languages.length < 1) { - languages = navigator.languages; - } - return cloneInto(languages, window); - }, window), -}); - -// this is configurable, so deletable -delete navigatorPrototypeWrapped.language; - -// navigator.language is a getter, so we need to define it as a getter -Reflect.defineProperty(navigatorPrototypeWrapped, 'language', { - configurable: true, - enumerable: true, - get: exportFunction(() => { - let language = gLanguageStore.language; - if (language === '') { - language = navigator.language; - } - return cloneInto(language, window); - }, window), -}); +let setupDone = false; +const setup = () => { + // this is configurable, so deletable + delete navigatorPrototypeWrapped.languages; + + // navigator.languages is a getter, so we need to define it as a getter + Reflect.defineProperty(navigatorPrototypeWrapped, 'languages', { + configurable: true, + enumerable: true, + get: exportFunction(() => { + let languages = gLanguageStore.languageList; + if (languages.length < 1) { + languages = navigator.languages; + } + return cloneInto(languages, window); + }, window), + }); + + // this is configurable, so deletable + delete navigatorPrototypeWrapped.language; + + // navigator.language is a getter, so we need to define it as a getter + Reflect.defineProperty(navigatorPrototypeWrapped, 'language', { + configurable: true, + enumerable: true, + get: exportFunction(() => { + let language = gLanguageStore.language; + if (language === '') { + language = navigator.language; + } + return cloneInto(language, window); + }, window), + }); + + setupDone = true; +}; gLanguageStore.onLanguagesChanged.addListener(() => { + if (!setupDone && gLanguageStore.language !== '') { + setup(); + } window.dispatchEvent(new Event('languagechange', { bubbles: false, cancelable: false, @@ -96,3 +104,7 @@ browser.runtime.onMessage.addListener((message) => { } } }); + +if (gLanguageStore.language !== '') { + setup(); +} diff --git a/src/languages/register-content-script.ts b/src/languages/register-content-script.ts index dfd68e85..abdb4e0f 100644 --- a/src/languages/register-content-script.ts +++ b/src/languages/register-content-script.ts @@ -23,6 +23,7 @@ import browser from 'webextension-polyfill'; import { LanguageSettings } from "./LanguageSettings"; import { CookieStoreSet } from '../frameworks/tabGroups'; import { OriginAttributes } from '../frameworks/tabGroups'; +import { config } from '../config/config'; const languageSettings = LanguageSettings.getInstance(); let languageSettingsValues = new Map(); @@ -34,7 +35,34 @@ const unregisterContentScript = (key: string) => { contentScripts.delete(key); }; -languageSettings.onChanged.addListener(async () => { +const unregisterAllContentScripts = () => { + for (const key of contentScripts.keys()) { + unregisterContentScript(key); + } +}; + +const emptyLanguageList = async () => { + const browserTabs = await browser.tabs.query({}); + for (const browserTab of browserTabs) { + if (null == browserTab.id) continue; + + browser.tabs.sendMessage(browserTab.id, { + type: 'language-changed', + languages: '', + }).catch(() => { + // ignore. + }); + } +} + +const update = async () => { + const enabled = await config['feature.languageOverrides'].getValue(); + if (!enabled) { + unregisterAllContentScripts(); + await emptyLanguageList(); + return; + } + const cookieStores = await cookieStoreSet.getAll(); const newValues = new Map(); for (const originAttributes of cookieStores) { @@ -89,4 +117,7 @@ languageSettings.onChanged.addListener(async () => { // ignore. }); } -}); +}; + +config['feature.languageOverrides'].observe(update); +languageSettings.onChanged.addListener(update); From 991a22664ea243eecd493303dff8e0fda1d573e8 Mon Sep 17 00:00:00 2001 From: metastable-void Date: Thu, 29 Dec 2022 01:21:43 +0900 Subject: [PATCH 08/15] CookieStore implementation --- src/frameworks/tabGroups/CookieStore.ts | 68 +++++++++++++++++++ src/frameworks/tabGroups/CookieStoreParams.ts | 27 ++++++++ 2 files changed, 95 insertions(+) create mode 100644 src/frameworks/tabGroups/CookieStore.ts create mode 100644 src/frameworks/tabGroups/CookieStoreParams.ts diff --git a/src/frameworks/tabGroups/CookieStore.ts b/src/frameworks/tabGroups/CookieStore.ts new file mode 100644 index 00000000..08dc6336 --- /dev/null +++ b/src/frameworks/tabGroups/CookieStore.ts @@ -0,0 +1,68 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import { Uint32 } from "../types"; +import { CookieStoreParams } from "./CookieStoreParams"; + +export class CookieStore implements CookieStoreParams { + private static readonly DEFAULT_STORE = 'firefox-default'; + private static readonly PRIVATE_STORE = 'firefox-private'; + private static readonly CONTAINER_STORE = 'firefox-container-'; + + public readonly id: string; + public readonly userContextId: Uint32.Uint32; + public readonly privateBrowsingId: Uint32.Uint32; + + public static fromParams(params: CookieStoreParams): CookieStore { + if (params.privateBrowsingId !== 0) { + return new CookieStore(CookieStore.PRIVATE_STORE); + } + if (params.userContextId === 0) { + return new CookieStore(CookieStore.DEFAULT_STORE); + } + return new CookieStore(`${CookieStore.CONTAINER_STORE}${params.userContextId}`); + } + + public constructor(cookieStoreId: string) { + this.id = cookieStoreId; + + if (cookieStoreId === CookieStore.DEFAULT_STORE) { + this.userContextId = 0 as Uint32.Uint32; + this.privateBrowsingId = 0 as Uint32.Uint32; + } else if (cookieStoreId === CookieStore.PRIVATE_STORE) { + this.userContextId = 0 as Uint32.Uint32; + this.privateBrowsingId = 1 as Uint32.Uint32; + } else if (cookieStoreId.startsWith(CookieStore.CONTAINER_STORE)) { + const userContextId = Uint32.fromString(cookieStoreId.slice(CookieStore.CONTAINER_STORE.length)); + this.userContextId = userContextId; + this.privateBrowsingId = 0 as Uint32.Uint32; + } + throw new Error(`CookieStore.constructor(): invalid cookieStoreId: ${cookieStoreId}`); + } + + public get isPrivate(): boolean { + return this.privateBrowsingId !== 0; + } + + public toString(): string { + return this.id; + } +} diff --git a/src/frameworks/tabGroups/CookieStoreParams.ts b/src/frameworks/tabGroups/CookieStoreParams.ts new file mode 100644 index 00000000..8325fcd1 --- /dev/null +++ b/src/frameworks/tabGroups/CookieStoreParams.ts @@ -0,0 +1,27 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import { Uint32 } from "../types"; + +export interface CookieStoreParams { + readonly userContextId: Uint32.Uint32; + readonly privateBrowsingId: Uint32.Uint32; +} From 3153f2cfc7e8e394079a945aea5210b924d61644 Mon Sep 17 00:00:00 2001 From: metastable-void Date: Thu, 29 Dec 2022 01:39:09 +0900 Subject: [PATCH 09/15] webpack use source-map --- .gitignore | 3 ++- webpack.config.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 1911f3ef..328336f7 100644 --- a/.gitignore +++ b/.gitignore @@ -95,6 +95,7 @@ ts-dist # Webpack output dist/**/*.js +dist/**/*.js.map # web-ext output *.xpi @@ -179,4 +180,4 @@ $RECYCLE.BIN/ *.msi *.msm *.msp -*.lnk \ No newline at end of file +*.lnk diff --git a/webpack.config.js b/webpack.config.js index 8585e876..8f509c18 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,8 +9,8 @@ const path = require('path'); module.exports = { mode: 'production', context: __dirname, - target: ['web', 'es2020'], - devtool: 'inline-cheap-source-map', + target: ['web', 'es2021'], + devtool: 'source-map', resolve: { extensions: ['.ts', '.d.ts', '.js'], From 6a55c4dd7bc1d0996852f590245f20eb4c891582 Mon Sep 17 00:00:00 2001 From: metastable-void Date: Thu, 29 Dec 2022 02:00:53 +0900 Subject: [PATCH 10/15] ExtendedCookieStore --- src/frameworks/tabGroups/CookieStore.ts | 47 +++++++++++-------- .../tabGroups/ExtendedCookieStore.ts | 32 +++++++++++++ .../tabGroups/ExtendedCookieStoreParams.ts | 26 ++++++++++ 3 files changed, 85 insertions(+), 20 deletions(-) create mode 100644 src/frameworks/tabGroups/ExtendedCookieStore.ts create mode 100644 src/frameworks/tabGroups/ExtendedCookieStoreParams.ts diff --git a/src/frameworks/tabGroups/CookieStore.ts b/src/frameworks/tabGroups/CookieStore.ts index 08dc6336..4cd0f747 100644 --- a/src/frameworks/tabGroups/CookieStore.ts +++ b/src/frameworks/tabGroups/CookieStore.ts @@ -31,31 +31,38 @@ export class CookieStore implements CookieStoreParams { public readonly userContextId: Uint32.Uint32; public readonly privateBrowsingId: Uint32.Uint32; - public static fromParams(params: CookieStoreParams): CookieStore { - if (params.privateBrowsingId !== 0) { - return new CookieStore(CookieStore.PRIVATE_STORE); - } - if (params.userContextId === 0) { - return new CookieStore(CookieStore.DEFAULT_STORE); - } - return new CookieStore(`${CookieStore.CONTAINER_STORE}${params.userContextId}`); - } - - public constructor(cookieStoreId: string) { - this.id = cookieStoreId; - + public static fromId(cookieStoreId: string): CookieStore { if (cookieStoreId === CookieStore.DEFAULT_STORE) { - this.userContextId = 0 as Uint32.Uint32; - this.privateBrowsingId = 0 as Uint32.Uint32; + return new CookieStore({ + userContextId: 0 as Uint32.Uint32, + privateBrowsingId: 0 as Uint32.Uint32, + }); } else if (cookieStoreId === CookieStore.PRIVATE_STORE) { - this.userContextId = 0 as Uint32.Uint32; - this.privateBrowsingId = 1 as Uint32.Uint32; + return new CookieStore({ + userContextId: 0 as Uint32.Uint32, + privateBrowsingId: 1 as Uint32.Uint32, + }); } else if (cookieStoreId.startsWith(CookieStore.CONTAINER_STORE)) { const userContextId = Uint32.fromString(cookieStoreId.slice(CookieStore.CONTAINER_STORE.length)); - this.userContextId = userContextId; - this.privateBrowsingId = 0 as Uint32.Uint32; + return new CookieStore({ + userContextId, + privateBrowsingId: 0 as Uint32.Uint32, + }); + } + throw new Error(`CookieStore.fromId(): invalid cookieStoreId: ${cookieStoreId}`); + } + + public constructor(params: CookieStoreParams) { + this.userContextId = params.userContextId; + this.privateBrowsingId = params.privateBrowsingId; + + if (this.privateBrowsingId !== 0) { + this.id = CookieStore.PRIVATE_STORE; + } else if (this.userContextId === 0) { + this.id = CookieStore.DEFAULT_STORE; + } else { + this.id = `${CookieStore.CONTAINER_STORE}${this.userContextId}`; } - throw new Error(`CookieStore.constructor(): invalid cookieStoreId: ${cookieStoreId}`); } public get isPrivate(): boolean { diff --git a/src/frameworks/tabGroups/ExtendedCookieStore.ts b/src/frameworks/tabGroups/ExtendedCookieStore.ts new file mode 100644 index 00000000..07610674 --- /dev/null +++ b/src/frameworks/tabGroups/ExtendedCookieStore.ts @@ -0,0 +1,32 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import { ExtendedCookieStoreParams } from "./ExtendedCookieStoreParams"; +import { CookieStore } from "./CookieStore"; + +export class ExtendedCookieStore extends CookieStore implements ExtendedCookieStoreParams { + public readonly firstPartyDomain: string; + + public constructor(params: ExtendedCookieStoreParams) { + super(params); + this.firstPartyDomain = params.firstPartyDomain; + } +} diff --git a/src/frameworks/tabGroups/ExtendedCookieStoreParams.ts b/src/frameworks/tabGroups/ExtendedCookieStoreParams.ts new file mode 100644 index 00000000..d618de7c --- /dev/null +++ b/src/frameworks/tabGroups/ExtendedCookieStoreParams.ts @@ -0,0 +1,26 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import { CookieStoreParams } from "./CookieStoreParams"; + +export interface ExtendedCookieStoreParams extends CookieStoreParams { + readonly firstPartyDomain: string; +} From c6f546145fb1a673e460e48990427bf4d651869e Mon Sep 17 00:00:00 2001 From: metastable-void Date: Thu, 29 Dec 2022 13:17:02 +0900 Subject: [PATCH 11/15] container handling rewrite --- .../tabAttributes/ContextualIdentity.ts | 75 +++++++++++++++++++ .../tabAttributes/ContextualIdentityParams.ts | 31 ++++++++ .../ContextualIdentityUniqueParams.ts | 29 +++++++ .../CookieStore.ts | 0 .../CookieStoreParams.ts | 0 .../ExtendedCookieStore.ts | 0 .../ExtendedCookieStoreParams.ts | 0 7 files changed, 135 insertions(+) create mode 100644 src/frameworks/tabAttributes/ContextualIdentity.ts create mode 100644 src/frameworks/tabAttributes/ContextualIdentityParams.ts create mode 100644 src/frameworks/tabAttributes/ContextualIdentityUniqueParams.ts rename src/frameworks/{tabGroups => tabAttributes}/CookieStore.ts (100%) rename src/frameworks/{tabGroups => tabAttributes}/CookieStoreParams.ts (100%) rename src/frameworks/{tabGroups => tabAttributes}/ExtendedCookieStore.ts (100%) rename src/frameworks/{tabGroups => tabAttributes}/ExtendedCookieStoreParams.ts (100%) diff --git a/src/frameworks/tabAttributes/ContextualIdentity.ts b/src/frameworks/tabAttributes/ContextualIdentity.ts new file mode 100644 index 00000000..985144e7 --- /dev/null +++ b/src/frameworks/tabAttributes/ContextualIdentity.ts @@ -0,0 +1,75 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import browser from 'webextension-polyfill'; +import { ContextualIdentityParams } from "./ContextualIdentityParams"; +import { ContextualIdentityUniqueParams } from "./ContextualIdentityUniqueParams"; +import { CookieStore } from "./CookieStore"; + +export class ContextualIdentity extends CookieStore implements ContextualIdentityParams { + public readonly name: string; + public readonly icon: string; + public readonly color: string; + + public static fromWebExtensionsContetualIdentity(identity: browser.ContextualIdentities.ContextualIdentity): ContextualIdentity { + const params: ContextualIdentityParams = { + ... CookieStore.fromId(identity.cookieStoreId), + name: identity.name, + icon: identity.icon, + color: identity.color, + }; + return new ContextualIdentity(params); + } + + public static async get(cookieStoreId: string): Promise { + const identity = await browser.contextualIdentities.get(cookieStoreId); + return ContextualIdentity.fromWebExtensionsContetualIdentity(identity); + } + + /** + * This returns all ContextualIdentities defined, but not all CookieStores, + * for example, the default CookieStore is not returned. + * @returns All ContextualIdentities + */ + public static async getAll(): Promise { + const identities = await browser.contextualIdentities.query({}); + return identities.map(ContextualIdentity.fromWebExtensionsContetualIdentity); + } + + public static async create(params: ContextualIdentityUniqueParams): Promise { + const identity = await browser.contextualIdentities.create(params); + return ContextualIdentity.fromWebExtensionsContetualIdentity(identity); + } + + constructor(params: ContextualIdentityParams) { + super(params); + this.name = params.name; + this.icon = params.icon; + this.color = params.color; + } + + public async setParams(params: ContextualIdentityUniqueParams): Promise { + // + const updated = await browser.contextualIdentities.update(this.id, params); + return ContextualIdentity.fromWebExtensionsContetualIdentity(updated); + } + +} diff --git a/src/frameworks/tabAttributes/ContextualIdentityParams.ts b/src/frameworks/tabAttributes/ContextualIdentityParams.ts new file mode 100644 index 00000000..9a4454c7 --- /dev/null +++ b/src/frameworks/tabAttributes/ContextualIdentityParams.ts @@ -0,0 +1,31 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import { CookieStoreParams } from "./CookieStoreParams"; +import { ContextualIdentityUniqueParams } from "./ContextualIdentityUniqueParams"; + +/** + * The parameters for a contextual identity. This interface represents + * the containers **defined** in Firefox. For the containers **displayed** in + * the UI (may not be defined in the browser in rare cases), see {@link ContainerAttributes}. + * @see https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities/ContextualIdentity + */ +export interface ContextualIdentityParams extends CookieStoreParams, ContextualIdentityUniqueParams {} diff --git a/src/frameworks/tabAttributes/ContextualIdentityUniqueParams.ts b/src/frameworks/tabAttributes/ContextualIdentityUniqueParams.ts new file mode 100644 index 00000000..275982cb --- /dev/null +++ b/src/frameworks/tabAttributes/ContextualIdentityUniqueParams.ts @@ -0,0 +1,29 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +/** + * The diff between a CookieStoreParams and a ContextualIdentityParams + */ +export interface ContextualIdentityUniqueParams { + name: string; + icon: string; + color: string; +} diff --git a/src/frameworks/tabGroups/CookieStore.ts b/src/frameworks/tabAttributes/CookieStore.ts similarity index 100% rename from src/frameworks/tabGroups/CookieStore.ts rename to src/frameworks/tabAttributes/CookieStore.ts diff --git a/src/frameworks/tabGroups/CookieStoreParams.ts b/src/frameworks/tabAttributes/CookieStoreParams.ts similarity index 100% rename from src/frameworks/tabGroups/CookieStoreParams.ts rename to src/frameworks/tabAttributes/CookieStoreParams.ts diff --git a/src/frameworks/tabGroups/ExtendedCookieStore.ts b/src/frameworks/tabAttributes/ExtendedCookieStore.ts similarity index 100% rename from src/frameworks/tabGroups/ExtendedCookieStore.ts rename to src/frameworks/tabAttributes/ExtendedCookieStore.ts diff --git a/src/frameworks/tabGroups/ExtendedCookieStoreParams.ts b/src/frameworks/tabAttributes/ExtendedCookieStoreParams.ts similarity index 100% rename from src/frameworks/tabGroups/ExtendedCookieStoreParams.ts rename to src/frameworks/tabAttributes/ExtendedCookieStoreParams.ts From c68b5fa2a60cb52bfec57017c3f74f5d797c7ab4 Mon Sep 17 00:00:00 2001 From: metastable-void Date: Thu, 29 Dec 2022 13:33:39 +0900 Subject: [PATCH 12/15] icon generation script from tree style tab --- Makefile | 3 + dist/img/contextual-identities/briefcase.svg | 14 +++ dist/img/contextual-identities/cart.svg | 14 +++ dist/img/contextual-identities/chill.svg | 14 +++ dist/img/contextual-identities/circle.svg | 14 +++ dist/img/contextual-identities/dollar.svg | 14 +++ dist/img/contextual-identities/fence.svg | 14 +++ .../img/contextual-identities/fingerprint.svg | 14 +++ dist/img/contextual-identities/food.svg | 14 +++ dist/img/contextual-identities/fruit.svg | 14 +++ dist/img/contextual-identities/gift.svg | 14 +++ dist/img/contextual-identities/pet.svg | 14 +++ dist/img/contextual-identities/tree.svg | 14 +++ dist/img/contextual-identities/vacation.svg | 14 +++ script/update-contextual-identities-icons.sh | 85 +++++++++++++++++++ 15 files changed, 270 insertions(+) create mode 100644 dist/img/contextual-identities/briefcase.svg create mode 100644 dist/img/contextual-identities/cart.svg create mode 100644 dist/img/contextual-identities/chill.svg create mode 100644 dist/img/contextual-identities/circle.svg create mode 100644 dist/img/contextual-identities/dollar.svg create mode 100644 dist/img/contextual-identities/fence.svg create mode 100644 dist/img/contextual-identities/fingerprint.svg create mode 100644 dist/img/contextual-identities/food.svg create mode 100644 dist/img/contextual-identities/fruit.svg create mode 100644 dist/img/contextual-identities/gift.svg create mode 100644 dist/img/contextual-identities/pet.svg create mode 100644 dist/img/contextual-identities/tree.svg create mode 100644 dist/img/contextual-identities/vacation.svg create mode 100755 script/update-contextual-identities-icons.sh diff --git a/Makefile b/Makefile index e442c09e..c6063b87 100644 --- a/Makefile +++ b/Makefile @@ -9,3 +9,6 @@ clean: typedoc: npm run typedoc + +icons: + cd script && ./update-contextual-identities-icons.sh diff --git a/dist/img/contextual-identities/briefcase.svg b/dist/img/contextual-identities/briefcase.svg new file mode 100644 index 00000000..1b615c31 --- /dev/null +++ b/dist/img/contextual-identities/briefcase.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/cart.svg b/dist/img/contextual-identities/cart.svg new file mode 100644 index 00000000..5df0b2fd --- /dev/null +++ b/dist/img/contextual-identities/cart.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/chill.svg b/dist/img/contextual-identities/chill.svg new file mode 100644 index 00000000..65cd45a2 --- /dev/null +++ b/dist/img/contextual-identities/chill.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/circle.svg b/dist/img/contextual-identities/circle.svg new file mode 100644 index 00000000..e3ceed77 --- /dev/null +++ b/dist/img/contextual-identities/circle.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/dollar.svg b/dist/img/contextual-identities/dollar.svg new file mode 100644 index 00000000..acc96eac --- /dev/null +++ b/dist/img/contextual-identities/dollar.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/fence.svg b/dist/img/contextual-identities/fence.svg new file mode 100644 index 00000000..d96775e4 --- /dev/null +++ b/dist/img/contextual-identities/fence.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/fingerprint.svg b/dist/img/contextual-identities/fingerprint.svg new file mode 100644 index 00000000..26926675 --- /dev/null +++ b/dist/img/contextual-identities/fingerprint.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/food.svg b/dist/img/contextual-identities/food.svg new file mode 100644 index 00000000..cd355828 --- /dev/null +++ b/dist/img/contextual-identities/food.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/fruit.svg b/dist/img/contextual-identities/fruit.svg new file mode 100644 index 00000000..d4147f1c --- /dev/null +++ b/dist/img/contextual-identities/fruit.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/gift.svg b/dist/img/contextual-identities/gift.svg new file mode 100644 index 00000000..56029ec6 --- /dev/null +++ b/dist/img/contextual-identities/gift.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/pet.svg b/dist/img/contextual-identities/pet.svg new file mode 100644 index 00000000..4c1899bd --- /dev/null +++ b/dist/img/contextual-identities/pet.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/tree.svg b/dist/img/contextual-identities/tree.svg new file mode 100644 index 00000000..888d9883 --- /dev/null +++ b/dist/img/contextual-identities/tree.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/dist/img/contextual-identities/vacation.svg b/dist/img/contextual-identities/vacation.svg new file mode 100644 index 00000000..dfdc9b12 --- /dev/null +++ b/dist/img/contextual-identities/vacation.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/script/update-contextual-identities-icons.sh b/script/update-contextual-identities-icons.sh new file mode 100755 index 00000000..5c53a517 --- /dev/null +++ b/script/update-contextual-identities-icons.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +# adapted from https://github.com/piroor/treestyletab/blob/84f49a91c038acc52bc7aa37aab0a572717eeaa2/webextensions/update-contextual-identities-icons.sh + +mkdir -p "$(dirname "$0")"/../dist/img +cd "$(dirname "$0")"/../dist/img + +mkdir -p contextual-identities +cd contextual-identities + +BASE='https://hg.mozilla.org/mozilla-central/raw-file/tip/browser/components/contextualidentity/content/' + +echo 'Fetching SVG icons...' +curl 'https://hg.mozilla.org/mozilla-central/file/tip/browser/components/contextualidentity/content/' | + grep '>file<' | + egrep -o '[^/]+\.svg' | + while read name; do + curl -O "${BASE}${name}" + done + + +TEMPLATE="$(cat << END + + + + +%SOURCE% + +%COLORS% + +END +)" + +COLORS="$(cat << END +blue #37adff +turquoise #00c79a +green #51cd00 +yellow #ffcb00 +orange #ff9f00 +red #ff613d +pink #ff4bda +purple #af51f5 +toolbar-dark #F9F9FA +toolbar-light #0C0C0D +END +)" + +case $(uname) in + Darwin|*BSD|CYGWIN*) + esed="sed -E" + ;; + *) + esed="sed -r" + ;; +esac + +colors() { + echo "$COLORS" | + while read set + do + name="$(echo "$set" | $esed 's/ +.*$//')" + color="$(echo "$set" | $esed 's/^[^ ]* *//')" + echo -n "" + done +} + +for file in *.svg; do + echo "Updating ${file}..." + svg="$(cat "${file}" | tr -d '\n')" + mv "${file}" "/tmp/${file}" + width="$(echo "$svg" | $esed 's/^.*width="([^"]+)".*$/\1/')" + height="$(echo "$svg" | $esed 's/^.*height="([^"]+)".*$/\1/')" + echo "$TEMPLATE" | + sed -e "s;%SOURCE%;$(echo "$svg" | $esed 's;|]*>|fill="context-fill";;g');" \ + -e "s;%COLORS%;$(colors);" \ + -e "s;%WIDTH%;${width};g" \ + -e "s;%HEIGHT%;${height};g" \ + > "${file}" +done From 468a71e5efc3d711b7e220d8f63cd49bf25352ba Mon Sep 17 00:00:00 2001 From: metastable-void Date: Thu, 29 Dec 2022 21:23:20 +0900 Subject: [PATCH 13/15] new user agent & language overrides --- dist/manifest.json | 2 +- src/background.ts | 3 + src/components/container-overrides.ts | 8 +- src/{languages => content}/LanguageStore.ts | 0 src/content/UaStore.ts | 48 ++++ .../content-interfaces.ts | 0 src/content/content.ts | 241 ++++++++++++++++++ .../tabAttributes/ContainerAttributes.ts | 85 ++++++ .../tabAttributes/ContextualIdentity.ts | 2 +- src/frameworks/tabAttributes/CookieStore.ts | 46 ++++ src/languages/content.ts | 110 -------- src/languages/register-content-script.ts | 1 - .../ChromiumReleaseService.ts | 2 - src/overrides/ContentScriptRegistrar.ts | 74 ++++++ src/overrides/UaContentScriptRegistrar.ts | 101 ++++++++ src/overrides/UserAgentSettings.ts | 37 +-- src/overrides/fetch.ts | 37 ++- webpack.config.js | 4 +- 18 files changed, 658 insertions(+), 143 deletions(-) rename src/{languages => content}/LanguageStore.ts (100%) create mode 100644 src/content/UaStore.ts rename src/{languages => content}/content-interfaces.ts (100%) create mode 100644 src/content/content.ts create mode 100644 src/frameworks/tabAttributes/ContainerAttributes.ts delete mode 100644 src/languages/content.ts rename src/{modules => overrides}/ChromiumReleaseService.ts (98%) create mode 100644 src/overrides/ContentScriptRegistrar.ts create mode 100644 src/overrides/UaContentScriptRegistrar.ts diff --git a/dist/manifest.json b/dist/manifest.json index 92c4d768..84d94697 100644 --- a/dist/manifest.json +++ b/dist/manifest.json @@ -81,7 +81,7 @@ "" ], "js": [ - "languages/content.js" + "content/content.js" ], "all_frames": true, "run_at": "document_start" diff --git a/src/background.ts b/src/background.ts index 2bf48769..3943bae7 100644 --- a/src/background.ts +++ b/src/background.ts @@ -38,6 +38,7 @@ import './background/BackgroundCookieAutoclean'; import './api/ApiDefinitions'; import './overrides/fetch'; import './languages/register-content-script'; +import { UaContentScriptRegistrar} from './overrides/UaContentScriptRegistrar'; // watchdog let scriptCompleted = false; @@ -303,6 +304,8 @@ const beforeRequestHandler = new BeforeRequestHandler(async (details) => { return true; }); +new UaContentScriptRegistrar(); + setTimeout(() => { beforeRequestHandler.startListening(); }, 1000); diff --git a/src/components/container-overrides.ts b/src/components/container-overrides.ts index a6e380e9..cb86726d 100644 --- a/src/components/container-overrides.ts +++ b/src/components/container-overrides.ts @@ -113,7 +113,7 @@ export class ContainerOverridesElement extends HTMLElement { // this._languageSettings.setUserAgent(originAttributes, userAgent); } else { input.readOnly = true; - input.value = this._userAgentSettings.getUserAgent(originAttributes) || navigator.userAgent; + input.value = this._userAgentSettings.getUserAgent(originAttributes.cookieStoreId) || navigator.userAgent; } } @@ -122,7 +122,7 @@ export class ContainerOverridesElement extends HTMLElement { const userAgent = input.value.trim(); this.setUserAgentOptions(userContext, select, input, preset as UserAgentPreset, userAgent); const originAttributes = userContext.toOriginAttributes(); - this._userAgentSettings.setUserAgent(originAttributes, preset as UserAgentPreset, userAgent || undefined); + this._userAgentSettings.setUserAgent(originAttributes.cookieStoreId, preset as UserAgentPreset, userAgent || undefined); } private createUserAgentSelectElement(userContext: UserContext, input: HTMLInputElement): HTMLSelectElement { @@ -149,7 +149,7 @@ export class ContainerOverridesElement extends HTMLElement { private createUserAgentOptionsElement(userContext: UserContext): HTMLDivElement { const originAttributes = userContext.toOriginAttributes(); - const initialParams = this._userAgentSettings.getUserAgentParams(originAttributes); + const initialParams = this._userAgentSettings.getUserAgentParams(originAttributes.cookieStoreId); const element = document.createElement('div'); element.classList.add('user-agent'); @@ -165,7 +165,7 @@ export class ContainerOverridesElement extends HTMLElement { this.handleUserAgentChange(userContext, select, input); }); this._userAgentSettings.onChanged.addListener(() => { - const {preset, userAgent} = this._userAgentSettings.getUserAgentParams(originAttributes); + const {preset, userAgent} = this._userAgentSettings.getUserAgentParams(originAttributes.cookieStoreId); this.setUserAgentOptions(userContext, select, input, preset, userAgent); }); this.setUserAgentOptions(userContext, select, input, initialParams.preset, initialParams.userAgent); diff --git a/src/languages/LanguageStore.ts b/src/content/LanguageStore.ts similarity index 100% rename from src/languages/LanguageStore.ts rename to src/content/LanguageStore.ts diff --git a/src/content/UaStore.ts b/src/content/UaStore.ts new file mode 100644 index 00000000..abb8ece6 --- /dev/null +++ b/src/content/UaStore.ts @@ -0,0 +1,48 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import { EventSink } from "../frameworks/utils"; + +export class UaStore { + private _userAgent = ''; + private _emulationMode = 'none'; + private readonly _languages: string[] = []; + + public readonly onChanged = new EventSink(); + + public set userAgent(userAgent: string) { + this._userAgent = userAgent; + this.onChanged.dispatch(); + } + + public get userAgent(): string { + return this._userAgent; + } + + public set emulationMode(emulationMode: string) { + this._emulationMode = emulationMode; + this.onChanged.dispatch(); + } + + public get emulationMode(): string { + return this._emulationMode; + } +} diff --git a/src/languages/content-interfaces.ts b/src/content/content-interfaces.ts similarity index 100% rename from src/languages/content-interfaces.ts rename to src/content/content-interfaces.ts diff --git a/src/content/content.ts b/src/content/content.ts new file mode 100644 index 00000000..c30030ba --- /dev/null +++ b/src/content/content.ts @@ -0,0 +1,241 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import browser from 'webextension-polyfill'; +import { LanguageStore } from './LanguageStore'; +import { UaStore } from './UaStore'; +import './content-interfaces'; + +declare global { + // eslint-disable-next-line no-var + var gLanguageStore: LanguageStore; + + // eslint-disable-next-line no-var + var gUaStore: UaStore; +} + +browser.runtime.sendMessage({ + type: 'content-script-loaded', + url: window.location.href, +}).catch(() => { + // ignore. +}); + +let languages = null; +if (globalThis.gLanguageStore) { + languages = gLanguageStore.languages; +} +globalThis.gLanguageStore = new LanguageStore(); +if (languages) { + gLanguageStore.languages = languages; +} + +let userAgent = null; +let emulationMode = null; +if (globalThis.gUaStore) { + userAgent = gUaStore.userAgent; + emulationMode = gUaStore.emulationMode; +} +globalThis.gUaStore = new UaStore(); +if (userAgent) { + gUaStore.userAgent = userAgent; +} +if (emulationMode) { + gUaStore.emulationMode = emulationMode; +} + +const navigatorPrototype = Object.getPrototypeOf(navigator); +const navigatorPrototypeWrapped = navigatorPrototype.wrappedJSObject; + +// const descriptors = Object.getOwnPropertyDescriptors(navigatorPrototypeWrapped); + +let languageSetupDone = false; +const setUpLanguageOverrides = () => { + // this is configurable, so deletable + delete navigatorPrototypeWrapped.languages; + + // navigator.languages is a getter, so we need to define it as a getter + Reflect.defineProperty(navigatorPrototypeWrapped, 'languages', { + configurable: true, + enumerable: true, + get: exportFunction(() => { + let languages = gLanguageStore.languageList; + if (languages.length < 1) { + languages = navigator.languages; + } + return cloneInto(languages, window); + }, window), + }); + + // this is configurable, so deletable + delete navigatorPrototypeWrapped.language; + + // navigator.language is a getter, so we need to define it as a getter + Reflect.defineProperty(navigatorPrototypeWrapped, 'language', { + configurable: true, + enumerable: true, + get: exportFunction(() => { + let language = gLanguageStore.language; + if (language === '') { + language = navigator.language; + } + return cloneInto(language, window); + }, window), + }); + + languageSetupDone = true; +}; + +gLanguageStore.onLanguagesChanged.addListener(() => { + if (!languageSetupDone && gLanguageStore.language !== '') { + setUpLanguageOverrides(); + } + window.dispatchEvent(new Event('languagechange', { + bubbles: false, + cancelable: false, + })); +}); + +const getUaDataPlatform = () => { + const userAgent = navigator.userAgent; + if (userAgent.includes('Windows')) { + return 'Windows'; + } else if (userAgent.includes('Macintosh')) { + return 'macOS'; + } + return 'Linux'; +}; + +let uaSetupDone = false; +const setupUaOverrides = () => { + try { + // this is configurable, so deletable + delete navigatorPrototypeWrapped.userAgent; + + // navigator.userAgent is a getter, so we need to define it as a getter + Reflect.defineProperty(navigatorPrototypeWrapped, 'userAgent', { + configurable: true, + enumerable: true, + get: exportFunction(() => { + let userAgent = gUaStore.userAgent; + if (userAgent === '') { + userAgent = navigator.userAgent; + } + return cloneInto(userAgent, window); + }, window), + }); + + // this is configurable, so deletable + delete navigatorPrototypeWrapped.userAgentData; + Reflect.defineProperty(navigatorPrototypeWrapped, 'userAgentData', { + configurable: true, + enumerable: true, + get: exportFunction(() => { + const emulationMode = gUaStore.emulationMode; + if (emulationMode === 'none') { + return undefined; + } + const userAgent = gUaStore.userAgent; + const chromeVersion = (userAgent.match(/Chrome\/([0-9]+)/) ?? []).pop() ?? '108'; + return cloneInto({ + brands: [ + { + "brand": "Not?A_Brand", + "version": "8", + }, + { + "brand": "Chromium", + "version": chromeVersion, + }, + { + "brand": "Google Chrome", + "version": chromeVersion, + }, + ], + + mobile: false, + + platform: getUaDataPlatform(), + + toJSON() { + return cloneInto({ + brands: this.brands, + mobile: this.mobile, + platform: this.platform, + }, window); + }, + + getHighEntropyValues() { + return window.Promise.resolve(cloneInto({ + brands: this.brands, + mobile: this.mobile, + platform: this.platform, + platformVersion: '', + architecture: '', + bitness: '', + model: '', + uaFullVersion: '', + fullVersionList: [], + }, window)); + }, + }, window, { + cloneFunctions: true, + }); + }, window), + }); + } catch (e) { + console.error(String(e)); + } + + uaSetupDone = true; +}; + +gUaStore.onChanged.addListener(() => { + if (!uaSetupDone && gUaStore.userAgent !== '') { + setupUaOverrides(); + } +}); + +browser.runtime.onMessage.addListener((message) => { + if (message.type === 'language-changed') { + const languages = String(message.languages ?? ''); + if (gLanguageStore.languages !== languages) { + gLanguageStore.languages = languages; + } + } else if (message.type === 'ua-changed') { + const userAgent = String(message.userAgent ?? ''); + const emulationMode = String(message.emulationMode ?? 'none'); + if (gUaStore.userAgent !== userAgent) { + gUaStore.userAgent = userAgent; + } + if (gUaStore.emulationMode !== emulationMode) { + gUaStore.emulationMode = emulationMode; + } + } +}); + +if (gLanguageStore.language !== '') { + setUpLanguageOverrides(); +} + +if (gUaStore.userAgent !== '') { + setupUaOverrides(); +} diff --git a/src/frameworks/tabAttributes/ContainerAttributes.ts b/src/frameworks/tabAttributes/ContainerAttributes.ts new file mode 100644 index 00000000..d44abea0 --- /dev/null +++ b/src/frameworks/tabAttributes/ContainerAttributes.ts @@ -0,0 +1,85 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import browser from 'webextension-polyfill'; +import { ContextualIdentity } from "./ContextualIdentity"; +import { CookieStoreParams } from "./CookieStoreParams"; +import { CookieStore } from './CookieStore'; + +export class ContainerAttributes extends ContextualIdentity { + // TODO: allow theming, or consider syncing with Firefox's theme + private static readonly _COLORS: { [color: string]: string } = { + "blue": "#37adff", + "green": "#51cd00", + "pink": "#ff4bda", + "turquoise": "#00c79a", + "yellow": "#ffcb00", + "red": "#ff613d", + "toolbar": "#7c7c7d", + "orange": "#ff9f00", + "purple": "#af51f5" + }; + + public static fromContextualIdentity(identity: ContextualIdentity): ContainerAttributes { + return new ContainerAttributes(identity, identity.name, identity.color, identity.icon); + } + + public static fromCookieStore(cookieStore: CookieStore): ContainerAttributes { + let name = ''; + if (cookieStore.isPrivate) { + name = browser.i18n.getMessage('privateBrowsing'); + } else if (cookieStore.userContextId == 0) { + name = browser.i18n.getMessage('noContainer'); + } else { + name = browser.i18n.getMessage('invalidContainerName', cookieStore.userContextId.toFixed(0)); + } + return new ContainerAttributes(cookieStore, name); + } + + public static getIconUrl(icon: string, color: string): string { + return browser.runtime.getURL(`/img/contextual-identities/${icon}.svg#${color}`); + } + + public readonly iconUrl: string; + public readonly colorCode: string; + + public constructor(cookieStoreParams: CookieStoreParams, name?: string, color?: string, icon?: string) { + const params = { + ... cookieStoreParams, + name: name || '', + color: color || '', + icon: icon || '' + }; + super(params); + + if (color && icon) { + this.iconUrl = ContainerAttributes.getIconUrl(icon, color); + } else { + this.iconUrl = ''; + } + + if (color) { + this.colorCode = ContainerAttributes._COLORS[color] ?? ''; + } else { + this.colorCode = ''; + } + } +} diff --git a/src/frameworks/tabAttributes/ContextualIdentity.ts b/src/frameworks/tabAttributes/ContextualIdentity.ts index 985144e7..512954d2 100644 --- a/src/frameworks/tabAttributes/ContextualIdentity.ts +++ b/src/frameworks/tabAttributes/ContextualIdentity.ts @@ -49,7 +49,7 @@ export class ContextualIdentity extends CookieStore implements ContextualIdentit * for example, the default CookieStore is not returned. * @returns All ContextualIdentities */ - public static async getAll(): Promise { + public static override async getAll(): Promise { const identities = await browser.contextualIdentities.query({}); return identities.map(ContextualIdentity.fromWebExtensionsContetualIdentity); } diff --git a/src/frameworks/tabAttributes/CookieStore.ts b/src/frameworks/tabAttributes/CookieStore.ts index 4cd0f747..1addf8bb 100644 --- a/src/frameworks/tabAttributes/CookieStore.ts +++ b/src/frameworks/tabAttributes/CookieStore.ts @@ -21,16 +21,26 @@ import { Uint32 } from "../types"; import { CookieStoreParams } from "./CookieStoreParams"; +import { ExtensionService } from "../extension"; + +const contextualIdentityPromise = import('./ContextualIdentity'); export class CookieStore implements CookieStoreParams { private static readonly DEFAULT_STORE = 'firefox-default'; private static readonly PRIVATE_STORE = 'firefox-private'; private static readonly CONTAINER_STORE = 'firefox-container-'; + private static readonly _extensionService = ExtensionService.getInstance(); + public readonly id: string; public readonly userContextId: Uint32.Uint32; public readonly privateBrowsingId: Uint32.Uint32; + /** + * Creates an instance of CookieStore from a cookie store id. + * @param cookieStoreId + * @returns + */ public static fromId(cookieStoreId: string): CookieStore { if (cookieStoreId === CookieStore.DEFAULT_STORE) { return new CookieStore({ @@ -52,6 +62,39 @@ export class CookieStore implements CookieStoreParams { throw new Error(`CookieStore.fromId(): invalid cookieStoreId: ${cookieStoreId}`); } + public static async getAll(): Promise { + if (!await CookieStore._extensionService.isAllowedInPrivateBrowsing()) { + return CookieStore.getAllNonPrivate(); + } + const { ContextualIdentity } = await contextualIdentityPromise; + const cookieStores = [ + CookieStore.fromId(CookieStore.DEFAULT_STORE), + CookieStore.fromId(CookieStore.PRIVATE_STORE), + ... await ContextualIdentity.getAll(), + ]; + return cookieStores; + } + + public static async getAllNonPrivate(): Promise { + const { ContextualIdentity } = await contextualIdentityPromise; + const cookieStores = [ + CookieStore.fromId(CookieStore.DEFAULT_STORE), + ... await ContextualIdentity.getAll(), + ]; + return cookieStores; + } + + /** + * Use this only when this extension is allowed in private browsing. + * @returns Private cookie store only + */ + public static async getAllPrivate(): Promise { + const cookieStores = [ + CookieStore.fromId(CookieStore.PRIVATE_STORE), + ]; + return cookieStores; + } + public constructor(params: CookieStoreParams) { this.userContextId = params.userContextId; this.privateBrowsingId = params.privateBrowsingId; @@ -65,6 +108,9 @@ export class CookieStore implements CookieStoreParams { } } + /** + * true if this is a private cookie store. + */ public get isPrivate(): boolean { return this.privateBrowsingId !== 0; } diff --git a/src/languages/content.ts b/src/languages/content.ts deleted file mode 100644 index b2565ec8..00000000 --- a/src/languages/content.ts +++ /dev/null @@ -1,110 +0,0 @@ -// -*- indent-tabs-mode: nil; tab-width: 2; -*- -// vim: set ts=2 sw=2 et ai : - -/* - Container Tab Groups - Copyright (C) 2022 Menhera.org - - 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 . -*/ - -import browser from 'webextension-polyfill'; -import { LanguageStore } from './LanguageStore'; -import './content-interfaces'; - -declare global { - // eslint-disable-next-line no-var - var gLanguageStore: LanguageStore; -} - -browser.runtime.sendMessage({ - type: 'content-script-loaded', - url: window.location.href, -}).catch(() => { - // ignore. -}); - -let languages = null; -if (globalThis.gLanguageStore) { - languages = gLanguageStore.languages; -} -globalThis.gLanguageStore = new LanguageStore(); -if (languages) { - gLanguageStore.languages = languages; -} - -const navigatorPrototype = Object.getPrototypeOf(navigator); -const navigatorPrototypeWrapped = navigatorPrototype.wrappedJSObject; - -// const descriptors = Object.getOwnPropertyDescriptors(navigatorPrototypeWrapped); - -let setupDone = false; -const setup = () => { - // this is configurable, so deletable - delete navigatorPrototypeWrapped.languages; - - // navigator.languages is a getter, so we need to define it as a getter - Reflect.defineProperty(navigatorPrototypeWrapped, 'languages', { - configurable: true, - enumerable: true, - get: exportFunction(() => { - let languages = gLanguageStore.languageList; - if (languages.length < 1) { - languages = navigator.languages; - } - return cloneInto(languages, window); - }, window), - }); - - // this is configurable, so deletable - delete navigatorPrototypeWrapped.language; - - // navigator.language is a getter, so we need to define it as a getter - Reflect.defineProperty(navigatorPrototypeWrapped, 'language', { - configurable: true, - enumerable: true, - get: exportFunction(() => { - let language = gLanguageStore.language; - if (language === '') { - language = navigator.language; - } - return cloneInto(language, window); - }, window), - }); - - setupDone = true; -}; - -gLanguageStore.onLanguagesChanged.addListener(() => { - if (!setupDone && gLanguageStore.language !== '') { - setup(); - } - window.dispatchEvent(new Event('languagechange', { - bubbles: false, - cancelable: false, - })); -}); - -browser.runtime.onMessage.addListener((message) => { - if (message.type === 'language-changed') { - const languages = String(message.languages ?? ''); - if (gLanguageStore.languages !== languages) { - gLanguageStore.languages = languages; - } - } -}); - -if (gLanguageStore.language !== '') { - setup(); -} diff --git a/src/languages/register-content-script.ts b/src/languages/register-content-script.ts index abdb4e0f..7d3b2acc 100644 --- a/src/languages/register-content-script.ts +++ b/src/languages/register-content-script.ts @@ -108,7 +108,6 @@ const update = async () => { if (!browserTab.cookieStoreId || null == browserTab.id) continue; const originAttributes = OriginAttributes.fromCookieStoreId(browserTab.cookieStoreId); const languages = languageSettings.getLanguages(originAttributes); - if ('' === languages) continue; browser.tabs.sendMessage(browserTab.id, { type: 'language-changed', diff --git a/src/modules/ChromiumReleaseService.ts b/src/overrides/ChromiumReleaseService.ts similarity index 98% rename from src/modules/ChromiumReleaseService.ts rename to src/overrides/ChromiumReleaseService.ts index a47414f6..b93139b6 100644 --- a/src/modules/ChromiumReleaseService.ts +++ b/src/overrides/ChromiumReleaseService.ts @@ -21,8 +21,6 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import browser from 'webextension-polyfill'; - const JAN = 0; const FEB = 1; const MAR = 2; diff --git a/src/overrides/ContentScriptRegistrar.ts b/src/overrides/ContentScriptRegistrar.ts new file mode 100644 index 00000000..921ccc1c --- /dev/null +++ b/src/overrides/ContentScriptRegistrar.ts @@ -0,0 +1,74 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import browser from 'webextension-polyfill'; +import { CookieStore } from "../frameworks/tabAttributes/CookieStore"; + +export abstract class ContentScriptRegistrar { + protected readonly contentScripts = new Map(); + + public async unregister(cookieStoreId: string): Promise { + await this.contentScripts.get(cookieStoreId)?.unregister(); + this.contentScripts.delete(cookieStoreId); + } + + public async unregisterAll(): Promise { + const promises: Promise[] = []; + for (const cookieStoreId of this.contentScripts.keys()) { + promises.push(this.unregister(cookieStoreId)); + } + await Promise.all(promises); + } + + public async register(cookieStoreId: string): Promise { + const cookieStore = CookieStore.fromId(cookieStoreId); + this.unregister(cookieStoreId); + this.contentScripts.set(cookieStoreId, await browser.contentScripts.register({ + js: [{ code: this.getContentScriptString(cookieStore) }], + matches: [''], + runAt: 'document_start', + allFrames: true, + cookieStoreId, + })); + } + + public async registerAll(): Promise { + const cookieStores = await CookieStore.getAll(); + const cookieStoreIds = cookieStores.map(cookieStore => cookieStore.id); + const previousCookieStoreIds = Array.from(this.contentScripts.keys()); + + const unregisterPromises: Promise[] = []; + for (const cookieStoreId of previousCookieStoreIds) { + if (!cookieStoreIds.includes(cookieStoreId)) { + unregisterPromises.push(this.unregister(cookieStoreId)); + } + } + await Promise.all(unregisterPromises); + + const registerPromises: Promise[] = []; + for (const cookieStoreId of cookieStoreIds) { + registerPromises.push(this.register(cookieStoreId)); + } + await Promise.all(registerPromises); + } + + public abstract getContentScriptString(cookieStore: CookieStore): string; +} diff --git a/src/overrides/UaContentScriptRegistrar.ts b/src/overrides/UaContentScriptRegistrar.ts new file mode 100644 index 00000000..923b457b --- /dev/null +++ b/src/overrides/UaContentScriptRegistrar.ts @@ -0,0 +1,101 @@ +// -*- indent-tabs-mode: nil; tab-width: 2; -*- +// vim: set ts=2 sw=2 et ai : + +/* + Container Tab Groups + Copyright (C) 2022 Menhera.org + + 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 . +*/ + +import browser from 'webextension-polyfill'; +import { UserAgentSettings } from './UserAgentSettings'; +import { config } from '../config/config'; +import { ContentScriptRegistrar } from './ContentScriptRegistrar'; +import { CookieStore } from '../frameworks/tabAttributes/CookieStore'; + +export class UaContentScriptRegistrar extends ContentScriptRegistrar { + private readonly settings: UserAgentSettings = UserAgentSettings.getInstance(); + + public constructor() { + super(); + this.settings.onChanged.addListener(() => { + this.updateInBackground(); + }); + config['feature.uaOverrides'].observe(() => { + this.updateInBackground(); + }) + } + + private async getEnabledStatus(): Promise { + return config['feature.uaOverrides'].getValue(); + } + + public getContentScriptString(cookieStore: CookieStore): string { + const ua = this.settings.getUserAgent(cookieStore.id); + const emulationMode = this.settings.getEmulationMode(cookieStore.id); + return ` + globalThis.gUaStore = globalThis.gUaStore || {}; + gUaStore.userAgent = ${JSON.stringify(ua)}; + gUaStore.emulateMode = ${JSON.stringify(emulationMode)}; + `; + } + + public async deleteUserAgent(): Promise { + const browserTabs = await browser.tabs.query({}); + for (const browserTab of browserTabs) { + if (null == browserTab.id) continue; + + browser.tabs.sendMessage(browserTab.id, { + type: 'ua-changed', + emulationMode: 'none', + userAgent: '', + }).catch(() => { + // ignore. + }); + } + } + + public async update(): Promise { + const enabled = await this.getEnabledStatus(); + if (!enabled) { + await this.unregisterAll(); + await this.deleteUserAgent(); + return; + } + + await this.registerAll(); + + const browserTabs = await browser.tabs.query({}); + for (const browserTab of browserTabs) { + if (!browserTab.cookieStoreId || null == browserTab.id) continue; + const emulationMode = this.settings.getEmulationMode(browserTab.cookieStoreId); + const userAgent = this.settings.getUserAgent(browserTab.cookieStoreId); + + browser.tabs.sendMessage(browserTab.id, { + type: 'ua-changed', + emulationMode, + userAgent, + }).catch(() => { + // ignore. + }); + } + } + + public updateInBackground(): void { + this.update().catch((e) => { + console.error(e); + }); + } +} diff --git a/src/overrides/UserAgentSettings.ts b/src/overrides/UserAgentSettings.ts index 73bd6c7c..37a2f5fb 100644 --- a/src/overrides/UserAgentSettings.ts +++ b/src/overrides/UserAgentSettings.ts @@ -22,10 +22,12 @@ import { StorageItem, StorageArea } from "../frameworks/storage"; import { EventSink } from "../frameworks/utils"; import { OriginAttributes } from '../frameworks/tabGroups'; -import { ChromiumReleaseService } from "../modules/ChromiumReleaseService"; +import { ChromiumReleaseService } from "./ChromiumReleaseService"; export type UserAgentPreset = 'default' | 'chrome' | 'googlebot' | 'custom'; +export type UserAgentEmulationMode = 'none' | 'chrome'; + export type UserAgentParams = { preset: UserAgentPreset; userAgent?: string; @@ -72,30 +74,29 @@ export class UserAgentSettings { }; } - public setUserAgent(originAttributes: OriginAttributes, preset: UserAgentPreset, userAgent?: string) { - const key = this.originAttributesToKey(originAttributes); + public setUserAgent(cookieStoreId: string, preset: UserAgentPreset, userAgent?: string) { switch (preset) { case 'default': { - delete this._value[key]; + delete this._value[cookieStoreId]; break; } case 'chrome': { - this._value[key] = { + this._value[cookieStoreId] = { preset: 'chrome', }; break; } case 'googlebot': { - this._value[key] = { + this._value[cookieStoreId] = { preset: 'googlebot', }; break; } default: { - this._value[key] = { + this._value[cookieStoreId] = { preset: 'custom', userAgent, }; @@ -106,13 +107,12 @@ export class UserAgentSettings { } /** - * Returns the user agent string set for the given origin attributes. - * @param originAttributes + * Returns the user agent string set for the given cookie store id. + * @param cookieStoreId * @returns the user agent string, or empty string if not set */ - public getUserAgent(originAttributes: OriginAttributes): string { - const key = this.originAttributesToKey(originAttributes); - const params = this._value[key]; + public getUserAgent(cookieStoreId: string): string { + const params = this._value[cookieStoreId]; if (!params) { return ''; } @@ -130,9 +130,8 @@ export class UserAgentSettings { return params.userAgent || ''; } - public getUserAgentParams(originAttributes: OriginAttributes): UserAgentParams { - const key = this.originAttributesToKey(originAttributes); - const params = this._value[key]; + public getUserAgentParams(cookieStoreId: string): UserAgentParams { + const params = this._value[cookieStoreId]; if (!params) { return { preset: 'default', @@ -141,4 +140,12 @@ export class UserAgentSettings { return params; } + + public getEmulationMode(cookieStoreId: string): UserAgentEmulationMode { + const ua = this.getUserAgent(cookieStoreId); + if (!ua) { + return 'none'; + } + return ua.match(/Chrome\/\d/) ? 'chrome' : 'none'; + } } diff --git a/src/overrides/fetch.ts b/src/overrides/fetch.ts index 57bc2505..1ed3637d 100644 --- a/src/overrides/fetch.ts +++ b/src/overrides/fetch.ts @@ -22,25 +22,48 @@ import browser from 'webextension-polyfill'; import { OriginAttributes } from '../frameworks/tabGroups'; import { LanguageSettings } from '../languages/LanguageSettings'; +import { UserAgentSettings } from './UserAgentSettings'; +import { config } from '../config/config'; const languageSettings = LanguageSettings.getInstance(); +const userAgentSettings = UserAgentSettings.getInstance(); + +let featureLanguageOverridesEnabled = false; +let featureUserAgentOverridesEnabled = false; + +config['feature.languageOverrides'].observe((newValue) => { + featureLanguageOverridesEnabled = newValue; +}); + +config['feature.uaOverrides'].observe((newValue) => { + featureUserAgentOverridesEnabled = newValue; +}); browser.webRequest.onBeforeSendHeaders.addListener((details) => { if (!details.cookieStoreId) { return; } + const userAgent = userAgentSettings.getUserAgent(details.cookieStoreId); + if ('' !== userAgent && featureUserAgentOverridesEnabled) { + details.requestHeaders?.forEach((header) => { + if ('user-agent' === header.name.toLowerCase()) { + header.value = userAgent; + } + }); + } + const originAttributes = OriginAttributes.fromCookieStoreId(details.cookieStoreId); const acceptLanguages = languageSettings.getAcceptLanguages(originAttributes); - if ('' === acceptLanguages) { - return; + if ('' !== acceptLanguages && featureLanguageOverridesEnabled) { + details.requestHeaders?.forEach((header) => { + if ('accept-language' === header.name.toLowerCase()) { + header.value = acceptLanguages; + } + }); } - details.requestHeaders?.forEach((header) => { - if ('accept-language' === header.name.toLowerCase()) { - header.value = acceptLanguages; - } - }); + // TODO: Sec-CH-UA-* headers. return { requestHeaders: details.requestHeaders }; }, { diff --git a/webpack.config.js b/webpack.config.js index 8f509c18..ad11c643 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -43,8 +43,8 @@ module.exports = { filename: 'cookies/cookies.js', }, 'languages': { - import: './src/languages/content.ts', - filename: 'languages/content.js', + import: './src/content/content.ts', + filename: 'content/content.js', }, }, From 72fce243816e04b137a16ee2c78a8c15bdd791bf Mon Sep 17 00:00:00 2001 From: metastable-void Date: Thu, 29 Dec 2022 22:00:02 +0900 Subject: [PATCH 14/15] Sec-CH-UA-* headers --- src/overrides/fetch.ts | 65 +++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/src/overrides/fetch.ts b/src/overrides/fetch.ts index 1ed3637d..95978053 100644 --- a/src/overrides/fetch.ts +++ b/src/overrides/fetch.ts @@ -39,6 +39,49 @@ config['feature.uaOverrides'].observe((newValue) => { featureUserAgentOverridesEnabled = newValue; }); +const getSecChUa = (cookieStoreId: string) => { + const userAgent = userAgentSettings.getUserAgent(cookieStoreId); + const chrome = userAgent.match(/Chrome\/([0-9]+)/); + if (!chrome) { + return ''; + } + const chromeVersion = chrome[1] || '108'; + const brands = [ + { + "brand": "Not?A_Brand", + "version": Math.floor(100 * Math.random()).toFixed(0), + }, + { + "brand": "Chromium", + "version": chromeVersion, + }, + { + "brand": "Google Chrome", + "version": chromeVersion, + }, + ]; + const brandStrings = brands.map((brandInfo) => { + return `"${brandInfo.brand}";v="${brandInfo.version}"`; + }); + return brandStrings.join(','); +}; + +const setHeader = (details: browser.WebRequest.OnBeforeSendHeadersDetailsType, headerName: string, headerValue: string) => { + let found = false; + details.requestHeaders?.forEach((header) => { + if (headerName === header.name.toLowerCase()) { + header.value = headerValue; + found = true; + } + }); + if (!found) { + details.requestHeaders?.push({ + name: headerName, + value: headerValue, + }); + } +}; + browser.webRequest.onBeforeSendHeaders.addListener((details) => { if (!details.cookieStoreId) { return; @@ -46,24 +89,24 @@ browser.webRequest.onBeforeSendHeaders.addListener((details) => { const userAgent = userAgentSettings.getUserAgent(details.cookieStoreId); if ('' !== userAgent && featureUserAgentOverridesEnabled) { - details.requestHeaders?.forEach((header) => { - if ('user-agent' === header.name.toLowerCase()) { - header.value = userAgent; - } - }); + setHeader(details, 'user-agent', userAgent); } const originAttributes = OriginAttributes.fromCookieStoreId(details.cookieStoreId); const acceptLanguages = languageSettings.getAcceptLanguages(originAttributes); if ('' !== acceptLanguages && featureLanguageOverridesEnabled) { - details.requestHeaders?.forEach((header) => { - if ('accept-language' === header.name.toLowerCase()) { - header.value = acceptLanguages; - } - }); + setHeader(details, 'accept-language', acceptLanguages); } - // TODO: Sec-CH-UA-* headers. + // this feature is only available in secure contexts. + if (featureUserAgentOverridesEnabled && details.url?.startsWith('https://')) { + const secChUa = getSecChUa(details.cookieStoreId); + if ('' !== secChUa) { + setHeader(details, 'sec-ch-ua', secChUa); + const secChUaFullVersionList = secChUa.replaceAll(/v="(\d+)"/g, 'v="$1.0.0.0"'); + setHeader(details, 'sec-ch-ua-full-version-list', secChUaFullVersionList); + } + } return { requestHeaders: details.requestHeaders }; }, { From 1714242b45e9972f5deaa427c6d7ab545caaea1a Mon Sep 17 00:00:00 2001 From: metastable-void Date: Thu, 29 Dec 2022 22:10:11 +0900 Subject: [PATCH 15/15] remove ua-list.json --- docs/ua-list.json | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 docs/ua-list.json diff --git a/docs/ua-list.json b/docs/ua-list.json deleted file mode 100644 index 7f75e218..00000000 --- a/docs/ua-list.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "name": "Latest Chrome", - "userAgent": "Mozilla/5.0 (%CHROME_UA_PLATFORM%) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%CHROME_RELEASE%.0.0.0 Safari/537.36", - "userAgentDataEnabled": true - }, - { - "name": "Googlebot", - "userAgent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)", - "userAgentDataEnabled": true - } -] \ No newline at end of file