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
|
@@ -25,6 +25,8 @@ var ReactTransitionGroup = require("./ReactTransitionGroup");
|
|
|
25
25
|
var ReactCSSTransitionGroupChild = require("./ReactCSSTransitionGroupChild");
|
|
26
26
|
|
|
27
27
|
var ReactCSSTransitionGroup = React.createClass({
|
|
28
|
+
displayName: 'ReactCSSTransitionGroup',
|
|
29
|
+
|
|
28
30
|
propTypes: {
|
|
29
31
|
transitionName: React.PropTypes.string.isRequired,
|
|
30
32
|
transitionEnter: React.PropTypes.bool,
|
|
@@ -48,6 +48,8 @@ if ("production" !== process.env.NODE_ENV) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
var ReactCSSTransitionGroupChild = React.createClass({
|
|
51
|
+
displayName: 'ReactCSSTransitionGroupChild',
|
|
52
|
+
|
|
51
53
|
transition: function(animationType, finishCallback) {
|
|
52
54
|
var node = this.getDOMNode();
|
|
53
55
|
var className = this.props.name + '-' + animationType;
|
|
@@ -84,11 +86,6 @@ var ReactCSSTransitionGroupChild = React.createClass({
|
|
|
84
86
|
queueClass: function(className) {
|
|
85
87
|
this.classNameQueue.push(className);
|
|
86
88
|
|
|
87
|
-
if (this.props.runNextTick) {
|
|
88
|
-
this.props.runNextTick(this.flushClassNameQueue);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
89
|
if (!this.timeout) {
|
|
93
90
|
this.timeout = setTimeout(this.flushClassNameQueue, TICK);
|
|
94
91
|
}
|
package/lib/ReactChildren.js
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
|
|
21
21
|
var PooledClass = require("./PooledClass");
|
|
22
22
|
|
|
23
|
-
var invariant = require("./invariant");
|
|
24
23
|
var traverseAllChildren = require("./traverseAllChildren");
|
|
24
|
+
var warning = require("./warning");
|
|
25
25
|
|
|
26
26
|
var twoArgumentPooler = PooledClass.twoArgumentPooler;
|
|
27
27
|
var threeArgumentPooler = PooledClass.threeArgumentPooler;
|
|
@@ -86,16 +86,21 @@ PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler);
|
|
|
86
86
|
function mapSingleChildIntoContext(traverseContext, child, name, i) {
|
|
87
87
|
var mapBookKeeping = traverseContext;
|
|
88
88
|
var mapResult = mapBookKeeping.mapResult;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
!mapResult.hasOwnProperty(name),
|
|
89
|
+
|
|
90
|
+
var keyUnique = !mapResult.hasOwnProperty(name);
|
|
91
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
92
|
+
keyUnique,
|
|
94
93
|
'ReactChildren.map(...): Encountered two children with the same key, ' +
|
|
95
|
-
'`%s`.
|
|
94
|
+
'`%s`. Child keys must be unique; when two children share a key, only ' +
|
|
95
|
+
'the first child will be used.',
|
|
96
96
|
name
|
|
97
|
-
) :
|
|
98
|
-
|
|
97
|
+
) : null);
|
|
98
|
+
|
|
99
|
+
if (keyUnique) {
|
|
100
|
+
var mappedChild =
|
|
101
|
+
mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);
|
|
102
|
+
mapResult[name] = mappedChild;
|
|
103
|
+
}
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
/**
|
|
@@ -124,9 +129,25 @@ function mapChildren(children, func, context) {
|
|
|
124
129
|
return mapResult;
|
|
125
130
|
}
|
|
126
131
|
|
|
132
|
+
function forEachSingleChildDummy(traverseContext, child, name, i) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Count the number of children that are typically specified as
|
|
138
|
+
* `props.children`.
|
|
139
|
+
*
|
|
140
|
+
* @param {?*} children Children tree container.
|
|
141
|
+
* @return {number} The number of children.
|
|
142
|
+
*/
|
|
143
|
+
function countChildren(children, context) {
|
|
144
|
+
return traverseAllChildren(children, forEachSingleChildDummy, null);
|
|
145
|
+
}
|
|
146
|
+
|
|
127
147
|
var ReactChildren = {
|
|
128
148
|
forEach: forEachChildren,
|
|
129
|
-
map: mapChildren
|
|
149
|
+
map: mapChildren,
|
|
150
|
+
count: countChildren
|
|
130
151
|
};
|
|
131
152
|
|
|
132
153
|
module.exports = ReactChildren;
|
package/lib/ReactComponent.js
CHANGED
|
@@ -18,14 +18,13 @@
|
|
|
18
18
|
|
|
19
19
|
"use strict";
|
|
20
20
|
|
|
21
|
-
var
|
|
21
|
+
var ReactDescriptor = require("./ReactDescriptor");
|
|
22
22
|
var ReactOwner = require("./ReactOwner");
|
|
23
23
|
var ReactUpdates = require("./ReactUpdates");
|
|
24
24
|
|
|
25
25
|
var invariant = require("./invariant");
|
|
26
26
|
var keyMirror = require("./keyMirror");
|
|
27
27
|
var merge = require("./merge");
|
|
28
|
-
var monitorCodeUse = require("./monitorCodeUse");
|
|
29
28
|
|
|
30
29
|
/**
|
|
31
30
|
* Every React component is in one of these life cycles.
|
|
@@ -42,18 +41,6 @@ var ComponentLifeCycle = keyMirror({
|
|
|
42
41
|
UNMOUNTED: null
|
|
43
42
|
});
|
|
44
43
|
|
|
45
|
-
/**
|
|
46
|
-
* Warn if there's no key explicitly set on dynamic arrays of children or
|
|
47
|
-
* object keys are not valid. This allows us to keep track of children between
|
|
48
|
-
* updates.
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
var ownerHasExplicitKeyWarning = {};
|
|
52
|
-
var ownerHasPropertyWarning = {};
|
|
53
|
-
var ownerHasMonitoredObjectMap = {};
|
|
54
|
-
|
|
55
|
-
var NUMERIC_PROPERTY_REGEX = /^\d+$/;
|
|
56
|
-
|
|
57
44
|
var injected = false;
|
|
58
45
|
|
|
59
46
|
/**
|
|
@@ -76,130 +63,6 @@ var unmountIDFromEnvironment = null;
|
|
|
76
63
|
*/
|
|
77
64
|
var mountImageIntoNode = null;
|
|
78
65
|
|
|
79
|
-
/**
|
|
80
|
-
* Warn if the component doesn't have an explicit key assigned to it.
|
|
81
|
-
* This component is in an array. The array could grow and shrink or be
|
|
82
|
-
* reordered. All children that haven't already been validated are required to
|
|
83
|
-
* have a "key" property assigned to it.
|
|
84
|
-
*
|
|
85
|
-
* @internal
|
|
86
|
-
* @param {ReactComponent} component Component that requires a key.
|
|
87
|
-
*/
|
|
88
|
-
function validateExplicitKey(component) {
|
|
89
|
-
if (component.__keyValidated__ || component.props.key != null) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
component.__keyValidated__ = true;
|
|
93
|
-
|
|
94
|
-
// We can't provide friendly warnings for top level components.
|
|
95
|
-
if (!ReactCurrentOwner.current) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Name of the component whose render method tried to pass children.
|
|
100
|
-
var currentName = ReactCurrentOwner.current.constructor.displayName;
|
|
101
|
-
if (ownerHasExplicitKeyWarning.hasOwnProperty(currentName)) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
ownerHasExplicitKeyWarning[currentName] = true;
|
|
105
|
-
|
|
106
|
-
var message = 'Each child in an array should have a unique "key" prop. ' +
|
|
107
|
-
'Check the render method of ' + currentName + '.';
|
|
108
|
-
|
|
109
|
-
var childOwnerName = null;
|
|
110
|
-
if (!component.isOwnedBy(ReactCurrentOwner.current)) {
|
|
111
|
-
// Name of the component that originally created this child.
|
|
112
|
-
childOwnerName =
|
|
113
|
-
component._owner &&
|
|
114
|
-
component._owner.constructor.displayName;
|
|
115
|
-
|
|
116
|
-
// Usually the current owner is the offender, but if it accepts
|
|
117
|
-
// children as a property, it may be the creator of the child that's
|
|
118
|
-
// responsible for assigning it a key.
|
|
119
|
-
message += ' It was passed a child from ' + childOwnerName + '.';
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
message += ' See http://fb.me/react-warning-keys for more information.';
|
|
123
|
-
monitorCodeUse('react_key_warning', {
|
|
124
|
-
component: currentName,
|
|
125
|
-
componentOwner: childOwnerName
|
|
126
|
-
});
|
|
127
|
-
console.warn(message);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Warn if the key is being defined as an object property but has an incorrect
|
|
132
|
-
* value.
|
|
133
|
-
*
|
|
134
|
-
* @internal
|
|
135
|
-
* @param {string} name Property name of the key.
|
|
136
|
-
* @param {ReactComponent} component Component that requires a key.
|
|
137
|
-
*/
|
|
138
|
-
function validatePropertyKey(name) {
|
|
139
|
-
if (NUMERIC_PROPERTY_REGEX.test(name)) {
|
|
140
|
-
// Name of the component whose render method tried to pass children.
|
|
141
|
-
var currentName = ReactCurrentOwner.current.constructor.displayName;
|
|
142
|
-
if (ownerHasPropertyWarning.hasOwnProperty(currentName)) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
ownerHasPropertyWarning[currentName] = true;
|
|
146
|
-
|
|
147
|
-
monitorCodeUse('react_numeric_key_warning');
|
|
148
|
-
console.warn(
|
|
149
|
-
'Child objects should have non-numeric keys so ordering is preserved. ' +
|
|
150
|
-
'Check the render method of ' + currentName + '. ' +
|
|
151
|
-
'See http://fb.me/react-warning-keys for more information.'
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Log that we're using an object map. We're considering deprecating this
|
|
158
|
-
* feature and replace it with proper Map and ImmutableMap data structures.
|
|
159
|
-
*
|
|
160
|
-
* @internal
|
|
161
|
-
*/
|
|
162
|
-
function monitorUseOfObjectMap() {
|
|
163
|
-
// Name of the component whose render method tried to pass children.
|
|
164
|
-
// We only use this to avoid spewing the logs. We lose additional
|
|
165
|
-
// owner stacks but hopefully one level is enough to trace the source.
|
|
166
|
-
var currentName = (ReactCurrentOwner.current &&
|
|
167
|
-
ReactCurrentOwner.current.constructor.displayName) || '';
|
|
168
|
-
if (ownerHasMonitoredObjectMap.hasOwnProperty(currentName)) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
ownerHasMonitoredObjectMap[currentName] = true;
|
|
172
|
-
monitorCodeUse('react_object_map_children');
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Ensure that every component either is passed in a static location, in an
|
|
177
|
-
* array with an explicit keys property defined, or in an object literal
|
|
178
|
-
* with valid key property.
|
|
179
|
-
*
|
|
180
|
-
* @internal
|
|
181
|
-
* @param {*} component Statically passed child of any type.
|
|
182
|
-
* @return {boolean}
|
|
183
|
-
*/
|
|
184
|
-
function validateChildKeys(component) {
|
|
185
|
-
if (Array.isArray(component)) {
|
|
186
|
-
for (var i = 0; i < component.length; i++) {
|
|
187
|
-
var child = component[i];
|
|
188
|
-
if (ReactComponent.isValidComponent(child)) {
|
|
189
|
-
validateExplicitKey(child);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
} else if (ReactComponent.isValidComponent(component)) {
|
|
193
|
-
// This component was passed in a valid location.
|
|
194
|
-
component.__keyValidated__ = true;
|
|
195
|
-
} else if (component && typeof component === 'object') {
|
|
196
|
-
monitorUseOfObjectMap();
|
|
197
|
-
for (var name in component) {
|
|
198
|
-
validatePropertyKey(name, component);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
66
|
/**
|
|
204
67
|
* Components are the basic units of composition in React.
|
|
205
68
|
*
|
|
@@ -238,32 +101,10 @@ var ReactComponent = {
|
|
|
238
101
|
ReactComponentEnvironment.unmountIDFromEnvironment;
|
|
239
102
|
ReactComponent.BackendIDOperations =
|
|
240
103
|
ReactComponentEnvironment.BackendIDOperations;
|
|
241
|
-
ReactComponent.ReactReconcileTransaction =
|
|
242
|
-
ReactComponentEnvironment.ReactReconcileTransaction;
|
|
243
104
|
injected = true;
|
|
244
105
|
}
|
|
245
106
|
},
|
|
246
107
|
|
|
247
|
-
/**
|
|
248
|
-
* @param {?object} object
|
|
249
|
-
* @return {boolean} True if `object` is a valid component.
|
|
250
|
-
* @final
|
|
251
|
-
*/
|
|
252
|
-
isValidComponent: function(object) {
|
|
253
|
-
if (!object || !object.type || !object.type.prototype) {
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
256
|
-
// This is the safer way of duck checking the type of instance this is.
|
|
257
|
-
// The object can be a generic descriptor but the type property refers to
|
|
258
|
-
// the constructor and it's prototype can be used to inspect the type that
|
|
259
|
-
// will actually get mounted.
|
|
260
|
-
var prototype = object.type.prototype;
|
|
261
|
-
return (
|
|
262
|
-
typeof prototype.mountComponentIntoNode === 'function' &&
|
|
263
|
-
typeof prototype.receiveComponent === 'function'
|
|
264
|
-
);
|
|
265
|
-
},
|
|
266
|
-
|
|
267
108
|
/**
|
|
268
109
|
* @internal
|
|
269
110
|
*/
|
|
@@ -278,14 +119,6 @@ var ReactComponent = {
|
|
|
278
119
|
*/
|
|
279
120
|
BackendIDOperations: null,
|
|
280
121
|
|
|
281
|
-
/**
|
|
282
|
-
* React references `ReactReconcileTransaction` using this property in order
|
|
283
|
-
* to allow dependency injection.
|
|
284
|
-
*
|
|
285
|
-
* @internal
|
|
286
|
-
*/
|
|
287
|
-
ReactReconcileTransaction: null,
|
|
288
|
-
|
|
289
122
|
/**
|
|
290
123
|
* Base functionality for every ReactComponent constructor. Mixed into the
|
|
291
124
|
* `ReactComponent` prototype, but exposed statically for easy access.
|
|
@@ -314,9 +147,11 @@ var ReactComponent = {
|
|
|
314
147
|
* @public
|
|
315
148
|
*/
|
|
316
149
|
setProps: function(partialProps, callback) {
|
|
317
|
-
// Merge with
|
|
150
|
+
// Merge with the pending descriptor if it exists, otherwise with existing
|
|
151
|
+
// descriptor props.
|
|
152
|
+
var descriptor = this._pendingDescriptor || this._descriptor;
|
|
318
153
|
this.replaceProps(
|
|
319
|
-
merge(
|
|
154
|
+
merge(descriptor.props, partialProps),
|
|
320
155
|
callback
|
|
321
156
|
);
|
|
322
157
|
},
|
|
@@ -342,7 +177,31 @@ var ReactComponent = {
|
|
|
342
177
|
'`render` method to pass the correct value as props to the component ' +
|
|
343
178
|
'where it is created.'
|
|
344
179
|
) : invariant(this._mountDepth === 0));
|
|
345
|
-
|
|
180
|
+
// This is a deoptimized path. We optimize for always having a descriptor.
|
|
181
|
+
// This creates an extra internal descriptor.
|
|
182
|
+
this._pendingDescriptor = ReactDescriptor.cloneAndReplaceProps(
|
|
183
|
+
this._pendingDescriptor || this._descriptor,
|
|
184
|
+
props
|
|
185
|
+
);
|
|
186
|
+
ReactUpdates.enqueueUpdate(this, callback);
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Schedule a partial update to the props. Only used for internal testing.
|
|
191
|
+
*
|
|
192
|
+
* @param {object} partialProps Subset of the next props.
|
|
193
|
+
* @param {?function} callback Called after props are updated.
|
|
194
|
+
* @final
|
|
195
|
+
* @internal
|
|
196
|
+
*/
|
|
197
|
+
_setPropsInternal: function(partialProps, callback) {
|
|
198
|
+
// This is a deoptimized path. We optimize for always having a descriptor.
|
|
199
|
+
// This creates an extra internal descriptor.
|
|
200
|
+
var descriptor = this._pendingDescriptor || this._descriptor;
|
|
201
|
+
this._pendingDescriptor = ReactDescriptor.cloneAndReplaceProps(
|
|
202
|
+
descriptor,
|
|
203
|
+
merge(descriptor.props, partialProps)
|
|
204
|
+
);
|
|
346
205
|
ReactUpdates.enqueueUpdate(this, callback);
|
|
347
206
|
},
|
|
348
207
|
|
|
@@ -352,43 +211,30 @@ var ReactComponent = {
|
|
|
352
211
|
* Subclasses that override this method should make sure to invoke
|
|
353
212
|
* `ReactComponent.Mixin.construct.call(this, ...)`.
|
|
354
213
|
*
|
|
355
|
-
* @param {
|
|
356
|
-
* @param {*} children
|
|
214
|
+
* @param {ReactDescriptor} descriptor
|
|
357
215
|
* @internal
|
|
358
216
|
*/
|
|
359
|
-
construct: function(
|
|
360
|
-
|
|
217
|
+
construct: function(descriptor) {
|
|
218
|
+
// This is the public exposed props object after it has been processed
|
|
219
|
+
// with default props. The descriptor's props represents the true internal
|
|
220
|
+
// state of the props.
|
|
221
|
+
this.props = descriptor.props;
|
|
361
222
|
// Record the component responsible for creating this component.
|
|
362
|
-
|
|
223
|
+
// This is accessible through the descriptor but we maintain an extra
|
|
224
|
+
// field for compatibility with devtools and as a way to make an
|
|
225
|
+
// incremental update. TODO: Consider deprecating this field.
|
|
226
|
+
this._owner = descriptor._owner;
|
|
227
|
+
|
|
363
228
|
// All components start unmounted.
|
|
364
229
|
this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
|
|
365
230
|
|
|
366
|
-
|
|
231
|
+
// See ReactUpdates.
|
|
367
232
|
this._pendingCallbacks = null;
|
|
368
233
|
|
|
369
|
-
//
|
|
370
|
-
//
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
this._pendingOwner = this._owner;
|
|
374
|
-
|
|
375
|
-
// Children can be more than one argument
|
|
376
|
-
var childrenLength = arguments.length - 1;
|
|
377
|
-
if (childrenLength === 1) {
|
|
378
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
379
|
-
validateChildKeys(children);
|
|
380
|
-
}
|
|
381
|
-
this.props.children = children;
|
|
382
|
-
} else if (childrenLength > 1) {
|
|
383
|
-
var childArray = Array(childrenLength);
|
|
384
|
-
for (var i = 0; i < childrenLength; i++) {
|
|
385
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
386
|
-
validateChildKeys(arguments[i + 1]);
|
|
387
|
-
}
|
|
388
|
-
childArray[i] = arguments[i + 1];
|
|
389
|
-
}
|
|
390
|
-
this.props.children = childArray;
|
|
391
|
-
}
|
|
234
|
+
// We keep the old descriptor and a reference to the pending descriptor
|
|
235
|
+
// to track updates.
|
|
236
|
+
this._descriptor = descriptor;
|
|
237
|
+
this._pendingDescriptor = null;
|
|
392
238
|
},
|
|
393
239
|
|
|
394
240
|
/**
|
|
@@ -413,9 +259,10 @@ var ReactComponent = {
|
|
|
413
259
|
'single component instance in multiple places.',
|
|
414
260
|
rootID
|
|
415
261
|
) : invariant(!this.isMounted()));
|
|
416
|
-
var props = this.props;
|
|
262
|
+
var props = this._descriptor.props;
|
|
417
263
|
if (props.ref != null) {
|
|
418
|
-
|
|
264
|
+
var owner = this._descriptor._owner;
|
|
265
|
+
ReactOwner.addComponentAsRefTo(this, props.ref, owner);
|
|
419
266
|
}
|
|
420
267
|
this._rootNodeID = rootID;
|
|
421
268
|
this._lifeCycleState = ComponentLifeCycle.MOUNTED;
|
|
@@ -458,66 +305,70 @@ var ReactComponent = {
|
|
|
458
305
|
* @param {ReactReconcileTransaction} transaction
|
|
459
306
|
* @internal
|
|
460
307
|
*/
|
|
461
|
-
receiveComponent: function(
|
|
308
|
+
receiveComponent: function(nextDescriptor, transaction) {
|
|
462
309
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
463
310
|
this.isMounted(),
|
|
464
311
|
'receiveComponent(...): Can only update a mounted component.'
|
|
465
312
|
) : invariant(this.isMounted()));
|
|
466
|
-
this.
|
|
467
|
-
this.
|
|
468
|
-
this._performUpdateIfNecessary(transaction);
|
|
313
|
+
this._pendingDescriptor = nextDescriptor;
|
|
314
|
+
this.performUpdateIfNecessary(transaction);
|
|
469
315
|
},
|
|
470
316
|
|
|
471
317
|
/**
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
* @internal
|
|
475
|
-
*/
|
|
476
|
-
performUpdateIfNecessary: function() {
|
|
477
|
-
var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
|
|
478
|
-
transaction.perform(this._performUpdateIfNecessary, this, transaction);
|
|
479
|
-
ReactComponent.ReactReconcileTransaction.release(transaction);
|
|
480
|
-
},
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* If `_pendingProps` is set, update the component.
|
|
318
|
+
* If `_pendingDescriptor` is set, update the component.
|
|
484
319
|
*
|
|
485
320
|
* @param {ReactReconcileTransaction} transaction
|
|
486
321
|
* @internal
|
|
487
322
|
*/
|
|
488
|
-
|
|
489
|
-
if (this.
|
|
323
|
+
performUpdateIfNecessary: function(transaction) {
|
|
324
|
+
if (this._pendingDescriptor == null) {
|
|
490
325
|
return;
|
|
491
326
|
}
|
|
492
|
-
var
|
|
493
|
-
var
|
|
494
|
-
this.
|
|
495
|
-
this.
|
|
496
|
-
this.
|
|
497
|
-
this.
|
|
327
|
+
var prevDescriptor = this._descriptor;
|
|
328
|
+
var nextDescriptor = this._pendingDescriptor;
|
|
329
|
+
this._descriptor = nextDescriptor;
|
|
330
|
+
this.props = nextDescriptor.props;
|
|
331
|
+
this._owner = nextDescriptor._owner;
|
|
332
|
+
this._pendingDescriptor = null;
|
|
333
|
+
this.updateComponent(transaction, prevDescriptor);
|
|
498
334
|
},
|
|
499
335
|
|
|
500
336
|
/**
|
|
501
337
|
* Updates the component's currently mounted representation.
|
|
502
338
|
*
|
|
503
339
|
* @param {ReactReconcileTransaction} transaction
|
|
504
|
-
* @param {object}
|
|
340
|
+
* @param {object} prevDescriptor
|
|
505
341
|
* @internal
|
|
506
342
|
*/
|
|
507
|
-
updateComponent: function(transaction,
|
|
508
|
-
var
|
|
343
|
+
updateComponent: function(transaction, prevDescriptor) {
|
|
344
|
+
var nextDescriptor = this._descriptor;
|
|
345
|
+
|
|
509
346
|
// If either the owner or a `ref` has changed, make sure the newest owner
|
|
510
347
|
// has stored a reference to `this`, and the previous owner (if different)
|
|
511
|
-
// has forgotten the reference to `this`.
|
|
512
|
-
|
|
513
|
-
|
|
348
|
+
// has forgotten the reference to `this`. We use the descriptor instead
|
|
349
|
+
// of the public this.props because the post processing cannot determine
|
|
350
|
+
// a ref. The ref conceptually lives on the descriptor.
|
|
351
|
+
|
|
352
|
+
// TODO: Should this even be possible? The owner cannot change because
|
|
353
|
+
// it's forbidden by shouldUpdateReactComponent. The ref can change
|
|
354
|
+
// if you swap the keys of but not the refs. Reconsider where this check
|
|
355
|
+
// is made. It probably belongs where the key checking and
|
|
356
|
+
// instantiateReactComponent is done.
|
|
357
|
+
|
|
358
|
+
if (nextDescriptor._owner !== prevDescriptor._owner ||
|
|
359
|
+
nextDescriptor.props.ref !== prevDescriptor.props.ref) {
|
|
360
|
+
if (prevDescriptor.props.ref != null) {
|
|
514
361
|
ReactOwner.removeComponentAsRefFrom(
|
|
515
|
-
this,
|
|
362
|
+
this, prevDescriptor.props.ref, prevDescriptor._owner
|
|
516
363
|
);
|
|
517
364
|
}
|
|
518
365
|
// Correct, even if the owner is the same, and only the ref has changed.
|
|
519
|
-
if (props.ref != null) {
|
|
520
|
-
ReactOwner.addComponentAsRefTo(
|
|
366
|
+
if (nextDescriptor.props.ref != null) {
|
|
367
|
+
ReactOwner.addComponentAsRefTo(
|
|
368
|
+
this,
|
|
369
|
+
nextDescriptor.props.ref,
|
|
370
|
+
nextDescriptor._owner
|
|
371
|
+
);
|
|
521
372
|
}
|
|
522
373
|
}
|
|
523
374
|
},
|
|
@@ -533,7 +384,7 @@ var ReactComponent = {
|
|
|
533
384
|
* @see {ReactMount.renderComponent}
|
|
534
385
|
*/
|
|
535
386
|
mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) {
|
|
536
|
-
var transaction =
|
|
387
|
+
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
|
|
537
388
|
transaction.perform(
|
|
538
389
|
this._mountComponentIntoNode,
|
|
539
390
|
this,
|
|
@@ -542,7 +393,7 @@ var ReactComponent = {
|
|
|
542
393
|
transaction,
|
|
543
394
|
shouldReuseMarkup
|
|
544
395
|
);
|
|
545
|
-
|
|
396
|
+
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
|
546
397
|
},
|
|
547
398
|
|
|
548
399
|
/**
|