This commit is contained in:
a 2020-08-18 22:17:04 +02:00
parent 5b4743768e
commit 5451b3713e
12 changed files with 137 additions and 88 deletions

View file

@ -9,10 +9,12 @@
},
"devDependencies": {
"@tsconfig/svelte": "^1.0.8",
"@typescript-eslint/eslint-plugin": "^3.9.1",
"@typescript-eslint/parser": "^3.9.1",
"copy-webpack-plugin": "^6.0.3",
"css-loader": "^4.0.0",
"eslint": "^7.6.0",
"eslint-plugin-svelte3": "^2.7.3",
"eslint": "^7.7.0",
"eslint-config-prettier": "^6.11.0",
"file-loader": "^6.0.0",
"html-loader": "^1.1.0",
"html-webpack-plugin": "4.3.0",

View file

@ -4,7 +4,7 @@ import { Flashcards } from "./database";
import { BackgroundMessenger } from "../background_frontend_commands";
import content_script from "../frontend/content_script/content_script.ts?file";
let con = new BackgroundMessenger();
const con = new BackgroundMessenger();
const scraper = new GTranslateScraper();
con.addMessageListener("translate", async (toTranslate, sender) =>
@ -14,14 +14,15 @@ con.addMessageListener("translate", async (toTranslate, sender) =>
con.addMessageListener("getLanguages", () => scraper.languages);
const db = new Flashcards();
window.flashcardDB = db;
con.addMessageListener("addFlashcard", (c) => db.addFlashcard(c));
con.addMessageListener("removeFlashcard", (c) => db.removeFlashcard(c));
const getCurrentLanguages = async () => {
const langs = await scraper.languages;
let srcLangCode =
const srcLangCode =
(await browser.storage.local.get("srcLang"))["srcLang"] ?? "de";
let dstLangCode =
const dstLangCode =
(await browser.storage.local.get("dstLang"))["dstLang"] ?? "en";
const srcLang = langs.filter((l) => l.code == srcLangCode).pop()!;
@ -39,7 +40,7 @@ con.addMessageListener("setCurrentLanguages", setCurrentLanguages);
const getTabID = async (s: Runtime.MessageSender): Promise<number> => {
if (s.tab?.id) return s.tab.id;
let tabs = await browser.tabs.query({
const tabs = await browser.tabs.query({
active: true,
currentWindow: true,
});

View file

@ -4,12 +4,12 @@ export class Flashcards {
db: Promise<IDBDatabase>;
constructor() {
let [promise, resolve, reject] = newPromise<IDBDatabase>();
const [promise, resolve, reject] = newPromise<IDBDatabase>();
this.db = promise;
const req = indexedDB.open("FlashCardDB", 1);
req.onupgradeneeded = () => {
let objectStore = req.result.createObjectStore("flashcards", {
const objectStore = req.result.createObjectStore("flashcards", {
keyPath: "id",
autoIncrement: true,
});
@ -38,11 +38,11 @@ export class Flashcards {
};
}
let req = (await this.db)
const req = (await this.db)
.transaction(["flashcards"], "readwrite")
.objectStore("flashcards")
.add(card);
let [promise, resolve, reject] = newPromise<Flashcard>();
const [promise, resolve, reject] = newPromise<Flashcard>();
req.onsuccess = () => {
card.id = req.result;
resolve(card);
@ -53,24 +53,24 @@ export class Flashcards {
async removeFlashcard(card: Flashcard): Promise<void> {
if (!card.id) return Promise.reject("Undefined ID");
let req = (await this.db)
const req = (await this.db)
.transaction(["flashcards"], "readwrite")
.objectStore("flashcards")
.delete(card.id);
let [promise, resolve, reject] = newPromise<void>();
const [promise, resolve, reject] = newPromise<void>();
req.onsuccess = () => resolve();
req.onerror = () => reject(req.error);
return promise;
}
async getAllCards(): Promise<Array<Flashcard>> {
let req = (await this.db)
const req = (await this.db)
.transaction(["flashcards"], "readonly")
.objectStore("flashcards")
.getAll();
let [promise, resolve, reject] = newPromise<Flashcard[]>();
const [promise, resolve, reject] = newPromise<Flashcard[]>();
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
return promise;

View file

@ -1,19 +1,5 @@
import { ContentScriptMessenger } from "./gtranslate_commands";
export enum MessageKinds {
translationFinished = "translation",
languageList = "languages",
}
export interface TranslationMessage {
messageKind: MessageKinds.translationFinished;
translation: Translation;
}
export interface LanguageListMessage {
messageKind: MessageKinds.languageList;
languages: Array<Language>;
}
export type Message = TranslationMessage | LanguageListMessage;
(async () => {
if (window.location.host != "translate.google.com" || window.hasRun) return;
window.hasRun = true;

View file

@ -1,4 +1,4 @@
import { browser, WebRequest, Runtime } from "webextension-polyfill-ts";
import { browser, WebRequest } from "webextension-polyfill-ts";
import content_script from "./gtranslate_content_script.ts?file";
import { BackgroundMessenger } from "./gtranslate_commands";
import { newPromise } from "../utils";
@ -6,7 +6,7 @@ import { newPromise } from "../utils";
interface TranslationRequest {
tabID?: number;
resolveFn: (value: Translation) => void;
rejectFn: (reason: String) => void;
rejectFn: (reason: string) => void;
toTranslate: string;
lang: LanguagePair;
}
@ -100,7 +100,9 @@ export class GTranslateScraper {
private async processCurrent() {
if (!this.current)
throw "ProcessCurrent called while current translation request is undefined";
throw new Error(
"ProcessCurrent called while current translation request is undefined"
);
const cur = this.current;
let promise = Promise.resolve();
@ -115,7 +117,9 @@ export class GTranslateScraper {
await promise;
if (cur == this.current) this.msg.runCommand("translate", cur.toTranslate);
else
throw "The current request changed while processCurrent was running. This should never happen";
throw new Error(
"The current request changed while processCurrent was running. This should never happen"
);
}
async translate(
@ -131,7 +135,7 @@ export class GTranslateScraper {
languages: langs,
});
let [promise, resolve, reject] = newPromise<Translation>();
const [promise, resolve, reject] = newPromise<Translation>();
const req = {
toTranslate: toTranslate,
@ -166,7 +170,7 @@ const allowIFrameAccess = (info: WebRequest.OnHeadersReceivedDetailsType) => {
let headers = info.responseHeaders;
headers = headers?.filter((header) => {
let h = header.name.toString().toLowerCase();
const h = header.name.toString().toLowerCase();
h != "x-frame-options" && h != "frame-options";
});
return { responseHeaders: headers };

View file

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { Runtime } from "webextension-polyfill-ts";
export interface commandFunction {
@ -31,14 +32,14 @@ export abstract class Communicator<
abstract async runCommand<K extends keyof SendCommands>(
command: K,
args: SendCommands[K]["args"],
...rest: any[]
...rest: unknown[]
): Promise<SendCommands[K]["return"]>;
addMessageListener<K extends keyof RecvCommands>(
command: K,
callback: listener<RecvCommands, K>
) {
this.listeners.set(command, <any>callback);
this.listeners.set(command, callback as any);
}
protected getCommandMessage<K extends keyof RecvCommands>(
@ -52,13 +53,13 @@ export abstract class Communicator<
m: commandMessage<RecvCommands, K>,
s?: Runtime.MessageSender
) {
let listener = this.listeners.get(m.name);
let args: [
const listener = this.listeners.get(m.name);
const args: [
RecvCommands[keyof RecvCommands]["args"],
Runtime.MessageSender
] = m.args;
if (args[0] === undefined) args.pop();
args.push(s);
if (listener) return listener.apply(null, args);
if (listener) return listener(...args);
}
}

View file

@ -8,7 +8,7 @@ import { FrontendMessenger } from "../../background_frontend_commands";
if (window.hasRun) return;
window.hasRun = true;
let con = new FrontendMessenger();
const con = new FrontendMessenger();
const tippyInstance = setupTippy();

View file

@ -12,6 +12,10 @@
"browser_style": true,
"default_popup": "popup.html"
},
"options_ui": {
"page": "options.html",
"open_in_tab": true
},
"background": { "scripts": ["background.bundle.js"] },
"permissions": [
"<all_urls>",

33
src/types.d.ts vendored
View file

@ -1,33 +0,0 @@
declare module "*?file" {
const file: string;
export = file;
}
declare interface Translation {
src: string;
result: string;
languages: LanguagePair;
}
declare interface Flashcard {
id?: IDBValidKey;
src: string;
result: string;
dateAdded: Date;
exported: boolean;
languages: LanguagePair;
}
declare interface LanguagePair {
srcLang: Language;
dstLang: Language;
}
declare interface Language {
code: string;
name: string;
}
declare interface Window {
hasRun: any;
}

View file

@ -1,5 +1,5 @@
type resolveCallback<T> = (value: T) => void;
type rejectCallback = (reason: any) => void;
type rejectCallback = (reason: unknown) => void;
export const newPromise = <T>(): [
Promise<T>,

View file

@ -9,6 +9,7 @@ let mode = process.env.NODE_ENV || "development";
let options = {
entry: {
popup: path.join(__dirname, "src", "frontend", "popup", "popup.ts"),
options: path.join(__dirname, "src", "frontend", "options", "options.ts"),
background: path.join(__dirname, "src", "background", "background.ts"),
},
output: {
@ -75,6 +76,10 @@ let options = {
filename: "popup.html",
chunks: ["popup"],
}),
new HtmlWebpackPlugin({
filename: "options.html",
chunks: ["options"],
}),
],
};

107
yarn.lock
View file

@ -134,12 +134,17 @@
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
"@types/eslint-visitor-keys@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
"@types/html-minifier-terser@^5.0.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz#551a4589b6ee2cc9c1dff08056128aec29b94880"
integrity sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA==
"@types/json-schema@^7.0.4":
"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4":
version "7.0.5"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
@ -209,6 +214,66 @@
"@types/webpack-sources" "*"
source-map "^0.6.0"
"@typescript-eslint/eslint-plugin@^3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.9.1.tgz#8cf27b6227d12d66dd8dc1f1a4b04d1daad51c2e"
integrity sha512-XIr+Mfv7i4paEdBf0JFdIl9/tVxyj+rlilWIfZ97Be0lZ7hPvUbS5iHt9Glc8kRI53dsr0PcAEudbf8rO2wGgg==
dependencies:
"@typescript-eslint/experimental-utils" "3.9.1"
debug "^4.1.1"
functional-red-black-tree "^1.0.1"
regexpp "^3.0.0"
semver "^7.3.2"
tsutils "^3.17.1"
"@typescript-eslint/experimental-utils@3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.1.tgz#b140b2dc7a7554a44f8a86fb6fe7cbfe57ca059e"
integrity sha512-lkiZ8iBBaYoyEKhCkkw4SAeatXyBq9Ece5bZXdLe1LWBUwTszGbmbiqmQbwWA8cSYDnjWXp9eDbXpf9Sn0hLAg==
dependencies:
"@types/json-schema" "^7.0.3"
"@typescript-eslint/types" "3.9.1"
"@typescript-eslint/typescript-estree" "3.9.1"
eslint-scope "^5.0.0"
eslint-utils "^2.0.0"
"@typescript-eslint/parser@^3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.9.1.tgz#ab7983abaea0ae138ff5671c7c7739d8a191b181"
integrity sha512-y5QvPFUn4Vl4qM40lI+pNWhTcOWtpZAJ8pOEQ21fTTW4xTJkRplMjMRje7LYTXqVKKX9GJhcyweMz2+W1J5bMg==
dependencies:
"@types/eslint-visitor-keys" "^1.0.0"
"@typescript-eslint/experimental-utils" "3.9.1"
"@typescript-eslint/types" "3.9.1"
"@typescript-eslint/typescript-estree" "3.9.1"
eslint-visitor-keys "^1.1.0"
"@typescript-eslint/types@3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.9.1.tgz#b2a6eaac843cf2f2777b3f2464fb1fbce5111416"
integrity sha512-15JcTlNQE1BsYy5NBhctnEhEoctjXOjOK+Q+rk8ugC+WXU9rAcS2BYhoh6X4rOaXJEpIYDl+p7ix+A5U0BqPTw==
"@typescript-eslint/typescript-estree@3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.1.tgz#fd81cada74bc8a7f3a2345b00897acb087935779"
integrity sha512-IqM0gfGxOmIKPhiHW/iyAEXwSVqMmR2wJ9uXHNdFpqVvPaQ3dWg302vW127sBpAiqM9SfHhyS40NKLsoMpN2KA==
dependencies:
"@typescript-eslint/types" "3.9.1"
"@typescript-eslint/visitor-keys" "3.9.1"
debug "^4.1.1"
glob "^7.1.6"
is-glob "^4.0.1"
lodash "^4.17.15"
semver "^7.3.2"
tsutils "^3.17.1"
"@typescript-eslint/visitor-keys@3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.1.tgz#92af3747cdb71509199a8f7a4f00b41d636551d1"
integrity sha512-zxdtUjeoSh+prCpogswMwVUJfEFmCOjdzK9rpNjNBfm6EyPt99x3RrJoBOGZO23FCt0WPKUCOL5mb/9D5LjdwQ==
dependencies:
eslint-visitor-keys "^1.1.0"
"@webassemblyjs/ast@1.9.0":
version "1.9.0"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
@ -2140,16 +2205,18 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
eslint-config-prettier@^6.11.0:
version "6.11.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz#f6d2238c1290d01c859a8b5c1f7d352a0b0da8b1"
integrity sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==
dependencies:
get-stdin "^6.0.0"
eslint-plugin-no-unsanitized@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-no-unsanitized/-/eslint-plugin-no-unsanitized-3.1.2.tgz#a54724e0b81d43279bb1f8f5e1d82c97da78c858"
integrity sha512-KPShfliA3Uy9qqwQx35P1fwIOeJjZkb0FbMMUFztRYRposzaynsM8JCEb952fqkidROl1kpqY80uSvn+TcWkQQ==
eslint-plugin-svelte3@^2.7.3:
version "2.7.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-svelte3/-/eslint-plugin-svelte3-2.7.3.tgz#e793b646b848e717674fe668c21b909cfa025eb3"
integrity sha512-p6HhxyICX9x/x+8WSy6AVk2bmv9ayoznoTSyCvK47th/k/07ksuJixMwbGX9qxJVAmPBaYMjEIMSEZtJHPIN7w==
eslint-scope@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848"
@ -2158,7 +2225,7 @@ eslint-scope@^4.0.3:
esrecurse "^4.1.0"
estraverse "^4.1.1"
eslint-scope@^5.1.0:
eslint-scope@^5.0.0, eslint-scope@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5"
integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==
@ -2173,7 +2240,7 @@ eslint-utils@^1.3.1:
dependencies:
eslint-visitor-keys "^1.1.0"
eslint-utils@^2.1.0:
eslint-utils@^2.0.0, eslint-utils@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==
@ -2232,10 +2299,10 @@ eslint@5.16.0:
table "^5.2.3"
text-table "^0.2.0"
eslint@^7.6.0:
version "7.6.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.6.0.tgz#522d67cfaea09724d96949c70e7a0550614d64d6"
integrity sha512-QlAManNtqr7sozWm5TF4wIH9gmUm2hE3vNRUvyoYAa4y1l5/jxD/PQStEjBMQtCqZmSep8UxrcecI60hOpe61w==
eslint@^7.7.0:
version "7.7.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.7.0.tgz#18beba51411927c4b64da0a8ceadefe4030d6073"
integrity sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==
dependencies:
"@babel/code-frame" "^7.0.0"
ajv "^6.10.0"
@ -2784,6 +2851,11 @@ get-own-enumerable-property-symbols@^3.0.0:
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==
get-stdin@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b"
integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==
get-stream@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
@ -5214,7 +5286,7 @@ regexpp@^2.0.1:
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
regexpp@^3.1.0:
regexpp@^3.0.0, regexpp@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
@ -6417,11 +6489,18 @@ ts-loader@^8.0.1:
micromatch "^4.0.0"
semver "^6.0.0"
tslib@^1.10.0, tslib@^1.9.0:
tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
tsutils@^3.17.1:
version "3.17.1"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==
dependencies:
tslib "^1.8.1"
tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"