diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2021-02-13 22:52:28 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-13 22:52:28 -0500 | 
| commit | 6a271e067fa917614f4c81f473533e24c6d04404 (patch) | |
| tree | 0d81658b1c03aecfbba133425aefc0ea7612338c /ext/mixed/js/display-generator.js | |
| parent | deed5027cd18bcdb9cb9d13cb7831be0ec5384e8 (diff) | |
Move mixed/js (#1383)
* Move mixed/js/core.js to js/core.js
* Move mixed/js/yomichan.js to js/yomichan.js
* Move mixed/js/timer.js to js/debug/timer.js
* Move mixed/js/hotkey-handler.js to js/input/hotkey-handler.js
* Move mixed/js/hotkey-help-controller.js to js/input/hotkey-help-controller.js
* Move mixed/js/hotkey-util.js to js/input/hotkey-util.js
* Move mixed/js/audio-system.js to js/input/audio-system.js
* Move mixed/js/media-loader.js to js/input/media-loader.js
* Move mixed/js/text-to-speech-audio.js to js/input/text-to-speech-audio.js
* Move mixed/js/comm.js to js/comm/cross-frame-api.js
* Move mixed/js/api.js to js/comm/api.js
* Move mixed/js/frame-client.js to js/comm/frame-client.js
* Move mixed/js/frame-endpoint.js to js/comm/frame-endpoint.js
* Move mixed/js/display.js to js/display/display.js
* Move mixed/js/display-audio.js to js/display/display-audio.js
* Move mixed/js/display-generator.js to js/display/display-generator.js
* Move mixed/js/display-history.js to js/display/display-history.js
* Move mixed/js/display-notification.js to js/display/display-notification.js
* Move mixed/js/display-profile-selection.js to js/display/display-profile-selection.js
* Move mixed/js/japanese.js to js/language/japanese-util.js
* Move mixed/js/dictionary-data-util.js to js/language/dictionary-data-util.js
* Move mixed/js/document-focus-controller.js to js/dom/document-focus-controller.js
* Move mixed/js/document-util.js to js/dom/document-util.js
* Move mixed/js/dom-data-binder.js to js/dom/dom-data-binder.js
* Move mixed/js/html-template-collection.js to js/dom/html-template-collection.js
* Move mixed/js/panel-element.js to js/dom/panel-element.js
* Move mixed/js/popup-menu.js to js/dom/popup-menu.js
* Move mixed/js/selector-observer.js to js/dom/selector-observer.js
* Move mixed/js/scroll.js to js/dom/window-scroll.js
* Move mixed/js/text-scanner.js to js/language/text-scanner.js
* Move mixed/js/cache-map.js to js/general/cache-map.js
* Move mixed/js/object-property-accessor.js to js/general/object-property-accessor.js
* Move mixed/js/task-accumulator.js to js/general/task-accumulator.js
* Move mixed/js/environment.js to js/background/environment.js
* Move mixed/js/dynamic-loader.js to js/scripting/dynamic-loader.js
* Move mixed/js/dynamic-loader-sentinel.js to js/scripting/dynamic-loader-sentinel.js
Diffstat (limited to 'ext/mixed/js/display-generator.js')
| -rw-r--r-- | ext/mixed/js/display-generator.js | 702 | 
1 files changed, 0 insertions, 702 deletions
| diff --git a/ext/mixed/js/display-generator.js b/ext/mixed/js/display-generator.js deleted file mode 100644 index 05376ee5..00000000 --- a/ext/mixed/js/display-generator.js +++ /dev/null @@ -1,702 +0,0 @@ -/* - * Copyright (C) 2019-2021  Yomichan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -/* global - * DictionaryDataUtil - * HtmlTemplateCollection - * api - */ - -class DisplayGenerator { -    constructor({japaneseUtil, mediaLoader, hotkeyHelpController=null}) { -        this._japaneseUtil = japaneseUtil; -        this._mediaLoader = mediaLoader; -        this._hotkeyHelpController = hotkeyHelpController; -        this._templates = null; -        this._termPitchAccentStaticTemplateIsSetup = false; -    } - -    async prepare() { -        const html = await api.getDisplayTemplatesHtml(); -        this._templates = new HtmlTemplateCollection(html); -        this.updateHotkeys(); -    } - -    updateHotkeys() { -        const hotkeyHelpController = this._hotkeyHelpController; -        if (hotkeyHelpController === null) { return; } -        for (const template of this._templates.getAllTemplates()) { -            hotkeyHelpController.setupNode(template.content); -        } -    } - -    preparePitchAccents() { -        if (this._termPitchAccentStaticTemplateIsSetup) { return; } -        this._termPitchAccentStaticTemplateIsSetup = true; -        const t = this._templates.instantiate('term-pitch-accent-static'); -        document.head.appendChild(t); -    } - -    createTermEntry(details) { -        const node = this._templates.instantiate('term-entry'); - -        const expressionsContainer = node.querySelector('.term-expression-list'); -        const reasonsContainer = node.querySelector('.term-reasons'); -        const pitchesContainer = node.querySelector('.term-pitch-accent-group-list'); -        const frequencyGroupListContainer = node.querySelector('.frequency-group-list'); -        const definitionsContainer = node.querySelector('.term-definition-list'); -        const termTagsContainer = node.querySelector('.term-tags'); - -        const {expressions, type, reasons, frequencies} = details; -        const definitions = (type === 'term' ? [details] : details.definitions); -        const merged = (type === 'termMerged' || type === 'termMergedByGlossary'); -        const pitches = DictionaryDataUtil.getPitchAccentInfos(details); -        const pitchCount = pitches.reduce((i, v) => i + v.pitches.length, 0); -        const groupedFrequencies = DictionaryDataUtil.groupTermFrequencies(frequencies); -        const termTags = DictionaryDataUtil.groupTermTags(details); - -        const uniqueExpressions = new Set(); -        const uniqueReadings = new Set(); -        for (const {expression, reading} of expressions) { -            uniqueExpressions.add(expression); -            uniqueReadings.add(reading); -        } - -        node.dataset.format = type; -        node.dataset.expressionMulti = `${merged}`; -        node.dataset.expressionCount = `${expressions.length}`; -        node.dataset.definitionCount = `${definitions.length}`; -        node.dataset.pitchAccentDictionaryCount = `${pitches.length}`; -        node.dataset.pitchAccentCount = `${pitchCount}`; -        node.dataset.uniqueExpressionCount = `${uniqueExpressions.size}`; -        node.dataset.uniqueReadingCount = `${uniqueReadings.size}`; -        node.dataset.frequencyCount = `${frequencies.length}`; -        node.dataset.groupedFrequencyCount = `${groupedFrequencies.length}`; - -        this._appendMultiple(expressionsContainer, this._createTermExpression.bind(this), expressions); -        this._appendMultiple(reasonsContainer, this._createTermReason.bind(this), reasons); -        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); - -        // Add definitions -        const dictionaryTag = this._createDictionaryTag(null); -        for (let i = 0, ii = definitions.length; i < ii; ++i) { -            const definition = definitions[i]; -            const {dictionary} = definition; - -            if (dictionaryTag.dictionary === dictionary) { -                dictionaryTag.redundant = true; -            } else { -                dictionaryTag.redundant = false; -                dictionaryTag.dictionary = dictionary; -                dictionaryTag.name = dictionary; -            } - -            const node2 = this._createTermDefinitionItem(definition, dictionaryTag); -            node2.dataset.index = `${i}`; -            definitionsContainer.appendChild(node2); -        } -        definitionsContainer.dataset.count = `${definitions.length}`; - -        return node; -    } - -    createKanjiEntry(details) { -        const node = this._templates.instantiate('kanji-entry'); - -        const glyphContainer = node.querySelector('.kanji-glyph'); -        const frequencyGroupListContainer = node.querySelector('.frequency-group-list'); -        const tagContainer = node.querySelector('.tags'); -        const glossaryContainer = 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'); -        const classificationsContainer = node.querySelector('.kanji-classifications'); -        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); - -        const dictionaryTag = this._createDictionaryTag(details.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.glossary); -        this._appendMultiple(chineseReadingsContainer, this._createKanjiReading.bind(this), details.onyomi); -        this._appendMultiple(japaneseReadingsContainer, this._createKanjiReading.bind(this), details.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)); - -        return node; -    } - -    createEmptyFooterNotification() { -        return this._templates.instantiate('footer-notification'); -    } - -    createTagFooterNotificationDetails(tagNode) { -        const node = this._templates.instantiateFragment('footer-notification-tag-details'); - -        const details = tagNode.dataset.details; -        this._setTextContent(node.querySelector('.tag-details'), details); - -        let disambiguation = null; -        try { -            let a = tagNode.dataset.disambiguation; -            if (typeof a !== 'undefined') { -                a = JSON.parse(a); -                if (Array.isArray(a)) { disambiguation = a; } -            } -        } catch (e) { -            // NOP -        } - -        if (disambiguation !== null) { -            const disambiguationContainer = node.querySelector('.tag-details-disambiguation-list'); -            const copyAttributes = ['totalExpressionCount', 'matchedExpressionCount', 'unmatchedExpressionCount']; -            for (const attribute of copyAttributes) { -                const value = tagNode.dataset[attribute]; -                if (typeof value === 'undefined') { continue; } -                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) => { -                    container.appendChild(document.createTextNode(text)); -                }); -                disambiguationContainer.appendChild(disambiguationItem); -            } -        } - -        return node; -    } - -    createAnkiNoteErrorsNotificationContent(errors) { -        const content = this._templates.instantiate('footer-notification-anki-errors-content'); - -        const header = content.querySelector('.anki-note-error-header'); -        this._setTextContent(header, (errors.length === 1 ? 'An error occurred:' : `${errors.length} errors occurred:`), 'en'); - -        const list = content.querySelector('.anki-note-error-list'); -        for (const error of errors) { -            const div = document.createElement('li'); -            div.className = 'anki-note-error-message'; -            this._setTextContent(div, isObject(error) && typeof error.message === 'string' ? error.message : `${error}`); -            list.appendChild(div); -        } - -        return content; -    } - -    createProfileListItem() { -        return this._templates.instantiate('profile-list-item'); -    } - -    createPopupMenu(name) { -        return this._templates.instantiate(`${name}-popup-menu`); -    } - -    // Private - -    _createTermExpression(details) { -        const {termFrequency, furiganaSegments, expression, reading, termTags} = details; - -        const searchQueries = []; -        if (expression) { searchQueries.push(expression); } -        if (reading) { searchQueries.push(reading); } - -        const node = this._templates.instantiate('term-expression'); - -        const expressionContainer = node.querySelector('.term-expression-text'); -        const tagContainer = node.querySelector('.tags'); - -        node.dataset.readingIsSame = `${!reading || reading === expression}`; -        node.dataset.frequency = termFrequency; - -        expressionContainer.lang = 'ja'; - -        this._appendFurigana(expressionContainer, furiganaSegments, this._appendKanjiLinks.bind(this)); -        this._appendMultiple(tagContainer, this._createTag.bind(this), termTags); -        this._appendMultiple(tagContainer, this._createSearchTag.bind(this), searchQueries); - -        return node; -    } - -    _createTermReason(reason) { -        const fragment = this._templates.instantiateFragment('term-reason'); -        const node = fragment.querySelector('.term-reason'); -        this._setTextContent(node, reason); -        node.dataset.reason = reason; -        return fragment; -    } - -    _createTermDefinitionItem(details, dictionaryTag) { -        const node = this._templates.instantiate('term-definition-item'); - -        const tagListContainer = node.querySelector('.term-definition-tag-list'); -        const onlyListContainer = node.querySelector('.term-definition-disambiguation-list'); -        const glossaryContainer = node.querySelector('.term-glossary-list'); - -        const {dictionary, definitionTags} = details; -        node.dataset.dictionary = dictionary; - -        this._appendMultiple(tagListContainer, this._createTag.bind(this), [...definitionTags, dictionaryTag]); -        this._appendMultiple(onlyListContainer, this._createTermDisambiguation.bind(this), details.only); -        this._appendMultiple(glossaryContainer, this._createTermGlossaryItem.bind(this), details.glossary, dictionary); - -        return node; -    } - -    _createTermGlossaryItem(glossary, dictionary) { -        if (typeof glossary === 'string') { -            return this._createTermGlossaryItemText(glossary); -        } else if (typeof glossary === 'object' && glossary !== null) { -            switch (glossary.type) { -                case 'image': -                    return this._createTermGlossaryItemImage(glossary, dictionary); -            } -        } - -        return null; -    } - -    _createTermGlossaryItemText(glossary) { -        const node = this._templates.instantiate('term-glossary-item'); -        const container = node.querySelector('.term-glossary'); -        this._setTextContent(container, glossary); -        return node; -    } - -    _createTermGlossaryItemImage(data, dictionary) { -        const {path, width, height, preferredWidth, preferredHeight, title, description, pixelated} = data; - -        const usedWidth = ( -            typeof preferredWidth === 'number' ? -            preferredWidth : -            width -        ); -        const aspectRatio = ( -            typeof preferredWidth === 'number' && -            typeof preferredHeight === 'number' ? -            preferredWidth / preferredHeight : -            width / height -        ); - -        const node = this._templates.instantiate('term-glossary-item-image'); -        node.dataset.path = path; -        node.dataset.dictionary = dictionary; -        node.dataset.imageLoadState = 'not-loaded'; - -        const imageContainer = node.querySelector('.term-glossary-image-container'); -        imageContainer.style.width = `${usedWidth}em`; -        if (typeof title === 'string') { -            imageContainer.title = title; -        } - -        const aspectRatioSizer = node.querySelector('.term-glossary-image-aspect-ratio-sizer'); -        aspectRatioSizer.style.paddingTop = `${aspectRatio * 100.0}%`; - -        const image = node.querySelector('img.term-glossary-image'); -        const imageLink = node.querySelector('.term-glossary-image-link'); -        image.dataset.pixelated = `${pixelated === true}`; - -        if (this._mediaLoader !== null) { -            this._mediaLoader.loadMedia( -                path, -                dictionary, -                (url) => this._setImageData(node, image, imageLink, url, false), -                () => this._setImageData(node, image, imageLink, null, true) -            ); -        } - -        if (typeof description === 'string') { -            const container = node.querySelector('.term-glossary-image-description'); -            this._setTextContent(container, description); -        } - -        return node; -    } - -    _setImageData(container, image, imageLink, url, unloaded) { -        if (url !== null) { -            image.src = url; -            imageLink.href = url; -            container.dataset.imageLoadState = 'loaded'; -        } else { -            image.removeAttribute('src'); -            imageLink.removeAttribute('href'); -            container.dataset.imageLoadState = unloaded ? 'unloaded' : 'load-error'; -        } -    } - -    _createTermDisambiguation(disambiguation) { -        const node = this._templates.instantiate('term-definition-disambiguation'); -        node.dataset.term = disambiguation; -        this._setTextContent(node, disambiguation, 'ja'); -        return node; -    } - -    _createKanjiLink(character) { -        const node = document.createElement('a'); -        node.className = 'kanji-link'; -        this._setTextContent(node, character, 'ja'); -        return node; -    } - -    _createKanjiGlossaryItem(glossary) { -        const node = this._templates.instantiate('kanji-glossary-item'); -        const container = node.querySelector('.kanji-glossary'); -        this._setTextContent(container, glossary); -        return node; -    } - -    _createKanjiReading(reading) { -        const node = this._templates.instantiate('kanji-reading'); -        this._setTextContent(node, reading, 'ja'); -        return node; -    } - -    _createKanjiInfoTable(details) { -        const node = this._templates.instantiate('kanji-info-table'); -        const container = node.querySelector('.kanji-info-table-body'); - -        const count = this._appendMultiple(container, this._createKanjiInfoTableItem.bind(this), details); -        if (count === 0) { -            const n = this._createKanjiInfoTableItemEmpty(); -            container.appendChild(n); -        } - -        return node; -    } - -    _createKanjiInfoTableItem(details) { -        const node = this._templates.instantiate('kanji-info-table-item'); -        const nameNode = node.querySelector('.kanji-info-table-item-header'); -        const valueNode = node.querySelector('.kanji-info-table-item-value'); -        this._setTextContent(nameNode, details.notes || details.name); -        this._setTextContent(valueNode, details.value); -        return node; -    } - -    _createKanjiInfoTableItemEmpty() { -        return this._templates.instantiate('kanji-info-table-empty'); -    } - -    _createTag(details) { -        const node = this._templates.instantiate('tag'); - -        const inner = node.querySelector('.tag-inner'); - -        node.title = details.notes; -        this._setTextContent(inner, details.name); -        node.dataset.details = details.notes || details.name; -        node.dataset.category = details.category; -        if (details.redundant) { node.dataset.redundant = 'true'; } - -        return node; -    } - -    _createTermTag(details, totalExpressionCount) { -        const {tag, expressions} = details; -        const node = this._createTag(tag); -        node.dataset.disambiguation = `${JSON.stringify(expressions)}`; -        node.dataset.totalExpressionCount = `${totalExpressionCount}`; -        node.dataset.matchedExpressionCount = `${expressions.length}`; -        node.dataset.unmatchedExpressionCount = `${Math.max(0, totalExpressionCount - expressions.length)}`; -        return node; -    } - -    _createSearchTag(text) { -        return this._createTag({ -            notes: '', -            name: text, -            category: 'search', -            redundant: false -        }); -    } - -    _createPitches(details) { -        this.preparePitchAccents(); - -        const {dictionary, pitches} = details; - -        const node = this._templates.instantiate('term-pitch-accent-group'); -        node.dataset.dictionary = dictionary; -        node.dataset.pitchesMulti = 'true'; -        node.dataset.pitchesCount = `${pitches.length}`; - -        const tag = this._createTag({notes: '', name: dictionary, category: 'pitch-accent-dictionary'}); -        node.querySelector('.term-pitch-accent-group-tag-list').appendChild(tag); - -        let hasTags = false; -        for (const {tags} of pitches) { -            if (tags.length > 0) { -                hasTags = true; -                break; -            } -        } - -        const n = node.querySelector('.term-pitch-accent-list'); -        n.dataset.hasTags = `${hasTags}`; -        this._appendMultiple(n, this._createPitch.bind(this), pitches); - -        return node; -    } - -    _createPitch(details) { -        const jp = this._japaneseUtil; -        const {reading, position, tags, exclusiveExpressions, exclusiveReadings} = details; -        const morae = jp.getKanaMorae(reading); - -        const node = this._templates.instantiate('term-pitch-accent'); - -        node.dataset.pitchAccentPosition = `${position}`; -        node.dataset.tagCount = `${tags.length}`; - -        let n = node.querySelector('.term-pitch-accent-position'); -        this._setTextContent(n, `${position}`, ''); - -        n = node.querySelector('.term-pitch-accent-tag-list'); -        this._appendMultiple(n, this._createTag.bind(this), tags); - -        n = node.querySelector('.term-pitch-accent-disambiguation-list'); -        this._createPitchAccentDisambiguations(n, exclusiveExpressions, exclusiveReadings); - -        n = node.querySelector('.term-pitch-accent-characters'); -        for (let i = 0, ii = morae.length; i < ii; ++i) { -            const mora = morae[i]; -            const highPitch = jp.isMoraPitchHigh(i, position); -            const highPitchNext = jp.isMoraPitchHigh(i + 1, position); - -            const n1 = this._templates.instantiate('term-pitch-accent-character'); -            const n2 = n1.querySelector('.term-pitch-accent-character-inner'); - -            n1.dataset.position = `${i}`; -            n1.dataset.pitch = highPitch ? 'high' : 'low'; -            n1.dataset.pitchNext = highPitchNext ? 'high' : 'low'; -            this._setTextContent(n2, mora, 'ja'); - -            n.appendChild(n1); -        } - -        if (morae.length > 0) { -            this._populatePitchGraph(node.querySelector('.term-pitch-accent-graph'), position, morae); -        } - -        return node; -    } - -    _createPitchAccentDisambiguations(container, exclusiveExpressions, exclusiveReadings) { -        const templateName = 'term-pitch-accent-disambiguation'; -        for (const exclusiveExpression of exclusiveExpressions) { -            const node = this._templates.instantiate(templateName); -            node.dataset.type = 'expression'; -            this._setTextContent(node, exclusiveExpression, 'ja'); -            container.appendChild(node); -        } - -        for (const exclusiveReading of exclusiveReadings) { -            const node = this._templates.instantiate(templateName); -            node.dataset.type = 'reading'; -            this._setTextContent(node, exclusiveReading, 'ja'); -            container.appendChild(node); -        } - -        container.dataset.count = `${exclusiveExpressions.length + exclusiveReadings.length}`; -        container.dataset.expressionCount = `${exclusiveExpressions.length}`; -        container.dataset.readingCount = `${exclusiveReadings.length}`; -    } - -    _populatePitchGraph(svg, position, morae) { -        const jp = this._japaneseUtil; -        const svgns = svg.getAttribute('xmlns'); -        const ii = morae.length; -        svg.setAttribute('viewBox', `0 0 ${50 * (ii + 1)} 100`); - -        const pathPoints = []; -        for (let i = 0; i < ii; ++i) { -            const highPitch = jp.isMoraPitchHigh(i, position); -            const highPitchNext = jp.isMoraPitchHigh(i + 1, position); -            const graphic = (highPitch && !highPitchNext ? '#term-pitch-accent-graph-dot-downstep' : '#term-pitch-accent-graph-dot'); -            const x = `${i * 50 + 25}`; -            const y = highPitch ? '25' : '75'; -            const use = document.createElementNS(svgns, 'use'); -            use.setAttribute('href', graphic); -            use.setAttribute('x', x); -            use.setAttribute('y', y); -            svg.appendChild(use); -            pathPoints.push(`${x} ${y}`); -        } - -        let path = svg.querySelector('.term-pitch-accent-graph-line'); -        path.setAttribute('d', `M${pathPoints.join(' L')}`); - -        pathPoints.splice(0, ii - 1); -        { -            const highPitch = jp.isMoraPitchHigh(ii, position); -            const x = `${ii * 50 + 25}`; -            const y = highPitch ? '25' : '75'; -            const use = document.createElementNS(svgns, 'use'); -            use.setAttribute('href', '#term-pitch-accent-graph-triangle'); -            use.setAttribute('x', x); -            use.setAttribute('y', y); -            svg.appendChild(use); -            pathPoints.push(`${x} ${y}`); -        } - -        path = svg.querySelector('.term-pitch-accent-graph-line-tail'); -        path.setAttribute('d', `M${pathPoints.join(' L')}`); -    } - -    _createFrequencyGroup(details, kanji) { -        const {dictionary, frequencyData} = details; -        const node = this._templates.instantiate('frequency-group-item'); - -        const tagList = node.querySelector('.frequency-tag-list'); -        const tag = this._createTag({notes: '', name: dictionary, category: 'frequency'}); -        tagList.appendChild(tag); - -        const frequencyListContainer = node.querySelector('.frequency-list'); -        const createItem = (kanji ? this._createKanjiFrequency.bind(this) : this._createTermFrequency.bind(this)); -        this._appendMultiple(frequencyListContainer, createItem, frequencyData, dictionary); - -        node.dataset.count = `${frequencyData.length}`; - -        return node; -    } - -    _createTermFrequency(details, dictionary) { -        const {expression, reading, frequencies} = details; -        const node = this._templates.instantiate('term-frequency-item'); - -        const frequency = frequencies.join(', '); - -        this._setTextContent(node.querySelector('.frequency-disambiguation-expression'), expression, 'ja'); -        this._setTextContent(node.querySelector('.frequency-disambiguation-reading'), (reading !== null ? reading : ''), 'ja'); -        this._setTextContent(node.querySelector('.frequency-value'), frequency, 'ja'); - -        node.dataset.expression = expression; -        node.dataset.reading = reading; -        node.dataset.hasReading = `${reading !== null}`; -        node.dataset.readingIsSame = `${reading === expression}`; -        node.dataset.dictionary = dictionary; -        node.dataset.frequency = `${frequency}`; - -        return node; -    } - -    _createKanjiFrequency(details, dictionary) { -        const {character, frequencies} = details; -        const node = this._templates.instantiate('kanji-frequency-item'); - -        const frequency = frequencies.join(', '); - -        this._setTextContent(node.querySelector('.frequency-value'), frequency, 'ja'); - -        node.dataset.character = character; -        node.dataset.dictionary = dictionary; -        node.dataset.frequency = `${frequency}`; - -        return node; -    } - -    _appendKanjiLinks(container, text) { -        container.lang = 'ja'; -        const jp = this._japaneseUtil; -        let part = ''; -        for (const c of text) { -            if (jp.isCodePointKanji(c.codePointAt(0))) { -                if (part.length > 0) { -                    container.appendChild(document.createTextNode(part)); -                    part = ''; -                } - -                const link = this._createKanjiLink(c); -                container.appendChild(link); -            } else { -                part += c; -            } -        } -        if (part.length > 0) { -            container.appendChild(document.createTextNode(part)); -        } -    } - -    _appendMultiple(container, createItem, detailsArray, ...args) { -        let count = 0; -        const {ELEMENT_NODE} = Node; -        if (Array.isArray(detailsArray)) { -            for (const details of detailsArray) { -                const item = createItem(details, ...args); -                if (item === null) { continue; } -                container.appendChild(item); -                if (item.nodeType === ELEMENT_NODE) { -                    item.dataset.index = `${count}`; -                } -                ++count; -            } -        } - -        container.dataset.count = `${count}`; - -        return count; -    } - -    _appendFurigana(container, segments, addText) { -        for (const {text, furigana} of segments) { -            if (furigana) { -                const ruby = document.createElement('ruby'); -                const rt = document.createElement('rt'); -                addText(ruby, text); -                ruby.appendChild(rt); -                rt.appendChild(document.createTextNode(furigana)); -                container.appendChild(ruby); -            } else { -                addText(container, text); -            } -        } -    } - -    _createDictionaryTag(dictionary) { -        return { -            name: dictionary, -            category: 'dictionary', -            notes: '', -            order: 100, -            score: 0, -            dictionary, -            redundant: false -        }; -    } - -    _setTextContent(node, value, language) { -        node.textContent = value; -        if (typeof language === 'string') { -            node.lang = language; -        } else if (this._japaneseUtil.isStringPartiallyJapanese(value)) { -            node.lang = 'ja'; -        } -    } -} |