diff options
| author | Darius Jahandarie <djahandarie@gmail.com> | 2023-12-06 03:53:16 +0000 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-06 03:53:16 +0000 | 
| commit | bd5bc1a5db29903bc098995cd9262c4576bf76af (patch) | |
| tree | c9214189e0214480fcf6539ad1c6327aef6cbd1c /ext/js/pages/settings/translation-text-replacements-controller.js | |
| parent | fd6bba8a2a869eaf2b2c1fa49001f933fce3c618 (diff) | |
| parent | 23e6fb76319c9ed7c9bcdc3efba39bc5dd38f288 (diff) | |
Merge pull request #339 from toasted-nutbread/type-annotations
Type annotations
Diffstat (limited to 'ext/js/pages/settings/translation-text-replacements-controller.js')
| -rw-r--r-- | ext/js/pages/settings/translation-text-replacements-controller.js | 107 | 
1 files changed, 87 insertions, 20 deletions
| diff --git a/ext/js/pages/settings/translation-text-replacements-controller.js b/ext/js/pages/settings/translation-text-replacements-controller.js index 4a860b52..050db8d1 100644 --- a/ext/js/pages/settings/translation-text-replacements-controller.js +++ b/ext/js/pages/settings/translation-text-replacements-controller.js @@ -19,15 +19,22 @@  import {EventListenerCollection} from '../../core.js';  export class TranslationTextReplacementsController { +    /** +     * @param {import('./settings-controller.js').SettingsController} settingsController +     */      constructor(settingsController) { +        /** @type {import('./settings-controller.js').SettingsController} */          this._settingsController = settingsController; +        /** @type {?HTMLElement} */          this._entryContainer = null; +        /** @type {TranslationTextReplacementsEntry[]} */          this._entries = [];      } +    /** */      async prepare() { -        this._entryContainer = document.querySelector('#translation-text-replacement-list'); -        const addButton = document.querySelector('#translation-text-replacement-add'); +        this._entryContainer = /** @type {HTMLElement} */ (document.querySelector('#translation-text-replacement-list')); +        const addButton = /** @type {HTMLButtonElement} */ (document.querySelector('#translation-text-replacement-add'));          addButton.addEventListener('click', this._onAdd.bind(this), false);          this._settingsController.on('optionsChanged', this._onOptionsChanged.bind(this)); @@ -35,11 +42,12 @@ export class TranslationTextReplacementsController {          await this._updateOptions();      } - +    /** */      async addGroup() {          const options = await this._settingsController.getOptions();          const {groups} = options.translation.textReplacements;          const newEntry = this._createNewEntry(); +        /** @type {import('settings-modifications').Modification} */          const target = (              (groups.length === 0) ?              { @@ -62,6 +70,10 @@ export class TranslationTextReplacementsController {          await this._updateOptions();      } +    /** +     * @param {number} index +     * @returns {Promise<boolean>} +     */      async deleteGroup(index) {          const options = await this._settingsController.getOptions();          const {groups} = options.translation.textReplacements; @@ -70,6 +82,7 @@ export class TranslationTextReplacementsController {          const group0 = groups[0];          if (index < 0 || index >= group0.length) { return false; } +        /** @type {import('settings-modifications').Modification} */          const target = (              (group0.length > 1) ?              { @@ -95,6 +108,9 @@ export class TranslationTextReplacementsController {      // Private +    /** +     * @param {import('settings-controller').OptionsChangedEvent} details +     */      _onOptionsChanged({options}) {          for (const entry of this._entries) {              entry.cleanup(); @@ -105,50 +121,70 @@ export class TranslationTextReplacementsController {          if (groups.length > 0) {              const group0 = groups[0];              for (let i = 0, ii = group0.length; i < ii; ++i) { -                const data = group0[i]; -                const node = this._settingsController.instantiateTemplate('translation-text-replacement-entry'); -                this._entryContainer.appendChild(node); -                const entry = new TranslationTextReplacementsEntry(this, node, i, data); +                const node = /** @type {HTMLElement} */ (this._settingsController.instantiateTemplate('translation-text-replacement-entry')); +                /** @type {HTMLElement} */ (this._entryContainer).appendChild(node); +                const entry = new TranslationTextReplacementsEntry(this, node, i);                  this._entries.push(entry);                  entry.prepare();              }          }      } +    /** */      _onAdd() {          this.addGroup();      } +    /** */      async _updateOptions() {          const options = await this._settingsController.getOptions(); -        this._onOptionsChanged({options}); +        const optionsContext = this._settingsController.getOptionsContext(); +        this._onOptionsChanged({options, optionsContext});      } +    /** +     * @returns {import('settings').TranslationTextReplacementGroup} +     */      _createNewEntry() {          return {pattern: '', ignoreCase: false, replacement: ''};      }  }  class TranslationTextReplacementsEntry { +    /** +     * @param {TranslationTextReplacementsController} parent +     * @param {HTMLElement} node +     * @param {number} index +     */      constructor(parent, node, index) { +        /** @type {TranslationTextReplacementsController} */          this._parent = parent; +        /** @type {HTMLElement} */          this._node = node; +        /** @type {number} */          this._index = index; +        /** @type {EventListenerCollection} */          this._eventListeners = new EventListenerCollection(); +        /** @type {?HTMLInputElement} */          this._patternInput = null; +        /** @type {?HTMLInputElement} */          this._replacementInput = null; +        /** @type {?HTMLInputElement} */          this._ignoreCaseToggle = null; +        /** @type {?HTMLInputElement} */          this._testInput = null; +        /** @type {?HTMLInputElement} */          this._testOutput = null;      } +    /** */      prepare() { -        const patternInput = this._node.querySelector('.translation-text-replacement-pattern'); -        const replacementInput = this._node.querySelector('.translation-text-replacement-replacement'); -        const ignoreCaseToggle = this._node.querySelector('.translation-text-replacement-pattern-ignore-case'); -        const menuButton = this._node.querySelector('.translation-text-replacement-button'); -        const testInput = this._node.querySelector('.translation-text-replacement-test-input'); -        const testOutput = this._node.querySelector('.translation-text-replacement-test-output'); +        const patternInput = /** @type {HTMLInputElement} */ (this._node.querySelector('.translation-text-replacement-pattern')); +        const replacementInput = /** @type {HTMLInputElement} */ (this._node.querySelector('.translation-text-replacement-replacement')); +        const ignoreCaseToggle = /** @type {HTMLInputElement} */ (this._node.querySelector('.translation-text-replacement-pattern-ignore-case')); +        const menuButton = /** @type {HTMLInputElement} */ (this._node.querySelector('.translation-text-replacement-button')); +        const testInput = /** @type {HTMLInputElement} */ (this._node.querySelector('.translation-text-replacement-test-input')); +        const testOutput = /** @type {HTMLInputElement} */ (this._node.querySelector('.translation-text-replacement-test-output'));          this._patternInput = patternInput;          this._replacementInput = replacementInput; @@ -169,6 +205,7 @@ class TranslationTextReplacementsEntry {          this._eventListeners.addEventListener(testInput, 'input', this._updateTestInput.bind(this), false);      } +    /** */      cleanup() {          this._eventListeners.removeAllEventListeners();          if (this._node.parentNode !== null) { @@ -178,13 +215,19 @@ class TranslationTextReplacementsEntry {      // Private +    /** +     * @param {import('popup-menu').MenuOpenEvent} e +     */      _onMenuOpen(e) {          const bodyNode = e.detail.menu.bodyNode;          const testVisible = this._isTestVisible(); -        bodyNode.querySelector('[data-menu-action=showTest]').hidden = testVisible; -        bodyNode.querySelector('[data-menu-action=hideTest]').hidden = !testVisible; +        /** @type {HTMLElement} */ (bodyNode.querySelector('[data-menu-action=showTest]')).hidden = testVisible; +        /** @type {HTMLElement} */ (bodyNode.querySelector('[data-menu-action=hideTest]')).hidden = !testVisible;      } +    /** +     * @param {import('popup-menu').MenuCloseEvent} e +     */      _onMenuClose(e) {          switch (e.detail.action) {              case 'remove': @@ -199,34 +242,58 @@ class TranslationTextReplacementsEntry {          }      } +    /** +     * @param {import('dom-data-binder').SettingChangedEvent} deatils +     */      _onPatternChanged({detail: {value}}) {          this._validatePattern(value);          this._updateTestInput();      } +    /** +     * @param {unknown} value +     */      _validatePattern(value) {          let okay = false;          try { -            new RegExp(value, 'g'); -            okay = true; +            if (typeof value === 'string') { +                new RegExp(value, 'g'); +                okay = true; +            }          } catch (e) {              // NOP          } -        this._patternInput.dataset.invalid = `${!okay}`; +        if (this._patternInput !== null) { +            this._patternInput.dataset.invalid = `${!okay}`; +        }      } +    /** +     * @returns {boolean} +     */      _isTestVisible() {          return this._node.dataset.testVisible === 'true';      } +    /** +     * @param {boolean} visible +     */      _setTestVisible(visible) {          this._node.dataset.testVisible = `${visible}`;          this._updateTestInput();      } +    /** */      _updateTestInput() { -        if (!this._isTestVisible()) { return; } +        if ( +            !this._isTestVisible() || +            this._ignoreCaseToggle === null || +            this._patternInput === null || +            this._replacementInput === null || +            this._testInput === null || +            this._testOutput === null +        ) { return; }          const ignoreCase = this._ignoreCaseToggle.checked;          const pattern = this._patternInput.value; |