Skip to content

Commit abab75d

Browse files
committed
Removed unused imperative events implementation
1 parent 4111002 commit abab75d

10 files changed

Lines changed: 61 additions & 368 deletions

File tree

packages/react-native-renderer/src/ReactFabricEventEmitter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ import {
2525
import {batchedUpdates} from './legacy-events/ReactGenericBatching';
2626
import accumulateInto from './legacy-events/accumulateInto';
2727

28-
import getListeners from './ReactNativeGetListeners';
28+
import getListener from './ReactNativeGetListener';
2929
import {runEventsInBatch} from './legacy-events/EventBatching';
3030

3131
import {RawEventEmitter} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
3232

33-
export {getListeners, registrationNameModules as registrationNames};
33+
export {getListener, registrationNameModules as registrationNames};
3434

3535
/**
3636
* Allows registered plugins an opportunity to extract events from top-level

packages/react-native-renderer/src/ReactFabricHostConfig.js

Lines changed: 0 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -99,28 +99,6 @@ export type RendererInspectionConfig = $ReadOnly<{
9999
) => void,
100100
}>;
101101

102-
// TODO?: find a better place for this type to live
103-
export type EventListenerOptions = $ReadOnly<{
104-
capture?: boolean,
105-
once?: boolean,
106-
passive?: boolean,
107-
signal: mixed, // not yet implemented
108-
}>;
109-
export type EventListenerRemoveOptions = $ReadOnly<{
110-
capture?: boolean,
111-
}>;
112-
113-
// TODO?: this will be changed in the future to be w3c-compatible and allow "EventListener" objects as well as functions.
114-
export type EventListener = Function;
115-
116-
type InternalEventListeners = {
117-
[string]: {
118-
listener: EventListener,
119-
options: EventListenerOptions,
120-
invalidated: boolean,
121-
}[],
122-
};
123-
124102
// TODO: Remove this conditional once all changes have propagated.
125103
if (registerEventHandler) {
126104
/**
@@ -137,7 +115,6 @@ class ReactFabricHostComponent {
137115
viewConfig: ViewConfig;
138116
currentProps: Props;
139117
_internalInstanceHandle: Object;
140-
_eventListeners: ?InternalEventListeners;
141118

142119
constructor(
143120
tag: number,
@@ -236,105 +213,6 @@ class ReactFabricHostComponent {
236213
setNativeProps(stateNode.node, updatePayload);
237214
}
238215
}
239-
240-
// This API (addEventListener, removeEventListener) attempts to adhere to the
241-
// w3 Level2 Events spec as much as possible, treating HostComponent as a DOM node.
242-
//
243-
// Unless otherwise noted, these methods should "just work" and adhere to the W3 specs.
244-
// If they deviate in a way that is not explicitly noted here, you've found a bug!
245-
//
246-
// See:
247-
// * https://www.w3.org/TR/DOM-Level-2-Events/events.html
248-
// * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
249-
// * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
250-
//
251-
// And notably, not implemented (yet?):
252-
// * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
253-
//
254-
//
255-
// Deviations from spec/TODOs:
256-
// (1) listener must currently be a function, we do not support EventListener objects yet.
257-
// (2) we do not support the `signal` option / AbortSignal yet
258-
addEventListener_unstable(
259-
eventType: string,
260-
listener: EventListener,
261-
options: EventListenerOptions | boolean,
262-
// $FlowFixMe[missing-local-annot]
263-
) {
264-
if (typeof eventType !== 'string') {
265-
throw new Error('addEventListener_unstable eventType must be a string');
266-
}
267-
if (typeof listener !== 'function') {
268-
throw new Error('addEventListener_unstable listener must be a function');
269-
}
270-
271-
// The third argument is either boolean indicating "captures" or an object.
272-
const optionsObj =
273-
typeof options === 'object' && options !== null ? options : {};
274-
const capture =
275-
(typeof options === 'boolean' ? options : optionsObj.capture) || false;
276-
const once = optionsObj.once || false;
277-
const passive = optionsObj.passive || false;
278-
const signal = null; // TODO: implement signal/AbortSignal
279-
280-
/* $FlowFixMe the old version of Flow doesn't have a good way to define an
281-
* empty exact object. */
282-
const eventListeners: InternalEventListeners = this._eventListeners || {};
283-
if (this._eventListeners == null) {
284-
this._eventListeners = eventListeners;
285-
}
286-
287-
const namedEventListeners = eventListeners[eventType] || [];
288-
if (eventListeners[eventType] == null) {
289-
eventListeners[eventType] = namedEventListeners;
290-
}
291-
292-
namedEventListeners.push({
293-
listener: listener,
294-
invalidated: false,
295-
options: {
296-
capture: capture,
297-
once: once,
298-
passive: passive,
299-
signal: signal,
300-
},
301-
});
302-
}
303-
304-
// See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
305-
removeEventListener_unstable(
306-
eventType: string,
307-
listener: EventListener,
308-
options: EventListenerRemoveOptions | boolean,
309-
) {
310-
// eventType and listener must be referentially equal to be removed from the listeners
311-
// data structure, but in "options" we only check the `capture` flag, according to spec.
312-
// That means if you add the same function as a listener with capture set to true and false,
313-
// you must also call removeEventListener twice with capture set to true/false.
314-
const optionsObj =
315-
typeof options === 'object' && options !== null ? options : {};
316-
const capture =
317-
(typeof options === 'boolean' ? options : optionsObj.capture) || false;
318-
319-
// If there are no event listeners or named event listeners, we can bail early - our
320-
// job is already done.
321-
const eventListeners = this._eventListeners;
322-
if (!eventListeners) {
323-
return;
324-
}
325-
const namedEventListeners = eventListeners[eventType];
326-
if (!namedEventListeners) {
327-
return;
328-
}
329-
330-
// TODO: optimize this path to make remove cheaper
331-
eventListeners[eventType] = namedEventListeners.filter(listenerObj => {
332-
return !(
333-
listenerObj.listener === listener &&
334-
listenerObj.options.capture === capture
335-
);
336-
});
337-
}
338216
}
339217

