mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Track currently replaying event (#22853)
* Track currently replaying event Co-authored-by: Dan Abramov <dan.abramov@me.com> * Add warnings Co-authored-by: Marco Salazar <salazarm@fb.com>
This commit is contained in:
42
packages/react-dom/src/events/CurrentReplayingEvent.js
vendored
Normal file
42
packages/react-dom/src/events/CurrentReplayingEvent.js
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
import type {AnyNativeEvent} from '../events/PluginModuleType';
|
||||
|
||||
// This exists to avoid circular dependency between ReactDOMEventReplaying
|
||||
// and DOMPluginEventSystem.
|
||||
|
||||
let currentReplayingEvent = null;
|
||||
|
||||
export function setReplayingEvent(event: AnyNativeEvent): void {
|
||||
if (__DEV__) {
|
||||
if (currentReplayingEvent !== null) {
|
||||
console.error(
|
||||
'Expected currently replaying event to be null. This error ' +
|
||||
'is likely caused by a bug in React. Please file an issue.',
|
||||
);
|
||||
}
|
||||
}
|
||||
currentReplayingEvent = event;
|
||||
}
|
||||
|
||||
export function resetReplayingEvent(): void {
|
||||
if (__DEV__) {
|
||||
if (currentReplayingEvent === null) {
|
||||
console.error(
|
||||
'Expected currently replaying event to not be null. This error ' +
|
||||
'is likely caused by a bug in React. Please file an issue.',
|
||||
);
|
||||
}
|
||||
}
|
||||
currentReplayingEvent = null;
|
||||
}
|
||||
|
||||
export function isReplayingEvent(event: AnyNativeEvent): boolean {
|
||||
return event === currentReplayingEvent;
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
IS_EVENT_HANDLE_NON_MANAGED_NODE,
|
||||
IS_NON_DELEGATED,
|
||||
} from './EventSystemFlags';
|
||||
import {isReplayingEvent} from './CurrentReplayingEvent';
|
||||
|
||||
import {
|
||||
HostRoot,
|
||||
@@ -557,7 +558,8 @@ export function dispatchEventForPluginEventSystem(
|
||||
// for legacy FB support, where the expected behavior was to
|
||||
// match React < 16 behavior of delegated clicks to the doc.
|
||||
domEventName === 'click' &&
|
||||
(eventSystemFlags & SHOULD_NOT_DEFER_CLICK_FOR_FB_SUPPORT_MODE) === 0
|
||||
(eventSystemFlags & SHOULD_NOT_DEFER_CLICK_FOR_FB_SUPPORT_MODE) === 0 &&
|
||||
!isReplayingEvent(nativeEvent)
|
||||
) {
|
||||
deferClickToDocumentForLegacyFBSupport(domEventName, targetContainer);
|
||||
return;
|
||||
|
||||
@@ -13,11 +13,10 @@ export const IS_EVENT_HANDLE_NON_MANAGED_NODE = 1;
|
||||
export const IS_NON_DELEGATED = 1 << 1;
|
||||
export const IS_CAPTURE_PHASE = 1 << 2;
|
||||
export const IS_PASSIVE = 1 << 3;
|
||||
export const IS_REPLAYED = 1 << 4;
|
||||
export const IS_LEGACY_FB_SUPPORT_MODE = 1 << 5;
|
||||
export const IS_LEGACY_FB_SUPPORT_MODE = 1 << 4;
|
||||
|
||||
export const SHOULD_NOT_DEFER_CLICK_FOR_FB_SUPPORT_MODE =
|
||||
IS_LEGACY_FB_SUPPORT_MODE | IS_REPLAYED | IS_CAPTURE_PHASE;
|
||||
IS_LEGACY_FB_SUPPORT_MODE | IS_CAPTURE_PHASE;
|
||||
|
||||
// We do not want to defer if the event system has already been
|
||||
// set to LEGACY_FB_SUPPORT. LEGACY_FB_SUPPORT only gets set when
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
findInstanceBlockingEvent,
|
||||
return_targetInst,
|
||||
} from './ReactDOMEventListener';
|
||||
import {setReplayingEvent, resetReplayingEvent} from './CurrentReplayingEvent';
|
||||
import {dispatchEventForPluginEventSystem} from './DOMPluginEventSystem';
|
||||
import {
|
||||
getInstanceFromNode,
|
||||
@@ -91,8 +92,6 @@ type PointerEvent = Event & {
|
||||
...
|
||||
};
|
||||
|
||||
import {IS_REPLAYED} from './EventSystemFlags';
|
||||
|
||||
type QueuedReplayableEvent = {|
|
||||
blockedOn: null | Container | SuspenseInstance,
|
||||
domEventName: DOMEventName,
|
||||
@@ -180,7 +179,7 @@ function createQueuedReplayableEvent(
|
||||
return {
|
||||
blockedOn,
|
||||
domEventName,
|
||||
eventSystemFlags: eventSystemFlags | IS_REPLAYED,
|
||||
eventSystemFlags,
|
||||
nativeEvent,
|
||||
targetContainers: [targetContainer],
|
||||
};
|
||||
@@ -473,6 +472,7 @@ function attemptReplayContinuousQueuedEvent(
|
||||
queuedEvent.nativeEvent,
|
||||
);
|
||||
if (nextBlockedOn === null) {
|
||||
setReplayingEvent(queuedEvent.nativeEvent);
|
||||
dispatchEventForPluginEventSystem(
|
||||
queuedEvent.domEventName,
|
||||
queuedEvent.eventSystemFlags,
|
||||
@@ -480,6 +480,7 @@ function attemptReplayContinuousQueuedEvent(
|
||||
return_targetInst,
|
||||
targetContainer,
|
||||
);
|
||||
resetReplayingEvent();
|
||||
} else {
|
||||
// We're still blocked. Try again later.
|
||||
const fiber = getInstanceFromNode(nextBlockedOn);
|
||||
@@ -531,6 +532,7 @@ function replayUnblockedEvents() {
|
||||
nextDiscreteEvent.nativeEvent,
|
||||
);
|
||||
if (nextBlockedOn === null) {
|
||||
setReplayingEvent(nextDiscreteEvent.nativeEvent);
|
||||
dispatchEventForPluginEventSystem(
|
||||
nextDiscreteEvent.domEventName,
|
||||
nextDiscreteEvent.eventSystemFlags,
|
||||
@@ -538,6 +540,7 @@ function replayUnblockedEvents() {
|
||||
return_targetInst,
|
||||
targetContainer,
|
||||
);
|
||||
resetReplayingEvent();
|
||||
} else {
|
||||
// We're still blocked. Try again later.
|
||||
nextDiscreteEvent.blockedOn = nextBlockedOn;
|
||||
|
||||
@@ -13,7 +13,7 @@ import type {DispatchQueue} from '../DOMPluginEventSystem';
|
||||
import type {EventSystemFlags} from '../EventSystemFlags';
|
||||
|
||||
import {registerDirectEvent} from '../EventRegistry';
|
||||
import {IS_REPLAYED} from 'react-dom/src/events/EventSystemFlags';
|
||||
import {isReplayingEvent} from '../CurrentReplayingEvent';
|
||||
import {SyntheticMouseEvent, SyntheticPointerEvent} from '../SyntheticEvent';
|
||||
import {
|
||||
getClosestInstanceFromNode,
|
||||
@@ -54,7 +54,7 @@ function extractEvents(
|
||||
const isOutEvent =
|
||||
domEventName === 'mouseout' || domEventName === 'pointerout';
|
||||
|
||||
if (isOverEvent && (eventSystemFlags & IS_REPLAYED) === 0) {
|
||||
if (isOverEvent && !isReplayingEvent(nativeEvent)) {
|
||||
// If this is an over event with a target, we might have already dispatched
|
||||
// the event in the out event of the other target. If this is replayed,
|
||||
// then it's because we couldn't dispatch against this target previously
|
||||
|
||||
Reference in New Issue
Block a user