Skip to content

Commit 353e0ee

Browse files
authored
[Flare] remove stopLocalPropagation option + modify responder ownership (#15889)
1 parent a146c1f commit 353e0ee

11 files changed

Lines changed: 46 additions & 106 deletions

File tree

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

Lines changed: 35 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,8 @@ const eventListeners:
107107
($Shape<PartialEventObject>) => void,
108108
> = new PossiblyWeakMap();
109109

110-
const responderOwners: Map<
111-
ReactEventResponder,
112-
ReactEventComponentInstance,
113-
> = new Map();
114110
let globalOwner = null;
111+
let continueLocalPropagation = false;
115112

116113
let currentTimeStamp = 0;
117114
let currentTimers = new Map();
@@ -308,31 +305,15 @@ const eventResponderContext: ReactResponderContext = {
308305
},
309306
hasOwnership(): boolean {
310307
validateResponderContext();
311-
const responder = ((currentInstance: any): ReactEventComponentInstance)
312-
.responder;
313-
return (
314-
globalOwner === currentInstance ||
315-
responderOwners.get(responder) === currentInstance
316-
);
308+
return globalOwner === currentInstance;
317309
},
318310
requestGlobalOwnership(): boolean {
319311
validateResponderContext();
320312
if (globalOwner !== null) {
321313
return false;
322314
}
323315
globalOwner = currentInstance;
324-
triggerOwnershipListeners(null);
325-
return true;
326-
},
327-
requestResponderOwnership(): boolean {
328-
validateResponderContext();
329-
const eventComponentInstance = ((currentInstance: any): ReactEventComponentInstance);
330-
const responder = eventComponentInstance.responder;
331-
if (responderOwners.has(responder)) {
332-
return false;
333-
}
334-
responderOwners.set(responder, eventComponentInstance);
335-
triggerOwnershipListeners(responder);
316+
triggerOwnershipListeners();
336317
return true;
337318
},
338319
releaseOwnership(): boolean {
@@ -433,6 +414,10 @@ const eventResponderContext: ReactResponderContext = {
433414
}
434415
return false;
435416
},
417+
continueLocalPropagation() {
418+
validateResponderContext();
419+
continueLocalPropagation = true;
420+
},
436421
};
437422