340218
// $FlowFixMe[class-object-subtyping] found when upgrading Flow

packages/react-native-renderer/src/ReactNativeBridgeEventPlugin.js

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,13 @@ import type {
1313
} from './legacy-events/PluginModuleType';
1414
import type {TopLevelType} from './legacy-events/TopLevelEventTypes';
1515
import SyntheticEvent from './legacy-events/SyntheticEvent';
16-
import type {PropagationPhases} from './legacy-events/PropagationPhases';
1716

1817
// Module provided by RN:
1918
import {ReactNativeViewConfigRegistry} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
2019
import accumulateInto from './legacy-events/accumulateInto';
21-
import getListeners from './ReactNativeGetListeners';
20+
import getListener from './ReactNativeGetListener';
2221
import forEachAccumulated from './legacy-events/forEachAccumulated';
2322
import {HostComponent} from 'react-reconciler/src/ReactWorkTags';
24-
import isArray from 'shared/isArray';
2523

2624
const {customBubblingEventTypes, customDirectEventTypes} =
2725
ReactNativeViewConfigRegistry;
@@ -30,38 +28,10 @@ const {customBubblingEventTypes, customDirectEventTypes} =
3028
// EventPropagator.js, as they deviated from ReactDOM's newer
3129
// implementations.
3230
// $FlowFixMe[missing-local-annot]
33-
function listenersAtPhase(inst, event, propagationPhase: PropagationPhases) {
31+
function listenerAtPhase(inst, event, propagationPhase: PropagationPhases) {
3432
const registrationName =
3533
event.dispatchConfig.phasedRegistrationNames[propagationPhase];
36-
return getListeners(inst, registrationName, propagationPhase, true);
37-
}
38-
39-
// $FlowFixMe[missing-local-annot]
40-
function accumulateListenersAndInstances(inst, event, listeners) {
41-
const listenersLength = listeners
42-
? isArray(listeners)
43-
? listeners.length
44-
: 1
45-
: 0;
46-
if (listenersLength > 0) {
47-
event._dispatchListeners = accumulateInto(
48-
event._dispatchListeners,
49-
listeners,
50-
);
51-
52-
// Avoid allocating additional arrays here
53-
if (event._dispatchInstances == null && listenersLength === 1) {
54-
event._dispatchInstances = inst;
55-
} else {
56-
event._dispatchInstances = event._dispatchInstances || [];
57-
if (!isArray(event._dispatchInstances)) {
58-
event._dispatchInstances = [event._dispatchInstances];
59-
}
60-
for (let i = 0; i < listenersLength; i++) {
61-
event._dispatchInstances.push(inst);
62-
}
63-
}
64-
}
34+
return getListener(inst, registrationName);
6535
}
6636

6737
// $FlowFixMe[missing-local-annot]
@@ -71,8 +41,14 @@ function accumulateDirectionalDispatches(inst, phase, event) {
7141
console.error('Dispatching inst must not be null');
7242
}
7343
}
74-
const listeners = listenersAtPhase(inst, event, phase);
75-
accumulateListenersAndInstances(inst, event, listeners);
44+
const listener = listenerAtPhase(inst, event, phase);
45+
if (listener) {
46+
event._dispatchListeners = accumulateInto(
47+
event._dispatchListeners,
48+
listener,
49+
);
50+
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
51+
}
7652
}
7753

