From e14b52ef84be7feeab60167605fd10918a242cd3 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 4 Apr 2021 16:22:35 -0400 Subject: [PATCH] Update dictionary entry terminology (#1592) * Update terminology * Update terminology in display.js * Update terminology in display-audio.js * Update terminology in text-scanner.js * Update terminology in backend.js * Update terminology in mecab.js * Update terminology in audio-downloader.js * Update terminology in translator-vm.js * Update terminology in dictionary-data-util.js * Update terminology in dictionary-database.js * Update terminology in japanese-util.js * Change/upgrade {expression} to {term} * Update terminology in test-japanese.js * Update terminology in test-database.js * Update terminology in anki-templates-controller.js * Update terminology in anki-note-builder.js * Update terminology in backend.js * Update terminology in text-scanner.js * Update terminology in display.js * Update terminology in display.js --- dev/translator-vm.js | 4 +- ext/js/app/frontend.js | 8 +- ext/js/background/backend.js | 26 +-- ext/js/comm/api.js | 4 +- ext/js/comm/mecab.js | 8 +- ext/js/data/anki-note-builder.js | 12 +- ext/js/data/anki-note-data-creator.js | 2 +- ext/js/data/options-util.js | 8 + ext/js/display/display-audio.js | 165 ++++++++-------- ext/js/display/display-generator.js | 138 +++++++------- ext/js/display/display.js | 180 +++++++++--------- ext/js/display/search-display-controller.js | 2 +- ext/js/language/dictionary-data-util.js | 8 +- ext/js/language/dictionary-database.js | 8 +- ext/js/language/japanese-util.js | 26 +-- ext/js/language/text-scanner.js | 34 ++-- ext/js/language/translator.js | 23 +-- ext/js/media/audio-downloader.js | 44 ++--- .../settings/anki-templates-controller.js | 34 ++-- ext/settings.html | 6 +- test/test-anki-note-builder.js | 2 +- test/test-database.js | 80 ++++---- test/test-japanese.js | 16 +- test/test-options-util.js | 4 +- 24 files changed, 428 insertions(+), 414 deletions(-) diff --git a/dev/translator-vm.js b/dev/translator-vm.js index b7760f4a..4b5403da 100644 --- a/dev/translator-vm.js +++ b/dev/translator-vm.js @@ -105,10 +105,10 @@ class TranslatorVM extends DatabaseVM { this._ankiNoteDataCreator = new AnkiNoteDataCreator(this._japaneseUtil); } - createTestAnkiNoteData(definition, mode) { + createTestAnkiNoteData(dictionaryEntry, mode) { const marker = '{marker}'; const data = { - definition, + dictionaryEntry, resultOutputMode: mode, mode: 'mode', glossaryLayoutMode: 'default', diff --git a/ext/js/app/frontend.js b/ext/js/app/frontend.js index 31e93a68..c7e8c9d8 100644 --- a/ext/js/app/frontend.js +++ b/ext/js/app/frontend.js @@ -257,7 +257,7 @@ class Frontend { } } - _onSearched({type, definitions, sentence, inputInfo: {eventType, passive, detail}, textSource, optionsContext, detail: {documentTitle}, error}) { + _onSearched({type, dictionaryEntries, sentence, inputInfo: {eventType, passive, detail}, textSource, optionsContext, detail: {documentTitle}, error}) { const scanningOptions = this._options.scanning; if (error !== null) { @@ -275,7 +275,7 @@ class Frontend { const focus2 = detail.focus; if (typeof focus2 === 'boolean') { focus = focus2; } } - this._showContent(textSource, focus, definitions, type, sentence, documentTitle, optionsContext); + this._showContent(textSource, focus, dictionaryEntries, type, sentence, documentTitle, optionsContext); } else { if (scanningOptions.autoHideResults) { this._clearSelectionDelayed(scanningOptions.hideDelay, false); @@ -505,7 +505,7 @@ class Frontend { this._showPopupContent(textSource, null); } - _showContent(textSource, focus, definitions, type, sentence, documentTitle, optionsContext) { + _showContent(textSource, focus, dictionaryEntries, type, sentence, documentTitle, optionsContext) { const query = textSource.text(); const {url} = optionsContext; const details = { @@ -524,7 +524,7 @@ class Frontend { documentTitle }, content: { - definitions, + dictionaryEntries, contentOrigin: { tabId: this._tabId, frameId: this._frameId diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js index cf8137e5..a6b9c0dc 100644 --- a/ext/js/background/backend.js +++ b/ext/js/background/backend.js @@ -101,7 +101,7 @@ class Backend { ['noteView', {async: true, contentScript: true, handler: this._onApiNoteView.bind(this)}], ['suspendAnkiCardsForNote', {async: true, contentScript: true, handler: this._onApiSuspendAnkiCardsForNote.bind(this)}], ['commandExec', {async: false, contentScript: true, handler: this._onApiCommandExec.bind(this)}], - ['getExpressionAudioInfoList', {async: true, contentScript: true, handler: this._onApiGetExpressionAudioInfoList.bind(this)}], + ['getTermAudioInfoList', {async: true, contentScript: true, handler: this._onApiGetTermAudioInfoList.bind(this)}], ['sendMessageToFrame', {async: false, contentScript: true, handler: this._onApiSendMessageToFrame.bind(this)}], ['broadcastTab', {async: false, contentScript: true, handler: this._onApiBroadcastTab.bind(this)}], ['frameInformationGet', {async: true, contentScript: true, handler: this._onApiFrameInformationGet.bind(this)}], @@ -405,9 +405,9 @@ class Backend { const options = this._getProfileOptions(optionsContext); const {general: {maxResults}} = options; const findKanjiOptions = this._getTranslatorFindKanjiOptions(options); - const definitions = await this._translator.findKanji(text, findKanjiOptions); - definitions.splice(maxResults); - return definitions; + const dictionaryEntries = await this._translator.findKanji(text, findKanjiOptions); + dictionaryEntries.splice(maxResults); + return dictionaryEntries; } async _onApiTermsFind({text, details, optionsContext}) { @@ -416,7 +416,7 @@ class Backend { const findTermsOptions = this._getTranslatorFindTermsOptions(details, options); const {dictionaryEntries, originalTextLength} = await this._translator.findTerms(mode, text, findTermsOptions); dictionaryEntries.splice(maxResults); - return {length: originalTextLength, definitions: dictionaryEntries}; + return {dictionaryEntries, originalTextLength}; } async _onApiTextParse({text, optionsContext}) { @@ -518,8 +518,8 @@ class Backend { return this._runCommand(command, params); } - async _onApiGetExpressionAudioInfoList({source, expression, reading, details}) { - return await this._audioDownloader.getExpressionAudioInfoList(source, expression, reading, details); + async _onApiGetTermAudioInfoList({source, term, reading, details}) { + return await this._audioDownloader.getTermAudioInfoList(source, term, reading, details); } _onApiSendMessageToFrame({frameId: targetFrameId, action, params}, sender) { @@ -1100,17 +1100,17 @@ class Backend { for (const {name, lines} of parseTextResults) { const result = []; for (const line of lines) { - for (const {expression, reading, source} of line) { - const term = []; + for (const {term, reading, source} of line) { + const termParts = []; for (const {text: text2, furigana} of jp.distributeFuriganaInflected( - expression.length > 0 ? expression : source, + term.length > 0 ? term : source, jp.convertKatakanaToHiragana(reading), source )) { const reading2 = jp.convertReading(text2, furigana, readingMode); - term.push({text: text2, reading: reading2}); + termParts.push({text: text2, reading: reading2}); } - result.push(term); + result.push(termParts); } result.push([{text: '\n', reading: ''}]); } @@ -1742,7 +1742,7 @@ class Backend { let data; let contentType; try { - ({data, contentType} = await this._audioDownloader.downloadExpressionAudio( + ({data, contentType} = await this._audioDownloader.downloadTermAudio( sources, preferredAudioIndex, term, diff --git a/ext/js/comm/api.js b/ext/js/comm/api.js index a2eb004c..137cda41 100644 --- a/ext/js/comm/api.js +++ b/ext/js/comm/api.js @@ -68,8 +68,8 @@ class API { return this._invoke('suspendAnkiCardsForNote', {noteId}); } - getExpressionAudioInfoList(source, expression, reading, details) { - return this._invoke('getExpressionAudioInfoList', {source, expression, reading, details}); + getTermAudioInfoList(source, term, reading, details) { + return this._invoke('getTermAudioInfoList', {source, term, reading, details}); } commandExec(command, params) { diff --git a/ext/js/comm/mecab.js b/ext/js/comm/mecab.js index 4eff2927..9a706391 100644 --- a/ext/js/comm/mecab.js +++ b/ext/js/comm/mecab.js @@ -108,7 +108,7 @@ class Mecab { * { * name: (string), * lines: [ - * {expression: (string), reading: (string), source: (string)}, + * {term: (string), reading: (string), source: (string)}, * ... * ] * }, @@ -172,11 +172,11 @@ class Mecab { const lines = []; for (const rawLine of rawLines) { const line = []; - for (let {expression, reading, source} of rawLine) { - if (typeof expression !== 'string') { expression = ''; } + for (let {expression: term, reading, source} of rawLine) { + if (typeof term !== 'string') { term = ''; } if (typeof reading !== 'string') { reading = ''; } if (typeof source !== 'string') { source = ''; } - line.push({expression, reading, source}); + line.push({term, reading, source}); } lines.push(line); } diff --git a/ext/js/data/anki-note-builder.js b/ext/js/data/anki-note-builder.js index 13e83aaf..85a68265 100644 --- a/ext/js/data/anki-note-builder.js +++ b/ext/js/data/anki-note-builder.js @@ -29,7 +29,7 @@ class AnkiNoteBuilder { } async createNote({ - definition, + dictionaryEntry, mode, context, template, @@ -53,7 +53,7 @@ class AnkiNoteBuilder { duplicateScopeCheckChildren = true; } - const commonData = this._createData(definition, mode, context, resultOutputMode, glossaryLayoutMode, compactTags, injectedMedia); + const commonData = this._createData(dictionaryEntry, mode, context, resultOutputMode, glossaryLayoutMode, compactTags, injectedMedia); const formattedFieldValuePromises = []; for (const [, fieldValue] of fields) { const formattedFieldValuePromise = this._formatField(fieldValue, commonData, template, errors); @@ -85,7 +85,7 @@ class AnkiNoteBuilder { } async getRenderingData({ - definition, + dictionaryEntry, mode, context, resultOutputMode='split', @@ -94,15 +94,15 @@ class AnkiNoteBuilder { injectedMedia=null, marker=null }) { - const commonData = this._createData(definition, mode, context, resultOutputMode, glossaryLayoutMode, compactTags, injectedMedia); + const commonData = this._createData(dictionaryEntry, mode, context, resultOutputMode, glossaryLayoutMode, compactTags, injectedMedia); return await this._templateRenderer.getModifiedData({marker, commonData}, 'ankiNote'); } // Private - _createData(definition, mode, context, resultOutputMode, glossaryLayoutMode, compactTags, injectedMedia) { + _createData(dictionaryEntry, mode, context, resultOutputMode, glossaryLayoutMode, compactTags, injectedMedia) { return { - definition, + dictionaryEntry, mode, context, resultOutputMode, diff --git a/ext/js/data/anki-note-data-creator.js b/ext/js/data/anki-note-data-creator.js index e7abaa21..1c32c4b4 100644 --- a/ext/js/data/anki-note-data-creator.js +++ b/ext/js/data/anki-note-data-creator.js @@ -38,7 +38,7 @@ class AnkiNoteDataCreator { * @returns An object used for rendering Anki templates. */ create(marker, { - definition: dictionaryEntry, + dictionaryEntry, resultOutputMode, mode, glossaryLayoutMode, diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js index 857ef630..42f9a38f 100644 --- a/ext/js/data/options-util.js +++ b/ext/js/data/options-util.js @@ -791,12 +791,20 @@ class OptionsUtil { _updateVersion11(options) { // Version 11 changes: // Changed dictionaries to an array. + // Changed audio.customSourceUrl's {expression} marker to {term}. + const customSourceUrlPattern = /\{expression\}/g; for (const profile of options.profiles) { const dictionariesNew = []; for (const [name, {priority, enabled, allowSecondarySearches, definitionsCollapsible}] of Object.entries(profile.options.dictionaries)) { dictionariesNew.push({name, priority, enabled, allowSecondarySearches, definitionsCollapsible}); } profile.options.dictionaries = dictionariesNew; + + let {customSourceUrl} = profile.options.audio; + if (typeof customSourceUrl === 'string') { + customSourceUrl = customSourceUrl.replace(customSourceUrlPattern, '{term}'); + } + profile.options.audio.customSourceUrl = customSourceUrl; } return options; } diff --git a/ext/js/display/display-audio.js b/ext/js/display/display-audio.js index 03966390..4a1f6305 100644 --- a/ext/js/display/display-audio.js +++ b/ext/js/display/display-audio.js @@ -58,12 +58,12 @@ class DisplayAudio { this._eventListeners.removeAllEventListeners(); } - setupEntry(entry, definitionIndex) { + setupEntry(entry, dictionaryEntryIndex) { for (const button of entry.querySelectorAll('.action-play-audio')) { - const expressionIndex = this._getAudioPlayButtonExpressionIndex(button); - this._eventListeners.addEventListener(button, 'click', this._onAudioPlayButtonClick.bind(this, definitionIndex, expressionIndex), false); - this._eventListeners.addEventListener(button, 'contextmenu', this._onAudioPlayButtonContextMenu.bind(this, definitionIndex, expressionIndex), false); - this._eventListeners.addEventListener(button, 'menuClose', this._onAudioPlayMenuCloseClick.bind(this, definitionIndex, expressionIndex), false); + const headwordIndex = this._getAudioPlayButtonHeadwordIndex(button); + this._eventListeners.addEventListener(button, 'click', this._onAudioPlayButtonClick.bind(this, dictionaryEntryIndex, headwordIndex), false); + this._eventListeners.addEventListener(button, 'contextmenu', this._onAudioPlayButtonContextMenu.bind(this, dictionaryEntryIndex, headwordIndex), false); + this._eventListeners.addEventListener(button, 'menuClose', this._onAudioPlayMenuCloseClick.bind(this, dictionaryEntryIndex, headwordIndex), false); } } @@ -73,11 +73,11 @@ class DisplayAudio { this.clearAutoPlayTimer(); - const definitions = this._display.definitions; - if (definitions.length === 0) { return; } + const {dictionaryEntries} = this._display; + if (dictionaryEntries.length === 0) { return; } - const firstDefinition = definitions[0]; - if (firstDefinition.type === 'kanji') { return; } + const firstDictionaryEntries = dictionaryEntries[0]; + if (firstDictionaryEntries.type === 'kanji') { return; } const callback = () => { this._autoPlayAudioTimer = null; @@ -103,18 +103,18 @@ class DisplayAudio { this._audioPlaying = null; } - async playAudio(definitionIndex, expressionIndex, sources=null, sourceDetailsMap=null) { + async playAudio(dictionaryEntryIndex, headwordIndex, sources=null, sourceDetailsMap=null) { this.stopAudio(); this.clearAutoPlayTimer(); - const expressionReading = this._getExpressionAndReading(definitionIndex, expressionIndex); - if (expressionReading === null) { + const headword = this._getHeadword(dictionaryEntryIndex, headwordIndex); + if (headword === null) { return {audio: null, source: null, valid: false}; } - const buttons = this._getAudioPlayButtons(definitionIndex, expressionIndex); + const buttons = this._getAudioPlayButtons(dictionaryEntryIndex, headwordIndex); - const {expression, reading} = expressionReading; + const {term, reading} = headword; const audioOptions = this._getAudioOptions(); const {textToSpeechVoice, customSourceUrl, customSourceType, volume} = audioOptions; if (!Array.isArray(sources)) { @@ -131,7 +131,7 @@ class DisplayAudio { let audio; let title; let source = null; - const info = await this._createExpressionAudio(sources, sourceDetailsMap, expression, reading, {textToSpeechVoice, customSourceUrl, customSourceType}); + const info = await this._createTermAudio(sources, sourceDetailsMap, term, reading, {textToSpeechVoice, customSourceUrl, customSourceType}); const valid = (info !== null); if (valid) { ({audio, source} = info); @@ -146,7 +146,7 @@ class DisplayAudio { this.stopAudio(); // Update details - const potentialAvailableAudioCount = this._getPotentialAvailableAudioCount(expression, reading); + const potentialAvailableAudioCount = this._getPotentialAvailableAudioCount(term, reading); for (const button of buttons) { const titleDefault = button.dataset.titleDefault || ''; button.title = `${titleDefault}\n${title}`; @@ -174,48 +174,48 @@ class DisplayAudio { } } - getPrimaryCardAudio(expression, reading) { - const cacheEntry = this._getCacheItem(expression, reading, false); + getPrimaryCardAudio(term, reading) { + const cacheEntry = this._getCacheItem(term, reading, false); const primaryCardAudio = typeof cacheEntry !== 'undefined' ? cacheEntry.primaryCardAudio : null; return primaryCardAudio; } // Private - _onAudioPlayButtonClick(definitionIndex, expressionIndex, e) { + _onAudioPlayButtonClick(dictionaryEntryIndex, headwordIndex, e) { e.preventDefault(); if (e.shiftKey) { - this._showAudioMenu(e.currentTarget, definitionIndex, expressionIndex); + this._showAudioMenu(e.currentTarget, dictionaryEntryIndex, headwordIndex); } else { - this.playAudio(definitionIndex, expressionIndex); + this.playAudio(dictionaryEntryIndex, headwordIndex); } } - _onAudioPlayButtonContextMenu(definitionIndex, expressionIndex, e) { + _onAudioPlayButtonContextMenu(dictionaryEntryIndex, headwordIndex, e) { e.preventDefault(); - this._showAudioMenu(e.currentTarget, definitionIndex, expressionIndex); + this._showAudioMenu(e.currentTarget, dictionaryEntryIndex, headwordIndex); } - _onAudioPlayMenuCloseClick(definitionIndex, expressionIndex, e) { + _onAudioPlayMenuCloseClick(dictionaryEntryIndex, headwordIndex, e) { const {detail: {action, item, menu, shiftKey}} = e; switch (action) { case 'playAudioFromSource': if (shiftKey) { e.preventDefault(); } - this._playAudioFromSource(definitionIndex, expressionIndex, item); + this._playAudioFromSource(dictionaryEntryIndex, headwordIndex, item); break; case 'setPrimaryAudio': e.preventDefault(); - this._setPrimaryAudio(definitionIndex, expressionIndex, item, menu, true); + this._setPrimaryAudio(dictionaryEntryIndex, headwordIndex, item, menu, true); break; } } - _getCacheItem(expression, reading, create) { - const key = this._getExpressionReadingKey(expression, reading); + _getCacheItem(term, reading, create) { + const key = this._getTermReadingKey(term, reading); let cacheEntry = this._cache.get(key); if (typeof cacheEntry === 'undefined' && create) { cacheEntry = { @@ -242,7 +242,7 @@ class DisplayAudio { return {source, index, hasIndex}; } - async _playAudioFromSource(definitionIndex, expressionIndex, item) { + async _playAudioFromSource(dictionaryEntryIndex, headwordIndex, item) { const sourceInfo = this._getMenuItemSourceInfo(item); if (sourceInfo === null) { return; } @@ -251,61 +251,61 @@ class DisplayAudio { try { const token = this._entriesToken; - const {valid} = await this.playAudio(definitionIndex, expressionIndex, [source], sourceDetailsMap); + const {valid} = await this.playAudio(dictionaryEntryIndex, headwordIndex, [source], sourceDetailsMap); if (valid && token === this._entriesToken) { - this._setPrimaryAudio(definitionIndex, expressionIndex, item, null, false); + this._setPrimaryAudio(dictionaryEntryIndex, headwordIndex, item, null, false); } } catch (e) { // NOP } } - _setPrimaryAudio(definitionIndex, expressionIndex, item, menu, canToggleOff) { + _setPrimaryAudio(dictionaryEntryIndex, headwordIndex, item, menu, canToggleOff) { const sourceInfo = this._getMenuItemSourceInfo(item); if (sourceInfo === null) { return; } const {source, index} = sourceInfo; if (!this._sourceIsDownloadable(source)) { return; } - const expressionReading = this._getExpressionAndReading(definitionIndex, expressionIndex); - if (expressionReading === null) { return; } + const headword = this._getHeadword(dictionaryEntryIndex, headwordIndex); + if (headword === null) { return; } - const {expression, reading} = expressionReading; - const cacheEntry = this._getCacheItem(expression, reading, true); + const {term, reading} = headword; + const cacheEntry = this._getCacheItem(term, reading, true); let {primaryCardAudio} = cacheEntry; primaryCardAudio = (!canToggleOff || primaryCardAudio === null || primaryCardAudio.source !== source || primaryCardAudio.index !== index) ? {source, index} : null; cacheEntry.primaryCardAudio = primaryCardAudio; if (menu !== null) { - this._updateMenuPrimaryCardAudio(menu.bodyNode, expression, reading); + this._updateMenuPrimaryCardAudio(menu.bodyNode, term, reading); } } - _getAudioPlayButtonExpressionIndex(button) { - const expressionNode = button.closest('.expression'); - if (expressionNode !== null) { - const expressionIndex = parseInt(expressionNode.dataset.index, 10); - if (Number.isFinite(expressionIndex)) { return expressionIndex; } + _getAudioPlayButtonHeadwordIndex(button) { + const headwordNode = button.closest('.expression'); + if (headwordNode !== null) { + const headwordIndex = parseInt(headwordNode.dataset.index, 10); + if (Number.isFinite(headwordIndex)) { return headwordIndex; } } return 0; } - _getAudioPlayButtons(definitionIndex, expressionIndex) { + _getAudioPlayButtons(dictionaryEntryIndex, headwordIndex) { const results = []; - const {definitionNodes} = this._display; - if (definitionIndex >= 0 && definitionIndex < definitionNodes.length) { - const node = definitionNodes[definitionIndex]; - const button1 = (expressionIndex === 0 ? node.querySelector('.action-play-audio') : null); - const button2 = node.querySelector(`.expression:nth-of-type(${expressionIndex + 1}) .action-play-audio`); + const {dictionaryEntryNodes} = this._display; + if (dictionaryEntryIndex >= 0 && dictionaryEntryIndex < dictionaryEntryNodes.length) { + const node = dictionaryEntryNodes[dictionaryEntryIndex]; + const button1 = (headwordIndex === 0 ? node.querySelector('.action-play-audio') : null); + const button2 = node.querySelector(`.expression:nth-of-type(${headwordIndex + 1}) .action-play-audio`); if (button1 !== null) { results.push(button1); } if (button2 !== null) { results.push(button2); } } return results; } - async _createExpressionAudio(sources, sourceDetailsMap, expression, reading, details) { - const {sourceMap} = this._getCacheItem(expression, reading, true); + async _createTermAudio(sources, sourceDetailsMap, term, reading, details) { + const {sourceMap} = this._getCacheItem(term, reading, true); for (let i = 0, ii = sources.length; i < ii; ++i) { const source = sources[i]; @@ -314,7 +314,7 @@ class DisplayAudio { let infoListPromise; let sourceInfo = sourceMap.get(source); if (typeof sourceInfo === 'undefined') { - infoListPromise = this._getExpressionAudioInfoList(source, expression, reading, details); + infoListPromise = this._getTermAudioInfoList(source, term, reading, details); sourceInfo = {infoListPromise, infoList: null}; sourceMap.set(source, sourceInfo); cacheUpdated = true; @@ -393,27 +393,26 @@ class DisplayAudio { } } - async _getExpressionAudioInfoList(source, expression, reading, details) { - const infoList = await yomichan.api.getExpressionAudioInfoList(source, expression, reading, details); + async _getTermAudioInfoList(source, term, reading, details) { + const infoList = await yomichan.api.getTermAudioInfoList(source, term, reading, details); return infoList.map((info) => ({info, audioPromise: null, audioResolved: false, audio: null})); } - _getExpressionAndReading(definitionIndex, expressionIndex) { - const {definitions} = this._display; - if (definitionIndex < 0 || definitionIndex >= definitions.length) { return null; } + _getHeadword(dictionaryEntryIndex, headwordIndex) { + const {dictionaryEntries} = this._display; + if (dictionaryEntryIndex < 0 || dictionaryEntryIndex >= dictionaryEntries.length) { return null; } - const definition = definitions[definitionIndex]; - if (definition.type === 'kanji') { return null; } + const dictionaryEntry = dictionaryEntries[dictionaryEntryIndex]; + if (dictionaryEntry.type === 'kanji') { return null; } - const {headwords} = definition; - if (expressionIndex < 0 || expressionIndex >= headwords.length) { return null; } + const {headwords} = dictionaryEntry; + if (headwordIndex < 0 || headwordIndex >= headwords.length) { return null; } - const {term, reading} = headwords[expressionIndex]; - return {expression: term, reading}; + return headwords[headwordIndex]; } - _getExpressionReadingKey(expression, reading) { - return JSON.stringify([expression, reading]); + _getTermReadingKey(term, reading) { + return JSON.stringify([term, reading]); } _getAudioOptions() { @@ -460,8 +459,8 @@ class DisplayAudio { } } - _getPotentialAvailableAudioCount(expression, reading) { - const cacheEntry = this._getCacheItem(expression, reading, false); + _getPotentialAvailableAudioCount(term, reading) { + const cacheEntry = this._getCacheItem(term, reading, false); if (typeof cacheEntry === 'undefined') { return null; } const {sourceMap} = cacheEntry; @@ -477,12 +476,12 @@ class DisplayAudio { return count; } - _showAudioMenu(button, definitionIndex, expressionIndex) { - const expressionReading = this._getExpressionAndReading(definitionIndex, expressionIndex); - if (expressionReading === null) { return; } + _showAudioMenu(button, dictionaryEntryIndex, headwordIndex) { + const headword = this._getHeadword(dictionaryEntryIndex, headwordIndex); + if (headword === null) { return; } - const {expression, reading} = expressionReading; - const popupMenu = this._createMenu(button, expression, reading); + const {term, reading} = headword; + const popupMenu = this._createMenu(button, term, reading); this._openMenus.add(popupMenu); popupMenu.prepare(); popupMenu.on('close', this._onPopupMenuClose.bind(this)); @@ -550,31 +549,31 @@ class DisplayAudio { return results; } - _createMenu(sourceButton, expression, reading) { + _createMenu(sourceButton, term, reading) { // Create menu const menuContainerNode = this._display.displayGenerator.instantiateTemplate('audio-button-popup-menu'); const menuBodyNode = menuContainerNode.querySelector('.popup-menu-body'); - menuContainerNode.dataset.expression = expression; + menuContainerNode.dataset.term = term; menuContainerNode.dataset.reading = reading; // Set up items based on options and cache data - this._createMenuItems(menuContainerNode, menuBodyNode, expression, reading); + this._createMenuItems(menuContainerNode, menuBodyNode, term, reading); // Update primary card audio display - this._updateMenuPrimaryCardAudio(menuBodyNode, expression, reading); + this._updateMenuPrimaryCardAudio(menuBodyNode, term, reading); // Create popup menu this._menuContainer.appendChild(menuContainerNode); return new PopupMenu(sourceButton, menuContainerNode); } - _createMenuItems(menuContainerNode, menuItemContainer, expression, reading) { + _createMenuItems(menuContainerNode, menuItemContainer, term, reading) { const sources = this._getAudioSources(this._getAudioOptions()); const {displayGenerator} = this._display; let showIcons = false; const currentItems = [...menuItemContainer.children]; for (const {source, displayName, isInOptions, downloadable} of sources) { - const entries = this._getMenuItemEntries(source, expression, reading); + const entries = this._getMenuItemEntries(source, term, reading); for (let i = 0, ii = entries.length; i < ii; ++i) { const {valid, index, name} = entries[i]; let node = this._getOrCreateMenuItem(currentItems, source, index); @@ -632,8 +631,8 @@ class DisplayAudio { return null; } - _getMenuItemEntries(source, expression, reading) { - const cacheEntry = this._getCacheItem(expression, reading, false); + _getMenuItemEntries(source, term, reading) { + const cacheEntry = this._getCacheItem(term, reading, false); if (typeof cacheEntry !== 'undefined') { const {sourceMap} = cacheEntry; const sourceInfo = sourceMap.get(source); @@ -659,8 +658,8 @@ class DisplayAudio { return [{valid: null, index: null, name: null}]; } - _updateMenuPrimaryCardAudio(menuBodyNode, expression, reading) { - const primaryCardAudio = this.getPrimaryCardAudio(expression, reading); + _updateMenuPrimaryCardAudio(menuBodyNode, term, reading) { + const primaryCardAudio = this.getPrimaryCardAudio(term, reading); const {source: primaryCardAudioSource, index: primaryCardAudioIndex} = (primaryCardAudio !== null ? primaryCardAudio : {source: null, index: -1}); const itemGroups = menuBodyNode.querySelectorAll('.popup-menu-item-group'); @@ -683,8 +682,8 @@ class DisplayAudio { _updateOpenMenu() { for (const menu of this._openMenus) { const menuContainerNode = menu.containerNode; - const {expression, reading} = menuContainerNode.dataset; - this._createMenuItems(menuContainerNode, menu.bodyNode, expression, reading); + const {term, reading} = menuContainerNode.dataset; + this._createMenuItems(menuContainerNode, menu.bodyNode, term, reading); menu.updatePosition(); } } diff --git a/ext/js/display/display-generator.js b/ext/js/display/display-generator.js index 724bec9c..32699ec7 100644 --- a/ext/js/display/display-generator.js +++ b/ext/js/display/display-generator.js @@ -50,56 +50,56 @@ class DisplayGenerator { document.head.appendChild(t); } - createTermEntry(details) { + createTermEntry(dictionaryEntry) { const node = this._templates.instantiate('term-entry'); - const expressionsContainer = node.querySelector('.expression-list'); - const reasonsContainer = node.querySelector('.inflection-list'); + const headwordsContainer = node.querySelector('.expression-list'); + const inflectionsContainer = node.querySelector('.inflection-list'); const pitchesContainer = node.querySelector('.pitch-accent-group-list'); const frequencyGroupListContainer = node.querySelector('.frequency-group-list'); const definitionsContainer = node.querySelector('.definition-list'); const termTagsContainer = node.querySelector('.expression-list-tag-list'); - const {headwords: expressions, type, inflections: reasons, definitions, frequencies, pronunciations} = details; - const pitches = DictionaryDataUtil.getPitchAccentInfos(details); + const {headwords, type, inflections, definitions, frequencies, pronunciations} = dictionaryEntry; + const pitches = DictionaryDataUtil.getPitchAccentInfos(dictionaryEntry); const pitchCount = pitches.reduce((i, v) => i + v.pitches.length, 0); - const groupedFrequencies = DictionaryDataUtil.groupTermFrequencies(details); - const termTags = DictionaryDataUtil.groupTermTags(details); + const groupedFrequencies = DictionaryDataUtil.groupTermFrequencies(dictionaryEntry); + const termTags = DictionaryDataUtil.groupTermTags(dictionaryEntry); - const uniqueExpressions = new Set(); + const uniqueTerms = new Set(); const uniqueReadings = new Set(); - for (const {term: expression, reading} of expressions) { - uniqueExpressions.add(expression); + for (const {term, reading} of headwords) { + uniqueTerms.add(term); uniqueReadings.add(reading); } node.dataset.format = type; - node.dataset.expressionCount = `${expressions.length}`; + node.dataset.expressionCount = `${headwords.length}`; node.dataset.definitionCount = `${definitions.length}`; node.dataset.pitchAccentDictionaryCount = `${pitches.length}`; node.dataset.pitchAccentCount = `${pitchCount}`; - node.dataset.uniqueExpressionCount = `${uniqueExpressions.size}`; + node.dataset.uniqueExpressionCount = `${uniqueTerms.size}`; node.dataset.uniqueReadingCount = `${uniqueReadings.size}`; node.dataset.frequencyCount = `${frequencies.length}`; node.dataset.groupedFrequencyCount = `${groupedFrequencies.length}`; - for (let i = 0, ii = expressions.length; i < ii; ++i) { - const node2 = this._createTermExpression(expressions[i], i, pronunciations); + for (let i = 0, ii = headwords.length; i < ii; ++i) { + const node2 = this._createTermHeadword(headwords[i], i, pronunciations); node2.dataset.index = `${i}`; - expressionsContainer.appendChild(node2); + headwordsContainer.appendChild(node2); } - expressionsContainer.dataset.count = `${expressions.length}`; + headwordsContainer.dataset.count = `${headwords.length}`; - this._appendMultiple(reasonsContainer, this._createTermReason.bind(this), reasons); + this._appendMultiple(inflectionsContainer, this._createTermInflection.bind(this), inflections); this._appendMultiple(frequencyGroupListContainer, this._createFrequencyGroup.bind(this), groupedFrequencies, false); this._appendMultiple(pitchesContainer, this._createPitches.bind(this), pitches); - this._appendMultiple(termTagsContainer, this._createTermTag.bind(this), termTags, expressions.length); + this._appendMultiple(termTagsContainer, this._createTermTag.bind(this), termTags, headwords.length); - for (const expression of uniqueExpressions) { - termTagsContainer.appendChild(this._createSearchTag(expression)); + for (const term of uniqueTerms) { + termTagsContainer.appendChild(this._createSearchTag(term)); } for (const reading of uniqueReadings) { - if (uniqueExpressions.has(reading)) { continue; } + if (uniqueTerms.has(reading)) { continue; } termTagsContainer.appendChild(this._createSearchTag(reading)); } @@ -117,7 +117,7 @@ class DisplayGenerator { dictionaryTag.name = dictionary; } - const node2 = this._createTermDefinitionItem(definition, dictionaryTag, expressions, uniqueExpressions, uniqueReadings); + const node2 = this._createTermDefinition(definition, dictionaryTag, headwords, uniqueTerms, uniqueReadings); node2.dataset.index = `${i}`; definitionsContainer.appendChild(node2); } @@ -126,13 +126,13 @@ class DisplayGenerator { return node; } - createKanjiEntry(details) { + createKanjiEntry(dictionaryEntry) { const node = this._templates.instantiate('kanji-entry'); const glyphContainer = node.querySelector('.kanji-glyph'); const frequencyGroupListContainer = node.querySelector('.frequency-group-list'); const tagContainer = node.querySelector('.kanji-tag-list'); - const glossaryContainer = node.querySelector('.kanji-glossary-list'); + const definitionsContainer = node.querySelector('.kanji-glossary-list'); const chineseReadingsContainer = node.querySelector('.kanji-readings-chinese'); const japaneseReadingsContainer = node.querySelector('.kanji-readings-japanese'); const statisticsContainer = node.querySelector('.kanji-statistics'); @@ -140,21 +140,21 @@ class DisplayGenerator { const codepointsContainer = node.querySelector('.kanji-codepoints'); const dictionaryIndicesContainer = node.querySelector('.kanji-dictionary-indices'); - this._setTextContent(glyphContainer, details.character, 'ja'); - const groupedFrequencies = DictionaryDataUtil.groupKanjiFrequencies(details.frequencies); + this._setTextContent(glyphContainer, dictionaryEntry.character, 'ja'); + const groupedFrequencies = DictionaryDataUtil.groupKanjiFrequencies(dictionaryEntry.frequencies); - const dictionaryTag = this._createDictionaryTag(details.dictionary); + const dictionaryTag = this._createDictionaryTag(dictionaryEntry.dictionary); this._appendMultiple(frequencyGroupListContainer, this._createFrequencyGroup.bind(this), groupedFrequencies, true); - this._appendMultiple(tagContainer, this._createTag.bind(this), [...details.tags, dictionaryTag]); - this._appendMultiple(glossaryContainer, this._createKanjiGlossaryItem.bind(this), details.definitions); - this._appendMultiple(chineseReadingsContainer, this._createKanjiReading.bind(this), details.onyomi); - this._appendMultiple(japaneseReadingsContainer, this._createKanjiReading.bind(this), details.kunyomi); + this._appendMultiple(tagContainer, this._createTag.bind(this), [...dictionaryEntry.tags, dictionaryTag]); + this._appendMultiple(definitionsContainer, this._createKanjiDefinition.bind(this), dictionaryEntry.definitions); + this._appendMultiple(chineseReadingsContainer, this._createKanjiReading.bind(this), dictionaryEntry.onyomi); + this._appendMultiple(japaneseReadingsContainer, this._createKanjiReading.bind(this), dictionaryEntry.kunyomi); - statisticsContainer.appendChild(this._createKanjiInfoTable(details.stats.misc)); - classificationsContainer.appendChild(this._createKanjiInfoTable(details.stats.class)); - codepointsContainer.appendChild(this._createKanjiInfoTable(details.stats.code)); - dictionaryIndicesContainer.appendChild(this._createKanjiInfoTable(details.stats.index)); + statisticsContainer.appendChild(this._createKanjiInfoTable(dictionaryEntry.stats.misc)); + classificationsContainer.appendChild(this._createKanjiInfoTable(dictionaryEntry.stats.class)); + codepointsContainer.appendChild(this._createKanjiInfoTable(dictionaryEntry.stats.code)); + dictionaryIndicesContainer.appendChild(this._createKanjiInfoTable(dictionaryEntry.stats.index)); return node; } @@ -235,20 +235,20 @@ class DisplayGenerator { // Private - _createTermExpression(headword, headwordIndex, pronunciations) { - const {term: expression, reading, tags: termTags} = headword; + _createTermHeadword(headword, headwordIndex, pronunciations) { + const {term, reading, tags} = headword; const searchQueries = []; - if (expression) { searchQueries.push(expression); } + if (term) { searchQueries.push(term); } if (reading) { searchQueries.push(reading); } const node = this._templates.instantiate('expression'); - const expressionContainer = node.querySelector('.expression-text'); + const termContainer = node.querySelector('.expression-text'); const tagContainer = node.querySelector('.expression-tag-list'); - node.dataset.readingIsSame = `${reading === expression}`; - node.dataset.frequency = DictionaryDataUtil.getTermFrequency(termTags); + node.dataset.readingIsSame = `${reading === term}`; + node.dataset.frequency = DictionaryDataUtil.getTermFrequency(tags); const {wordClasses} = headword; const pitchAccentCategories = this._getPitchAccentCategories(reading, pronunciations, wordClasses, headwordIndex); @@ -261,61 +261,61 @@ class DisplayGenerator { this._setTextContent(node.querySelector('.expression-reading'), reading); - this._appendFurigana(expressionContainer, expression, reading, this._appendKanjiLinks.bind(this)); - this._appendMultiple(tagContainer, this._createTag.bind(this), termTags); + this._appendFurigana(termContainer, term, reading, this._appendKanjiLinks.bind(this)); + this._appendMultiple(tagContainer, this._createTag.bind(this), tags); this._appendMultiple(tagContainer, this._createSearchTag.bind(this), searchQueries); return node; } - _createTermReason(reason) { + _createTermInflection(inflection) { const fragment = this._templates.instantiateFragment('inflection'); const node = fragment.querySelector('.inflection'); - this._setTextContent(node, reason); - node.dataset.reason = reason; + this._setTextContent(node, inflection); + node.dataset.reason = inflection; return fragment; } - _createTermDefinitionItem(details, dictionaryTag, headwords, uniqueTerms, uniqueReadings) { - const {dictionary, tags, headwordIndices, entries} = details; + _createTermDefinition(definition, dictionaryTag, headwords, uniqueTerms, uniqueReadings) { + const {dictionary, tags, headwordIndices, entries} = definition; const disambiguations = DictionaryDataUtil.getDisambiguations(headwords, headwordIndices, uniqueTerms, uniqueReadings); const node = this._templates.instantiate('definition-item'); const tagListContainer = node.querySelector('.definition-tag-list'); const onlyListContainer = node.querySelector('.definition-disambiguation-list'); - const glossaryContainer = node.querySelector('.glossary-list'); + const entriesContainer = node.querySelector('.glossary-list'); node.dataset.dictionary = dictionary; this._appendMultiple(tagListContainer, this._createTag.bind(this), [...tags, dictionaryTag]); this._appendMultiple(onlyListContainer, this._createTermDisambiguation.bind(this), disambiguations); - this._appendMultiple(glossaryContainer, this._createTermGlossaryItem.bind(this), entries, dictionary); + this._appendMultiple(entriesContainer, this._createTermDefinitionEntry.bind(this), entries, dictionary); return node; } - _createTermGlossaryItem(glossary, dictionary) { - if (typeof glossary === 'string') { - return this._createTermGlossaryItemText(glossary); - } else if (typeof glossary === 'object' && glossary !== null) { - switch (glossary.type) { + _createTermDefinitionEntry(entry, dictionary) { + if (typeof entry === 'string') { + return this._createTermDefinitionEntryText(entry); + } else if (typeof entry === 'object' && entry !== null) { + switch (entry.type) { case 'image': - return this._createTermGlossaryItemImage(glossary, dictionary); + return this._createTermDefinitionEntryImage(entry, dictionary); } } return null; } - _createTermGlossaryItemText(glossary) { + _createTermDefinitionEntryText(text) { const node = this._templates.instantiate('glossary-item'); const container = node.querySelector('.glossary'); - this._setMultilineTextContent(container, glossary); + this._setMultilineTextContent(container, text); return node; } - _createTermGlossaryItemImage(data, dictionary) { + _createTermDefinitionEntryImage(data, dictionary) { const {path, width, height, preferredWidth, preferredHeight, title, description, pixelated} = data; const usedWidth = ( @@ -391,10 +391,10 @@ class DisplayGenerator { return node; } - _createKanjiGlossaryItem(glossary) { + _createKanjiDefinition(text) { const node = this._templates.instantiate('kanji-glossary-item'); const container = node.querySelector('.kanji-glossary'); - this._setMultilineTextContent(container, glossary); + this._setMultilineTextContent(container, text); return node; } @@ -431,8 +431,8 @@ class DisplayGenerator { return this._templates.instantiate('kanji-info-table-empty'); } - _createTag(details) { - const {content, name, category, redundant} = details; + _createTag(tag) { + const {content, name, category, redundant} = tag; const node = this._templates.instantiate('tag'); const inner = node.querySelector('.tag-label-content'); @@ -448,8 +448,8 @@ class DisplayGenerator { return node; } - _createTermTag(details, totalHeadwordCount) { - const {tag, headwordIndices} = details; + _createTermTag(tagInfo, totalHeadwordCount) { + const {tag, headwordIndices} = tagInfo; const node = this._createTag(tag); node.dataset.headwords = headwordIndices.join(' '); node.dataset.totalExpressionCount = `${totalHeadwordCount}`; @@ -547,10 +547,10 @@ class DisplayGenerator { _createPitchAccentDisambiguations(container, exclusiveTerms, exclusiveReadings) { const templateName = 'pitch-accent-disambiguation'; - for (const exclusiveExpression of exclusiveTerms) { + for (const term of exclusiveTerms) { const node = this._templates.instantiate(templateName); node.dataset.type = 'expression'; - this._setTextContent(node, exclusiveExpression, 'ja'); + this._setTextContent(node, term, 'ja'); container.appendChild(node); } @@ -712,9 +712,9 @@ class DisplayGenerator { return count; } - _appendFurigana(container, expression, reading, addText) { + _appendFurigana(container, term, reading, addText) { container.lang = 'ja'; - const segments = this._japaneseUtil.distributeFurigana(expression, reading); + const segments = this._japaneseUtil.distributeFurigana(term, reading); for (const {text, furigana} of segments) { if (furigana) { const ruby = document.createElement('ruby'); diff --git a/ext/js/display/display.js b/ext/js/display/display.js index 0677611e..ab3ec7e1 100644 --- a/ext/js/display/display.js +++ b/ext/js/display/display.js @@ -47,8 +47,8 @@ class Display extends EventDispatcher { this._documentFocusController = documentFocusController; this._hotkeyHandler = hotkeyHandler; this._container = document.querySelector('#definitions'); - this._definitions = []; - this._definitionNodes = []; + this._dictionaryEntries = []; + this._dictionaryEntryNodes = []; this._optionsContext = {depth: 0, url: window.location.href}; this._options = null; this._index = 0; @@ -107,7 +107,7 @@ class Display extends EventDispatcher { this._frameEndpoint = (pageType === 'popup' ? new FrameEndpoint() : null); this._browser = null; this._copyTextarea = null; - this._definitionTextScanner = null; + this._contentTextScanner = null; this._tagNotification = null; this._footerNotificationContainer = document.querySelector('#content-footer'); this._displayAudio = new DisplayAudio(this); @@ -121,14 +121,14 @@ class Display extends EventDispatcher { ['close', () => { this._onHotkeyClose(); }], ['nextEntry', this._onHotkeyActionMoveRelative.bind(this, 1)], ['previousEntry', this._onHotkeyActionMoveRelative.bind(this, -1)], - ['lastEntry', () => { this._focusEntry(this._definitions.length - 1, true); }], + ['lastEntry', () => { this._focusEntry(this._dictionaryEntries.length - 1, true); }], ['firstEntry', () => { this._focusEntry(0, true); }], ['historyBackward', () => { this._sourceTermView(); }], ['historyForward', () => { this._nextTermView(); }], - ['addNoteKanji', () => { this._tryAddAnkiNoteForSelectedDefinition('kanji'); }], - ['addNoteTermKanji', () => { this._tryAddAnkiNoteForSelectedDefinition('term-kanji'); }], - ['addNoteTermKana', () => { this._tryAddAnkiNoteForSelectedDefinition('term-kana'); }], - ['viewNote', () => { this._tryViewAnkiNoteForSelectedDefinition(); }], + ['addNoteKanji', () => { this._tryAddAnkiNoteForSelectedEntry('kanji'); }], + ['addNoteTermKanji', () => { this._tryAddAnkiNoteForSelectedEntry('term-kanji'); }], + ['addNoteTermKana', () => { this._tryAddAnkiNoteForSelectedEntry('term-kana'); }], + ['viewNote', () => { this._tryViewAnkiNoteForSelectedEntry(); }], ['playAudio', () => { this._playAudioCurrent(); }], ['playAudioFromSource', this._onHotkeyActionPlayAudioFromSource.bind(this)], ['copyHostSelection', () => this._copyHostSelection()], @@ -181,12 +181,12 @@ class Display extends EventDispatcher { return this._hotkeyHandler; } - get definitions() { - return this._definitions; + get dictionaryEntries() { + return this._dictionaryEntries; } - get definitionNodes() { - return this._definitionNodes; + get dictionaryEntryNodes() { + return this._dictionaryEntryNodes; } get progressIndicatorVisible() { @@ -327,7 +327,7 @@ class Display extends EventDispatcher { }); this._updateNestedFrontend(options); - this._updateDefinitionTextScanner(options); + this._updateContentTextScanner(options); this.trigger('optionsUpdated', {options}); } @@ -434,7 +434,7 @@ class Display extends EventDispatcher { params: this._createSearchParams(type, query, false), state, content: { - definitions: null, + dictionaryEntries: null, contentOrigin: this.getContentOrigin() } }; @@ -536,8 +536,8 @@ class Display extends EventDispatcher { this._displayAudio.cleanupEntries(); this._hideTagNotification(false); this._hideAnkiNoteErrors(false); - this._definitions = []; - this._definitionNodes = []; + this._dictionaryEntries = []; + this._dictionaryEntryNodes = []; this._elementOverflowController.clearElements(); // Prepare @@ -606,7 +606,7 @@ class Display extends EventDispatcher { } } - _onQueryParserSearch({type, definitions, sentence, inputInfo: {eventType}, textSource, optionsContext}) { + _onQueryParserSearch({type, dictionaryEntries, sentence, inputInfo: {eventType}, textSource, optionsContext}) { const query = textSource.text(); const historyState = this._history.state; const history = ( @@ -624,7 +624,7 @@ class Display extends EventDispatcher { cause: 'queryParser' }, content: { - definitions, + dictionaryEntries, contentOrigin: this.getContentOrigin() } }; @@ -693,7 +693,7 @@ class Display extends EventDispatcher { if (typeof documentTitle !== 'string') { documentTitle = document.title; } const optionsContext = this.getOptionsContext(); const query = e.currentTarget.textContent; - const definitions = await yomichan.api.kanjiFind(query, optionsContext); + const dictionaryEntries = await yomichan.api.kanjiFind(query, optionsContext); const details = { focus: false, history: true, @@ -706,7 +706,7 @@ class Display extends EventDispatcher { documentTitle }, content: { - definitions, + dictionaryEntries, contentOrigin: this.getContentOrigin() } }; @@ -719,7 +719,7 @@ class Display extends EventDispatcher { _onNoteAdd(e) { e.preventDefault(); const link = e.currentTarget; - const index = this._getClosestDefinitionIndex(link); + const index = this._getClosestDictionaryEntryIndex(link); this._addAnkiNote(index, link.dataset.mode); } @@ -756,8 +756,8 @@ class Display extends EventDispatcher { _onDebugLogClick(e) { const link = e.currentTarget; - const index = this._getClosestDefinitionIndex(link); - this._logDefinitionData(index); + const index = this._getClosestDictionaryEntryIndex(link); + this._logDictionaryEntryData(index); } _onDocumentElementMouseUp(e) { @@ -814,8 +814,8 @@ class Display extends EventDispatcher { this._tagNotification = new DisplayNotification(this._footerNotificationContainer, node); } - const index = this._getClosestDefinitionIndex(tagNode); - const dictionaryEntry = (index >= 0 && index < this._definitions.length ? this._definitions[index] : null); + const index = this._getClosestDictionaryEntryIndex(tagNode); + const dictionaryEntry = (index >= 0 && index < this._dictionaryEntries.length ? this._dictionaryEntries[index] : null); const content = this._displayGenerator.createTagFooterNotificationDetails(tagNode, dictionaryEntry); this._tagNotification.setContent(content); @@ -850,7 +850,7 @@ class Display extends EventDispatcher { document.documentElement.dataset.theme = themeName; } - async _findDefinitions(isTerms, source, wildcardsEnabled, optionsContext) { + async _findDictionaryEntries(isTerms, source, wildcardsEnabled, optionsContext) { if (isTerms) { const findDetails = {}; if (wildcardsEnabled) { @@ -865,11 +865,11 @@ class Display extends EventDispatcher { } } - const {definitions} = await yomichan.api.termsFind(source, findDetails, optionsContext); - return definitions; + const {dictionaryEntries} = await yomichan.api.termsFind(source, findDetails, optionsContext); + return dictionaryEntries; } else { - const definitions = await yomichan.api.kanjiFind(source, optionsContext); - return definitions; + const dictionaryEntries = await yomichan.api.kanjiFind(source, optionsContext); + return dictionaryEntries; } } @@ -901,11 +901,11 @@ class Display extends EventDispatcher { this._setFullQuery(queryFull); this._setTitleText(query); - let {definitions} = content; - if (!Array.isArray(definitions)) { - definitions = lookup && query.length > 0 ? await this._findDefinitions(isTerms, query, wildcardsEnabled, optionsContext) : []; + let {dictionaryEntries} = content; + if (!Array.isArray(dictionaryEntries)) { + dictionaryEntries = lookup && query.length > 0 ? await this._findDictionaryEntries(isTerms, query, wildcardsEnabled, optionsContext) : []; if (this._setContentToken !== token) { return; } - content.definitions = definitions; + content.dictionaryEntries = dictionaryEntries; changeHistory = true; } @@ -940,28 +940,28 @@ class Display extends EventDispatcher { eventArgs.content = content; this.trigger('contentUpdating', eventArgs); - this._definitions = definitions; + this._dictionaryEntries = dictionaryEntries; this._updateNavigation(this._history.hasPrevious(), this._history.hasNext()); - this._setNoContentVisible(definitions.length === 0 && lookup); + this._setNoContentVisible(dictionaryEntries.length === 0 && lookup); const container = this._container; container.textContent = ''; - for (let i = 0, ii = definitions.length; i < ii; ++i) { + for (let i = 0, ii = dictionaryEntries.length; i < ii; ++i) { if (i > 0) { await promiseTimeout(1); if (this._setContentToken !== token) { return; } } - const definition = definitions[i]; + const dictionaryEntry = dictionaryEntries[i]; const entry = ( isTerms ? - this._displayGenerator.createTermEntry(definition) : - this._displayGenerator.createKanjiEntry(definition) + this._displayGenerator.createTermEntry(dictionaryEntry) : + this._displayGenerator.createKanjiEntry(dictionaryEntry) ); entry.dataset.index = `${i}`; - this._definitionNodes.push(entry); + this._dictionaryEntryNodes.push(entry); this._addEntryEventListeners(entry); this._displayAudio.setupEntry(entry, i); container.appendChild(entry); @@ -982,7 +982,7 @@ class Display extends EventDispatcher { this._displayAudio.setupEntriesComplete(); - this._updateAdderButtons(token, isTerms, definitions); + this._updateAdderButtons(token, isTerms, dictionaryEntries); } _setContentExtensionUnloaded() { @@ -1069,7 +1069,7 @@ class Display extends EventDispatcher { } } - async _updateAdderButtons(token, isTerms, definitions) { + async _updateAdderButtons(token, isTerms, dictionaryEntries) { await this._updateAdderButtonsPromise; if (this._setContentToken !== token) { return; } @@ -1082,7 +1082,7 @@ class Display extends EventDispatcher { try { const noteContext = this._getNoteContext(); const {checkForDuplicates} = this._options.anki; - states = await this._areDefinitionsAddable(definitions, modes, noteContext, checkForDuplicates ? null : true); + states = await this._areDictionaryEntriesAddable(dictionaryEntries, modes, noteContext, checkForDuplicates ? null : true); } catch (e) { return; } @@ -1136,7 +1136,7 @@ class Display extends EventDispatcher { } _focusEntry(index, smooth) { - index = Math.max(Math.min(index, this._definitions.length - 1), 0); + index = Math.max(Math.min(index, this._dictionaryEntries.length - 1), 0); const entry = this._entrySetCurrent(index); let target = index === 0 || entry === null ? 0 : this._getElementTop(entry); @@ -1158,12 +1158,12 @@ class Display extends EventDispatcher { if (offsetSign === 0) { return false; } let index = this._index; - const definitionCount = this._definitions.length; - if (index < 0 || index >= definitionCount) { return false; } + const dictionaryEntryCount = this._dictionaryEntries.length; + if (index < 0 || index >= dictionaryEntryCount) { return false; } - const {dictionary} = this._definitions[index]; - for (let indexNext = index + offsetSign; indexNext >= 0 && indexNext < definitionCount; indexNext += offsetSign) { - const {dictionaryNames} = this._definitions[indexNext]; + const {dictionary} = this._dictionaryEntries[index]; + for (let indexNext = index + offsetSign; indexNext >= 0 && indexNext < dictionaryEntryCount; indexNext += offsetSign) { + const {dictionaryNames} = this._dictionaryEntries[indexNext]; if (dictionaryNames.length > 1 || !dictionaryNames.includes(dictionary)) { offset -= offsetSign; if (Math.sign(offsetSign) !== offset) { @@ -1195,22 +1195,22 @@ class Display extends EventDispatcher { } } - _tryAddAnkiNoteForSelectedDefinition(mode) { + _tryAddAnkiNoteForSelectedEntry(mode) { this._addAnkiNote(this._index, mode); } - _tryViewAnkiNoteForSelectedDefinition() { + _tryViewAnkiNoteForSelectedEntry() { const button = this._viewerButtonFind(this._index); if (button !== null && !button.disabled) { yomichan.api.noteView(button.dataset.noteId); } } - async _addAnkiNote(definitionIndex, mode) { - if (definitionIndex < 0 || definitionIndex >= this._definitions.length) { return; } - const definition = this._definitions[definitionIndex]; + async _addAnkiNote(dictionaryEntryIndex, mode) { + if (dictionaryEntryIndex < 0 || dictionaryEntryIndex >= this._dictionaryEntries.length) { return; } + const dictionaryEntry = this._dictionaryEntries[dictionaryEntryIndex]; - const button = this._adderButtonFind(definitionIndex, mode); + const button = this._adderButtonFind(dictionaryEntryIndex, mode); if (button === null || button.disabled) { return; } this._hideAnkiNoteErrors(true); @@ -1220,7 +1220,7 @@ class Display extends EventDispatcher { try { const {anki: {suspendNewCards}} = this._options; const noteContext = this._getNoteContext(); - const note = await this._createNote(definition, mode, noteContext, true, errors); + const note = await this._createNote(dictionaryEntry, mode, noteContext, true, errors); let noteId = null; let addNoteOkay = false; @@ -1244,7 +1244,7 @@ class Display extends EventDispatcher { } } button.disabled = true; - this._viewerButtonShow(definitionIndex, noteId); + this._viewerButtonShow(dictionaryEntryIndex, noteId); } } } catch (e) { @@ -1293,7 +1293,7 @@ class Display extends EventDispatcher { } _getEntry(index) { - const entries = this._definitionNodes; + const entries = this._dictionaryEntryNodes; return index >= 0 && index < entries.length ? entries[index] : null; } @@ -1304,7 +1304,7 @@ class Display extends EventDispatcher { return {text, offset}; } - _getClosestDefinitionIndex(element) { + _getClosestDictionaryEntryIndex(element) { return this._getClosestIndex(element, '.entry'); } @@ -1424,12 +1424,12 @@ class Display extends EventDispatcher { return templates; } - async _areDefinitionsAddable(definitions, modes, context, forceCanAddValue) { + async _areDictionaryEntriesAddable(dictionaryEntries, modes, context, forceCanAddValue) { const modeCount = modes.length; const notePromises = []; - for (const definition of definitions) { + for (const dictionaryEntry of dictionaryEntries) { for (const mode of modes) { - const notePromise = this._createNote(definition, mode, context, false, null); + const notePromise = this._createNote(dictionaryEntry, mode, context, false, null); notePromises.push(notePromise); } } @@ -1461,7 +1461,7 @@ class Display extends EventDispatcher { return results; } - async _createNote(definition, mode, context, injectMedia, errors) { + async _createNote(dictionaryEntry, mode, context, injectMedia, errors) { const options = this._options; const template = this._ankiFieldTemplates; const { @@ -1476,7 +1476,7 @@ class Display extends EventDispatcher { let injectedMedia = null; if (injectMedia) { let errors2; - ({result: injectedMedia, errors: errors2} = await this._injectAnkiNoteMedia(definition, options, fields)); + ({result: injectedMedia, errors: errors2} = await this._injectAnkiNoteMedia(dictionaryEntry, options, fields)); if (Array.isArray(errors)) { for (const error of errors2) { errors.push(deserializeError(error)); @@ -1485,7 +1485,7 @@ class Display extends EventDispatcher { } return await this._ankiNoteBuilder.createNote({ - definition, + dictionaryEntry, mode, context, template, @@ -1503,7 +1503,7 @@ class Display extends EventDispatcher { }); } - async _injectAnkiNoteMedia(definition, options, fields) { + async _injectAnkiNoteMedia(dictionaryEntry, options, fields) { const { anki: {screenshot: {format, quality}}, audio: {sources, customSourceUrl, customSourceType} @@ -1511,11 +1511,11 @@ class Display extends EventDispatcher { const timestamp = Date.now(); - const definitionDetails = this._getDefinitionDetailsForNote(definition); + const dictionaryEntryDetails = this._getDictionaryEntryDetailsForNote(dictionaryEntry); let audioDetails = null; - if (definitionDetails.type !== 'kanji' && AnkiUtil.fieldsObjectContainsMarker(fields, 'audio')) { - const primaryCardAudio = this._displayAudio.getPrimaryCardAudio(definitionDetails.term, definitionDetails.reading); + if (dictionaryEntryDetails.type !== 'kanji' && AnkiUtil.fieldsObjectContainsMarker(fields, 'audio')) { + const primaryCardAudio = this._displayAudio.getPrimaryCardAudio(dictionaryEntryDetails.term, dictionaryEntryDetails.reading); let preferredAudioIndex = null; let sources2 = sources; if (primaryCardAudio !== null) { @@ -1534,14 +1534,14 @@ class Display extends EventDispatcher { return await yomichan.api.injectAnkiNoteMedia( timestamp, - definitionDetails, + dictionaryEntryDetails, audioDetails, screenshotDetails, clipboardDetails ); } - _getDefinitionDetailsForNote(dictionaryEntry) { + _getDictionaryEntryDetailsForNote(dictionaryEntry) { const {type} = dictionaryEntry; if (type === 'kanji') { const {character} = dictionaryEntry; @@ -1710,16 +1710,16 @@ class Display extends EventDispatcher { this._addMultipleEventListeners(entry, '.tag-label', 'click', this._onTagClick.bind(this)); } - _updateDefinitionTextScanner(options) { + _updateContentTextScanner(options) { if (!options.scanning.enablePopupSearch) { - if (this._definitionTextScanner !== null) { - this._definitionTextScanner.setEnabled(false); + if (this._contentTextScanner !== null) { + this._contentTextScanner.setEnabled(false); } return; } - if (this._definitionTextScanner === null) { - this._definitionTextScanner = new TextScanner({ + if (this._contentTextScanner === null) { + this._contentTextScanner = new TextScanner({ node: window, getSearchContext: this._getSearchContext.bind(this), documentUtil: this._documentUtil, @@ -1728,14 +1728,14 @@ class Display extends EventDispatcher { searchOnClick: true, searchOnClickOnly: true }); - this._definitionTextScanner.includeSelector = '.click-scannable,.click-scannable *'; - this._definitionTextScanner.excludeSelector = '.scan-disable,.scan-disable *'; - this._definitionTextScanner.prepare(); - this._definitionTextScanner.on('searched', this._onDefinitionTextScannerSearched.bind(this)); + this._contentTextScanner.includeSelector = '.click-scannable,.click-scannable *'; + this._contentTextScanner.excludeSelector = '.scan-disable,.scan-disable *'; + this._contentTextScanner.prepare(); + this._contentTextScanner.on('searched', this._onContentTextScannerSearched.bind(this)); } const {scanning: scanningOptions, sentenceParsing: sentenceParsingOptions} = options; - this._definitionTextScanner.setOptions({ + this._contentTextScanner.setOptions({ inputs: [{ include: 'mouse0', exclude: '', @@ -1761,10 +1761,10 @@ class Display extends EventDispatcher { sentenceParsingOptions }); - this._definitionTextScanner.setEnabled(true); + this._contentTextScanner.setEnabled(true); } - _onDefinitionTextScannerSearched({type, definitions, sentence, textSource, optionsContext, error}) { + _onContentTextScannerSearched({type, dictionaryEntries, sentence, textSource, optionsContext, error}) { if (error !== null && !yomichan.isExtensionUnloaded) { log.error(error); } @@ -1790,11 +1790,11 @@ class Display extends EventDispatcher { documentTitle }, content: { - definitions, + dictionaryEntries, contentOrigin: this.getContentOrigin() } }; - this._definitionTextScanner.clearSelection(true); + this._contentTextScanner.clearSelection(true); this.setContent(details); } @@ -1865,16 +1865,16 @@ class Display extends EventDispatcher { return typeof queryPostProcessor === 'function' ? queryPostProcessor(query) : query; } - async _logDefinitionData(index) { - if (index < 0 || index >= this._definitions.length) { return; } - const dictionaryEntry = this._definitions[index]; + async _logDictionaryEntryData(index) { + if (index < 0 || index >= this._dictionaryEntries.length) { return; } + const dictionaryEntry = this._dictionaryEntries[index]; let ankiNoteData; let ankiNoteDataException; try { const context = this._getNoteContext(); const {general: {resultOutputMode, glossaryLayoutMode, compactTags}} = this._options; ankiNoteData = await this._ankiNoteBuilder.getRenderingData({ - definition: dictionaryEntry, + dictionaryEntry, mode: 'test', context, resultOutputMode, diff --git a/ext/js/display/search-display-controller.js b/ext/js/display/search-display-controller.js index 459d2257..f672909e 100644 --- a/ext/js/display/search-display-controller.js +++ b/ext/js/display/search-display-controller.js @@ -361,7 +361,7 @@ class SearchDisplayController { documentTitle }, content: { - definitions: null, + dictionaryEntries: null, animate, contentOrigin: { tabId: this.tabId, diff --git a/ext/js/language/dictionary-data-util.js b/ext/js/language/dictionary-data-util.js index 3f096b02..0a3be234 100644 --- a/ext/js/language/dictionary-data-util.js +++ b/ext/js/language/dictionary-data-util.js @@ -93,10 +93,10 @@ class DictionaryDataUtil { static getPitchAccentInfos(dictionaryEntry) { const {headwords, pronunciations} = dictionaryEntry; - const allExpressions = new Set(); + const allTerms = new Set(); const allReadings = new Set(); for (const {term, reading} of headwords) { - allExpressions.add(term); + allTerms.add(term); allReadings.add(reading); } @@ -129,8 +129,8 @@ class DictionaryDataUtil { for (const dictionaryPitchAccentInfoList of pitchAccentInfoMap.values()) { for (const pitchAccentInfo of dictionaryPitchAccentInfoList) { const {terms, reading, exclusiveTerms, exclusiveReadings} = pitchAccentInfo; - if (!this._areSetsEqual(terms, allExpressions)) { - exclusiveTerms.push(...this._getSetIntersection(terms, allExpressions)); + if (!this._areSetsEqual(terms, allTerms)) { + exclusiveTerms.push(...this._getSetIntersection(terms, allTerms)); } if (multipleReadings) { exclusiveReadings.push(reading); diff --git a/ext/js/language/dictionary-database.js b/ext/js/language/dictionary-database.js index fc4336c5..98f56986 100644 --- a/ext/js/language/dictionary-database.js +++ b/ext/js/language/dictionary-database.js @@ -26,7 +26,7 @@ class DictionaryDatabase { this._schemas = new Map(); this._createOnlyQuery1 = (item) => IDBKeyRange.only(item); this._createOnlyQuery2 = (item) => IDBKeyRange.only(item.query); - this._createOnlyQuery3 = (item) => IDBKeyRange.only(item.expression); + this._createOnlyQuery3 = (item) => IDBKeyRange.only(item.term); this._createOnlyQuery4 = (item) => IDBKeyRange.only(item.path); this._createBoundQuery1 = (item) => IDBKeyRange.bound(item, `${item}\uffff`, false, false); this._createBoundQuery2 = (item) => { item = stringReverse(item); return IDBKeyRange.bound(item, `${item}\uffff`, false, false); }; @@ -387,7 +387,7 @@ class DictionaryDatabase { _createTerm(row, index) { return { index, - expression: row.expression, + term: row.expression, reading: row.reading, definitionTags: this._splitField(row.definitionTags || row.tags || ''), termTags: this._splitField(row.termTags || ''), @@ -413,8 +413,8 @@ class DictionaryDatabase { }; } - _createTermMeta({expression, mode, data, dictionary}, index) { - return {expression, mode, data, dictionary, index}; + _createTermMeta({expression: term, mode, data, dictionary}, index) { + return {term, mode, data, dictionary, index}; } _createKanjiMeta({character, mode, data, dictionary}, index) { diff --git a/ext/js/language/japanese-util.js b/ext/js/language/japanese-util.js index cade393b..4d5e8092 100644 --- a/ext/js/language/japanese-util.js +++ b/ext/js/language/japanese-util.js @@ -315,7 +315,7 @@ const JapaneseUtil = (() => { return wanakana.toRomaji(text); } - convertReading(expression, reading, readingMode) { + convertReading(term, reading, readingMode) { switch (readingMode) { case 'hiragana': return this.convertKatakanaToHiragana(reading); @@ -325,8 +325,8 @@ const JapaneseUtil = (() => { if (reading) { return this.convertToRomaji(reading); } else { - if (this.isStringEntirelyKana(expression)) { - return this.convertToRomaji(expression); + if (this.isStringEntirelyKana(term)) { + return this.convertToRomaji(term); } } return reading; @@ -429,16 +429,16 @@ const JapaneseUtil = (() => { // Furigana distribution - distributeFurigana(expression, reading) { - if (reading === expression) { + distributeFurigana(term, reading) { + if (reading === term) { // Same - return [this._createFuriganaSegment(expression, '')]; + return [this._createFuriganaSegment(term, '')]; } const groups = []; let groupPre = null; let isKanaPre = null; - for (const c of expression) { + for (const c of term) { const codePoint = c.codePointAt(0); const isKana = !(this.isCodePointKanji(codePoint) || codePoint === ITERATION_MARK_CODE_POINT); if (isKana === isKanaPre) { @@ -462,18 +462,18 @@ const JapaneseUtil = (() => { } // Fallback - return [this._createFuriganaSegment(expression, reading)]; + return [this._createFuriganaSegment(term, reading)]; } - distributeFuriganaInflected(expression, reading, source) { - const expressionNormalized = this.convertKatakanaToHiragana(expression); + distributeFuriganaInflected(term, reading, source) { + const termNormalized = this.convertKatakanaToHiragana(term); const readingNormalized = this.convertKatakanaToHiragana(reading); const sourceNormalized = this.convertKatakanaToHiragana(source); - let mainText = expression; - let stemLength = this._getStemLength(expressionNormalized, sourceNormalized); + let mainText = term; + let stemLength = this._getStemLength(termNormalized, sourceNormalized); - // Check if source is derived from the reading instead of the expression + // Check if source is derived from the reading instead of the term const readingStemLength = this._getStemLength(readingNormalized, sourceNormalized); if (readingStemLength > 0 && readingStemLength >= stemLength) { mainText = reading; diff --git a/ext/js/language/text-scanner.js b/ext/js/language/text-scanner.js index 4dbd782b..b571435b 100644 --- a/ext/js/language/text-scanner.js +++ b/ext/js/language/text-scanner.js @@ -304,7 +304,7 @@ class TextScanner extends EventDispatcher { } async _search(textSource, searchTerms, searchKanji, inputInfo) { - let definitions = null; + let dictionaryEntries = null; let sentence = null; let type = null; let error = null; @@ -322,13 +322,13 @@ class TextScanner extends EventDispatcher { searched = true; - const result = await this._findDefinitions(textSource, searchTerms, searchKanji, optionsContext); + const result = await this._findDictionaryEntries(textSource, searchTerms, searchKanji, optionsContext); if (result !== null) { - ({definitions, sentence, type} = result); + ({dictionaryEntries, sentence, type} = result); this._inputInfoCurrent = inputInfo; this.setCurrentTextSource(textSource); } else if (textSource instanceof TextSourceElement && await this._hasJapanese(textSource.fullContent)) { - definitions = []; + dictionaryEntries = []; sentence = {sentence: '', offset: 0}; type = 'terms'; this._inputInfoCurrent = inputInfo; @@ -343,7 +343,7 @@ class TextScanner extends EventDispatcher { const results = { textScanner: this, type, - definitions, + dictionaryEntries, sentence, inputInfo, textSource, @@ -804,22 +804,22 @@ class TextScanner extends EventDispatcher { return null; } - async _findDefinitions(textSource, searchTerms, searchKanji, optionsContext) { + async _findDictionaryEntries(textSource, searchTerms, searchKanji, optionsContext) { if (textSource === null) { return null; } if (searchTerms) { - const results = await this._findTerms(textSource, optionsContext); + const results = await this._findTermDictionaryEntries(textSource, optionsContext); if (results !== null) { return results; } } if (searchKanji) { - const results = await this._findKanji(textSource, optionsContext); + const results = await this._findKanjiDictionaryEntries(textSource, optionsContext); if (results !== null) { return results; } } return null; } - async _findTerms(textSource, optionsContext) { + async _findTermDictionaryEntries(textSource, optionsContext) { const scanLength = this._scanLength; const sentenceScanExtent = this._sentenceScanExtent; const sentenceTerminatorMap = this._sentenceTerminatorMap; @@ -829,10 +829,10 @@ class TextScanner extends EventDispatcher { const searchText = this.getTextSourceContent(textSource, scanLength, layoutAwareScan); if (searchText.length === 0) { return null; } - const {definitions, length} = await yomichan.api.termsFind(searchText, {}, optionsContext); - if (definitions.length === 0) { return null; } + const {dictionaryEntries, originalTextLength} = await yomichan.api.termsFind(searchText, {}, optionsContext); + if (dictionaryEntries.length === 0) { return null; } - textSource.setEndOffset(length, layoutAwareScan); + textSource.setEndOffset(originalTextLength, layoutAwareScan); const sentence = this._documentUtil.extractSentence( textSource, layoutAwareScan, @@ -842,10 +842,10 @@ class TextScanner extends EventDispatcher { sentenceBackwardQuoteMap ); - return {definitions, sentence, type: 'terms'}; + return {dictionaryEntries, sentence, type: 'terms'}; } - async _findKanji(textSource, optionsContext) { + async _findKanjiDictionaryEntries(textSource, optionsContext) { const sentenceScanExtent = this._sentenceScanExtent; const sentenceTerminatorMap = this._sentenceTerminatorMap; const sentenceForwardQuoteMap = this._sentenceForwardQuoteMap; @@ -854,8 +854,8 @@ class TextScanner extends EventDispatcher { const searchText = this.getTextSourceContent(textSource, 1, layoutAwareScan); if (searchText.length === 0) { return null; } - const definitions = await yomichan.api.kanjiFind(searchText, optionsContext); - if (definitions.length === 0) { return null; } + const dictionaryEntries = await yomichan.api.kanjiFind(searchText, optionsContext); + if (dictionaryEntries.length === 0) { return null; } textSource.setEndOffset(1, layoutAwareScan); const sentence = this._documentUtil.extractSentence( @@ -867,7 +867,7 @@ class TextScanner extends EventDispatcher { sentenceBackwardQuoteMap ); - return {definitions, sentence, type: 'kanji'}; + return {dictionaryEntries, sentence, type: 'kanji'}; } async _searchAt(x, y, inputInfo) { diff --git a/ext/js/language/translator.js b/ext/js/language/translator.js index e066d62e..68a55cf9 100644 --- a/ext/js/language/translator.js +++ b/ext/js/language/translator.js @@ -27,6 +27,7 @@ class Translator { /** * Creates a new Translator instance. + * @param japaneseUtil An instance of JapaneseUtil. * @param database An instance of DictionaryDatabase. */ constructor({japaneseUtil, database}) { @@ -396,8 +397,8 @@ class Translator { const {id} = databaseEntry; if (ids.has(id)) { continue; } - const sourceText = databaseEntry.expression; - const dictionaryEntry = this._createTermDictionaryEntryFromDatabaseEntry(databaseEntry, sourceText, sourceText, sourceText, [], false, enabledDictionaryMap); + const {term} = databaseEntry; + const dictionaryEntry = this._createTermDictionaryEntryFromDatabaseEntry(databaseEntry, term, term, term, [], false, enabledDictionaryMap); dictionaryEntries.push(dictionaryEntry); ids.add(id); ungroupedDictionaryEntriesMap.delete(id); @@ -426,13 +427,13 @@ class Translator { target.groups.push(group); if (!dictionaryEntry.isPrimary && !target.searchSecondary) { target.searchSecondary = true; - termList.push({expression: term, reading}); + termList.push({term, reading}); targetList.push(target); } } } - // Group unsequenced dictionary entries with sequenced entries that have a matching [expression, reading]. + // Group unsequenced dictionary entries with sequenced entries that have a matching [term, reading]. for (const [id, dictionaryEntry] of ungroupedDictionaryEntriesMap.entries()) { const {term, reading} = dictionaryEntry.headwords[0]; const key = this._createMapKey([term, reading]); @@ -457,7 +458,7 @@ class Translator { for (const databaseEntry of databaseEntries) { const {index, id} = databaseEntry; - const sourceText = termList[index].expression; + const sourceText = termList[index].term; const target = targetList[index]; for (const {ids, dictionaryEntries} of target.groups) { if (ids.has(id)) { continue; } @@ -959,10 +960,10 @@ class Translator { } _createTermDictionaryEntryFromDatabaseEntry(databaseEntry, originalText, transformedText, deinflectedText, reasons, isPrimary, enabledDictionaryMap) { - const {expression, reading: rawReading, definitionTags, termTags, glossary, score, dictionary, id, sequence, rules} = databaseEntry; - const reading = (rawReading.length > 0 ? rawReading : expression); + const {term, reading: rawReading, definitionTags, termTags, glossary, score, dictionary, id, sequence, rules} = databaseEntry; + const reading = (rawReading.length > 0 ? rawReading : term); const {index: dictionaryIndex, priority: dictionaryPriority} = this._getDictionaryOrder(dictionary, enabledDictionaryMap); - const sourceTermExactMatchCount = (isPrimary && deinflectedText === expression ? 1 : 0); + const sourceTermExactMatchCount = (isPrimary && deinflectedText === term ? 1 : 0); const source = this._createSource(originalText, transformedText, deinflectedText, isPrimary); const maxTransformedTextLength = transformedText.length; @@ -982,7 +983,7 @@ class Translator { dictionaryPriority, sourceTermExactMatchCount, maxTransformedTextLength, - [this._createTermHeadword(0, expression, reading, [source], headwordTagGroups, rules)], + [this._createTermHeadword(0, term, reading, [source], headwordTagGroups, rules)], [this._createTermDefinition(0, [0], dictionary, definitionTagGroups, glossary)] ); } @@ -1204,7 +1205,7 @@ class Translator { i = v2.score - v1.score; if (i !== 0) { return i; } - // Sort by expression text + // Sort by headword term text const headwords1 = v1.headwords; const headwords2 = v2.headwords; for (let j = 0, jj = Math.min(headwords1.length, headwords2.length); j < jj; ++j) { @@ -1277,7 +1278,7 @@ class Translator { let i = v2.dictionaryPriority - v1.dictionaryPriority; if (i !== 0) { return i; } - // Sory by expression order + // Sory by headword order i = v1.headwordIndex - v2.headwordIndex; if (i !== 0) { return i; } diff --git a/ext/js/media/audio-downloader.js b/ext/js/media/audio-downloader.js index 8fd6d3f5..47cdaf13 100644 --- a/ext/js/media/audio-downloader.js +++ b/ext/js/media/audio-downloader.js @@ -37,11 +37,11 @@ class AudioDownloader { ]); } - async getExpressionAudioInfoList(source, expression, reading, details) { + async getTermAudioInfoList(source, term, reading, details) { const handler = this._getInfoHandlers.get(source); if (typeof handler === 'function') { try { - return await handler(expression, reading, details); + return await handler(term, reading, details); } catch (e) { // NOP } @@ -49,9 +49,9 @@ class AudioDownloader { return []; } - async downloadExpressionAudio(sources, preferredAudioIndex, expression, reading, details) { + async downloadTermAudio(sources, preferredAudioIndex, term, reading, details) { for (const source of sources) { - let infoList = await this.getExpressionAudioInfoList(source, expression, reading, details); + let infoList = await this.getTermAudioInfoList(source, term, reading, details); if (typeof preferredAudioIndex === 'number') { infoList = (preferredAudioIndex >= 0 && preferredAudioIndex < infoList.length ? [infoList[preferredAudioIndex]] : []); } @@ -77,15 +77,15 @@ class AudioDownloader { return new URL(url, base).href; } - async _getInfoJpod101(expression, reading) { - if (reading === expression && this._japaneseUtil.isStringEntirelyKana(expression)) { - reading = expression; - expression = null; + async _getInfoJpod101(term, reading) { + if (reading === term && this._japaneseUtil.isStringEntirelyKana(term)) { + reading = term; + term = null; } const params = new URLSearchParams(); - if (expression) { - params.set('kanji', expression); + if (term) { + params.set('kanji', term); } if (reading) { params.set('kana', reading); @@ -95,12 +95,12 @@ class AudioDownloader { return [{type: 'url', url}]; } - async _getInfoJpod101Alternate(expression, reading) { + async _getInfoJpod101Alternate(term, reading) { const fetchUrl = 'https://www.japanesepod101.com/learningcenter/reference/dictionary_post'; const data = new URLSearchParams({ post: 'dictionary_reference', match_type: 'exact', - search_query: expression, + search_query: term, vulgar: 'true' }); const response = await this._requestBuilder.fetchAnonymous(fetchUrl, { @@ -133,7 +133,7 @@ class AudioDownloader { if (htmlReadings.length === 0) { continue; } const htmlReading = dom.getTextContent(htmlReadings[0]); - if (htmlReading && (reading === expression || reading === htmlReading)) { + if (htmlReading && (reading === term || reading === htmlReading)) { url = this._normalizeUrl(url, response.url); return [{type: 'url', url}]; } @@ -145,8 +145,8 @@ class AudioDownloader { throw new Error('Failed to find audio URL'); } - async _getInfoJisho(expression, reading) { - const fetchUrl = `https://jisho.org/search/${expression}`; + async _getInfoJisho(term, reading) { + const fetchUrl = `https://jisho.org/search/${term}`; const response = await this._requestBuilder.fetchAnonymous(fetchUrl, { method: 'GET', mode: 'cors', @@ -159,7 +159,7 @@ class AudioDownloader { const dom = this._createSimpleDOMParser(responseText); try { - const audio = dom.getElementById(`audio_${expression}:${reading}`); + const audio = dom.getElementById(`audio_${term}:${reading}`); if (audio !== null) { const source = dom.getElementByTagName('source', audio); if (source !== null) { @@ -177,25 +177,25 @@ class AudioDownloader { throw new Error('Failed to find audio URL'); } - async _getInfoTextToSpeech(expression, reading, {textToSpeechVoice}) { + async _getInfoTextToSpeech(term, reading, {textToSpeechVoice}) { if (!textToSpeechVoice) { throw new Error('No voice'); } - return [{type: 'tts', text: expression, voice: textToSpeechVoice}]; + return [{type: 'tts', text: term, voice: textToSpeechVoice}]; } - async _getInfoTextToSpeechReading(expression, reading, {textToSpeechVoice}) { + async _getInfoTextToSpeechReading(term, reading, {textToSpeechVoice}) { if (!textToSpeechVoice) { throw new Error('No voice'); } - return [{type: 'tts', text: reading || expression, voice: textToSpeechVoice}]; + return [{type: 'tts', text: reading, voice: textToSpeechVoice}]; } - async _getInfoCustom(expression, reading, {customSourceUrl, customSourceType}) { + async _getInfoCustom(term, reading, {customSourceUrl, customSourceType}) { if (typeof customSourceUrl !== 'string') { throw new Error('No custom URL defined'); } - const data = {expression, reading}; + const data = {term, reading}; const url = customSourceUrl.replace(/\{([^}]*)\}/g, (m0, m1) => (Object.prototype.hasOwnProperty.call(data, m1) ? `${data[m1]}` : m0)); switch (customSourceType) { diff --git a/ext/js/pages/settings/anki-templates-controller.js b/ext/js/pages/settings/anki-templates-controller.js index 685c80d0..eab0681f 100644 --- a/ext/js/pages/settings/anki-templates-controller.js +++ b/ext/js/pages/settings/anki-templates-controller.js @@ -24,8 +24,8 @@ class AnkiTemplatesController { this._settingsController = settingsController; this._modalController = modalController; this._ankiController = ankiController; - this._cachedDefinitionValue = null; - this._cachedDefinitionText = null; + this._cachedDictionaryEntryValue = null; + this._cachedDictionaryEntryText = null; this._defaultFieldTemplates = null; this._fieldTemplatesTextarea = null; this._compileResultInfo = null; @@ -114,7 +114,7 @@ class AnkiTemplatesController { const field = this._renderFieldInput.value; const infoNode = this._renderResult; infoNode.hidden = true; - this._cachedDefinitionText = null; + this._cachedDictionaryEntryText = null; this._validate(infoNode, field, 'term-kanji', true, false); } @@ -132,15 +132,18 @@ class AnkiTemplatesController { input.dispatchEvent(new Event('change')); } - async _getDefinition(text, optionsContext) { - if (this._cachedDefinitionText !== text) { - const {definitions} = await yomichan.api.termsFind(text, {}, optionsContext); - if (definitions.length === 0) { return null; } + async _getDictionaryEntry(text, optionsContext) { + if (this._cachedDictionaryEntryText !== text) { + const {dictionaryEntries} = await yomichan.api.termsFind(text, {}, optionsContext); + if (dictionaryEntries.length === 0) { return null; } - this._cachedDefinitionValue = definitions[0]; - this._cachedDefinitionText = text; + this._cachedDictionaryEntryValue = dictionaryEntries[0]; + this._cachedDictionaryEntryText = text; } - return this._cachedDefinitionValue; + return { + dictionaryEntry: this._cachedDictionaryEntryValue, + text: this._cachedDictionaryEntryText + }; } async _validate(infoNode, field, mode, showSuccessResult, invalidateInput) { @@ -149,19 +152,22 @@ class AnkiTemplatesController { let result = `No definition found for ${text}`; try { const optionsContext = this._settingsController.getOptionsContext(); - const definition = await this._getDefinition(text, optionsContext); - if (definition !== null) { + const {dictionaryEntry, text: sentenceText} = await this._getDictionaryEntry(text, optionsContext); + if (dictionaryEntry !== null) { const options = await this._settingsController.getOptions(); const context = { url: window.location.href, - sentence: {text: definition.rawSource, offset: 0}, + sentence: { + text: sentenceText, + offset: 0 + }, documentTitle: document.title }; let template = options.anki.fieldTemplates; if (typeof template !== 'string') { template = this._defaultFieldTemplates; } const {general: {resultOutputMode, glossaryLayoutMode, compactTags}} = options; const note = await this._ankiNoteBuilder.createNote({ - definition, + dictionaryEntry, mode, context, template, diff --git a/ext/settings.html b/ext/settings.html index 712dda3f..3e2b6237 100644 --- a/ext/settings.html +++ b/ext/settings.html @@ -2315,8 +2315,8 @@