438423
function collectFocusableElements(
@@ -485,22 +470,12 @@ function getActiveDocument(): Document {
485470
function releaseOwnershipForEventComponentInstance(
486471
eventComponentInstance: ReactEventComponentInstance,
487472
): boolean {
488-
const responder = eventComponentInstance.responder;
489-
let triggerOwnershipListenersWith;
490-
if (responderOwners.get(responder) === eventComponentInstance) {
491-
responderOwners.delete(responder);
492-
triggerOwnershipListenersWith = responder;
493-
}
494473
if (globalOwner === eventComponentInstance) {
495474
globalOwner = null;
496-
triggerOwnershipListenersWith = null;
497-
}
498-
if (triggerOwnershipListenersWith !== undefined) {
499-
triggerOwnershipListeners(triggerOwnershipListenersWith);
475+
triggerOwnershipListeners();
500476
return true;
501-
} else {
502-
return false;
503477
}
478+
return false;
504479
}
505480

506481
function isFiberHostComponentFocusable(fiber: Fiber): boolean {
@@ -725,10 +700,10 @@ function getRootEventResponderInstances(
725700

726701
function shouldSkipEventComponent(
727702
eventResponderInstance: ReactEventComponentInstance,
703+
responder: ReactEventResponder,
728704
propagatedEventResponders: null | Set<ReactEventResponder>,
729705
): boolean {
730-
const responder = eventResponderInstance.responder;
731-
if (propagatedEventResponders !== null && responder.stopLocalPropagation) {
706+
if (propagatedEventResponders !== null) {
732707
if (propagatedEventResponders.has(responder)) {
733708
return true;
734709
}
@@ -737,15 +712,19 @@ function shouldSkipEventComponent(
737712
if (globalOwner && globalOwner !== eventResponderInstance) {
738713
return true;
739714
}
740-
if (
741-
responderOwners.has(responder) &&
742-
responderOwners.get(responder) !== eventResponderInstance
743-
) {
744-
return true;
745-
}
746715
return false;
747716
}
748717

718+
function checkForLocalPropagationContinuation(
719+
responder: ReactEventResponder,
720+
propagatedEventResponders: Set<ReactEventResponder>,
721+
) {
722+
if (continueLocalPropagation === true) {
723+
propagatedEventResponders.delete(responder);
724+
continueLocalPropagation = false;
725+
}
726+
}
727+
749728
function traverseAndHandleEventResponderInstances(
750729
topLevelType: DOMTopLevelEventType,
751730
targetFiber: null | Fiber,
@@ -795,13 +774,18 @@ function traverseAndHandleEventResponderInstances(
795774
if (
796775
shouldSkipEventComponent(
797776
targetEventResponderInstance,
777+
responder,
798778
propagatedEventResponders,
799779
)
800780
) {
801781
continue;
802782
}
803783
currentInstance = targetEventResponderInstance;
804784
eventListener(responderEvent, eventResponderContext, props, state);
785+
checkForLocalPropagationContinuation(
786+
responder,
787+
propagatedEventResponders,
788+
);
805789
}
806790
}
807791
// We clean propagated event responders between phases.
@@ -815,13 +799,18 @@ function traverseAndHandleEventResponderInstances(
815799
if (
816800
shouldSkipEventComponent(
817801
targetEventResponderInstance,
802+
responder,
818803
propagatedEventResponders,
819804
)
820805
) {
821806
continue;
822807
}
823808
currentInstance = targetEventResponderInstance;
824809
eventListener(responderEvent, eventResponderContext, props, state);
810+
checkForLocalPropagationContinuation(
811+
responder,
812+
propagatedEventResponders,
813+
);
825814
}
826815
}
827816
}
@@ -836,7 +825,9 @@ function traverseAndHandleEventResponderInstances(
836825
const {responder, props, state} = rootEventResponderInstance;
837826
const eventListener = responder.onRootEvent;
838827
if (eventListener !== undefined) {
839-
if (shouldSkipEventComponent(rootEventResponderInstance, null)) {
828+
if (
829+
shouldSkipEventComponent(rootEventResponderInstance, responder, null)
830+
) {
840831
continue;
841832
}
842833
currentInstance = rootEventResponderInstance;
@@ -846,18 +837,13 @@ function traverseAndHandleEventResponderInstances(
846837
}
847838
}
848839

849-
function triggerOwnershipListeners(
850-
limitByResponder: null | ReactEventResponder,
851-
): void {
840+
function triggerOwnershipListeners(): void {
852841
const listeningInstances = Array.from(ownershipChangeListeners);
853842
const previousInstance = currentInstance;
854843
try {
855844
for (let i = 0; i < listeningInstances.length; i++) {
856845
const instance = listeningInstances[i];
857846
const {props, responder, state} = instance;
858-
if (limitByResponder !== null && limitByResponder !== responder) {
859-
continue;
860-
}
861847
currentInstance = instance;
862848
const onOwnershipChange = responder.onOwnershipChange;
863849
if (onOwnershipChange !== undefined) {

packages/react-dom/src/events/__tests__/DOMEventResponderSystem-test.internal.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ function createReactEventComponent({
2727
onMount,
2828
onUnmount,
2929
onOwnershipChange,
30-
stopLocalPropagation,
3130
allowMultipleHostChildren,
3231
}) {
3332
const testEventResponder = {
@@ -40,7 +39,6 @@ function createReactEventComponent({
4039
onMount,
4140
onUnmount,
4241
onOwnershipChange,
43-
stopLocalPropagation: stopLocalPropagation || false,
4442
allowMultipleHostChildren: allowMultipleHostChildren || false,
4543
};
4644

@@ -215,6 +213,7 @@ describe('DOMEventResponderSystem', () => {
215213
const ClickEventComponent = createReactEventComponent({
216214
targetEventTypes: ['click'],
217215
onEvent: (event, context, props) => {
216+
context.continueLocalPropagation();
218217
eventResponderFiredCount++;
219218
eventLog.push({
220219
name: event.type,
@@ -224,6 +223,7 @@ describe('DOMEventResponderSystem', () => {
224223
});
225224
},
226225
onEventCapture: (event, context, props) => {
226+
context.continueLocalPropagation();
227227
eventResponderFiredCount++;
228228
eventLog.push({
229229
name: event.type,
@@ -324,19 +324,20 @@ describe('DOMEventResponderSystem', () => {
324324
]);
325325
});
326326

327-
it('nested event responders should fire in the correct order without stopLocalPropagation', () => {
327+
it('nested event responders should fire in the correct order with continueLocalPropagation', () => {
328328
let eventLog = [];
329329
const buttonRef = React.createRef();
330330

331331
const ClickEventComponent = createReactEventComponent({
332332
targetEventTypes: ['click'],
333333
onEvent: (event, context, props) => {
334+
context.continueLocalPropagation();
334335
eventLog.push(`${props.name} [bubble]`);
335336
},
336337
onEventCapture: (event, context, props) => {
338+
context.continueLocalPropagation();
337339
eventLog.push(`${props.name} [capture]`);
338340
},
339-
stopLocalPropagation: false,
340341
});
341342

342343
const Test = () => (
@@ -361,7 +362,7 @@ describe('DOMEventResponderSystem', () => {
361362
]);
362363
});
363364

364-
it('nested event responders should fire in the correct order with stopLocalPropagation', () => {
365+
it('nested event responders should fire in the correct order', () => {
365366
let eventLog = [];
366367
const buttonRef = React.createRef();
367368

@@ -373,7 +374,6 @@ describe('DOMEventResponderSystem', () => {
373374
onEventCapture: (event, context, props) => {
374375
eventLog.push(`${props.name} [capture]`);
375376
},
376-
stopLocalPropagation: true,
377377
});
378378

379379
const Test = () => (
@@ -686,6 +686,7 @@ describe('DOMEventResponderSystem', () => {
686686
const EventComponent = createReactEventComponent({
687687
targetEventTypes: ['pointerout'],
688688
onEvent: (event, context) => {
689+
context.continueLocalPropagation();
689690
const isWithin = context.isTargetWithinEventResponderScope(
690691
event.nativeEvent.relatedTarget,
691692
);

packages/react-events/README.md

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,6 @@ Called before an Event Component in unmounted.
8282

8383
Defines the DOM events to listen to on the root of the app.
8484

85-
### stopLocalPropagation: boolean
86-
87-
Defines whether or not synthetic events propagate to other Event Components *of
88-
the same type*. This has no effect on propagation of the source DOM events or
89-
the synthetic events dispatched to Event Components of different types.
90-
9185
### targetEventTypes?: Array<ResponderEventType>
9286

9387
Defines the DOM events to listen to within the Event Component subtree.
@@ -159,14 +153,6 @@ has global ownership, only that instance and its responder are active. To releas
159153
either `releaseOwnership()` must be called or the Event Component instance that had global ownership must be
160154
unmounted. Calling `requestGlobalOwnership` also returns `true`/`false` if the request was successful.
161155

162-
### requestResponderOwnership(): boolean
163-
164-
The current Event Component instance can request responder ownership within the event system. When an Event Component
165-
instance has responder ownership, all other Event Component instances that have the same responder as the Event Component
166-
instance will no longer be active. To release ownership to other event responders, either `releaseOwnership()` must be
167-
called or the Event Component instance that had global ownership must be unmounted. Calling `requestResponderOwnership`
168-
also returns `true`/`false` if the request was successful.
169-
170156
### setTimeout(func: () => void, delay: number): Symbol
171157

172158
This can be used to dispatch async events, e.g., those that fire after a delay.

packages/react-events/src/Drag.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ const DragResponder = {
9898
};
9999
},
100100
allowMultipleHostChildren: false,
101-
stopLocalPropagation: true,
102101
onEvent(
103102
event: ReactResponderEvent,
104103
context: ReactResponderContext,

packages/react-events/src/Focus.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ const FocusResponder = {
228228
};
229229
},
230230
allowMultipleHostChildren: false,
231-
stopLocalPropagation: true,
232231
onEvent(
233232
event: ReactResponderEvent,
234233
context: ReactResponderContext,

0 commit comments

Comments
 (0)