From 93cdbe4b718f9f7a2cd0d6efc545ec51d049812f Mon Sep 17 00:00:00 2001 From: Stephen Kraus <8003332+stephenmk@users.noreply.github.com> Date: Fri, 22 Dec 2023 19:17:17 -0600 Subject: Add support for alt attribute on structured content images (#359) * Add support for alt attribute on structured content images * Add new `alt` property for structured content images * Update test script with new media file count --------- Co-authored-by: stephenmk --- ext/css/structured-content.css | 2 +- ext/data/schemas/dictionary-term-bank-v3-schema.json | 8 ++++++++ ext/data/structured-content-style.json | 2 +- ext/js/display/sandbox/structured-content-generator.js | 3 ++- ext/js/language/dictionary-importer.js | 2 ++ test/data/dictionaries/valid-dictionary1/aosaba_auto.png | Bin 0 -> 1699 bytes test/data/dictionaries/valid-dictionary1/aosaba_mono.png | Bin 0 -> 1807 bytes .../data/dictionaries/valid-dictionary1/term_bank_1.json | 9 ++++++++- test/database.test.js | 12 ++++++------ types/ext/structured-content.d.ts | 4 ++++ 10 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 test/data/dictionaries/valid-dictionary1/aosaba_auto.png create mode 100644 test/data/dictionaries/valid-dictionary1/aosaba_mono.png diff --git a/ext/css/structured-content.css b/ext/css/structured-content.css index 1d4677b5..50fcad02 100644 --- a/ext/css/structured-content.css +++ b/ext/css/structured-content.css @@ -147,7 +147,7 @@ } .gloss-image-link[data-appearance=monochrome] .gloss-image { - visibility: hidden; + opacity: 0; } .gloss-image-link:not([data-appearance=monochrome]) .gloss-image-background { 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 2fc39c2e..547bde49 100644 --- a/ext/data/schemas/dictionary-term-bank-v3-schema.json +++ b/ext/data/schemas/dictionary-term-bank-v3-schema.json @@ -155,6 +155,10 @@ "type": "string", "description": "Hover text for the image." }, + "alt": { + "type": "string", + "description": "Alt text for the image." + }, "description": { "type": "string", "description": "Description of the image." @@ -424,6 +428,10 @@ "type": "string", "description": "Hover text for the image." }, + "alt": { + "type": "string", + "description": "Alt text for the image." + }, "description": { "type": "string", "description": "Description of the image." diff --git a/ext/data/structured-content-style.json b/ext/data/structured-content-style.json index fe222486..52bd41c8 100644 --- a/ext/data/structured-content-style.json +++ b/ext/data/structured-content-style.json @@ -169,7 +169,7 @@ { "selectors": [".gloss-image-link[data-appearance=monochrome] .gloss-image"], "styles": [ - ["visibility", "hidden"] + ["opacity", "0"] ] }, { diff --git a/ext/js/display/sandbox/structured-content-generator.js b/ext/js/display/sandbox/structured-content-generator.js index a28464ae..ad63667a 100644 --- a/ext/js/display/sandbox/structured-content-generator.js +++ b/ext/js/display/sandbox/structured-content-generator.js @@ -65,6 +65,7 @@ export class StructuredContentGenerator { preferredWidth, preferredHeight, title, + alt, pixelated, imageRendering, appearance, @@ -102,7 +103,7 @@ export class StructuredContentGenerator { imageContainer.appendChild(imageBackground); const image = /** @type {HTMLImageElement} */ (this._createElement('img', 'gloss-image')); - image.alt = ''; + image.alt = typeof alt === 'string' ? alt : ''; imageContainer.appendChild(image); const overlay = this._createElement('span', 'gloss-image-container-overlay'); diff --git a/ext/js/language/dictionary-importer.js b/ext/js/language/dictionary-importer.js index 2b9792ea..2c0c7e9c 100644 --- a/ext/js/language/dictionary-importer.js +++ b/ext/js/language/dictionary-importer.js @@ -503,6 +503,7 @@ export class DictionaryImporter { width: preferredWidth, height: preferredHeight, title, + alt, description, pixelated, imageRendering, @@ -518,6 +519,7 @@ export class DictionaryImporter { if (typeof preferredWidth === 'number') { target.preferredWidth = preferredWidth; } if (typeof preferredHeight === 'number') { target.preferredHeight = preferredHeight; } if (typeof title === 'string') { target.title = title; } + if (typeof alt === 'string') { target.alt = alt; } if (typeof description === 'string') { target.description = description; } if (typeof pixelated === 'boolean') { target.pixelated = pixelated; } if (typeof imageRendering === 'string') { target.imageRendering = imageRendering; } diff --git a/test/data/dictionaries/valid-dictionary1/aosaba_auto.png b/test/data/dictionaries/valid-dictionary1/aosaba_auto.png new file mode 100644 index 00000000..ddef36ac Binary files /dev/null and b/test/data/dictionaries/valid-dictionary1/aosaba_auto.png differ diff --git a/test/data/dictionaries/valid-dictionary1/aosaba_mono.png b/test/data/dictionaries/valid-dictionary1/aosaba_mono.png new file mode 100644 index 00000000..a0776098 Binary files /dev/null and b/test/data/dictionaries/valid-dictionary1/aosaba_mono.png differ diff --git a/test/data/dictionaries/valid-dictionary1/term_bank_1.json b/test/data/dictionaries/valid-dictionary1/term_bank_1.json index 38b022fa..14f66d95 100644 --- a/test/data/dictionaries/valid-dictionary1/term_bank_1.json +++ b/test/data/dictionaries/valid-dictionary1/term_bank_1.json @@ -66,7 +66,7 @@ "莢\n" ]}, {"type": "structured-content", "content": [ - "Imgae aspect ratio tests:\nあ", + "Image aspect ratio tests:\nあ", {"tag": "img", "path": "character2.gif", "height": 1.1, "imageRendering": "crisp-edges", "appearance": "monochrome", "background": false, "sizeUnits": "em", "collapsed": false, "collapsible": false}, "あ\nあ", {"tag": "img", "path": "character2.gif", "width": 0.4125, "imageRendering": "crisp-edges", "appearance": "monochrome", "background": false, "sizeUnits": "em", "collapsed": false, "collapsible": false}, @@ -76,6 +76,13 @@ {"tag": "img", "path": "character3.gif", "height": 0.4125, "imageRendering": "crisp-edges", "appearance": "monochrome", "background": false, "sizeUnits": "em", "collapsed": false, "collapsible": false}, "あ" ]}, + {"type": "structured-content", "content": [ + "Image alt text tests.\n𬵪 = Unicode character\n", + {"tag": "img", "alt": "𬵪", "path": "aosaba_mono.png", "height": 1.0, "width": 1.0, "background": false, "sizeUnits": "em", "collapsed": false, "collapsible": false, "appearance": "monochrome"}, + " = monochrome PNG\n", + {"tag": "img", "alt": "𬵪", "path": "aosaba_auto.png", "height": 1.0, "width": 1.0, "background": false, "sizeUnits": "em", "collapsed": false, "collapsible": false, "appearance": "auto"}, + " = color PNG" + ]}, {"type": "structured-content", "content": [ {"tag": "div", "style": {"fontStyle": "normal"}, "content": "fontStyle:normal"}, {"tag": "div", "style": {"fontStyle": "italic"}, "content": "fontStyle:italic"}, diff --git a/test/database.test.js b/test/database.test.js index 702de9f8..86c69a41 100644 --- a/test/database.test.js +++ b/test/database.test.js @@ -163,7 +163,7 @@ async function testDatabase1() { counts: { kanji: {total: 2}, kanjiMeta: {total: 6, freq: 6}, - media: {total: 4}, + media: {total: 6}, tagMeta: {total: 15}, termMeta: {total: 38, freq: 31, pitch: 7}, terms: {total: 21} @@ -193,13 +193,13 @@ async function testDatabase1() { true ); expect(counts).toStrictEqual({ - counts: [{kanji: 2, kanjiMeta: 6, terms: 21, termMeta: 38, tagMeta: 15, media: 4}], - total: {kanji: 2, kanjiMeta: 6, terms: 21, termMeta: 38, tagMeta: 15, media: 4} + counts: [{kanji: 2, kanjiMeta: 6, terms: 21, termMeta: 38, tagMeta: 15, media: 6}], + total: {kanji: 2, kanjiMeta: 6, terms: 21, termMeta: 38, tagMeta: 15, media: 6} }); // Test find* functions await testFindTermsBulkTest1(dictionaryDatabase, titles); - await testTindTermsExactBulk1(dictionaryDatabase, titles); + await testFindTermsExactBulk1(dictionaryDatabase, titles); await testFindTermsBySequenceBulk1(dictionaryDatabase, title); await testFindTermMetaBulk1(dictionaryDatabase, titles); await testFindKanjiBulk1(dictionaryDatabase, titles); @@ -335,8 +335,8 @@ async function testFindTermsBulkTest1(database, titles) { * @param {DictionaryDatabase} database * @param {import('dictionary-database').DictionarySet} titles */ -async function testTindTermsExactBulk1(database, titles) { - test('TindTermsExactBulk1', async () => { +async function testFindTermsExactBulk1(database, titles) { + test('FindTermsExactBulk1', async () => { /** @type {{inputs: {termList: {term: string, reading: string}[]}[], expectedResults: {total: number, terms: [key: string, count: number][], readings: [key: string, count: number][]}}[]} */ const data = [ { diff --git a/types/ext/structured-content.d.ts b/types/ext/structured-content.d.ts index 572b827a..2144cd84 100644 --- a/types/ext/structured-content.d.ts +++ b/types/ext/structured-content.d.ts @@ -133,6 +133,10 @@ export type ImageElementBase = { * Hover text for the image. */ title?: string; + /** + * Alt text for the image. + */ + alt?: string; /** * Description of the image. */ -- cgit v1.2.3