@@ -28,8 +28,8 @@ export type EventConfig = {
28
28
function attachNativeEvent (
29
29
viewRef : any ,
30
30
eventName : string ,
31
- argMapping : Array < ?Mapping > ,
32
- ) : { | detach : ( ) => void | } {
31
+ argMapping : $ReadOnlyArray < ?Mapping > ,
32
+ ) : { detach: ( ) => void } {
33
33
// Find animated values in `argMapping` and create an array representing their
34
34
// key path inside the `nativeEvent` object. Ex.: ['contentOffset', 'x'].
35
35
const eventMappings = [ ] ;
@@ -58,7 +58,6 @@ function attachNativeEvent(
58
58
traverse ( argMapping [ 0 ] . nativeEvent , [ ] ) ;
59
59
60
60
const viewTag = ReactNative . findNodeHandle ( viewRef ) ;
61
-
62
61
if ( viewTag != null ) {
63
62
eventMappings . forEach ( mapping => {
64
63
NativeAnimatedHelper . API . addAnimatedEventToView (
@@ -84,14 +83,59 @@ function attachNativeEvent(
84
83
} ;
85
84
}
86
85
86
+ function validateMapping ( argMapping , args ) {
87
+ const validate = ( recMapping , recEvt , key ) => {
88
+ if ( recMapping instanceof AnimatedValue ) {
89
+ invariant (
90
+ typeof recEvt === 'number' ,
91
+ 'Bad mapping of event key ' +
92
+ key +
93
+ ', should be number but got ' +
94
+ typeof recEvt ,
95
+ ) ;
96
+ return ;
97
+ }
98
+ if ( typeof recEvt === 'number' ) {
99
+ invariant (
100
+ recMapping instanceof AnimatedValue ,
101
+ 'Bad mapping of type ' +
102
+ typeof recMapping +
103
+ ' for key ' +
104
+ key +
105
+ ', event value must map to AnimatedValue' ,
106
+ ) ;
107
+ return ;
108
+ }
109
+ invariant (
110
+ typeof recMapping === 'object' ,
111
+ 'Bad mapping of type ' + typeof recMapping + ' for key ' + key ,
112
+ ) ;
113
+ invariant (
114
+ typeof recEvt === 'object' ,
115
+ 'Bad event of type ' + typeof recEvt + ' for key ' + key ,
116
+ ) ;
117
+ for ( const mappingKey in recMapping ) {
118
+ validate ( recMapping [ mappingKey ] , recEvt [ mappingKey ] , mappingKey ) ;
119
+ }
120
+ } ;
121
+
122
+ invariant (
123
+ args . length >= argMapping . length ,
124
+ 'Event has less arguments than mapping' ,
125
+ ) ;
126
+ argMapping . forEach ( ( mapping , idx ) => {
127
+ validate ( mapping , args [ idx ] , 'arg' + idx ) ;
128
+ } ) ;
129
+ }
130
+
87
131
class AnimatedEvent {
88
- _argMapping : Array < ?Mapping > ;
132
+ _argMapping : $ReadOnlyArray < ?Mapping > ;
89
133
_listeners : Array < Function > = [ ] ;
90
134
_callListeners : Function ;
91
135
_attachedEvent : ?{ detach : ( ) => void , ...} ;
92
136
__isNative : boolean ;
93
137
94
- constructor ( argMapping : Array < ?Mapping > , config : EventConfig ) {
138
+ constructor ( argMapping : $ReadOnlyArray < ?Mapping > , config : EventConfig ) {
95
139
this . _argMapping = argMapping ;
96
140
97
141
if ( config == null ) {
@@ -105,10 +149,6 @@ class AnimatedEvent {
105
149
this . _callListeners = this . _callListeners . bind ( this ) ;
106
150
this . _attachedEvent = null ;
107
151
this . __isNative = shouldUseNativeDriver ( config ) ;
108
-
109
- if ( __DEV__ ) {
110
- this . _validateMapping ( ) ;
111
- }
112
152
}
113
153
114
154
__addListener ( callback : Function ) : void {
@@ -143,62 +183,49 @@ class AnimatedEvent {
143
183
144
184
__getHandler ( ) : any | ( ( ...args : any ) => void ) {
145
185
if ( this . __isNative ) {
146
- return this . _callListeners ;
186
+ if ( __DEV__ ) {
187
+ let validatedMapping = false ;
188
+ return ( ...args : any ) => {
189
+ if ( ! validatedMapping ) {
190
+ validateMapping ( this . _argMapping , args ) ;
191
+ validatedMapping = true ;
192
+ }
193
+ this . _callListeners ( ...args ) ;
194
+ } ;
195
+ } else {
196
+ return this . _callListeners ;
197
+ }
147
198
}
148
199
200
+ let validatedMapping = false ;
149
201
return ( ...args : any ) => {
202
+ if ( __DEV__ && ! validatedMapping ) {
203
+ validateMapping ( this . _argMapping , args ) ;
204
+ validatedMapping = true ;
205
+ }
206
+
150
207
const traverse = ( recMapping , recEvt , key ) => {
151
- if ( typeof recEvt === 'number' && recMapping instanceof AnimatedValue ) {
152
- recMapping . setValue ( recEvt ) ;
208
+ if ( recMapping instanceof AnimatedValue ) {
209
+ if ( typeof recEvt === 'number' ) {
210
+ recMapping . setValue ( recEvt ) ;
211
+ }
153
212
} else if ( typeof recMapping === 'object' ) {
154
213
for ( const mappingKey in recMapping ) {
155
- /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This
156
- * comment suppresses an error when upgrading Flow's support for
157
- * React. To see the error delete this comment and run Flow. */
158
214
traverse ( recMapping [ mappingKey ] , recEvt [ mappingKey ] , mappingKey ) ;
159
215
}
160
216
}
161
217
} ;
218
+ this . _argMapping . forEach ( ( mapping , idx ) => {
219
+ traverse ( mapping , args [ idx ] , 'arg' + idx ) ;
220
+ } ) ;
162
221
163
- if ( ! this . __isNative ) {
164
- this . _argMapping . forEach ( ( mapping , idx ) => {
165
- traverse ( mapping , args [ idx ] , 'arg' + idx ) ;
166
- } ) ;
167
- }
168
222
this . _callListeners ( ...args ) ;
169
223
} ;
170
224
}
171
225
172
226
_callListeners ( ...args : any ) {
173
227
this . _listeners . forEach ( listener => listener ( ...args ) ) ;
174
228
}
175
-
176
- _validateMapping ( ) {
177
- const traverse = ( recMapping , recEvt , key ) = > {
178
- if ( typeof recEvt === 'number' ) {
179
- invariant (
180
- recMapping instanceof AnimatedValue ,
181
- 'Bad mapping of type ' +
182
- typeof recMapping +
183
- ' for key ' +
184
- key +
185
- ', event value must map to AnimatedValue' ,
186
- ) ;
187
- return ;
188
- }
189
- invariant (
190
- typeof recMapping === 'object' ,
191
- 'Bad mapping of type ' + typeof recMapping + ' for key ' + key ,
192
- ) ;
193
- invariant (
194
- typeof recEvt === 'object' ,
195
- 'Bad event of type ' + typeof recEvt + ' for key ' + key ,
196
- ) ;
197
- for ( const mappingKey in recMapping ) {
198
- traverse ( recMapping [ mappingKey ] , recEvt [ mappingKey ] , mappingKey ) ;
199
- }
200
- } ;
201
- }
202
229
}
203
230
204
231
module . exports = { AnimatedEvent, attachNativeEvent} ;
0 commit comments