Refactor furigana segment data (#1502)
* Remove redundant language assignment * Segment furigana from DisplayGenerator * Remove furiganaSegments from translator data * Add backwards compatibility for furiganaSegments * Update tests
This commit is contained in:
parent
7793e14e57
commit
19f6bf5a3a
@ -31,7 +31,7 @@
|
||||
<div class="debug-info"><a class="debug-log-link">Log debug info to console</a></div>
|
||||
</div></template>
|
||||
<template id="expression-template" data-remove-whitespace-text="true"><div class="expression">
|
||||
<div class="expression-text-container" lang="ja">
|
||||
<div class="expression-text-container">
|
||||
<span class="expression-text-outer source-text">
|
||||
<span class="expression-current-indicator"></span>
|
||||
<span class="expression-text"></span>
|
||||
|
@ -24,7 +24,7 @@
|
||||
* The public properties and data should be backwards compatible.
|
||||
*/
|
||||
class AnkiNoteData {
|
||||
constructor({
|
||||
constructor(japaneseUtil, marker, {
|
||||
definition,
|
||||
resultOutputMode,
|
||||
mode,
|
||||
@ -32,7 +32,8 @@ class AnkiNoteData {
|
||||
compactTags,
|
||||
context,
|
||||
injectedMedia=null
|
||||
}, marker) {
|
||||
}) {
|
||||
this._japaneseUtil = japaneseUtil;
|
||||
this._definition = definition;
|
||||
this._resultOutputMode = resultOutputMode;
|
||||
this._mode = mode;
|
||||
@ -47,6 +48,7 @@ class AnkiNoteData {
|
||||
this._uniqueReadings = null;
|
||||
this._publicContext = null;
|
||||
this._cloze = null;
|
||||
this._furiganaSegmentsCache = null;
|
||||
|
||||
this._prepareDefinition(definition, injectedMedia, context);
|
||||
}
|
||||
@ -236,5 +238,47 @@ class AnkiNoteData {
|
||||
enumerable: true,
|
||||
get: this._getClozeCached.bind(this)
|
||||
});
|
||||
|
||||
for (const definition2 of this._getAllDefinitions(definition)) {
|
||||
if (definition2.type === 'term') {
|
||||
this._defineFuriganaSegments(definition2);
|
||||
}
|
||||
for (const expression of definition2.expressions) {
|
||||
this._defineFuriganaSegments(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_defineFuriganaSegments(object) {
|
||||
Object.defineProperty(object, 'furiganaSegments', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: this._getFuriganaSegments.bind(this, object)
|
||||
});
|
||||
}
|
||||
|
||||
_getFuriganaSegments(object) {
|
||||
if (this._furiganaSegmentsCache !== null) {
|
||||
const cachedResult = this._furiganaSegmentsCache.get(object);
|
||||
if (typeof cachedResult !== 'undefined') { return cachedResult; }
|
||||
} else {
|
||||
this._furiganaSegmentsCache = new Map();
|
||||
}
|
||||
|
||||
const {expression, reading} = object;
|
||||
const result = this._japaneseUtil.distributeFurigana(expression, reading);
|
||||
this._furiganaSegmentsCache.set(object, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
_getAllDefinitions(definition) {
|
||||
const definitions = [definition];
|
||||
for (let i = 0; i < definitions.length; ++i) {
|
||||
const childDefinitions = definitions[i].definitions;
|
||||
if (Array.isArray(childDefinitions)) {
|
||||
definitions.push(...childDefinitions);
|
||||
}
|
||||
}
|
||||
return definitions;
|
||||
}
|
||||
}
|
||||
|
@ -190,11 +190,9 @@ class DisplayGenerator {
|
||||
disambiguationContainer.dataset[attribute] = value;
|
||||
}
|
||||
for (const {expression, reading} of disambiguation) {
|
||||
const segments = this._japaneseUtil.distributeFurigana(expression, reading);
|
||||
const disambiguationItem = document.createElement('span');
|
||||
disambiguationItem.className = 'tag-details-disambiguation';
|
||||
disambiguationItem.lang = 'ja';
|
||||
this._appendFurigana(disambiguationItem, segments, (container, text) => {
|
||||
this._appendFurigana(disambiguationItem, expression, reading, (container, text) => {
|
||||
container.appendChild(document.createTextNode(text));
|
||||
});
|
||||
disambiguationContainer.appendChild(disambiguationItem);
|
||||
@ -232,7 +230,7 @@ class DisplayGenerator {
|
||||
// Private
|
||||
|
||||
_createTermExpression(details) {
|
||||
const {termFrequency, furiganaSegments, expression, reading, termTags, pitches} = details;
|
||||
const {termFrequency, expression, reading, termTags, pitches} = details;
|
||||
|
||||
const searchQueries = [];
|
||||
if (expression) { searchQueries.push(expression); }
|
||||
@ -253,7 +251,7 @@ class DisplayGenerator {
|
||||
|
||||
this._setTextContent(node.querySelector('.expression-reading'), reading);
|
||||
|
||||
this._appendFurigana(expressionContainer, furiganaSegments, this._appendKanjiLinks.bind(this));
|
||||
this._appendFurigana(expressionContainer, expression, reading, this._appendKanjiLinks.bind(this));
|
||||
this._appendMultiple(tagContainer, this._createTag.bind(this), termTags);
|
||||
this._appendMultiple(tagContainer, this._createSearchTag.bind(this), searchQueries);
|
||||
|
||||
@ -651,7 +649,6 @@ class DisplayGenerator {
|
||||
}
|
||||
|
||||
_appendKanjiLinks(container, text) {
|
||||
container.lang = 'ja';
|
||||
const jp = this._japaneseUtil;
|
||||
let part = '';
|
||||
for (const c of text) {
|
||||
@ -692,7 +689,9 @@ class DisplayGenerator {
|
||||
return count;
|
||||
}
|
||||
|
||||
_appendFurigana(container, segments, addText) {
|
||||
_appendFurigana(container, expression, reading, addText) {
|
||||
container.lang = 'ja';
|
||||
const segments = this._japaneseUtil.distributeFurigana(expression, reading);
|
||||
for (const {text, furigana} of segments) {
|
||||
if (furigana) {
|
||||
const ruby = document.createElement('ruby');
|
||||
|
@ -1080,8 +1080,7 @@ class Translator {
|
||||
this._sortTags(definitionTagsExpanded);
|
||||
this._sortTags(termTagsExpanded);
|
||||
|
||||
const furiganaSegments = this._japaneseUtil.distributeFurigana(expression, reading);
|
||||
const termDetailsList = [this._createTermDetails(sourceTerm, expression, reading, furiganaSegments, termTagsExpanded)];
|
||||
const termDetailsList = [this._createTermDetails(sourceTerm, expression, reading, termTagsExpanded)];
|
||||
const sourceTermExactMatchCount = (sourceTerm === expression ? 1 : 0);
|
||||
|
||||
return {
|
||||
@ -1100,7 +1099,6 @@ class Translator {
|
||||
expression,
|
||||
reading,
|
||||
expressions: termDetailsList,
|
||||
furiganaSegments,
|
||||
glossary,
|
||||
definitionTags: definitionTagsExpanded,
|
||||
termTags: termTagsExpanded,
|
||||
@ -1118,12 +1116,12 @@ class Translator {
|
||||
* @returns A single 'termGrouped' definition.
|
||||
*/
|
||||
_createGroupedTermDefinition(definitions) {
|
||||
const {reasons, source, rawSource, sourceTerm, expressions: [{expression, reading, furiganaSegments}]} = definitions[0];
|
||||
const {reasons, source, rawSource, sourceTerm, expressions: [{expression, reading}]} = definitions[0];
|
||||
const score = this._getMaxDefinitionScore(definitions);
|
||||
const dictionaryOrder = this._getBestDictionaryOrder(definitions);
|
||||
const dictionaryNames = this._getUniqueDictionaryNames(definitions);
|
||||
const termTags = this._getUniqueTermTags(definitions);
|
||||
const termDetailsList = [this._createTermDetails(sourceTerm, expression, reading, furiganaSegments, termTags)];
|
||||
const termDetailsList = [this._createTermDetails(sourceTerm, expression, reading, termTags)];
|
||||
const sourceTermExactMatchCount = (sourceTerm === expression ? 1 : 0);
|
||||
return {
|
||||
type: 'termGrouped',
|
||||
@ -1141,7 +1139,6 @@ class Translator {
|
||||
expression,
|
||||
reading,
|
||||
expressions: termDetailsList,
|
||||
furiganaSegments, // Contains duplicate data
|
||||
// glossary
|
||||
// definitionTags
|
||||
termTags,
|
||||
@ -1173,7 +1170,6 @@ class Translator {
|
||||
expression: expressions,
|
||||
reading: readings,
|
||||
expressions: termDetailsList,
|
||||
// furiganaSegments
|
||||
// glossary
|
||||
// definitionTags
|
||||
// termTags
|
||||
@ -1221,7 +1217,6 @@ class Translator {
|
||||
expression: [...expressions],
|
||||
reading: [...readings],
|
||||
expressions: termDetailsList,
|
||||
// furiganaSegments
|
||||
glossary: [...glossary],
|
||||
definitionTags,
|
||||
// termTags
|
||||
@ -1240,7 +1235,7 @@ class Translator {
|
||||
*/
|
||||
_createTermDetailsList(definitions) {
|
||||
const termInfoMap = new Map();
|
||||
for (const {expression, reading, sourceTerm, furiganaSegments, termTags} of definitions) {
|
||||
for (const {expression, reading, sourceTerm, termTags} of definitions) {
|
||||
let readingMap = termInfoMap.get(expression);
|
||||
if (typeof readingMap === 'undefined') {
|
||||
readingMap = new Map();
|
||||
@ -1251,7 +1246,6 @@ class Translator {
|
||||
if (typeof termInfo === 'undefined') {
|
||||
termInfo = {
|
||||
sourceTerm,
|
||||
furiganaSegments,
|
||||
termTagsMap: new Map()
|
||||
};
|
||||
readingMap.set(reading, termInfo);
|
||||
@ -1267,22 +1261,21 @@ class Translator {
|
||||
|
||||
const termDetailsList = [];
|
||||
for (const [expression, readingMap] of termInfoMap.entries()) {
|
||||
for (const [reading, {termTagsMap, sourceTerm, furiganaSegments}] of readingMap.entries()) {
|
||||
for (const [reading, {termTagsMap, sourceTerm}] of readingMap.entries()) {
|
||||
const termTags = [...termTagsMap.values()];
|
||||
this._sortTags(termTags);
|
||||
termDetailsList.push(this._createTermDetails(sourceTerm, expression, reading, furiganaSegments, termTags));
|
||||
termDetailsList.push(this._createTermDetails(sourceTerm, expression, reading, termTags));
|
||||
}
|
||||
}
|
||||
return termDetailsList;
|
||||
}
|
||||
|
||||
_createTermDetails(sourceTerm, expression, reading, furiganaSegments, termTags) {
|
||||
_createTermDetails(sourceTerm, expression, reading, termTags) {
|
||||
const termFrequency = this._scoreToTermFrequency(this._getTermTagsScoreSum(termTags));
|
||||
return {
|
||||
sourceTerm,
|
||||
expression,
|
||||
reading,
|
||||
furiganaSegments, // Contains duplicate data
|
||||
termTags,
|
||||
termFrequency,
|
||||
frequencies: [],
|
||||
|
@ -26,7 +26,7 @@
|
||||
const japaneseUtil = new JapaneseUtil(null);
|
||||
const templateRenderer = new TemplateRenderer(japaneseUtil);
|
||||
templateRenderer.registerDataType('ankiNote', {
|
||||
modifier: ({data, marker}) => new AnkiNoteData(data, marker).createPublic()
|
||||
modifier: ({data, marker}) => new AnkiNoteData(japaneseUtil, marker, data).createPublic()
|
||||
});
|
||||
const templateRendererFrameApi = new TemplateRendererFrameApi(templateRenderer);
|
||||
templateRendererFrameApi.prepare();
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user