From 3f85d53ca6f2af8a711daae6322e6bdda862f660 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Thu, 20 Feb 2020 00:46:03 +0000 Subject: [PATCH] Further pre-requisite changes to plugin event system (#18083) --- packages/legacy-events/PluginModuleType.js | 2 +- .../legacy-events/ReactSyntheticEventType.js | 2 +- packages/react-dom/src/client/ReactDOMRoot.js | 2 +- .../src/events/DOMLegacyEventPluginSystem.js | 8 ++-- .../src/events/ReactDOMEventListener.js | 20 ++++----- .../src/events/ReactDOMEventReplaying.js | 44 ++++++++++--------- .../react-dom/src/events/SelectEventPlugin.js | 9 +++- 7 files changed, 48 insertions(+), 39 deletions(-) diff --git a/packages/legacy-events/PluginModuleType.js b/packages/legacy-events/PluginModuleType.js index 04ec9e67357e5..df353f2f3cc6b 100644 --- a/packages/legacy-events/PluginModuleType.js +++ b/packages/legacy-events/PluginModuleType.js @@ -29,7 +29,7 @@ export type PluginModule = { nativeTarget: NativeEvent, nativeEventTarget: null | EventTarget, eventSystemFlags: EventSystemFlags, + container?: Document | Element | Node, ) => ?ReactSyntheticEvent, tapMoveThreshold?: number, - ... }; diff --git a/packages/legacy-events/ReactSyntheticEventType.js b/packages/legacy-events/ReactSyntheticEventType.js index 922d49d5c30f8..51929b8da2b6c 100644 --- a/packages/legacy-events/ReactSyntheticEventType.js +++ b/packages/legacy-events/ReactSyntheticEventType.js @@ -31,4 +31,4 @@ export type ReactSyntheticEvent = {| nativeEventTarget: EventTarget, ) => ReactSyntheticEvent, isPersistent: () => boolean, -|} & SyntheticEvent<>; +|}; diff --git a/packages/react-dom/src/client/ReactDOMRoot.js b/packages/react-dom/src/client/ReactDOMRoot.js index f9282e919c0dd..da256457e0fb7 100644 --- a/packages/react-dom/src/client/ReactDOMRoot.js +++ b/packages/react-dom/src/client/ReactDOMRoot.js @@ -123,7 +123,7 @@ function createRootImpl( container.nodeType === DOCUMENT_NODE ? container : container.ownerDocument; - eagerlyTrapReplayableEvents(doc); + eagerlyTrapReplayableEvents(container, doc); } return root; } diff --git a/packages/react-dom/src/events/DOMLegacyEventPluginSystem.js b/packages/react-dom/src/events/DOMLegacyEventPluginSystem.js index 064dd2ee1f532..2897d3b42fef6 100644 --- a/packages/react-dom/src/events/DOMLegacyEventPluginSystem.js +++ b/packages/react-dom/src/events/DOMLegacyEventPluginSystem.js @@ -264,7 +264,7 @@ function handleTopLevel(bookKeeping: BookKeepingInstance) { } } -export function dispatchEventForPluginEventSystem( +export function dispatchEventForLegacyPluginEventSystem( topLevelType: DOMTopLevelEventType, eventSystemFlags: EventSystemFlags, nativeEvent: AnyNativeEvent, @@ -311,16 +311,16 @@ export function legacyListenToEvent( registrationName: string, mountAt: Document | Element | Node, ): void { - const listeningSet = getListenerMapForElement(mountAt); + const listenerMap = getListenerMapForElement(mountAt); const dependencies = registrationNameDependencies[registrationName]; for (let i = 0; i < dependencies.length; i++) { const dependency = dependencies[i]; - listenToTopLevelEvent(dependency, mountAt, listeningSet); + legacyListenToTopLevelEvent(dependency, mountAt, listenerMap); } } -export function listenToTopLevelEvent( +export function legacyListenToTopLevelEvent( topLevelType: DOMTopLevelEventType, mountAt: Document | Element | Node, listenerMap: Map void)>, diff --git a/packages/react-dom/src/events/ReactDOMEventListener.js b/packages/react-dom/src/events/ReactDOMEventListener.js index ac01507da4845..c63dc0ee648dd 100644 --- a/packages/react-dom/src/events/ReactDOMEventListener.js +++ b/packages/react-dom/src/events/ReactDOMEventListener.js @@ -60,7 +60,7 @@ import { DiscreteEvent, } from 'shared/ReactTypes'; import {getEventPriorityForPluginSystem} from './DOMEventProperties'; -import {dispatchEventForPluginEventSystem} from './DOMLegacyEventPluginSystem'; +import {dispatchEventForLegacyPluginEventSystem} from './DOMLegacyEventPluginSystem'; const { unstable_UserBlockingPriority: UserBlockingPriority, @@ -242,8 +242,8 @@ export function dispatchEvent( null, // Flags that we're not actually blocked on anything as far as we know. topLevelType, eventSystemFlags, - nativeEvent, container, + nativeEvent, ); return; } @@ -251,8 +251,8 @@ export function dispatchEvent( const blockedOn = attemptToDispatchEvent( topLevelType, eventSystemFlags, - nativeEvent, container, + nativeEvent, ); if (blockedOn === null) { @@ -267,8 +267,8 @@ export function dispatchEvent( blockedOn, topLevelType, eventSystemFlags, - nativeEvent, container, + nativeEvent, ); return; } @@ -278,8 +278,8 @@ export function dispatchEvent( blockedOn, topLevelType, eventSystemFlags, - nativeEvent, container, + nativeEvent, ) ) { return; @@ -293,7 +293,7 @@ export function dispatchEvent( // in case the event system needs to trace it. if (enableDeprecatedFlareAPI) { if (eventSystemFlags & PLUGIN_EVENT_SYSTEM) { - dispatchEventForPluginEventSystem( + dispatchEventForLegacyPluginEventSystem( topLevelType, eventSystemFlags, nativeEvent, @@ -311,7 +311,7 @@ export function dispatchEvent( ); } } else { - dispatchEventForPluginEventSystem( + dispatchEventForLegacyPluginEventSystem( topLevelType, eventSystemFlags, nativeEvent, @@ -324,8 +324,8 @@ export function dispatchEvent( export function attemptToDispatchEvent( topLevelType: DOMTopLevelEventType, eventSystemFlags: EventSystemFlags, - nativeEvent: AnyNativeEvent, container: Document | Element | Node, + nativeEvent: AnyNativeEvent, ): null | Container | SuspenseInstance { // TODO: Warn if _enabled is false. @@ -372,7 +372,7 @@ export function attemptToDispatchEvent( if (enableDeprecatedFlareAPI) { if (eventSystemFlags & PLUGIN_EVENT_SYSTEM) { - dispatchEventForPluginEventSystem( + dispatchEventForLegacyPluginEventSystem( topLevelType, eventSystemFlags, nativeEvent, @@ -390,7 +390,7 @@ export function attemptToDispatchEvent( ); } } else { - dispatchEventForPluginEventSystem( + dispatchEventForLegacyPluginEventSystem( topLevelType, eventSystemFlags, nativeEvent, diff --git a/packages/react-dom/src/events/ReactDOMEventReplaying.js b/packages/react-dom/src/events/ReactDOMEventReplaying.js index be5f05f08ecc9..48ff7a5b00190 100644 --- a/packages/react-dom/src/events/ReactDOMEventReplaying.js +++ b/packages/react-dom/src/events/ReactDOMEventReplaying.js @@ -12,6 +12,7 @@ import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig'; import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes'; import type {EventSystemFlags} from 'legacy-events/EventSystemFlags'; import type {FiberRoot} from 'react-reconciler/src/ReactFiberRoot'; +import type {DOMContainer} from '../client/ReactDOM'; import { enableDeprecatedFlareAPI, @@ -117,7 +118,7 @@ import { TOP_BLUR, } from './DOMTopLevelEventTypes'; import {IS_REPLAYED} from 'legacy-events/EventSystemFlags'; -import {listenToTopLevelEvent} from './DOMLegacyEventPluginSystem'; +import {legacyListenToTopLevelEvent} from './DOMLegacyEventPluginSystem'; type QueuedReplayableEvent = {| blockedOn: null | Container | SuspenseInstance, @@ -211,12 +212,12 @@ export function isReplayableDiscreteEvent( return discreteReplayableEvents.indexOf(eventType) > -1; } -function trapReplayableEvent( +function trapReplayableEventForDocument( topLevelType: DOMTopLevelEventType, document: Document, listenerMap: Map void)>, ) { - listenToTopLevelEvent(topLevelType, document, listenerMap); + legacyListenToTopLevelEvent(topLevelType, document, listenerMap); if (enableDeprecatedFlareAPI) { // Trap events for the responder system. const topLevelTypeString = unsafeCastDOMTopLevelTypeToString(topLevelType); @@ -236,15 +237,18 @@ function trapReplayableEvent( } } -export function eagerlyTrapReplayableEvents(document: Document) { - const listenerMap = getListenerMapForElement(document); +export function eagerlyTrapReplayableEvents( + container: DOMContainer, + document: Document, +) { + const listenerMapForDoc = getListenerMapForElement(document); // Discrete discreteReplayableEvents.forEach(topLevelType => { - trapReplayableEvent(topLevelType, document, listenerMap); + trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc); }); // Continuous continuousReplayableEvents.forEach(topLevelType => { - trapReplayableEvent(topLevelType, document, listenerMap); + trapReplayableEventForDocument(topLevelType, document, listenerMapForDoc); }); } @@ -252,8 +256,8 @@ function createQueuedReplayableEvent( blockedOn: null | Container | SuspenseInstance, topLevelType: DOMTopLevelEventType, eventSystemFlags: EventSystemFlags, - nativeEvent: AnyNativeEvent, container: Document | Element | Node, + nativeEvent: AnyNativeEvent, ): QueuedReplayableEvent { return { blockedOn, @@ -268,15 +272,15 @@ export function queueDiscreteEvent( blockedOn: null | Container | SuspenseInstance, topLevelType: DOMTopLevelEventType, eventSystemFlags: EventSystemFlags, - nativeEvent: AnyNativeEvent, container: Document | Element | Node, + nativeEvent: AnyNativeEvent, ): void { const queuedEvent = createQueuedReplayableEvent( blockedOn, topLevelType, eventSystemFlags, - nativeEvent, container, + nativeEvent, ); queuedDiscreteEvents.push(queuedEvent); if (enableSelectiveHydration) { @@ -343,8 +347,8 @@ function accumulateOrCreateContinuousQueuedReplayableEvent( blockedOn: null | Container | SuspenseInstance, topLevelType: DOMTopLevelEventType, eventSystemFlags: EventSystemFlags, - nativeEvent: AnyNativeEvent, container: Document | Element | Node, + nativeEvent: AnyNativeEvent, ): QueuedReplayableEvent { if ( existingQueuedEvent === null || @@ -354,8 +358,8 @@ function accumulateOrCreateContinuousQueuedReplayableEvent( blockedOn, topLevelType, eventSystemFlags, - nativeEvent, container, + nativeEvent, ); if (blockedOn !== null) { let fiber = getInstanceFromNode(blockedOn); @@ -378,8 +382,8 @@ export function queueIfContinuousEvent( blockedOn: null | Container | SuspenseInstance, topLevelType: DOMTopLevelEventType, eventSystemFlags: EventSystemFlags, - nativeEvent: AnyNativeEvent, container: Document | Element | Node, + nativeEvent: AnyNativeEvent, ): 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. @@ -392,8 +396,8 @@ export function queueIfContinuousEvent( blockedOn, topLevelType, eventSystemFlags, - focusEvent, container, + focusEvent, ); return true; } @@ -404,8 +408,8 @@ export function queueIfContinuousEvent( blockedOn, topLevelType, eventSystemFlags, - dragEvent, container, + dragEvent, ); return true; } @@ -416,8 +420,8 @@ export function queueIfContinuousEvent( blockedOn, topLevelType, eventSystemFlags, - mouseEvent, container, + mouseEvent, ); return true; } @@ -431,8 +435,8 @@ export function queueIfContinuousEvent( blockedOn, topLevelType, eventSystemFlags, - pointerEvent, container, + pointerEvent, ), ); return true; @@ -447,8 +451,8 @@ export function queueIfContinuousEvent( blockedOn, topLevelType, eventSystemFlags, - pointerEvent, container, + pointerEvent, ), ); return true; @@ -524,8 +528,8 @@ function attemptReplayContinuousQueuedEvent( let nextBlockedOn = attemptToDispatchEvent( queuedEvent.topLevelType, queuedEvent.eventSystemFlags, - queuedEvent.nativeEvent, queuedEvent.container, + queuedEvent.nativeEvent, ); if (nextBlockedOn !== null) { // We're still blocked. Try again later. @@ -567,8 +571,8 @@ function replayUnblockedEvents() { let nextBlockedOn = attemptToDispatchEvent( nextDiscreteEvent.topLevelType, nextDiscreteEvent.eventSystemFlags, - nextDiscreteEvent.nativeEvent, nextDiscreteEvent.container, + nextDiscreteEvent.nativeEvent, ); if (nextBlockedOn !== null) { // We're still blocked. Try again later. diff --git a/packages/react-dom/src/events/SelectEventPlugin.js b/packages/react-dom/src/events/SelectEventPlugin.js index d1ab609abde6f..a370b225f28d2 100644 --- a/packages/react-dom/src/events/SelectEventPlugin.js +++ b/packages/react-dom/src/events/SelectEventPlugin.js @@ -166,11 +166,16 @@ const SelectEventPlugin = { nativeEvent, nativeEventTarget, eventSystemFlags, + container, ) { - const doc = getEventTargetDocument(nativeEventTarget); + const containerOrDoc = + container || getEventTargetDocument(nativeEventTarget); // Track whether all listeners exists for this plugin. If none exist, we do // not extract events. See #3639. - if (!doc || !isListeningToAllDependencies('onSelect', doc)) { + if ( + !containerOrDoc || + !isListeningToAllDependencies('onSelect', containerOrDoc) + ) { return null; }