@planningcenter/chat-react-native 3.15.0-rc.6 → 3.15.0-rc.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/display/avatar.d.ts +3 -1
- package/build/components/display/avatar.d.ts.map +1 -1
- package/build/components/display/avatar.js +2 -2
- package/build/components/display/avatar.js.map +1 -1
- package/build/components/display/avatar_group.d.ts +3 -1
- package/build/components/display/avatar_group.d.ts.map +1 -1
- package/build/components/display/avatar_group.js +2 -2
- package/build/components/display/avatar_group.js.map +1 -1
- package/build/components/primitive/avatar_primitive.d.ts +2 -0
- package/build/components/primitive/avatar_primitive.d.ts.map +1 -1
- package/build/components/primitive/avatar_primitive.js +20 -19
- package/build/components/primitive/avatar_primitive.js.map +1 -1
- package/build/index.d.ts +2 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -0
- package/build/index.js.map +1 -1
- package/build/polyfills/events/CustomEvent.d.ts +21 -0
- package/build/polyfills/events/CustomEvent.d.ts.map +1 -0
- package/build/polyfills/events/CustomEvent.js +22 -0
- package/build/polyfills/events/CustomEvent.js.map +1 -0
- package/build/polyfills/events/Event.d.ts +49 -0
- package/build/polyfills/events/Event.d.ts.map +1 -0
- package/build/polyfills/events/Event.js +125 -0
- package/build/polyfills/events/Event.js.map +1 -0
- package/build/polyfills/events/EventHandlerAttributes.d.ts +8 -0
- package/build/polyfills/events/EventHandlerAttributes.d.ts.map +1 -0
- package/build/polyfills/events/EventHandlerAttributes.js +46 -0
- package/build/polyfills/events/EventHandlerAttributes.js.map +1 -0
- package/build/polyfills/events/EventTarget.d.ts +33 -0
- package/build/polyfills/events/EventTarget.d.ts.map +1 -0
- package/build/polyfills/events/EventTarget.js +238 -0
- package/build/polyfills/events/EventTarget.js.map +1 -0
- package/build/polyfills/events/internals/EventInternals.d.ts +30 -0
- package/build/polyfills/events/internals/EventInternals.d.ts.map +1 -0
- package/build/polyfills/events/internals/EventInternals.js +76 -0
- package/build/polyfills/events/internals/EventInternals.js.map +1 -0
- package/build/polyfills/events/internals/EventTargetInternals.d.ts +9 -0
- package/build/polyfills/events/internals/EventTargetInternals.d.ts.map +1 -0
- package/build/polyfills/events/internals/EventTargetInternals.js +11 -0
- package/build/polyfills/events/internals/EventTargetInternals.js.map +1 -0
- package/build/polyfills/webidl/PlatformObjects.d.ts +31 -0
- package/build/polyfills/webidl/PlatformObjects.d.ts.map +1 -0
- package/build/polyfills/webidl/PlatformObjects.js +39 -0
- package/build/polyfills/webidl/PlatformObjects.js.map +1 -0
- package/package.json +5 -5
- package/src/__tests__/event-polyfill.test.ts +314 -0
- package/src/components/display/avatar.tsx +5 -1
- package/src/components/display/avatar_group.tsx +5 -1
- package/src/components/primitive/avatar_primitive.tsx +35 -19
- package/src/index.tsx +2 -0
- package/src/polyfills/events/CustomEvent.ts +32 -0
- package/src/polyfills/events/Event.ts +186 -0
- package/src/polyfills/events/EventHandlerAttributes.ts +67 -0
- package/src/polyfills/events/EventTarget.ts +360 -0
- package/src/polyfills/events/README.md +1 -0
- package/src/polyfills/events/internals/EventInternals.ts +95 -0
- package/src/polyfills/events/internals/EventTargetInternals.ts +16 -0
- package/src/polyfills/webidl/PlatformObjects.ts +50 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* This module implements the `Event` interface from the DOM.
|
|
10
|
+
* See https://dom.spec.whatwg.org/#interface-event.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type RNEventTarget from './EventTarget'
|
|
14
|
+
import {
|
|
15
|
+
getComposedPath,
|
|
16
|
+
getCurrentTarget,
|
|
17
|
+
getEventPhase,
|
|
18
|
+
getInPassiveListenerFlag,
|
|
19
|
+
getIsTrusted,
|
|
20
|
+
getTarget,
|
|
21
|
+
setStopImmediatePropagationFlag,
|
|
22
|
+
setStopPropagationFlag,
|
|
23
|
+
setIsTrusted,
|
|
24
|
+
setEventPhase,
|
|
25
|
+
} from './internals/EventInternals'
|
|
26
|
+
import { setPlatformObject } from '../webidl/PlatformObjects'
|
|
27
|
+
|
|
28
|
+
export interface EventInit {
|
|
29
|
+
bubbles?: boolean
|
|
30
|
+
cancelable?: boolean
|
|
31
|
+
composed?: boolean
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type EventPhase = 0 | 1 | 2 | 3
|
|
35
|
+
|
|
36
|
+
export default class Event {
|
|
37
|
+
static NONE: 0
|
|
38
|
+
static CAPTURING_PHASE: 1
|
|
39
|
+
static AT_TARGET: 2
|
|
40
|
+
static BUBBLING_PHASE: 3
|
|
41
|
+
|
|
42
|
+
readonly NONE!: 0
|
|
43
|
+
readonly CAPTURING_PHASE!: 1
|
|
44
|
+
readonly AT_TARGET!: 2
|
|
45
|
+
readonly BUBBLING_PHASE!: 3
|
|
46
|
+
|
|
47
|
+
private _bubbles: boolean
|
|
48
|
+
private _cancelable: boolean
|
|
49
|
+
private _composed: boolean
|
|
50
|
+
private _type: string
|
|
51
|
+
|
|
52
|
+
private _defaultPrevented: boolean = false
|
|
53
|
+
private _timeStamp: number = performance.now()
|
|
54
|
+
|
|
55
|
+
// Symbol-keyed fields are internal and managed via helpers; not declared here.
|
|
56
|
+
|
|
57
|
+
constructor(type: string, options?: EventInit | null) {
|
|
58
|
+
if (arguments.length < 1) {
|
|
59
|
+
throw new TypeError("Failed to construct 'Event': 1 argument required, but only 0 present.")
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const typeOfOptions = typeof options
|
|
63
|
+
if (options != null && typeOfOptions !== 'object' && typeOfOptions !== 'function') {
|
|
64
|
+
throw new TypeError(
|
|
65
|
+
"Failed to construct 'Event': The provided value is not of type 'EventInit'."
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
this._type = String(type)
|
|
70
|
+
this._bubbles = Boolean((options as EventInit | undefined)?.bubbles)
|
|
71
|
+
this._cancelable = Boolean((options as EventInit | undefined)?.cancelable)
|
|
72
|
+
this._composed = Boolean((options as EventInit | undefined)?.composed)
|
|
73
|
+
|
|
74
|
+
// Initialize internal flags
|
|
75
|
+
setIsTrusted(this, false)
|
|
76
|
+
setEventPhase(this, 0 as 0)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
get bubbles(): boolean {
|
|
80
|
+
return this._bubbles
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
get cancelable(): boolean {
|
|
84
|
+
return this._cancelable
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
get composed(): boolean {
|
|
88
|
+
return this._composed
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
get currentTarget(): RNEventTarget | null {
|
|
92
|
+
return getCurrentTarget(this)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
get defaultPrevented(): boolean {
|
|
96
|
+
return this._defaultPrevented
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
get eventPhase(): EventPhase {
|
|
100
|
+
return getEventPhase(this)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
get isTrusted(): boolean {
|
|
104
|
+
return getIsTrusted(this)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
get target(): RNEventTarget | null {
|
|
108
|
+
return getTarget(this)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
get timeStamp(): number {
|
|
112
|
+
return this._timeStamp
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
get type(): string {
|
|
116
|
+
return this._type
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
composedPath(): ReadonlyArray<RNEventTarget> {
|
|
120
|
+
return getComposedPath(this).slice()
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
preventDefault(): void {
|
|
124
|
+
if (!this._cancelable) {
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (getInPassiveListenerFlag(this)) {
|
|
129
|
+
console.error(new Error('Unable to preventDefault inside passive event listener invocation.'))
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
this._defaultPrevented = true
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
stopImmediatePropagation(): void {
|
|
137
|
+
setStopPropagationFlag(this, true)
|
|
138
|
+
setStopImmediatePropagationFlag(this, true)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
stopPropagation(): void {
|
|
142
|
+
setStopPropagationFlag(this, true)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Object.defineProperty(Event, 'NONE', {
|
|
147
|
+
enumerable: true,
|
|
148
|
+
value: 0,
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
Object.defineProperty(Event.prototype, 'NONE', {
|
|
152
|
+
enumerable: true,
|
|
153
|
+
value: 0,
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
Object.defineProperty(Event, 'CAPTURING_PHASE', {
|
|
157
|
+
enumerable: true,
|
|
158
|
+
value: 1,
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
Object.defineProperty(Event.prototype, 'CAPTURING_PHASE', {
|
|
162
|
+
enumerable: true,
|
|
163
|
+
value: 1,
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
Object.defineProperty(Event, 'AT_TARGET', {
|
|
167
|
+
enumerable: true,
|
|
168
|
+
value: 2,
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
Object.defineProperty(Event.prototype, 'AT_TARGET', {
|
|
172
|
+
enumerable: true,
|
|
173
|
+
value: 2,
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
Object.defineProperty(Event, 'BUBBLING_PHASE', {
|
|
177
|
+
enumerable: true,
|
|
178
|
+
value: 3,
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
Object.defineProperty(Event.prototype, 'BUBBLING_PHASE', {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
value: 3,
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
setPlatformObject(Event)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers to implement event handler IDL attributes.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type EventTarget from './EventTarget'
|
|
6
|
+
import type { EventCallback } from './EventTarget'
|
|
7
|
+
|
|
8
|
+
type EventHandler = Readonly<{
|
|
9
|
+
handleEvent: EventCallback
|
|
10
|
+
}>
|
|
11
|
+
type EventHandlerAttributeMap = Map<string, EventHandler | null>
|
|
12
|
+
|
|
13
|
+
const EVENT_HANDLER_CONTENT_ATTRIBUTE_MAP_KEY = Symbol('eventHandlerAttributeMap')
|
|
14
|
+
|
|
15
|
+
function getEventHandlerAttributeMap(
|
|
16
|
+
target: EventTarget
|
|
17
|
+
): EventHandlerAttributeMap | null | undefined {
|
|
18
|
+
return (target as any)[EVENT_HANDLER_CONTENT_ATTRIBUTE_MAP_KEY]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function setEventHandlerAttributeMap(target: EventTarget, map: EventHandlerAttributeMap | null) {
|
|
22
|
+
;(target as any)[EVENT_HANDLER_CONTENT_ATTRIBUTE_MAP_KEY] = map
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getEventHandlerAttribute(target: EventTarget, type: string): EventCallback | null {
|
|
26
|
+
const listener = getEventHandlerAttributeMap(target)?.get(type)
|
|
27
|
+
return listener != null ? listener.handleEvent : null
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function setEventHandlerAttribute(
|
|
31
|
+
target: EventTarget,
|
|
32
|
+
type: string,
|
|
33
|
+
callback: EventCallback | null | undefined
|
|
34
|
+
): void {
|
|
35
|
+
let map = getEventHandlerAttributeMap(target)
|
|
36
|
+
if (map != null) {
|
|
37
|
+
const currentListener = map.get(type)
|
|
38
|
+
if (currentListener) {
|
|
39
|
+
target.removeEventListener(type, currentListener)
|
|
40
|
+
map.delete(type)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (
|
|
45
|
+
callback != null &&
|
|
46
|
+
(typeof callback === 'function' || typeof (callback as any) === 'object')
|
|
47
|
+
) {
|
|
48
|
+
const listener: EventHandler = {
|
|
49
|
+
handleEvent: callback as EventCallback,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
target.addEventListener(type, listener)
|
|
54
|
+
if (map == null) {
|
|
55
|
+
map = new Map()
|
|
56
|
+
setEventHandlerAttributeMap(target, map)
|
|
57
|
+
}
|
|
58
|
+
map.set(type, listener)
|
|
59
|
+
} catch (_e) {
|
|
60
|
+
// Assigning incorrect listener does not throw in setters.
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (map != null && map.size === 0) {
|
|
65
|
+
setEventHandlerAttributeMap(target, null)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Implements the `EventTarget` interface from the DOM.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import Event from './Event'
|
|
13
|
+
import {
|
|
14
|
+
getStopImmediatePropagationFlag,
|
|
15
|
+
getStopPropagationFlag,
|
|
16
|
+
setComposedPath,
|
|
17
|
+
setCurrentTarget,
|
|
18
|
+
setEventPhase,
|
|
19
|
+
setInPassiveListenerFlag,
|
|
20
|
+
setIsTrusted,
|
|
21
|
+
setStopImmediatePropagationFlag,
|
|
22
|
+
setStopPropagationFlag,
|
|
23
|
+
setTarget,
|
|
24
|
+
} from './internals/EventInternals'
|
|
25
|
+
import {
|
|
26
|
+
EVENT_TARGET_GET_THE_PARENT_KEY,
|
|
27
|
+
INTERNAL_DISPATCH_METHOD_KEY,
|
|
28
|
+
} from './internals/EventTargetInternals'
|
|
29
|
+
import { setPlatformObject } from '../webidl/PlatformObjects'
|
|
30
|
+
|
|
31
|
+
export type EventCallback = (event: Event) => void
|
|
32
|
+
export type EventHandler = { handleEvent(event: Event): void }
|
|
33
|
+
export type EventListener = EventCallback | EventHandler
|
|
34
|
+
|
|
35
|
+
export type EventListenerOptions = Readonly<{
|
|
36
|
+
capture?: boolean
|
|
37
|
+
}>
|
|
38
|
+
|
|
39
|
+
export type AddEventListenerOptions = Readonly<{
|
|
40
|
+
capture?: boolean
|
|
41
|
+
passive?: boolean
|
|
42
|
+
once?: boolean
|
|
43
|
+
signal?: AbortSignal
|
|
44
|
+
}>
|
|
45
|
+
|
|
46
|
+
type EventListenerRegistration = {
|
|
47
|
+
readonly callback: EventListener
|
|
48
|
+
readonly passive: boolean
|
|
49
|
+
readonly once: boolean
|
|
50
|
+
removed: boolean
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type ListenersMap = Map<string, Map<EventListener, EventListenerRegistration>>
|
|
54
|
+
|
|
55
|
+
export default class EventTarget {
|
|
56
|
+
addEventListener(
|
|
57
|
+
type: string,
|
|
58
|
+
callback: EventListener | null,
|
|
59
|
+
optionsOrUseCapture: AddEventListenerOptions | boolean = {}
|
|
60
|
+
): void {
|
|
61
|
+
if (arguments.length < 2) {
|
|
62
|
+
throw new TypeError(
|
|
63
|
+
`Failed to execute 'addEventListener' on 'EventTarget': 2 arguments required, but only ${arguments.length} present.`
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (callback == null) {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
validateCallback(callback, 'addEventListener')
|
|
72
|
+
|
|
73
|
+
const processedType = String(type)
|
|
74
|
+
|
|
75
|
+
let capture: boolean
|
|
76
|
+
let passive: boolean
|
|
77
|
+
let once: boolean
|
|
78
|
+
let signal: AbortSignal | null | undefined
|
|
79
|
+
|
|
80
|
+
if (
|
|
81
|
+
optionsOrUseCapture != null &&
|
|
82
|
+
(typeof optionsOrUseCapture === 'object' || typeof optionsOrUseCapture === 'function')
|
|
83
|
+
) {
|
|
84
|
+
const opts = optionsOrUseCapture as AddEventListenerOptions
|
|
85
|
+
capture = Boolean(opts.capture)
|
|
86
|
+
passive =
|
|
87
|
+
opts.passive == null ? getDefaultPassiveValue(processedType, this) : Boolean(opts.passive)
|
|
88
|
+
once = Boolean(opts.once)
|
|
89
|
+
signal = opts.signal
|
|
90
|
+
if (signal !== undefined && !(signal instanceof AbortSignal)) {
|
|
91
|
+
throw new TypeError(
|
|
92
|
+
"Failed to execute 'addEventListener' on 'EventTarget': Failed to read the 'signal' property from 'AddEventListenerOptions': Failed to convert value to 'AbortSignal'."
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
capture = Boolean(optionsOrUseCapture)
|
|
97
|
+
passive = false
|
|
98
|
+
once = false
|
|
99
|
+
signal = null
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (signal?.aborted) {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let listenersByType = getListenersForPhase(this, capture)
|
|
107
|
+
let listeners = listenersByType?.get(processedType)
|
|
108
|
+
if (listeners == null) {
|
|
109
|
+
if (listenersByType == null) {
|
|
110
|
+
listenersByType = new Map()
|
|
111
|
+
setListenersMap(this, capture, listenersByType)
|
|
112
|
+
}
|
|
113
|
+
listeners = new Map()
|
|
114
|
+
listenersByType.set(processedType, listeners)
|
|
115
|
+
} else if (listeners.has(callback)) {
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const listener: EventListenerRegistration = {
|
|
120
|
+
callback,
|
|
121
|
+
passive,
|
|
122
|
+
once,
|
|
123
|
+
removed: false,
|
|
124
|
+
}
|
|
125
|
+
listeners.set(callback, listener)
|
|
126
|
+
|
|
127
|
+
const nonNullListeners = listeners
|
|
128
|
+
|
|
129
|
+
if (signal != null) {
|
|
130
|
+
signal.addEventListener(
|
|
131
|
+
'abort',
|
|
132
|
+
() => {
|
|
133
|
+
listener.removed = true
|
|
134
|
+
if (nonNullListeners.get(callback) === listener) {
|
|
135
|
+
nonNullListeners.delete(callback)
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{ once: true }
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
removeEventListener(
|
|
144
|
+
type: string,
|
|
145
|
+
callback: EventListener,
|
|
146
|
+
optionsOrUseCapture: EventListenerOptions | boolean = {}
|
|
147
|
+
): void {
|
|
148
|
+
if (arguments.length < 2) {
|
|
149
|
+
throw new TypeError(
|
|
150
|
+
`Failed to execute 'removeEventListener' on 'EventTarget': 2 arguments required, but only ${arguments.length} present.`
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (callback == null) {
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
validateCallback(callback, 'removeEventListener')
|
|
159
|
+
|
|
160
|
+
const processedType = String(type)
|
|
161
|
+
|
|
162
|
+
const capture =
|
|
163
|
+
typeof optionsOrUseCapture === 'boolean'
|
|
164
|
+
? optionsOrUseCapture
|
|
165
|
+
: Boolean((optionsOrUseCapture as EventListenerOptions).capture)
|
|
166
|
+
|
|
167
|
+
const listenersByType = getListenersForPhase(this, capture)
|
|
168
|
+
const listeners = listenersByType?.get(processedType)
|
|
169
|
+
if (listeners == null) {
|
|
170
|
+
return
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const listener = listeners.get(callback)
|
|
174
|
+
if (listener != null) {
|
|
175
|
+
listener.removed = true
|
|
176
|
+
listeners.delete(callback)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
dispatchEvent(event: Event): boolean {
|
|
181
|
+
if (!(event instanceof Event)) {
|
|
182
|
+
throw new TypeError(
|
|
183
|
+
"Failed to execute 'dispatchEvent' on 'EventTarget': parameter 1 is not of type 'Event'."
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (getEventDispatchFlag(event)) {
|
|
188
|
+
throw new Error(
|
|
189
|
+
"Failed to execute 'dispatchEvent' on 'EventTarget': The event is already being dispatched."
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
setIsTrusted(event, false)
|
|
194
|
+
dispatch(this, event)
|
|
195
|
+
return !event.defaultPrevented
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// "protected" for subclasses: get the parent (see spec)
|
|
199
|
+
[EVENT_TARGET_GET_THE_PARENT_KEY](): EventTarget | null {
|
|
200
|
+
return null
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// "protected" to dispatch trusted events
|
|
204
|
+
[INTERNAL_DISPATCH_METHOD_KEY](event: Event): void {
|
|
205
|
+
dispatch(this, event)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
setPlatformObject(EventTarget)
|
|
210
|
+
|
|
211
|
+
function validateCallback(callback: EventListener, methodName: string): void {
|
|
212
|
+
if (typeof callback !== 'function' && typeof callback !== 'object') {
|
|
213
|
+
throw new TypeError(
|
|
214
|
+
`Failed to execute '${methodName}' on 'EventTarget': parameter 2 is not of type 'Object'.`
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function getDefaultPassiveValue(_type: string, _eventTarget: EventTarget): boolean {
|
|
220
|
+
return false
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function dispatch(eventTarget: EventTarget, event: Event): void {
|
|
224
|
+
setEventDispatchFlag(event, true)
|
|
225
|
+
|
|
226
|
+
const eventPath = getEventPath(eventTarget, event)
|
|
227
|
+
setComposedPath(event, eventPath)
|
|
228
|
+
setTarget(event, eventTarget)
|
|
229
|
+
|
|
230
|
+
for (let i = eventPath.length - 1; i >= 0; i--) {
|
|
231
|
+
if (getStopPropagationFlag(event)) {
|
|
232
|
+
break
|
|
233
|
+
}
|
|
234
|
+
const target = eventPath[i]
|
|
235
|
+
setEventPhase(event, target === eventTarget ? Event.AT_TARGET : Event.CAPTURING_PHASE)
|
|
236
|
+
invoke(target, event, Event.CAPTURING_PHASE)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
for (const target of eventPath) {
|
|
240
|
+
if (getStopPropagationFlag(event)) {
|
|
241
|
+
break
|
|
242
|
+
}
|
|
243
|
+
if (!event.bubbles && target !== eventTarget) {
|
|
244
|
+
break
|
|
245
|
+
}
|
|
246
|
+
setEventPhase(event, target === eventTarget ? Event.AT_TARGET : Event.BUBBLING_PHASE)
|
|
247
|
+
invoke(target, event, Event.BUBBLING_PHASE)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
setEventPhase(event, Event.NONE)
|
|
251
|
+
setCurrentTarget(event, null)
|
|
252
|
+
setComposedPath(event, [])
|
|
253
|
+
|
|
254
|
+
setEventDispatchFlag(event, false)
|
|
255
|
+
setStopImmediatePropagationFlag(event, false)
|
|
256
|
+
setStopPropagationFlag(event, false)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function getEventPath(eventTarget: EventTarget, _event: Event): ReadonlyArray<EventTarget> {
|
|
260
|
+
const path: EventTarget[] = []
|
|
261
|
+
let target: EventTarget | null = eventTarget
|
|
262
|
+
|
|
263
|
+
while (target != null) {
|
|
264
|
+
path.push(target)
|
|
265
|
+
target = target[EVENT_TARGET_GET_THE_PARENT_KEY]()
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return path
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function invoke(eventTarget: EventTarget, event: Event, eventPhase: import('./Event').EventPhase) {
|
|
272
|
+
const listenersByType = getListenersForPhase(eventTarget, eventPhase === Event.CAPTURING_PHASE)
|
|
273
|
+
|
|
274
|
+
setCurrentTarget(event, eventTarget)
|
|
275
|
+
|
|
276
|
+
const maybeListeners = listenersByType?.get(event.type)
|
|
277
|
+
if (maybeListeners == null) {
|
|
278
|
+
return
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const listeners = Array.from(maybeListeners.values())
|
|
282
|
+
setCurrentTarget(event, eventTarget)
|
|
283
|
+
|
|
284
|
+
for (const listener of listeners) {
|
|
285
|
+
if (listener.removed) {
|
|
286
|
+
continue
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (listener.once) {
|
|
290
|
+
eventTarget.removeEventListener(
|
|
291
|
+
event.type,
|
|
292
|
+
listener.callback,
|
|
293
|
+
eventPhase === Event.CAPTURING_PHASE
|
|
294
|
+
)
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (listener.passive) {
|
|
298
|
+
setInPassiveListenerFlag(event, true)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const currentEvent = (global as any).event
|
|
302
|
+
;(global as any).event = event
|
|
303
|
+
|
|
304
|
+
const callback = listener.callback as any
|
|
305
|
+
try {
|
|
306
|
+
if (typeof callback === 'function') {
|
|
307
|
+
callback.call(eventTarget, event)
|
|
308
|
+
} else if (typeof callback.handleEvent === 'function') {
|
|
309
|
+
callback.handleEvent(event)
|
|
310
|
+
}
|
|
311
|
+
} catch (error) {
|
|
312
|
+
// TODO: replace with `reportError` when it's available.
|
|
313
|
+
|
|
314
|
+
console.error(error)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (listener.passive) {
|
|
318
|
+
setInPassiveListenerFlag(event, false)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
;(global as any).event = currentEvent
|
|
322
|
+
|
|
323
|
+
if (getStopImmediatePropagationFlag(event)) {
|
|
324
|
+
break
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const CAPTURING_LISTENERS_KEY = Symbol('capturingListeners')
|
|
330
|
+
const BUBBLING_LISTENERS_KEY = Symbol('bubblingListeners')
|
|
331
|
+
|
|
332
|
+
function getListenersForPhase(
|
|
333
|
+
eventTarget: EventTarget,
|
|
334
|
+
isCapture: boolean
|
|
335
|
+
): ListenersMap | null | undefined {
|
|
336
|
+
// @ts-expect-error index on symbol
|
|
337
|
+
return isCapture ? eventTarget[CAPTURING_LISTENERS_KEY] : eventTarget[BUBBLING_LISTENERS_KEY]
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function setListenersMap(
|
|
341
|
+
eventTarget: EventTarget,
|
|
342
|
+
isCapture: boolean,
|
|
343
|
+
listenersMap: ListenersMap
|
|
344
|
+
): void {
|
|
345
|
+
if (isCapture) {
|
|
346
|
+
;(eventTarget as any)[CAPTURING_LISTENERS_KEY] = listenersMap
|
|
347
|
+
} else {
|
|
348
|
+
;(eventTarget as any)[BUBBLING_LISTENERS_KEY] = listenersMap
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const EVENT_DISPATCH_FLAG = Symbol('Event.dispatch')
|
|
353
|
+
|
|
354
|
+
function getEventDispatchFlag(event: Event): boolean {
|
|
355
|
+
return (event as any)[EVENT_DISPATCH_FLAG]
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function setEventDispatchFlag(event: Event, value: boolean): void {
|
|
359
|
+
;(event as any)[EVENT_DISPATCH_FLAG] = value
|
|
360
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This code is taken from react-native core.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal implementation details for the `Event` module.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type Event from '../Event'
|
|
6
|
+
import type EventTarget from '../EventTarget'
|
|
7
|
+
|
|
8
|
+
export const COMPOSED_PATH_KEY: unique symbol = Symbol('composedPath')
|
|
9
|
+
export const CURRENT_TARGET_KEY: unique symbol = Symbol('currentTarget')
|
|
10
|
+
export const EVENT_PHASE_KEY: unique symbol = Symbol('eventPhase')
|
|
11
|
+
export const IN_PASSIVE_LISTENER_FLAG_KEY: unique symbol = Symbol('inPassiveListenerFlag')
|
|
12
|
+
export const IS_TRUSTED_KEY: unique symbol = Symbol('isTrusted')
|
|
13
|
+
export const STOP_IMMEDIATE_PROPAGATION_FLAG_KEY: unique symbol = Symbol('stopPropagationFlag')
|
|
14
|
+
export const STOP_PROPAGATION_FLAG_KEY: unique symbol = Symbol('stopPropagationFlag')
|
|
15
|
+
export const TARGET_KEY: unique symbol = Symbol('target')
|
|
16
|
+
|
|
17
|
+
export function getCurrentTarget(event: Event): EventTarget | null {
|
|
18
|
+
// @ts-expect-error index on symbol
|
|
19
|
+
return event[CURRENT_TARGET_KEY]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function setCurrentTarget(event: Event, currentTarget: EventTarget | null): void {
|
|
23
|
+
// @ts-expect-error index on symbol
|
|
24
|
+
event[CURRENT_TARGET_KEY] = currentTarget
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getComposedPath(event: Event): ReadonlyArray<EventTarget> {
|
|
28
|
+
// @ts-expect-error index on symbol
|
|
29
|
+
return event[COMPOSED_PATH_KEY]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function setComposedPath(event: Event, composedPath: ReadonlyArray<EventTarget>): void {
|
|
33
|
+
// @ts-expect-error index on symbol
|
|
34
|
+
event[COMPOSED_PATH_KEY] = composedPath
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function getEventPhase(event: Event): import('../Event').EventPhase {
|
|
38
|
+
// @ts-expect-error index on symbol
|
|
39
|
+
return event[EVENT_PHASE_KEY]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function setEventPhase(event: Event, eventPhase: import('../Event').EventPhase): void {
|
|
43
|
+
// @ts-expect-error index on symbol
|
|
44
|
+
event[EVENT_PHASE_KEY] = eventPhase
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function getInPassiveListenerFlag(event: Event): boolean {
|
|
48
|
+
// @ts-expect-error index on symbol
|
|
49
|
+
return event[IN_PASSIVE_LISTENER_FLAG_KEY]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function setInPassiveListenerFlag(event: Event, value: boolean): void {
|
|
53
|
+
// @ts-expect-error index on symbol
|
|
54
|
+
event[IN_PASSIVE_LISTENER_FLAG_KEY] = value
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function getIsTrusted(event: Event): boolean {
|
|
58
|
+
// @ts-expect-error index on symbol
|
|
59
|
+
return event[IS_TRUSTED_KEY]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function setIsTrusted(event: Event, isTrusted: boolean): void {
|
|
63
|
+
// @ts-expect-error index on symbol
|
|
64
|
+
event[IS_TRUSTED_KEY] = isTrusted
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function getStopImmediatePropagationFlag(event: Event): boolean {
|
|
68
|
+
// @ts-expect-error index on symbol
|
|
69
|
+
return event[STOP_IMMEDIATE_PROPAGATION_FLAG_KEY]
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function setStopImmediatePropagationFlag(event: Event, value: boolean): void {
|
|
73
|
+
// @ts-expect-error index on symbol
|
|
74
|
+
event[STOP_IMMEDIATE_PROPAGATION_FLAG_KEY] = value
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getStopPropagationFlag(event: Event): boolean {
|
|
78
|
+
// @ts-expect-error index on symbol
|
|
79
|
+
return event[STOP_PROPAGATION_FLAG_KEY]
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function setStopPropagationFlag(event: Event, value: boolean): void {
|
|
83
|
+
// @ts-expect-error index on symbol
|
|
84
|
+
event[STOP_PROPAGATION_FLAG_KEY] = value
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function getTarget(event: Event): EventTarget | null {
|
|
88
|
+
// @ts-expect-error index on symbol
|
|
89
|
+
return event[TARGET_KEY]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function setTarget(event: Event, target: EventTarget | null): void {
|
|
93
|
+
// @ts-expect-error index on symbol
|
|
94
|
+
event[TARGET_KEY] = target
|
|
95
|
+
}
|