@@ -17,6 +17,19 @@ var assign = require('Object.assign');
17
17
var emptyFunction = require ( 'emptyFunction' ) ;
18
18
var warning = require ( 'warning' ) ;
19
19
20
+ var didWarnForAddedNewProperty = false ;
21
+ var isProxySupported = typeof Proxy === 'function' ;
22
+
23
+ var shouldBeReleasedProperties = [
24
+ 'dispatchConfig' ,
25
+ '_targetInst' ,
26
+ 'nativeEvent' ,
27
+ 'isDefaultPrevented' ,
28
+ 'isPropagationStopped' ,
29
+ '_dispatchListeners' ,
30
+ '_dispatchInstances' ,
31
+ ] ;
32
+
20
33
/**
21
34
* @interface Event
22
35
* @see http://www.w3.org/TR/DOM-Level-3-Events/
@@ -57,7 +70,7 @@ var EventInterface = {
57
70
function SyntheticEvent ( dispatchConfig , targetInst , nativeEvent , nativeEventTarget ) {
58
71
if ( __DEV__ ) {
59
72
// these have a getter/setter for warnings
60
- delete this . nativeEvent ;
73
+ delete this . nativeEvent ;
61
74
delete this . preventDefault ;
62
75
delete this . stopPropagation ;
63
76
}
@@ -95,6 +108,7 @@ function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarg
95
108
this . isDefaultPrevented = emptyFunction . thatReturnsFalse ;
96
109
}
97
110
this . isPropagationStopped = emptyFunction . thatReturnsFalse ;
111
+ return this ;
98
112
}
99
113
100
114
assign ( SyntheticEvent . prototype , {
@@ -156,22 +170,52 @@ assign(SyntheticEvent.prototype, {
156
170
this [ propName ] = null ;
157
171
}
158
172
}
173
+ for ( var i = 0 ; i < shouldBeReleasedProperties . length ; i ++ ) {
174
+ this [ shouldBeReleasedProperties [ i ] ] = null ;
175
+ }
159
176
if ( __DEV__ ) {
160
177
var noop = require ( 'emptyFunction' ) ;
161
178
Object . defineProperty ( this , 'nativeEvent' , getPooledWarningPropertyDefinition ( 'nativeEvent' , null ) ) ;
162
179
Object . defineProperty ( this , 'preventDefault' , getPooledWarningPropertyDefinition ( 'preventDefault' , noop ) ) ;
163
180
Object . defineProperty ( this , 'stopPropagation' , getPooledWarningPropertyDefinition ( 'stopPropagation' , noop ) ) ;
164
- } else {
165
- this . nativeEvent = null ;
166
181
}
167
- this . dispatchConfig = null ;
168
- this . _targetInst = null ;
169
182
} ,
170
183
171
184
} ) ;
172
185
173
186
SyntheticEvent . Interface = EventInterface ;
174
187
188
+ if ( __DEV__ ) {
189
+ if ( isProxySupported ) {
190
+ /*eslint-disable no-func-assign */
191
+ SyntheticEvent = new Proxy ( SyntheticEvent , {
192
+ construct : function ( target , args ) {
193
+ return this . apply ( target , { } , args ) ;
194
+ } ,
195
+ apply : function ( constructor , that , args ) {
196
+ return new Proxy ( constructor . apply ( that , args ) , {
197
+ set : function ( target , prop , value ) {
198
+ if ( prop !== 'isPersistent' &&
199
+ ! target . constructor . Interface . hasOwnProperty ( prop ) &&
200
+ shouldBeReleasedProperties . indexOf ( prop ) === - 1 ) {
201
+ warning (
202
+ didWarnForAddedNewProperty || target . isPersistent ( ) ,
203
+ 'This synthetic event is reused for performance reasons. If you\'re ' +
204
+ 'seeing this, you\'re adding a new property in the synthetic event object. ' +
205
+ 'The property is never released. See ' +
206
+ 'https://fb.me/react-event-pooling for more information.'
207
+ ) ;
208
+ didWarnForAddedNewProperty = true ;
209
+ }
210
+ target [ prop ] = value ;
211
+ return true ;
212
+ } ,
213
+ } ) ;
214
+ } ,
215
+ } ) ;
216
+ /*eslint-enable no-func-assign */
217
+ }
218
+ }
175
219
/**
176
220
* Helper to reduce boilerplate when creating subclasses.
177
221
*
0 commit comments