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

This commit is contained in:
Dominic Gannaway
2020-03-13 17:57:17 +00:00
committed by GitHub
parent 45d26f6edb
commit 0705b7282f
5 changed files with 32 additions and 10 deletions
+3 -2
View File
@@ -59,7 +59,7 @@ import {
import {getListenerMapForElement} from '../events/DOMEventListenerMap';
import {
addResponderEventSystemEvent,
removeTrappedPassiveEventListener,
removeTrappedEventListener,
} from '../events/ReactDOMEventListener.js';
import {mediaEventTypes} from '../events/DOMTopLevelEventTypes';
import {
@@ -1360,10 +1360,11 @@ export function listenToEventResponderEventTypes(
const passiveKey = targetEventType + '_passive';
const passiveListener = listenerMap.get(passiveKey);
if (passiveListener != null) {
removeTrappedPassiveEventListener(
removeTrappedEventListener(
document,
targetEventType,
passiveListener,
true,
);
}
}
+6 -1
View File
@@ -18,9 +18,14 @@ const elementListenerMap:
| WeakMap
| Map<EventTarget, Map<DOMTopLevelEventType | string, null | (any => void)>> = new PossiblyWeakMap();
export type ElementListenerMap = Map<
DOMTopLevelEventType | string,
null | (any => void),
>;
export function getListenerMapForElement(
target: EventTarget,
): Map<DOMTopLevelEventType | string, null | (any => void)> {
): ElementListenerMap {
let listenerMap = elementListenerMap.get(target);
if (listenerMap === undefined) {
listenerMap = new Map();
+10 -2
View File
@@ -9,7 +9,9 @@
import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
import type {ElementListenerMap} from '../events/DOMEventListenerMap';
import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
import type {EventPriority} from 'shared/ReactTypes';
import type {Fiber} from 'react-reconciler/src/ReactFiber';
import type {PluginModule} from 'legacy-events/PluginModuleType';
import type {ReactSyntheticEvent} from 'legacy-events/ReactSyntheticEventType';
@@ -154,9 +156,13 @@ function dispatchEventsForPlugins(
export function listenToTopLevelEvent(
topLevelType: DOMTopLevelEventType,
targetContainer: EventTarget,
listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
listenerMap: ElementListenerMap,
passive?: boolean,
priority?: EventPriority,
): void {
// TODO: we need to know if the listenerMap previously was passive
// and to check if we need to upgrade to active. This will come in
// a useEvent follow up PR.
if (!listenerMap.has(topLevelType)) {
const isCapturePhase = capturePhaseEvents.has(topLevelType);
const listener = addTrappedEventListener(
@@ -165,6 +171,7 @@ export function listenToTopLevelEvent(
isCapturePhase,
false,
passive,
priority,
);
listenerMap.set(topLevelType, listener);
}
@@ -354,7 +361,7 @@ function getNearestRootOrPortalContainer(instance: Element): Element {
export function attachElementListener(listener: ReactDOMListener): void {
const {event, target} = listener;
const {passive, type} = event;
const {passive, priority, type} = event;
let containerEventTarget = target;
// If we the target is a managed React element, then we need to
// find the nearest root/portal contained to attach the event listener
@@ -376,6 +383,7 @@ export function attachElementListener(listener: ReactDOMListener): void {
containerEventTarget,
listenerMap,
passive,
priority,
);
// Get the internal listeners Set from the target instance.
let listeners = getListenersFromTarget(target);
+10 -3
View File
@@ -8,6 +8,7 @@
*/
import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
import type {EventPriority} from 'shared/ReactTypes';
import type {FiberRoot} from 'react-reconciler/src/ReactFiberRoot';
import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
@@ -137,10 +138,15 @@ export function addTrappedEventListener(
capture: boolean,
legacyFBSupport?: boolean,
passive?: boolean,
priority?: EventPriority,
): any => void {
const eventPriority =
priority === undefined
? getEventPriorityForPluginSystem(topLevelType)
: priority;
let listener;
let listenerWrapper;
switch (getEventPriorityForPluginSystem(topLevelType)) {
switch (eventPriority) {
case DiscreteEvent:
listenerWrapper = dispatchDiscreteEvent;
break;
@@ -247,10 +253,11 @@ export function addTrappedEventListener(
return fbListener || listener;
}
export function removeTrappedPassiveEventListener(
export function removeTrappedEventListener(
targetContainer: EventTarget,
topLevelType: string,
listener: any => void,
passive: boolean,
) {
if (listener.remove != null) {
listener.remove();
@@ -258,7 +265,7 @@ export function removeTrappedPassiveEventListener(
if (passiveBrowserEventsSupported) {
targetContainer.removeEventListener(topLevelType, listener, {
capture: true,
passive: true,
passive,
});
} else {
targetContainer.removeEventListener(topLevelType, listener, true);
+3 -2
View File
@@ -10,6 +10,7 @@
import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
import type {ElementListenerMap} from '../events/DOMEventListenerMap';
import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
import type {FiberRoot} from 'react-reconciler/src/ReactFiberRoot';
@@ -216,7 +217,7 @@ export function isReplayableDiscreteEvent(
function trapReplayableEventForContainer(
topLevelType: DOMTopLevelEventType,
container: Container,
listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
listenerMap: ElementListenerMap,
) {
listenToTopLevelEvent(topLevelType, ((container: any): Element), listenerMap);
}
@@ -224,7 +225,7 @@ function trapReplayableEventForContainer(
function trapReplayableEventForDocument(
topLevelType: DOMTopLevelEventType,
document: Document,
listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
listenerMap: ElementListenerMap,
) {
if (!enableModernEventSystem) {
legacyListenToTopLevelEvent(topLevelType, document, listenerMap);