summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-09-04 12:43:56 -0400
committerGitHub <noreply@github.com>2021-09-04 12:43:56 -0400
commitf68ad1f843607d4ba1ad216fe16305c420cee8d6 (patch)
tree0a1dc9a3d78df62fee501f467dce3277fb5b4f1e
parenteb457caea9b3e5484355ffce80edb371d3bf232d (diff)
Structured content data (#1930)
* Add support for structured-content data attributes * Assign dataset properties * Don't remove data-sc attributes * Use helper functions * Update test data
-rw-r--r--ext/data/schemas/dictionary-term-bank-v3-schema.json22
-rw-r--r--ext/js/display/sandbox/structured-content-generator.js12
-rw-r--r--ext/js/templates/sandbox/anki-template-renderer.js35
-rw-r--r--test/data/dictionaries/valid-dictionary1/term_bank_1.json15
4 files changed, 67 insertions, 17 deletions
diff --git a/ext/data/schemas/dictionary-term-bank-v3-schema.json b/ext/data/schemas/dictionary-term-bank-v3-schema.json
index abb4e58f..9898a15e 100644
--- a/ext/data/schemas/dictionary-term-bank-v3-schema.json
+++ b/ext/data/schemas/dictionary-term-bank-v3-schema.json
@@ -28,6 +28,9 @@
"tag": {
"type": "string",
"enum": ["br"]
+ },
+ "data": {
+ "$ref": "#/definitions/structuredContentData"
}
}
},
@@ -45,6 +48,9 @@
},
"content": {
"$ref": "#/definitions/structuredContent"
+ },
+ "data": {
+ "$ref": "#/definitions/structuredContentData"
}
}
},
@@ -63,6 +69,9 @@
"content": {
"$ref": "#/definitions/structuredContent"
},
+ "data": {
+ "$ref": "#/definitions/structuredContentData"
+ },
"colSpan": {
"type": "integer",
"minimum": 1
@@ -91,6 +100,9 @@
"content": {
"$ref": "#/definitions/structuredContent"
},
+ "data": {
+ "$ref": "#/definitions/structuredContentData"
+ },
"style": {
"$ref": "#/definitions/structuredContentStyle"
}
@@ -109,6 +121,9 @@
"type": "string",
"const": "img"
},
+ "data": {
+ "$ref": "#/definitions/structuredContentData"
+ },
"path": {
"type": "string",
"description": "Path to the image file in the archive."
@@ -175,6 +190,13 @@
}
]
},
+ "structuredContentData": {
+ "type": "object",
+ "description": "Generic data attributes that should be added to the element.",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
"structuredContentStyle": {
"type": "object",
"additionalProperties": false,
diff --git a/ext/js/display/sandbox/structured-content-generator.js b/ext/js/display/sandbox/structured-content-generator.js
index 82bf0421..8aa34bb2 100644
--- a/ext/js/display/sandbox/structured-content-generator.js
+++ b/ext/js/display/sandbox/structured-content-generator.js
@@ -169,6 +169,16 @@ class StructuredContentGenerator {
return this._document.createDocumentFragment();
}
+ _setElementDataset(element, data) {
+ for (let [key, value] of Object.entries(data)) {
+ if (key.length > 0) {
+ key = `${key[0].toUpperCase()}${key.substring(1)}`;
+ }
+ key = `sc${key}`;
+ element.dataset[key] = value;
+ }
+ }
+
_setImageData(node, image, imageBackground, url, unloaded) {
if (url !== null) {
image.src = url;
@@ -192,6 +202,8 @@ class StructuredContentGenerator {
_createStructuredContentElement(tag, content, dictionary, type, hasChildren, hasStyle) {
const node = this._createElement(tag, `gloss-sc-${tag}`);
+ const {data} = content;
+ if (typeof data === 'object' && data !== null) { this._setElementDataset(node, data); }
switch (type) {
case 'table-cell':
{
diff --git a/ext/js/templates/sandbox/anki-template-renderer.js b/ext/js/templates/sandbox/anki-template-renderer.js
index 8a257bcc..10283761 100644
--- a/ext/js/templates/sandbox/anki-template-renderer.js
+++ b/ext/js/templates/sandbox/anki-template-renderer.js
@@ -38,6 +38,7 @@ class AnkiTemplateRenderer {
constructor() {
this._structuredContentStyleApplier = new CssStyleApplier('/data/structured-content-style.json');
this._pronunciationStyleApplier = new CssStyleApplier('/data/pronunciation-style.json');
+ this._structuredContentDatasetKeyIgnorePattern = /^sc([^a-z]|$)/;
this._japaneseUtil = new JapaneseUtil(null);
this._templateRenderer = new TemplateRenderer();
this._ankiNoteDataCreator = new AnkiNoteDataCreator(this._japaneseUtil);
@@ -462,16 +463,24 @@ class AnkiTemplateRenderer {
return element;
}
- _getHtml(node, styleApplier) {
+ _getStructuredContentHtml(node) {
+ return this._getHtml(node, this._structuredContentStyleApplier, this._structuredContentDatasetKeyIgnorePattern);
+ }
+
+ _getPronunciationHtml(node) {
+ return this._getHtml(node, this._pronunciationStyleApplier, null);
+ }
+
+ _getHtml(node, styleApplier, datasetKeyIgnorePattern) {
const container = this._getTemporaryElement();
container.appendChild(node);
- this._normalizeHtml(container, styleApplier);
+ this._normalizeHtml(container, styleApplier, datasetKeyIgnorePattern);
const result = container.innerHTML;
container.textContent = '';
return result;
}
- _normalizeHtml(root, styleApplier) {
+ _normalizeHtml(root, styleApplier, datasetKeyIgnorePattern) {
const {ELEMENT_NODE, TEXT_NODE} = Node;
const treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);
const elements = [];
@@ -492,6 +501,7 @@ class AnkiTemplateRenderer {
for (const element of elements) {
const {dataset} = element;
for (const key of Object.keys(dataset)) {
+ if (datasetKeyIgnorePattern !== null && datasetKeyIgnorePattern.test(key)) { continue; }
delete dataset[key];
}
}
@@ -541,13 +551,13 @@ class AnkiTemplateRenderer {
_formatGlossaryImage(content, dictionary, data) {
const structuredContentGenerator = this._createStructuredContentGenerator(data);
const node = structuredContentGenerator.createDefinitionImage(content, dictionary);
- return this._getHtml(node, this._structuredContentStyleApplier);
+ return this._getStructuredContentHtml(node);
}
_formatStructuredContent(content, dictionary, data) {
const structuredContentGenerator = this._createStructuredContentGenerator(data);
const node = structuredContentGenerator.createStructuredContent(content.content, dictionary);
- return node !== null ? this._getHtml(node, this._structuredContentStyleApplier) : '';
+ return node !== null ? this._getStructuredContentHtml(node) : '';
}
_hasMedia(context, ...args) {
@@ -575,20 +585,11 @@ class AnkiTemplateRenderer {
switch (format) {
case 'text':
- return this._getHtml(
- this._pronunciationGenerator.createPronunciationText(morae, downstepPosition, nasalPositions, devoicePositions),
- this._pronunciationStyleApplier
- );
+ return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationText(morae, downstepPosition, nasalPositions, devoicePositions));
case 'graph':
- return this._getHtml(
- this._pronunciationGenerator.createPronunciationGraph(morae, downstepPosition),
- this._pronunciationStyleApplier
- );
+ return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationGraph(morae, downstepPosition));
case 'position':
- return this._getHtml(
- this._pronunciationGenerator.createPronunciationDownstepPosition(downstepPosition),
- this._pronunciationStyleApplier
- );
+ return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationDownstepPosition(downstepPosition));
default:
return '';
}
diff --git a/test/data/dictionaries/valid-dictionary1/term_bank_1.json b/test/data/dictionaries/valid-dictionary1/term_bank_1.json
index 58136d79..0d94d6d1 100644
--- a/test/data/dictionaries/valid-dictionary1/term_bank_1.json
+++ b/test/data/dictionaries/valid-dictionary1/term_bank_1.json
@@ -164,6 +164,21 @@
]
},
"margin"
+ ]},
+ {"type": "structured-content", "content": [
+ "text 1 ",
+ {
+ "tag": "span",
+ "data": {
+ "": "empty",
+ "a": "b",
+ "c": "d"
+ },
+ "content": [
+ "text 2"
+ ]
+ },
+ " text 3"
]}
],
100, "P E1"