aboutsummaryrefslogtreecommitdiff
path: root/ext/bg/js/backend.js
diff options
context:
space:
mode:
authorAlex Yatskov <alex@foosoft.net>2020-04-16 17:30:09 -0700
committerAlex Yatskov <alex@foosoft.net>2020-04-16 17:30:09 -0700
commit93c4fb9eab2651da24fb816f20dcb967eae1437e (patch)
treedf8f6d5e04da7e6e78db4712d4d3d92c460454b9 /ext/bg/js/backend.js
parent3b9a87b2ebe843e30536924639d6c14afef936cd (diff)
parent8c16a6e580bfdd70e27df1816ca90807062cf9b5 (diff)
Merge branch 'master' of https://github.com/FooSoft/yomichan
Diffstat (limited to 'ext/bg/js/backend.js')
-rw-r--r--ext/bg/js/backend.js236
1 files changed, 130 insertions, 106 deletions
diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js
index 6386319b..2265c1a9 100644
--- a/ext/bg/js/backend.js
+++ b/ext/bg/js/backend.js
@@ -30,7 +30,6 @@
* Translator
* conditionsTestValue
* dictConfigured
- * dictEnabledSet
* dictTermsSort
* handlebarsRenderDynamic
* jp
@@ -76,33 +75,32 @@ class Backend {
this.messageToken = yomichan.generateId(16);
this._messageHandlers = new Map([
- ['yomichanCoreReady', this._onApiYomichanCoreReady.bind(this)],
- ['optionsSchemaGet', this._onApiOptionsSchemaGet.bind(this)],
- ['optionsGet', this._onApiOptionsGet.bind(this)],
- ['optionsGetFull', this._onApiOptionsGetFull.bind(this)],
- ['optionsSet', this._onApiOptionsSet.bind(this)],
- ['optionsSave', this._onApiOptionsSave.bind(this)],
- ['kanjiFind', this._onApiKanjiFind.bind(this)],
- ['termsFind', this._onApiTermsFind.bind(this)],
- ['textParse', this._onApiTextParse.bind(this)],
- ['textParseMecab', this._onApiTextParseMecab.bind(this)],
- ['definitionAdd', this._onApiDefinitionAdd.bind(this)],
- ['definitionsAddable', this._onApiDefinitionsAddable.bind(this)],
- ['noteView', this._onApiNoteView.bind(this)],
- ['templateRender', this._onApiTemplateRender.bind(this)],
- ['commandExec', this._onApiCommandExec.bind(this)],
- ['audioGetUri', this._onApiAudioGetUri.bind(this)],
- ['screenshotGet', this._onApiScreenshotGet.bind(this)],
- ['forward', this._onApiForward.bind(this)],
- ['frameInformationGet', this._onApiFrameInformationGet.bind(this)],
- ['injectStylesheet', this._onApiInjectStylesheet.bind(this)],
- ['getEnvironmentInfo', this._onApiGetEnvironmentInfo.bind(this)],
- ['clipboardGet', this._onApiClipboardGet.bind(this)],
- ['getDisplayTemplatesHtml', this._onApiGetDisplayTemplatesHtml.bind(this)],
- ['getQueryParserTemplatesHtml', this._onApiGetQueryParserTemplatesHtml.bind(this)],
- ['getZoom', this._onApiGetZoom.bind(this)],
- ['getMessageToken', this._onApiGetMessageToken.bind(this)],
- ['getDefaultAnkiFieldTemplates', this._onApiGetDefaultAnkiFieldTemplates.bind(this)]
+ ['yomichanCoreReady', {handler: this._onApiYomichanCoreReady.bind(this), async: false}],
+ ['optionsSchemaGet', {handler: this._onApiOptionsSchemaGet.bind(this), async: false}],
+ ['optionsGet', {handler: this._onApiOptionsGet.bind(this), async: false}],
+ ['optionsGetFull', {handler: this._onApiOptionsGetFull.bind(this), async: false}],
+ ['optionsSet', {handler: this._onApiOptionsSet.bind(this), async: true}],
+ ['optionsSave', {handler: this._onApiOptionsSave.bind(this), async: true}],
+ ['kanjiFind', {handler: this._onApiKanjiFind.bind(this), async: true}],
+ ['termsFind', {handler: this._onApiTermsFind.bind(this), async: true}],
+ ['textParse', {handler: this._onApiTextParse.bind(this), async: true}],
+ ['definitionAdd', {handler: this._onApiDefinitionAdd.bind(this), async: true}],
+ ['definitionsAddable', {handler: this._onApiDefinitionsAddable.bind(this), async: true}],
+ ['noteView', {handler: this._onApiNoteView.bind(this), async: true}],
+ ['templateRender', {handler: this._onApiTemplateRender.bind(this), async: true}],
+ ['commandExec', {handler: this._onApiCommandExec.bind(this), async: false}],
+ ['audioGetUri', {handler: this._onApiAudioGetUri.bind(this), async: true}],
+ ['screenshotGet', {handler: this._onApiScreenshotGet.bind(this), async: true}],
+ ['broadcastTab', {handler: this._onApiBroadcastTab.bind(this), async: false}],
+ ['frameInformationGet', {handler: this._onApiFrameInformationGet.bind(this), async: true}],
+ ['injectStylesheet', {handler: this._onApiInjectStylesheet.bind(this), async: true}],
+ ['getEnvironmentInfo', {handler: this._onApiGetEnvironmentInfo.bind(this), async: true}],
+ ['clipboardGet', {handler: this._onApiClipboardGet.bind(this), async: true}],
+ ['getDisplayTemplatesHtml', {handler: this._onApiGetDisplayTemplatesHtml.bind(this), async: true}],
+ ['getQueryParserTemplatesHtml', {handler: this._onApiGetQueryParserTemplatesHtml.bind(this), async: true}],
+ ['getZoom', {handler: this._onApiGetZoom.bind(this), async: true}],
+ ['getMessageToken', {handler: this._onApiGetMessageToken.bind(this), async: false}],
+ ['getDefaultAnkiFieldTemplates', {handler: this._onApiGetDefaultAnkiFieldTemplates.bind(this), async: false}]
]);
this._commandHandlers = new Map([
@@ -166,16 +164,23 @@ class Backend {
}
onMessage({action, params}, sender, callback) {
- const handler = this._messageHandlers.get(action);
- if (typeof handler !== 'function') { return false; }
+ const messageHandler = this._messageHandlers.get(action);
+ if (typeof messageHandler === 'undefined') { return false; }
+
+ const {handler, async} = messageHandler;
try {
- const promise = handler(params, sender);
- promise.then(
- (result) => callback({result}),
- (error) => callback({error: errorToJson(error)})
- );
- return true;
+ const promiseOrResult = handler(params, sender);
+ if (async) {
+ promiseOrResult.then(
+ (result) => callback({result}),
+ (error) => callback({error: errorToJson(error)})
+ );
+ return true;
+ } else {
+ callback({result: promiseOrResult});
+ return false;
+ }
} catch (error) {
callback({error: errorToJson(error)});
return false;
@@ -308,31 +313,84 @@ class Backend {
return await this.dictionaryImporter.import(this.database, archiveSource, onProgress, details);
}
+ async _textParseScanning(text, options) {
+ const results = [];
+ while (text.length > 0) {
+ const term = [];
+ const [definitions, sourceLength] = await this.translator.findTerms(
+ 'simple',
+ text.substring(0, options.scanning.length),
+ {},
+ options
+ );
+ if (definitions.length > 0 && sourceLength > 0) {
+ dictTermsSort(definitions);
+ const {expression, reading} = definitions[0];
+ const source = text.substring(0, sourceLength);
+ for (const {text: text2, furigana} of jp.distributeFuriganaInflected(expression, reading, source)) {
+ const reading2 = jp.convertReading(text2, furigana, options.parsing.readingMode);
+ term.push({text: text2, reading: reading2});
+ }
+ text = text.substring(source.length);
+ } else {
+ const reading = jp.convertReading(text[0], '', options.parsing.readingMode);
+ term.push({text: text[0], reading});
+ text = text.substring(1);
+ }
+ results.push(term);
+ }
+ return results;
+ }
+
+ async _textParseMecab(text, options) {
+ const results = [];
+ const rawResults = await this.mecab.parseText(text);
+ for (const [mecabName, parsedLines] of Object.entries(rawResults)) {
+ const result = [];
+ for (const parsedLine of parsedLines) {
+ for (const {expression, reading, source} of parsedLine) {
+ const term = [];
+ for (const {text: text2, furigana} of jp.distributeFuriganaInflected(
+ expression.length > 0 ? expression : source,
+ jp.convertKatakanaToHiragana(reading),
+ source
+ )) {
+ const reading2 = jp.convertReading(text2, furigana, options.parsing.readingMode);
+ term.push({text: text2, reading: reading2});
+ }
+ result.push(term);
+ }
+ result.push([{text: '\n', reading: ''}]);
+ }
+ results.push([mecabName, result]);
+ }
+ return results;
+ }
+
// Message handlers
_onApiYomichanCoreReady(_params, sender) {
// tab ID isn't set in background (e.g. browser_action)
+ const callback = () => this.checkLastError(chrome.runtime.lastError);
+ const data = {action: 'backendPrepared'};
if (typeof sender.tab === 'undefined') {
- const callback = () => this.checkLastError(chrome.runtime.lastError);
- chrome.runtime.sendMessage({action: 'backendPrepared'}, callback);
- return Promise.resolve();
+ chrome.runtime.sendMessage(data, callback);
+ return false;
+ } else {
+ chrome.tabs.sendMessage(sender.tab.id, data, callback);
+ return true;
}
-
- const tabId = sender.tab.id;
- return new Promise((resolve) => {
- chrome.tabs.sendMessage(tabId, {action: 'backendPrepared'}, resolve);
- });
}
- async _onApiOptionsSchemaGet() {
+ _onApiOptionsSchemaGet() {
return this.getOptionsSchema();
}
- async _onApiOptionsGet({optionsContext}) {
+ _onApiOptionsGet({optionsContext}) {
return this.getOptions(optionsContext);
}
- async _onApiOptionsGetFull() {
+ _onApiOptionsGetFull() {
return this.getFullOptions();
}
@@ -400,61 +458,27 @@ class Backend {
async _onApiTextParse({text, optionsContext}) {
const options = this.getOptions(optionsContext);
const results = [];
- while (text.length > 0) {
- const term = [];
- const [definitions, sourceLength] = await this.translator.findTerms(
- 'simple',
- text.substring(0, options.scanning.length),
- {},
- options
- );
- if (definitions.length > 0) {
- dictTermsSort(definitions);
- const {expression, reading} = definitions[0];
- const source = text.substring(0, sourceLength);
- for (const {text: text2, furigana} of jp.distributeFuriganaInflected(expression, reading, source)) {
- const reading2 = jp.convertReading(text2, furigana, options.parsing.readingMode);
- term.push({text: text2, reading: reading2});
- }
- text = text.substring(source.length);
- } else {
- const reading = jp.convertReading(text[0], null, options.parsing.readingMode);
- term.push({text: text[0], reading});
- text = text.substring(1);
- }
- results.push(term);
+
+ if (options.parsing.enableScanningParser) {
+ results.push({
+ source: 'scanning-parser',
+ id: 'scan',
+ content: await this._textParseScanning(text, options)
+ });
}
- return results;
- }
- async _onApiTextParseMecab({text, optionsContext}) {
- const options = this.getOptions(optionsContext);
- const results = [];
- const rawResults = await this.mecab.parseText(text);
- for (const [mecabName, parsedLines] of Object.entries(rawResults)) {
- const result = [];
- for (const parsedLine of parsedLines) {
- for (const {expression, reading, source} of parsedLine) {
- const term = [];
- if (expression !== null && reading !== null) {
- for (const {text: text2, furigana} of jp.distributeFuriganaInflected(
- expression,
- jp.convertKatakanaToHiragana(reading),
- source
- )) {
- const reading2 = jp.convertReading(text2, furigana, options.parsing.readingMode);
- term.push({text: text2, reading: reading2});
- }
- } else {
- const reading2 = jp.convertReading(source, null, options.parsing.readingMode);
- term.push({text: source, reading: reading2});
- }
- result.push(term);
- }
- result.push([{text: '\n'}]);
+ if (options.parsing.enableMecabParser) {
+ const mecabResults = await this._textParseMecab(text, options);
+ for (const [mecabDictName, mecabDictResults] of mecabResults) {
+ results.push({
+ source: 'mecab',
+ dictionary: mecabDictName,
+ id: `mecab-${mecabDictName}`,
+ content: mecabDictResults
+ });
}
- results.push([mecabName, result]);
}
+
return results;
}
@@ -539,7 +563,7 @@ class Backend {
return this._renderTemplate(template, data);
}
- async _onApiCommandExec({command, params}) {
+ _onApiCommandExec({command, params}) {
return this._runCommand(command, params);
}
@@ -559,15 +583,15 @@ class Backend {
});
}
- _onApiForward({action, params}, sender) {
+ _onApiBroadcastTab({action, params}, sender) {
if (!(sender && sender.tab)) {
- return Promise.resolve();
+ return false;
}
const tabId = sender.tab.id;
- return new Promise((resolve) => {
- chrome.tabs.sendMessage(tabId, {action, params}, (response) => resolve(response));
- });
+ const callback = () => this.checkLastError(chrome.runtime.lastError);
+ chrome.tabs.sendMessage(tabId, {action, params}, callback);
+ return true;
}
_onApiFrameInformationGet(params, sender) {
@@ -690,11 +714,11 @@ class Backend {
});
}
- async _onApiGetMessageToken() {
+ _onApiGetMessageToken() {
return this.messageToken;
}
- async _onApiGetDefaultAnkiFieldTemplates() {
+ _onApiGetDefaultAnkiFieldTemplates() {
return this.defaultAnkiFieldTemplates;
}