diff options
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/css/display.css | 75 | ||||
| -rw-r--r-- | ext/data/schemas/dictionary-term-bank-v3-schema.json | 10 | ||||
| -rw-r--r-- | ext/display-templates.html | 3 | ||||
| -rw-r--r-- | ext/js/display/display-generator.js | 44 | ||||
| -rw-r--r-- | ext/js/language/dictionary-importer.js | 7 | 
5 files changed, 87 insertions, 52 deletions
| diff --git a/ext/css/display.css b/ext/css/display.css index d9a2acd2..529e4249 100644 --- a/ext/css/display.css +++ b/ext/css/display.css @@ -1571,6 +1571,8 @@ button.definition-item-expansion-button:focus:focus-visible+.definition-item-con  .gloss-image-link {      cursor: inherit;      color: inherit; +    display: inline-block; +    position: relative;  }  .gloss-image-link[href]:hover {      cursor: pointer; @@ -1588,7 +1590,7 @@ button.definition-item-expansion-button:focus:focus-visible+.definition-item-con      white-space: normal;      color: var(--text-color-light3);  } -.gloss-item[data-has-image=true][data-image-load-state=load-error] .gloss-image-container-overlay::after { +.gloss-image-link[data-has-image=true][data-image-load-state=load-error] .gloss-image-container-overlay::after {      content: 'Image failed to load';      display: table-cell;      width: 100%; @@ -1599,15 +1601,17 @@ button.definition-item-expansion-button:focus:focus-visible+.definition-item-con  }  .gloss-image {      display: inline-block; +    vertical-align: top; +    object-fit: contain; +    border: none; +    outline: none; +} +.gloss-image-link[data-has-aspect-ratio=true] .gloss-image {      position: absolute;      left: 0;      top: 0;      width: 100%;      height: 100%; -    vertical-align: top; -    object-fit: contain; -    border: none; -    outline: none;  }  .gloss-image:not([src]) {      display: none; @@ -1619,13 +1623,15 @@ button.definition-item-expansion-button:focus:focus-visible+.definition-item-con      image-rendering: pixelated;      image-rendering: crisp-edges;  } -.gloss-image-aspect-ratio-sizer { -    content: ''; +.gloss-image-link[data-has-aspect-ratio=true] .gloss-image-aspect-ratio-sizer {      display: inline-block;      width: 0;      vertical-align: top;      font-size: 0;  } +.gloss-image-link-text { +    display: none; +}  .gloss-image-link-text::before {      content: '[';  } @@ -1633,9 +1639,38 @@ button.definition-item-expansion-button:focus:focus-visible+.definition-item-con      content: ']';  }  .gloss-image-description { +    display: block;      white-space: pre-line;  } +.gloss-image-link[data-collapsed=true] .gloss-image-container, +:root[data-glossary-layout-mode=compact] .gloss-image-link[data-collapsible=true] .gloss-image-container { +    display: none; +    position: absolute; +    left: 0; +    top: 100%; +    z-index: 1; +} +.entry:nth-last-of-type(1):not(:nth-of-type(1)) .gloss-image-link[data-collapsed=true] .gloss-image-container, +:root[data-glossary-layout-mode=compact] .entry:nth-last-of-type(1):not(:nth-of-type(1)) .gloss-image-link[data-collapsible=true] .gloss-image-container { +    bottom: 100%; +    top: auto; +} +.gloss-image-link[data-collapsed=true]:hover .gloss-image-container, +.gloss-image-link[data-collapsed=true]:focus .gloss-image-container, +:root[data-glossary-layout-mode=compact] .gloss-image-link[data-collapsible=true]:hover .gloss-image-container, +:root[data-glossary-layout-mode=compact] .gloss-image-link[data-collapsible=true]:focus .gloss-image-container { +    display: block; +} +.gloss-image-link[data-collapsed=true] .gloss-image-link-text, +:root[data-glossary-layout-mode=compact] .gloss-image-link[data-collapsible=true] .gloss-image-link-text { +    display: inline; +} +.gloss-image-link[data-collapsed=true]~.gloss-image-description, +:root[data-glossary-layout-mode=compact] .gloss-image-description { +    display: inline; +} +  /* Kanji */  .kanji-glyph-container { @@ -2110,32 +2145,6 @@ button.footer-notification-close-button {      color: var(--text-color-light3);  } -:root[data-glossary-layout-mode=compact] .gloss-image-container { -    display: none; -    position: absolute; -    left: 0; -    top: 100%; -    z-index: 1; -} -:root[data-glossary-layout-mode=compact] .entry:nth-last-of-type(1):not(:nth-of-type(1)) .gloss-image-container { -    bottom: 100%; -    top: auto; -} -:root[data-glossary-layout-mode=compact] .gloss-image-link { -    position: relative; -    display: inline-block; -} -:root[data-glossary-layout-mode=compact] .gloss-image-link:hover .gloss-image-container, -:root[data-glossary-layout-mode=compact] .gloss-image-link:focus .gloss-image-container { -    display: block; -} -:root:not([data-glossary-layout-mode=compact]) .gloss-image-link-text { -    display: none; -} -:root:not([data-glossary-layout-mode=compact]) .gloss-image-description { -    display: block; -} -  :root[data-popup-display-mode=full-width] .frame-resizer-container {      display: none;  } diff --git a/ext/data/schemas/dictionary-term-bank-v3-schema.json b/ext/data/schemas/dictionary-term-bank-v3-schema.json index 4790e561..2289dfd6 100644 --- a/ext/data/schemas/dictionary-term-bank-v3-schema.json +++ b/ext/data/schemas/dictionary-term-bank-v3-schema.json @@ -104,6 +104,16 @@                                              "type": "boolean",                                              "description": "Whether or not the image should appear pixelated at sizes larger than the image's native resolution.",                                              "default": false +                                        }, +                                        "collapsed": { +                                            "type": "boolean", +                                            "description": "Whether or not the image is collapsed by default.", +                                            "default": false +                                        }, +                                        "collapsible": { +                                            "type": "boolean", +                                            "description": "Whether or not the image can be collapsed.", +                                            "default": true                                          }                                      }                                  } diff --git a/ext/display-templates.html b/ext/display-templates.html index 3262c15a..61d55638 100644 --- a/ext/display-templates.html +++ b/ext/display-templates.html @@ -57,7 +57,8 @@  </li></template>  <template id="definition-disambiguation-template"><span class="definition-disambiguation"></span></template>  <template id="gloss-item-template"><li class="gloss-item click-scannable"><span class="gloss-separator"> </span><span class="gloss-content"></span></li></template> -<template id="gloss-item-image-template"><li class="gloss-item click-scannable" data-has-image="true"><span class="gloss-separator"> </span><span class="gloss-content"><a class="gloss-image-link" target="_blank" rel="noreferrer noopener"><span class="gloss-image-container"><span class="gloss-image-aspect-ratio-sizer"></span><img class="gloss-image" alt=""><span class="gloss-image-container-overlay"></span></span><span class="gloss-image-link-text">Image</span></a> <span class="gloss-image-description"></span></span></li></template> +<template id="gloss-item-image-template"><a class="gloss-image-link" target="_blank" rel="noreferrer noopener"><span class="gloss-image-container"><span class="gloss-image-aspect-ratio-sizer"></span><img class="gloss-image" alt=""><span class="gloss-image-container-overlay"></span></span><span class="gloss-image-link-text">Image</span></a></template> +<template id="gloss-item-image-description-template"> <span class="gloss-image-description"></span></template>  <template id="inflection-template"><span class="inflection"></span><span class="inflection-separator"> </span></template>  <!-- Frequency templates --> diff --git a/ext/js/display/display-generator.js b/ext/js/display/display-generator.js index eb9c122d..299d730b 100644 --- a/ext/js/display/display-generator.js +++ b/ext/js/display/display-generator.js @@ -309,7 +309,26 @@ class DisplayGenerator {      }      _createTermDefinitionEntryImage(data, dictionary) { -        const {path, width, height, preferredWidth, preferredHeight, title, description, pixelated} = data; +        const {description} = data; + +        const node = this._templates.instantiate('gloss-item'); + +        const contentContainer = node.querySelector('.gloss-content'); +        const image = this._createDefinitionImage(data, dictionary); +        contentContainer.appendChild(image); + +        if (typeof description === 'string') { +            const fragment = this._templates.instantiateFragment('gloss-item-image-description'); +            const container = fragment.querySelector('.gloss-image-description'); +            this._setMultilineTextContent(container, description); +            contentContainer.appendChild(fragment); +        } + +        return node; +    } + +    _createDefinitionImage(data, dictionary) { +        const {path, width, height, preferredWidth, preferredHeight, title, pixelated, collapsed, collapsible} = data;          const usedWidth = (              typeof preferredWidth === 'number' ? @@ -327,6 +346,9 @@ class DisplayGenerator {          node.dataset.path = path;          node.dataset.dictionary = dictionary;          node.dataset.imageLoadState = 'not-loaded'; +        node.dataset.hasAspectRatio = 'true'; +        node.dataset.collapsed = typeof collapsed === 'boolean' ? `${collapsed}` : 'false'; +        node.dataset.collapsible = typeof collapsible === 'boolean' ? `${collapsible}` : 'true';          const imageContainer = node.querySelector('.gloss-image-container');          imageContainer.style.width = `${usedWidth}em`; @@ -338,35 +360,29 @@ class DisplayGenerator {          aspectRatioSizer.style.paddingTop = `${aspectRatio * 100.0}%`;          const image = node.querySelector('img.gloss-image'); -        const imageLink = node.querySelector('.gloss-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) +                (url) => this._setImageData(node, image, url, false), +                () => this._setImageData(node, image, null, true)              );          } -        if (typeof description === 'string') { -            const container = node.querySelector('.gloss-image-description'); -            this._setMultilineTextContent(container, description); -        } -          return node;      } -    _setImageData(container, image, imageLink, url, unloaded) { +    _setImageData(node, image, url, unloaded) {          if (url !== null) {              image.src = url; -            imageLink.href = url; -            container.dataset.imageLoadState = 'loaded'; +            node.href = url; +            node.dataset.imageLoadState = 'loaded';          } else {              image.removeAttribute('src'); -            imageLink.removeAttribute('href'); -            container.dataset.imageLoadState = unloaded ? 'unloaded' : 'load-error'; +            node.removeAttribute('href'); +            node.dataset.imageLoadState = unloaded ? 'unloaded' : 'load-error';          }      } diff --git a/ext/js/language/dictionary-importer.js b/ext/js/language/dictionary-importer.js index e060b3b1..051375a0 100644 --- a/ext/js/language/dictionary-importer.js +++ b/ext/js/language/dictionary-importer.js @@ -306,10 +306,8 @@ class DictionaryImporter {      }      async _formatDictionaryTermGlossaryImage(data, context, entry) { -        const {path, width: preferredWidth, height: preferredHeight, title, description, pixelated} = data; +        const {path, width: preferredWidth, height: preferredHeight, title, description, pixelated, collapsed, collapsible} = data;          const {width, height} = await this._getImageMedia(path, context, entry); - -        // Create new data          const newData = {              type: 'image',              path, @@ -321,7 +319,8 @@ class DictionaryImporter {          if (typeof title === 'string') { newData.title = title; }          if (typeof description === 'string') { newData.description = description; }          if (typeof pixelated === 'boolean') { newData.pixelated = pixelated; } - +        if (typeof collapsed === 'boolean') { newData.collapsed = collapsed; } +        if (typeof collapsible === 'boolean') { newData.collapsible = collapsible; }          return newData;      } |