@samitouri / QOS-React-2 / commits / 0705b7282f

Refine event system types + pass through priority (#18305)

Dominic Gannaway committed Mar 13, 2020 at 17:57 UTC 0705b7282f9c52ce85b6125ebbe32f6a6abf01a4
5 files changed +32 -10
packages/react-dom/src/client/ReactDOMComponent.js
+3 -2
@@ -59,7 +59,7 @@ import {
59 import {getListenerMapForElement} from '../events/DOMEventListenerMap';
60 import {
61 addResponderEventSystemEvent,
62 - removeTrappedPassiveEventListener,
62 + removeTrappedEventListener,
63 } from '../events/ReactDOMEventListener.js';
64 import {mediaEventTypes} from '../events/DOMTopLevelEventTypes';
65 import {
@@ -1360,10 +1360,11 @@ export function listenToEventResponderEventTypes(
1360 const passiveKey = targetEventType + '_passive';
1361 const passiveListener = listenerMap.get(passiveKey);
1362 if (passiveListener != null) {
1363 - removeTrappedPassiveEventListener(
1363 + removeTrappedEventListener(
1364 document,
1365 targetEventType,
1366 passiveListener,
1367 + true,
1368 );
1369 }
1370 }
packages/react-dom/src/events/DOMEventListenerMap.js
+6 -1
@@ -18,9 +18,14 @@ const elementListenerMap:
18 | WeakMap
19 | Map<EventTarget, Map<DOMTopLevelEventType | string, null | (any => void)>> = new PossiblyWeakMap();
20
21 +export type ElementListenerMap = Map<
22 + DOMTopLevelEventType | string,
23 + null | (any => void),
24 +>;
25 +
26 export function getListenerMapForElement(
27 target: EventTarget,
23 -): Map<DOMTopLevelEventType | string, null | (any => void)> {
28 +): ElementListenerMap {
29 let listenerMap = elementListenerMap.get(target);
30 if (listenerMap === undefined) {
31 listenerMap = new Map();
packages/react-dom/src/events/DOMModernPluginEventSystem.js
+10 -2
@@ -9,7 +9,9 @@
9
10 import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
11 import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
12 +import type {ElementListenerMap} from '../events/DOMEventListenerMap';
13 import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
14 +import type {EventPriority} from 'shared/ReactTypes';
15 import type {Fiber} from 'react-reconciler/src/ReactFiber';
16 import type {PluginModule} from 'legacy-events/PluginModuleType';
17 import type {ReactSyntheticEvent} from 'legacy-events/ReactSyntheticEventType';
@@ -154,9 +156,13 @@ function dispatchEventsForPlugins(
156 export function listenToTopLevelEvent(
157 topLevelType: DOMTopLevelEventType,
158 targetContainer: EventTarget,
157 - listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
159 + listenerMap: ElementListenerMap,
160 passive?: boolean,
161 + priority?: EventPriority,
162 ): void {
163 + // TODO: we need to know if the listenerMap previously was passive
164 + // and to check if we need to upgrade to active. This will come in
165 + // a useEvent follow up PR.
166 if (!listenerMap.has(topLevelType)) {
167 const isCapturePhase = capturePhaseEvents.has(topLevelType);
168 const listener = addTrappedEventListener(
@@ -165,6 +171,7 @@ export function listenToTopLevelEvent(
171 isCapturePhase,
172 false,
173 passive,
174 + priority,
175 );
176 listenerMap.set(topLevelType, listener);
177 }
@@ -354,7 +361,7 @@ function getNearestRootOrPortalContainer(instance: Element): Element {
361
362 export function attachElementListener(listener: ReactDOMListener): void {
363 const {event, target} = listener;
357 - const {passive, type} = event;
364 + const {passive, priority, type} = event;
365 let containerEventTarget = target;
366 // If we the target is a managed React element, then we need to
367 // find the nearest root/portal contained to attach the event listener
@@ -376,6 +383,7 @@ export function attachElementListener(listener: ReactDOMListener): void {
383 containerEventTarget,
384 listenerMap,
385 passive,
386 + priority,
387 );
388 // Get the internal listeners Set from the target instance.
389 let listeners = getListenersFromTarget(target);
packages/react-dom/src/events/ReactDOMEventListener.js
+10 -3
@@ -8,6 +8,7 @@
8 */
9
10 import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
11 +import type {EventPriority} from 'shared/ReactTypes';
12 import type {FiberRoot} from 'react-reconciler/src/ReactFiberRoot';
13 import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
14 import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
@@ -137,10 +138,15 @@ export function addTrappedEventListener(
138 capture: boolean,
139 legacyFBSupport?: boolean,
140 passive?: boolean,
141 + priority?: EventPriority,
142 ): any => void {
143 + const eventPriority =
144 + priority === undefined
145 + ? getEventPriorityForPluginSystem(topLevelType)
146 + : priority;
147 let listener;
148 let listenerWrapper;
143 - switch (getEventPriorityForPluginSystem(topLevelType)) {
149 + switch (eventPriority) {
150 case DiscreteEvent:
151 listenerWrapper = dispatchDiscreteEvent;
152 break;
@@ -247,10 +253,11 @@ export function addTrappedEventListener(
253 return fbListener || listener;
254 }
255
250 -export function removeTrappedPassiveEventListener(
256 +export function removeTrappedEventListener(
257 targetContainer: EventTarget,
258 topLevelType: string,
259 listener: any => void,
260 + passive: boolean,
261 ) {
262 if (listener.remove != null) {
263 listener.remove();
@@ -258,7 +265,7 @@ export function removeTrappedPassiveEventListener(
265 if (passiveBrowserEventsSupported) {
266 targetContainer.removeEventListener(topLevelType, listener, {
267 capture: true,
261 - passive: true,
268 + passive,
269 });
270 } else {
271 targetContainer.removeEventListener(topLevelType, listener, true);
packages/react-dom/src/events/ReactDOMEventReplaying.js
+3 -2
@@ -10,6 +10,7 @@
10 import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
11 import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
12 import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
13 +import type {ElementListenerMap} from '../events/DOMEventListenerMap';
14 import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
15 import type {FiberRoot} from 'react-reconciler/src/ReactFiberRoot';
16
@@ -216,7 +217,7 @@ export function isReplayableDiscreteEvent(
217 function trapReplayableEventForContainer(
218 topLevelType: DOMTopLevelEventType,
219 container: Container,
219 - listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
220 + listenerMap: ElementListenerMap,
221 ) {
222 listenToTopLevelEvent(topLevelType, ((container: any): Element), listenerMap);
223 }
@@ -224,7 +225,7 @@ function trapReplayableEventForContainer(
225 function trapReplayableEventForDocument(
226 topLevelType: DOMTopLevelEventType,
227 document: Document,
227 - listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
228 + listenerMap: ElementListenerMap,
229 ) {
230 if (!enableModernEventSystem) {
231 legacyListenToTopLevelEvent(topLevelType, document, listenerMap);