You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					400 lines
				
				10 KiB
			
		
		
			
		
	
	
					400 lines
				
				10 KiB
			| 
											3 years ago
										 | export as namespace EventTargetShim | ||
|  | 
 | ||
|  | /** | ||
|  |  * `Event` interface. | ||
|  |  * @see https://dom.spec.whatwg.org/#event
 | ||
|  |  */ | ||
|  | export interface Event { | ||
|  |     /** | ||
|  |      * The type of this event. | ||
|  |      */ | ||
|  |     readonly type: string | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The target of this event. | ||
|  |      */ | ||
|  |     readonly target: EventTarget<{}, {}, "standard"> | null | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The current target of this event. | ||
|  |      */ | ||
|  |     readonly currentTarget: EventTarget<{}, {}, "standard"> | null | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The target of this event. | ||
|  |      * @deprecated | ||
|  |      */ | ||
|  |     readonly srcElement: any | null | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The composed path of this event. | ||
|  |      */ | ||
|  |     composedPath(): EventTarget<{}, {}, "standard">[] | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Constant of NONE. | ||
|  |      */ | ||
|  |     readonly NONE: number | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Constant of CAPTURING_PHASE. | ||
|  |      */ | ||
|  |     readonly CAPTURING_PHASE: number | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Constant of BUBBLING_PHASE. | ||
|  |      */ | ||
|  |     readonly BUBBLING_PHASE: number | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Constant of AT_TARGET. | ||
|  |      */ | ||
|  |     readonly AT_TARGET: number | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Indicates which phase of the event flow is currently being evaluated. | ||
|  |      */ | ||
|  |     readonly eventPhase: number | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Stop event bubbling. | ||
|  |      */ | ||
|  |     stopPropagation(): void | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Stop event bubbling. | ||
|  |      */ | ||
|  |     stopImmediatePropagation(): void | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Initialize event. | ||
|  |      * @deprecated | ||
|  |      */ | ||
|  |     initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The flag indicating bubbling. | ||
|  |      */ | ||
|  |     readonly bubbles: boolean | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Stop event bubbling. | ||
|  |      * @deprecated | ||
|  |      */ | ||
|  |     cancelBubble: boolean | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Set or get cancellation flag. | ||
|  |      * @deprecated | ||
|  |      */ | ||
|  |     returnValue: boolean | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The flag indicating whether the event can be canceled. | ||
|  |      */ | ||
|  |     readonly cancelable: boolean | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Cancel this event. | ||
|  |      */ | ||
|  |     preventDefault(): void | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The flag to indicating whether the event was canceled. | ||
|  |      */ | ||
|  |     readonly defaultPrevented: boolean | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The flag to indicating if event is composed. | ||
|  |      */ | ||
|  |     readonly composed: boolean | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Indicates whether the event was dispatched by the user agent. | ||
|  |      */ | ||
|  |     readonly isTrusted: boolean | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The unix time of this event. | ||
|  |      */ | ||
|  |     readonly timeStamp: number | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * The constructor of `EventTarget` interface. | ||
|  |  */ | ||
|  | export type EventTargetConstructor< | ||
|  |     TEvents extends EventTarget.EventDefinition = {}, | ||
|  |     TEventAttributes extends EventTarget.EventDefinition = {}, | ||
|  |     TMode extends EventTarget.Mode = "loose" | ||
|  | > = { | ||
|  |     prototype: EventTarget<TEvents, TEventAttributes, TMode> | ||
|  |     new(): EventTarget<TEvents, TEventAttributes, TMode> | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * `EventTarget` interface. | ||
|  |  * @see https://dom.spec.whatwg.org/#interface-eventtarget
 | ||
|  |  */ | ||
|  | export type EventTarget< | ||
|  |     TEvents extends EventTarget.EventDefinition = {}, | ||
|  |     TEventAttributes extends EventTarget.EventDefinition = {}, | ||
|  |     TMode extends EventTarget.Mode = "loose" | ||
|  | > = EventTarget.EventAttributes<TEventAttributes> & { | ||
|  |     /** | ||
|  |      * Add a given listener to this event target. | ||
|  |      * @param eventName The event name to add. | ||
|  |      * @param listener The listener to add. | ||
|  |      * @param options The options for this listener. | ||
|  |      */ | ||
|  |     addEventListener<TEventType extends EventTarget.EventType<TEvents, TMode>>( | ||
|  |         type: TEventType, | ||
|  |         listener: | ||
|  |             | EventTarget.Listener<EventTarget.PickEvent<TEvents, TEventType>> | ||
|  |             | null, | ||
|  |         options?: boolean | EventTarget.AddOptions | ||
|  |     ): void | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Remove a given listener from this event target. | ||
|  |      * @param eventName The event name to remove. | ||
|  |      * @param listener The listener to remove. | ||
|  |      * @param options The options for this listener. | ||
|  |      */ | ||
|  |     removeEventListener<TEventType extends EventTarget.EventType<TEvents, TMode>>( | ||
|  |         type: TEventType, | ||
|  |         listener: | ||
|  |             | EventTarget.Listener<EventTarget.PickEvent<TEvents, TEventType>> | ||
|  |             | null, | ||
|  |         options?: boolean | EventTarget.RemoveOptions | ||
|  |     ): void | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Dispatch a given event. | ||
|  |      * @param event The event to dispatch. | ||
|  |      * @returns `false` if canceled. | ||
|  |      */ | ||
|  |     dispatchEvent<TEventType extends EventTarget.EventType<TEvents, TMode>>( | ||
|  |         event: EventTarget.EventData<TEvents, TEventType, TMode> | ||
|  |     ): boolean | ||
|  | } | ||
|  | 
 | ||
|  | export const EventTarget: EventTargetConstructor & { | ||
|  |     /** | ||
|  |      * Create an `EventTarget` instance with detailed event definition. | ||
|  |      * | ||
|  |      * The detailed event definition requires to use `defineEventAttribute()` | ||
|  |      * function later. | ||
|  |      * | ||
|  |      * Unfortunately, the second type parameter `TEventAttributes` was needed | ||
|  |      * because we cannot compute string literal types. | ||
|  |      * | ||
|  |      * @example | ||
|  |      * const signal = new EventTarget<{ abort: Event }, { onabort: Event }>() | ||
|  |      * defineEventAttribute(signal, "abort") | ||
|  |      */ | ||
|  |     new < | ||
|  |         TEvents extends EventTarget.EventDefinition, | ||
|  |         TEventAttributes extends EventTarget.EventDefinition, | ||
|  |         TMode extends EventTarget.Mode = "loose" | ||
|  |     >(): EventTarget<TEvents, TEventAttributes, TMode> | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Define an `EventTarget` constructor with attribute events and detailed event definition. | ||
|  |      * | ||
|  |      * Unfortunately, the second type parameter `TEventAttributes` was needed | ||
|  |      * because we cannot compute string literal types. | ||
|  |      * | ||
|  |      * @example | ||
|  |      * class AbortSignal extends EventTarget<{ abort: Event }, { onabort: Event }>("abort") { | ||
|  |      *      abort(): void {} | ||
|  |      * } | ||
|  |      * | ||
|  |      * @param events Optional event attributes (e.g. passing in `"click"` adds `onclick` to prototype). | ||
|  |      */ | ||
|  |     < | ||
|  |         TEvents extends EventTarget.EventDefinition = {}, | ||
|  |         TEventAttributes extends EventTarget.EventDefinition = {}, | ||
|  |         TMode extends EventTarget.Mode = "loose" | ||
|  |     >(events: string[]): EventTargetConstructor< | ||
|  |         TEvents, | ||
|  |         TEventAttributes, | ||
|  |         TMode | ||
|  |     > | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Define an `EventTarget` constructor with attribute events and detailed event definition. | ||
|  |      * | ||
|  |      * Unfortunately, the second type parameter `TEventAttributes` was needed | ||
|  |      * because we cannot compute string literal types. | ||
|  |      * | ||
|  |      * @example | ||
|  |      * class AbortSignal extends EventTarget<{ abort: Event }, { onabort: Event }>("abort") { | ||
|  |      *      abort(): void {} | ||
|  |      * } | ||
|  |      * | ||
|  |      * @param events Optional event attributes (e.g. passing in `"click"` adds `onclick` to prototype). | ||
|  |      */ | ||
|  |     < | ||
|  |         TEvents extends EventTarget.EventDefinition = {}, | ||
|  |         TEventAttributes extends EventTarget.EventDefinition = {}, | ||
|  |         TMode extends EventTarget.Mode = "loose" | ||
|  |     >(event0: string, ...events: string[]): EventTargetConstructor< | ||
|  |         TEvents, | ||
|  |         TEventAttributes, | ||
|  |         TMode | ||
|  |     > | ||
|  | } | ||
|  | 
 | ||
|  | export namespace EventTarget { | ||
|  |     /** | ||
|  |      * Options of `removeEventListener()` method. | ||
|  |      */ | ||
|  |     export interface RemoveOptions { | ||
|  |         /** | ||
|  |          * The flag to indicate that the listener is for the capturing phase. | ||
|  |          */ | ||
|  |         capture?: boolean | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Options of `addEventListener()` method. | ||
|  |      */ | ||
|  |     export interface AddOptions extends RemoveOptions { | ||
|  |         /** | ||
|  |          * The flag to indicate that the listener doesn't support | ||
|  |          * `event.preventDefault()` operation. | ||
|  |          */ | ||
|  |         passive?: boolean | ||
|  |         /** | ||
|  |          * The flag to indicate that the listener will be removed on the first | ||
|  |          * event. | ||
|  |          */ | ||
|  |         once?: boolean | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The type of regular listeners. | ||
|  |      */ | ||
|  |     export interface FunctionListener<TEvent> { | ||
|  |         (event: TEvent): void | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The type of object listeners. | ||
|  |      */ | ||
|  |     export interface ObjectListener<TEvent> { | ||
|  |         handleEvent(event: TEvent): void | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The type of listeners. | ||
|  |      */ | ||
|  |     export type Listener<TEvent> = | ||
|  |         | FunctionListener<TEvent> | ||
|  |         | ObjectListener<TEvent> | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Event definition. | ||
|  |      */ | ||
|  |     export type EventDefinition = { | ||
|  |         readonly [key: string]: Event | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Mapped type for event attributes. | ||
|  |      */ | ||
|  |     export type EventAttributes<TEventAttributes extends EventDefinition> = { | ||
|  |         [P in keyof TEventAttributes]: | ||
|  |             | FunctionListener<TEventAttributes[P]> | ||
|  |             | null | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The type of event data for `dispatchEvent()` method. | ||
|  |      */ | ||
|  |     export type EventData< | ||
|  |         TEvents extends EventDefinition, | ||
|  |         TEventType extends keyof TEvents | string, | ||
|  |         TMode extends Mode | ||
|  |     > = | ||
|  |         TEventType extends keyof TEvents | ||
|  |             ? ( | ||
|  |                 // Require properties which are not generated automatically.
 | ||
|  |                 & Pick< | ||
|  |                     TEvents[TEventType], | ||
|  |                     Exclude<keyof TEvents[TEventType], OmittableEventKeys> | ||
|  |                 > | ||
|  |                 // Properties which are generated automatically are optional.
 | ||
|  |                 & Partial<Pick<Event, OmittableEventKeys>> | ||
|  |             ) | ||
|  |             : ( | ||
|  |                 TMode extends "standard" | ||
|  |                     ? Event | ||
|  |                     : Event | NonStandardEvent | ||
|  |             ) | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The string literal types of the properties which are generated | ||
|  |      * automatically in `dispatchEvent()` method. | ||
|  |      */ | ||
|  |     export type OmittableEventKeys = Exclude<keyof Event, "type"> | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The type of event data. | ||
|  |      */ | ||
|  |     export type NonStandardEvent = { | ||
|  |         [key: string]: any | ||
|  |         type: string | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * The type of listeners. | ||
|  |      */ | ||
|  |     export type PickEvent< | ||
|  |         TEvents extends EventDefinition, | ||
|  |         TEventType extends keyof TEvents | string, | ||
|  |     > = | ||
|  |         TEventType extends keyof TEvents | ||
|  |             ? TEvents[TEventType] | ||
|  |             : Event | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Event type candidates. | ||
|  |      */ | ||
|  |     export type EventType< | ||
|  |         TEvents extends EventDefinition, | ||
|  |         TMode extends Mode | ||
|  |     > = | ||
|  |         TMode extends "strict" | ||
|  |             ? keyof TEvents | ||
|  |             : keyof TEvents | string | ||
|  | 
 | ||
|  |     /** | ||
|  |      * - `"strict"` ..... Methods don't accept unknown events. | ||
|  |      *                    `dispatchEvent()` accepts partial objects. | ||
|  |      * - `"loose"` ...... Methods accept unknown events. | ||
|  |      *                    `dispatchEvent()` accepts partial objects. | ||
|  |      * - `"standard"` ... Methods accept unknown events. | ||
|  |      *                    `dispatchEvent()` doesn't accept partial objects. | ||
|  |      */ | ||
|  |     export type Mode = "strict" | "standard" | "loose" | ||
|  | } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Specialized `type` property. | ||
|  |  */ | ||
|  | export type Type<T extends string> = { type: T } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Define an event attribute (e.g. `eventTarget.onclick`). | ||
|  |  * @param prototype The event target prototype to define an event attribute. | ||
|  |  * @param eventName The event name to define. | ||
|  |  */ | ||
|  | export function defineEventAttribute( | ||
|  |     prototype: EventTarget, | ||
|  |     eventName: string | ||
|  | ): void | ||
|  | 
 | ||
|  | export default EventTarget |