1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | 'use strict';
|
12 |
|
13 | var _assign = require('object-assign');
|
14 |
|
15 | var PooledClass = require('./PooledClass');
|
16 |
|
17 | var emptyFunction = require('fbjs/lib/emptyFunction');
|
18 | var warning = require('fbjs/lib/warning');
|
19 |
|
20 | var didWarnForAddedNewProperty = false;
|
21 | var isProxySupported = typeof Proxy === 'function';
|
22 |
|
23 | var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances'];
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | var EventInterface = {
|
30 | type: null,
|
31 | target: null,
|
32 |
|
33 | currentTarget: emptyFunction.thatReturnsNull,
|
34 | eventPhase: null,
|
35 | bubbles: null,
|
36 | cancelable: null,
|
37 | timeStamp: function (event) {
|
38 | return event.timeStamp || Date.now();
|
39 | },
|
40 | defaultPrevented: null,
|
41 | isTrusted: null
|
42 | };
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 | function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
|
63 | if (process.env.NODE_ENV !== 'production') {
|
64 |
|
65 | delete this.nativeEvent;
|
66 | delete this.preventDefault;
|
67 | delete this.stopPropagation;
|
68 | }
|
69 |
|
70 | this.dispatchConfig = dispatchConfig;
|
71 | this._targetInst = targetInst;
|
72 | this.nativeEvent = nativeEvent;
|
73 |
|
74 | var Interface = this.constructor.Interface;
|
75 | for (var propName in Interface) {
|
76 | if (!Interface.hasOwnProperty(propName)) {
|
77 | continue;
|
78 | }
|
79 | if (process.env.NODE_ENV !== 'production') {
|
80 | delete this[propName];
|
81 | }
|
82 | var normalize = Interface[propName];
|
83 | if (normalize) {
|
84 | this[propName] = normalize(nativeEvent);
|
85 | } else {
|
86 | if (propName === 'target') {
|
87 | this.target = nativeEventTarget;
|
88 | } else {
|
89 | this[propName] = nativeEvent[propName];
|
90 | }
|
91 | }
|
92 | }
|
93 |
|
94 | var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
|
95 | if (defaultPrevented) {
|
96 | this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
|
97 | } else {
|
98 | this.isDefaultPrevented = emptyFunction.thatReturnsFalse;
|
99 | }
|
100 | this.isPropagationStopped = emptyFunction.thatReturnsFalse;
|
101 | return this;
|
102 | }
|
103 |
|
104 | _assign(SyntheticEvent.prototype, {
|
105 | preventDefault: function () {
|
106 | this.defaultPrevented = true;
|
107 | var event = this.nativeEvent;
|
108 | if (!event) {
|
109 | return;
|
110 | }
|
111 |
|
112 | if (event.preventDefault) {
|
113 | event.preventDefault();
|
114 |
|
115 | } else if (typeof event.returnValue !== 'unknown') {
|
116 | event.returnValue = false;
|
117 | }
|
118 | this.isDefaultPrevented = emptyFunction.thatReturnsTrue;
|
119 | },
|
120 |
|
121 | stopPropagation: function () {
|
122 | var event = this.nativeEvent;
|
123 | if (!event) {
|
124 | return;
|
125 | }
|
126 |
|
127 | if (event.stopPropagation) {
|
128 | event.stopPropagation();
|
129 |
|
130 | } else if (typeof event.cancelBubble !== 'unknown') {
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 | event.cancelBubble = true;
|
137 | }
|
138 |
|
139 | this.isPropagationStopped = emptyFunction.thatReturnsTrue;
|
140 | },
|
141 |
|
142 | |
143 |
|
144 |
|
145 |
|
146 |
|
147 | persist: function () {
|
148 | this.isPersistent = emptyFunction.thatReturnsTrue;
|
149 | },
|
150 |
|
151 | |
152 |
|
153 |
|
154 |
|
155 |
|
156 | isPersistent: emptyFunction.thatReturnsFalse,
|
157 |
|
158 | |
159 |
|
160 |
|
161 | destructor: function () {
|
162 | var Interface = this.constructor.Interface;
|
163 | for (var propName in Interface) {
|
164 | if (process.env.NODE_ENV !== 'production') {
|
165 | Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
|
166 | } else {
|
167 | this[propName] = null;
|
168 | }
|
169 | }
|
170 | for (var i = 0; i < shouldBeReleasedProperties.length; i++) {
|
171 | this[shouldBeReleasedProperties[i]] = null;
|
172 | }
|
173 | if (process.env.NODE_ENV !== 'production') {
|
174 | Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
|
175 | Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction));
|
176 | Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction));
|
177 | }
|
178 | }
|
179 | });
|
180 |
|
181 | SyntheticEvent.Interface = EventInterface;
|
182 |
|
183 | if (process.env.NODE_ENV !== 'production') {
|
184 | if (isProxySupported) {
|
185 |
|
186 | SyntheticEvent = new Proxy(SyntheticEvent, {
|
187 | construct: function (target, args) {
|
188 | return this.apply(target, Object.create(target.prototype), args);
|
189 | },
|
190 | apply: function (constructor, that, args) {
|
191 | return new Proxy(constructor.apply(that, args), {
|
192 | set: function (target, prop, value) {
|
193 | if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) {
|
194 | process.env.NODE_ENV !== 'production' ? warning(didWarnForAddedNewProperty || target.isPersistent(), "This synthetic event is reused for performance reasons. If you're " + "seeing this, you're adding a new property in the synthetic event object. " + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.') : void 0;
|
195 | didWarnForAddedNewProperty = true;
|
196 | }
|
197 | target[prop] = value;
|
198 | return true;
|
199 | }
|
200 | });
|
201 | }
|
202 | });
|
203 |
|
204 | }
|
205 | }
|
206 |
|
207 |
|
208 |
|
209 |
|
210 |
|
211 |
|
212 | SyntheticEvent.augmentClass = function (Class, Interface) {
|
213 | var Super = this;
|
214 |
|
215 | var E = function () {};
|
216 | E.prototype = Super.prototype;
|
217 | var prototype = new E();
|
218 |
|
219 | _assign(prototype, Class.prototype);
|
220 | Class.prototype = prototype;
|
221 | Class.prototype.constructor = Class;
|
222 |
|
223 | Class.Interface = _assign({}, Super.Interface, Interface);
|
224 | Class.augmentClass = Super.augmentClass;
|
225 |
|
226 | PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler);
|
227 | };
|
228 |
|
229 | PooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler);
|
230 |
|
231 | module.exports = SyntheticEvent;
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 | function getPooledWarningPropertyDefinition(propName, getVal) {
|
241 | var isFunction = typeof getVal === 'function';
|
242 | return {
|
243 | configurable: true,
|
244 | set: set,
|
245 | get: get
|
246 | };
|
247 |
|
248 | function set(val) {
|
249 | var action = isFunction ? 'setting the method' : 'setting the property';
|
250 | warn(action, 'This is effectively a no-op');
|
251 | return val;
|
252 | }
|
253 |
|
254 | function get() {
|
255 | var action = isFunction ? 'accessing the method' : 'accessing the property';
|
256 | var result = isFunction ? 'This is a no-op function' : 'This is set to null';
|
257 | warn(action, result);
|
258 | return getVal;
|
259 | }
|
260 |
|
261 | function warn(action, result) {
|
262 | var warningCondition = false;
|
263 | process.env.NODE_ENV !== 'production' ? warning(warningCondition, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;
|
264 | }
|
265 | } |
\ | No newline at end of file |