diff options
Diffstat (limited to 'ext/js/display')
-rw-r--r-- | ext/js/display/display-anki.js | 4 | ||||
-rw-r--r-- | ext/js/display/display-content-manager.js | 4 | ||||
-rw-r--r-- | ext/js/display/display-generator.js | 26 | ||||
-rw-r--r-- | ext/js/display/sandbox/pronunciation-generator.js | 378 |
4 files changed, 204 insertions, 208 deletions
diff --git a/ext/js/display/display-anki.js b/ext/js/display/display-anki.js index 5433142d..68d28d33 100644 --- a/ext/js/display/display-anki.js +++ b/ext/js/display/display-anki.js @@ -20,7 +20,7 @@ import {EventListenerCollection} from '../core/event-listener-collection.js'; import {toError} from '../core/to-error.js'; import {deferPromise} from '../core/utilities.js'; import {AnkiNoteBuilder} from '../data/anki-note-builder.js'; -import {AnkiUtil} from '../data/anki-util.js'; +import {isNoteDataValid} from '../data/anki-util.js'; import {PopupMenu} from '../dom/popup-menu.js'; import {querySelectorNotNull} from '../dom/query-selector.js'; import {TemplateRendererProxy} from '../templates/template-renderer-proxy.js'; @@ -676,7 +676,7 @@ export class DisplayAnki { _getAnkiNoteInfoForceValue(notes, canAdd) { const results = []; for (const note of notes) { - const valid = AnkiUtil.isNoteDataValid(note); + const valid = isNoteDataValid(note); results.push({canAdd, valid, noteIds: null}); } return results; diff --git a/ext/js/display/display-content-manager.js b/ext/js/display/display-content-manager.js index d13dffb3..4465ce3e 100644 --- a/ext/js/display/display-content-manager.js +++ b/ext/js/display/display-content-manager.js @@ -17,7 +17,7 @@ */ import {EventListenerCollection} from '../core/event-listener-collection.js'; -import {ArrayBufferUtil} from '../data/sandbox/array-buffer-util.js'; +import {base64ToArrayBuffer} from '../data/sandbox/array-buffer-util.js'; import {yomitan} from '../yomitan.js'; /** @@ -143,7 +143,7 @@ export class DisplayContentManager { const datas = await yomitan.api.getMedia([{path, dictionary}]); if (token === this._token && datas.length > 0) { const data = datas[0]; - const buffer = ArrayBufferUtil.base64ToArrayBuffer(data.content); + const buffer = base64ToArrayBuffer(data.content); const blob = new Blob([buffer], {type: data.mediaType}); const url = URL.createObjectURL(blob); return {data, url}; diff --git a/ext/js/display/display-generator.js b/ext/js/display/display-generator.js index eef58bb0..01f6f38b 100644 --- a/ext/js/display/display-generator.js +++ b/ext/js/display/display-generator.js @@ -18,11 +18,11 @@ import {ExtensionError} from '../core/extension-error.js'; import {isObject} from '../core/utilities.js'; -import {DictionaryDataUtil} from '../dictionary/dictionary-data-util.js'; +import {getDisambiguations, getGroupedPronunciations, getTermFrequency, groupKanjiFrequencies, groupTermFrequencies, groupTermTags, isNonNounVerbOrAdjective} from '../dictionary/dictionary-data-util.js'; import {HtmlTemplateCollection} from '../dom/html-template-collection.js'; import {distributeFurigana, getKanaMorae, getPitchCategory, isCodePointKanji, isStringPartiallyJapanese} from '../language/japanese.js'; import {yomitan} from '../yomitan.js'; -import {PronunciationGenerator} from './sandbox/pronunciation-generator.js'; +import {createPronunciationDownstepPosition, createPronunciationGraph, createPronunciationText} from './sandbox/pronunciation-generator.js'; import {StructuredContentGenerator} from './sandbox/structured-content-generator.js'; export class DisplayGenerator { @@ -38,8 +38,6 @@ export class DisplayGenerator { this._templates = new HtmlTemplateCollection(); /** @type {StructuredContentGenerator} */ this._structuredContentGenerator = new StructuredContentGenerator(this._contentManager, document); - /** @type {PronunciationGenerator} */ - this._pronunciationGenerator = new PronunciationGenerator(); } /** */ @@ -73,10 +71,10 @@ export class DisplayGenerator { const headwordTagsContainer = this._querySelector(node, '.headword-list-tag-list'); const {headwords, type, inflectionRuleChainCandidates, definitions, frequencies, pronunciations} = dictionaryEntry; - const groupedPronunciations = DictionaryDataUtil.getGroupedPronunciations(dictionaryEntry); + const groupedPronunciations = getGroupedPronunciations(dictionaryEntry); const pronunciationCount = groupedPronunciations.reduce((i, v) => i + v.pronunciations.length, 0); - const groupedFrequencies = DictionaryDataUtil.groupTermFrequencies(dictionaryEntry); - const termTags = DictionaryDataUtil.groupTermTags(dictionaryEntry); + const groupedFrequencies = groupTermFrequencies(dictionaryEntry); + const termTags = groupTermTags(dictionaryEntry); /** @type {Set<string>} */ const uniqueTerms = new Set(); @@ -166,7 +164,7 @@ export class DisplayGenerator { const dictionaryIndicesContainer = this._querySelector(node, '.kanji-dictionary-indices'); this._setTextContent(glyphContainer, dictionaryEntry.character, 'ja'); - const groupedFrequencies = DictionaryDataUtil.groupKanjiFrequencies(dictionaryEntry.frequencies); + const groupedFrequencies = groupKanjiFrequencies(dictionaryEntry.frequencies); const dictionaryTag = this._createDictionaryTag(dictionaryEntry.dictionary); @@ -334,7 +332,7 @@ export class DisplayGenerator { node.dataset.isPrimary = `${isPrimaryAny}`; node.dataset.readingIsSame = `${reading === term}`; - node.dataset.frequency = DictionaryDataUtil.getTermFrequency(tags); + node.dataset.frequency = getTermFrequency(tags); node.dataset.matchTypes = [...matchTypes].join(' '); node.dataset.matchSources = [...matchSources].join(' '); @@ -415,7 +413,7 @@ export class DisplayGenerator { */ _createTermDefinition(definition, dictionaryTag, headwords, uniqueTerms, uniqueReadings) { const {dictionary, tags, headwordIndices, entries} = definition; - const disambiguations = DictionaryDataUtil.getDisambiguations(headwords, headwordIndices, uniqueTerms, uniqueReadings); + const disambiguations = getDisambiguations(headwords, headwordIndices, uniqueTerms, uniqueReadings); const node = this._instantiate('definition-item'); @@ -742,15 +740,15 @@ export class DisplayGenerator { this._createPronunciationDisambiguations(n, exclusiveTerms, exclusiveReadings); n = this._querySelector(node, '.pronunciation-downstep-notation-container'); - n.appendChild(this._pronunciationGenerator.createPronunciationDownstepPosition(position)); + n.appendChild(createPronunciationDownstepPosition(position)); n = this._querySelector(node, '.pronunciation-text-container'); n.lang = 'ja'; - n.appendChild(this._pronunciationGenerator.createPronunciationText(morae, position, nasalPositions, devoicePositions)); + n.appendChild(createPronunciationText(morae, position, nasalPositions, devoicePositions)); n = this._querySelector(node, '.pronunciation-graph-container'); - n.appendChild(this._pronunciationGenerator.createPronunciationGraph(morae, position)); + n.appendChild(createPronunciationGraph(morae, position)); return node; } @@ -1040,7 +1038,7 @@ export class DisplayGenerator { */ _getPronunciationCategories(reading, termPronunciations, wordClasses, headwordIndex) { if (termPronunciations.length === 0) { return null; } - const isVerbOrAdjective = DictionaryDataUtil.isNonNounVerbOrAdjective(wordClasses); + const isVerbOrAdjective = isNonNounVerbOrAdjective(wordClasses); /** @type {Set<import('japanese-util').PitchCategory>} */ const categories = new Set(); for (const termPronunciation of termPronunciations) { diff --git a/ext/js/display/sandbox/pronunciation-generator.js b/ext/js/display/sandbox/pronunciation-generator.js index 45631e74..373ec830 100644 --- a/ext/js/display/sandbox/pronunciation-generator.js +++ b/ext/js/display/sandbox/pronunciation-generator.js @@ -18,221 +18,219 @@ import {getKanaDiacriticInfo, isMoraPitchHigh} from '../../language/japanese.js'; -export class PronunciationGenerator { - /** - * @param {string[]} morae - * @param {number} downstepPosition - * @param {number[]} nasalPositions - * @param {number[]} devoicePositions - * @returns {HTMLSpanElement} - */ - createPronunciationText(morae, downstepPosition, nasalPositions, devoicePositions) { - const nasalPositionsSet = nasalPositions.length > 0 ? new Set(nasalPositions) : null; - const devoicePositionsSet = devoicePositions.length > 0 ? new Set(devoicePositions) : null; - const container = document.createElement('span'); - container.className = 'pronunciation-text'; - for (let i = 0, ii = morae.length; i < ii; ++i) { - const i1 = i + 1; - const mora = morae[i]; - const highPitch = isMoraPitchHigh(i, downstepPosition); - const highPitchNext = isMoraPitchHigh(i1, downstepPosition); - const nasal = nasalPositionsSet !== null && nasalPositionsSet.has(i1); - const devoice = devoicePositionsSet !== null && devoicePositionsSet.has(i1); - - const n1 = document.createElement('span'); - n1.className = 'pronunciation-mora'; - n1.dataset.position = `${i}`; - n1.dataset.pitch = highPitch ? 'high' : 'low'; - n1.dataset.pitchNext = highPitchNext ? 'high' : 'low'; - - const characterNodes = []; - for (const character of mora) { - const n2 = document.createElement('span'); - n2.className = 'pronunciation-character'; - n2.textContent = character; - n1.appendChild(n2); - characterNodes.push(n2); - } - - if (devoice) { - n1.dataset.devoice = 'true'; - const n3 = document.createElement('span'); - n3.className = 'pronunciation-devoice-indicator'; - n1.appendChild(n3); - } - if (nasal && characterNodes.length > 0) { - n1.dataset.nasal = 'true'; - - const group = document.createElement('span'); - group.className = 'pronunciation-character-group'; +/** + * @param {string[]} morae + * @param {number} downstepPosition + * @param {number[]} nasalPositions + * @param {number[]} devoicePositions + * @returns {HTMLSpanElement} + */ +export function createPronunciationText(morae, downstepPosition, nasalPositions, devoicePositions) { + const nasalPositionsSet = nasalPositions.length > 0 ? new Set(nasalPositions) : null; + const devoicePositionsSet = devoicePositions.length > 0 ? new Set(devoicePositions) : null; + const container = document.createElement('span'); + container.className = 'pronunciation-text'; + for (let i = 0, ii = morae.length; i < ii; ++i) { + const i1 = i + 1; + const mora = morae[i]; + const highPitch = isMoraPitchHigh(i, downstepPosition); + const highPitchNext = isMoraPitchHigh(i1, downstepPosition); + const nasal = nasalPositionsSet !== null && nasalPositionsSet.has(i1); + const devoice = devoicePositionsSet !== null && devoicePositionsSet.has(i1); - const n2 = characterNodes[0]; - const character = /** @type {string} */ (n2.textContent); + const n1 = document.createElement('span'); + n1.className = 'pronunciation-mora'; + n1.dataset.position = `${i}`; + n1.dataset.pitch = highPitch ? 'high' : 'low'; + n1.dataset.pitchNext = highPitchNext ? 'high' : 'low'; + + const characterNodes = []; + for (const character of mora) { + const n2 = document.createElement('span'); + n2.className = 'pronunciation-character'; + n2.textContent = character; + n1.appendChild(n2); + characterNodes.push(n2); + } - const characterInfo = getKanaDiacriticInfo(character); - if (characterInfo !== null) { - n1.dataset.originalText = mora; - n2.dataset.originalText = character; - n2.textContent = characterInfo.character; - } + if (devoice) { + n1.dataset.devoice = 'true'; + const n3 = document.createElement('span'); + n3.className = 'pronunciation-devoice-indicator'; + n1.appendChild(n3); + } + if (nasal && characterNodes.length > 0) { + n1.dataset.nasal = 'true'; - let n3 = document.createElement('span'); - n3.className = 'pronunciation-nasal-diacritic'; - n3.textContent = '\u309a'; // Combining handakuten - group.appendChild(n3); + const group = document.createElement('span'); + group.className = 'pronunciation-character-group'; - n3 = document.createElement('span'); - n3.className = 'pronunciation-nasal-indicator'; - group.appendChild(n3); + const n2 = characterNodes[0]; + const character = /** @type {string} */ (n2.textContent); - /** @type {ParentNode} */ (n2.parentNode).replaceChild(group, n2); - group.insertBefore(n2, group.firstChild); + const characterInfo = getKanaDiacriticInfo(character); + if (characterInfo !== null) { + n1.dataset.originalText = mora; + n2.dataset.originalText = character; + n2.textContent = characterInfo.character; } - const line = document.createElement('span'); - line.className = 'pronunciation-mora-line'; - n1.appendChild(line); + let n3 = document.createElement('span'); + n3.className = 'pronunciation-nasal-diacritic'; + n3.textContent = '\u309a'; // Combining handakuten + group.appendChild(n3); - container.appendChild(n1); - } - return container; - } + n3 = document.createElement('span'); + n3.className = 'pronunciation-nasal-indicator'; + group.appendChild(n3); - /** - * @param {string[]} morae - * @param {number} downstepPosition - * @returns {SVGSVGElement} - */ - createPronunciationGraph(morae, downstepPosition) { - const ii = morae.length; - - const svgns = 'http://www.w3.org/2000/svg'; - const svg = document.createElementNS(svgns, 'svg'); - svg.setAttribute('xmlns', svgns); - svg.setAttribute('class', 'pronunciation-graph'); - svg.setAttribute('focusable', 'false'); - svg.setAttribute('viewBox', `0 0 ${50 * (ii + 1)} 100`); - - if (ii <= 0) { return svg; } - - const path1 = document.createElementNS(svgns, 'path'); - svg.appendChild(path1); - - const path2 = document.createElementNS(svgns, 'path'); - svg.appendChild(path2); - - const pathPoints = []; - for (let i = 0; i < ii; ++i) { - const highPitch = isMoraPitchHigh(i, downstepPosition); - const highPitchNext = isMoraPitchHigh(i + 1, downstepPosition); - const x = i * 50 + 25; - const y = highPitch ? 25 : 75; - if (highPitch && !highPitchNext) { - this._addGraphDotDownstep(svg, svgns, x, y); - } else { - this._addGraphDot(svg, svgns, x, y); - } - pathPoints.push(`${x} ${y}`); + /** @type {ParentNode} */ (n2.parentNode).replaceChild(group, n2); + group.insertBefore(n2, group.firstChild); } - path1.setAttribute('class', 'pronunciation-graph-line'); - path1.setAttribute('d', `M${pathPoints.join(' L')}`); + const line = document.createElement('span'); + line.className = 'pronunciation-mora-line'; + n1.appendChild(line); + + container.appendChild(n1); + } + return container; +} - pathPoints.splice(0, ii - 1); - { - const highPitch = isMoraPitchHigh(ii, downstepPosition); - const x = ii * 50 + 25; - const y = highPitch ? 25 : 75; - this._addGraphTriangle(svg, svgns, x, y); - pathPoints.push(`${x} ${y}`); +/** + * @param {string[]} morae + * @param {number} downstepPosition + * @returns {SVGSVGElement} + */ +export function createPronunciationGraph(morae, downstepPosition) { + const ii = morae.length; + + const svgns = 'http://www.w3.org/2000/svg'; + const svg = document.createElementNS(svgns, 'svg'); + svg.setAttribute('xmlns', svgns); + svg.setAttribute('class', 'pronunciation-graph'); + svg.setAttribute('focusable', 'false'); + svg.setAttribute('viewBox', `0 0 ${50 * (ii + 1)} 100`); + + if (ii <= 0) { return svg; } + + const path1 = document.createElementNS(svgns, 'path'); + svg.appendChild(path1); + + const path2 = document.createElementNS(svgns, 'path'); + svg.appendChild(path2); + + const pathPoints = []; + for (let i = 0; i < ii; ++i) { + const highPitch = isMoraPitchHigh(i, downstepPosition); + const highPitchNext = isMoraPitchHigh(i + 1, downstepPosition); + const x = i * 50 + 25; + const y = highPitch ? 25 : 75; + if (highPitch && !highPitchNext) { + addGraphDotDownstep(svg, svgns, x, y); + } else { + addGraphDot(svg, svgns, x, y); } + pathPoints.push(`${x} ${y}`); + } - path2.setAttribute('class', 'pronunciation-graph-line-tail'); - path2.setAttribute('d', `M${pathPoints.join(' L')}`); + path1.setAttribute('class', 'pronunciation-graph-line'); + path1.setAttribute('d', `M${pathPoints.join(' L')}`); - return svg; + pathPoints.splice(0, ii - 1); + { + const highPitch = isMoraPitchHigh(ii, downstepPosition); + const x = ii * 50 + 25; + const y = highPitch ? 25 : 75; + addGraphTriangle(svg, svgns, x, y); + pathPoints.push(`${x} ${y}`); } - /** - * @param {number} downstepPosition - * @returns {HTMLSpanElement} - */ - createPronunciationDownstepPosition(downstepPosition) { - const downstepPositionString = `${downstepPosition}`; + path2.setAttribute('class', 'pronunciation-graph-line-tail'); + path2.setAttribute('d', `M${pathPoints.join(' L')}`); - const n1 = document.createElement('span'); - n1.className = 'pronunciation-downstep-notation'; - n1.dataset.downstepPosition = downstepPositionString; + return svg; +} - let n2 = document.createElement('span'); - n2.className = 'pronunciation-downstep-notation-prefix'; - n2.textContent = '['; - n1.appendChild(n2); +/** + * @param {number} downstepPosition + * @returns {HTMLSpanElement} + */ +export function createPronunciationDownstepPosition(downstepPosition) { + const downstepPositionString = `${downstepPosition}`; - n2 = document.createElement('span'); - n2.className = 'pronunciation-downstep-notation-number'; - n2.textContent = downstepPositionString; - n1.appendChild(n2); + const n1 = document.createElement('span'); + n1.className = 'pronunciation-downstep-notation'; + n1.dataset.downstepPosition = downstepPositionString; - n2 = document.createElement('span'); - n2.className = 'pronunciation-downstep-notation-suffix'; - n2.textContent = ']'; - n1.appendChild(n2); + let n2 = document.createElement('span'); + n2.className = 'pronunciation-downstep-notation-prefix'; + n2.textContent = '['; + n1.appendChild(n2); - return n1; - } + n2 = document.createElement('span'); + n2.className = 'pronunciation-downstep-notation-number'; + n2.textContent = downstepPositionString; + n1.appendChild(n2); - // Private + n2 = document.createElement('span'); + n2.className = 'pronunciation-downstep-notation-suffix'; + n2.textContent = ']'; + n1.appendChild(n2); - /** - * @param {Element} container - * @param {string} svgns - * @param {number} x - * @param {number} y - */ - _addGraphDot(container, svgns, x, y) { - container.appendChild(this._createGraphCircle(svgns, 'pronunciation-graph-dot', x, y, '15')); - } + return n1; +} - /** - * @param {Element} container - * @param {string} svgns - * @param {number} x - * @param {number} y - */ - _addGraphDotDownstep(container, svgns, x, y) { - container.appendChild(this._createGraphCircle(svgns, 'pronunciation-graph-dot-downstep1', x, y, '15')); - container.appendChild(this._createGraphCircle(svgns, 'pronunciation-graph-dot-downstep2', x, y, '5')); - } +// Private - /** - * @param {Element} container - * @param {string} svgns - * @param {number} x - * @param {number} y - */ - _addGraphTriangle(container, svgns, x, y) { - const node = document.createElementNS(svgns, 'path'); - node.setAttribute('class', 'pronunciation-graph-triangle'); - node.setAttribute('d', 'M0 13 L15 -13 L-15 -13 Z'); - node.setAttribute('transform', `translate(${x},${y})`); - container.appendChild(node); - } +/** + * @param {Element} container + * @param {string} svgns + * @param {number} x + * @param {number} y + */ +function addGraphDot(container, svgns, x, y) { + container.appendChild(createGraphCircle(svgns, 'pronunciation-graph-dot', x, y, '15')); +} - /** - * @param {string} svgns - * @param {string} className - * @param {number} x - * @param {number} y - * @param {string} radius - * @returns {Element} - */ - _createGraphCircle(svgns, className, x, y, radius) { - const node = document.createElementNS(svgns, 'circle'); - node.setAttribute('class', className); - node.setAttribute('cx', `${x}`); - node.setAttribute('cy', `${y}`); - node.setAttribute('r', radius); - return node; - } +/** + * @param {Element} container + * @param {string} svgns + * @param {number} x + * @param {number} y + */ +function addGraphDotDownstep(container, svgns, x, y) { + container.appendChild(createGraphCircle(svgns, 'pronunciation-graph-dot-downstep1', x, y, '15')); + container.appendChild(createGraphCircle(svgns, 'pronunciation-graph-dot-downstep2', x, y, '5')); +} + +/** + * @param {Element} container + * @param {string} svgns + * @param {number} x + * @param {number} y + */ +function addGraphTriangle(container, svgns, x, y) { + const node = document.createElementNS(svgns, 'path'); + node.setAttribute('class', 'pronunciation-graph-triangle'); + node.setAttribute('d', 'M0 13 L15 -13 L-15 -13 Z'); + node.setAttribute('transform', `translate(${x},${y})`); + container.appendChild(node); +} + +/** + * @param {string} svgns + * @param {string} className + * @param {number} x + * @param {number} y + * @param {string} radius + * @returns {Element} + */ +function createGraphCircle(svgns, className, x, y, radius) { + const node = document.createElementNS(svgns, 'circle'); + node.setAttribute('class', className); + node.setAttribute('cx', `${x}`); + node.setAttribute('cy', `${y}`); + node.setAttribute('r', radius); + return node; } |