File size: 2,526 Bytes
064bfd6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | import { Event } from './event.js'
type EventPhase = 'none' | 'capturing' | 'at_target' | 'bubbling'
type TerminalEventInit = {
bubbles?: boolean
cancelable?: boolean
}
/**
* Base class for all terminal events with DOM-style propagation.
*
* Extends Event so existing event types (ClickEvent, InputEvent,
* TerminalFocusEvent) share a common ancestor and can migrate later.
*
* Mirrors the browser's Event API: target, currentTarget, eventPhase,
* stopPropagation(), preventDefault(), timeStamp.
*/
export class TerminalEvent extends Event {
readonly type: string
readonly timeStamp: number
readonly bubbles: boolean
readonly cancelable: boolean
private _target: EventTarget | null = null
private _currentTarget: EventTarget | null = null
private _eventPhase: EventPhase = 'none'
private _propagationStopped = false
private _defaultPrevented = false
constructor(type: string, init?: TerminalEventInit) {
super()
this.type = type
this.timeStamp = performance.now()
this.bubbles = init?.bubbles ?? true
this.cancelable = init?.cancelable ?? true
}
get target(): EventTarget | null {
return this._target
}
get currentTarget(): EventTarget | null {
return this._currentTarget
}
get eventPhase(): EventPhase {
return this._eventPhase
}
get defaultPrevented(): boolean {
return this._defaultPrevented
}
stopPropagation(): void {
this._propagationStopped = true
}
override stopImmediatePropagation(): void {
super.stopImmediatePropagation()
this._propagationStopped = true
}
preventDefault(): void {
if (this.cancelable) {
this._defaultPrevented = true
}
}
// -- Internal setters used by the Dispatcher
/** @internal */
_setTarget(target: EventTarget): void {
this._target = target
}
/** @internal */
_setCurrentTarget(target: EventTarget | null): void {
this._currentTarget = target
}
/** @internal */
_setEventPhase(phase: EventPhase): void {
this._eventPhase = phase
}
/** @internal */
_isPropagationStopped(): boolean {
return this._propagationStopped
}
/** @internal */
_isImmediatePropagationStopped(): boolean {
return this.didStopImmediatePropagation()
}
/**
* Hook for subclasses to do per-node setup before each handler fires.
* Default is a no-op.
*/
_prepareForTarget(_target: EventTarget): void {}
}
export type EventTarget = {
parentNode: EventTarget | undefined
_eventHandlers?: Record<string, unknown>
}
|