react 0.10.0 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/JSXTransformer.js +20344 -0
- package/dist/react-with-addons.js +20276 -0
- package/dist/react-with-addons.min.js +22 -0
- package/dist/react.js +18484 -0
- package/dist/react.min.js +21 -0
- package/lib/BeforeInputEventPlugin.js +222 -0
- package/lib/CSSPropertyOperations.js +3 -3
- package/lib/{ReactMountReady.js → CallbackQueue.js} +32 -24
- package/lib/ChangeEventPlugin.js +1 -1
- package/lib/CompositionEventPlugin.js +5 -1
- package/lib/DOMChildrenOperations.js +21 -14
- package/lib/DOMProperty.js +45 -17
- package/lib/DOMPropertyOperations.js +22 -10
- package/lib/DefaultEventPluginOrder.js +1 -0
- package/lib/EventConstants.js +1 -0
- package/lib/EventListener.js +5 -2
- package/lib/EventPluginHub.js +0 -5
- package/lib/EventPluginRegistry.js +6 -4
- package/lib/EventPluginUtils.js +11 -1
- package/lib/ExecutionEnvironment.js +8 -2
- package/lib/{DefaultDOMPropertyConfig.js → HTMLDOMPropertyConfig.js} +42 -49
- package/lib/LinkedValueUtils.js +21 -22
- package/lib/LocalEventTrapMixin.js +52 -0
- package/lib/React.js +57 -3
- package/lib/ReactBrowserComponentMixin.js +4 -0
- package/lib/{ReactEventEmitter.js → ReactBrowserEventEmitter.js} +115 -94
- package/lib/ReactCSSTransitionGroup.js +2 -0
- package/lib/ReactCSSTransitionGroupChild.js +2 -5
- package/lib/ReactChildren.js +31 -10
- package/lib/ReactComponent.js +88 -237
- package/lib/ReactComponentBrowserEnvironment.js +3 -2
- package/lib/ReactComponentWithPureRenderMixin.js +54 -0
- package/lib/ReactCompositeComponent.js +222 -384
- package/lib/ReactDOM.js +22 -18
- package/lib/ReactDOMComponent.js +26 -24
- package/lib/ReactDOMForm.js +5 -13
- package/lib/ReactDOMIDOperations.js +2 -31
- package/lib/ReactDOMImg.js +5 -14
- package/lib/ReactDOMSelect.js +16 -15
- package/lib/ReactDOMSelection.js +35 -10
- package/lib/ReactDOMTextarea.js +2 -4
- package/lib/ReactDefaultBatchingStrategy.js +3 -3
- package/lib/ReactDefaultInjection.js +18 -15
- package/lib/ReactDefaultPerf.js +28 -11
- package/lib/ReactDefaultPerfAnalysis.js +4 -0
- package/lib/ReactDescriptor.js +251 -0
- package/lib/ReactDescriptorValidator.js +283 -0
- package/lib/ReactEmptyComponent.js +78 -0
- package/lib/ReactEventEmitterMixin.js +1 -3
- package/lib/ReactEventListener.js +189 -0
- package/lib/ReactInjection.js +4 -2
- package/lib/ReactLink.js +24 -0
- package/lib/ReactMount.js +51 -19
- package/lib/ReactMultiChild.js +9 -11
- package/lib/ReactPropTransferer.js +44 -29
- package/lib/ReactPropTypes.js +226 -242
- package/lib/ReactPutListenerQueue.js +2 -2
- package/lib/ReactReconcileTransaction.js +14 -14
- package/lib/ReactServerRendering.js +5 -5
- package/lib/ReactServerRenderingTransaction.js +4 -5
- package/lib/ReactTestUtils.js +39 -21
- package/lib/ReactTextComponent.js +8 -22
- package/lib/ReactTransitionChildMapping.js +2 -2
- package/lib/ReactTransitionEvents.js +19 -0
- package/lib/ReactTransitionGroup.js +9 -6
- package/lib/ReactUpdates.js +139 -22
- package/lib/ReactWithAddons.js +5 -2
- package/lib/SVGDOMPropertyConfig.js +97 -0
- package/lib/SimpleEventPlugin.js +7 -1
- package/lib/SyntheticInputEvent.js +52 -0
- package/lib/SyntheticKeyboardEvent.js +33 -4
- package/lib/SyntheticMouseEvent.js +3 -0
- package/lib/SyntheticTouchEvent.js +4 -1
- package/lib/SyntheticUIEvent.js +24 -2
- package/lib/Transaction.js +0 -32
- package/lib/cloneWithProps.js +3 -1
- package/lib/createFullPageComponent.js +1 -1
- package/lib/dangerousStyleValue.js +11 -5
- package/lib/escapeTextForBrowser.js +2 -3
- package/lib/flattenChildren.js +9 -7
- package/lib/getEventKey.js +35 -5
- package/lib/getEventModifierState.js +52 -0
- package/lib/getMarkupWrap.js +2 -0
- package/lib/getTextContentAccessor.js +1 -1
- package/lib/hyphenate.js +3 -0
- package/lib/hyphenateStyleName.js +46 -0
- package/lib/instantiateReactComponent.js +13 -21
- package/lib/invariant.js +17 -19
- package/lib/{objMap.js → mapObject.js} +8 -3
- package/lib/mergeHelpers.js +11 -0
- package/lib/mergeInto.js +3 -2
- package/lib/onlyChild.js +3 -3
- package/lib/performance.js +33 -0
- package/lib/performanceNow.js +5 -14
- package/lib/setInnerHTML.js +85 -0
- package/lib/shouldUpdateReactComponent.js +12 -29
- package/lib/toArray.js +1 -1
- package/lib/traverseAllChildren.js +7 -4
- package/lib/update.js +57 -45
- package/package.json +4 -3
- package/lib/ReactEventTopLevelCallback.js +0 -149
- package/lib/createObjectFrom.js +0 -61
- package/lib/objMapKeyVal.js +0 -47
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2014 Facebook, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
* @providesModule ReactDescriptorValidator
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* ReactDescriptorValidator provides a wrapper around a descriptor factory
|
|
21
|
+
* which validates the props passed to the descriptor. This is intended to be
|
|
22
|
+
* used only in DEV and could be replaced by a static type checker for languages
|
|
23
|
+
* that support it.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
"use strict";
|
|
27
|
+
|
|
28
|
+
var ReactDescriptor = require("./ReactDescriptor");
|
|
29
|
+
var ReactPropTypeLocations = require("./ReactPropTypeLocations");
|
|
30
|
+
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
31
|
+
|
|
32
|
+
var monitorCodeUse = require("./monitorCodeUse");
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Warn if there's no key explicitly set on dynamic arrays of children or
|
|
36
|
+
* object keys are not valid. This allows us to keep track of children between
|
|
37
|
+
* updates.
|
|
38
|
+
*/
|
|
39
|
+
var ownerHasKeyUseWarning = {
|
|
40
|
+
'react_key_warning': {},
|
|
41
|
+
'react_numeric_key_warning': {}
|
|
42
|
+
};
|
|
43
|
+
var ownerHasMonitoredObjectMap = {};
|
|
44
|
+
|
|
45
|
+
var loggedTypeFailures = {};
|
|
46
|
+
|
|
47
|
+
var NUMERIC_PROPERTY_REGEX = /^\d+$/;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Gets the current owner's displayName for use in warnings.
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
* @return {?string} Display name or undefined
|
|
54
|
+
*/
|
|
55
|
+
function getCurrentOwnerDisplayName() {
|
|
56
|
+
var current = ReactCurrentOwner.current;
|
|
57
|
+
return current && current.constructor.displayName || undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Warn if the component doesn't have an explicit key assigned to it.
|
|
62
|
+
* This component is in an array. The array could grow and shrink or be
|
|
63
|
+
* reordered. All children that haven't already been validated are required to
|
|
64
|
+
* have a "key" property assigned to it.
|
|
65
|
+
*
|
|
66
|
+
* @internal
|
|
67
|
+
* @param {ReactComponent} component Component that requires a key.
|
|
68
|
+
* @param {*} parentType component's parent's type.
|
|
69
|
+
*/
|
|
70
|
+
function validateExplicitKey(component, parentType) {
|
|
71
|
+
if (component._store.validated || component.props.key != null) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
component._store.validated = true;
|
|
75
|
+
|
|
76
|
+
warnAndMonitorForKeyUse(
|
|
77
|
+
'react_key_warning',
|
|
78
|
+
'Each child in an array should have a unique "key" prop.',
|
|
79
|
+
component,
|
|
80
|
+
parentType
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Warn if the key is being defined as an object property but has an incorrect
|
|
86
|
+
* value.
|
|
87
|
+
*
|
|
88
|
+
* @internal
|
|
89
|
+
* @param {string} name Property name of the key.
|
|
90
|
+
* @param {ReactComponent} component Component that requires a key.
|
|
91
|
+
* @param {*} parentType component's parent's type.
|
|
92
|
+
*/
|
|
93
|
+
function validatePropertyKey(name, component, parentType) {
|
|
94
|
+
if (!NUMERIC_PROPERTY_REGEX.test(name)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
warnAndMonitorForKeyUse(
|
|
98
|
+
'react_numeric_key_warning',
|
|
99
|
+
'Child objects should have non-numeric keys so ordering is preserved.',
|
|
100
|
+
component,
|
|
101
|
+
parentType
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Shared warning and monitoring code for the key warnings.
|
|
107
|
+
*
|
|
108
|
+
* @internal
|
|
109
|
+
* @param {string} warningID The id used when logging.
|
|
110
|
+
* @param {string} message The base warning that gets output.
|
|
111
|
+
* @param {ReactComponent} component Component that requires a key.
|
|
112
|
+
* @param {*} parentType component's parent's type.
|
|
113
|
+
*/
|
|
114
|
+
function warnAndMonitorForKeyUse(warningID, message, component, parentType) {
|
|
115
|
+
var ownerName = getCurrentOwnerDisplayName();
|
|
116
|
+
var parentName = parentType.displayName;
|
|
117
|
+
|
|
118
|
+
var useName = ownerName || parentName;
|
|
119
|
+
var memoizer = ownerHasKeyUseWarning[warningID];
|
|
120
|
+
if (memoizer.hasOwnProperty(useName)) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
memoizer[useName] = true;
|
|
124
|
+
|
|
125
|
+
message += ownerName ?
|
|
126
|
+
(" Check the render method of " + ownerName + ".") :
|
|
127
|
+
(" Check the renderComponent call using <" + parentName + ">.");
|
|
128
|
+
|
|
129
|
+
// Usually the current owner is the offender, but if it accepts children as a
|
|
130
|
+
// property, it may be the creator of the child that's responsible for
|
|
131
|
+
// assigning it a key.
|
|
132
|
+
var childOwnerName = null;
|
|
133
|
+
if (component._owner && component._owner !== ReactCurrentOwner.current) {
|
|
134
|
+
// Name of the component that originally created this child.
|
|
135
|
+
childOwnerName = component._owner.constructor.displayName;
|
|
136
|
+
|
|
137
|
+
message += (" It was passed a child from " + childOwnerName + ".");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
message += ' See http://fb.me/react-warning-keys for more information.';
|
|
141
|
+
monitorCodeUse(warningID, {
|
|
142
|
+
component: useName,
|
|
143
|
+
componentOwner: childOwnerName
|
|
144
|
+
});
|
|
145
|
+
console.warn(message);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Log that we're using an object map. We're considering deprecating this
|
|
150
|
+
* feature and replace it with proper Map and ImmutableMap data structures.
|
|
151
|
+
*
|
|
152
|
+
* @internal
|
|
153
|
+
*/
|
|
154
|
+
function monitorUseOfObjectMap() {
|
|
155
|
+
var currentName = getCurrentOwnerDisplayName() || '';
|
|
156
|
+
if (ownerHasMonitoredObjectMap.hasOwnProperty(currentName)) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
ownerHasMonitoredObjectMap[currentName] = true;
|
|
160
|
+
monitorCodeUse('react_object_map_children');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Ensure that every component either is passed in a static location, in an
|
|
165
|
+
* array with an explicit keys property defined, or in an object literal
|
|
166
|
+
* with valid key property.
|
|
167
|
+
*
|
|
168
|
+
* @internal
|
|
169
|
+
* @param {*} component Statically passed child of any type.
|
|
170
|
+
* @param {*} parentType component's parent's type.
|
|
171
|
+
* @return {boolean}
|
|
172
|
+
*/
|
|
173
|
+
function validateChildKeys(component, parentType) {
|
|
174
|
+
if (Array.isArray(component)) {
|
|
175
|
+
for (var i = 0; i < component.length; i++) {
|
|
176
|
+
var child = component[i];
|
|
177
|
+
if (ReactDescriptor.isValidDescriptor(child)) {
|
|
178
|
+
validateExplicitKey(child, parentType);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
} else if (ReactDescriptor.isValidDescriptor(component)) {
|
|
182
|
+
// This component was passed in a valid location.
|
|
183
|
+
component._store.validated = true;
|
|
184
|
+
} else if (component && typeof component === 'object') {
|
|
185
|
+
monitorUseOfObjectMap();
|
|
186
|
+
for (var name in component) {
|
|
187
|
+
validatePropertyKey(name, component[name], parentType);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Assert that the props are valid
|
|
194
|
+
*
|
|
195
|
+
* @param {string} componentName Name of the component for error messages.
|
|
196
|
+
* @param {object} propTypes Map of prop name to a ReactPropType
|
|
197
|
+
* @param {object} props
|
|
198
|
+
* @param {string} location e.g. "prop", "context", "child context"
|
|
199
|
+
* @private
|
|
200
|
+
*/
|
|
201
|
+
function checkPropTypes(componentName, propTypes, props, location) {
|
|
202
|
+
for (var propName in propTypes) {
|
|
203
|
+
if (propTypes.hasOwnProperty(propName)) {
|
|
204
|
+
var error;
|
|
205
|
+
// Prop type validation may throw. In case they do, we don't want to
|
|
206
|
+
// fail the render phase where it didn't fail before. So we log it.
|
|
207
|
+
// After these have been cleaned up, we'll let them throw.
|
|
208
|
+
try {
|
|
209
|
+
error = propTypes[propName](props, propName, componentName, location);
|
|
210
|
+
} catch (ex) {
|
|
211
|
+
error = ex;
|
|
212
|
+
}
|
|
213
|
+
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
|
|
214
|
+
// Only monitor this failure once because there tends to be a lot of the
|
|
215
|
+
// same error.
|
|
216
|
+
loggedTypeFailures[error.message] = true;
|
|
217
|
+
// This will soon use the warning module
|
|
218
|
+
monitorCodeUse(
|
|
219
|
+
'react_failed_descriptor_type_check',
|
|
220
|
+
{ message: error.message }
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
var ReactDescriptorValidator = {
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Wraps a descriptor factory function in another function which validates
|
|
231
|
+
* the props and context of the descriptor and warns about any failed type
|
|
232
|
+
* checks.
|
|
233
|
+
*
|
|
234
|
+
* @param {function} factory The original descriptor factory
|
|
235
|
+
* @param {object?} propTypes A prop type definition set
|
|
236
|
+
* @param {object?} contextTypes A context type definition set
|
|
237
|
+
* @return {object} The component descriptor, which may be invalid.
|
|
238
|
+
* @private
|
|
239
|
+
*/
|
|
240
|
+
createFactory: function(factory, propTypes, contextTypes) {
|
|
241
|
+
var validatedFactory = function(props, children) {
|
|
242
|
+
var descriptor = factory.apply(this, arguments);
|
|
243
|
+
|
|
244
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
245
|
+
validateChildKeys(arguments[i], descriptor.type);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
var name = descriptor.type.displayName;
|
|
249
|
+
if (propTypes) {
|
|
250
|
+
checkPropTypes(
|
|
251
|
+
name,
|
|
252
|
+
propTypes,
|
|
253
|
+
descriptor.props,
|
|
254
|
+
ReactPropTypeLocations.prop
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
if (contextTypes) {
|
|
258
|
+
checkPropTypes(
|
|
259
|
+
name,
|
|
260
|
+
contextTypes,
|
|
261
|
+
descriptor._context,
|
|
262
|
+
ReactPropTypeLocations.context
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
return descriptor;
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
validatedFactory.prototype = factory.prototype;
|
|
269
|
+
validatedFactory.type = factory.type;
|
|
270
|
+
|
|
271
|
+
// Copy static properties
|
|
272
|
+
for (var key in factory) {
|
|
273
|
+
if (factory.hasOwnProperty(key)) {
|
|
274
|
+
validatedFactory[key] = factory[key];
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return validatedFactory;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
module.exports = ReactDescriptorValidator;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2014 Facebook, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
* @providesModule ReactEmptyComponent
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
"use strict";
|
|
20
|
+
|
|
21
|
+
var invariant = require("./invariant");
|
|
22
|
+
|
|
23
|
+
var component;
|
|
24
|
+
// This registry keeps track of the React IDs of the components that rendered to
|
|
25
|
+
// `null` (in reality a placeholder such as `noscript`)
|
|
26
|
+
var nullComponentIdsRegistry = {};
|
|
27
|
+
|
|
28
|
+
var ReactEmptyComponentInjection = {
|
|
29
|
+
injectEmptyComponent: function(emptyComponent) {
|
|
30
|
+
component = emptyComponent;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @return {ReactComponent} component The injected empty component.
|
|
36
|
+
*/
|
|
37
|
+
function getEmptyComponent() {
|
|
38
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
39
|
+
component,
|
|
40
|
+
'Trying to return null from a render, but no null placeholder component ' +
|
|
41
|
+
'was injected.'
|
|
42
|
+
) : invariant(component));
|
|
43
|
+
return component();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Mark the component as having rendered to null.
|
|
48
|
+
* @param {string} id Component's `_rootNodeID`.
|
|
49
|
+
*/
|
|
50
|
+
function registerNullComponentID(id) {
|
|
51
|
+
nullComponentIdsRegistry[id] = true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Unmark the component as having rendered to null: it renders to something now.
|
|
56
|
+
* @param {string} id Component's `_rootNodeID`.
|
|
57
|
+
*/
|
|
58
|
+
function deregisterNullComponentID(id) {
|
|
59
|
+
delete nullComponentIdsRegistry[id];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @param {string} id Component's `_rootNodeID`.
|
|
64
|
+
* @return {boolean} True if the component is rendered to null.
|
|
65
|
+
*/
|
|
66
|
+
function isNullComponentID(id) {
|
|
67
|
+
return nullComponentIdsRegistry[id];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var ReactEmptyComponent = {
|
|
71
|
+
deregisterNullComponentID: deregisterNullComponentID,
|
|
72
|
+
getEmptyComponent: getEmptyComponent,
|
|
73
|
+
injection: ReactEmptyComponentInjection,
|
|
74
|
+
isNullComponentID: isNullComponentID,
|
|
75
|
+
registerNullComponentID: registerNullComponentID
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
module.exports = ReactEmptyComponent;
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"use strict";
|
|
20
20
|
|
|
21
21
|
var EventPluginHub = require("./EventPluginHub");
|
|
22
|
-
var ReactUpdates = require("./ReactUpdates");
|
|
23
22
|
|
|
24
23
|
function runEventQueueInBatch(events) {
|
|
25
24
|
EventPluginHub.enqueueEvents(events);
|
|
@@ -49,8 +48,7 @@ var ReactEventEmitterMixin = {
|
|
|
49
48
|
nativeEvent
|
|
50
49
|
);
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
ReactUpdates.batchedUpdates(runEventQueueInBatch, events);
|
|
51
|
+
runEventQueueInBatch(events);
|
|
54
52
|
}
|
|
55
53
|
};
|
|
56
54
|
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013-2014 Facebook, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
* @providesModule ReactEventListener
|
|
17
|
+
* @typechecks static-only
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
"use strict";
|
|
21
|
+
|
|
22
|
+
var EventListener = require("./EventListener");
|
|
23
|
+
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
24
|
+
var PooledClass = require("./PooledClass");
|
|
25
|
+
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
26
|
+
var ReactMount = require("./ReactMount");
|
|
27
|
+
var ReactUpdates = require("./ReactUpdates");
|
|
28
|
+
|
|
29
|
+
var getEventTarget = require("./getEventTarget");
|
|
30
|
+
var getUnboundedScrollPosition = require("./getUnboundedScrollPosition");
|
|
31
|
+
var mixInto = require("./mixInto");
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Finds the parent React component of `node`.
|
|
35
|
+
*
|
|
36
|
+
* @param {*} node
|
|
37
|
+
* @return {?DOMEventTarget} Parent container, or `null` if the specified node
|
|
38
|
+
* is not nested.
|
|
39
|
+
*/
|
|
40
|
+
function findParent(node) {
|
|
41
|
+
// TODO: It may be a good idea to cache this to prevent unnecessary DOM
|
|
42
|
+
// traversal, but caching is difficult to do correctly without using a
|
|
43
|
+
// mutation observer to listen for all DOM changes.
|
|
44
|
+
var nodeID = ReactMount.getID(node);
|
|
45
|
+
var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);
|
|
46
|
+
var container = ReactMount.findReactContainerForID(rootID);
|
|
47
|
+
var parent = ReactMount.getFirstReactDOM(container);
|
|
48
|
+
return parent;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Used to store ancestor hierarchy in top level callback
|
|
52
|
+
function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) {
|
|
53
|
+
this.topLevelType = topLevelType;
|
|
54
|
+
this.nativeEvent = nativeEvent;
|
|
55
|
+
this.ancestors = [];
|
|
56
|
+
}
|
|
57
|
+
mixInto(TopLevelCallbackBookKeeping, {
|
|
58
|
+
destructor: function() {
|
|
59
|
+
this.topLevelType = null;
|
|
60
|
+
this.nativeEvent = null;
|
|
61
|
+
this.ancestors.length = 0;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
PooledClass.addPoolingTo(
|
|
65
|
+
TopLevelCallbackBookKeeping,
|
|
66
|
+
PooledClass.twoArgumentPooler
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
function handleTopLevelImpl(bookKeeping) {
|
|
70
|
+
var topLevelTarget = ReactMount.getFirstReactDOM(
|
|
71
|
+
getEventTarget(bookKeeping.nativeEvent)
|
|
72
|
+
) || window;
|
|
73
|
+
|
|
74
|
+
// Loop through the hierarchy, in case there's any nested components.
|
|
75
|
+
// It's important that we build the array of ancestors before calling any
|
|
76
|
+
// event handlers, because event handlers can modify the DOM, leading to
|
|
77
|
+
// inconsistencies with ReactMount's node cache. See #1105.
|
|
78
|
+
var ancestor = topLevelTarget;
|
|
79
|
+
while (ancestor) {
|
|
80
|
+
bookKeeping.ancestors.push(ancestor);
|
|
81
|
+
ancestor = findParent(ancestor);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) {
|
|
85
|
+
topLevelTarget = bookKeeping.ancestors[i];
|
|
86
|
+
var topLevelTargetID = ReactMount.getID(topLevelTarget) || '';
|
|
87
|
+
ReactEventListener._handleTopLevel(
|
|
88
|
+
bookKeeping.topLevelType,
|
|
89
|
+
topLevelTarget,
|
|
90
|
+
topLevelTargetID,
|
|
91
|
+
bookKeeping.nativeEvent
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function scrollValueMonitor(cb) {
|
|
97
|
+
var scrollPosition = getUnboundedScrollPosition(window);
|
|
98
|
+
cb(scrollPosition);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
var ReactEventListener = {
|
|
102
|
+
_enabled: true,
|
|
103
|
+
_handleTopLevel: null,
|
|
104
|
+
|
|
105
|
+
WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null,
|
|
106
|
+
|
|
107
|
+
setHandleTopLevel: function(handleTopLevel) {
|
|
108
|
+
ReactEventListener._handleTopLevel = handleTopLevel;
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
setEnabled: function(enabled) {
|
|
112
|
+
ReactEventListener._enabled = !!enabled;
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
isEnabled: function() {
|
|
116
|
+
return ReactEventListener._enabled;
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Traps top-level events by using event bubbling.
|
|
122
|
+
*
|
|
123
|
+
* @param {string} topLevelType Record from `EventConstants`.
|
|
124
|
+
* @param {string} handlerBaseName Event name (e.g. "click").
|
|
125
|
+
* @param {object} handle Element on which to attach listener.
|
|
126
|
+
* @return {object} An object with a remove function which will forcefully
|
|
127
|
+
* remove the listener.
|
|
128
|
+
* @internal
|
|
129
|
+
*/
|
|
130
|
+
trapBubbledEvent: function(topLevelType, handlerBaseName, handle) {
|
|
131
|
+
var element = handle;
|
|
132
|
+
if (!element) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
return EventListener.listen(
|
|
136
|
+
element,
|
|
137
|
+
handlerBaseName,
|
|
138
|
+
ReactEventListener.dispatchEvent.bind(null, topLevelType)
|
|
139
|
+
);
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Traps a top-level event by using event capturing.
|
|
144
|
+
*
|
|
145
|
+
* @param {string} topLevelType Record from `EventConstants`.
|
|
146
|
+
* @param {string} handlerBaseName Event name (e.g. "click").
|
|
147
|
+
* @param {object} handle Element on which to attach listener.
|
|
148
|
+
* @return {object} An object with a remove function which will forcefully
|
|
149
|
+
* remove the listener.
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
trapCapturedEvent: function(topLevelType, handlerBaseName, handle) {
|
|
153
|
+
var element = handle;
|
|
154
|
+
if (!element) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
return EventListener.capture(
|
|
158
|
+
element,
|
|
159
|
+
handlerBaseName,
|
|
160
|
+
ReactEventListener.dispatchEvent.bind(null, topLevelType)
|
|
161
|
+
);
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
monitorScrollValue: function(refresh) {
|
|
165
|
+
var callback = scrollValueMonitor.bind(null, refresh);
|
|
166
|
+
EventListener.listen(window, 'scroll', callback);
|
|
167
|
+
EventListener.listen(window, 'resize', callback);
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
dispatchEvent: function(topLevelType, nativeEvent) {
|
|
171
|
+
if (!ReactEventListener._enabled) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
var bookKeeping = TopLevelCallbackBookKeeping.getPooled(
|
|
176
|
+
topLevelType,
|
|
177
|
+
nativeEvent
|
|
178
|
+
);
|
|
179
|
+
try {
|
|
180
|
+
// Event queue being processed in the same cycle allows
|
|
181
|
+
// `preventDefault`.
|
|
182
|
+
ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
|
|
183
|
+
} finally {
|
|
184
|
+
TopLevelCallbackBookKeeping.release(bookKeeping);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
module.exports = ReactEventListener;
|