From 25c590e54b3086558c10765a4df6f1ddea00fc54 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 10 Oct 2020 20:58:38 -0400 Subject: [PATCH] Add modal controller class (#908) * Add ModalController * Use modalController instead of new Modal --- .../js/settings/anki-templates-controller.js | 5 +- ext/bg/js/settings/backup-controller.js | 9 +-- ext/bg/js/settings/dictionary-controller.js | 5 +- .../settings/dictionary-import-controller.js | 5 +- ext/bg/js/settings/main.js | 14 ++-- ext/bg/js/settings/modal-controller.js | 66 +++++++++++++++++++ ext/bg/js/settings/profile-controller.js | 7 +- ext/bg/settings.html | 1 + 8 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 ext/bg/js/settings/modal-controller.js diff --git a/ext/bg/js/settings/anki-templates-controller.js b/ext/bg/js/settings/anki-templates-controller.js index f2e5be43..65900336 100644 --- a/ext/bg/js/settings/anki-templates-controller.js +++ b/ext/bg/js/settings/anki-templates-controller.js @@ -23,8 +23,9 @@ */ class AnkiTemplatesController { - constructor(settingsController, ankiController) { + constructor(settingsController, modalController, ankiController) { this._settingsController = settingsController; + this._modalController = modalController; this._ankiController = ankiController; this._cachedDefinitionValue = null; this._cachedDefinitionText = null; @@ -36,7 +37,7 @@ class AnkiTemplatesController { async prepare() { this._defaultFieldTemplates = await api.getDefaultAnkiFieldTemplates(); - this._fieldTemplateResetModal = new Modal(document.querySelector('#field-template-reset-modal')); + this._fieldTemplateResetModal = this._modalController.getModal('field-template-reset-modal'); const markers = new Set([ ...this._ankiController.getFieldMarkers('terms'), diff --git a/ext/bg/js/settings/backup-controller.js b/ext/bg/js/settings/backup-controller.js index 80f83eb7..50390d5c 100644 --- a/ext/bg/js/settings/backup-controller.js +++ b/ext/bg/js/settings/backup-controller.js @@ -22,8 +22,9 @@ */ class BackupController { - constructor(settingsController) { + constructor(settingsController, modalController) { this._settingsController = settingsController; + this._modalController = modalController; this._settingsExportToken = null; this._settingsExportRevoke = null; this._currentVersion = 0; @@ -36,9 +37,9 @@ class BackupController { async prepare() { await this._optionsUtil.prepare(); - this._settingsResetModal = new Modal(document.querySelector('#settings-reset-modal')); - this._settingsImportErrorModal = new Modal(document.querySelector('#settings-import-error-modal')); - this._settingsImportWarningModal = new Modal(document.querySelector('#settings-import-warning-modal')); + this._settingsResetModal = this._modalController.getModal('settings-reset-modal'); + this._settingsImportErrorModal = this._modalController.getModal('settings-import-error-modal'); + this._settingsImportWarningModal = this._modalController.getModal('settings-import-warning-modal'); document.querySelector('#settings-export').addEventListener('click', this._onSettingsExportClick.bind(this), false); document.querySelector('#settings-import').addEventListener('click', this._onSettingsImportClick.bind(this), false); diff --git a/ext/bg/js/settings/dictionary-controller.js b/ext/bg/js/settings/dictionary-controller.js index cbbd0a8e..34a4b933 100644 --- a/ext/bg/js/settings/dictionary-controller.js +++ b/ext/bg/js/settings/dictionary-controller.js @@ -144,8 +144,9 @@ class DictionaryEntry { } class DictionaryController { - constructor(settingsController) { + constructor(settingsController, modalController) { this._settingsController = settingsController; + this._modalController = modalController; this._dictionaries = null; this._dictionaryEntries = []; this._databaseStateToken = null; @@ -166,7 +167,7 @@ class DictionaryController { this._checkIntegrityButton = document.querySelector('#dict-check-integrity'); this._dictionaryEntryContainer = document.querySelector('#dict-groups'); this._integrityExtraInfoContainer = document.querySelector('#dict-groups-extra'); - this._deleteDictionaryModal = new Modal(document.querySelector('#dict-delete-modal')); + this._deleteDictionaryModal = this._modalController.getModal('dict-delete-modal'); yomichan.on('databaseUpdated', this._onDatabaseUpdated.bind(this)); diff --git a/ext/bg/js/settings/dictionary-import-controller.js b/ext/bg/js/settings/dictionary-import-controller.js index a78378e8..2c954ef8 100644 --- a/ext/bg/js/settings/dictionary-import-controller.js +++ b/ext/bg/js/settings/dictionary-import-controller.js @@ -24,8 +24,9 @@ */ class DictionaryImportController { - constructor(settingsController, storageController) { + constructor(settingsController, modalController, storageController) { this._settingsController = settingsController; + this._modalController = modalController; this._storageController = storageController; this._modifying = false; this._purgeButton = null; @@ -54,7 +55,7 @@ class DictionaryImportController { this._purgeConfirmButton = document.querySelector('#dict-purge-confirm'); this._importFileButton = document.querySelector('#dict-file-button'); this._importFileInput = document.querySelector('#dict-file'); - this._purgeConfirmModal = new Modal(document.querySelector('#dict-purge-modal')); + this._purgeConfirmModal = this._modalController.getModal('dict-purge-modal'); this._errorContainer = document.querySelector('#dict-error'); this._spinner = document.querySelector('#dict-spinner'); this._progressContainer = document.querySelector('#dict-import-progress'); diff --git a/ext/bg/js/settings/main.js b/ext/bg/js/settings/main.js index 37c6375d..3b2ff29d 100644 --- a/ext/bg/js/settings/main.js +++ b/ext/bg/js/settings/main.js @@ -24,6 +24,7 @@ * DictionaryController * DictionaryImportController * GenericSettingController + * ModalController * PopupPreviewController * ProfileController * ScanInputsController @@ -57,6 +58,9 @@ async function setupEnvironmentInfo() { const optionsFull = await api.optionsGetFull(); + const modalController = new ModalController(); + modalController.prepare(); + const settingsController = new SettingsController(optionsFull.profileCurrent); settingsController.prepare(); @@ -75,22 +79,22 @@ async function setupEnvironmentInfo() { const audioController = new AudioController(settingsController); audioController.prepare(); - const profileController = new ProfileController(settingsController); + const profileController = new ProfileController(settingsController, modalController); profileController.prepare(); - const dictionaryController = new DictionaryController(settingsController); + const dictionaryController = new DictionaryController(settingsController, modalController); dictionaryController.prepare(); - const dictionaryImportController = new DictionaryImportController(settingsController, storageController); + const dictionaryImportController = new DictionaryImportController(settingsController, modalController, storageController); dictionaryImportController.prepare(); const ankiController = new AnkiController(settingsController); ankiController.prepare(); - const ankiTemplatesController = new AnkiTemplatesController(settingsController, ankiController); + const ankiTemplatesController = new AnkiTemplatesController(settingsController, modalController, ankiController); ankiTemplatesController.prepare(); - const settingsBackup = new BackupController(settingsController); + const settingsBackup = new BackupController(settingsController, modalController); settingsBackup.prepare(); const scanInputsController = new ScanInputsController(settingsController); diff --git a/ext/bg/js/settings/modal-controller.js b/ext/bg/js/settings/modal-controller.js new file mode 100644 index 00000000..d604b050 --- /dev/null +++ b/ext/bg/js/settings/modal-controller.js @@ -0,0 +1,66 @@ +/* + * Copyright (C) 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 . + */ + +/* global + * Modal + */ + +class ModalController { + constructor() { + this._modals = []; + this._modalMap = new Map(); + } + + prepare() { + for (const node of document.querySelectorAll('.modal')) { + const {id} = node; + const modal = new Modal(node); + this._modalMap.set(id, modal); + this._modals.push(modal); + } + + for (const node of document.querySelectorAll('.modal-container')) { + const {id} = node; + const modal = new Modal(node); + this._modalMap.set(id, modal); + this._modals.push(modal); + node.addEventListener('click', this._onModalContainerClick.bind(this, modal), false); + } + } + + getModal(name) { + const modal = this._modalMap.get(name); + return (typeof modal !== 'undefined' ? modal : null); + } + + getTopVisibleModal() { + for (let i = this._modals.length - 1; i >= 0; --i) { + const modal = this._modals[i]; + if (modal.isVisible()) { + return modal; + } + } + return null; + } + + // Private + + _onModalContainerClick(modal, e) { + if (e.currentTarget !== e.target) { return; } + modal.setVisible(false); + } +} diff --git a/ext/bg/js/settings/profile-controller.js b/ext/bg/js/settings/profile-controller.js index 7c6dfae5..63a82c40 100644 --- a/ext/bg/js/settings/profile-controller.js +++ b/ext/bg/js/settings/profile-controller.js @@ -22,8 +22,9 @@ */ class ProfileController { - constructor(settingsController) { + constructor(settingsController, modalController) { this._settingsController = settingsController; + this._modalController = modalController; this._profileConditionsUI = new ProfileConditionsUI(settingsController); this._profileActiveSelect = null; this._profileTargetSelect = null; @@ -52,8 +53,8 @@ class ProfileController { this._profileCopyButton = document.querySelector('#profile-copy'); this._profileMoveUpButton = document.querySelector('#profile-move-up'); this._profileMoveDownButton = document.querySelector('#profile-move-down'); - this._profileRemoveModal = new Modal(document.querySelector('#profile-remove-modal')); - this._profileCopyModal = new Modal(document.querySelector('#profile-copy-modal')); + this._profileRemoveModal = this._modalController.getModal('profile-remove-modal'); + this._profileCopyModal = this._modalController.getModal('profile-copy-modal'); this._profileActiveSelect.addEventListener('change', this._onProfileActiveChange.bind(this), false); this._profileTargetSelect.addEventListener('change', this._onProfileTargetChange.bind(this), false); diff --git a/ext/bg/settings.html b/ext/bg/settings.html index c36bd8bf..18e3e389 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -1246,6 +1246,7 @@ +