diff options
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/mixed/css/display.css | 33 | ||||
| -rw-r--r-- | ext/mixed/display-templates.html | 9 | ||||
| -rw-r--r-- | ext/mixed/js/dictionary-data-util.js | 37 | ||||
| -rw-r--r-- | ext/mixed/js/display-generator.js | 52 | ||||
| -rw-r--r-- | ext/mixed/js/display-notification.js | 9 | ||||
| -rw-r--r-- | ext/mixed/js/display.js | 7 | 
6 files changed, 137 insertions, 10 deletions
| diff --git a/ext/mixed/css/display.css b/ext/mixed/css/display.css index fd320904..e33ef802 100644 --- a/ext/mixed/css/display.css +++ b/ext/mixed/css/display.css @@ -699,6 +699,26 @@ button.action-button[data-icon=source-term]::before {  .tag-inner {      display: block;  } +.tag-details-disambiguation-list::before { +    content: 'Only: '; +} +.tag-details-disambiguation-list ruby>rt { +    display: inline; +    font-size: 1em; +} +.tag-details-disambiguation-list ruby>rt::before { +    content: '('; +} +.tag-details-disambiguation-list ruby>rt::after { +    content: ')'; +} +.tag-details-disambiguation-list[data-unmatched-expression-count='0'], +.tag-details-disambiguation-list:not([data-unmatched-expression-count]) { +    display: none; +} +.tag-details-disambiguation:not(:last-child)::after { +    content: ', '; +}  /* Entries */ @@ -755,13 +775,13 @@ button.action-button[data-icon=source-term]::before {      display: inline;  }  .term-expression { -    display: inline; +    display: inline-block;  }  .term-expression-details {      display: inline;  }  .term-expression-details>.tags { -    display: inline; +    display: none;  }  .term-expression-details>.frequencies {      display: none; @@ -769,6 +789,15 @@ button.action-button[data-icon=source-term]::before {  .term-expression-list>.term-expression:not(:last-of-type)>.term-expression-text-container>.term-expression-text::after {      content: '\3001';  } +.term-details { +    display: inline; +} +.term-tags { +    display: inline; +} +.entry[data-expression-multi=true] .term-details { +    display: block; +}  /* Entry indicator */ diff --git a/ext/mixed/display-templates.html b/ext/mixed/display-templates.html index ac42e138..83232b4c 100644 --- a/ext/mixed/display-templates.html +++ b/ext/mixed/display-templates.html @@ -15,7 +15,10 @@                  </div>                  <div class="term-expression-list"></div>              </div> -            <div class="term-reasons"></div> +            <div class="term-details"> +                <div class="term-tags tag-list"></div> +                <div class="term-reasons"></div> +            </div>          </div>      </div>      <div class="entry-body"> @@ -137,6 +140,10 @@      <div class="footer-notification-body"></div>      <button class="footer-notification-close-button"><span class="footer-notification-close-button-icon icon" data-icon="cross"></span></button>  </div></template> +<template id="footer-notification-tag-details-template" data-remove-whitespace-text="true"> +    <div class="tag-details"></div> +    <div class="tag-details-disambiguation-list"></div> +</div></template>  <template id="profile-list-item-template"><label class="profile-list-item">      <div class="profile-list-item-selection"><label class="radio"><input type="radio" class="profile-entry-is-default-radio" name="profile-entry-default-radio"><span class="radio-body"><span class="radio-border"></span><span class="radio-dot"></span></span></label></div>      <div class="profile-list-item-name"></div> diff --git a/ext/mixed/js/dictionary-data-util.js b/ext/mixed/js/dictionary-data-util.js index 1e82ef63..70a51e89 100644 --- a/ext/mixed/js/dictionary-data-util.js +++ b/ext/mixed/js/dictionary-data-util.js @@ -16,6 +16,37 @@   */  class DictionaryDataUtil { +    static groupTermTags(definition) { +        const {expressions} = definition; +        const expressionsLength = expressions.length; +        const uniqueCheck = (expressionsLength > 1); +        const resultsMap = new Map(); +        const results = []; +        for (let i = 0; i < expressionsLength; ++i) { +            const {termTags, expression, reading} = expressions[i]; +            for (const tag of termTags) { +                if (uniqueCheck) { +                    const {name, category, notes, dictionary} = tag; +                    const key = this._createMapKey([name, category, notes, dictionary]); +                    const index = resultsMap.get(key); +                    if (typeof index !== 'undefined') { +                        const existingItem = results[index]; +                        existingItem.expressions.push({index: i, expression, reading}); +                        continue; +                    } +                    resultsMap.set(key, results.length); +                } + +                const item = { +                    tag, +                    expressions: [{index: i, expression, reading}] +                }; +                results.push(item); +            } +        } +        return results; +    } +      static groupTermFrequencies(frequencies) {          const map1 = new Map();          for (const {dictionary, expression, reading, hasReading, frequency} of frequencies) { @@ -26,7 +57,7 @@ class DictionaryDataUtil {              }              const readingKey = hasReading ? reading : null; -            const key = JSON.stringify([expression, readingKey], null, 0); +            const key = this._createMapKey([expression, readingKey]);              let frequencyData = map2.get(key);              if (typeof frequencyData === 'undefined') {                  frequencyData = {expression, reading: readingKey, frequencies: new Set()}; @@ -179,4 +210,8 @@ class DictionaryDataUtil {          }          return result;      } + +    static _createMapKey(array) { +        return JSON.stringify(array); +    }  } diff --git a/ext/mixed/js/display-generator.js b/ext/mixed/js/display-generator.js index a47a65ee..b48ddadc 100644 --- a/ext/mixed/js/display-generator.js +++ b/ext/mixed/js/display-generator.js @@ -49,6 +49,7 @@ class DisplayGenerator {          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); @@ -56,6 +57,7 @@ class DisplayGenerator {          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(); @@ -80,6 +82,7 @@ class DisplayGenerator {          this._appendMultiple(frequencyGroupListContainer, this._createFrequencyGroup.bind(this), groupedFrequencies, false);          this._appendMultiple(pitchesContainer, this._createPitches.bind(this), pitches);          this._appendMultiple(definitionsContainer, this._createTermDefinitionItem.bind(this), definitions); +        this._appendMultiple(termTagsContainer, this._createTermTag.bind(this), termTags, expressions.length);          return node;      } @@ -119,6 +122,45 @@ class DisplayGenerator {          return this._templates.instantiate('footer-notification');      } +    createTagFooterNotificationDetails(tagNode) { +        const node = this._templates.instantiateFragment('footer-notification-tag-details'); + +        const details = tagNode.dataset.details; +        node.querySelector('.tag-details').textContent = 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'; +                this._appendFurigana(disambiguationItem, segments, (container, text) => { +                    container.appendChild(document.createTextNode(text)); +                }); +                disambiguationContainer.appendChild(disambiguationItem); +            } +        } + +        return node; +    } +      createProfileListItem() {          return this._templates.instantiate('profile-list-item');      } @@ -321,6 +363,16 @@ class DisplayGenerator {          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: '', diff --git a/ext/mixed/js/display-notification.js b/ext/mixed/js/display-notification.js index 0e79f1c6..8b6325d0 100644 --- a/ext/mixed/js/display-notification.js +++ b/ext/mixed/js/display-notification.js @@ -58,8 +58,13 @@ class DisplayNotification {          }      } -    setContent(text) { -        this._body.textContent = text; +    setContent(value) { +        if (typeof value === 'string') { +            this._body.textContent = value; +        } else { +            this._body.textContent = ''; +            this._body.appendChild(value); +        }      }      isClosing() { diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index c36a0c1c..e4433925 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -837,18 +837,17 @@ class Display extends EventDispatcher {      }      _onTagClick(e) { -        const node = e.currentTarget; -        const {dataset: {details}} = node; -        this._showTagNotification(details); +        this._showTagNotification(e.currentTarget);      } -    _showTagNotification(content) { +    _showTagNotification(tagNode) {          if (this._tagNotification === null) {              const node = this._displayGenerator.createEmptyFooterNotification();              node.classList.add('click-scannable');              this._tagNotification = new DisplayNotification(this._tagNotificationContainer, node);          } +        const content = this._displayGenerator.createTagFooterNotificationDetails(tagNode);          this._tagNotification.setContent(content);          this._tagNotification.open();      } |