7854
// $FlowFixMe[missing-local-annot]
@@ -160,8 +136,14 @@ function accumulateDispatches(
160136
): void {
161137
if (inst && event && event.dispatchConfig.registrationName) {
162138
const registrationName = event.dispatchConfig.registrationName;
163-
const listeners = getListeners(inst, registrationName, 'bubbled', false);
164-
accumulateListenersAndInstances(inst, event, listeners);
139+
const listener = getListener(inst, registrationName);
140+
if (listener) {
141+
event._dispatchListeners = accumulateInto(
142+
event._dispatchListeners,
143+
listener,
144+
);
145+
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
146+
}
165147
}
166148
}
167149

@@ -181,6 +163,7 @@ function accumulateDirectDispatches(events: ?(Array<Object> | Object)) {
181163
}
182164

183165
// End of inline
166+
type PropagationPhases = 'bubbled' | 'captured';
184167

185168
const ReactNativeBridgeEventPlugin = {
186169
eventTypes: ({}: EventTypes),

packages/react-native-renderer/src/ReactNativeEventEmitter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ import {
2121
} from './legacy-events/EventPluginRegistry';
2222
import {batchedUpdates} from './legacy-events/ReactGenericBatching';
2323
import {runEventsInBatch} from './legacy-events/EventBatching';
24-
import getListeners from './ReactNativeGetListeners';
24+
import getListener from './ReactNativeGetListener';
2525
import accumulateInto from './legacy-events/accumulateInto';
2626

2727
import {getInstanceFromNode} from './ReactNativeComponentTree';
2828

29-
export {getListeners, registrationNameModules as registrationNames};
29+
export {getListener, registrationNameModules as registrationNames};
3030

3131
/**
3232
* Version of `ReactBrowserEventEmitter` that works on the receiving side of a
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
11+
12+
import {getFiberCurrentPropsFromNode} from './legacy-events/EventPluginUtils';
13+
14+
export default function getListener(
15+
inst: Fiber,
16+
registrationName: string,
17+
): Function | null {
18+
const stateNode = inst.stateNode;
19+
if (stateNode === null) {
20+
// Work in progress (ex: onload events in incremental mode).
21+
return null;
22+
}
23+
const props = getFiberCurrentPropsFromNode(stateNode);
24+
if (props === null) {
25+
// Work in progress.
26+
return null;
27+
}
28+
const listener = props[registrationName];
29+
30+
if (listener && typeof listener !== 'function') {
31+
throw new Error(
32+
`Expected \`${registrationName}\` listener to be a function, instead got a value of \`${typeof listener}\` type.`,
33+
);
34+
}
35+
36+
return listener;
37+
}

0 commit comments

Comments
 (0)