Fork dispatch function based on the flag (#22852)
* Fork function based on a flag * Prune false branches Co-authored-by: Marco Salazar <salazarm@fb.com>
Dan Abramov committed
Dec 2, 2021 at 14:02 UTC
e737ea965573930eabc97bafea673b7f29b46e79
1 file changed
+103
-6
packages/react-dom/src/events/ReactDOMEventListener.js
+103
-6
@@ -154,7 +154,29 @@ export function dispatchEvent(
154
if (!_enabled) {
155
return;
156
}
157
+ if (enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay) {
158
+ dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(
159
+ domEventName,
160
+ eventSystemFlags,
161
+ targetContainer,
162
+ nativeEvent,
163
+ );
164
+ } else {
165
+ dispatchEventOriginal(
166
+ domEventName,
167
+ eventSystemFlags,
168
+ targetContainer,
169
+ nativeEvent,
170
+ );
171
+ }
172
+}
173
174
+function dispatchEventOriginal(
175
+ domEventName: DOMEventName,
176
+ eventSystemFlags: EventSystemFlags,
177
+ targetContainer: EventTarget,
178
+ nativeEvent: AnyNativeEvent,
179
+) {
180
// TODO: replaying capture phase events is currently broken
181
// because we used to do it during top-level native bubble handlers
182
// but now we use different bubble and capture handlers.
@@ -180,7 +202,7 @@ export function dispatchEvent(
202
return;
203
}
204
183
- let blockedOn = findInstanceBlockingEvent(
205
+ const blockedOn = findInstanceBlockingEvent(
206
domEventName,
207
eventSystemFlags,
208
targetContainer,
@@ -201,10 +223,7 @@ export function dispatchEvent(
223
}
224
225
if (allowReplay) {
204
- if (
205
- !enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay &&
206
- isDiscreteEventThatRequiresHydration(domEventName)
207
- ) {
226
+ if (isDiscreteEventThatRequiresHydration(domEventName)) {
227
// This this to be replayed later once the target is available.
228
queueDiscreteEvent(
229
blockedOn,
@@ -231,8 +250,86 @@ export function dispatchEvent(
250
clearIfContinuousEvent(domEventName, nativeEvent);
251
}
252
253
+ // This is not replayable so we'll invoke it but without a target,
254
+ // in case the event system needs to trace it.
255
+ dispatchEventForPluginEventSystem(
256
+ domEventName,
257
+ eventSystemFlags,
258
+ nativeEvent,
259
+ null,
260
+ targetContainer,
261
+ );
262
+}
263
+
264
+function dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(
265
+ domEventName: DOMEventName,
266
+ eventSystemFlags: EventSystemFlags,
267
+ targetContainer: EventTarget,
268
+ nativeEvent: AnyNativeEvent,
269
+) {
270
+ // TODO: replaying capture phase events is currently broken
271
+ // because we used to do it during top-level native bubble handlers
272
+ // but now we use different bubble and capture handlers.
273
+ // In eager mode, we attach capture listeners early, so we need
274
+ // to filter them out until we fix the logic to handle them correctly.
275
+ const allowReplay = (eventSystemFlags & IS_CAPTURE_PHASE) === 0;
276
+
277
+ if (
278
+ allowReplay &&
279
+ hasQueuedDiscreteEvents() &&
280
+ isDiscreteEventThatRequiresHydration(domEventName)
281
+ ) {
282
+ // If we already have a queue of discrete events, and this is another discrete
283
+ // event, then we can't dispatch it regardless of its target, since they
284
+ // need to dispatch in order.
285
+ queueDiscreteEvent(
286
+ null, // Flags that we're not actually blocked on anything as far as we know.
287
+ domEventName,
288
+ eventSystemFlags,
289
+ targetContainer,
290
+ nativeEvent,
291
+ );
292
+ return;
293
+ }
294
+
295
+ let blockedOn = findInstanceBlockingEvent(
296
+ domEventName,
297
+ eventSystemFlags,
298
+ targetContainer,
299
+ nativeEvent,
300
+ );
301
+ if (blockedOn === null) {
302
+ dispatchEventForPluginEventSystem(
303
+ domEventName,
304
+ eventSystemFlags,
305
+ nativeEvent,
306
+ return_targetInst,
307
+ targetContainer,
308
+ );
309
+ if (allowReplay) {
310
+ clearIfContinuousEvent(domEventName, nativeEvent);
311
+ }
312
+ return;
313
+ }
314
+
315
+ if (allowReplay) {
316
+ if (
317
+ queueIfContinuousEvent(
318
+ blockedOn,
319
+ domEventName,
320
+ eventSystemFlags,
321
+ targetContainer,
322
+ nativeEvent,
323
+ )
324
+ ) {
325
+ return;
326
+ }
327
+ // We need to clear only if we didn't queue because
328
+ // queueing is accumulative.
329
+ clearIfContinuousEvent(domEventName, nativeEvent);
330
+ }
331
+
332
if (
235
- enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay &&
333
eventSystemFlags & IS_CAPTURE_PHASE &&
334
isDiscreteEventThatRequiresHydration(domEventName)
335
) {