aboutsummaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/bg/data/default-anki-field-templates.handlebars4
-rw-r--r--ext/bg/js/backend.js2
-rw-r--r--ext/bg/js/handlebars.js21
-rw-r--r--ext/bg/js/options.js32
-rw-r--r--ext/mixed/js/core.js5
5 files changed, 51 insertions, 13 deletions
diff --git a/ext/bg/data/default-anki-field-templates.handlebars b/ext/bg/data/default-anki-field-templates.handlebars
index 4382f707..42deae23 100644
--- a/ext/bg/data/default-anki-field-templates.handlebars
+++ b/ext/bg/data/default-anki-field-templates.handlebars
@@ -151,7 +151,7 @@
{{/inline}}
{{#*inline "tags"}}
- {{~#each definition.definitionTags}}{{name}}{{#unless @last}}, {{/unless}}{{/each~}}
+ {{~#mergeTags definition group merge}}{{this}}{{/mergeTags~}}
{{/inline}}
{{#*inline "url"}}
@@ -166,4 +166,4 @@
{{~context.document.title~}}
{{/inline}}
-{{~> (lookup . "marker") ~}} \ No newline at end of file
+{{~> (lookup . "marker") ~}}
diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js
index 557ceb29..20d31efc 100644
--- a/ext/bg/js/backend.js
+++ b/ext/bg/js/backend.js
@@ -150,7 +150,7 @@ class Backend {
await profileConditionsDescriptorPromise;
this.optionsSchema = await requestJson(chrome.runtime.getURL('/bg/data/options-schema.json'), 'GET');
- this.defaultAnkiFieldTemplates = await requestText(chrome.runtime.getURL('/bg/data/default-anki-field-templates.handlebars'), 'GET');
+ this.defaultAnkiFieldTemplates = (await requestText(chrome.runtime.getURL('/bg/data/default-anki-field-templates.handlebars'), 'GET')).trim();
this.options = await optionsLoad();
this.options = JsonSchema.getValidValueOrDefault(this.optionsSchema, this.options);
diff --git a/ext/bg/js/handlebars.js b/ext/bg/js/handlebars.js
index 860acb14..822174e2 100644
--- a/ext/bg/js/handlebars.js
+++ b/ext/bg/js/handlebars.js
@@ -123,6 +123,26 @@ function handlebarsRegexMatch(...args) {
return value;
}
+function handlebarsMergeTags(object, isGroupMode, isMergeMode) {
+ const tagSources = [];
+ if (isGroupMode || isMergeMode) {
+ for (const definition of object.definitions) {
+ tagSources.push(definition.definitionTags);
+ }
+ } else {
+ tagSources.push(object.definitionTags);
+ }
+
+ const tags = new Set();
+ for (const tagSource of tagSources) {
+ for (const tag of tagSource) {
+ tags.add(tag.name);
+ }
+ }
+
+ return [...tags].join(', ');
+}
+
function handlebarsRegisterHelpers() {
if (Handlebars.partials !== Handlebars.templates) {
Handlebars.partials = Handlebars.templates;
@@ -134,6 +154,7 @@ function handlebarsRegisterHelpers() {
Handlebars.registerHelper('sanitizeCssClass', handlebarsSanitizeCssClass);
Handlebars.registerHelper('regexReplace', handlebarsRegexReplace);
Handlebars.registerHelper('regexMatch', handlebarsRegexMatch);
+ Handlebars.registerHelper('mergeTags', handlebarsMergeTags);
}
}
diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js
index 10df033c..35fdde82 100644
--- a/ext/bg/js/options.js
+++ b/ext/bg/js/options.js
@@ -111,19 +111,31 @@ const profileOptionsVersionUpdates = [
},
(options) => {
// Version 14 changes:
- // Changed template for Anki audio.
+ // Changed template for Anki audio and tags.
let fieldTemplates = options.anki.fieldTemplates;
if (typeof fieldTemplates !== 'string') { return; }
- const replacement = '{{#*inline "audio"}}\n {{~#if definition.audioFileName~}}\n [sound:{{definition.audioFileName}}]\n {{~/if~}}\n{{/inline}}';
- let replaced = false;
- fieldTemplates = fieldTemplates.replace(/\{\{#\*inline "audio"\}\}\{\{\/inline\}\}/g, () => {
- replaced = true;
- return replacement;
- });
-
- if (!replaced) {
- fieldTemplates += '\n\n' + replacement;
+ const replacements = [
+ [
+ '{{#*inline "audio"}}{{/inline}}',
+ '{{#*inline "audio"}}\n {{~#if definition.audioFileName~}}\n [sound:{{definition.audioFileName}}]\n {{~/if~}}\n{{/inline}}'
+ ],
+ [
+ '{{#*inline "tags"}}\n {{~#each definition.definitionTags}}{{name}}{{#unless @last}}, {{/unless}}{{/each~}}\n{{/inline}}',
+ '{{#*inline "tags"}}\n {{~#mergeTags definition group merge}}{{this}}{{/mergeTags~}}\n{{/inline}}'
+ ]
+ ];
+
+ for (const [pattern, replacement] of replacements) {
+ let replaced = false;
+ fieldTemplates = fieldTemplates.replace(new RegExp(escapeRegExp(pattern), 'g'), () => {
+ replaced = true;
+ return replacement;
+ });
+
+ if (!replaced) {
+ fieldTemplates += '\n\n' + replacement;
+ }
}
options.anki.fieldTemplates = fieldTemplates;
diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js
index 835d9cea..589425f2 100644
--- a/ext/mixed/js/core.js
+++ b/ext/mixed/js/core.js
@@ -94,6 +94,11 @@ function hasOwn(object, property) {
return Object.prototype.hasOwnProperty.call(object, property);
}
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
+function escapeRegExp(string) {
+ return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&');
+}
+
// toIterable is required on Edge for cross-window origin objects.
function toIterable(value) {
if (typeof Symbol !== 'undefined' && typeof value[Symbol.iterator] !== 'undefined') {