diff --git a/packages/legacy-events/ReactGenericBatching.js b/packages/legacy-events/ReactGenericBatching.js
index e5f536ee15c8f..f3c8d4d768fbf 100644
--- a/packages/legacy-events/ReactGenericBatching.js
+++ b/packages/legacy-events/ReactGenericBatching.js
@@ -23,8 +23,8 @@ import {invokeGuardedCallbackAndCatchFirstError} from 'shared/ReactErrorUtils';
let batchedUpdatesImpl = function(fn, bookkeeping) {
return fn(bookkeeping);
};
-let discreteUpdatesImpl = function(fn, a, b, c) {
- return fn(a, b, c);
+let discreteUpdatesImpl = function(fn, a, b, c, d) {
+ return fn(a, b, c, d);
};
let flushDiscreteUpdatesImpl = function() {};
let batchedEventUpdatesImpl = batchedUpdatesImpl;
@@ -89,11 +89,11 @@ export function executeUserEventHandler(fn: any => void, value: any): void {
}
}
-export function discreteUpdates(fn, a, b, c) {
+export function discreteUpdates(fn, a, b, c, d) {
const prevIsInsideEventHandler = isInsideEventHandler;
isInsideEventHandler = true;
try {
- return discreteUpdatesImpl(fn, a, b, c);
+ return discreteUpdatesImpl(fn, a, b, c, d);
} finally {
isInsideEventHandler = prevIsInsideEventHandler;
if (!isInsideEventHandler) {
diff --git a/packages/react-dom/src/events/ReactDOMEventListener.js b/packages/react-dom/src/events/ReactDOMEventListener.js
index e119fafa48eec..d3b5a88f8f347 100644
--- a/packages/react-dom/src/events/ReactDOMEventListener.js
+++ b/packages/react-dom/src/events/ReactDOMEventListener.js
@@ -119,6 +119,7 @@ export function addResponderEventSystemEvent(
null,
((topLevelType: any): DOMTopLevelEventType),
eventFlags,
+ document,
);
if (passiveBrowserEventsSupported) {
addEventCaptureListenerWithPassiveFlag(
@@ -149,7 +150,7 @@ export function removeActiveResponderEventSystemEvent(
}
function trapEventForPluginEventSystem(
- element: Document | Element | Node,
+ container: Document | Element | Node,
topLevelType: DOMTopLevelEventType,
capture: boolean,
): void {
@@ -160,6 +161,7 @@ function trapEventForPluginEventSystem(
null,
topLevelType,
PLUGIN_EVENT_SYSTEM,
+ container,
);
break;
case UserBlockingEvent:
@@ -167,41 +169,66 @@ function trapEventForPluginEventSystem(
null,
topLevelType,
PLUGIN_EVENT_SYSTEM,
+ container,
);
break;
case ContinuousEvent:
default:
- listener = dispatchEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM);
+ listener = dispatchEvent.bind(
+ null,
+ topLevelType,
+ PLUGIN_EVENT_SYSTEM,
+ container,
+ );
break;
}
const rawEventName = getRawEventName(topLevelType);
if (capture) {
- addEventCaptureListener(element, rawEventName, listener);
+ addEventCaptureListener(container, rawEventName, listener);
} else {
- addEventBubbleListener(element, rawEventName, listener);
+ addEventBubbleListener(container, rawEventName, listener);
}
}
-function dispatchDiscreteEvent(topLevelType, eventSystemFlags, nativeEvent) {
+function dispatchDiscreteEvent(
+ topLevelType,
+ eventSystemFlags,
+ container,
+ nativeEvent,
+) {
flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
- discreteUpdates(dispatchEvent, topLevelType, eventSystemFlags, nativeEvent);
+ discreteUpdates(
+ dispatchEvent,
+ topLevelType,
+ eventSystemFlags,
+ container,
+ nativeEvent,
+ );
}
function dispatchUserBlockingUpdate(
topLevelType,
eventSystemFlags,
+ container,
nativeEvent,
) {
runWithPriority(
UserBlockingPriority,
- dispatchEvent.bind(null, topLevelType, eventSystemFlags, nativeEvent),
+ dispatchEvent.bind(
+ null,
+ topLevelType,
+ eventSystemFlags,
+ container,
+ nativeEvent,
+ ),
);
}
export function dispatchEvent(
topLevelType: DOMTopLevelEventType,
eventSystemFlags: EventSystemFlags,
+ container: Document | Element | Node,
nativeEvent: AnyNativeEvent,
): void {
if (!_enabled) {
@@ -216,6 +243,7 @@ export function dispatchEvent(
topLevelType,
eventSystemFlags,
nativeEvent,
+ container,
);
return;
}
@@ -224,6 +252,7 @@ export function dispatchEvent(
topLevelType,
eventSystemFlags,
nativeEvent,
+ container,
);
if (blockedOn === null) {
@@ -234,7 +263,13 @@ export function dispatchEvent(
if (isReplayableDiscreteEvent(topLevelType)) {
// This this to be replayed later once the target is available.
- queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, nativeEvent);
+ queueDiscreteEvent(
+ blockedOn,
+ topLevelType,
+ eventSystemFlags,
+ nativeEvent,
+ container,
+ );
return;
}
@@ -244,6 +279,7 @@ export function dispatchEvent(
topLevelType,
eventSystemFlags,
nativeEvent,
+ container,
)
) {
return;
@@ -289,6 +325,7 @@ export function attemptToDispatchEvent(
topLevelType: DOMTopLevelEventType,
eventSystemFlags: EventSystemFlags,
nativeEvent: AnyNativeEvent,
+ container: Document | Element | Node,
): null | Container | SuspenseInstance {
// TODO: Warn if _enabled is false.
diff --git a/packages/react-dom/src/events/ReactDOMEventReplaying.js b/packages/react-dom/src/events/ReactDOMEventReplaying.js
index 36a78b5d0fcf7..d46bbdf817158 100644
--- a/packages/react-dom/src/events/ReactDOMEventReplaying.js
+++ b/packages/react-dom/src/events/ReactDOMEventReplaying.js
@@ -124,6 +124,7 @@ type QueuedReplayableEvent = {|
topLevelType: DOMTopLevelEventType,
eventSystemFlags: EventSystemFlags,
nativeEvent: AnyNativeEvent,
+ container: Document | Element | Node,
|};
let hasScheduledReplayAttempt = false;
@@ -252,12 +253,14 @@ function createQueuedReplayableEvent(
topLevelType: DOMTopLevelEventType,
eventSystemFlags: EventSystemFlags,
nativeEvent: AnyNativeEvent,
+ container: Document | Element | Node,
): QueuedReplayableEvent {
return {
blockedOn,
topLevelType,
eventSystemFlags: eventSystemFlags | IS_REPLAYED,
nativeEvent,
+ container,
};
}
@@ -266,12 +269,14 @@ export function queueDiscreteEvent(
topLevelType: DOMTopLevelEventType,
eventSystemFlags: EventSystemFlags,
nativeEvent: AnyNativeEvent,
+ container: Document | Element | Node,
): void {
const queuedEvent = createQueuedReplayableEvent(
blockedOn,
topLevelType,
eventSystemFlags,
nativeEvent,
+ container,
);
queuedDiscreteEvents.push(queuedEvent);
if (enableSelectiveHydration) {
@@ -339,6 +344,7 @@ function accumulateOrCreateContinuousQueuedReplayableEvent(
topLevelType: DOMTopLevelEventType,
eventSystemFlags: EventSystemFlags,
nativeEvent: AnyNativeEvent,
+ container: Document | Element | Node,
): QueuedReplayableEvent {
if (
existingQueuedEvent === null ||
@@ -349,6 +355,7 @@ function accumulateOrCreateContinuousQueuedReplayableEvent(
topLevelType,
eventSystemFlags,
nativeEvent,
+ container,
);
if (blockedOn !== null) {
let fiber = getInstanceFromNode(blockedOn);
@@ -372,6 +379,7 @@ export function queueIfContinuousEvent(
topLevelType: DOMTopLevelEventType,
eventSystemFlags: EventSystemFlags,
nativeEvent: AnyNativeEvent,
+ container: Document | Element | Node,
): boolean {
// These set relatedTarget to null because the replayed event will be treated as if we
// moved from outside the window (no target) onto the target once it hydrates.
@@ -385,6 +393,7 @@ export function queueIfContinuousEvent(
topLevelType,
eventSystemFlags,
focusEvent,
+ container,
);
return true;
}
@@ -396,6 +405,7 @@ export function queueIfContinuousEvent(
topLevelType,
eventSystemFlags,
dragEvent,
+ container,
);
return true;
}
@@ -407,6 +417,7 @@ export function queueIfContinuousEvent(
topLevelType,
eventSystemFlags,
mouseEvent,
+ container,
);
return true;
}
@@ -421,6 +432,7 @@ export function queueIfContinuousEvent(
topLevelType,
eventSystemFlags,
pointerEvent,
+ container,
),
);
return true;
@@ -436,6 +448,7 @@ export function queueIfContinuousEvent(
topLevelType,
eventSystemFlags,
pointerEvent,
+ container,
),
);
return true;
@@ -512,6 +525,7 @@ function attemptReplayContinuousQueuedEvent(
queuedEvent.topLevelType,
queuedEvent.eventSystemFlags,
queuedEvent.nativeEvent,
+ queuedEvent.container,
);
if (nextBlockedOn !== null) {
// We're still blocked. Try again later.
@@ -554,6 +568,7 @@ function replayUnblockedEvents() {
nextDiscreteEvent.topLevelType,
nextDiscreteEvent.eventSystemFlags,
nextDiscreteEvent.nativeEvent,
+ nextDiscreteEvent.container,
);
if (nextBlockedOn !== null) {
// We're still blocked. Try again later.
diff --git a/packages/react-dom/src/test-utils/ReactTestUtils.js b/packages/react-dom/src/test-utils/ReactTestUtils.js
index 23e99cd15ae47..18e4c50ee2ebb 100644
--- a/packages/react-dom/src/test-utils/ReactTestUtils.js
+++ b/packages/react-dom/src/test-utils/ReactTestUtils.js
@@ -62,7 +62,7 @@ let hasWarnedAboutDeprecatedMockComponent = false;
*/
function simulateNativeEventOnNode(topLevelType, node, fakeNativeEvent) {
fakeNativeEvent.target = node;
- dispatchEvent(topLevelType, PLUGIN_EVENT_SYSTEM, fakeNativeEvent);
+ dispatchEvent(topLevelType, PLUGIN_EVENT_SYSTEM, document, fakeNativeEvent);
}
/**
diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.js b/packages/react-reconciler/src/ReactFiberWorkLoop.js
index f647ccb88b2ce..d4ebabfc783f6 100644
--- a/packages/react-reconciler/src/ReactFiberWorkLoop.js
+++ b/packages/react-reconciler/src/ReactFiberWorkLoop.js
@@ -1160,17 +1160,18 @@ export function batchedEventUpdates(fn: A => R, a: A): R {
}
}
-export function discreteUpdates(
+export function discreteUpdates(
fn: (A, B, C) => R,
a: A,
b: B,
c: C,
+ d: D,
): R {
const prevExecutionContext = executionContext;
executionContext |= DiscreteEventContext;
try {
// Should this
- return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c));
+ return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c, d));
} finally {
executionContext = prevExecutionContext;
if (executionContext === NoContext) {