diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2023-11-27 17:43:53 -0500 |
---|---|---|
committer | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2023-11-27 17:43:53 -0500 |
commit | 29317da4ea237557e1805a834913dad73c51ed8a (patch) | |
tree | e19ff6014774b42a95c22dbc7874b51d7bc3bf66 /ext/js/background/offscreen.js | |
parent | a96be7d413c8f1714f0d1b44b3987f2eb87b22d8 (diff) |
Update offscreen
Diffstat (limited to 'ext/js/background/offscreen.js')
-rw-r--r-- | ext/js/background/offscreen.js | 121 |
1 files changed, 68 insertions, 53 deletions
diff --git a/ext/js/background/offscreen.js b/ext/js/background/offscreen.js index 6302aa84..1b68887b 100644 --- a/ext/js/background/offscreen.js +++ b/ext/js/background/offscreen.js @@ -23,7 +23,6 @@ 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 {yomitan} from '../yomitan.js'; /** * This class controls the core logic of the extension, including API calls @@ -34,12 +33,16 @@ export class Offscreen { * Creates a new instance. */ constructor() { + /** @type {JapaneseUtil} */ this._japaneseUtil = new JapaneseUtil(wanakana); + /** @type {DictionaryDatabase} */ this._dictionaryDatabase = new DictionaryDatabase(); + /** @type {Translator} */ this._translator = new Translator({ japaneseUtil: this._japaneseUtil, database: this._dictionaryDatabase }); + /** @type {ClipboardReader} */ this._clipboardReader = new ClipboardReader({ // eslint-disable-next-line no-undef document: (typeof document === 'object' && document !== null ? document : null), @@ -47,42 +50,45 @@ export class Offscreen { richContentPasteTargetSelector: '#clipboard-rich-content-paste-target' }); + /** @type {import('offscreen').MessageHandlerMap} */ this._messageHandlers = new Map([ - ['clipboardGetTextOffscreen', {async: true, contentScript: true, handler: this._getTextHandler.bind(this)}], - ['clipboardGetImageOffscreen', {async: true, contentScript: true, handler: this._getImageHandler.bind(this)}], - ['clipboardSetBrowserOffsecreen', {async: false, contentScript: true, handler: this._setClipboardBrowser.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)}] + ['clipboardGetTextOffscreen', {async: true, handler: this._getTextHandler.bind(this)}], + ['clipboardGetImageOffscreen', {async: true, handler: this._getImageHandler.bind(this)}], + ['clipboardSetBrowserOffscreen', {async: false, handler: this._setClipboardBrowser.bind(this)}], + ['databasePrepareOffscreen', {async: true, handler: this._prepareDatabaseHandler.bind(this)}], + ['getDictionaryInfoOffscreen', {async: true, handler: this._getDictionaryInfoHandler.bind(this)}], + ['databasePurgeOffscreen', {async: true, handler: this._purgeDatabaseHandler.bind(this)}], + ['databaseGetMediaOffscreen', {async: true, handler: this._getMediaHandler.bind(this)}], + ['translatorPrepareOffscreen', {async: false, handler: this._prepareTranslatorHandler.bind(this)}], + ['findKanjiOffscreen', {async: true, handler: this._findKanjiHandler.bind(this)}], + ['findTermsOffscreen', {async: true, handler: this._findTermsHandler.bind(this)}], + ['getTermFrequenciesOffscreen', {async: true, handler: this._getTermFrequenciesHandler.bind(this)}], + ['clearDatabaseCachesOffscreen', {async: false, handler: this._clearDatabaseCachesHandler.bind(this)}] ]); const onMessage = this._onMessage.bind(this); chrome.runtime.onMessage.addListener(onMessage); + /** @type {?Promise<void>} */ this._prepareDatabasePromise = null; } - _getTextHandler({useRichText}) { - return this._clipboardReader.getText(useRichText); + /** @type {import('offscreen').MessageHandler<'clipboardGetTextOffscreen', true>} */ + async _getTextHandler({useRichText}) { + return await this._clipboardReader.getText(useRichText); } - _getImageHandler() { - return this._clipboardReader.getImage(); + /** @type {import('offscreen').MessageHandler<'clipboardGetImageOffscreen', true>} */ + async _getImageHandler() { + return await this._clipboardReader.getImage(); } - /** - * @param {{value: import('environment').Browser}} details - */ + /** @type {import('offscreen').MessageHandler<'clipboardSetBrowserOffscreen', false>} */ _setClipboardBrowser({value}) { this._clipboardReader.browser = value; } + /** @type {import('offscreen').MessageHandler<'databasePrepareOffscreen', true>} */ _prepareDatabaseHandler() { if (this._prepareDatabasePromise !== null) { return this._prepareDatabasePromise; @@ -91,70 +97,79 @@ export class Offscreen { return this._prepareDatabasePromise; } - _getDictionaryInfoHandler() { - return this._dictionaryDatabase.getDictionaryInfo(); + /** @type {import('offscreen').MessageHandler<'getDictionaryInfoOffscreen', true>} */ + async _getDictionaryInfoHandler() { + return await this._dictionaryDatabase.getDictionaryInfo(); } - _purgeDatabaseHandler() { - return this._dictionaryDatabase.purge(); + /** @type {import('offscreen').MessageHandler<'databasePurgeOffscreen', true>} */ + async _purgeDatabaseHandler() { + return await this._dictionaryDatabase.purge(); } + /** @type {import('offscreen').MessageHandler<'databaseGetMediaOffscreen', true>} */ async _getMediaHandler({targets}) { const media = await this._dictionaryDatabase.getMedia(targets); const serializedMedia = media.map((m) => ({...m, content: ArrayBufferUtil.arrayBufferToBase64(m.content)})); return serializedMedia; } + /** @type {import('offscreen').MessageHandler<'translatorPrepareOffscreen', false>} */ _prepareTranslatorHandler({deinflectionReasons}) { - return this._translator.prepare(deinflectionReasons); + this._translator.prepare(deinflectionReasons); } - _findKanjiHandler({text, findKanjiOptions}) { - findKanjiOptions.enabledDictionaryMap = new Map(findKanjiOptions.enabledDictionaryMap); - return this._translator.findKanji(text, findKanjiOptions); + /** @type {import('offscreen').MessageHandler<'findKanjiOffscreen', true>} */ + async _findKanjiHandler({text, options}) { + /** @type {import('translation').FindKanjiOptions} */ + const modifiedOptions = { + ...options, + enabledDictionaryMap: new Map(options.enabledDictionaryMap) + }; + return await this._translator.findKanji(text, modifiedOptions); } - _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; - } + /** @type {import('offscreen').MessageHandler<'findTermsOffscreen', true>} */ + _findTermsHandler({mode, text, options}) { + const enabledDictionaryMap = new Map(options.enabledDictionaryMap); + const excludeDictionaryDefinitions = ( + options.excludeDictionaryDefinitions !== null ? + new Set(options.excludeDictionaryDefinitions) : + null + ); + const textReplacements = options.textReplacements.map((group) => { + if (group === null) { return null; } return group.map((opt) => { - const [, pattern, flags] = opt.pattern.match(/\/(.*?)\/([a-z]*)?$/i); // https://stackoverflow.com/a/33642463 + // https://stackoverflow.com/a/33642463 + const match = opt.pattern.match(/\/(.*?)\/([a-z]*)?$/i); + const [, pattern, flags] = match !== null ? match : ['', '', '']; return {...opt, pattern: new RegExp(pattern, flags ?? '')}; }); }); - return this._translator.findTerms(mode, text, findTermsOptions); + /** @type {import('translation').FindTermsOptions} */ + const modifiedOptions = { + ...options, + enabledDictionaryMap, + excludeDictionaryDefinitions, + textReplacements + }; + return this._translator.findTerms(mode, text, modifiedOptions); } + /** @type {import('offscreen').MessageHandler<'getTermFrequenciesOffscreen', true>} */ _getTermFrequenciesHandler({termReadingList, dictionaries}) { return this._translator.getTermFrequencies(termReadingList, dictionaries); } + /** @type {import('offscreen').MessageHandler<'clearDatabaseCachesOffscreen', false>} */ _clearDatabaseCachesHandler() { - return this._translator.clearDatabaseCaches(); + this._translator.clearDatabaseCaches(); } + /** @type {import('extension').ChromeRuntimeOnMessageCallback} */ _onMessage({action, params}, sender, callback) { const messageHandler = this._messageHandlers.get(action); if (typeof messageHandler === 'undefined') { return false; } - this._validatePrivilegedMessageSender(sender); - return invokeMessageHandler(messageHandler, params, callback, sender); } - - _validatePrivilegedMessageSender(sender) { - let {url} = sender; - if (typeof url === 'string' && yomitan.isExtensionUrl(url)) { return; } - const {tab} = url; - if (typeof tab === 'object' && tab !== null) { - ({url} = tab); - if (typeof url === 'string' && yomitan.isExtensionUrl(url)) { return; } - } - throw new Error('Invalid message sender'); - } } |