Skip to content

Commit 11ee82d

Browse files
authored
[Events] Make passiveness and priority non-configurable (#19807)
1 parent ebb2253 commit 11ee82d

File tree

10 files changed

+161
-480
lines changed

10 files changed

+161
-480
lines changed

packages/react-dom/src/client/ReactDOMComponentTree.js

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import type {
2020
SuspenseInstance,
2121
Props,
2222
} from './ReactDOMHostConfig';
23-
import type {DOMEventName} from '../events/DOMEventNames';
2423

2524
import {
2625
HostComponent,
@@ -44,16 +43,6 @@ const internalEventHandlersKey = '__reactEvents$' + randomKey;
4443
const internalEventHandlerListenersKey = '__reactListeners$' + randomKey;
4544
const internalEventHandlesSetKey = '__reactHandles$' + randomKey;
4645

47-
export type ElementListenerMap = Map<
48-
DOMEventName | string,
49-
ElementListenerMapEntry | null,
50-
>;
51-
52-
export type ElementListenerMapEntry = {
53-
passive: void | boolean,
54-
listener: any => void,
55-
};
56-
5746
export function precacheFiberNode(
5847
hostInst: Fiber,
5948
node: Instance | TextInstance | SuspenseInstance | ReactScopeInstance,
@@ -207,12 +196,12 @@ export function updateFiberProps(
207196
(node: any)[internalPropsKey] = props;
208197
}
209198

210-
export function getEventListenerMap(node: EventTarget): ElementListenerMap {
211-
let elementListenerMap = (node: any)[internalEventHandlersKey];
212-
if (elementListenerMap === undefined) {
213-
elementListenerMap = (node: any)[internalEventHandlersKey] = new Map();
199+
export function getEventListenerSet(node: EventTarget): Set<string> {
200+
let elementListenerSet = (node: any)[internalEventHandlersKey];
201+
if (elementListenerSet === undefined) {
202+
elementListenerSet = (node: any)[internalEventHandlersKey] = new Set();
214203
}
215-
return elementListenerMap;
204+
return elementListenerSet;
216205
}
217206

218207
export function getFiberFromScopeInstance(

packages/react-dom/src/client/ReactDOMEventHandle.js

Lines changed: 69 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@
88
*/
99

1010
import type {DOMEventName} from '../events/DOMEventNames';
11-
import type {EventPriority, ReactScopeInstance} from 'shared/ReactTypes';
11+
import type {ReactScopeInstance} from 'shared/ReactTypes';
1212
import type {
1313
ReactDOMEventHandle,
1414
ReactDOMEventHandleListener,
1515
} from '../shared/ReactDOMTypes';
1616

17-
import {getEventPriorityForListenerSystem} from '../events/DOMEventProperties';
1817
import {allNativeEvents} from '../events/EventRegistry';
1918
import {
2019
getClosestInstanceFromNode,
@@ -25,10 +24,7 @@ import {
2524
addEventHandleToTarget,
2625
} from './ReactDOMComponentTree';
2726
import {ELEMENT_NODE, COMMENT_NODE} from '../shared/HTMLNodeType';
28-
import {
29-
listenToNativeEvent,
30-
addEventTypeToDispatchConfig,
31-
} from '../events/DOMPluginEventSystem';
27+
import {listenToNativeEvent} from '../events/DOMPluginEventSystem';
3228

3329
import {HostRoot, HostPortal} from 'react-reconciler/src/ReactWorkTags';
3430
import {IS_EVENT_HANDLE_NON_MANAGED_NODE} from '../events/EventSystemFlags';
@@ -42,8 +38,6 @@ import invariant from 'shared/invariant';
4238

4339
type EventHandleOptions = {|
4440
capture?: boolean,
45-
passive?: boolean,
46-
priority?: EventPriority,
4741
|};
4842

4943
function getNearestRootOrPortalContainer(node: Fiber): null | Element {
@@ -82,76 +76,76 @@ function createEventHandleListener(
8276
function registerEventOnNearestTargetContainer(
8377
targetFiber: Fiber,
8478
domEventName: DOMEventName,
85-
isPassiveListener: boolean | void,
86-
listenerPriority: EventPriority | void,
8779
isCapturePhaseListener: boolean,
8880
targetElement: Element | null,
8981
): void {
90-
// If it is, find the nearest root or portal and make it
91-
// our event handle target container.
92-
let targetContainer = getNearestRootOrPortalContainer(targetFiber);
93-
if (targetContainer === null) {
94-
invariant(
95-
false,
96-
'ReactDOM.createEventHandle: setListener called on an target ' +
97-
'that did not have a corresponding root. This is likely a bug in React.',
82+
if (!enableEagerRootListeners) {
83+
// If it is, find the nearest root or portal and make it
84+
// our event handle target container.
85+
let targetContainer = getNearestRootOrPortalContainer(targetFiber);
86+
if (targetContainer === null) {
87+
if (__DEV__) {
88+
console.error(
89+
'ReactDOM.createEventHandle: setListener called on an target ' +
90+
'that did not have a corresponding root. This is likely a bug in React.',
91+
);
92+
}
93+
return;
94+
}
95+
if (targetContainer.nodeType === COMMENT_NODE) {
96+
targetContainer = ((targetContainer.parentNode: any): Element);
97+
}
98+
listenToNativeEvent(
99+
domEventName,
100+
isCapturePhaseListener,
101+
targetContainer,
102+
targetElement,
98103
);
99104
}
100-
if (targetContainer.nodeType === COMMENT_NODE) {
101-
targetContainer = ((targetContainer.parentNode: any): Element);
102-
}
103-
listenToNativeEvent(
104-
domEventName,
105-
isCapturePhaseListener,
106-
targetContainer,
107-
targetElement,
108-
isPassiveListener,
109-
listenerPriority,
110-
);
111105
}
112106

113107
function registerReactDOMEvent(
114108
target: EventTarget | ReactScopeInstance,
115109
domEventName: DOMEventName,
116-
isPassiveListener: boolean | void,
117110
isCapturePhaseListener: boolean,
118-
listenerPriority: EventPriority | void,
119111
): void {
120112
// Check if the target is a DOM element.
121113
if ((target: any).nodeType === ELEMENT_NODE) {
122-
const targetElement = ((target: any): Element);
123-
// Check if the DOM element is managed by React.
124-
const targetFiber = getClosestInstanceFromNode(targetElement);
125-
if (targetFiber === null) {
126-
invariant(
127-
false,
128-
'ReactDOM.createEventHandle: setListener called on an element ' +
129-
'target that is not managed by React. Ensure React rendered the DOM element.',
114+
if (!enableEagerRootListeners) {
115+
const targetElement = ((target: any): Element);
116+
// Check if the DOM element is managed by React.
117+
const targetFiber = getClosestInstanceFromNode(targetElement);
118+
if (targetFiber === null) {
119+
if (__DEV__) {
120+
console.error(
121+
'ReactDOM.createEventHandle: setListener called on an element ' +
122+
'target that is not managed by React. Ensure React rendered the DOM element.',
123+
);
124+
}
125+
return;
126+
}
127+
registerEventOnNearestTargetContainer(
128+
targetFiber,
129+
domEventName,
130+
isCapturePhaseListener,
131+
targetElement,
130132
);
131133
}
132-
registerEventOnNearestTargetContainer(
133-
targetFiber,
134-
domEventName,
135-
isPassiveListener,
136-
listenerPriority,
137-
isCapturePhaseListener,
138-
targetElement,
139-
);
140134
} else if (enableScopeAPI && isReactScope(target)) {
141-
const scopeTarget = ((target: any): ReactScopeInstance);
142-
const targetFiber = getFiberFromScopeInstance(scopeTarget);
143-
if (targetFiber === null) {
144-
// Scope is unmounted, do not proceed.
145-
return;
135+
if (!enableEagerRootListeners) {
136+
const scopeTarget = ((target: any): ReactScopeInstance);
137+
const targetFiber = getFiberFromScopeInstance(scopeTarget);
138+
if (targetFiber === null) {
139+
// Scope is unmounted, do not proceed.
140+
return;
141+
}
142+
registerEventOnNearestTargetContainer(
143+
targetFiber,
144+
domEventName,
145+
isCapturePhaseListener,
146+
null,
147+
);
146148
}
147-
registerEventOnNearestTargetContainer(
148-
targetFiber,
149-
domEventName,
150-
isPassiveListener,
151-
listenerPriority,
152-
isCapturePhaseListener,
153-
null,
154-
);
155149
} else if (isValidEventTarget(target)) {
156150
const eventTarget = ((target: any): EventTarget);
157151
// These are valid event targets, but they are also
@@ -161,8 +155,6 @@ function registerReactDOMEvent(
161155
isCapturePhaseListener,
162156
eventTarget,
163157
null,
164-
isPassiveListener,
165-
listenerPriority,
166158
IS_EVENT_HANDLE_NON_MANAGED_NODE,
167159
);
168160
} else {
@@ -181,46 +173,27 @@ export function createEventHandle(
181173
if (enableCreateEventHandleAPI) {
182174
const domEventName = ((type: any): DOMEventName);
183175

184-
if (enableEagerRootListeners) {
185-
// We cannot support arbitrary native events with eager root listeners
186-
// because the eager strategy relies on knowing the whole list ahead of time.
187-
// If we wanted to support this, we'd have to add code to keep track
188-
// (or search) for all portal and root containers, and lazily add listeners
189-
// to them whenever we see a previously unknown event. This seems like a lot
190-
// of complexity for something we don't even have a particular use case for.
191-
// Unfortunately, the downside of this invariant is that *removing* a native
192-
// event from the list of known events has now become a breaking change for
193-
// any code relying on the createEventHandle API.
194-
invariant(
195-
allNativeEvents.has(domEventName) ||
196-
domEventName === 'beforeblur' ||
197-
domEventName === 'afterblur',
198-
'Cannot call unstable_createEventHandle with "%s", as it is not an event known to React.',
199-
domEventName,
200-
);
201-
}
176+
// We cannot support arbitrary native events with eager root listeners
177+
// because the eager strategy relies on knowing the whole list ahead of time.
178+
// If we wanted to support this, we'd have to add code to keep track
179+
// (or search) for all portal and root containers, and lazily add listeners
180+
// to them whenever we see a previously unknown event. This seems like a lot
181+
// of complexity for something we don't even have a particular use case for.
182+
// Unfortunately, the downside of this invariant is that *removing* a native
183+
// event from the list of known events has now become a breaking change for
184+
// any code relying on the createEventHandle API.
185+
invariant(
186+
allNativeEvents.has(domEventName),
187+
'Cannot call unstable_createEventHandle with "%s", as it is not an event known to React.',
188+
domEventName,
189+
);
202190

203191
let isCapturePhaseListener = false;
204-
let isPassiveListener = undefined; // Undefined means to use the browser default
205-
let listenerPriority;
206-
207192
if (options != null) {
208193
const optionsCapture = options.capture;
209-
const optionsPassive = options.passive;
210-
const optionsPriority = options.priority;
211-
212194
if (typeof optionsCapture === 'boolean') {
213195
isCapturePhaseListener = optionsCapture;
214196
}
215-
if (typeof optionsPassive === 'boolean') {
216-
isPassiveListener = optionsPassive;
217-
}
218-
if (typeof optionsPriority === 'number') {
219-
listenerPriority = optionsPriority;
220-
}
221-
}
222-
if (listenerPriority === undefined) {
223-
listenerPriority = getEventPriorityForListenerSystem(domEventName);
224197
}
225198

226199
const eventHandle = (
@@ -234,15 +207,7 @@ export function createEventHandle(
234207
);
235208
if (!doesTargetHaveEventHandle(target, eventHandle)) {
236209
addEventHandleToTarget(target, eventHandle);
237-
registerReactDOMEvent(
238-
target,
239-
domEventName,
240-
isPassiveListener,
241-
isCapturePhaseListener,
242-
listenerPriority,
243-
);
244-
// Add the event to our known event types list.
245-
addEventTypeToDispatchConfig(domEventName);
210+
registerReactDOMEvent(target, domEventName, isCapturePhaseListener);
246211
}
247212
const listener = createEventHandleListener(
248213
domEventName,

packages/react-dom/src/events/DOMEventProperties.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ const otherDiscreteEvents: Array<DOMEventName> = [
8989
];
9090

9191
if (enableCreateEventHandleAPI) {
92+
// Special case: these two events don't have on* React handler
93+
// and are only accessible via the createEventHandle API.
94+
topLevelEventsToReactNames.set('beforeblur', null);
95+
topLevelEventsToReactNames.set('afterblur', null);
9296
otherDiscreteEvents.push('beforeblur', 'afterblur');
9397
}
9498

@@ -202,7 +206,7 @@ export function getEventPriorityForListenerSystem(
202206
if (__DEV__) {
203207
console.warn(
204208
'The event "%s" provided to createEventHandle() does not have a known priority type.' +
205-
' It is recommended to provide a "priority" option to specify a priority.',
209+
' This is likely a bug in React.',
206210
type,
207211
);
208212
}

0 commit comments

Comments
 (0)