diff options
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/css/display.css | 26 | ||||
| -rw-r--r-- | ext/css/material.css | 2 | ||||
| -rw-r--r-- | ext/data/schemas/dictionary-term-bank-v3-schema.json | 107 | ||||
| -rw-r--r-- | ext/js/display/display-generator.js | 71 | 
4 files changed, 197 insertions, 9 deletions
| diff --git a/ext/css/display.css b/ext/css/display.css index 45658f19..e1efb223 100644 --- a/ext/css/display.css +++ b/ext/css/display.css @@ -1726,6 +1726,32 @@ button.definition-item-expansion-button:focus:focus-visible+.definition-item-con  } +/* Structured content glossary styles */ +.gloss-sc-table-container { +    display: block; +} +.gloss-sc-table { +    table-layout: auto; +    border-collapse: collapse; +    border-spacing: 0; +} +.gloss-sc-tbody { +    background-color: transparent; +} +.gloss-sc-thead, +.gloss-sc-tfoot, +.gloss-sc-th { +    font-weight: bold; +    background-color: var(--background-color-dark1); +} +.gloss-sc-th, +.gloss-sc-td { +    border: calc(1em / var(--font-size-no-units)) solid var(--text-color-light2); +    padding: 0.25em; +    vertical-align: top; +} + +  /* Kanji */  .kanji-glyph-container {      display: block; diff --git a/ext/css/material.css b/ext/css/material.css index dd135065..b19b0b0f 100644 --- a/ext/css/material.css +++ b/ext/css/material.css @@ -69,6 +69,7 @@      --text-color-light4: #888888;      --background-color: #f8f9fa;      --background-color-light: #ffffff; +    --background-color-dark1: #eeeeee;      --shadow-color: rgba(0, 0, 0, 0.185);      --shadow-color-off: rgba(0, 0, 0, 0); @@ -128,6 +129,7 @@      --text-color-light4: #777777;      --background-color: #1e1e1e;      --background-color-light: #0a0a0a; +    --background-color-dark1: #333333;      --shadow-color: rgba(255, 255, 255, 0.185);      --shadow-color-off: rgba(255, 255, 255, 0); diff --git a/ext/data/schemas/dictionary-term-bank-v3-schema.json b/ext/data/schemas/dictionary-term-bank-v3-schema.json index fd3f3844..af4494ff 100644 --- a/ext/data/schemas/dictionary-term-bank-v3-schema.json +++ b/ext/data/schemas/dictionary-term-bank-v3-schema.json @@ -19,6 +19,20 @@                      "oneOf": [                          {                              "type": "object", +                            "description": "Empty tags.", +                            "required": [ +                                "tag" +                            ], +                            "additionalProperties": false, +                            "properties": { +                                "tag": { +                                    "type": "string", +                                    "enum": ["br"] +                                } +                            } +                        }, +                        { +                            "type": "object",                              "description": "Generic container tags.",                              "required": [                                  "tag" @@ -27,10 +41,58 @@                              "properties": {                                  "tag": {                                      "type": "string", -                                    "enum": ["ruby", "rt", "rp"] +                                    "enum": ["ruby", "rt", "rp", "table", "thead", "tbody", "tfoot", "tr"] +                                }, +                                "content": { +                                    "$ref": "#/definitions/structuredContent" +                                } +                            } +                        }, +                        { +                            "type": "object", +                            "description": "Table tags.", +                            "required": [ +                                "tag" +                            ], +                            "additionalProperties": false, +                            "properties": { +                                "tag": { +                                    "type": "string", +                                    "enum": ["td", "th"] +                                }, +                                "content": { +                                    "$ref": "#/definitions/structuredContent" +                                }, +                                "colSpan": { +                                    "type": "integer", +                                    "minimum": 1 +                                }, +                                "rowSpan": { +                                    "type": "integer", +                                    "minimum": 1 +                                }, +                                "style": { +                                    "$ref": "#/definitions/structuredContentStyle" +                                } +                            } +                        }, +                        { +                            "type": "object", +                            "description": "Container tags supporting configurable styles.", +                            "required": [ +                                "tag" +                            ], +                            "additionalProperties": false, +                            "properties": { +                                "tag": { +                                    "type": "string", +                                    "enum": ["span", "div"]                                  },                                  "content": {                                      "$ref": "#/definitions/structuredContent" +                                }, +                                "style": { +                                    "$ref": "#/definitions/structuredContentStyle"                                  }                              }                          }, @@ -112,6 +174,49 @@                      ]                  }              ] +        }, +        "structuredContentStyle": { +            "type": "object", +            "additionalProperties": false, +            "properties": { +                "fontStyle": { +                    "type": "string", +                    "enum": ["normal", "italic"], +                    "default": "normal" +                }, +                "fontWeight": { +                    "type": "string", +                    "enum": ["normal", "bold"], +                    "default": "normal" +                }, +                "fontSize": { +                    "type": "string", +                    "enum": ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "xxx-large"], +                    "default": "medium" +                }, +                "textDecorationLine": { +                    "oneOf": [ +                        { +                            "type": "string", +                            "enum": ["none", "underline", "overline", "line-through"], +                            "default": "none" +                        }, +                        { +                            "type": "array", +                            "items": { +                                "type": "string", +                                "enum": ["underline", "overline", "line-through"], +                                "default": "none" +                            } +                        } +                    ] +                }, +                "verticalAlign": { +                    "type": "string", +                    "enum": ["baseline", "sub", "super", "text-top", "text-bottom", "middle", "top", "bottom"], +                    "default": "baseline" +                } +            }          }      },      "type": "array", diff --git a/ext/js/display/display-generator.js b/ext/js/display/display-generator.js index 6a5b26f1..7de65f78 100644 --- a/ext/js/display/display-generator.js +++ b/ext/js/display/display-generator.js @@ -442,23 +442,78 @@ class DisplayGenerator {          }          const {tag} = content;          switch (tag) { +            case 'br': +                return this._createStructuredContentElement(tag, content, dictionary, 'simple', false, false);              case 'ruby':              case 'rt':              case 'rp': -            { -                const node = document.createElement(tag); -                const child = this._createStructuredContent(content.content, dictionary); -                if (child !== null) { -                    node.appendChild(child); -                } -                return node; -            } +                return this._createStructuredContentElement(tag, content, dictionary, 'simple', true, false); +            case 'table': +                return this._createStructuredContentTableElement(tag, content, dictionary); +            case 'thead': +            case 'tbody': +            case 'tfoot': +            case 'tr': +                return this._createStructuredContentElement(tag, content, dictionary, 'table', true, false); +            case 'th': +            case 'td': +                return this._createStructuredContentElement(tag, content, dictionary, 'table-cell', true, true); +            case 'div': +            case 'span': +                return this._createStructuredContentElement(tag, content, dictionary, 'simple', true, true);              case 'img':                  return this._createDefinitionImage(content, dictionary);          }          return null;      } +    _createStructuredContentTableElement(tag, content, dictionary) { +        const container = document.createElement('div'); +        container.classList = 'gloss-sc-table-container'; +        const table = this._createStructuredContentElement(tag, content, dictionary, 'table', true, false); +        container.appendChild(table); +        return container; +    } + +    _createStructuredContentElement(tag, content, dictionary, type, hasChildren, hasStyle) { +        const node = document.createElement(tag); +        node.className = `gloss-sc-${tag}`; +        switch (type) { +            case 'table-cell': +                { +                    const {colSpan, rowSpan} = content; +                    if (typeof colSpan === 'number') { node.colSpan = colSpan; } +                    if (typeof rowSpan === 'number') { node.rowSpan = rowSpan; } +                } +                break; +        } +        if (hasStyle) { +            const {style} = content; +            if (typeof style === 'object' && style !== null) { +                this._setStructuredContentElementStyle(node, style); +            } +        } +        if (hasChildren) { +            const child = this._createStructuredContent(content.content, dictionary); +            if (child !== null) { node.appendChild(child); } +        } +        return node; +    } + +    _setStructuredContentElementStyle(node, contentStyle) { +        const {style} = node; +        const {fontStyle, fontWeight, fontSize, textDecorationLine, verticalAlign} = contentStyle; +        if (typeof fontStyle === 'string') { style.fontStyle = fontStyle; } +        if (typeof fontWeight === 'string') { style.fontWeight = fontWeight; } +        if (typeof fontSize === 'string') { style.fontSize = fontSize; } +        if (typeof verticalAlign === 'string') { style.verticalAlign = verticalAlign; } +        if (typeof textDecorationLine === 'string') { +            style.textDecoration = textDecorationLine; +        } else if (Array.isArray(textDecorationLine)) { +            style.textDecoration = textDecorationLine.join(' '); +        } +    } +      _createTermDisambiguation(disambiguation) {          const node = this._templates.instantiate('definition-disambiguation');          node.dataset.term = disambiguation; |