diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /toolkit/components/translations/actors/TranslationsChild.sys.mjs | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/translations/actors/TranslationsChild.sys.mjs')
-rw-r--r-- | toolkit/components/translations/actors/TranslationsChild.sys.mjs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/toolkit/components/translations/actors/TranslationsChild.sys.mjs b/toolkit/components/translations/actors/TranslationsChild.sys.mjs new file mode 100644 index 0000000000..a3f8d15c85 --- /dev/null +++ b/toolkit/components/translations/actors/TranslationsChild.sys.mjs @@ -0,0 +1,118 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const lazy = {}; +ChromeUtils.defineESModuleGetters(lazy, { + TranslationsDocument: + "chrome://global/content/translations/translations-document.sys.mjs", + LRUCache: + "chrome://global/content/translations/translations-document.sys.mjs", + LanguageDetector: + "resource://gre/modules/translation/LanguageDetector.sys.mjs", +}); + +/** + * This file is extremely sensitive to memory size and performance! + */ +export class TranslationsChild extends JSWindowActorChild { + /** + * @type {TranslationsDocument | null} + */ + #translatedDoc = null; + + /** + * This cache is shared across TranslationsChild instances. This means + * that it will be shared across multiple page loads in the same origin. + * @type {LRUCache | null} + */ + static #translationsCache = null; + + handleEvent(event) { + switch (event.type) { + case "DOMContentLoaded": + this.sendAsyncMessage("Translations:ReportLangTags", { + documentElementLang: this.document.documentElement.lang, + }); + break; + } + } + + addProfilerMarker(message) { + ChromeUtils.addProfilerMarker( + "TranslationsChild", + { innerWindowId: this.contentWindow.windowGlobalChild.innerWindowId }, + message + ); + } + + async receiveMessage({ name, data }) { + switch (name) { + case "Translations:TranslatePage": { + if (this.#translatedDoc?.translator.engineStatus === "error") { + this.#translatedDoc.destroy(); + this.#translatedDoc = null; + } + + if (this.#translatedDoc) { + console.error("This page was already translated."); + return undefined; + } + + const { fromLanguage, toLanguage, port, translationsStart } = data; + if ( + !TranslationsChild.#translationsCache || + !TranslationsChild.#translationsCache.matches( + fromLanguage, + toLanguage + ) + ) { + TranslationsChild.#translationsCache = new lazy.LRUCache( + fromLanguage, + toLanguage + ); + } + + this.#translatedDoc = new lazy.TranslationsDocument( + this.document, + fromLanguage, + toLanguage, + this.contentWindow.windowGlobalChild.innerWindowId, + port, + () => this.sendAsyncMessage("Translations:RequestPort"), + translationsStart, + () => this.docShell.now(), + TranslationsChild.#translationsCache + ); + + return undefined; + } + case "Translations:GetDocumentElementLang": + return this.document.documentElement.lang; + case "Translations:IdentifyLanguage": { + // Wait for idle callback as the page will be more settled if it has + // dynamic content, like on a React app. + if (this.contentWindow) { + await new Promise(resolve => { + this.contentWindow.requestIdleCallback(resolve); + }); + } + + try { + return lazy.LanguageDetector.detectLanguageFromDocument( + this.document + ); + } catch (error) { + return null; + } + } + case "Translations:AcquirePort": { + this.addProfilerMarker("Acquired a port, resuming translations"); + this.#translatedDoc.translator.acquirePort(data.port); + return undefined; + } + default: + throw new Error("Unknown message.", name); + } + } +} |