Gtranslate queue
This commit is contained in:
parent
d5092e4ac0
commit
57ec8ac956
2 changed files with 53 additions and 18 deletions
|
@ -7,7 +7,8 @@ import content_script from "../frontend/content_script/content_script.ts?file";
|
||||||
let com = new Communicator();
|
let com = new Communicator();
|
||||||
|
|
||||||
const scraper = new GTranslateScraper();
|
const scraper = new GTranslateScraper();
|
||||||
com.translateCallback = (toTranslate) => scraper.translate(toTranslate);
|
com.translateCallback = (toTranslate, sender) =>
|
||||||
|
scraper.translate(toTranslate, sender.tab?.id);
|
||||||
|
|
||||||
const db = new Flashcards();
|
const db = new Flashcards();
|
||||||
com.addFlashcardCallback = (c) => db.addFlashcard(c);
|
com.addFlashcardCallback = (c) => db.addFlashcard(c);
|
||||||
|
|
|
@ -1,23 +1,29 @@
|
||||||
import { browser, WebRequest, Runtime } from "webextension-polyfill-ts";
|
import { browser, WebRequest, Runtime } from "webextension-polyfill-ts";
|
||||||
import content_script from "./gtranslate_content_script.ts?file";
|
import content_script from "./gtranslate_content_script.ts?file";
|
||||||
|
|
||||||
|
interface TranslationRequest {
|
||||||
|
tabID?: number;
|
||||||
|
resolveFn: (value: Translation) => void;
|
||||||
|
rejectFn: (reason: String) => void;
|
||||||
|
toTranslate: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class GTranslateScraper {
|
export class GTranslateScraper {
|
||||||
iframe: HTMLIFrameElement;
|
private conn?: Runtime.Port;
|
||||||
conn?: Runtime.Port;
|
private current?: TranslationRequest;
|
||||||
resolveFn?: (value: Translation) => void;
|
private queue: Array<TranslationRequest> = [];
|
||||||
rejectFn?: (reason: String) => void;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
browser.runtime.onConnect.addListener((p) => {
|
browser.runtime.onConnect.addListener((p) => {
|
||||||
if (p.name != "gtranslate_scraper_conn") return;
|
if (p.name != "gtranslate_scraper_conn") return;
|
||||||
this.conn = p;
|
this.conn = p;
|
||||||
|
this.processFromQueue(p);
|
||||||
p.onMessage.addListener((m) => this.onTranslationRecieved(m));
|
p.onMessage.addListener((m) => this.onTranslationRecieved(m));
|
||||||
});
|
});
|
||||||
|
|
||||||
//This allows us to create the google translate iframe by removing the x-frame-options header
|
//This allows us to create the google translate iframe by removing the x-frame-options header
|
||||||
browser.webRequest.onHeadersReceived.addListener(
|
browser.webRequest.onHeadersReceived.addListener(
|
||||||
allowIFrameAccess,
|
allowIFrameAccess,
|
||||||
|
|
||||||
{
|
{
|
||||||
urls: ["<all_urls>"],
|
urls: ["<all_urls>"],
|
||||||
types: ["sub_frame"],
|
types: ["sub_frame"],
|
||||||
|
@ -28,7 +34,6 @@ export class GTranslateScraper {
|
||||||
|
|
||||||
//TODO make the language customizable
|
//TODO make the language customizable
|
||||||
iframe.src = "https://translate.google.com/?op=translate&sl=de&tl=en";
|
iframe.src = "https://translate.google.com/?op=translate&sl=de&tl=en";
|
||||||
this.iframe = iframe;
|
|
||||||
|
|
||||||
//Registers a temp content script, because we cannot inject scripts into iframes created on the background html page, because they have no tabId
|
//Registers a temp content script, because we cannot inject scripts into iframes created on the background html page, because they have no tabId
|
||||||
const js = {
|
const js = {
|
||||||
|
@ -46,21 +51,50 @@ export class GTranslateScraper {
|
||||||
document.body.appendChild(iframe);
|
document.body.appendChild(iframe);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
onTranslationRecieved(message: Translation) {
|
private onTranslationRecieved(message: Translation) {
|
||||||
if (this.resolveFn) this.resolveFn(message);
|
if (this.current) this.current.resolveFn(message);
|
||||||
this.resolveFn = undefined;
|
this.current = undefined;
|
||||||
this.rejectFn = undefined;
|
this.processFromQueue(this.conn!);
|
||||||
}
|
}
|
||||||
|
|
||||||
translate(to_translate: string): Promise<Translation> {
|
private processTranslationRequest(
|
||||||
if (this.rejectFn) this.rejectFn("Got a different translation request");
|
request: TranslationRequest,
|
||||||
if (!this.conn) return Promise.reject("The translator is not yet ready");
|
conn: Runtime.Port
|
||||||
|
) {
|
||||||
|
this.current = request;
|
||||||
|
conn.postMessage(request.toTranslate);
|
||||||
|
}
|
||||||
|
|
||||||
this.conn.postMessage(to_translate);
|
private processFromQueue(conn: Runtime.Port) {
|
||||||
return new Promise((resolve, reject) => {
|
const next = this.queue.pop();
|
||||||
this.resolveFn = resolve;
|
if (next) this.processTranslationRequest(next, conn);
|
||||||
this.rejectFn = reject;
|
}
|
||||||
|
|
||||||
|
translate(to_translate: string, tabID?: number): Promise<Translation> {
|
||||||
|
if (to_translate == "") return Promise.resolve({ src: "", result: "" });
|
||||||
|
|
||||||
|
const p = new Promise((resolve: (value: Translation) => void, reject) => {
|
||||||
|
const req = {
|
||||||
|
toTranslate: to_translate,
|
||||||
|
resolveFn: resolve,
|
||||||
|
rejectFn: reject,
|
||||||
|
tabID: tabID,
|
||||||
|
};
|
||||||
|
if (this.current || !this.conn) {
|
||||||
|
//Remove the requests from the same tab
|
||||||
|
if (tabID)
|
||||||
|
this.queue = this.queue.filter((r) => {
|
||||||
|
if (r.tabID !== tabID) {
|
||||||
|
r.rejectFn("Got another request from the same tab");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
this.queue.push(req);
|
||||||
|
} else {
|
||||||
|
this.processTranslationRequest(req, this.conn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue