aboutsummaryrefslogtreecommitdiff
path: root/ext/bg/js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-05-29 19:52:51 -0400
committerGitHub <noreply@github.com>2020-05-29 19:52:51 -0400
commit5f9889fd26f38396aa6ffaa5c669081b02467393 (patch)
tree6f8991ee47439830ae0f7a33f8c5440c12c971c2 /ext/bg/js
parentfde0072118128ea698e15472c9b61b17b4827c8a (diff)
Anki settings controllers (#567)
* Convert anki-templates.js to a class * Convert anki.js to a class
Diffstat (limited to 'ext/bg/js')
-rw-r--r--ext/bg/js/settings/anki-templates.js216
-rw-r--r--ext/bg/js/settings/anki.js464
-rw-r--r--ext/bg/js/settings/main.js22
3 files changed, 354 insertions, 348 deletions
diff --git a/ext/bg/js/settings/anki-templates.js b/ext/bg/js/settings/anki-templates.js
index 0dadb433..dd128ab8 100644
--- a/ext/bg/js/settings/anki-templates.js
+++ b/ext/bg/js/settings/anki-templates.js
@@ -17,141 +17,147 @@
/* global
* AnkiNoteBuilder
- * ankiGetFieldMarkers
- * ankiGetFieldMarkersHtml
* api
* getOptionsContext
* getOptionsMutable
* settingsSaveOptions
*/
-function onAnkiFieldTemplatesReset(e) {
- e.preventDefault();
- $('#field-template-reset-modal').modal('show');
-}
-
-async function onAnkiFieldTemplatesResetConfirm(e) {
- e.preventDefault();
+class AnkiTemplatesController {
+ constructor(ankiController) {
+ this._ankiController = ankiController;
+ this._cachedDefinitionValue = null;
+ this._cachedDefinitionText = null;
+ }
- $('#field-template-reset-modal').modal('hide');
+ prepare() {
+ 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);
+ }
- const value = await api.getDefaultAnkiFieldTemplates();
+ $('#field-templates').on('change', this._onChanged.bind(this));
+ $('#field-template-render').on('click', this._onRender.bind(this));
+ $('#field-templates-reset').on('click', this._onReset.bind(this));
+ $('#field-templates-reset-confirm').on('click', this._onResetConfirm.bind(this));
- const element = document.querySelector('#field-templates');
- element.value = value;
- element.dispatchEvent(new Event('change'));
-}
+ this.updateValue();
+ }
-function ankiTemplatesInitialize() {
- const markers = new Set(ankiGetFieldMarkers('terms').concat(ankiGetFieldMarkers('kanji')));
- const fragment = ankiGetFieldMarkersHtml(markers);
+ async updateValue() {
+ const optionsContext = getOptionsContext();
+ const options = await api.optionsGet(optionsContext);
+ let templates = options.anki.fieldTemplates;
+ if (typeof templates !== 'string') { templates = await api.getDefaultAnkiFieldTemplates(); }
+ $('#field-templates').val(templates);
- const list = document.querySelector('#field-templates-list');
- list.appendChild(fragment);
- for (const node of list.querySelectorAll('.marker-link')) {
- node.addEventListener('click', onAnkiTemplateMarkerClicked, false);
+ this._onValidateCompile();
}
- $('#field-templates').on('change', onAnkiFieldTemplatesChanged);
- $('#field-template-render').on('click', onAnkiTemplateRender);
- $('#field-templates-reset').on('click', onAnkiFieldTemplatesReset);
- $('#field-templates-reset-confirm').on('click', onAnkiFieldTemplatesResetConfirm);
+ // Private
- ankiTemplatesUpdateValue();
-}
+ _onReset(e) {
+ e.preventDefault();
+ $('#field-template-reset-modal').modal('show');
+ }
-async function ankiTemplatesUpdateValue() {
- const optionsContext = getOptionsContext();
- const options = await api.optionsGet(optionsContext);
- let templates = options.anki.fieldTemplates;
- if (typeof templates !== 'string') { templates = await api.getDefaultAnkiFieldTemplates(); }
- $('#field-templates').val(templates);
+ async _onResetConfirm(e) {
+ e.preventDefault();
- onAnkiTemplatesValidateCompile();
-}
+ $('#field-template-reset-modal').modal('hide');
-const ankiTemplatesValidateGetDefinition = (() => {
- let cachedValue = null;
- let cachedText = null;
+ const value = await api.getDefaultAnkiFieldTemplates();
- return async (text, optionsContext) => {
- if (cachedText !== text) {
- const {definitions} = await api.termsFind(text, {}, optionsContext);
- if (definitions.length === 0) { return null; }
+ const element = document.querySelector('#field-templates');
+ element.value = value;
+ element.dispatchEvent(new Event('change'));
+ }
- cachedValue = definitions[0];
- cachedText = text;
+ async _onChanged(e) {
+ // Get value
+ let templates = e.currentTarget.value;
+ if (templates === await api.getDefaultAnkiFieldTemplates()) {
+ // Default
+ templates = null;
}
- return cachedValue;
- };
-})();
-
-async function ankiTemplatesValidate(infoNode, field, mode, showSuccessResult, invalidateInput) {
- const text = document.querySelector('#field-templates-preview-text').value || '';
- const exceptions = [];
- let result = `No definition found for ${text}`;
- try {
+
+ // Overwrite
const optionsContext = getOptionsContext();
- const definition = await ankiTemplatesValidateGetDefinition(text, optionsContext);
- if (definition !== null) {
- const options = await api.optionsGet(optionsContext);
- const context = {
- document: {
- title: document.title
- }
- };
- let templates = options.anki.fieldTemplates;
- if (typeof templates !== 'string') { templates = await api.getDefaultAnkiFieldTemplates(); }
- const ankiNoteBuilder = new AnkiNoteBuilder({renderTemplate: api.templateRender.bind(api)});
- result = await ankiNoteBuilder.formatField(field, definition, mode, context, options, templates, exceptions);
- }
- } catch (e) {
- exceptions.push(e);
+ const options = await getOptionsMutable(optionsContext);
+ options.anki.fieldTemplates = templates;
+ await settingsSaveOptions();
+
+ // Compile
+ this._onValidateCompile();
}
- const hasException = exceptions.length > 0;
- infoNode.hidden = !(showSuccessResult || hasException);
- 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);
+ _onValidateCompile() {
+ const infoNode = document.querySelector('#field-template-compile-result');
+ this._validate(infoNode, '{expression}', 'term-kanji', false, true);
}
-}
-async function onAnkiFieldTemplatesChanged(e) {
- // Get value
- let templates = e.currentTarget.value;
- if (templates === await api.getDefaultAnkiFieldTemplates()) {
- // Default
- templates = null;
+ _onMarkerClicked(e) {
+ e.preventDefault();
+ document.querySelector('#field-template-render-text').value = `{${e.target.textContent}}`;
}
- // Overwrite
- const optionsContext = getOptionsContext();
- const options = await getOptionsMutable(optionsContext);
- options.anki.fieldTemplates = templates;
- await settingsSaveOptions();
+ _onRender(e) {
+ e.preventDefault();
- // Compile
- onAnkiTemplatesValidateCompile();
-}
+ const field = document.querySelector('#field-template-render-text').value;
+ const infoNode = document.querySelector('#field-template-render-result');
+ infoNode.hidden = true;
+ this._validate(infoNode, field, 'term-kanji', true, false);
+ }
-function onAnkiTemplatesValidateCompile() {
- const infoNode = document.querySelector('#field-template-compile-result');
- ankiTemplatesValidate(infoNode, '{expression}', 'term-kanji', false, true);
-}
+ async _getDefinition(text, optionsContext) {
+ if (this._cachedDefinitionText !== text) {
+ const {definitions} = await api.termsFind(text, {}, optionsContext);
+ if (definitions.length === 0) { return null; }
-function onAnkiTemplateMarkerClicked(e) {
- e.preventDefault();
- document.querySelector('#field-template-render-text').value = `{${e.target.textContent}}`;
-}
+ this._cachedDefinitionValue = definitions[0];
+ this._cachedDefinitionText = text;
+ }
+ return this._cachedDefinitionValue;
+ }
-function onAnkiTemplateRender(e) {
- e.preventDefault();
+ async _validate(infoNode, field, mode, showSuccessResult, invalidateInput) {
+ const text = document.querySelector('#field-templates-preview-text').value || '';
+ const exceptions = [];
+ let result = `No definition found for ${text}`;
+ try {
+ const optionsContext = getOptionsContext();
+ const definition = await this._getDefinition(text, optionsContext);
+ if (definition !== null) {
+ const options = await api.optionsGet(optionsContext);
+ const context = {
+ document: {
+ title: document.title
+ }
+ };
+ let templates = options.anki.fieldTemplates;
+ if (typeof templates !== 'string') { templates = await api.getDefaultAnkiFieldTemplates(); }
+ const ankiNoteBuilder = new AnkiNoteBuilder({renderTemplate: api.templateRender.bind(api)});
+ result = await ankiNoteBuilder.formatField(field, definition, mode, context, options, templates, exceptions);
+ }
+ } catch (e) {
+ exceptions.push(e);
+ }
- const field = document.querySelector('#field-template-render-text').value;
- const infoNode = document.querySelector('#field-template-render-result');
- infoNode.hidden = true;
- ankiTemplatesValidate(infoNode, field, 'term-kanji', true, false);
+ const hasException = exceptions.length > 0;
+ infoNode.hidden = !(showSuccessResult || hasException);
+ 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);
+ }
+ }
}
diff --git a/ext/bg/js/settings/anki.js b/ext/bg/js/settings/anki.js
index 8de97554..d110ef39 100644
--- a/ext/bg/js/settings/anki.js
+++ b/ext/bg/js/settings/anki.js
@@ -23,287 +23,281 @@
* utilBackgroundIsolate
*/
-// Private
-
-function _ankiSpinnerShow(show) {
- const spinner = $('#anki-spinner');
- if (show) {
- spinner.show();
- } else {
- spinner.hide();
- }
-}
+class AnkiController {
+ prepare() {
+ $('#anki-fields-container input,#anki-fields-container select,#anki-fields-container textarea').change(this._onFieldsChanged.bind(this));
-function _ankiSetError(error) {
- const node = document.querySelector('#anki-error');
- const node2 = document.querySelector('#anki-invalid-response-error');
- if (error) {
- const errorString = `${error}`;
- if (node !== null) {
- node.hidden = false;
- node.textContent = errorString;
- _ankiSetErrorData(node, error);
+ for (const node of document.querySelectorAll('#anki-terms-model,#anki-kanji-model')) {
+ node.addEventListener('change', this._onModelChanged.bind(this), false);
}
- if (node2 !== null) {
- node2.hidden = (errorString.indexOf('Invalid response') < 0);
- }
- } else {
- if (node !== null) {
- node.hidden = true;
- node.textContent = '';
+ this.optionsChanged();
+ }
+
+ async optionsChanged(options=null) {
+ if (options === null) {
+ const optionsContext = getOptionsContext();
+ options = await getOptionsMutable(optionsContext);
}
- if (node2 !== null) {
- node2.hidden = true;
+ if (!options.anki.enable) {
+ return;
}
- }
-}
-function _ankiSetErrorData(node, error) {
- const data = error.data;
- let message = '';
- if (typeof data !== 'undefined') {
- message += `${JSON.stringify(data, null, 4)}\n\n`;
+ await this._deckAndModelPopulate(options);
+ await Promise.all([
+ this._fieldsPopulate('terms', options),
+ this._fieldsPopulate('kanji', options)
+ ]);
}
- message += `${error.stack}`.trimRight();
- const button = document.createElement('a');
- button.className = 'error-data-show-button';
-
- const content = document.createElement('div');
- content.className = 'error-data-container';
- content.textContent = message;
- content.hidden = true;
+ getFieldMarkers(type) {
+ switch (type) {
+ case 'terms':
+ return [
+ 'audio',
+ 'cloze-body',
+ 'cloze-prefix',
+ 'cloze-suffix',
+ 'dictionary',
+ 'document-title',
+ 'expression',
+ 'furigana',
+ 'furigana-plain',
+ 'glossary',
+ 'glossary-brief',
+ 'reading',
+ 'screenshot',
+ 'sentence',
+ 'tags',
+ 'url'
+ ];
+ case 'kanji':
+ return [
+ 'character',
+ 'dictionary',
+ 'document-title',
+ 'glossary',
+ 'kunyomi',
+ 'onyomi',
+ 'screenshot',
+ 'sentence',
+ 'tags',
+ 'url'
+ ];
+ default:
+ return [];
+ }
+ }
- button.addEventListener('click', () => content.hidden = !content.hidden, false);
+ getFieldMarkersHtml(markers) {
+ const template = document.querySelector('#anki-field-marker-template').content;
+ const fragment = document.createDocumentFragment();
+ for (const marker of markers) {
+ const markerNode = document.importNode(template, true).firstChild;
+ markerNode.querySelector('.marker-link').textContent = marker;
+ fragment.appendChild(markerNode);
+ }
+ return fragment;
+ }
- node.appendChild(button);
- node.appendChild(content);
-}
+ // Private
-function _ankiSetDropdownOptions(dropdown, optionValues) {
- const fragment = document.createDocumentFragment();
- for (const optionValue of optionValues) {
- const option = document.createElement('option');
- option.value = optionValue;
- option.textContent = optionValue;
- fragment.appendChild(option);
+ _fieldsToDict(elements) {
+ const result = {};
+ for (const element of elements) {
+ result[element.dataset.field] = element.value;
+ }
+ return result;
}
- dropdown.textContent = '';
- dropdown.appendChild(fragment);
-}
-async function _ankiDeckAndModelPopulate(options) {
- const termsDeck = {value: options.anki.terms.deck, selector: '#anki-terms-deck'};
- const kanjiDeck = {value: options.anki.kanji.deck, selector: '#anki-kanji-deck'};
- const termsModel = {value: options.anki.terms.model, selector: '#anki-terms-model'};
- const kanjiModel = {value: options.anki.kanji.model, selector: '#anki-kanji-model'};
- try {
- _ankiSpinnerShow(true);
- const [deckNames, modelNames] = await Promise.all([api.getAnkiDeckNames(), api.getAnkiModelNames()]);
- deckNames.sort();
- modelNames.sort();
- termsDeck.values = deckNames;
- kanjiDeck.values = deckNames;
- termsModel.values = modelNames;
- kanjiModel.values = modelNames;
- _ankiSetError(null);
- } catch (error) {
- _ankiSetError(error);
- } finally {
- _ankiSpinnerShow(false);
+ _spinnerShow(show) {
+ const spinner = $('#anki-spinner');
+ if (show) {
+ spinner.show();
+ } else {
+ spinner.hide();
+ }
}
- for (const {value, values, selector} of [termsDeck, kanjiDeck, termsModel, kanjiModel]) {
- const node = document.querySelector(selector);
- _ankiSetDropdownOptions(node, Array.isArray(values) ? values : [value]);
- node.value = value;
+ _setError(error) {
+ const node = document.querySelector('#anki-error');
+ const node2 = document.querySelector('#anki-invalid-response-error');
+ if (error) {
+ const errorString = `${error}`;
+ if (node !== null) {
+ node.hidden = false;
+ node.textContent = errorString;
+ this._setErrorData(node, error);
+ }
+
+ if (node2 !== null) {
+ node2.hidden = (errorString.indexOf('Invalid response') < 0);
+ }
+ } else {
+ if (node !== null) {
+ node.hidden = true;
+ node.textContent = '';
+ }
+
+ if (node2 !== null) {
+ node2.hidden = true;
+ }
+ }
}
-}
-
-function _ankiCreateFieldTemplate(name, value, markers) {
- const template = document.querySelector('#anki-field-template').content;
- const content = document.importNode(template, true).firstChild;
-
- content.querySelector('.anki-field-name').textContent = name;
-
- const field = content.querySelector('.anki-field-value');
- field.dataset.field = name;
- field.value = value;
- content.querySelector('.anki-field-marker-list').appendChild(ankiGetFieldMarkersHtml(markers));
+ _setErrorData(node, error) {
+ const data = error.data;
+ let message = '';
+ if (typeof data !== 'undefined') {
+ message += `${JSON.stringify(data, null, 4)}\n\n`;
+ }
+ message += `${error.stack}`.trimRight();
- return content;
-}
+ const button = document.createElement('a');
+ button.className = 'error-data-show-button';
-async function _ankiFieldsPopulate(tabId, options) {
- const tab = document.querySelector(`.tab-pane[data-anki-card-type=${tabId}]`);
- const container = tab.querySelector('tbody');
- const markers = ankiGetFieldMarkers(tabId);
-
- const fragment = document.createDocumentFragment();
- const fields = options.anki[tabId].fields;
- for (const name of Object.keys(fields)) {
- const value = fields[name];
- const html = _ankiCreateFieldTemplate(name, value, markers);
- fragment.appendChild(html);
- }
+ const content = document.createElement('div');
+ content.className = 'error-data-container';
+ content.textContent = message;
+ content.hidden = true;
- container.textContent = '';
- container.appendChild(fragment);
+ button.addEventListener('click', () => content.hidden = !content.hidden, false);
- for (const node of container.querySelectorAll('.anki-field-value')) {
- node.addEventListener('change', _onAnkiFieldsChanged, false);
- }
- for (const node of container.querySelectorAll('.marker-link')) {
- node.addEventListener('click', _onAnkiMarkerClicked, false);
+ node.appendChild(button);
+ node.appendChild(content);
}
-}
-
-function _onAnkiMarkerClicked(e) {
- e.preventDefault();
- const link = e.currentTarget;
- const input = $(link).closest('.input-group').find('.anki-field-value')[0];
- input.value = `{${link.textContent}}`;
- input.dispatchEvent(new Event('change'));
-}
-async function _onAnkiModelChanged(e) {
- const node = e.currentTarget;
- let fieldNames;
- try {
- const modelName = node.value;
- fieldNames = await api.getAnkiModelFieldNames(modelName);
- _ankiSetError(null);
- } catch (error) {
- _ankiSetError(error);
- return;
- } finally {
- _ankiSpinnerShow(false);
+ _setDropdownOptions(dropdown, optionValues) {
+ const fragment = document.createDocumentFragment();
+ for (const optionValue of optionValues) {
+ const option = document.createElement('option');
+ option.value = optionValue;
+ option.textContent = optionValue;
+ fragment.appendChild(option);
+ }
+ dropdown.textContent = '';
+ dropdown.appendChild(fragment);
}
- const tabId = node.dataset.ankiCardType;
- if (tabId !== 'terms' && tabId !== 'kanji') { return; }
+ async _deckAndModelPopulate(options) {
+ const termsDeck = {value: options.anki.terms.deck, selector: '#anki-terms-deck'};
+ const kanjiDeck = {value: options.anki.kanji.deck, selector: '#anki-kanji-deck'};
+ const termsModel = {value: options.anki.terms.model, selector: '#anki-terms-model'};
+ const kanjiModel = {value: options.anki.kanji.model, selector: '#anki-kanji-model'};
+ try {
+ this._spinnerShow(true);
+ const [deckNames, modelNames] = await Promise.all([api.getAnkiDeckNames(), api.getAnkiModelNames()]);
+ deckNames.sort();
+ modelNames.sort();
+ termsDeck.values = deckNames;
+ kanjiDeck.values = deckNames;
+ termsModel.values = modelNames;
+ kanjiModel.values = modelNames;
+ this._setError(null);
+ } catch (error) {
+ this._setError(error);
+ } finally {
+ this._spinnerShow(false);
+ }
- const fields = {};
- for (const name of fieldNames) {
- fields[name] = '';
+ for (const {value, values, selector} of [termsDeck, kanjiDeck, termsModel, kanjiModel]) {
+ const node = document.querySelector(selector);
+ this._setDropdownOptions(node, Array.isArray(values) ? values : [value]);
+ node.value = value;
+ }
}
- const optionsContext = getOptionsContext();
- const options = await getOptionsMutable(optionsContext);
- options.anki[tabId].fields = utilBackgroundIsolate(fields);
- await settingsSaveOptions();
-
- await _ankiFieldsPopulate(tabId, options);
-}
-
-async function _onAnkiFieldsChanged() {
- const optionsContext = getOptionsContext();
- const options = await getOptionsMutable(optionsContext);
-
- options.anki.terms.deck = $('#anki-terms-deck').val();
- options.anki.terms.model = $('#anki-terms-model').val();
- options.anki.terms.fields = utilBackgroundIsolate(ankiFieldsToDict(document.querySelectorAll('#terms .anki-field-value')));
- options.anki.kanji.deck = $('#anki-kanji-deck').val();
- options.anki.kanji.model = $('#anki-kanji-model').val();
- options.anki.kanji.fields = utilBackgroundIsolate(ankiFieldsToDict(document.querySelectorAll('#kanji .anki-field-value')));
+ _createFieldTemplate(name, value, markers) {
+ const template = document.querySelector('#anki-field-template').content;
+ const content = document.importNode(template, true).firstChild;
- await settingsSaveOptions();
+ content.querySelector('.anki-field-name').textContent = name;
- await onAnkiOptionsChanged(options);
-}
+ const field = content.querySelector('.anki-field-value');
+ field.dataset.field = name;
+ field.value = value;
+ content.querySelector('.anki-field-marker-list').appendChild(this.getFieldMarkersHtml(markers));
+ return content;
+ }
-// Public
+ async _fieldsPopulate(tabId, options) {
+ const tab = document.querySelector(`.tab-pane[data-anki-card-type=${tabId}]`);
+ const container = tab.querySelector('tbody');
+ const markers = this.getFieldMarkers(tabId);
+
+ const fragment = document.createDocumentFragment();
+ const fields = options.anki[tabId].fields;
+ for (const name of Object.keys(fields)) {
+ const value = fields[name];
+ const html = this._createFieldTemplate(name, value, markers);
+ fragment.appendChild(html);
+ }
-function ankiErrorShown() {
- const node = document.querySelector('#anki-error');
- return node && !node.hidden;
-}
+ container.textContent = '';
+ container.appendChild(fragment);
-function ankiFieldsToDict(elements) {
- const result = {};
- for (const element of elements) {
- result[element.dataset.field] = element.value;
+ for (const node of container.querySelectorAll('.anki-field-value')) {
+ node.addEventListener('change', this._onFieldsChanged.bind(this), false);
+ }
+ for (const node of container.querySelectorAll('.marker-link')) {
+ node.addEventListener('click', this._onMarkerClicked.bind(this), false);
+ }
}
- return result;
-}
-
-function ankiGetFieldMarkersHtml(markers) {
- const template = document.querySelector('#anki-field-marker-template').content;
- const fragment = document.createDocumentFragment();
- for (const marker of markers) {
- const markerNode = document.importNode(template, true).firstChild;
- markerNode.querySelector('.marker-link').textContent = marker;
- fragment.appendChild(markerNode);
+ _onMarkerClicked(e) {
+ e.preventDefault();
+ const link = e.currentTarget;
+ const input = $(link).closest('.input-group').find('.anki-field-value')[0];
+ input.value = `{${link.textContent}}`;
+ input.dispatchEvent(new Event('change'));
}
- return fragment;
-}
-function ankiGetFieldMarkers(type) {
- switch (type) {
- case 'terms':
- return [
- 'audio',
- 'cloze-body',
- 'cloze-prefix',
- 'cloze-suffix',
- 'dictionary',
- 'document-title',
- 'expression',
- 'furigana',
- 'furigana-plain',
- 'glossary',
- 'glossary-brief',
- 'reading',
- 'screenshot',
- 'sentence',
- 'tags',
- 'url'
- ];
- case 'kanji':
- return [
- 'character',
- 'dictionary',
- 'document-title',
- 'glossary',
- 'kunyomi',
- 'onyomi',
- 'screenshot',
- 'sentence',
- 'tags',
- 'url'
- ];
- default:
- return [];
- }
-}
+ async _onModelChanged(e) {
+ const node = e.currentTarget;
+ let fieldNames;
+ try {
+ const modelName = node.value;
+ fieldNames = await api.getAnkiModelFieldNames(modelName);
+ this._setError(null);
+ } catch (error) {
+ this._setError(error);
+ return;
+ } finally {
+ this._spinnerShow(false);
+ }
+ const tabId = node.dataset.ankiCardType;
+ if (tabId !== 'terms' && tabId !== 'kanji') { return; }
-function ankiInitialize() {
- $('#anki-fields-container input,#anki-fields-container select,#anki-fields-container textarea').change(_onAnkiFieldsChanged);
+ const fields = {};
+ for (const name of fieldNames) {
+ fields[name] = '';
+ }
- for (const node of document.querySelectorAll('#anki-terms-model,#anki-kanji-model')) {
- node.addEventListener('change', _onAnkiModelChanged, false);
- }
+ const optionsContext = getOptionsContext();
+ const options = await getOptionsMutable(optionsContext);
+ options.anki[tabId].fields = utilBackgroundIsolate(fields);
+ await settingsSaveOptions();
- onAnkiOptionsChanged();
-}
+ await this._fieldsPopulate(tabId, options);
+ }
-async function onAnkiOptionsChanged(options=null) {
- if (options === null) {
+ async _onFieldsChanged() {
const optionsContext = getOptionsContext();
- options = await getOptionsMutable(optionsContext);
- }
+ const options = await getOptionsMutable(optionsContext);
- if (!options.anki.enable) {
- return;
- }
+ options.anki.terms.deck = $('#anki-terms-deck').val();
+ options.anki.terms.model = $('#anki-terms-model').val();
+ options.anki.terms.fields = utilBackgroundIsolate(this._fieldsToDict(document.querySelectorAll('#terms .anki-field-value')));
+ options.anki.kanji.deck = $('#anki-kanji-deck').val();
+ options.anki.kanji.model = $('#anki-kanji-model').val();
+ options.anki.kanji.fields = utilBackgroundIsolate(this._fieldsToDict(document.querySelectorAll('#kanji .anki-field-value')));
+
+ await settingsSaveOptions();
- await _ankiDeckAndModelPopulate(options);
- await Promise.all([_ankiFieldsPopulate('terms', options), _ankiFieldsPopulate('kanji', options)]);
+ await this.optionsChanged(options);
+ }
}
diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js
index 64611ad5..872f8f05 100644
--- a/ext/bg/js/settings/main.js
+++ b/ext/bg/js/settings/main.js
@@ -16,17 +16,15 @@
*/
/* global
+ * AnkiController
+ * AnkiTemplatesController
* ProfileController
* SettingsBackup
* SettingsController
- * ankiInitialize
- * ankiTemplatesInitialize
- * ankiTemplatesUpdateValue
* api
* appearanceInitialize
* audioSettingsInitialize
* dictSettingsInitialize
- * onAnkiOptionsChanged
* onDictionaryOptionsChanged
* storageInfoInitialize
* utilBackend
@@ -269,9 +267,13 @@ async function onOptionsUpdated({source}) {
const options = await getOptionsMutable(optionsContext);
document.querySelector('#enable-clipboard-popups').checked = options.general.enableClipboardPopups;
- ankiTemplatesUpdateValue();
+ if (ankiTemplatesController !== null) {
+ ankiTemplatesController.updateValue();
+ }
onDictionaryOptionsChanged();
- onAnkiOptionsChanged();
+ if (ankiController !== null) {
+ ankiController.optionsChanged();
+ }
await formWrite(options);
}
@@ -302,6 +304,8 @@ async function settingsPopulateModifierKeys() {
}
}
+let ankiController = null;
+let ankiTemplatesController = null;
async function onReady() {
api.forwardLogsToBackend();
@@ -318,8 +322,10 @@ async function onReady() {
await audioSettingsInitialize();
await (new ProfileController()).prepare();
await dictSettingsInitialize();
- ankiInitialize();
- ankiTemplatesInitialize();
+ ankiController = new AnkiController();
+ ankiController.prepare();
+ ankiTemplatesController = new AnkiTemplatesController(ankiController);
+ ankiTemplatesController.prepare();
new SettingsBackup().prepare();
storageInfoInitialize();