Skip to content

Commit 67e3f3f

Browse files
authored
[Flare] Revise responder event types (#16081)
1 parent 2a0f639 commit 67e3f3f

25 files changed

+141
-279
lines changed

packages/react-art/src/ReactARTHostConfig.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -428,19 +428,19 @@ export function unhideTextInstance(textInstance, text): void {
428428
}
429429

430430
export function mountEventComponent(
431-
eventComponentInstance: ReactEventComponentInstance<any, any, any>,
431+
eventComponentInstance: ReactEventComponentInstance<any, any>,
432432
) {
433433
throw new Error('Not yet implemented.');
434434
}
435435

436436
export function updateEventComponent(
437-
eventComponentInstance: ReactEventComponentInstance<any, any, any>,
437+
eventComponentInstance: ReactEventComponentInstance<any, any>,
438438
) {
439439
throw new Error('Not yet implemented.');
440440
}
441441

442442
export function unmountEventComponent(
443-
eventComponentInstance: ReactEventComponentInstance<any, any, any>,
443+
eventComponentInstance: ReactEventComponentInstance<any, any>,
444444
): void {
445445
throw new Error('Not yet implemented.');
446446
}

packages/react-dom/src/client/ReactDOMComponent.js

+13-37
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,9 @@ import {registrationNameModules} from 'events/EventPluginRegistry';
1313
import warning from 'shared/warning';
1414
import {canUseDOM} from 'shared/ExecutionEnvironment';
1515
import warningWithoutStack from 'shared/warningWithoutStack';
16-
import type {ReactDOMEventResponderEventType} from 'shared/ReactDOMTypes';
16+
import endsWith from 'shared/endsWith';
1717
import type {DOMTopLevelEventType} from 'events/TopLevelEventTypes';
18-
import {
19-
setListenToResponderEventTypes,
20-
generateListeningKey,
21-
} from '../events/DOMEventResponderSystem';
18+
import {setListenToResponderEventTypes} from '../events/DOMEventResponderSystem';
2219

2320
import {
2421
getValueForAttribute,
@@ -1284,7 +1281,7 @@ export function restoreControlledState(
12841281
}
12851282

12861283
export function listenToEventResponderEventTypes(
1287-
eventTypes: Array<ReactDOMEventResponderEventType>,
1284+
eventTypes: Array<string>,
12881285
element: Element | Document,
12891286
): void {
12901287
if (enableFlareAPI) {
@@ -1294,40 +1291,19 @@ export function listenToEventResponderEventTypes(
12941291

12951292
// Go through each target event type of the event responder
12961293
for (let i = 0, length = eventTypes.length; i < length; ++i) {
1297-
const targetEventType = eventTypes[i];
1298-
let topLevelType;
1299-
let passive = true;
1300-
1301-
// If no event config object is provided (i.e. - only a string),
1302-
// we default to enabling passive and not capture.
1303-
if (typeof targetEventType === 'string') {
1304-
topLevelType = targetEventType;
1305-
} else {
1306-
if (__DEV__) {
1307-
warning(
1308-
typeof targetEventType === 'object' && targetEventType !== null,
1309-
'Event Responder: invalid entry in event types array. ' +
1310-
'Entry must be string or an object. Instead, got %s.',
1311-
targetEventType,
1312-
);
1313-
}
1314-
const targetEventConfigObject = ((targetEventType: any): {
1315-
name: string,
1316-
passive?: boolean,
1317-
});
1318-
topLevelType = targetEventConfigObject.name;
1319-
if (targetEventConfigObject.passive !== undefined) {
1320-
passive = targetEventConfigObject.passive;
1321-
}
1322-
}
1323-
const listeningName = generateListeningKey(topLevelType, passive);
1324-
if (!listeningSet.has(listeningName)) {
1294+
const eventType = eventTypes[i];
1295+
const isPassive = !endsWith(eventType, '_active');
1296+
const eventKey = isPassive ? eventType + '_passive' : eventType;
1297+
const targetEventType = isPassive
1298+
? eventType
1299+
: eventType.substring(0, eventType.length - 7);
1300+
if (!listeningSet.has(eventKey)) {
13251301
trapEventForResponderEventSystem(
13261302
element,
1327-
((topLevelType: any): DOMTopLevelEventType),
1328-
passive,
1303+
((targetEventType: any): DOMTopLevelEventType),
1304+
isPassive,
13291305
);
1330-
listeningSet.add(listeningName);
1306+
listeningSet.add(eventKey);
13311307
}
13321308
}
13331309
}

packages/react-dom/src/events/DOMEventResponderSystem.js

+29-106
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import type {EventPriority} from 'shared/ReactTypes';
2121
import type {
2222
ReactDOMEventResponder,
2323
ReactDOMEventComponentInstance,
24-
ReactDOMEventResponderEventType,
2524
ReactDOMResponderContext,
2625
ReactDOMResponderEvent,
2726
} from 'shared/ReactDOMTypes';
@@ -95,10 +94,6 @@ const rootEventTypesToEventComponentInstances: Map<
9594
DOMTopLevelEventType | string,
9695
Set<ReactDOMEventComponentInstance>,
9796
> = new Map();
98-
const targetEventTypeCached: Map<
99-
Array<ReactDOMEventResponderEventType>,
100-
Set<string>,
101-
> = new Map();
10297
const ownershipChangeListeners: Set<ReactDOMEventComponentInstance> = new Set();
10398
const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
10499
const eventListeners:
@@ -248,9 +243,7 @@ const eventResponderContext: ReactDOMResponderContext = {
248243
}
249244
return false;
250245
},
251-
addRootEventTypes(
252-
rootEventTypes: Array<ReactDOMEventResponderEventType>,
253-
): void {
246+
addRootEventTypes(rootEventTypes: Array<string>): void {
254247
validateResponderContext();
255248
const activeDocument = getActiveDocument();
256249
listenToResponderEventTypesImpl(rootEventTypes, activeDocument);
@@ -260,37 +253,17 @@ const eventResponderContext: ReactDOMResponderContext = {
260253
registerRootEventType(rootEventType, eventComponentInstance);
261254
}
262255
},
263-
removeRootEventTypes(
264-
rootEventTypes: Array<ReactDOMEventResponderEventType>,
265-
): void {
256+
removeRootEventTypes(rootEventTypes: Array<string>): void {
266257
validateResponderContext();
267258
for (let i = 0; i < rootEventTypes.length; i++) {
268259
const rootEventType = rootEventTypes[i];
269-
let name = rootEventType;
270-
let passive = true;
271-
272-
if (typeof rootEventType !== 'string') {
273-
const targetEventConfigObject = ((rootEventType: any): {
274-
name: string,
275-
passive?: boolean,
276-
});
277-
name = targetEventConfigObject.name;
278-
if (targetEventConfigObject.passive !== undefined) {
279-
passive = targetEventConfigObject.passive;
280-
}
281-
}
282-
283-
const listeningName = generateListeningKey(
284-
((name: any): string),
285-
passive,
286-
);
287260
let rootEventComponents = rootEventTypesToEventComponentInstances.get(
288-
listeningName,
261+
rootEventType,
289262
);
290263
let rootEventTypesSet = ((currentInstance: any): ReactDOMEventComponentInstance)
291264
.rootEventTypes;
292265
if (rootEventTypesSet !== null) {
293-
rootEventTypesSet.delete(listeningName);
266+
rootEventTypesSet.delete(rootEventType);
294267
}
295268
if (rootEventComponents !== undefined) {
296269
rootEventComponents.delete(
@@ -595,41 +568,20 @@ function processEventQueue(): void {
595568
}
596569
}
597570

598-
function getDOMTargetEventTypesSet(
599-
eventTypes: Array<ReactDOMEventResponderEventType>,
600-
): Set<string> {
601-
let cachedSet = targetEventTypeCached.get(eventTypes);
602-
603-
if (cachedSet === undefined) {
604-
cachedSet = new Set();
605-
for (let i = 0; i < eventTypes.length; i++) {
606-
const eventType = eventTypes[i];
607-
let name = eventType;
608-
let passive = true;
609-
610-
if (typeof eventType !== 'string') {
611-
const targetEventConfigObject = ((eventType: any): {
612-
name: string,
613-
passive?: boolean,
614-
});
615-
name = targetEventConfigObject.name;
616-
if (targetEventConfigObject.passive !== undefined) {
617-
passive = targetEventConfigObject.passive;
618-
}
619-
}
620-
const listeningName = generateListeningKey(
621-
((name: any): string),
622-
passive,
623-
);
624-
cachedSet.add(listeningName);
571+
function responderEventTypesContainType(
572+
eventTypes: Array<string>,
573+
type: string,
574+
): boolean {
575+
for (let i = 0, len = eventTypes.length; i < len; i++) {
576+
if (eventTypes[i] === type) {
577+
return true;
625578
}
626-
targetEventTypeCached.set(eventTypes, cachedSet);
627579
}
628-
return cachedSet;
580+
return false;
629581
}
630582

631583
function handleTargetEventResponderInstance(
632-
listeningName: string,
584+
eventType: string,
633585
responderEvent: ReactDOMResponderEvent,
634586
eventComponentInstance: ReactDOMEventComponentInstance,
635587
hookComponentResponderValidation: null | Set<ReactDOMEventResponder>,
@@ -639,8 +591,7 @@ function handleTargetEventResponderInstance(
639591
const targetEventTypes = responder.targetEventTypes;
640592
// Validate the target event type exists on the responder
641593
if (targetEventTypes !== undefined) {
642-
const targetEventTypesSet = getDOMTargetEventTypesSet(targetEventTypes);
643-
if (targetEventTypesSet.has(listeningName)) {
594+
if (responderEventTypesContainType(targetEventTypes, eventType)) {
644595
if (hookComponentResponderValidation !== null) {
645596
hookComponentResponderValidation.add(responder);
646597
}
@@ -700,25 +651,23 @@ function checkForLocalPropagationContinuation(
700651
}
701652

702653
function traverseAndHandleEventResponderInstances(
703-
topLevelType: DOMTopLevelEventType,
654+
topLevelType: string,
704655
targetFiber: null | Fiber,
705656
nativeEvent: AnyNativeEvent,
706657
nativeEventTarget: EventTarget,
707658
eventSystemFlags: EventSystemFlags,
708659
): void {
709660
const isPassiveEvent = (eventSystemFlags & IS_PASSIVE) !== 0;
710661
const isPassiveSupported = (eventSystemFlags & PASSIVE_NOT_SUPPORTED) === 0;
711-
const listeningName = generateListeningKey(
712-
((topLevelType: any): string),
713-
isPassiveEvent || !isPassiveSupported,
714-
);
662+
const isPassive = isPassiveEvent || !isPassiveSupported;
663+
const eventType = isPassive ? topLevelType : topLevelType + '_active';
715664

716665
// Trigger event responders in this order:
717666
// - Bubble target phase
718667
// - Root phase
719668

720669
const responderEvent = createDOMResponderEvent(
721-
((topLevelType: any): string),
670+
topLevelType,
722671
nativeEvent,
723672
((nativeEventTarget: any): Element | Document),
724673
isPassiveEvent,
@@ -743,7 +692,7 @@ function traverseAndHandleEventResponderInstances(
743692
// Switch to the current fiber tree
744693
node = eventComponentInstance.currentFiber;
745694
handleTargetEventResponderInstance(
746-
listeningName,
695+
eventType,
747696
responderEvent,
748697
eventComponentInstance,
749698
hookComponentResponderValidation,
@@ -760,7 +709,7 @@ function traverseAndHandleEventResponderInstances(
760709
)
761710
) {
762711
handleTargetEventResponderInstance(
763-
listeningName,
712+
eventType,
764713
responderEvent,
765714
eventComponentInstance,
766715
null,
@@ -776,7 +725,7 @@ function traverseAndHandleEventResponderInstances(
776725
responderEvent.currentTarget = null;
777726
// Root phase
778727
const rootEventInstances = rootEventTypesToEventComponentInstances.get(
779-
listeningName,
728+
eventType,
780729
);
781730
if (rootEventInstances !== undefined) {
782731
const rootEventComponentInstances = Array.from(rootEventInstances);
@@ -906,7 +855,7 @@ function validateResponderContext(): void {
906855
}
907856

908857
export function dispatchEventForResponderEventSystem(
909-
topLevelType: DOMTopLevelEventType,
858+
topLevelType: string,
910859
targetFiber: null | Fiber,
911860
nativeEvent: AnyNativeEvent,
912861
nativeEventTarget: EventTarget,
@@ -950,7 +899,7 @@ export function dispatchEventForResponderEventSystem(
950899

951900
export function addRootEventTypesForComponentInstance(
952901
eventComponentInstance: ReactDOMEventComponentInstance,
953-
rootEventTypes: Array<ReactDOMEventResponderEventType>,
902+
rootEventTypes: Array<string>,
954903
): void {
955904
for (let i = 0; i < rootEventTypes.length; i++) {
956905
const rootEventType = rootEventTypes[i];
@@ -959,31 +908,16 @@ export function addRootEventTypesForComponentInstance(
959908
}
960909

961910
function registerRootEventType(
962-
rootEventType: ReactDOMEventResponderEventType,
911+
rootEventType: string,
963912
eventComponentInstance: ReactDOMEventComponentInstance,
964913
): void {
965-
let name = rootEventType;
966-
let passive = true;
967-
968-
if (typeof rootEventType !== 'string') {
969-
const targetEventConfigObject = ((rootEventType: any): {
970-
name: string,
971-
passive?: boolean,
972-
});
973-
name = targetEventConfigObject.name;
974-
if (targetEventConfigObject.passive !== undefined) {
975-
passive = targetEventConfigObject.passive;
976-
}
977-
}
978-
979-
const listeningName = generateListeningKey(((name: any): string), passive);
980914
let rootEventComponentInstances = rootEventTypesToEventComponentInstances.get(
981-
listeningName,
915+
rootEventType,
982916
);
983917
if (rootEventComponentInstances === undefined) {
984918
rootEventComponentInstances = new Set();
985919
rootEventTypesToEventComponentInstances.set(
986-
listeningName,
920+
rootEventType,
987921
rootEventComponentInstances,
988922
);
989923
}
@@ -992,23 +926,12 @@ function registerRootEventType(
992926
rootEventTypesSet = eventComponentInstance.rootEventTypes = new Set();
993927
}
994928
invariant(
995-
!rootEventTypesSet.has(listeningName),
929+
!rootEventTypesSet.has(rootEventType),
996930
'addRootEventTypes() found a duplicate root event ' +
997931
'type of "%s". This might be because the event type exists in the event responder "rootEventTypes" ' +
998932
'array or because of a previous addRootEventTypes() using this root event type.',
999-
name,
933+
rootEventType,
1000934
);
1001-
rootEventTypesSet.add(listeningName);
935+
rootEventTypesSet.add(rootEventType);
1002936
rootEventComponentInstances.add(eventComponentInstance);
1003937
}
1004-
1005-
export function generateListeningKey(
1006-
topLevelType: string,
1007-
passive: boolean,
1008-
): string {
1009-
// Create a unique name for this event, plus its properties. We'll
1010-
// use this to ensure we don't listen to the same event with the same
1011-
// properties again.
1012-
const passiveKey = passive ? '_passive' : '_active';
1013-
return `${topLevelType}${passiveKey}`;
1014-
}

packages/react-dom/src/events/ReactDOMEventListener.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ export function dispatchEvent(
334334
} else {
335335
// React Flare event system
336336
dispatchEventForResponderEventSystem(
337-
topLevelType,
337+
(topLevelType: any),
338338
targetInst,
339339
nativeEvent,
340340
nativeEventTarget,

0 commit comments

Comments
 (0)