Strict ts mode
This commit is contained in:
parent
fdf8cbe0ff
commit
2f8d94bb1a
10 changed files with 98 additions and 85 deletions
|
@ -9,16 +9,17 @@ const scraper = new GTranslateScraper();
|
|||
com.translateCallback = (toTranslate) => scraper.translate(toTranslate);
|
||||
|
||||
const db = new Flashcards();
|
||||
com.addFlashcardCallback = (card) => db.addFlashcard(card);
|
||||
com.removeFlashcardCallback = (card) => console.log(db);
|
||||
com.addFlashcardCallback = db.addFlashcard;
|
||||
com.removeFlashcardCallback = db.removeFlashcard;
|
||||
console.log(db);
|
||||
|
||||
const getTab = async (s: Runtime.MessageSender): Promise<Tabs.Tab> => {
|
||||
if (s.tab) return s.tab;
|
||||
const getTabID = async (s: Runtime.MessageSender): Promise<number> => {
|
||||
if (s.tab?.id) return s.tab.id;
|
||||
let tabs = await browser.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true,
|
||||
});
|
||||
return tabs[0];
|
||||
return tabs[0].id!;
|
||||
};
|
||||
|
||||
const isEnabledSession = async (tabID: number): Promise<boolean> =>
|
||||
|
@ -39,15 +40,15 @@ const injectScript = async (tabID: number, enabled?: boolean) => {
|
|||
};
|
||||
|
||||
com.setEnabledCallback = async (v: boolean, s: Runtime.MessageSender) => {
|
||||
const tab = await getTab(s);
|
||||
const tab = await getTabID(s);
|
||||
|
||||
injectScript(tab.id);
|
||||
await setEnabledSession(tab.id, v);
|
||||
injectScript(tab);
|
||||
await setEnabledSession(tab, v);
|
||||
};
|
||||
|
||||
com.getEnabledCallback = async (s: Runtime.MessageSender): Promise<boolean> => {
|
||||
const tab = await getTab(s);
|
||||
return isEnabledSession(tab.id);
|
||||
const tab = await getTabID(s);
|
||||
return isEnabledSession(tab);
|
||||
};
|
||||
|
||||
browser.tabs.onUpdated.addListener(async (tabID, changeInfo) => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export class Flashcards {
|
||||
db: IDBDatabase;
|
||||
db!: IDBDatabase;
|
||||
|
||||
constructor() {
|
||||
const req = indexedDB.open("FlashCardDB", 1);
|
||||
|
@ -16,6 +16,11 @@ export class Flashcards {
|
|||
req.onsuccess = () => {
|
||||
this.db = req.result;
|
||||
};
|
||||
req.onerror = () => {
|
||||
throw new Error(
|
||||
`Error initializing the database backend, ${req.error}. This shouldn't ever happen`
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
addFlashcard(t: Translation | Flashcard): Promise<Flashcard> {
|
||||
|
@ -43,14 +48,16 @@ export class Flashcards {
|
|||
}
|
||||
|
||||
removeFlashcard(card: Flashcard): Promise<void> {
|
||||
let req = this.db
|
||||
.transaction(["flashcards"], "readwrite")
|
||||
.objectStore("flashcards")
|
||||
.delete(card.id);
|
||||
return new Promise((resolve, reject) => {
|
||||
req.onsuccess = () => resolve();
|
||||
req.onerror = () => reject(req.error);
|
||||
});
|
||||
if (card.id) {
|
||||
let req = this.db
|
||||
.transaction(["flashcards"], "readwrite")
|
||||
.objectStore("flashcards")
|
||||
.delete(card.id);
|
||||
return new Promise((resolve, reject) => {
|
||||
req.onsuccess = () => resolve();
|
||||
req.onerror = () => reject(req.error);
|
||||
});
|
||||
} else return Promise.reject("Undefined ID");
|
||||
}
|
||||
|
||||
async getAllCards(): Promise<Array<Flashcard>> {
|
||||
|
|
|
@ -22,7 +22,7 @@ declare interface Window {
|
|||
const observer = new MutationObserver((mutations) => {
|
||||
console.log(mutations);
|
||||
const wasTranslating = mutations.some((m) =>
|
||||
m.oldValue.split(" ").some((c) => c == "translating")
|
||||
m.oldValue!.split(" ").some((c) => c == "translating")
|
||||
);
|
||||
if (wasTranslating && !isTranslating()) {
|
||||
sendTranslation();
|
||||
|
|
|
@ -46,9 +46,9 @@ export class GTranslateScraper {
|
|||
});
|
||||
}
|
||||
onTranslationRecieved(message: Translation) {
|
||||
this.resolveFn(message);
|
||||
this.resolveFn = null;
|
||||
this.rejectFn = null;
|
||||
if (this.resolveFn) this.resolveFn(message);
|
||||
this.resolveFn = undefined;
|
||||
this.rejectFn = undefined;
|
||||
}
|
||||
|
||||
translate(to_translate: string): Promise<Translation> {
|
||||
|
@ -68,7 +68,7 @@ const allowIFrameAccess = (info: WebRequest.OnHeadersReceivedDetailsType) => {
|
|||
if (info.documentUrl != document.URL) return;
|
||||
|
||||
let headers = info.responseHeaders;
|
||||
headers = headers.filter((header) => {
|
||||
headers = headers?.filter((header) => {
|
||||
let h = header.name.toString().toLowerCase();
|
||||
h != "x-frame-options" && h != "frame-options";
|
||||
});
|
||||
|
|
|
@ -2,36 +2,41 @@
|
|||
import { browser, Runtime } from "webextension-polyfill-ts";
|
||||
|
||||
export class Communicator {
|
||||
setEnabledCallback: (value: boolean, sender: Runtime.MessageSender) => void;
|
||||
getEnabledCallback: (sender: Runtime.MessageSender) => Promise<boolean>;
|
||||
translateCallback: (
|
||||
setEnabledCallback?: (value: boolean, sender: Runtime.MessageSender) => void;
|
||||
getEnabledCallback?: (sender: Runtime.MessageSender) => Promise<boolean>;
|
||||
translateCallback?: (
|
||||
toTranslate: string,
|
||||
sender: Runtime.MessageSender
|
||||
) => Promise<Translation>;
|
||||
|
||||
addFlashcardCallback: (
|
||||
addFlashcardCallback?: (
|
||||
value: Translation | Flashcard,
|
||||
sender: Runtime.MessageSender
|
||||
) => Promise<Flashcard>;
|
||||
removeFlashcardCallback: (
|
||||
removeFlashcardCallback?: (
|
||||
value: Flashcard,
|
||||
sender: Runtime.MessageSender
|
||||
) => Promise<Flashcard>;
|
||||
) => Promise<void>;
|
||||
|
||||
constructor() {
|
||||
browser.runtime.onMessage.addListener(
|
||||
(c: command, s: Runtime.MessageSender) => {
|
||||
switch (c.commandKind) {
|
||||
case commandKinds.setEnabled:
|
||||
return this.setEnabledCallback(c.value, s);
|
||||
case commandKinds.getEnabled:
|
||||
return this.getEnabledCallback(s);
|
||||
case commandKinds.translate:
|
||||
return this.translateCallback(c.toTranslate, s);
|
||||
case commandKinds.addFlashcard:
|
||||
return this.addFlashcardCallback(c.card, s);
|
||||
case commandKinds.removeFlashcard:
|
||||
return this.removeFlashcardCallback(c.card, s);
|
||||
try {
|
||||
switch (c.commandKind) {
|
||||
case commandKinds.setEnabled:
|
||||
return this.setEnabledCallback!(c.value, s);
|
||||
case commandKinds.getEnabled:
|
||||
return this.getEnabledCallback!(s);
|
||||
case commandKinds.translate:
|
||||
return this.translateCallback!(c.toTranslate, s);
|
||||
case commandKinds.addFlashcard:
|
||||
return this.addFlashcardCallback!(c.card, s);
|
||||
case commandKinds.removeFlashcard:
|
||||
return this.removeFlashcardCallback!(c.card, s);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof ReferenceError)
|
||||
console.warn(`Unimplemented command ${c.commandKind}`);
|
||||
else throw e;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -46,12 +51,10 @@ export class Communicator {
|
|||
commandKind: commandKinds.translate,
|
||||
toTranslate: toTranslate,
|
||||
});
|
||||
static addFlashcard = (card: Flashcard | Translation) => {
|
||||
static addFlashcard = (card: Flashcard | Translation): Promise<Flashcard> =>
|
||||
sendMessage({ commandKind: commandKinds.addFlashcard, card: card });
|
||||
};
|
||||
static removeFlashcard = (card: Flashcard) => {
|
||||
static removeFlashcard = (card: Flashcard) =>
|
||||
sendMessage({ commandKind: commandKinds.removeFlashcard, card: card });
|
||||
};
|
||||
}
|
||||
|
||||
const sendMessage = (m: command) => browser.runtime.sendMessage(m);
|
||||
|
|
|
@ -29,7 +29,7 @@ declare global {
|
|||
const onSelectionChange = () => {
|
||||
tippyInstance.hide();
|
||||
clearTimeout(timeoutID);
|
||||
if (document.getSelection().type == "Range")
|
||||
if (document.getSelection()?.type == "Range")
|
||||
timeoutID = window.setTimeout(tippyInstance.show, 500);
|
||||
};
|
||||
|
||||
|
@ -41,16 +41,16 @@ declare global {
|
|||
trigger: "manual",
|
||||
interactive: true,
|
||||
getReferenceClientRect: () =>
|
||||
document.getSelection().getRangeAt(0).getBoundingClientRect(),
|
||||
document.getSelection()!.getRangeAt(0).getBoundingClientRect(),
|
||||
onCreate: (instance) => {
|
||||
translateElement.addEventListener("translationFinished", () =>
|
||||
instance.popperInstance.update()
|
||||
instance.popperInstance!.update()
|
||||
);
|
||||
},
|
||||
onShow: () => {
|
||||
translateElement.setAttribute(
|
||||
"translate",
|
||||
document.getSelection().toString()
|
||||
document.getSelection()?.toString() ?? ""
|
||||
);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -7,10 +7,12 @@ class LingoTranslate extends HTMLElement {
|
|||
translationElm: LingoTranslation;
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: "open" });
|
||||
this.shadowRoot.innerHTML = `<lingo-loading></lingo-loading> <lingo-translation></lingo-translation>`;
|
||||
this.loadingElm = this.shadowRoot.querySelector("lingo-loading");
|
||||
this.translationElm = this.shadowRoot.querySelector("lingo-translation");
|
||||
const shadow = this.attachShadow({ mode: "open" });
|
||||
shadow.innerHTML = `<lingo-loading></lingo-loading> <lingo-translation></lingo-translation>`;
|
||||
this.loadingElm = <LingoLoading>shadow.querySelector("lingo-loading");
|
||||
this.translationElm = <LingoTranslation>(
|
||||
shadow.querySelector("lingo-translation")
|
||||
);
|
||||
}
|
||||
|
||||
render = () => {
|
||||
|
@ -25,8 +27,7 @@ class LingoTranslate extends HTMLElement {
|
|||
this.loadingElm.hidden = true;
|
||||
this.translationElm.hidden = false;
|
||||
|
||||
this.translationElm.setAttribute("src", t.src);
|
||||
this.translationElm.setAttribute("translation", t.result);
|
||||
this.translationElm.translation = t;
|
||||
this.dispatchEvent(new Event("translationFinished"));
|
||||
}
|
||||
});
|
||||
|
@ -62,44 +63,46 @@ class LingoTranslation extends HTMLElement {
|
|||
srcElm: HTMLSpanElement;
|
||||
translateElm: HTMLSpanElement;
|
||||
addToCollection: HTMLButtonElement;
|
||||
private _translation?: Translation;
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: "open" });
|
||||
const shadow = this.attachShadow({ mode: "open" });
|
||||
|
||||
let style = document.createElement("style");
|
||||
style.textContent = translationCSS;
|
||||
this.shadowRoot.appendChild(style);
|
||||
shadow.appendChild(style);
|
||||
|
||||
this.shadowRoot.innerHTML = `
|
||||
shadow.innerHTML = `
|
||||
<div id="translation">
|
||||
<span id="src"></span> - <span id="translated"></span>
|
||||
</div>
|
||||
<button is="toggleButton"> Add to collection </button>
|
||||
`;
|
||||
|
||||
this.srcElm = this.shadowRoot.querySelector("#src");
|
||||
this.translateElm = this.shadowRoot.querySelector("#translated");
|
||||
this.srcElm = <HTMLSpanElement>shadow.querySelector("#src");
|
||||
this.translateElm = <HTMLSpanElement>shadow.querySelector("#translated");
|
||||
|
||||
this.addToCollection = <HTMLButtonElement>shadow.querySelector("button");
|
||||
|
||||
this.addToCollection = this.shadowRoot.querySelector("button");
|
||||
this.addToCollection.addEventListener("click", () =>
|
||||
Communicator.addFlashcard({
|
||||
src: this.getAttribute("src"),
|
||||
result: this.getAttribute("translation"),
|
||||
})
|
||||
Communicator.addFlashcard(this.translation)
|
||||
);
|
||||
}
|
||||
|
||||
render = () => {
|
||||
this.srcElm.textContent = this.getAttribute("src");
|
||||
this.translateElm.textContent = this.getAttribute("translation");
|
||||
};
|
||||
|
||||
attributeChangedCallback() {
|
||||
public set translation(v: Translation) {
|
||||
this._translation = v;
|
||||
this.render();
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["src", "translation"];
|
||||
public get translation(): Translation {
|
||||
if (this._translation == null)
|
||||
throw new Error("No translation object provided");
|
||||
return this._translation;
|
||||
}
|
||||
|
||||
render = () => {
|
||||
this.srcElm.textContent = this.translation.src;
|
||||
this.translateElm.textContent = this.translation.result;
|
||||
};
|
||||
}
|
||||
customElements.define("lingo-translation", LingoTranslation);
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<button is="extension-toggle"></button>
|
||||
<button is="lingo-toggle"></button>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -3,7 +3,7 @@ import "./popup.scss";
|
|||
|
||||
const con = new Communicator();
|
||||
|
||||
class ExtensionToggle extends HTMLButtonElement {
|
||||
class Toggle extends HTMLButtonElement {
|
||||
isON: boolean = false;
|
||||
textContent: string = "OFF";
|
||||
|
||||
|
@ -27,23 +27,21 @@ class ExtensionToggle extends HTMLButtonElement {
|
|||
this.addEventListener("click", () => {
|
||||
this.on = !this.on;
|
||||
|
||||
const toggleEvent = new CustomEvent("extensionToggled", {
|
||||
const toggleEvent = new CustomEvent("toggled", {
|
||||
detail: this.on,
|
||||
});
|
||||
this.dispatchEvent(toggleEvent);
|
||||
});
|
||||
}
|
||||
}
|
||||
customElements.define("extension-toggle", ExtensionToggle, {
|
||||
customElements.define("lingo-toggle", Toggle, {
|
||||
extends: "button",
|
||||
});
|
||||
|
||||
const toggle = <ExtensionToggle>(
|
||||
document.querySelector("button[is=extension-toggle]")
|
||||
);
|
||||
toggle.addEventListener("extensionToggled", (e: CustomEvent) =>
|
||||
Communicator.setEnabled(e.detail)
|
||||
);
|
||||
const toggle = <Toggle>document.querySelector("button[is=extension-toggle]");
|
||||
toggle.addEventListener("toggled", ((e: CustomEvent) => {
|
||||
Communicator.setEnabled(e.detail);
|
||||
}) as EventListener); //Hate to do this but ts forced me
|
||||
|
||||
con.setEnabledCallback = (v) => (toggle.on = v);
|
||||
Communicator.getEnabled().then((v) => (toggle.on = v));
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"target": "es6",
|
||||
"allowJs": true,
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true
|
||||
"esModuleInterop": true,
|
||||
"strict": true
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue