From b418760a521033dd0939194ab8cfef3dbeac29fc Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 5 Dec 2019 22:36:59 -0500 Subject: Simplify audio settings UI --- ext/bg/js/audio-ui.js | 131 -------------------------------------- ext/bg/js/settings/audio-ui.js | 141 +++++++++++++++++++++++++++++++++++++++++ ext/bg/js/settings/audio.js | 41 +++++++----- ext/bg/settings.html | 4 +- 4 files changed, 169 insertions(+), 148 deletions(-) delete mode 100644 ext/bg/js/audio-ui.js create mode 100644 ext/bg/js/settings/audio-ui.js (limited to 'ext/bg') diff --git a/ext/bg/js/audio-ui.js b/ext/bg/js/audio-ui.js deleted file mode 100644 index 381129ac..00000000 --- a/ext/bg/js/audio-ui.js +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2019 Alex Yatskov - * Author: Alex Yatskov - * - * 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 . - */ - - -class AudioSourceUI { - static instantiateTemplate(templateSelector) { - const template = document.querySelector(templateSelector); - const content = document.importNode(template.content, true); - return $(content.firstChild); - } -} - -AudioSourceUI.Container = class Container { - constructor(audioSources, container, addButton) { - this.audioSources = audioSources; - this.container = container; - this.addButton = addButton; - this.children = []; - - this.container.empty(); - - for (const audioSource of toIterable(audioSources)) { - this.children.push(new AudioSourceUI.AudioSource(this, audioSource, this.children.length)); - } - - this.addButton.on('click', () => this.onAddAudioSource()); - } - - cleanup() { - for (const child of this.children) { - child.cleanup(); - } - - this.addButton.off('click'); - this.container.empty(); - } - - save() { - // Override - } - - remove(child) { - const index = this.children.indexOf(child); - if (index < 0) { - return; - } - - child.cleanup(); - this.children.splice(index, 1); - this.audioSources.splice(index, 1); - - for (let i = index; i < this.children.length; ++i) { - this.children[i].index = i; - } - } - - onAddAudioSource() { - const audioSource = this.getUnusedAudioSource(); - this.audioSources.push(audioSource); - this.save(); - this.children.push(new AudioSourceUI.AudioSource(this, audioSource, this.children.length)); - } - - getUnusedAudioSource() { - const audioSourcesAvailable = [ - 'jpod101', - 'jpod101-alternate', - 'jisho', - 'custom' - ]; - for (const source of audioSourcesAvailable) { - if (this.audioSources.indexOf(source) < 0) { - return source; - } - } - return audioSourcesAvailable[0]; - } -}; - -AudioSourceUI.AudioSource = class AudioSource { - constructor(parent, audioSource, index) { - this.parent = parent; - this.audioSource = audioSource; - this.index = index; - - this.container = AudioSourceUI.instantiateTemplate('#audio-source-template').appendTo(parent.container); - this.select = this.container.find('.audio-source-select'); - this.removeButton = this.container.find('.audio-source-remove'); - - this.select.val(audioSource); - - this.select.on('change', () => this.onSelectChanged()); - this.removeButton.on('click', () => this.onRemoveClicked()); - } - - cleanup() { - this.select.off('change'); - this.removeButton.off('click'); - this.container.remove(); - } - - save() { - this.parent.save(); - } - - onSelectChanged() { - this.audioSource = this.select.val(); - this.parent.audioSources[this.index] = this.audioSource; - this.save(); - } - - onRemoveClicked() { - this.parent.remove(this); - this.save(); - } -}; diff --git a/ext/bg/js/settings/audio-ui.js b/ext/bg/js/settings/audio-ui.js new file mode 100644 index 00000000..de3be083 --- /dev/null +++ b/ext/bg/js/settings/audio-ui.js @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2019 Alex Yatskov + * Author: Alex Yatskov + * + * 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 . + */ + + +class AudioSourceUI { + static instantiateTemplate(templateSelector) { + const template = document.querySelector(templateSelector); + const content = document.importNode(template.content, true); + return content.firstChild; + } +} + +AudioSourceUI.Container = class Container { + constructor(audioSources, container, addButton) { + this.audioSources = audioSources; + this.container = container; + this.addButton = addButton; + this.children = []; + + this.container.textContent = ''; + + for (const audioSource of toIterable(audioSources)) { + this.children.push(new AudioSourceUI.AudioSource(this, audioSource, this.children.length)); + } + + this._clickListener = () => this.onAddAudioSource(); + this.addButton.addEventListener('click', this._clickListener, false); + } + + cleanup() { + for (const child of this.children) { + child.cleanup(); + } + + this.addButton.removeEventListener('click', this._clickListener, false); + this.container.textContent = ''; + this._clickListener = null; + } + + save() { + // Override + } + + remove(child) { + const index = this.children.indexOf(child); + if (index < 0) { + return; + } + + child.cleanup(); + this.children.splice(index, 1); + this.audioSources.splice(index, 1); + + for (let i = index; i < this.children.length; ++i) { + this.children[i].index = i; + } + } + + onAddAudioSource() { + const audioSource = this.getUnusedAudioSource(); + this.audioSources.push(audioSource); + this.save(); + this.children.push(new AudioSourceUI.AudioSource(this, audioSource, this.children.length)); + } + + getUnusedAudioSource() { + const audioSourcesAvailable = [ + 'jpod101', + 'jpod101-alternate', + 'jisho', + 'custom' + ]; + for (const source of audioSourcesAvailable) { + if (this.audioSources.indexOf(source) < 0) { + return source; + } + } + return audioSourcesAvailable[0]; + } +}; + +AudioSourceUI.AudioSource = class AudioSource { + constructor(parent, audioSource, index) { + this.parent = parent; + this.audioSource = audioSource; + this.index = index; + + this.container = AudioSourceUI.instantiateTemplate('#audio-source-template'); + this.select = this.container.querySelector('.audio-source-select'); + this.removeButton = this.container.querySelector('.audio-source-remove'); + + this.select.value = audioSource; + + this._selectChangeListener = () => this.onSelectChanged(); + this._removeClickListener = () => this.onRemoveClicked(); + + this.select.addEventListener('change', this._selectChangeListener, false); + this.removeButton.addEventListener('click', this._removeClickListener, false); + + parent.container.appendChild(this.container); + } + + cleanup() { + this.select.removeEventListener('change', this._selectChangeListener, false); + this.removeButton.removeEventListener('click', this._removeClickListener, false); + + if (this.container.parentNode !== null) { + this.container.parentNode.removeChild(this.container); + } + } + + save() { + this.parent.save(); + } + + onSelectChanged() { + this.audioSource = this.select.value; + this.parent.audioSources[this.index] = this.audioSource; + this.save(); + } + + onRemoveClicked() { + this.parent.remove(this); + this.save(); + } +}; diff --git a/ext/bg/js/settings/audio.js b/ext/bg/js/settings/audio.js index f63551ed..2ac4590b 100644 --- a/ext/bg/js/settings/audio.js +++ b/ext/bg/js/settings/audio.js @@ -22,7 +22,11 @@ let audioSourceUI = null; async function audioSettingsInitialize() { const optionsContext = getOptionsContext(); const options = await apiOptionsGet(optionsContext); - audioSourceUI = new AudioSourceUI.Container(options.audio.sources, $('.audio-source-list'), $('.audio-source-add')); + audioSourceUI = new AudioSourceUI.Container( + options.audio.sources, + document.querySelector('.audio-source-list'), + document.querySelector('.audio-source-add') + ); audioSourceUI.save = () => settingsSaveOptions(); textToSpeechInitialize(); @@ -34,24 +38,33 @@ function textToSpeechInitialize() { speechSynthesis.addEventListener('voiceschanged', () => updateTextToSpeechVoices(), false); updateTextToSpeechVoices(); - $('#text-to-speech-voice-test').on('click', () => textToSpeechTest()); + document.querySelector('#text-to-speech-voice-test').addEventListener('click', () => textToSpeechTest(), false); } function updateTextToSpeechVoices() { const voices = Array.prototype.map.call(speechSynthesis.getVoices(), (voice, index) => ({voice, index})); voices.sort(textToSpeechVoiceCompare); - if (voices.length > 0) { - $('#text-to-speech-voice-container').css('display', ''); - } - const select = $('#text-to-speech-voice'); - select.empty(); - select.append($('