aboutsummaryrefslogtreecommitdiff
path: root/ext/bg/js/settings/anki.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/bg/js/settings/anki.js')
-rw-r--r--ext/bg/js/settings/anki.js305
1 files changed, 0 insertions, 305 deletions
diff --git a/ext/bg/js/settings/anki.js b/ext/bg/js/settings/anki.js
deleted file mode 100644
index 0965e633..00000000
--- a/ext/bg/js/settings/anki.js
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2019-2020 Yomichan Authors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-/* global
- * api
- */
-
-class AnkiController {
- constructor(settingsController) {
- this._settingsController = settingsController;
- }
-
- async prepare() {
- for (const element of document.querySelectorAll('#anki-fields-container input,#anki-fields-container select')) {
- element.addEventListener('change', this._onFieldsChanged.bind(this), false);
- }
-
- for (const element of document.querySelectorAll('#anki-terms-model,#anki-kanji-model')) {
- element.addEventListener('change', this._onModelChanged.bind(this), false);
- }
-
- this._settingsController.on('optionsChanged', this._onOptionsChanged.bind(this));
-
- const options = await this._settingsController.getOptions();
- this._onOptionsChanged({options});
- }
-
- getFieldMarkers(type) {
- switch (type) {
- case 'terms':
- return [
- 'audio',
- 'clipboard-image',
- 'cloze-body',
- 'cloze-prefix',
- 'cloze-suffix',
- 'dictionary',
- 'document-title',
- 'expression',
- 'furigana',
- 'furigana-plain',
- 'glossary',
- 'glossary-brief',
- 'pitch-accents',
- 'pitch-accent-graphs',
- 'pitch-accent-positions',
- 'reading',
- 'screenshot',
- 'sentence',
- 'tags',
- 'url'
- ];
- case 'kanji':
- return [
- 'character',
- 'clipboard-image',
- 'cloze-body',
- 'cloze-prefix',
- 'cloze-suffix',
- 'dictionary',
- 'document-title',
- 'glossary',
- 'kunyomi',
- 'onyomi',
- 'screenshot',
- 'sentence',
- 'tags',
- 'url'
- ];
- default:
- return [];
- }
- }
-
- 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;
- }
-
- // Private
-
- async _onOptionsChanged({options}) {
- if (!options.anki.enable) {
- return;
- }
-
- await this._deckAndModelPopulate(options);
- await Promise.all([
- this._populateFields('terms', options.anki.terms.fields),
- this._populateFields('kanji', options.anki.kanji.fields)
- ]);
- }
-
- _fieldsToDict(elements) {
- const result = {};
- for (const element of elements) {
- result[element.dataset.field] = element.value;
- }
- return result;
- }
-
- _spinnerShow(show) {
- const spinner = document.querySelector('#anki-spinner');
- spinner.hidden = !show;
- }
-
- _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;
- }
- }
- }
-
- _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();
-
- 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;
-
- button.addEventListener('click', () => content.hidden = !content.hidden, false);
-
- node.appendChild(button);
- node.appendChild(content);
- }
-
- _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);
- }
-
- 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);
- }
-
- 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;
- }
- }
-
- _createFieldTemplate(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(this.getFieldMarkersHtml(markers));
-
- return content;
- }
-
- async _populateFields(tabId, fields) {
- 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();
- for (const [name, value] of Object.entries(fields)) {
- const html = this._createFieldTemplate(name, value, markers);
- fragment.appendChild(html);
- }
-
- container.textContent = '';
- container.appendChild(fragment);
-
- 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);
- }
- }
-
- _onMarkerClicked(e) {
- e.preventDefault();
- const link = e.currentTarget;
- const input = link.closest('.input-group').querySelector('.anki-field-value');
- input.value = `{${link.textContent}}`;
- input.dispatchEvent(new Event('change'));
- }
-
- 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; }
-
- const fields = {};
- for (const name of fieldNames) {
- fields[name] = '';
- }
-
- await this._settingsController.setProfileSetting(`anki["${tabId}"].fields`, fields);
- await this._populateFields(tabId, fields);
- }
-
- async _onFieldsChanged() {
- const termsDeck = document.querySelector('#anki-terms-deck').value;
- const termsModel = document.querySelector('#anki-terms-model').value;
- const termsFields = this._fieldsToDict(document.querySelectorAll('#terms .anki-field-value'));
- const kanjiDeck = document.querySelector('#anki-kanji-deck').value;
- const kanjiModel = document.querySelector('#anki-kanji-model').value;
- const kanjiFields = this._fieldsToDict(document.querySelectorAll('#kanji .anki-field-value'));
-
- const targets = [
- {action: 'set', path: 'anki.terms.deck', value: termsDeck},
- {action: 'set', path: 'anki.terms.model', value: termsModel},
- {action: 'set', path: 'anki.terms.fields', value: termsFields},
- {action: 'set', path: 'anki.kanji.deck', value: kanjiDeck},
- {action: 'set', path: 'anki.kanji.model', value: kanjiModel},
- {action: 'set', path: 'anki.kanji.fields', value: kanjiFields}
- ];
-
- await this._settingsController.modifyProfileSettings(targets);
- }
-}