Indicate if first Anki card field is invalid (#1145)

* Add AnkiNoteBuilder.containsAnyMarker

* Flag first field as invalid when there is no marker
This commit is contained in:
toasted-nutbread 2020-12-20 12:20:29 -05:00 committed by GitHub
parent 113e3b68b8
commit 7dd06e1a64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 5 deletions

View File

@ -22,6 +22,7 @@
class AnkiNoteBuilder { class AnkiNoteBuilder {
constructor({renderTemplate}) { constructor({renderTemplate}) {
this._renderTemplate = renderTemplate; this._renderTemplate = renderTemplate;
this._markerPattern = /\{([\w-]+)\}/g;
} }
async createNote({ async createNote({
@ -98,6 +99,12 @@ class AnkiNoteBuilder {
return false; return false;
} }
containsAnyMarker(field) {
const result = this._markerPattern.test(field);
this._markerPattern.lastIndex = 0;
return result;
}
getRootDeckName(deckName) { getRootDeckName(deckName) {
const index = deckName.indexOf('::'); const index = deckName.indexOf('::');
return index >= 0 ? deckName.substring(0, index) : deckName; return index >= 0 ? deckName.substring(0, index) : deckName;
@ -136,8 +143,7 @@ class AnkiNoteBuilder {
} }
async _formatField(field, data, templates, errors=null) { async _formatField(field, data, templates, errors=null) {
const pattern = /\{([\w-]+)\}/g; return await this._stringReplaceAsync(field, this._markerPattern, async (g0, marker) => {
return await this._stringReplaceAsync(field, pattern, async (g0, marker) => {
try { try {
return await this._renderTemplate(templates, data, marker); return await this._renderTemplate(templates, data, marker);
} catch (e) { } catch (e) {

View File

@ -17,6 +17,7 @@
/* global /* global
* AnkiConnect * AnkiConnect
* AnkiNoteBuilder
* ObjectPropertyAccessor * ObjectPropertyAccessor
* SelectorObserver * SelectorObserver
*/ */
@ -25,6 +26,9 @@ class AnkiController {
constructor(settingsController) { constructor(settingsController) {
this._settingsController = settingsController; this._settingsController = settingsController;
this._ankiConnect = new AnkiConnect(); this._ankiConnect = new AnkiConnect();
this._ankiNoteBuilder = new AnkiNoteBuilder({
renderTemplate: null
});
this._selectorObserver = new SelectorObserver({ this._selectorObserver = new SelectorObserver({
selector: '.anki-card', selector: '.anki-card',
ignoreSelector: null, ignoreSelector: null,
@ -159,6 +163,10 @@ class AnkiController {
} }
} }
containsAnyMarker(field) {
return this._ankiNoteBuilder.containsAnyMarker(field);
}
// Private // Private
async _onOptionsChanged({options: {anki}}) { async _onOptionsChanged({options: {anki}}) {
@ -403,8 +411,15 @@ class AnkiCardController {
this._setModel(e.currentTarget.value); this._setModel(e.currentTarget.value);
} }
_onFieldChange(e) { _onFieldChange(index, e) {
this._ankiController.validateFieldPermissions(e.currentTarget.value); 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}}) { _onFieldMenuClosed({currentTarget: node, detail: {action, item}}) {
@ -421,6 +436,13 @@ class AnkiCardController {
this._setFieldMarker(link, link.textContent); 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) { _setFieldMarker(element, marker) {
const input = element.closest('.anki-card-field-value-container').querySelector('.anki-card-field-value'); const input = element.closest('.anki-card-field-value-container').querySelector('.anki-card-field-value');
input.value = `{${marker}}`; input.value = `{${marker}}`;
@ -482,7 +504,9 @@ class AnkiCardController {
const inputField = content.querySelector('.anki-card-field-value'); const inputField = content.querySelector('.anki-card-field-value');
inputField.value = fieldValue; inputField.value = fieldValue;
inputField.dataset.setting = ObjectPropertyAccessor.getPathString(['anki', this._cardType, 'fields', fieldName]); 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'); const markerList = content.querySelector('.anki-card-field-marker-list');
if (markerList !== null) { if (markerList !== null) {