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
This commit is contained in:
parent
b8bedd5185
commit
e14b52ef84
@ -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',
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -38,7 +38,7 @@ class AnkiNoteDataCreator {
|
||||
* @returns An object used for rendering Anki templates.
|
||||
*/
|
||||
create(marker, {
|
||||
definition: dictionaryEntry,
|
||||
dictionaryEntry,
|
||||
resultOutputMode,
|
||||
mode,
|
||||
glossaryLayoutMode,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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');
|
||||
|
@ -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;
|
||||