aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-10-30 17:41:52 -0400
committerGitHub <noreply@github.com>2020-10-30 17:41:52 -0400
commit327d7b1f26d8553809292e159b97d44bc77b7b8e (patch)
tree175d18d86fc09e97cef6dba68ed62331467ca934
parentcb76848df980b4245e9f5c0dee4eec4280ed645d (diff)
Anki templates refactor (#970)
* Support menus with multiple sources * Update anki templates controller
-rw-r--r--ext/bg/css/settings.css6
-rw-r--r--ext/bg/js/settings/anki-controller.js14
-rw-r--r--ext/bg/js/settings/anki-templates-controller.js73
-rw-r--r--ext/bg/settings.html26
4 files changed, 76 insertions, 43 deletions
diff --git a/ext/bg/css/settings.css b/ext/bg/css/settings.css
index 231df1b3..5416371f 100644
--- a/ext/bg/css/settings.css
+++ b/ext/bg/css/settings.css
@@ -272,7 +272,7 @@ html:root:not([data-options-general-result-output-mode=merge]) #dictionary-main-
#custom-popup-css,
#custom-popup-outer-css,
-#field-templates {
+#anki-card-templates-textarea {
width: 100%;
min-height: 34px;
line-height: 18px;
@@ -280,12 +280,10 @@ html:root:not([data-options-general-result-output-mode=merge]) #dictionary-main-
resize: vertical;
font-family: 'Courier New', Courier, monospace;
white-space: pre;
-}
-#field-templates {
height: 240px;
border-bottom-left-radius: 0;
}
-#field-templates-reset {
+#anki-card-templates-reset-button {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
diff --git a/ext/bg/js/settings/anki-controller.js b/ext/bg/js/settings/anki-controller.js
index 6988e4b8..c205c160 100644
--- a/ext/bg/js/settings/anki-controller.js
+++ b/ext/bg/js/settings/anki-controller.js
@@ -214,14 +214,20 @@ class AnkiController {
_setupFieldMenus() {
const fieldMenuTargets = [
- ['terms', '#anki-card-terms-field-menu-template'],
- ['kanji', '#anki-card-kanji-field-menu-template']
+ [['terms'], '#anki-card-terms-field-menu-template'],
+ [['kanji'], '#anki-card-kanji-field-menu-template'],
+ [['terms', 'kanji'], '#anki-card-all-field-menu-template']
];
- for (const [type, selector] of fieldMenuTargets) {
+ for (const [types, selector] of fieldMenuTargets) {
const element = document.querySelector(selector);
if (element === null) { continue; }
- const markers = this.getFieldMarkers(type);
+ let markers = [];
+ for (const type of types) {
+ markers.push(...this.getFieldMarkers(type));
+ }
+ markers = [...new Set(markers)];
+
const container = element.content.querySelector('.popup-menu');
if (container === null) { return; }
diff --git a/ext/bg/js/settings/anki-templates-controller.js b/ext/bg/js/settings/anki-templates-controller.js
index 65900336..e6bab256 100644
--- a/ext/bg/js/settings/anki-templates-controller.js
+++ b/ext/bg/js/settings/anki-templates-controller.js
@@ -30,6 +30,10 @@ class AnkiTemplatesController {
this._cachedDefinitionValue = null;
this._cachedDefinitionText = null;
this._defaultFieldTemplates = null;
+ this._fieldTemplatesTextarea = null;
+ this._compileResultInfo = null;
+ this._renderFieldInput = null;
+ this._renderResult = null;
this._fieldTemplateResetModal = null;
this._templateRenderer = new TemplateRendererProxy();
}
@@ -37,24 +41,38 @@ class AnkiTemplatesController {
async prepare() {
this._defaultFieldTemplates = await api.getDefaultAnkiFieldTemplates();
- this._fieldTemplateResetModal = this._modalController.getModal('field-template-reset-modal');
+ this._fieldTemplatesTextarea = document.querySelector('#anki-card-templates-textarea');
+ this._compileResultInfo = document.querySelector('#anki-card-templates-compile-result');
+ this._renderFieldInput = document.querySelector('#anki-card-templates-test-field-input');
+ this._renderTextInput = document.querySelector('#anki-card-templates-test-text-input');
+ this._renderResult = document.querySelector('#anki-card-templates-render-result');
+ const menuButton = document.querySelector('#anki-card-templates-test-field-menu-button');
+ const testRenderButton = document.querySelector('#anki-card-templates-test-render-button');
+ const resetButton = document.querySelector('#anki-card-templates-reset-button');
+ const resetConfirmButton = document.querySelector('#anki-card-templates-reset-button-confirm');
+ const fieldList = document.querySelector('#anki-card-templates-field-list');
+ this._fieldTemplateResetModal = this._modalController.getModal('anki-card-templates-reset');
const markers = new Set([
...this._ankiController.getFieldMarkers('terms'),
...this._ankiController.getFieldMarkers('kanji')
]);
- const fragment = this._ankiController.getFieldMarkersHtml(markers);
- const list = document.querySelector('#field-templates-list');
- list.appendChild(fragment);
- for (const node of list.querySelectorAll('.marker-link')) {
- node.addEventListener('click', this._onMarkerClicked.bind(this), false);
+ if (fieldList !== null) {
+ const fragment = this._ankiController.getFieldMarkersHtml(markers);
+ fieldList.appendChild(fragment);
+ for (const node of fieldList.querySelectorAll('.marker-link')) {
+ node.addEventListener('click', this._onMarkerClicked.bind(this), false);
+ }
}
- document.querySelector('#field-templates').addEventListener('change', this._onChanged.bind(this), false);
- document.querySelector('#field-template-render').addEventListener('click', this._onRender.bind(this), false);
- document.querySelector('#field-templates-reset').addEventListener('click', this._onReset.bind(this), false);
- document.querySelector('#field-templates-reset-confirm').addEventListener('click', this._onResetConfirm.bind(this), false);
+ this._fieldTemplatesTextarea.addEventListener('change', this._onChanged.bind(this), false);
+ testRenderButton.addEventListener('click', this._onRender.bind(this), false);
+ resetButton.addEventListener('click', this._onReset.bind(this), false);
+ resetConfirmButton.addEventListener('click', this._onResetConfirm.bind(this), false);
+ if (menuButton !== null) {
+ menuButton.addEventListener('menuClosed', this._onFieldMenuClosed.bind(this), false);
+ }
this._settingsController.on('optionsChanged', this._onOptionsChanged.bind(this));
@@ -67,7 +85,7 @@ class AnkiTemplatesController {
_onOptionsChanged({options}) {
let templates = options.anki.fieldTemplates;
if (typeof templates !== 'string') { templates = this._defaultFieldTemplates; }
- document.querySelector('#field-templates').value = templates;
+ this._fieldTemplatesTextarea.value = templates;
this._onValidateCompile();
}
@@ -84,9 +102,8 @@ class AnkiTemplatesController {
const value = this._defaultFieldTemplates;
- const element = document.querySelector('#field-templates');
- element.value = value;
- element.dispatchEvent(new Event('change'));
+ this._fieldTemplatesTextarea.value = value;
+ this._fieldTemplatesTextarea.dispatchEvent(new Event('change'));
}
async _onChanged(e) {
@@ -105,24 +122,37 @@ class AnkiTemplatesController {
}
_onValidateCompile() {
- const infoNode = document.querySelector('#field-template-compile-result');
- this._validate(infoNode, '{expression}', 'term-kanji', false, true);
+ this._validate(this._compileResultInfo, '{expression}', 'term-kanji', false, true);
}
_onMarkerClicked(e) {
e.preventDefault();
- document.querySelector('#field-template-render-text').value = `{${e.target.textContent}}`;
+ this._renderFieldInput.value = `{${e.target.textContent}}`;
}
_onRender(e) {
e.preventDefault();
- const field = document.querySelector('#field-template-render-text').value;
- const infoNode = document.querySelector('#field-template-render-result');
+ const field = this._renderFieldInput.value;
+ const infoNode = this._renderResult;
infoNode.hidden = true;
this._validate(infoNode, field, 'term-kanji', true, false);
}
+ _onFieldMenuClosed({currentTarget: node, detail: {action, item}}) {
+ switch (action) {
+ case 'setFieldMarker':
+ this._setFieldMarker(node, item.dataset.marker);
+ break;
+ }
+ }
+
+ _setFieldMarker(element, marker) {
+ const input = this._renderFieldInput;
+ input.value = `{${marker}}`;
+ input.dispatchEvent(new Event('change'));
+ }
+
async _getDefinition(text, optionsContext) {
if (this._cachedDefinitionText !== text) {
const {definitions} = await api.termsFind(text, {}, optionsContext);
@@ -135,7 +165,7 @@ class AnkiTemplatesController {
}
async _validate(infoNode, field, mode, showSuccessResult, invalidateInput) {
- const text = document.querySelector('#field-templates-preview-text').value || '';
+ const text = this._renderTextInput.value || '';
const exceptions = [];
let result = `No definition found for ${text}`;
try {
@@ -179,8 +209,7 @@ class AnkiTemplatesController {
infoNode.textContent = hasException ? exceptions.map((e) => `${e}`).join('\n') : (showSuccessResult ? result : '');
infoNode.classList.toggle('text-danger', hasException);
if (invalidateInput) {
- const input = document.querySelector('#field-templates');
- input.classList.toggle('is-invalid', hasException);
+ this._fieldTemplatesTextarea.classList.toggle('is-invalid', hasException);
}
}
diff --git a/ext/bg/settings.html b/ext/bg/settings.html
index 066662e5..1b1e9124 100644
--- a/ext/bg/settings.html
+++ b/ext/bg/settings.html
@@ -1004,32 +1004,32 @@
their Anki cards. If you encounter problems with your changes, you can always reset to the default template settings.
</p>
<div class="ignore-form-changes">
- <textarea autocomplete="off" spellcheck="false" wrap="soft" class="form-control" rows="10" id="field-templates"></textarea>
+ <textarea autocomplete="off" spellcheck="false" wrap="soft" class="form-control" rows="10" id="anki-card-templates-textarea"></textarea>
</div>
<div>
- <button class="btn btn-danger" id="field-templates-reset">Reset Templates</button>
+ <button class="btn btn-danger" id="anki-card-templates-reset-button">Reset Templates</button>
</div>
<p></p>
- <pre id="field-template-compile-result" hidden></pre>
+ <pre id="anki-card-templates-compile-result" hidden></pre>
<p>Templates can be tested using the inputs below.</p>
<div class="form-group">
<div class="row">
<div class="col-xs-6">
- <label for="field-templates-preview-text">Preview text</label>
- <input type="text" id="field-templates-preview-text" class="form-control" value="読め" placeholder="Preview text">
+ <label for="anki-card-templates-test-text-input">Preview text</label>
+ <input type="text" id="anki-card-templates-test-text-input" class="form-control" value="読め" placeholder="Preview text">
</div>
<div class="col-xs-6">
- <label for="field-template-render-text">Test field</label>
+ <label for="anki-card-templates-test-field-input">Test field</label>
<div class="input-group">
<div class="input-group-btn">
- <button class="btn btn-default" id="field-template-render" title="Test"><span class="glyphicon glyphicon-play"></span></button>
+ <button class="btn btn-default" id="anki-card-templates-test-render-button" title="Test"><span class="glyphicon glyphicon-play"></span></button>
</div>
- <input type="text" class="form-control" id="field-template-render-text" value="{expression}" placeholder="{marker}">
+ <input type="text" class="form-control" id="anki-card-templates-test-field-input" value="{expression}" placeholder="{marker}">
<div class="input-group-btn">
- <button class="btn btn-default dropdown-toggle" id="field-templates-dropdown" data-toggle="dropdown"><span class="caret"></span></button>
- <ul class="dropdown-menu dropdown-menu-right" id="field-templates-list"></ul>
+ <button class="btn btn-default dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
+ <ul class="dropdown-menu dropdown-menu-right" id="anki-card-templates-field-list"></ul>
</div>
</div>
</div>
@@ -1037,10 +1037,10 @@
</div>
<p></p>
- <pre id="field-template-render-result" hidden></pre>
+ <pre id="anki-card-templates-render-result" hidden></pre>
</div>
- <div class="modal fade" tabindex="-1" role="dialog" id="field-template-reset-modal">
+ <div class="modal fade" tabindex="-1" role="dialog" id="anki-card-templates-reset">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
@@ -1053,7 +1053,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
- <button type="button" class="btn btn-danger" id="field-templates-reset-confirm">Reset Templates</button>
+ <button type="button" class="btn btn-danger" id="anki-card-templates-reset-button-confirm">Reset Templates</button>
</div>
</div>
</div>