7
* @flow
8
*/
9
10
-import EventPluginHub from 'events/EventPluginHub';
11
-import EventPluginRegistry from 'events/EventPluginRegistry';
12
-import ReactEventEmitterMixin from 'events/ReactEventEmitterMixin';
13
-import ReactGenericBatching from 'events/ReactGenericBatching';
10
+import {getListener} from 'events/EventPluginHub';
11
+import {registrationNameModules} from 'events/EventPluginRegistry';
12
+import {batchedUpdates} from 'events/ReactGenericBatching';
13
+import {handleTopLevel} from 'events/ReactEventEmitterMixin';
14
import warning from 'fbjs/lib/warning';
15
16
-import ReactNativeComponentTree from './ReactNativeComponentTree';
16
+import {getInstanceFromNode} from './ReactNativeComponentTree';
17
import ReactNativeTagHandles from './ReactNativeTagHandles';
18
19
+export * from 'events/ReactEventEmitterMixin';
20
+export {getListener, registrationNameModules as registrationNames};
21
+
22
/**
23
* Version of `ReactBrowserEventEmitter` that works on the receiving side of a
24
* serialized worker boundary.
77
return rippedOut;
78
};
79
77
-var ReactNativeEventEmitter = {
78
- ...ReactEventEmitterMixin,
79
-
80
- registrationNames: EventPluginRegistry.registrationNameModules,
81
-
82
- getListener: EventPluginHub.getListener,
83
-
84
- /**
85
- * Internal version of `receiveEvent` in terms of normalized (non-tag)
86
- * `rootNodeID`.
87
- *
88
- * @see receiveEvent.
89
- *
90
- * @param {rootNodeID} rootNodeID React root node ID that event occurred on.
91
- * @param {TopLevelType} topLevelType Top level type of event.
92
- * @param {?object} nativeEventParam Object passed from native.
93
- */
94
- _receiveRootNodeIDEvent: function(
95
- rootNodeID: number,
96
- topLevelType: string,
97
- nativeEventParam: ?Object,
98
- ) {
99
- var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT;
100
- var inst = ReactNativeComponentTree.getInstanceFromNode(rootNodeID);
101
- ReactGenericBatching.batchedUpdates(function() {
102
- ReactNativeEventEmitter.handleTopLevel(
103
- topLevelType,
104
- inst,
105
- nativeEvent,
106
- nativeEvent.target,
107
- );
108
- });
109
- // React Native doesn't use ReactControlledComponent but if it did, here's
110
- // where it would do it.
111
- },
80
+/**
81
+ * Internal version of `receiveEvent` in terms of normalized (non-tag)
82
+ * `rootNodeID`.
83
+ *
84
+ * @see receiveEvent.
85
+ *
86
+ * @param {rootNodeID} rootNodeID React root node ID that event occurred on.
87
+ * @param {TopLevelType} topLevelType Top level type of event.
88
+ * @param {?object} nativeEventParam Object passed from native.
89
+ */
90
+export function _receiveRootNodeIDEvent(
91
+ rootNodeID: number,
92
+ topLevelType: string,
93
+ nativeEventParam: ?Object,
94
+) {
95
+ var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT;
96
+ var inst = getInstanceFromNode(rootNodeID);
97
+ batchedUpdates(function() {
98
+ handleTopLevel(topLevelType, inst, nativeEvent, nativeEvent.target);
99
+ });
100
+ // React Native doesn't use ReactControlledComponent but if it did, here's
101
+ // where it would do it.
102
+}
103
113
- /**
114
- * Publicly exposed method on module for native objc to invoke when a top
115
- * level event is extracted.
116
- * @param {rootNodeID} rootNodeID React root node ID that event occurred on.
117
- * @param {TopLevelType} topLevelType Top level type of event.
118
- * @param {object} nativeEventParam Object passed from native.
119
- */
120
- receiveEvent: function(
121
- rootNodeID: number,
122
- topLevelType: string,
123
- nativeEventParam: Object,
124
- ) {
125
- ReactNativeEventEmitter._receiveRootNodeIDEvent(
126
- rootNodeID,
127
- topLevelType,
128
- nativeEventParam,
129
- );
130
- },
104
+/**
105
+ * Publicly exposed method on module for native objc to invoke when a top
106
+ * level event is extracted.
107
+ * @param {rootNodeID} rootNodeID React root node ID that event occurred on.
108
+ * @param {TopLevelType} topLevelType Top level type of event.
109
+ * @param {object} nativeEventParam Object passed from native.
110
+ */
111
+export function receiveEvent(
112
+ rootNodeID: number,
113
+ topLevelType: string,
114
+ nativeEventParam: Object,
115
+) {
116
+ _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam);
117
+}
118
132
- /**
133
- * Simple multi-wrapper around `receiveEvent` that is intended to receive an
134
- * efficient representation of `Touch` objects, and other information that
135
- * can be used to construct W3C compliant `Event` and `Touch` lists.
136
- *
137
- * This may create dispatch behavior that differs than web touch handling. We
138
- * loop through each of the changed touches and receive it as a single event.
139
- * So two `touchStart`/`touchMove`s that occur simultaneously are received as
140
- * two separate touch event dispatches - when they arguably should be one.
141
- *
142
- * This implementation reuses the `Touch` objects themselves as the `Event`s
143
- * since we dispatch an event for each touch (though that might not be spec
144
- * compliant). The main purpose of reusing them is to save allocations.
145
- *
146
- * TODO: Dispatch multiple changed touches in one event. The bubble path
147
- * could be the first common ancestor of all the `changedTouches`.
148
- *
149
- * One difference between this behavior and W3C spec: cancelled touches will
150
- * not appear in `.touches`, or in any future `.touches`, though they may
151
- * still be "actively touching the surface".
152
- *
153
- * Web desktop polyfills only need to construct a fake touch event with
154
- * identifier 0, also abandoning traditional click handlers.
155
- */
156
- receiveTouches: function(
157
- eventTopLevelType: string,
158
- touches: Array<Object>,
159
- changedIndices: Array<number>,
160
- ) {
161
- var changedTouches = eventTopLevelType === 'topTouchEnd' ||
162
- eventTopLevelType === 'topTouchCancel'
163
- ? removeTouchesAtIndices(touches, changedIndices)
164
- : touchSubsequence(touches, changedIndices);
119
+/**
120
+ * Simple multi-wrapper around `receiveEvent` that is intended to receive an
121
+ * efficient representation of `Touch` objects, and other information that
122
+ * can be used to construct W3C compliant `Event` and `Touch` lists.
123
+ *
124
+ * This may create dispatch behavior that differs than web touch handling. We
125
+ * loop through each of the changed touches and receive it as a single event.
126
+ * So two `touchStart`/`touchMove`s that occur simultaneously are received as
127
+ * two separate touch event dispatches - when they arguably should be one.
128
+ *
129
+ * This implementation reuses the `Touch` objects themselves as the `Event`s
130
+ * since we dispatch an event for each touch (though that might not be spec
131
+ * compliant). The main purpose of reusing them is to save allocations.
132
+ *
133
+ * TODO: Dispatch multiple changed touches in one event. The bubble path
134
+ * could be the first common ancestor of all the `changedTouches`.
135
+ *
136
+ * One difference between this behavior and W3C spec: cancelled touches will
137
+ * not appear in `.touches`, or in any future `.touches`, though they may
138
+ * still be "actively touching the surface".
139
+ *
140
+ * Web desktop polyfills only need to construct a fake touch event with
141
+ * identifier 0, also abandoning traditional click handlers.
142
+ */
143
+export function receiveTouches(
144
+ eventTopLevelType: string,
145
+ touches: Array<Object>,
146
+ changedIndices: Array<number>,
147
+) {
148
+ var changedTouches = eventTopLevelType === 'topTouchEnd' ||
149
+ eventTopLevelType === 'topTouchCancel'
150
+ ? removeTouchesAtIndices(touches, changedIndices)
151
+ : touchSubsequence(touches, changedIndices);
152
166
- for (var jj = 0; jj < changedTouches.length; jj++) {
167
- var touch = changedTouches[jj];
168
- // Touch objects can fulfill the role of `DOM` `Event` objects if we set
169
- // the `changedTouches`/`touches`. This saves allocations.
170
- touch.changedTouches = changedTouches;
171
- touch.touches = touches;
172
- var nativeEvent = touch;
173
- var rootNodeID = null;
174
- var target = nativeEvent.target;
175
- if (target !== null && target !== undefined) {
176
- if (target < ReactNativeTagHandles.tagsStartAt) {
177
- if (__DEV__) {
178
- warning(
179
- false,
180
- 'A view is reporting that a touch occurred on tag zero.',
181
- );
182
- }
183
- } else {
184
- rootNodeID = target;
153
+ for (var jj = 0; jj < changedTouches.length; jj++) {
154
+ var touch = changedTouches[jj];
155
+ // Touch objects can fulfill the role of `DOM` `Event` objects if we set
156
+ // the `changedTouches`/`touches`. This saves allocations.
157
+ touch.changedTouches = changedTouches;
158
+ touch.touches = touches;
159
+ var nativeEvent = touch;
160
+ var rootNodeID = null;
161
+ var target = nativeEvent.target;
162
+ if (target !== null && target !== undefined) {
163
+ if (target < ReactNativeTagHandles.tagsStartAt) {
164
+ if (__DEV__) {
165
+ warning(
166
+ false,
167
+ 'A view is reporting that a touch occurred on tag zero.',
168
+ );
169
}
170
+ } else {
171
+ rootNodeID = target;
172
}
187
- ReactNativeEventEmitter._receiveRootNodeIDEvent(
188
- rootNodeID,
189
- eventTopLevelType,
190
- nativeEvent,
191
- );
173
}
193
- },
194
-};
195
-
196
-export default ReactNativeEventEmitter;
174
+ // $FlowFixMe Shouldn't we *not* call it if rootNodeID is null?
175
+ _receiveRootNodeIDEvent(rootNodeID, eventTopLevelType, nativeEvent);
176
+ }
177
+}