aboutsummaryrefslogtreecommitdiff
path: root/ext/js
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2023-12-28 22:17:38 -0500
committerGitHub <noreply@github.com>2023-12-29 03:17:38 +0000
commit1e254fd1d4423b984e176547ef36a14383bbd7f5 (patch)
tree8aae2c47f80265d5f1f39c927e19455ec3986387 /ext/js
parenta51ae1533c54162f14785652e9128f90afb86aed (diff)
Event dispatcher refactor (#463)
* Refactor EventDispatcher template type * Update core types * Update log * Update clipboard monitor * Update application events * Update popup events * Update text scanner * Update cross frame API * Update display events * Type updates * Update display history * Update query parser * Update search persistent state controller * Update panel element * Update popup menu * Update audio system * Update hotkey handler * Update settings controller * Update audio controller * Update types * Update types * Update types * Add event handler types * Update type * Fix issues * Remove error suppression * Fix typo
Diffstat (limited to 'ext/js')
-rw-r--r--ext/js/app/popup-proxy.js4
-rw-r--r--ext/js/app/popup-window.js2
-rw-r--r--ext/js/app/popup.js8
-rw-r--r--ext/js/background/backend.js2
-rw-r--r--ext/js/comm/clipboard-monitor.js4
-rw-r--r--ext/js/comm/cross-frame-api.js4
-rw-r--r--ext/js/core.js44
-rw-r--r--ext/js/display/display-anki.js6
-rw-r--r--ext/js/display/display-audio.js8
-rw-r--r--ext/js/display/display-history.js4
-rw-r--r--ext/js/display/display.js32
-rw-r--r--ext/js/display/query-parser.js8
-rw-r--r--ext/js/display/search-display-controller.js4
-rw-r--r--ext/js/display/search-persistent-state-controller.js2
-rw-r--r--ext/js/dom/panel-element.js15
-rw-r--r--ext/js/dom/popup-menu.js4
-rw-r--r--ext/js/input/hotkey-handler.js22
-rw-r--r--ext/js/language/text-scanner.js4
-rw-r--r--ext/js/media/audio-system.js2
-rw-r--r--ext/js/pages/settings/anki-controller.js4
-rw-r--r--ext/js/pages/settings/anki-templates-controller.js2
-rw-r--r--ext/js/pages/settings/audio-controller.js6
-rw-r--r--ext/js/pages/settings/backup-controller.js4
-rw-r--r--ext/js/pages/settings/collapsible-dictionary-controller.js2
-rw-r--r--ext/js/pages/settings/dictionary-controller.js6
-rw-r--r--ext/js/pages/settings/dictionary-import-controller.js2
-rw-r--r--ext/js/pages/settings/extension-keyboard-shortcuts-controller.js2
-rw-r--r--ext/js/pages/settings/keyboard-mouse-input-field.js6
-rw-r--r--ext/js/pages/settings/keyboard-shortcuts-controller.js4
-rw-r--r--ext/js/pages/settings/nested-popups-controller.js2
-rw-r--r--ext/js/pages/settings/permissions-origin-controller.js2
-rw-r--r--ext/js/pages/settings/permissions-toggle-controller.js4
-rw-r--r--ext/js/pages/settings/persistent-storage-controller.js2
-rw-r--r--ext/js/pages/settings/popup-preview-frame.js2
-rw-r--r--ext/js/pages/settings/profile-conditions-ui.js33
-rw-r--r--ext/js/pages/settings/profile-controller.js2
-rw-r--r--ext/js/pages/settings/recommended-permissions-controller.js2
-rw-r--r--ext/js/pages/settings/scan-inputs-controller.js10
-rw-r--r--ext/js/pages/settings/scan-inputs-simple-controller.js6
-rw-r--r--ext/js/pages/settings/secondary-search-dictionary-controller.js2
-rw-r--r--ext/js/pages/settings/sentence-termination-characters-controller.js2
-rw-r--r--ext/js/pages/settings/settings-controller.js12
-rw-r--r--ext/js/pages/settings/sort-frequency-dictionary-controller.js2
-rw-r--r--ext/js/pages/settings/translation-text-replacements-controller.js2
-rw-r--r--ext/js/yomitan.js14
45 files changed, 154 insertions, 162 deletions
diff --git a/ext/js/app/popup-proxy.js b/ext/js/app/popup-proxy.js
index 924175e2..d141d35b 100644
--- a/ext/js/app/popup-proxy.js
+++ b/ext/js/app/popup-proxy.js
@@ -22,7 +22,7 @@ import {yomitan} from '../yomitan.js';
/**
* This class is a proxy for a Popup that is hosted in a different frame.
* It effectively forwards all API calls to the underlying Popup.
- * @augments EventDispatcher<import('popup').PopupAnyEventType>
+ * @augments EventDispatcher<import('popup').Events>
*/
export class PopupProxy extends EventDispatcher {
/**
@@ -361,7 +361,7 @@ export class PopupProxy extends EventDispatcher {
} else {
this._frameOffsetX = 0;
this._frameOffsetY = 0;
- this.trigger('offsetNotFound');
+ this.trigger('offsetNotFound', {});
return;
}
this._frameOffsetUpdatedAt = now;
diff --git a/ext/js/app/popup-window.js b/ext/js/app/popup-window.js
index 9a0f8011..0b083d80 100644
--- a/ext/js/app/popup-window.js
+++ b/ext/js/app/popup-window.js
@@ -21,7 +21,7 @@ import {yomitan} from '../yomitan.js';
/**
* This class represents a popup that is hosted in a new native window.
- * @augments EventDispatcher<import('popup').PopupAnyEventType>
+ * @augments EventDispatcher<import('popup').Events>
*/
export class PopupWindow extends EventDispatcher {
/**
diff --git a/ext/js/app/popup.js b/ext/js/app/popup.js
index a0712604..4f2368d4 100644
--- a/ext/js/app/popup.js
+++ b/ext/js/app/popup.js
@@ -26,7 +26,7 @@ import {ThemeController} from './theme-controller.js';
/**
* This class is the container which hosts the display of search results.
- * @augments EventDispatcher<import('popup').PopupAnyEventType>
+ * @augments EventDispatcher<import('popup').Events>
*/
export class Popup extends EventDispatcher {
/**
@@ -360,9 +360,7 @@ export class Popup extends EventDispatcher {
parentNode = this._shadow;
}
const node = await loadStyle('yomitan-popup-outer-user-stylesheet', 'code', css, useWebExtensionApi, parentNode);
- /** @type {import('popup').CustomOuterCssChangedEvent} */
- const event = {node, useWebExtensionApi, inShadow};
- this.trigger('customOuterCssChanged', event);
+ this.trigger('customOuterCssChanged', {node, useWebExtensionApi, inShadow});
}
/**
@@ -653,7 +651,7 @@ export class Popup extends EventDispatcher {
}
/**
- * @param {import('dynamic-property').ChangeEventDetails<boolean>} event
+ * @param {import('dynamic-property').EventArgument<boolean, 'change'>} event
*/
_onVisibleChange({value}) {
if (this._visibleValue === value) { return; }
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js
index 68d4e0c8..b523cd6e 100644
--- a/ext/js/background/backend.js
+++ b/ext/js/background/backend.js
@@ -315,7 +315,7 @@ export class Backend {
// Event handlers
/**
- * @param {{text: string}} params
+ * @param {import('clipboard-monitor').EventArgument<'change'>} details
*/
async _onClipboardTextChange({text}) {
const {clipboard: {maximumSearchLength}} = this._getProfileOptions({current: true}, false);
diff --git a/ext/js/comm/clipboard-monitor.js b/ext/js/comm/clipboard-monitor.js
index 3b3a56a9..d717dff2 100644
--- a/ext/js/comm/clipboard-monitor.js
+++ b/ext/js/comm/clipboard-monitor.js
@@ -19,7 +19,7 @@
import {EventDispatcher} from '../core.js';
/**
- * @augments EventDispatcher<import('clipboard-monitor').EventType>
+ * @augments EventDispatcher<import('clipboard-monitor').Events>
*/
export class ClipboardMonitor extends EventDispatcher {
/**
@@ -71,7 +71,7 @@ export class ClipboardMonitor extends EventDispatcher {
) {
this._previousText = text;
if (canChange && this._japaneseUtil.isStringPartiallyJapanese(text)) {
- this.trigger('change', /** @type {import('clipboard-monitor').ChangeEvent} */ ({text}));
+ this.trigger('change', {text});
}
}
diff --git a/ext/js/comm/cross-frame-api.js b/ext/js/comm/cross-frame-api.js
index 023ca18e..14e410a8 100644
--- a/ext/js/comm/cross-frame-api.js
+++ b/ext/js/comm/cross-frame-api.js
@@ -22,9 +22,9 @@ import {parseJson} from '../core/json.js';
import {yomitan} from '../yomitan.js';
/**
- * @augments EventDispatcher<import('cross-frame-api').CrossFrameAPIPortEventType>
+ * @augments EventDispatcher<import('cross-frame-api').CrossFrameAPIPortEvents>
*/
-class CrossFrameAPIPort extends EventDispatcher {
+export class CrossFrameAPIPort extends EventDispatcher {
/**
* @param {number} otherTabId
* @param {number} otherFrameId
diff --git a/ext/js/core.js b/ext/js/core.js
index 63c2f527..c9c989ac 100644
--- a/ext/js/core.js
+++ b/ext/js/core.js
@@ -353,22 +353,30 @@ export function invokeMessageHandler(handler, params, callback, ...extraArgs) {
}
/**
- * @template {string} TEventName
+ * The following typedef is required because the JSDoc `implements` tag doesn't work with `import()`.
+ * https://github.com/microsoft/TypeScript/issues/49905
+ * @typedef {import('core').EventDispatcherOffGeneric} EventDispatcherOffGeneric
+ */
+
+/**
* Base class controls basic event dispatching.
+ * @template {import('core').EventSurface} TSurface
+ * @implements {EventDispatcherOffGeneric}
*/
export class EventDispatcher {
/**
* Creates a new instance.
*/
constructor() {
- /** @type {Map<string, ((details: import('core').SafeAny) => void)[]>} */
+ /** @type {Map<import('core').EventNames<TSurface>, import('core').EventHandlerAny[]>} */
this._eventMap = new Map();
}
/**
* Triggers an event with the given name and specified argument.
- * @param {TEventName} eventName The string representing the event's name.
- * @param {unknown} [details] The argument passed to the callback functions.
+ * @template {import('core').EventNames<TSurface>} TName
+ * @param {TName} eventName The string representing the event's name.
+ * @param {import('core').EventArgument<TSurface, TName>} details The argument passed to the callback functions.
* @returns {boolean} `true` if any callbacks were registered, `false` otherwise.
*/
trigger(eventName, details) {
@@ -383,8 +391,9 @@ export class EventDispatcher {
/**
* Adds a single event listener to a specific event.
- * @param {TEventName} eventName The string representing the event's name.
- * @param {(details: import('core').SafeAny) => void} callback The event listener callback to add.
+ * @template {import('core').EventNames<TSurface>} TName
+ * @param {TName} eventName The string representing the event's name.
+ * @param {import('core').EventHandler<TSurface, TName>} callback The event listener callback to add.
*/
on(eventName, callback) {
let callbacks = this._eventMap.get(eventName);
@@ -397,8 +406,9 @@ export class EventDispatcher {
/**
* Removes a single event listener from a specific event.
- * @param {TEventName} eventName The string representing the event's name.
- * @param {(details: import('core').SafeAny) => void} callback The event listener callback to add.
+ * @template {import('core').EventNames<TSurface>} TName
+ * @param {TName} eventName The string representing the event's name.
+ * @param {import('core').EventHandler<TSurface, TName>} callback The event listener callback to add.
* @returns {boolean} `true` if the callback was removed, `false` otherwise.
*/
off(eventName, callback) {
@@ -420,7 +430,8 @@ export class EventDispatcher {
/**
* Checks if an event has any listeners.
- * @param {TEventName} eventName The string representing the event's name.
+ * @template {import('core').EventNames<TSurface>} TName
+ * @param {TName} eventName The string representing the event's name.
* @returns {boolean} `true` if the event has listeners, `false` otherwise.
*/
hasListeners(eventName) {
@@ -476,10 +487,11 @@ export class EventListenerCollection {
/**
* Adds an event listener using `object.on`. The listener will later be removed using `object.off`.
- * @template {string} TEventName
- * @param {EventDispatcher<TEventName>} target The object to add the event listener to.
- * @param {TEventName} eventName The string representing the event's name.
- * @param {(details: import('core').SafeAny) => void} callback The event listener callback to add.
+ * @template {import('core').EventSurface} TSurface
+ * @template {import('core').EventNames<TSurface>} TName
+ * @param {EventDispatcher<TSurface>} target The object to add the event listener to.
+ * @param {TName} eventName The string representing the event's name.
+ * @param {import('core').EventHandler<TSurface, TName>} callback The event listener callback to add.
*/
on(target, eventName, callback) {
target.on(eventName, callback);
@@ -512,7 +524,7 @@ export class EventListenerCollection {
* Class representing a generic value with an override stack.
* Changes can be observed by listening to the 'change' event.
* @template [T=unknown]
- * @augments EventDispatcher<import('dynamic-property').EventType>
+ * @augments EventDispatcher<import('dynamic-property').Events<T>>
*/
export class DynamicProperty extends EventDispatcher {
/**
@@ -615,14 +627,14 @@ export class DynamicProperty extends EventDispatcher {
const value = this._overrides.length > 0 ? this._overrides[0].value : this._defaultValue;
if (this._value === value) { return; }
this._value = value;
- this.trigger('change', /** @type {import('dynamic-property').ChangeEventDetails<T>} */ ({value}));
+ this.trigger('change', {value});
}
}
/**
* This class handles logging of messages to the console and triggering
* an event for log calls.
- * @augments EventDispatcher<import('log').LoggerEventType>
+ * @augments EventDispatcher<import('log').Events>
*/
export class Logger extends EventDispatcher {
/**
diff --git a/ext/js/display/display-anki.js b/ext/js/display/display-anki.js
index 423cdfdc..759998c4 100644
--- a/ext/js/display/display-anki.js
+++ b/ext/js/display/display-anki.js
@@ -182,7 +182,7 @@ export class DisplayAnki {
// Private
/**
- * @param {import('display').OptionsUpdatedEvent} details
+ * @param {import('display').EventArgument<'optionsUpdated'>} details
*/
_onOptionsUpdated({options}) {
const {
@@ -238,7 +238,7 @@ export class DisplayAnki {
}
/**
- * @param {import('display').ContentUpdateEntryEvent} details
+ * @param {import('display').EventArgument<'contentUpdateEntry'>} details
*/
_onContentUpdateEntry({element}) {
const eventListeners = this._eventListeners;
@@ -261,7 +261,7 @@ export class DisplayAnki {
}
/**
- * @param {import('display').LogDictionaryEntryDataEvent} details
+ * @param {import('display').EventArgument<'logDictionaryEntryData'>} details
*/
_onLogDictionaryEntryData({dictionaryEntry, promises}) {
promises.push(this.getLogData(dictionaryEntry));
diff --git a/ext/js/display/display-audio.js b/ext/js/display/display-audio.js
index 30cf2b92..cba9c43c 100644
--- a/ext/js/display/display-audio.js
+++ b/ext/js/display/display-audio.js
@@ -162,7 +162,7 @@ export class DisplayAudio {
// Private
/**
- * @param {import('display').OptionsUpdatedEvent} details
+ * @param {import('display').EventArgument<'optionsUpdated'>} details
*/
_onOptionsUpdated({options}) {
const {enabled, autoPlay, volume, sources} = options.audio;
@@ -201,7 +201,7 @@ export class DisplayAudio {
}
/**
- * @param {import('display').ContentUpdateEntryEvent} details
+ * @param {import('display').EventArgument<'contentUpdateEntry'>} details
*/
_onContentUpdateEntry({element}) {
const eventListeners = this._eventListeners;
@@ -237,7 +237,7 @@ export class DisplayAudio {
}
/**
- * @param {import('display').FrameVisibilityChangeEvent} details
+ * @param {import('display').EventArgument<'frameVisibilityChange'>} details
*/
_onFrameVisibilityChange({value}) {
if (!value) {
@@ -779,7 +779,7 @@ export class DisplayAudio {
}
/**
- * @param {import('popup-menu').MenuCloseEventDetails} details
+ * @param {import('popup-menu').EventArgument<'close'>} details
*/
_onPopupMenuClose({menu}) {
this._openMenus.delete(menu);
diff --git a/ext/js/display/display-history.js b/ext/js/display/display-history.js
index af6d734e..30bc3eec 100644
--- a/ext/js/display/display-history.js
+++ b/ext/js/display/display-history.js
@@ -19,7 +19,7 @@
import {EventDispatcher, generateId, isObject} from '../core.js';
/**
- * @augments EventDispatcher<import('display-history').EventType>
+ * @augments EventDispatcher<import('display-history').Events>
*/
export class DisplayHistory extends EventDispatcher {
/**
@@ -161,7 +161,7 @@ export class DisplayHistory extends EventDispatcher {
* @param {boolean} synthetic
*/
_triggerStateChanged(synthetic) {
- this.trigger('stateChanged', /** @type {import('display-history').StateChangedEvent} */ ({synthetic}));
+ this.trigger('stateChanged', {synthetic});
}
/**
diff --git a/ext/js/display/display.js b/ext/js/display/display.js
index 79cf79a8..08f640d0 100644
--- a/ext/js/display/display.js
+++ b/ext/js/display/display.js
@@ -34,7 +34,7 @@ import {OptionToggleHotkeyHandler} from './option-toggle-hotkey-handler.js';
import {QueryParser} from './query-parser.js';
/**
- * @augments EventDispatcher<import('display').DisplayEventType>
+ * @augments EventDispatcher<import('display').Events>
*/
export class Display extends EventDispatcher {
/**
@@ -449,9 +449,7 @@ export class Display extends EventDispatcher {
this._updateNestedFrontend(options);
this._updateContentTextScanner(options);
- /** @type {import('display').OptionsUpdatedEvent} */
- const event = {options};
- this.trigger('optionsUpdated', event);
+ this.trigger('optionsUpdated', {options});
}
/**
@@ -716,9 +714,7 @@ export class Display extends EventDispatcher {
*/
_onMessageVisibilityChanged({value}) {
this._frameVisible = value;
- /** @type {import('display').FrameVisibilityChangeEvent} */
- const event = {value};
- this.trigger('frameVisibilityChange', event);
+ this.trigger('frameVisibilityChange', {value});
}
/** */
@@ -796,7 +792,7 @@ export class Display extends EventDispatcher {
}
/**
- * @param {import('display').QueryParserSearchedEvent} details
+ * @param {import('query-parser').EventArgument<'searched'>} details
*/
_onQueryParserSearch({type, dictionaryEntries, sentence, inputInfo: {eventType}, textSource, optionsContext, sentenceOffset}) {
const query = textSource.text();
@@ -869,7 +865,7 @@ export class Display extends EventDispatcher {
}
/**
- * @param {import('dynamic-property').ChangeEventDetails<boolean>} details
+ * @param {import('dynamic-property').EventArgument<boolean, 'change'>} details
*/
_onProgressIndicatorVisibleChanged({value}) {
if (this._progressIndicatorTimer !== null) {
@@ -1646,7 +1642,7 @@ export class Display extends EventDispatcher {
/** */
_closePopups() {
- yomitan.trigger('closePopups');
+ yomitan.triggerClosePopups();
}
/**
@@ -2011,9 +2007,7 @@ export class Display extends EventDispatcher {
/** @type {Promise<unknown>[]} */
const promises = [];
- /** @type {import('display').LogDictionaryEntryDataEvent} */
- const event = {dictionaryEntry, promises};
- this.trigger('logDictionaryEntryData', event);
+ this.trigger('logDictionaryEntryData', {dictionaryEntry, promises});
if (promises.length > 0) {
for (const result2 of await Promise.all(promises)) {
Object.assign(result, result2);
@@ -2031,9 +2025,7 @@ export class Display extends EventDispatcher {
/** */
_triggerContentUpdateStart() {
- /** @type {import('display').ContentUpdateStartEvent} */
- const event = {type: this._contentType, query: this._query};
- this.trigger('contentUpdateStart', event);
+ this.trigger('contentUpdateStart', {type: this._contentType, query: this._query});
}
/**
@@ -2042,15 +2034,11 @@ export class Display extends EventDispatcher {
* @param {number} index
*/
_triggerContentUpdateEntry(dictionaryEntry, element, index) {
- /** @type {import('display').ContentUpdateEntryEvent} */
- const event = {dictionaryEntry, element, index};
- this.trigger('contentUpdateEntry', event);
+ this.trigger('contentUpdateEntry', {dictionaryEntry, element, index});
}
/** */
_triggerContentUpdateComplete() {
- /** @type {import('display').ContentUpdateCompleteEvent} */
- const event = {type: this._contentType};
- this.trigger('contentUpdateComplete', event);
+ this.trigger('contentUpdateComplete', {type: this._contentType});
}
}
diff --git a/ext/js/display/query-parser.js b/ext/js/display/query-parser.js
index 0e7e1e1a..11c5a4ec 100644
--- a/ext/js/display/query-parser.js
+++ b/ext/js/display/query-parser.js
@@ -22,7 +22,7 @@ import {TextScanner} from '../language/text-scanner.js';
import {yomitan} from '../yomitan.js';
/**
- * @augments EventDispatcher<import('display').QueryParserEventType>
+ * @augments EventDispatcher<import('query-parser').Events>
*/
export class QueryParser extends EventDispatcher {
/**
@@ -160,8 +160,7 @@ export class QueryParser extends EventDispatcher {
} = e;
if (type === null || dictionaryEntries === null || sentence === null || optionsContext === null) { return; }
- /** @type {import('display').QueryParserSearchedEvent} */
- const event2 = {
+ this.trigger('searched', {
textScanner,
type,
dictionaryEntries,
@@ -170,8 +169,7 @@ export class QueryParser extends EventDispatcher {
textSource,
optionsContext,
sentenceOffset: this._getSentenceOffset(e.textSource)
- };
- this.trigger('searched', event2);
+ });
}
/**
diff --git a/ext/js/display/search-display-controller.js b/ext/js/display/search-display-controller.js
index 6767d201..3df3a332 100644
--- a/ext/js/display/search-display-controller.js
+++ b/ext/js/display/search-display-controller.js
@@ -183,7 +183,7 @@ export class SearchDisplayController {
}
/**
- * @param {import('display').OptionsUpdatedEvent} details
+ * @param {import('display').EventArgument<'optionsUpdated'>} details
*/
_onDisplayOptionsUpdated({options}) {
this._clipboardMonitorEnabled = options.clipboard.enableSearchPageMonitor;
@@ -195,7 +195,7 @@ export class SearchDisplayController {
}
/**
- * @param {import('display').ContentUpdateStartEvent} details
+ * @param {import('display').EventArgument<'contentUpdateStart'>} details
*/
_onContentUpdateStart({type, query}) {
let animate = false;
diff --git a/ext/js/display/search-persistent-state-controller.js b/ext/js/display/search-persistent-state-controller.js
index d92ddf68..1bd32f5b 100644
--- a/ext/js/display/search-persistent-state-controller.js
+++ b/ext/js/display/search-persistent-state-controller.js
@@ -19,7 +19,7 @@
import {EventDispatcher} from '../core.js';
/**
- * @augments EventDispatcher<import('display').SearchPersistentStateControllerEventType>
+ * @augments EventDispatcher<import('search-persistent-state-controller').Events>
*/
export class SearchPersistentStateController extends EventDispatcher {
constructor() {
diff --git a/ext/js/dom/panel-element.js b/ext/js/dom/panel-element.js
index d4cb28fd..959ca420 100644
--- a/ext/js/dom/panel-element.js
+++ b/ext/js/dom/panel-element.js
@@ -19,7 +19,7 @@
import {EventDispatcher} from '../core.js';
/**
- * @augments EventDispatcher<import('panel-element').EventType>
+ * @augments EventDispatcher<import('panel-element').Events>
*/
export class PanelElement extends EventDispatcher {
/**
@@ -84,9 +84,9 @@ export class PanelElement extends EventDispatcher {
}
/**
- * @param {import('panel-element').EventType} eventName
- * @param {(details: import('core').SafeAny) => void} callback
- * @returns {void}
+ * @template {import('core').EventNames<import('panel-element').Events>} TName
+ * @param {TName} eventName
+ * @param {(details: import('core').EventArgument<import('panel-element').Events, TName>) => void} callback
*/
on(eventName, callback) {
if (eventName === 'visibilityChanged') {
@@ -100,12 +100,13 @@ export class PanelElement extends EventDispatcher {
});
}
}
- return super.on(eventName, callback);
+ super.on(eventName, callback);
}
/**
- * @param {import('panel-element').EventType} eventName
- * @param {(details: import('core').SafeAny) => void} callback
+ * @template {import('core').EventNames<import('panel-element').Events>} TName
+ * @param {TName} eventName
+ * @param {(details: import('core').EventArgument<import('panel-element').Events, TName>) => void} callback
* @returns {boolean}
*/
off(eventName, callback) {
diff --git a/ext/js/dom/popup-menu.js b/ext/js/dom/popup-menu.js
index 72df82a0..61f20ba8 100644
--- a/ext/js/dom/popup-menu.js
+++ b/ext/js/dom/popup-menu.js
@@ -20,7 +20,7 @@ import {EventDispatcher, EventListenerCollection} from '../core.js';
import {querySelectorNotNull} from './query-selector.js';
/**
- * @augments EventDispatcher<import('popup-menu').EventType>
+ * @augments EventDispatcher<import('popup-menu').Events>
*/
export class PopupMenu extends EventDispatcher {
/**
@@ -247,7 +247,7 @@ export class PopupMenu extends EventDispatcher {
{altKey: false, ctrlKey: false, metaKey: false, shiftKey: false}
);
- /** @type {import('popup-menu').MenuCloseEventDetails} */
+ /** @type {import('popup-menu').EventArgument<'close'>} */
const detail = {
menu: this,
item,
diff --git a/ext/js/input/hotkey-handler.js b/ext/js/input/hotkey-handler.js
index da763662..48c2de57 100644
--- a/ext/js/input/hotkey-handler.js
+++ b/ext/js/input/hotkey-handler.js
@@ -22,7 +22,7 @@ import {yomitan} from '../yomitan.js';
/**
* Class which handles hotkey events and actions.
- * @augments EventDispatcher<import('hotkey-handler').EventType>
+ * @augments EventDispatcher<import('hotkey-handler').Events>
*/
export class HotkeyHandler extends EventDispatcher {
/**
@@ -120,25 +120,21 @@ export class HotkeyHandler extends EventDispatcher {
}
/**
- * Adds a single event listener to a specific event.
- * @template [TEventDetails=unknown]
- * @param {import('hotkey-handler').EventType} eventName The string representing the event's name.
- * @param {(details: TEventDetails) => void} callback The event listener callback to add.
- * @returns {void}
+ * @template {import('core').EventNames<import('hotkey-handler').Events>} TName
+ * @param {TName} eventName
+ * @param {(details: import('core').EventArgument<import('hotkey-handler').Events, TName>) => void} callback
*/
on(eventName, callback) {
- const result = super.on(eventName, callback);
+ super.on(eventName, callback);
this._updateHasEventListeners();
this._updateEventHandlers();
- return result;
}
/**
- * Removes a single event listener from a specific event.
- * @template [TEventDetails=unknown]
- * @param {import('hotkey-handler').EventType} eventName The string representing the event's name.
- * @param {(details: TEventDetails) => void} callback The event listener callback to add.
- * @returns {boolean} `true` if the callback was removed, `false` otherwise.
+ * @template {import('core').EventNames<import('hotkey-handler').Events>} TName
+ * @param {TName} eventName
+ * @param {(details: import('core').EventArgument<import('hotkey-handler').Events, TName>) => void} callback
+ * @returns {boolean}
*/
off(eventName, callback) {
const result = super.off(eventName, callback);
diff --git a/ext/js/language/text-scanner.js b/ext/js/language/text-scanner.js
index 164e150e..9c254e44 100644
--- a/ext/js/language/text-scanner.js
+++ b/ext/js/language/text-scanner.js
@@ -22,7 +22,7 @@ import {TextSourceElement} from '../dom/text-source-element.js';
import {yomitan} from '../yomitan.js';
/**
- * @augments EventDispatcher<import('text-scanner').EventType>
+ * @augments EventDispatcher<import('text-scanner').Events>
*/
export class TextScanner extends EventDispatcher {
/**
@@ -1597,7 +1597,7 @@ export class TextScanner extends EventDispatcher {
}
/**
- * @param {string} reason
+ * @param {import('text-scanner').ClearReason} reason
*/
_triggerClear(reason) {
this.trigger('clear', {reason});
diff --git a/ext/js/media/audio-system.js b/ext/js/media/audio-system.js
index 1e8f1be2..c311b96c 100644
--- a/ext/js/media/audio-system.js
+++ b/ext/js/media/audio-system.js
@@ -20,7 +20,7 @@ import {EventDispatcher} from '../core.js';
import {TextToSpeechAudio} from './text-to-speech-audio.js';
/**
- * @augments EventDispatcher<import('audio-system').EventType>
+ * @augments EventDispatcher<import('audio-system').Events>
*/
export class AudioSystem extends EventDispatcher {
constructor() {
diff --git a/ext/js/pages/settings/anki-controller.js b/ext/js/pages/settings/anki-controller.js
index aea94b65..d64034a5 100644
--- a/ext/js/pages/settings/anki-controller.js
+++ b/ext/js/pages/settings/anki-controller.js
@@ -221,7 +221,7 @@ export class AnkiController {
}
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
async _onOptionsChanged({options: {anki}}) {
/** @type {?string} */
@@ -964,7 +964,7 @@ class AnkiCardController {
}
/**
- * @param {import('settings-controller').PermissionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'permissionsChanged'>} details
*/
_onPermissionsChanged({permissions: {permissions}}) {
const permissionsSet = new Set(permissions);
diff --git a/ext/js/pages/settings/anki-templates-controller.js b/ext/js/pages/settings/anki-templates-controller.js
index ac0cc9c2..56e992b0 100644
--- a/ext/js/pages/settings/anki-templates-controller.js
+++ b/ext/js/pages/settings/anki-templates-controller.js
@@ -94,7 +94,7 @@ export class AnkiTemplatesController {
// Private
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
let templates = options.anki.fieldTemplates;
diff --git a/ext/js/pages/settings/audio-controller.js b/ext/js/pages/settings/audio-controller.js
index af05ee70..2b46455f 100644
--- a/ext/js/pages/settings/audio-controller.js
+++ b/ext/js/pages/settings/audio-controller.js
@@ -21,7 +21,7 @@ import {querySelectorNotNull} from '../../dom/query-selector.js';
import {AudioSystem} from '../../media/audio-system.js';
/**
- * @augments EventDispatcher<import('audio-controller').EventType>
+ * @augments EventDispatcher<import('audio-controller').Events>
*/
export class AudioController extends EventDispatcher {
/**
@@ -117,7 +117,7 @@ export class AudioController extends EventDispatcher {
// Private
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
for (const entry of this._audioSourceEntries) {
@@ -163,7 +163,7 @@ export class AudioController extends EventDispatcher {
);
voices.sort(this._textToSpeechVoiceCompare.bind(this));
this._voices = voices;
- this.trigger('voicesUpdated');
+ this.trigger('voicesUpdated', {});
}
/**
diff --git a/ext/js/pages/settings/backup-controller.js b/ext/js/pages/settings/backup-controller.js
index c0e56e96..2ae52925 100644
--- a/ext/js/pages/settings/backup-controller.js
+++ b/ext/js/pages/settings/backup-controller.js
@@ -290,7 +290,7 @@ export class BackupController {
modal.setVisible(false);
};
/**
- * @param {import('panel-element').VisibilityChangedEvent} details
+ * @param {import('panel-element').EventArgument<'visibilityChanged'>} details
*/
const onModalVisibilityChanged = ({visible}) => {
if (visible) { return; }
@@ -644,7 +644,7 @@ export class BackupController {
await yomitan.api.purgeDatabase();
await Dexie.import(file, {progressCallback: this._databaseImportProgressCallback});
yomitan.api.triggerDatabaseUpdated('dictionary', 'import');
- yomitan.trigger('storageChanged');
+ yomitan.triggerStorageChanged();
}
/** */
diff --git a/ext/js/pages/settings/collapsible-dictionary-controller.js b/ext/js/pages/settings/collapsible-dictionary-controller.js
index cff3ad20..341522cf 100644
--- a/ext/js/pages/settings/collapsible-dictionary-controller.js
+++ b/ext/js/pages/settings/collapsible-dictionary-controller.js
@@ -70,7 +70,7 @@ export class CollapsibleDictionaryController {
}
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
this._eventListeners.removeAllEventListeners();
diff --git a/ext/js/pages/settings/dictionary-controller.js b/ext/js/pages/settings/dictionary-controller.js
index db6a73d4..0132fe9e 100644
--- a/ext/js/pages/settings/dictionary-controller.js
+++ b/ext/js/pages/settings/dictionary-controller.js
@@ -473,7 +473,7 @@ export class DictionaryController {
value: dictionaries
}]);
- /** @type {import('settings-controller').DictionarySettingsReorderedEvent} */
+ /** @type {import('settings-controller').EventArgument<'dictionarySettingsReordered'>} */
const event = {source: this};
this._settingsController.trigger('dictionarySettingsReordered', event);
@@ -577,7 +577,7 @@ export class DictionaryController {
// Private
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
this._updateDictionariesEnabledWarnings(options);
@@ -930,7 +930,7 @@ export class DictionaryController {
/** */
_triggerStorageChanged() {
- yomitan.trigger('storageChanged');
+ yomitan.triggerStorageChanged();
}
/** */
diff --git a/ext/js/pages/settings/dictionary-import-controller.js b/ext/js/pages/settings/dictionary-import-controller.js
index 79a62d32..eadfcb91 100644
--- a/ext/js/pages/settings/dictionary-import-controller.js
+++ b/ext/js/pages/settings/dictionary-import-controller.js
@@ -398,6 +398,6 @@ export class DictionaryImportController {
/** */
_triggerStorageChanged() {
- yomitan.trigger('storageChanged');
+ yomitan.triggerStorageChanged();
}
}
diff --git a/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js b/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js
index e92d9e93..e3d84ac2 100644
--- a/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js
+++ b/ext/js/pages/settings/extension-keyboard-shortcuts-controller.js
@@ -313,7 +313,7 @@ class ExtensionKeyboardShortcutHotkeyEntry {
// Private
/**
- * @param {import('keyboard-mouse-input-field').ChangeEvent} e
+ * @param {import('keyboard-mouse-input-field').EventArgument<'change'>} e
*/
_onInputFieldChange(e) {
const {key, modifiers} = e;
diff --git a/ext/js/pages/settings/keyboard-mouse-input-field.js b/ext/js/pages/settings/keyboard-mouse-input-field.js
index f50ca112..0628d065 100644
--- a/ext/js/pages/settings/keyboard-mouse-input-field.js
+++ b/ext/js/pages/settings/keyboard-mouse-input-field.js
@@ -21,7 +21,7 @@ import {DocumentUtil} from '../../dom/document-util.js';
import {HotkeyUtil} from '../../input/hotkey-util.js';
/**
- * @augments EventDispatcher<import('keyboard-mouse-input-field').EventType>
+ * @augments EventDispatcher<import('keyboard-mouse-input-field').Events>
*/
export class KeyboardMouseInputField extends EventDispatcher {
/**
@@ -308,9 +308,7 @@ export class KeyboardMouseInputField extends EventDispatcher {
this._updateDisplayString();
if (changed) {
- /** @type {import('keyboard-mouse-input-field').ChangeEvent} */
- const event = {modifiers: this._modifiers, key: this._key};
- this.trigger('change', event);
+ this.trigger('change', {modifiers: this._modifiers, key: this._key});
}
}
diff --git a/ext/js/pages/settings/keyboard-shortcuts-controller.js b/ext/js/pages/settings/keyboard-shortcuts-controller.js
index cbdae77d..b45c656a 100644
--- a/ext/js/pages/settings/keyboard-shortcuts-controller.js
+++ b/ext/js/pages/settings/keyboard-shortcuts-controller.js
@@ -160,7 +160,7 @@ export class KeyboardShortcutController {
// Private
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
for (const entry of this._entries) {
@@ -395,7 +395,7 @@ class KeyboardShortcutHotkeyEntry {
}
/**
- * @param {import('keyboard-mouse-input-field').ChangeEvent} details
+ * @param {import('keyboard-mouse-input-field').EventArgument<'change'>} details
*/
_onInputFieldChange({key, modifiers}) {
/** @type {import('input').ModifierKey[]} */
diff --git a/ext/js/pages/settings/nested-popups-controller.js b/ext/js/pages/settings/nested-popups-controller.js
index 7eb78148..4f0aa761 100644
--- a/ext/js/pages/settings/nested-popups-controller.js
+++ b/ext/js/pages/settings/nested-popups-controller.js
@@ -50,7 +50,7 @@ export class NestedPopupsController {
// Private
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
this._updatePopupNestingMaxDepth(options.scanning.popupNestingMaxDepth);
diff --git a/ext/js/pages/settings/permissions-origin-controller.js b/ext/js/pages/settings/permissions-origin-controller.js
index 6dacced8..3a9db602 100644
--- a/ext/js/pages/settings/permissions-origin-controller.js
+++ b/ext/js/pages/settings/permissions-origin-controller.js
@@ -60,7 +60,7 @@ export class PermissionsOriginController {
// Private
/**
- * @param {import('settings-controller').PermissionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'permissionsChanged'>} details
*/
_onPermissionsChanged({permissions}) {
this._eventListeners.removeAllEventListeners();
diff --git a/ext/js/pages/settings/permissions-toggle-controller.js b/ext/js/pages/settings/permissions-toggle-controller.js
index 85752a7e..055ce1f4 100644
--- a/ext/js/pages/settings/permissions-toggle-controller.js
+++ b/ext/js/pages/settings/permissions-toggle-controller.js
@@ -47,7 +47,7 @@ export class PermissionsToggleController {
// Private
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
let accessor = null;
@@ -104,7 +104,7 @@ export class PermissionsToggleController {
}
/**
- * @param {import('settings-controller').PermissionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'permissionsChanged'>} details
*/
_onPermissionsChanged({permissions}) {
const permissions2 = permissions.permissions;
diff --git a/ext/js/pages/settings/persistent-storage-controller.js b/ext/js/pages/settings/persistent-storage-controller.js
index 7386edd7..70c9a177 100644
--- a/ext/js/pages/settings/persistent-storage-controller.js
+++ b/ext/js/pages/settings/persistent-storage-controller.js
@@ -82,7 +82,7 @@ export class PersistentStorageController {
const node = document.querySelector('#storage-persistent-fail-warning');
if (node !== null) { node.hidden = isStoragePeristent; }
- yomitan.trigger('storageChanged');
+ yomitan.triggerStorageChanged();
}
/**
diff --git a/ext/js/pages/settings/popup-preview-frame.js b/ext/js/pages/settings/popup-preview-frame.js
index 7828a025..609710ba 100644
--- a/ext/js/pages/settings/popup-preview-frame.js
+++ b/ext/js/pages/settings/popup-preview-frame.js
@@ -140,7 +140,7 @@ export class PopupPreviewFrame {
}
/**
- * @param {import('popup').CustomOuterCssChangedEvent} details
+ * @param {import('popup').EventArgument<'customOuterCssChanged'>} details
*/
_onCustomOuterCssChanged({node, inShadow}) {
if (node === null || inShadow) { return; }
diff --git a/ext/js/pages/settings/profile-conditions-ui.js b/ext/js/pages/settings/profile-conditions-ui.js
index 29e7460f..22e47a9b 100644
--- a/ext/js/pages/settings/profile-conditions-ui.js
+++ b/ext/js/pages/settings/profile-conditions-ui.js
@@ -22,7 +22,7 @@ import {querySelectorNotNull} from '../../dom/query-selector.js';
import {KeyboardMouseInputField} from './keyboard-mouse-input-field.js';
/**
- * @augments EventDispatcher<import('profile-conditions-ui').EventType>
+ * @augments EventDispatcher<import('profile-conditions-ui').Events>
*/
export class ProfileConditionsUI extends EventDispatcher {
/**
@@ -440,9 +440,7 @@ export class ProfileConditionsUI extends EventDispatcher {
* @param {number} count
*/
_triggerConditionGroupCountChanged(count) {
- /** @type {import('profile-conditions-ui').ConditionGroupCountChangedEvent} */
- const event = {count, profileIndex: this._profileIndex};
- this.trigger('conditionGroupCountChanged', event);
+ this.trigger('conditionGroupCountChanged', {count, profileIndex: this._profileIndex});
}
}
@@ -747,7 +745,7 @@ class ProfileConditionUI {
/**
* @param {import('profile-conditions-ui').InputData} details
- * @param {import('keyboard-mouse-input-field').ChangeEvent} event
+ * @param {import('keyboard-mouse-input-field').EventArgument<'change'>} event
*/
_onModifierInputChange({validate, normalize}, event) {
const modifiers = this._joinModifiers(event.modifiers);
@@ -863,10 +861,6 @@ class ProfileConditionUI {
let inputValue = value;
let inputStep = null;
let showMouseButton = false;
- /** @type {import('event-listener-collection').AddEventListenerArgs[]} */
- const events1 = [];
- /** @type {import('event-listener-collection').OnArgs[]} */
- const events2 = [];
/** @type {import('profile-conditions-ui').InputData} */
const inputData = {validate, normalize};
const node = this._valueInput;
@@ -875,7 +869,6 @@ class ProfileConditionUI {
case 'integer':
inputType = 'number';
inputStep = '1';
- events1.push([node, 'change', this._onValueInputChange.bind(this, inputData), false]);
break;
case 'modifierKeys':
case 'modifierInputs':
@@ -883,10 +876,6 @@ class ProfileConditionUI {
showMouseButton = (type === 'modifierInputs');
this._kbmInputField = this._parent.parent.createKeyboardMouseInputField(node, this._mouseButton);
this._kbmInputField.prepare(null, this._splitModifiers(value), showMouseButton, false);
- events2.push([this._kbmInputField, 'change', this._onModifierInputChange.bind(this, inputData)]);
- break;
- default: // 'string'
- events1.push([node, 'change', this._onValueInputChange.bind(this, inputData), false]);
break;
}
@@ -902,11 +891,17 @@ class ProfileConditionUI {
node.removeAttribute('step');
}
this._mouseButtonContainer.hidden = !showMouseButton;
- for (const args of events1) {
- this._inputEventListeners.addEventListener(...args);
- }
- for (const args of events2) {
- this._inputEventListeners.on(...args);
+
+ switch (type) {
+ case 'modifierKeys':
+ case 'modifierInputs':
+ if (this._kbmInputField !== null) {
+ this._inputEventListeners.on(this._kbmInputField, 'change', this._onModifierInputChange.bind(this, inputData));
+ }
+ break;
+ default: // 'integer', 'string'
+ this._inputEventListeners.addEventListener(node, 'change', this._onValueInputChange.bind(this, inputData), false);
+ break;
}
return this._validateValue(value, validate);
diff --git a/ext/js/pages/settings/profile-controller.js b/ext/js/pages/settings/profile-controller.js
index c54bfe73..54a41058 100644
--- a/ext/js/pages/settings/profile-controller.js
+++ b/ext/js/pages/settings/profile-controller.js
@@ -475,7 +475,7 @@ export class ProfileController {
}
/**
- * @param {import('profile-conditions-ui').ConditionGroupCountChangedEvent} details
+ * @param {import('profile-conditions-ui').EventArgument<'conditionGroupCountChanged'>} details
*/
_onConditionGroupCountChanged({count, profileIndex}) {
if (profileIndex >= 0 && profileIndex < this._profileEntryList.length) {
diff --git a/ext/js/pages/settings/recommended-permissions-controller.js b/ext/js/pages/settings/recommended-permissions-controller.js
index b19311aa..a870de50 100644
--- a/ext/js/pages/settings/recommended-permissions-controller.js
+++ b/ext/js/pages/settings/recommended-permissions-controller.js
@@ -48,7 +48,7 @@ export class RecommendedPermissionsController {
// Private
/**
- * @param {import('settings-controller').PermissionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'permissionsChanged'>} details
*/
_onPermissionsChanged({permissions}) {
this._eventListeners.removeAllEventListeners();
diff --git a/ext/js/pages/settings/scan-inputs-controller.js b/ext/js/pages/settings/scan-inputs-controller.js
index eb526863..4854c28f 100644
--- a/ext/js/pages/settings/scan-inputs-controller.js
+++ b/ext/js/pages/settings/scan-inputs-controller.js
@@ -110,7 +110,7 @@ export class ScanInputsController {
// Private
/**
- * @param {import('settings-controller').ScanInputsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'scanInputsChanged'>} details
*/
_onScanInputsChanged({source}) {
if (source === this) { return; }
@@ -118,7 +118,7 @@ export class ScanInputsController {
}
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
const {inputs} = options.scanning;
@@ -190,7 +190,7 @@ export class ScanInputsController {
/** */
_triggerScanInputsChanged() {
- /** @type {import('settings-controller').ScanInputsChangedEvent} */
+ /** @type {import('settings-controller').EventArgument<'scanInputsChanged'>} */
const event = {source: this};
this._settingsController.trigger('scanInputsChanged', event);
}
@@ -312,7 +312,7 @@ class ScanInputField {
// Private
/**
- * @param {import('keyboard-mouse-input-field').ChangeEvent} details
+ * @param {import('keyboard-mouse-input-field').EventArgument<'change'>} details
*/
_onIncludeValueChange({modifiers}) {
const modifiers2 = this._joinModifiers(modifiers);
@@ -320,7 +320,7 @@ class ScanInputField {
}
/**
- * @param {import('keyboard-mouse-input-field').ChangeEvent} details
+ * @param {import('keyboard-mouse-input-field').EventArgument<'change'>} details
*/
_onExcludeValueChange({modifiers}) {
const modifiers2 = this._joinModifiers(modifiers);
diff --git a/ext/js/pages/settings/scan-inputs-simple-controller.js b/ext/js/pages/settings/scan-inputs-simple-controller.js
index ddb68825..f0255595 100644
--- a/ext/js/pages/settings/scan-inputs-simple-controller.js
+++ b/ext/js/pages/settings/scan-inputs-simple-controller.js
@@ -67,7 +67,7 @@ export class ScanInputsSimpleController {
// Private
/**
- * @param {import('settings-controller').ScanInputsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'scanInputsChanged'>} details
*/
_onScanInputsChanged({source}) {
if (source === this) { return; }
@@ -75,7 +75,7 @@ export class ScanInputsSimpleController {
}
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
const {scanning: {inputs}} = options;
@@ -236,7 +236,7 @@ export class ScanInputsSimpleController {
*/
async _modifyProfileSettings(targets) {
await this._settingsController.modifyProfileSettings(targets);
- /** @type {import('settings-controller').ScanInputsChangedEvent} */
+ /** @type {import('settings-controller').EventArgument<'scanInputsChanged'>} */
const event = {source: this};
this._settingsController.trigger('scanInputsChanged', event);
}
diff --git a/ext/js/pages/settings/secondary-search-dictionary-controller.js b/ext/js/pages/settings/secondary-search-dictionary-controller.js
index f24f6ea3..7f0882b8 100644
--- a/ext/js/pages/settings/secondary-search-dictionary-controller.js
+++ b/ext/js/pages/settings/secondary-search-dictionary-controller.js
@@ -66,7 +66,7 @@ export class SecondarySearchDictionaryController {
}
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
this._eventListeners.removeAllEventListeners();
diff --git a/ext/js/pages/settings/sentence-termination-characters-controller.js b/ext/js/pages/settings/sentence-termination-characters-controller.js
index 7fd90b28..f7793943 100644
--- a/ext/js/pages/settings/sentence-termination-characters-controller.js
+++ b/ext/js/pages/settings/sentence-termination-characters-controller.js
@@ -105,7 +105,7 @@ export class SentenceTerminationCharactersController {
// Private
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
for (const entry of this._entries) {
diff --git a/ext/js/pages/settings/settings-controller.js b/ext/js/pages/settings/settings-controller.js
index 1b46c745..52b777a3 100644
--- a/ext/js/pages/settings/settings-controller.js
+++ b/ext/js/pages/settings/settings-controller.js
@@ -23,7 +23,7 @@ import {HtmlTemplateCollection} from '../../dom/html-template-collection.js';
import {yomitan} from '../../yomitan.js';
/**
- * @augments EventDispatcher<import('settings-controller').EventType>
+ * @augments EventDispatcher<import('settings-controller').Events>
*/
export class SettingsController extends EventDispatcher {
constructor() {
@@ -234,7 +234,7 @@ export class SettingsController extends EventDispatcher {
*/
_setProfileIndex(value, canUpdateProfileIndex) {
this._profileIndex = value;
- this.trigger('optionsContextChanged');
+ this.trigger('optionsContextChanged', {});
this._onOptionsUpdatedInternal(canUpdateProfileIndex);
}
@@ -253,9 +253,7 @@ export class SettingsController extends EventDispatcher {
const optionsContext = this.getOptionsContext();
try {
const options = await this.getOptions();
- /** @type {import('settings-controller').OptionsChangedEvent} */
- const event = {options, optionsContext};
- this.trigger('optionsChanged', event);
+ this.trigger('optionsChanged', {options, optionsContext});
} catch (e) {
if (canUpdateProfileIndex) {
this._setProfileIndex(0, false);
@@ -339,9 +337,7 @@ export class SettingsController extends EventDispatcher {
if (!this.hasListeners(eventName)) { return; }
const permissions = await this._permissionsUtil.getAllPermissions();
- /** @type {import('settings-controller').PermissionsChangedEvent} */
- const event = {permissions};
- this.trigger(eventName, event);
+ this.trigger(eventName, {permissions});
}
/**
diff --git a/ext/js/pages/settings/sort-frequency-dictionary-controller.js b/ext/js/pages/settings/sort-frequency-dictionary-controller.js
index 2c56f023..3fdd66c7 100644
--- a/ext/js/pages/settings/sort-frequency-dictionary-controller.js
+++ b/ext/js/pages/settings/sort-frequency-dictionary-controller.js
@@ -68,7 +68,7 @@ export class SortFrequencyDictionaryController {
}
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
const {sortFrequencyDictionary, sortFrequencyDictionaryOrder} = options.general;
diff --git a/ext/js/pages/settings/translation-text-replacements-controller.js b/ext/js/pages/settings/translation-text-replacements-controller.js
index ebd1b58d..9f3fda00 100644
--- a/ext/js/pages/settings/translation-text-replacements-controller.js
+++ b/ext/js/pages/settings/translation-text-replacements-controller.js
@@ -110,7 +110,7 @@ export class TranslationTextReplacementsController {
// Private
/**
- * @param {import('settings-controller').OptionsChangedEvent} details
+ * @param {import('settings-controller').EventArgument<'optionsChanged'>} details
*/
_onOptionsChanged({options}) {
for (const entry of this._entries) {
diff --git a/ext/js/yomitan.js b/ext/js/yomitan.js
index 621e9cf0..8980c589 100644
--- a/ext/js/yomitan.js
+++ b/ext/js/yomitan.js
@@ -50,7 +50,7 @@ if (checkChromeNotAvailable()) {
/**
* The Yomitan class is a core component through which various APIs are handled and invoked.
- * @augments EventDispatcher<import('extension').ExtensionEventType>
+ * @augments EventDispatcher<import('application').Events>
*/
export class Yomitan extends EventDispatcher {
/**
@@ -208,12 +208,22 @@ export class Yomitan extends EventDispatcher {
if (this._isTriggeringExtensionUnloaded) { return; }
try {
this._isTriggeringExtensionUnloaded = true;
- this.trigger('extensionUnloaded');
+ this.trigger('extensionUnloaded', {});
} finally {
this._isTriggeringExtensionUnloaded = false;
}
}
+ /** */
+ triggerStorageChanged() {
+ this.trigger('storageChanged', {});
+ }
+
+ /** */
+ triggerClosePopups() {
+ this.trigger('closePopups', {});
+ }
+
// Private
/**