Skip to content

Commit

Permalink
Refine event system types + pass through priority (#18305)
Browse files Browse the repository at this point in the history
  • Loading branch information
trueadm committed Mar 13, 2020
1 parent 45d26f6 commit 0705b72
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 10 deletions.
5 changes: 3 additions & 2 deletions packages/react-dom/src/client/ReactDOMComponent.js
Expand Up @@ -59,7 +59,7 @@ import {
import {getListenerMapForElement} from '../events/DOMEventListenerMap';
import {
addResponderEventSystemEvent,
removeTrappedPassiveEventListener,
removeTrappedEventListener,
} from '../events/ReactDOMEventListener.js';
import {mediaEventTypes} from '../events/DOMTopLevelEventTypes';
import {
Expand Down Expand Up @@ -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,
);
}
}
Expand Down
7 changes: 6 additions & 1 deletion packages/react-dom/src/events/DOMEventListenerMap.js
Expand Up @@ -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();
Expand Down
12 changes: 10 additions & 2 deletions packages/react-dom/src/events/DOMModernPluginEventSystem.js
Expand Up @@ -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';
Expand Down Expand Up @@ -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(
Expand All @@ -165,6 +171,7 @@ export function listenToTopLevelEvent(
isCapturePhase,
false,
passive,
priority,
);
listenerMap.set(topLevelType, listener);
}
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down
13 changes: 10 additions & 3 deletions packages/react-dom/src/events/ReactDOMEventListener.js
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -247,18 +253,19 @@ 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();
} else {
if (passiveBrowserEventsSupported) {
targetContainer.removeEventListener(topLevelType, listener, {
capture: true,
passive: true,
passive,
});
} else {
targetContainer.removeEventListener(topLevelType, listener, true);
Expand Down
5 changes: 3 additions & 2 deletions packages/react-dom/src/events/ReactDOMEventReplaying.js
Expand Up @@ -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';

Expand Down Expand Up @@ -216,15 +217,15 @@ export function isReplayableDiscreteEvent(
function trapReplayableEventForContainer(
topLevelType: DOMTopLevelEventType,
container: Container,
listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
listenerMap: ElementListenerMap,
) {
listenToTopLevelEvent(topLevelType, ((container: any): Element), listenerMap);
}

function trapReplayableEventForDocument(
topLevelType: DOMTopLevelEventType,
document: Document,
listenerMap: Map<DOMTopLevelEventType | string, null | (any => void)>,
listenerMap: ElementListenerMap,
) {
if (!enableModernEventSystem) {
legacyListenToTopLevelEvent(topLevelType, document, listenerMap);
Expand Down

0 comments on commit 0705b72

Please sign in to comment.