From 7dd06e1a64bf563ac083ab2e3ca45fb71ed40a8b Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 20 Dec 2020 12:20:29 -0500 Subject: [PATCH] Indicate if first Anki card field is invalid (#1145) * Add AnkiNoteBuilder.containsAnyMarker * Flag first field as invalid when there is no marker --- ext/bg/js/anki-note-builder.js | 10 +++++++-- ext/bg/js/settings/anki-controller.js | 30 ++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/ext/bg/js/anki-note-builder.js b/ext/bg/js/anki-note-builder.js index b6114e4b..094dd77b 100644 --- a/ext/bg/js/anki-note-builder.js +++ b/ext/bg/js/anki-note-builder.js @@ -22,6 +22,7 @@ class AnkiNoteBuilder { constructor({renderTemplate}) { this._renderTemplate = renderTemplate; + this._markerPattern = /\{([\w-]+)\}/g; } async createNote({ @@ -98,6 +99,12 @@ class AnkiNoteBuilder { return false; } + containsAnyMarker(field) { + const result = this._markerPattern.test(field); + this._markerPattern.lastIndex = 0; + return result; + } + getRootDeckName(deckName) { const index = deckName.indexOf('::'); return index >= 0 ? deckName.substring(0, index) : deckName; @@ -136,8 +143,7 @@ class AnkiNoteBuilder { } async _formatField(field, data, templates, errors=null) { - const pattern = /\{([\w-]+)\}/g; - return await this._stringReplaceAsync(field, pattern, async (g0, marker) => { + return await this._stringReplaceAsync(field, this._markerPattern, async (g0, marker) => { try { return await this._renderTemplate(templates, data, marker); } catch (e) { diff --git a/ext/bg/js/settings/anki-controller.js b/ext/bg/js/settings/anki-controller.js index 77b4ce96..b382bf26 100644 --- a/ext/bg/js/settings/anki-controller.js +++ b/ext/bg/js/settings/anki-controller.js @@ -17,6 +17,7 @@ /* global * AnkiConnect + * AnkiNoteBuilder * ObjectPropertyAccessor * SelectorObserver */ @@ -25,6 +26,9 @@ class AnkiController { constructor(settingsController) { this._settingsController = settingsController; this._ankiConnect = new AnkiConnect(); + this._ankiNoteBuilder = new AnkiNoteBuilder({ + renderTemplate: null + }); this._selectorObserver = new SelectorObserver({ selector: '.anki-card', ignoreSelector: null, @@ -159,6 +163,10 @@ class AnkiController { } } + containsAnyMarker(field) { + return this._ankiNoteBuilder.containsAnyMarker(field); + } + // Private async _onOptionsChanged({options: {anki}}) { @@ -403,8 +411,15 @@ class AnkiCardController { this._setModel(e.currentTarget.value); } - _onFieldChange(e) { - this._ankiController.validateFieldPermissions(e.currentTarget.value); + _onFieldChange(index, e) { + const node = e.currentTarget; + this._ankiController.validateFieldPermissions(node.value); + this._validateField(node, index); + } + + _onFieldInput(index, e) { + const node = e.currentTarget; + this._validateField(node, index); } _onFieldMenuClosed({currentTarget: node, detail: {action, item}}) { @@ -421,6 +436,13 @@ class AnkiCardController { this._setFieldMarker(link, link.textContent); } + _validateField(node, index) { + if (index === 0) { + const containsAnyMarker = this._ankiController.containsAnyMarker(node.value); + node.dataset.invalid = `${!containsAnyMarker}`; + } + } + _setFieldMarker(element, marker) { const input = element.closest('.anki-card-field-value-container').querySelector('.anki-card-field-value'); input.value = `{${marker}}`; @@ -482,7 +504,9 @@ class AnkiCardController { const inputField = content.querySelector('.anki-card-field-value'); inputField.value = fieldValue; inputField.dataset.setting = ObjectPropertyAccessor.getPathString(['anki', this._cardType, 'fields', fieldName]); - this._fieldEventListeners.addEventListener(inputField, 'change', this._onFieldChange.bind(this), false); + this._fieldEventListeners.addEventListener(inputField, 'change', this._onFieldChange.bind(this, index), false); + this._fieldEventListeners.addEventListener(inputField, 'input', this._onFieldInput.bind(this, index), false); + this._validateField(inputField, index); const markerList = content.querySelector('.anki-card-field-marker-list'); if (markerList !== null) {