parent
613c7ebf69
commit
2ff4f83072
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
/* global
|
/* global
|
||||||
* AnkiNoteBuilder
|
* AnkiNoteBuilder
|
||||||
|
* Modal
|
||||||
* TemplateRendererProxy
|
* TemplateRendererProxy
|
||||||
* api
|
* api
|
||||||
*/
|
*/
|
||||||
@ -28,12 +29,15 @@ class AnkiTemplatesController {
|
|||||||
this._cachedDefinitionValue = null;
|
this._cachedDefinitionValue = null;
|
||||||
this._cachedDefinitionText = null;
|
this._cachedDefinitionText = null;
|
||||||
this._defaultFieldTemplates = null;
|
this._defaultFieldTemplates = null;
|
||||||
|
this._fieldTemplateResetModal = null;
|
||||||
this._templateRenderer = new TemplateRendererProxy();
|
this._templateRenderer = new TemplateRendererProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
async prepare() {
|
async prepare() {
|
||||||
this._defaultFieldTemplates = await api.getDefaultAnkiFieldTemplates();
|
this._defaultFieldTemplates = await api.getDefaultAnkiFieldTemplates();
|
||||||
|
|
||||||
|
this._fieldTemplateResetModal = new Modal(document.querySelector('#field-template-reset-modal'));
|
||||||
|
|
||||||
const markers = new Set([
|
const markers = new Set([
|
||||||
...this._ankiController.getFieldMarkers('terms'),
|
...this._ankiController.getFieldMarkers('terms'),
|
||||||
...this._ankiController.getFieldMarkers('kanji')
|
...this._ankiController.getFieldMarkers('kanji')
|
||||||
@ -69,13 +73,13 @@ class AnkiTemplatesController {
|
|||||||
|
|
||||||
_onReset(e) {
|
_onReset(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$('#field-template-reset-modal').modal('show');
|
this._fieldTemplateResetModal.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onResetConfirm(e) {
|
_onResetConfirm(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
$('#field-template-reset-modal').modal('hide');
|
this._fieldTemplateResetModal.setVisible(false);
|
||||||
|
|
||||||
const value = this._defaultFieldTemplates;
|
const value = this._defaultFieldTemplates;
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* global
|
/* global
|
||||||
|
* Modal
|
||||||
* OptionsUtil
|
* OptionsUtil
|
||||||
* api
|
* api
|
||||||
*/
|
*/
|
||||||
@ -26,12 +27,19 @@ class BackupController {
|
|||||||
this._settingsExportToken = null;
|
this._settingsExportToken = null;
|
||||||
this._settingsExportRevoke = null;
|
this._settingsExportRevoke = null;
|
||||||
this._currentVersion = 0;
|
this._currentVersion = 0;
|
||||||
|
this._settingsResetModal = null;
|
||||||
|
this._settingsImportErrorModal = null;
|
||||||
|
this._settingsImportWarningModal = null;
|
||||||
this._optionsUtil = new OptionsUtil();
|
this._optionsUtil = new OptionsUtil();
|
||||||
}
|
}
|
||||||
|
|
||||||
async prepare() {
|
async prepare() {
|
||||||
await this._optionsUtil.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'));
|
||||||
|
|
||||||
document.querySelector('#settings-export').addEventListener('click', this._onSettingsExportClick.bind(this), false);
|
document.querySelector('#settings-export').addEventListener('click', this._onSettingsExportClick.bind(this), false);
|
||||||
document.querySelector('#settings-import').addEventListener('click', this._onSettingsImportClick.bind(this), false);
|
document.querySelector('#settings-import').addEventListener('click', this._onSettingsImportClick.bind(this), false);
|
||||||
document.querySelector('#settings-import-file').addEventListener('change', this._onSettingsImportFileChange.bind(this), false);
|
document.querySelector('#settings-import-file').addEventListener('change', this._onSettingsImportFileChange.bind(this), false);
|
||||||
@ -153,14 +161,14 @@ class BackupController {
|
|||||||
_showSettingsImportError(error) {
|
_showSettingsImportError(error) {
|
||||||
yomichan.logError(error);
|
yomichan.logError(error);
|
||||||
document.querySelector('#settings-import-error-modal-message').textContent = `${error}`;
|
document.querySelector('#settings-import-error-modal-message').textContent = `${error}`;
|
||||||
$('#settings-import-error-modal').modal('show');
|
this._settingsImportErrorModal.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _showSettingsImportWarnings(warnings) {
|
async _showSettingsImportWarnings(warnings) {
|
||||||
const modalNode = $('#settings-import-warning-modal');
|
const modal = this._settingsImportWarningModal;
|
||||||
const buttons = document.querySelectorAll('.settings-import-warning-modal-import-button');
|
const buttons = document.querySelectorAll('.settings-import-warning-modal-import-button');
|
||||||
const messageContainer = document.querySelector('#settings-import-warning-modal-message');
|
const messageContainer = document.querySelector('#settings-import-warning-modal-message');
|
||||||
if (modalNode.length === 0 || buttons.length === 0 || messageContainer === null) {
|
if (buttons.length === 0 || messageContainer === null) {
|
||||||
return {result: false};
|
return {result: false};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +183,7 @@ class BackupController {
|
|||||||
messageContainer.appendChild(fragment);
|
messageContainer.appendChild(fragment);
|
||||||
|
|
||||||
// Show modal
|
// Show modal
|
||||||
modalNode.modal('show');
|
modal.setVisible(true);
|
||||||
|
|
||||||
// Wait for modal to close
|
// Wait for modal to close
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
@ -185,9 +193,10 @@ class BackupController {
|
|||||||
result: true,
|
result: true,
|
||||||
sanitize: e.currentTarget.dataset.importSanitize === 'true'
|
sanitize: e.currentTarget.dataset.importSanitize === 'true'
|
||||||
});
|
});
|
||||||
modalNode.modal('hide');
|
modal.setVisible(false);
|
||||||
};
|
};
|
||||||
const onModalHide = () => {
|
const onModalVisibilityChanged = ({visible}) => {
|
||||||
|
if (visible) { return; }
|
||||||
complete({result: false});
|
complete({result: false});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -196,7 +205,7 @@ class BackupController {
|
|||||||
if (completed) { return; }
|
if (completed) { return; }
|
||||||
completed = true;
|
completed = true;
|
||||||
|
|
||||||
modalNode.off('hide.bs.modal', onModalHide);
|
modal.off('visibilityChanged', onModalVisibilityChanged);
|
||||||
for (const button of buttons) {
|
for (const button of buttons) {
|
||||||
button.removeEventListener('click', onButtonClick, false);
|
button.removeEventListener('click', onButtonClick, false);
|
||||||
}
|
}
|
||||||
@ -205,7 +214,7 @@ class BackupController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Hook events
|
// Hook events
|
||||||
modalNode.on('hide.bs.modal', onModalHide);
|
modal.on('visibilityChanged', onModalVisibilityChanged);
|
||||||
for (const button of buttons) {
|
for (const button of buttons) {
|
||||||
button.addEventListener('click', onButtonClick, false);
|
button.addEventListener('click', onButtonClick, false);
|
||||||
}
|
}
|
||||||
@ -368,11 +377,11 @@ class BackupController {
|
|||||||
// Resetting
|
// Resetting
|
||||||
|
|
||||||
_onSettingsResetClick() {
|
_onSettingsResetClick() {
|
||||||
$('#settings-reset-modal').modal('show');
|
this._settingsResetModal.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onSettingsResetConfirmClick() {
|
async _onSettingsResetConfirmClick() {
|
||||||
$('#settings-reset-modal').modal('hide');
|
this._settingsResetModal.setVisible(false);
|
||||||
|
|
||||||
// Get default options
|
// Get default options
|
||||||
const optionsFull = this._optionsUtil.getDefault();
|
const optionsFull = this._optionsUtil.getDefault();
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* global
|
/* global
|
||||||
|
* Modal
|
||||||
* ObjectPropertyAccessor
|
* ObjectPropertyAccessor
|
||||||
* api
|
* api
|
||||||
*/
|
*/
|
||||||
@ -164,7 +165,7 @@ class DictionaryController {
|
|||||||
this._checkIntegrityButton = document.querySelector('#dict-check-integrity');
|
this._checkIntegrityButton = document.querySelector('#dict-check-integrity');
|
||||||
this._dictionaryEntryContainer = document.querySelector('#dict-groups');
|
this._dictionaryEntryContainer = document.querySelector('#dict-groups');
|
||||||
this._integrityExtraInfoContainer = document.querySelector('#dict-groups-extra');
|
this._integrityExtraInfoContainer = document.querySelector('#dict-groups-extra');
|
||||||
this._deleteDictionaryModal = document.querySelector('#dict-delete-modal');
|
this._deleteDictionaryModal = new Modal(document.querySelector('#dict-delete-modal'));
|
||||||
|
|
||||||
yomichan.on('databaseUpdated', this._onDatabaseUpdated.bind(this));
|
yomichan.on('databaseUpdated', this._onDatabaseUpdated.bind(this));
|
||||||
|
|
||||||
@ -177,9 +178,9 @@ class DictionaryController {
|
|||||||
deleteDictionary(dictionaryTitle) {
|
deleteDictionary(dictionaryTitle) {
|
||||||
if (this._isDeleting) { return; }
|
if (this._isDeleting) { return; }
|
||||||
const modal = this._deleteDictionaryModal;
|
const modal = this._deleteDictionaryModal;
|
||||||
modal.dataset.dictionaryTitle = dictionaryTitle;
|
modal.node.dataset.dictionaryTitle = dictionaryTitle;
|
||||||
modal.querySelector('#dict-remove-modal-dict-name').textContent = dictionaryTitle;
|
modal.node.querySelector('#dict-remove-modal-dict-name').textContent = dictionaryTitle;
|
||||||
this._setModalVisible(modal, true);
|
modal.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
@ -209,11 +210,11 @@ class DictionaryController {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const modal = this._deleteDictionaryModal;
|
const modal = this._deleteDictionaryModal;
|
||||||
this._setModalVisible(modal, false);
|
modal.setVisible(false);
|
||||||
|
|
||||||
const title = modal.dataset.dictionaryTitle;
|
const title = modal.node.dataset.dictionaryTitle;
|
||||||
if (typeof title !== 'string') { return; }
|
if (typeof title !== 'string') { return; }
|
||||||
delete modal.dataset.dictionaryTitle;
|
delete modal.node.dataset.dictionaryTitle;
|
||||||
|
|
||||||
this._deleteDictionary(title);
|
this._deleteDictionary(title);
|
||||||
}
|
}
|
||||||
@ -223,10 +224,6 @@ class DictionaryController {
|
|||||||
this._checkIntegrity();
|
this._checkIntegrity();
|
||||||
}
|
}
|
||||||
|
|
||||||
_setModalVisible(node, visible) {
|
|
||||||
$(node).modal(visible ? 'show' : 'hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateMainDictionarySelectOptions(dictionaries) {
|
_updateMainDictionarySelectOptions(dictionaries) {
|
||||||
const fragment = document.createDocumentFragment();
|
const fragment = document.createDocumentFragment();
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
/* global
|
/* global
|
||||||
* DictionaryDatabase
|
* DictionaryDatabase
|
||||||
* DictionaryImporter
|
* DictionaryImporter
|
||||||
|
* Modal
|
||||||
* ObjectPropertyAccessor
|
* ObjectPropertyAccessor
|
||||||
* api
|
* api
|
||||||
*/
|
*/
|
||||||
@ -53,7 +54,7 @@ class DictionaryImportController {
|
|||||||
this._purgeConfirmButton = document.querySelector('#dict-purge-confirm');
|
this._purgeConfirmButton = document.querySelector('#dict-purge-confirm');
|
||||||
this._importFileButton = document.querySelector('#dict-file-button');
|
this._importFileButton = document.querySelector('#dict-file-button');
|
||||||
this._importFileInput = document.querySelector('#dict-file');
|
this._importFileInput = document.querySelector('#dict-file');
|
||||||
this._purgeConfirmModal = document.querySelector('#dict-purge-modal');
|
this._purgeConfirmModal = new Modal(document.querySelector('#dict-purge-modal'));
|
||||||
this._errorContainer = document.querySelector('#dict-error');
|
this._errorContainer = document.querySelector('#dict-error');
|
||||||
this._spinner = document.querySelector('#dict-spinner');
|
this._spinner = document.querySelector('#dict-spinner');
|
||||||
this._progressContainer = document.querySelector('#dict-import-progress');
|
this._progressContainer = document.querySelector('#dict-import-progress');
|
||||||
@ -75,12 +76,12 @@ class DictionaryImportController {
|
|||||||
|
|
||||||
_onPurgeButtonClick(e) {
|
_onPurgeButtonClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._setPurgeModalVisible(true);
|
this._purgeConfirmModal.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onPurgeConfirmButtonClick(e) {
|
_onPurgeConfirmButtonClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._setPurgeModalVisible(false);
|
this._purgeConfirmModal.setVisible(false);
|
||||||
this._purgeDatabase();
|
this._purgeDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,11 +221,6 @@ class DictionaryImportController {
|
|||||||
return await this._modifyGlobalSettings(targets);
|
return await this._modifyGlobalSettings(targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
_setPurgeModalVisible(visible) {
|
|
||||||
const node = $(this._purgeConfirmModal);
|
|
||||||
node.modal(visible ? 'show' : 'hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
_setSpinnerVisible(visible) {
|
_setSpinnerVisible(visible) {
|
||||||
this._spinner.hidden = !visible;
|
this._spinner.hidden = !visible;
|
||||||
}
|
}
|
||||||
|
65
ext/bg/js/settings/modal.js
Normal file
65
ext/bg/js/settings/modal.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Modal extends EventDispatcher {
|
||||||
|
constructor(node) {
|
||||||
|
super();
|
||||||
|
this._node = node;
|
||||||
|
this._eventListeners = new EventListenerCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
get node() {
|
||||||
|
return this._node;
|
||||||
|
}
|
||||||
|
|
||||||
|
setVisible(value) {
|
||||||
|
this._getWrappedNode().modal(value ? 'show' : 'hide');
|
||||||
|
}
|
||||||
|
|
||||||
|
on(eventName, callback) {
|
||||||
|
if (eventName === 'visibilityChanged') {
|
||||||
|
if (this._eventListeners.size === 0) {
|
||||||
|
const wrappedNode = this._getWrappedNode();
|
||||||
|
this._eventListeners.on(wrappedNode, 'hidden.bs.modal', this._onModalHide.bind(this));
|
||||||
|
this._eventListeners.on(wrappedNode, 'shown.bs.modal', this._onModalShow.bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.on(eventName, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
off(eventName, callback) {
|
||||||
|
const result = super.off(eventName, callback);
|
||||||
|
if (eventName === 'visibilityChanged' && !this.hasListeners(eventName)) {
|
||||||
|
this._eventListeners.removeAllEventListeners();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private
|
||||||
|
|
||||||
|
_onModalHide() {
|
||||||
|
this.trigger('visibilityChanged', {visible: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
_onModalShow() {
|
||||||
|
this.trigger('visibilityChanged', {visible: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
_getWrappedNode() {
|
||||||
|
return $(this._node);
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* global
|
/* global
|
||||||
|
* Modal
|
||||||
* ProfileConditionsUI
|
* ProfileConditionsUI
|
||||||
* api
|
* api
|
||||||
*/
|
*/
|
||||||
@ -51,8 +52,8 @@ class ProfileController {
|
|||||||
this._profileCopyButton = document.querySelector('#profile-copy');
|
this._profileCopyButton = document.querySelector('#profile-copy');
|
||||||
this._profileMoveUpButton = document.querySelector('#profile-move-up');
|
this._profileMoveUpButton = document.querySelector('#profile-move-up');
|
||||||
this._profileMoveDownButton = document.querySelector('#profile-move-down');
|
this._profileMoveDownButton = document.querySelector('#profile-move-down');
|
||||||
this._profileRemoveModal = document.querySelector('#profile-remove-modal');
|
this._profileRemoveModal = new Modal(document.querySelector('#profile-remove-modal'));
|
||||||
this._profileCopyModal = document.querySelector('#profile-copy-modal');
|
this._profileCopyModal = new Modal(document.querySelector('#profile-copy-modal'));
|
||||||
|
|
||||||
this._profileActiveSelect.addEventListener('change', this._onProfileActiveChange.bind(this), false);
|
this._profileActiveSelect.addEventListener('change', this._onProfileActiveChange.bind(this), false);
|
||||||
this._profileTargetSelect.addEventListener('change', this._onProfileTargetChange.bind(this), false);
|
this._profileTargetSelect.addEventListener('change', this._onProfileTargetChange.bind(this), false);
|
||||||
@ -135,11 +136,11 @@ class ProfileController {
|
|||||||
const profileIndex = this._settingsController.profileIndex;
|
const profileIndex = this._settingsController.profileIndex;
|
||||||
const profile = this._optionsFull.profiles[profileIndex];
|
const profile = this._optionsFull.profiles[profileIndex];
|
||||||
this._removeProfileNameElement.textContent = profile.name;
|
this._removeProfileNameElement.textContent = profile.name;
|
||||||
this._setModalVisible(this._profileRemoveModal, true);
|
this._profileRemoveModal.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRemoveConfirm() {
|
_onRemoveConfirm() {
|
||||||
this._setModalVisible(this._profileRemoveModal, false);
|
this._profileRemoveModal.setVisible(false);
|
||||||
if (this._optionsFull.profiles.length <= 1) { return; }
|
if (this._optionsFull.profiles.length <= 1) { return; }
|
||||||
const profileIndex = this._settingsController.profileIndex;
|
const profileIndex = this._settingsController.profileIndex;
|
||||||
this._removeProfile(profileIndex);
|
this._removeProfile(profileIndex);
|
||||||
@ -160,11 +161,11 @@ class ProfileController {
|
|||||||
}
|
}
|
||||||
this._profileCopySourceSelect.value = `${copyFromIndex}`;
|
this._profileCopySourceSelect.value = `${copyFromIndex}`;
|
||||||
|
|
||||||
this._setModalVisible(this._profileCopyModal, true);
|
this._profileCopyModal.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCopyConfirm() {
|
_onCopyConfirm() {
|
||||||
this._setModalVisible(this._profileCopyModal, false);
|
this._profileCopyModal.setVisible(false);
|
||||||
|
|
||||||
const profileIndex = this._settingsController.profileIndex;
|
const profileIndex = this._settingsController.profileIndex;
|
||||||
const max = this._optionsFull.profiles.length;
|
const max = this._optionsFull.profiles.length;
|
||||||
@ -265,10 +266,6 @@ class ProfileController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_setModalVisible(node, visible) {
|
|
||||||
$(node).modal(visible ? 'show' : 'hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
async _addProfile() {
|
async _addProfile() {
|
||||||
const profileIndex = this._settingsController.profileIndex;
|
const profileIndex = this._settingsController.profileIndex;
|
||||||
const profiles = this._optionsFull.profiles;
|
const profiles = this._optionsFull.profiles;
|
||||||
|
@ -1216,6 +1216,7 @@
|
|||||||
<script src="/bg/js/template-renderer-proxy.js"></script>
|
<script src="/bg/js/template-renderer-proxy.js"></script>
|
||||||
|
|
||||||
<script src="/bg/js/settings/keyboard-mouse-input-field.js"></script>
|
<script src="/bg/js/settings/keyboard-mouse-input-field.js"></script>
|
||||||
|
<script src="/bg/js/settings/modal.js"></script>
|
||||||
<script src="/bg/js/settings/profile-conditions-ui.js"></script>
|
<script src="/bg/js/settings/profile-conditions-ui.js"></script>
|
||||||
|
|
||||||
<script src="/bg/js/settings/anki-controller.js"></script>
|
<script src="/bg/js/settings/anki-controller.js"></script>
|
||||||
|
@ -325,6 +325,11 @@ class EventDispatcher {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasListeners(eventName) {
|
||||||
|
const callbacks = this._eventMap.get(eventName);
|
||||||
|
return (typeof callbacks !== 'undefined' && callbacks.length > 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EventListenerCollection {
|
class EventListenerCollection {
|
||||||
|
Loading…
Reference in New Issue
Block a user