diff options
| -rw-r--r-- | ext/bg/js/settings/anki-templates.js | 216 | ||||
| -rw-r--r-- | ext/bg/js/settings/anki.js | 464 | ||||
| -rw-r--r-- | ext/bg/js/settings/main.js | 22 | 
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(); |