summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjbukl <noreply@github.com>2023-11-11 00:57:38 -0500
committerjbukl <noreply@github.com>2023-11-11 00:57:38 -0500
commit9162d950eb2b3aa0339d95a98a60be89b8315f26 (patch)
tree68818c7a12bce02bee8e579d0d5cf8560d941d3c
parent99a4b379565547ac624d0905dce1a5b802c2f9e4 (diff)
Move dictionary db to offscreen
-rw-r--r--ext/js/background/backend.js61
-rw-r--r--ext/js/background/offscreen.js78
2 files changed, 133 insertions, 6 deletions
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js
index cccfcbb3..2c007973 100644
--- a/ext/js/background/backend.js
+++ b/ext/js/background/backend.js
@@ -50,15 +50,15 @@ export class Backend {
constructor() {
this._japaneseUtil = new JapaneseUtil(wanakana);
this._environment = new Environment();
- this._dictionaryDatabase = new DictionaryDatabase();
- this._translator = new Translator({
- japaneseUtil: this._japaneseUtil,
- database: this._dictionaryDatabase
- });
this._anki = new AnkiConnect();
this._mecab = new Mecab();
if (!chrome.offscreen) {
+ this._dictionaryDatabase = new DictionaryDatabase();
+ this._translator = new Translator({
+ japaneseUtil: this._japaneseUtil,
+ database: this._dictionaryDatabase
+ });
this._clipboardReader = new ClipboardReader({
// eslint-disable-next-line no-undef
document: (typeof document === 'object' && document !== null ? document : null),
@@ -66,6 +66,19 @@ export class Backend {
richContentPasteTargetSelector: '#clipboard-rich-content-paste-target'
});
} else {
+ this._dictionaryDatabase = {
+ prepare: () => this._sendMessagePromise({action: 'databasePrepareOffscreen'}),
+ getDictionaryInfo: () => this._sendMessagePromise({action: 'getDictionaryInfoOffscreen'}),
+ purge: () => this._sendMessagePromise({action: 'databasePurgeOffscreen'}),
+ getMedia: this._getMediaOffscreen.bind(this)
+ };
+ this._translator = {
+ prepare: (deinflectionReasons) => this._sendMessagePromise({action: 'translatorPrepareOffscreen', params: {deinflectionReasons}}),
+ findKanji: this._findKanjiOffscreen.bind(this),
+ findTerms: this._findTermsOffscreen.bind(this),
+ getTermFrequencies: this._getTermFrequenciesOffscreen.bind(this),
+ clearDatabaseCaches: () => this._sendMessagePromise({action: 'clearDatabaseCachesOffscreen'})
+ };
this._clipboardReader = {
getText: this._getTextOffscreen.bind(this),
getImage: this._getImageOffscreen.bind(this)
@@ -2240,6 +2253,44 @@ export class Backend {
return results;
}
+ async _getMediaOffscreen(targets) {
+ const serializedMedia = await this._sendMessagePromise({action: 'databaseGetMediaOffscreen', params: {targets}});
+ const media = serializedMedia.map((m) => ({...m, content: ArrayBufferUtil.base64ToArrayBuffer(m.content)}));
+ return media;
+ }
+
+ async _findKanjiOffscreen(text, findKanjiOptions) {
+ const enabledDictionaryMapList = [...findKanjiOptions.enabledDictionaryMap];
+ const modifiedKanjiOptions = {
+ ...findKanjiOptions,
+ enabledDictionaryMap: enabledDictionaryMapList
+ };
+ return this._sendMessagePromise({action: 'findKanjiOffscreen', params: {text, findKanjiOptions: modifiedKanjiOptions}});
+ }
+
+ async _findTermsOffscreen(mode, text, findTermsOptions) {
+ const {enabledDictionaryMap, excludeDictionaryDefinitions, textReplacements} = findTermsOptions;
+ const enabledDictionaryMapList = [...enabledDictionaryMap];
+ const excludeDictionaryDefinitionsList = excludeDictionaryDefinitions ? [...excludeDictionaryDefinitions] : null;
+ const textReplacementsSerialized = textReplacements.map((group) => {
+ if (!group) {
+ return group;
+ }
+ return group.map((opt) => ({...opt, pattern: opt.pattern.toString()}));
+ });
+ const modifiedFindTermsOptions = {
+ ...findTermsOptions,
+ enabledDictionaryMap: enabledDictionaryMapList,
+ excludeDictionaryDefinitions: excludeDictionaryDefinitionsList,
+ textReplacementsOptions: textReplacementsSerialized
+ };
+ return this._sendMessagePromise({action: 'findTermsOffscreen', params: {mode, text, findTermsOptions: modifiedFindTermsOptions}});
+ }
+
+ async _getTermFrequenciesOffscreen(termReadingList, dictionaries) {
+ return this._sendMessagePromise({action: 'getTermFrequenciesOffscreen', params: {termReadingList, dictionaries}});
+ }
+
async _getTextOffscreen(useRichText) {
return this._sendMessagePromise({action: 'clipboardGetTextOffscreen', params: {useRichText}});
}
diff --git a/ext/js/background/offscreen.js b/ext/js/background/offscreen.js
index c37cdedc..1553d996 100644
--- a/ext/js/background/offscreen.js
+++ b/ext/js/background/offscreen.js
@@ -16,8 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import * as wanakana from '../../lib/wanakana.js';
import {ClipboardReader} from '../comm/clipboard-reader.js';
import {invokeMessageHandler} from '../core.js';
+import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js';
+import {DictionaryDatabase} from '../language/dictionary-database.js';
+import {JapaneseUtil} from '../language/sandbox/japanese-util.js';
+import {Translator} from '../language/translator.js';
import {yomichan} from '../yomichan.js';
/**
@@ -29,6 +34,12 @@ export class Offscreen {
* Creates a new instance.
*/
constructor() {
+ this._japaneseUtil = new JapaneseUtil(wanakana);
+ this._dictionaryDatabase = new DictionaryDatabase();
+ this._translator = new Translator({
+ japaneseUtil: this._japaneseUtil,
+ database: this._dictionaryDatabase
+ });
this._clipboardReader = new ClipboardReader({
// eslint-disable-next-line no-undef
document: (typeof document === 'object' && document !== null ? document : null),
@@ -38,11 +49,23 @@ export class Offscreen {
this._messageHandlers = new Map([
['clipboardGetTextOffscreen', {async: true, contentScript: true, handler: this._getTextHandler.bind(this)}],
- ['clipboardGetImageOffscreen', {async: true, contentScript: true, handler: this._getImageHandler.bind(this)}]
+ ['clipboardGetImageOffscreen', {async: true, contentScript: true, handler: this._getImageHandler.bind(this)}],
+ ['databasePrepareOffscreen', {async: true, contentScript: true, handler: this._prepareDatabaseHandler.bind(this)}],
+ ['getDictionaryInfoOffscreen', {async: true, contentScript: true, handler: this._getDictionaryInfoHandler.bind(this)}],
+ ['databasePurgeOffscreen', {async: true, contentScript: true, handler: this._purgeDatabaseHandler.bind(this)}],
+ ['databaseGetMediaOffscreen', {async: true, contentScript: true, handler: this._getMediaHandler.bind(this)}],
+ ['translatorPrepareOffscreen', {async: false, contentScript: true, handler: this._prepareTranslatorHandler.bind(this)}],
+ ['findKanjiOffscreen', {async: true, contentScript: true, handler: this._findKanjiHandler.bind(this)}],
+ ['findTermsOffscreen', {async: true, contentScript: true, handler: this._findTermsHandler.bind(this)}],
+ ['getTermFrequenciesOffscreen', {async: true, contentScript: true, handler: this._getTermFrequenciesHandler.bind(this)}],
+ ['clearDatabaseCachesOffscreen', {async: false, contentScript: true, handler: this._clearDatabaseCachesHandler.bind(this)}]
+
]);
const onMessage = this._onMessage.bind(this);
chrome.runtime.onMessage.addListener(onMessage);
+
+ this._prepareDatabasePromise = null;
}
_getTextHandler({useRichText}) {
@@ -53,6 +76,59 @@ export class Offscreen {
return this._clipboardReader.getImage();
}
+ _prepareDatabaseHandler() {
+ if (this._prepareDatabasePromise !== null) {
+ return this._prepareDatabasePromise;
+ }
+ this._prepareDatabasePromise = this._dictionaryDatabase.prepare();
+ return this._prepareDatabasePromise;
+ }
+
+ _getDictionaryInfoHandler() {
+ return this._dictionaryDatabase.getDictionaryInfo();
+ }
+
+ _purgeDatabaseHandler() {
+ return this._dictionaryDatabase.purge();
+ }
+
+ async _getMediaHandler({targets}) {
+ const media = await this._dictionaryDatabase.getMedia(targets);
+ const serializedMedia = media.map((m) => ({...m, content: ArrayBufferUtil.arrayBufferToBase64(m.content)}));
+ return serializedMedia;
+ }
+
+ _prepareTranslatorHandler({deinflectionReasons}) {
+ return this._translator.prepare(deinflectionReasons);
+ }
+
+ _findKanjiHandler({text, findKanjiOptions}) {
+ findKanjiOptions.enabledDictionaryMap = new Map(findKanjiOptions.enabledDictionaryMap);
+ return this._translator.findKanji(text, findKanjiOptions);
+ }
+
+ _findTermsHandler({mode, text, findTermsOptions}) {
+ findTermsOptions.enabledDictionaryMap = new Map(findTermsOptions.enabledDictionaryMap);
+ if (findTermsOptions.excludeDictionaryDefinitions) {
+ findTermsOptions.excludeDictionaryDefinitions = new Set(findTermsOptions.excludeDictionaryDefinitions);
+ }
+ findTermsOptions.textReplacements = findTermsOptions.textReplacements.map((group) => {
+ if (!group) {
+ return group;
+ }
+ return group.map((opt) => ({...opt, pattern: new RegExp(opt.pattern)}));
+ });
+ return this._translator.findTerms(mode, text, findTermsOptions);
+ }
+
+ _getTermFrequenciesHandler({termReadingList, dictionaries}) {
+ return this._translator.getTermFrequencies(termReadingList, dictionaries);
+ }
+
+ _clearDatabaseCachesHandler() {
+ return this._translator.clearDatabaseCaches();
+ }
+
_onMessage({action, params}, sender, callback) {
const messageHandler = this._messageHandlers.get(action);
if (typeof messageHandler === 'undefined') { return false; }