react 0.9.0 → 0.11.0

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.
Files changed (114) hide show
  1. package/README.md +3 -0
  2. package/dist/JSXTransformer.js +13448 -0
  3. package/dist/react-with-addons.js +20235 -0
  4. package/dist/react-with-addons.min.js +22 -0
  5. package/dist/react.js +18443 -0
  6. package/dist/react.min.js +21 -0
  7. package/lib/AutoFocusMixin.js +3 -1
  8. package/lib/BeforeInputEventPlugin.js +222 -0
  9. package/lib/CSSPropertyOperations.js +3 -3
  10. package/lib/{ReactMountReady.js → CallbackQueue.js} +32 -24
  11. package/lib/ChangeEventPlugin.js +1 -1
  12. package/lib/CompositionEventPlugin.js +5 -1
  13. package/lib/DOMChildrenOperations.js +33 -20
  14. package/lib/DOMProperty.js +51 -21
  15. package/lib/DOMPropertyOperations.js +28 -16
  16. package/lib/DefaultEventPluginOrder.js +1 -0
  17. package/lib/EventConstants.js +1 -0
  18. package/lib/EventListener.js +5 -2
  19. package/lib/EventPluginHub.js +2 -5
  20. package/lib/EventPluginRegistry.js +6 -4
  21. package/lib/EventPluginUtils.js +11 -1
  22. package/lib/ExecutionEnvironment.js +8 -2
  23. package/lib/{DefaultDOMPropertyConfig.js → HTMLDOMPropertyConfig.js} +41 -58
  24. package/lib/LinkedValueUtils.js +26 -28
  25. package/lib/LocalEventTrapMixin.js +52 -0
  26. package/lib/React.js +39 -3
  27. package/lib/ReactBrowserComponentMixin.js +46 -0
  28. package/lib/{ReactEventEmitter.js → ReactBrowserEventEmitter.js} +115 -94
  29. package/lib/ReactCSSTransitionGroup.js +12 -10
  30. package/lib/ReactCSSTransitionGroupChild.js +2 -5
  31. package/lib/ReactChildren.js +31 -10
  32. package/lib/ReactComponent.js +119 -223
  33. package/lib/ReactComponentBrowserEnvironment.js +3 -36
  34. package/lib/ReactComponentWithPureRenderMixin.js +54 -0
  35. package/lib/ReactCompositeComponent.js +249 -287
  36. package/lib/ReactDOM.js +25 -23
  37. package/lib/ReactDOMButton.js +2 -1
  38. package/lib/ReactDOMComponent.js +42 -23
  39. package/lib/ReactDOMForm.js +7 -12
  40. package/lib/ReactDOMIDOperations.js +2 -31
  41. package/lib/ReactDOMImg.js +7 -13
  42. package/lib/ReactDOMInput.js +2 -1
  43. package/lib/ReactDOMOption.js +11 -7
  44. package/lib/ReactDOMSelect.js +18 -16
  45. package/lib/ReactDOMSelection.js +35 -10
  46. package/lib/ReactDOMTextarea.js +9 -7
  47. package/lib/ReactDefaultBatchingStrategy.js +3 -3
  48. package/lib/ReactDefaultInjection.js +27 -14
  49. package/lib/ReactDefaultPerf.js +28 -11
  50. package/lib/ReactDefaultPerfAnalysis.js +4 -0
  51. package/lib/ReactDescriptor.js +251 -0
  52. package/lib/ReactDescriptorValidator.js +283 -0
  53. package/lib/ReactEmptyComponent.js +78 -0
  54. package/lib/ReactEventEmitterMixin.js +1 -3
  55. package/lib/ReactEventListener.js +189 -0
  56. package/lib/ReactInjection.js +8 -2
  57. package/lib/ReactInputSelection.js +2 -1
  58. package/lib/ReactLink.js +24 -0
  59. package/lib/ReactMount.js +61 -21
  60. package/lib/ReactMultiChild.js +18 -13
  61. package/lib/ReactOwner.js +6 -1
  62. package/lib/ReactPropTransferer.js +44 -29
  63. package/lib/ReactPropTypes.js +226 -242
  64. package/lib/ReactPutListenerQueue.js +2 -2
  65. package/lib/ReactReconcileTransaction.js +21 -20
  66. package/lib/ReactServerRendering.js +41 -11
  67. package/lib/ReactServerRenderingTransaction.js +115 -0
  68. package/lib/ReactTestUtils.js +39 -21
  69. package/lib/ReactTextComponent.js +21 -13
  70. package/lib/ReactTransitionChildMapping.js +2 -2
  71. package/lib/ReactTransitionEvents.js +19 -0
  72. package/lib/ReactTransitionGroup.js +9 -6
  73. package/lib/ReactUpdates.js +139 -22
  74. package/lib/ReactWithAddons.js +8 -3
  75. package/lib/SVGDOMPropertyConfig.js +97 -0
  76. package/lib/SimpleEventPlugin.js +7 -1
  77. package/lib/SyntheticInputEvent.js +52 -0
  78. package/lib/SyntheticKeyboardEvent.js +33 -4
  79. package/lib/SyntheticMouseEvent.js +3 -0
  80. package/lib/SyntheticTouchEvent.js +4 -1
  81. package/lib/SyntheticUIEvent.js +24 -2
  82. package/lib/Transaction.js +0 -32
  83. package/lib/cloneWithProps.js +10 -8
  84. package/lib/createFullPageComponent.js +1 -1
  85. package/lib/dangerousStyleValue.js +11 -5
  86. package/lib/{ReactComponentEnvironment.js → emptyObject.js} +6 -5
  87. package/lib/escapeTextForBrowser.js +2 -3
  88. package/lib/flattenChildren.js +9 -7
  89. package/lib/focusNode.js +33 -0
  90. package/lib/getEventKey.js +35 -5
  91. package/lib/getEventModifierState.js +52 -0
  92. package/lib/getMarkupWrap.js +2 -0
  93. package/lib/getTextContentAccessor.js +1 -1
  94. package/lib/hyphenate.js +3 -0
  95. package/lib/hyphenateStyleName.js +46 -0
  96. package/lib/instantiateReactComponent.js +62 -0
  97. package/lib/invariant.js +17 -19
  98. package/lib/isNode.js +1 -1
  99. package/lib/{objMap.js → mapObject.js} +8 -3
  100. package/lib/mergeHelpers.js +11 -0
  101. package/lib/mergeInto.js +3 -2
  102. package/lib/monitorCodeUse.js +37 -0
  103. package/lib/onlyChild.js +3 -3
  104. package/lib/performance.js +33 -0
  105. package/lib/performanceNow.js +5 -14
  106. package/lib/setInnerHTML.js +77 -0
  107. package/lib/shouldUpdateReactComponent.js +14 -28
  108. package/lib/toArray.js +1 -1
  109. package/lib/traverseAllChildren.js +9 -5
  110. package/lib/update.js +171 -0
  111. package/package.json +4 -3
  112. package/lib/ReactEventTopLevelCallback.js +0 -149
  113. package/lib/createObjectFrom.js +0 -61
  114. package/lib/objMapKeyVal.js +0 -47
@@ -15,7 +15,6 @@
15
15
  *
16
16
  * @typechecks
17
17
  * @providesModule ReactCSSTransitionGroup
18
- * @jsx React.DOM
19
18
  */
20
19
 
21
20
  "use strict";
@@ -25,7 +24,9 @@ var React = require("./React");
25
24
  var ReactTransitionGroup = require("./ReactTransitionGroup");
26
25
  var ReactCSSTransitionGroupChild = require("./ReactCSSTransitionGroupChild");
27
26
 
28
- var ReactCSSTransitionGroup = React.createClass({displayName: 'ReactCSSTransitionGroup',
27
+ var ReactCSSTransitionGroup = React.createClass({
28
+ displayName: 'ReactCSSTransitionGroup',
29
+
29
30
  propTypes: {
30
31
  transitionName: React.PropTypes.string.isRequired,
31
32
  transitionEnter: React.PropTypes.bool,
@@ -43,19 +44,20 @@ var ReactCSSTransitionGroup = React.createClass({displayName: 'ReactCSSTransitio
43
44
  // We need to provide this childFactory so that
44
45
  // ReactCSSTransitionGroupChild can receive updates to name, enter, and
45
46
  // leave while it is leaving.
46
- return (
47
- ReactCSSTransitionGroupChild(
48
- {name:this.props.transitionName,
49
- enter:this.props.transitionEnter,
50
- leave:this.props.transitionLeave},
51
- child
52
- )
47
+ return ReactCSSTransitionGroupChild(
48
+ {
49
+ name: this.props.transitionName,
50
+ enter: this.props.transitionEnter,
51
+ leave: this.props.transitionLeave
52
+ },
53
+ child
53
54
  );
54
55
  },
55
56
 
56
57
  render: function() {
57
58
  return this.transferPropsTo(
58
- ReactTransitionGroup( {childFactory:this._wrapChild},
59
+ ReactTransitionGroup(
60
+ {childFactory: this._wrapChild},
59
61
  this.props.children
60
62
  )
61
63
  );
@@ -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
  }
@@ -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
- var mappedChild =
90
- mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);
91
- // We found a component instance
92
- ("production" !== process.env.NODE_ENV ? invariant(
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`. Children keys must be unique.',
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
- ) : invariant(!mapResult.hasOwnProperty(name)));
98
- mapResult[name] = mappedChild;
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;
@@ -18,8 +18,7 @@
18
18
 
19
19
  "use strict";
20
20
 
21
- var ReactComponentEnvironment = require("./ReactComponentEnvironment");
22
- var ReactCurrentOwner = require("./ReactCurrentOwner");
21
+ var ReactDescriptor = require("./ReactDescriptor");
23
22
  var ReactOwner = require("./ReactOwner");
24
23
  var ReactUpdates = require("./ReactUpdates");
25
24
 
@@ -42,113 +41,27 @@ 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
-
54
- var NUMERIC_PROPERTY_REGEX = /^\d+$/;
44
+ var injected = false;
55
45
 
56
46
  /**
57
- * Warn if the component doesn't have an explicit key assigned to it.
58
- * This component is in an array. The array could grow and shrink or be
59
- * reordered. All children that haven't already been validated are required to
60
- * have a "key" property assigned to it.
47
+ * Optionally injectable environment dependent cleanup hook. (server vs.
48
+ * browser etc). Example: A browser system caches DOM nodes based on component
49
+ * ID and must remove that cache entry when this instance is unmounted.
61
50
  *
62
- * @internal
63
- * @param {ReactComponent} component Component that requires a key.
51
+ * @private
64
52
  */
65
- function validateExplicitKey(component) {
66
- if (component.__keyValidated__ || component.props.key != null) {
67
- return;
68
- }
69
- component.__keyValidated__ = true;
70
-
71
- // We can't provide friendly warnings for top level components.
72
- if (!ReactCurrentOwner.current) {
73
- return;
74
- }
75
-
76
- // Name of the component whose render method tried to pass children.
77
- var currentName = ReactCurrentOwner.current.constructor.displayName;
78
- if (ownerHasExplicitKeyWarning.hasOwnProperty(currentName)) {
79
- return;
80
- }
81
- ownerHasExplicitKeyWarning[currentName] = true;
82
-
83
- var message = 'Each child in an array should have a unique "key" prop. ' +
84
- 'Check the render method of ' + currentName + '.';
85
- if (!component.isOwnedBy(ReactCurrentOwner.current)) {
86
- // Name of the component that originally created this child.
87
- var childOwnerName =
88
- component._owner &&
89
- component._owner.constructor.displayName;
90
-
91
- // Usually the current owner is the offender, but if it accepts
92
- // children as a property, it may be the creator of the child that's
93
- // responsible for assigning it a key.
94
- message += ' It was passed a child from ' + childOwnerName + '.';
95
- }
96
-
97
- message += ' See http://fb.me/react-warning-keys for more information.';
98
- console.warn(message);
99
- }
100
-
101
- /**
102
- * Warn if the key is being defined as an object property but has an incorrect
103
- * value.
104
- *
105
- * @internal
106
- * @param {string} name Property name of the key.
107
- * @param {ReactComponent} component Component that requires a key.
108
- */
109
- function validatePropertyKey(name) {
110
- if (NUMERIC_PROPERTY_REGEX.test(name)) {
111
- // Name of the component whose render method tried to pass children.
112
- var currentName = ReactCurrentOwner.current.constructor.displayName;
113
- if (ownerHasPropertyWarning.hasOwnProperty(currentName)) {
114
- return;
115
- }
116
- ownerHasPropertyWarning[currentName] = true;
117
-
118
- console.warn(
119
- 'Child objects should have non-numeric keys so ordering is preserved. ' +
120
- 'Check the render method of ' + currentName + '. ' +
121
- 'See http://fb.me/react-warning-keys for more information.'
122
- );
123
- }
124
- }
53
+ var unmountIDFromEnvironment = null;
125
54
 
126
55
  /**
127
- * Ensure that every component either is passed in a static location, in an
128
- * array with an explicit keys property defined, or in an object literal
129
- * with valid key property.
56
+ * The "image" of a component tree, is the platform specific (typically
57
+ * serialized) data that represents a tree of lower level UI building blocks.
58
+ * On the web, this "image" is HTML markup which describes a construction of
59
+ * low level `div` and `span` nodes. Other platforms may have different
60
+ * encoding of this "image". This must be injected.
130
61
  *
131
- * @internal
132
- * @param {*} component Statically passed child of any type.
133
- * @return {boolean}
62
+ * @private
134
63
  */
135
- function validateChildKeys(component) {
136
- if (Array.isArray(component)) {
137
- for (var i = 0; i < component.length; i++) {
138
- var child = component[i];
139
- if (ReactComponent.isValidComponent(child)) {
140
- validateExplicitKey(child);
141
- }
142
- }
143
- } else if (ReactComponent.isValidComponent(component)) {
144
- // This component was passed in a valid location.
145
- component.__keyValidated__ = true;
146
- } else if (component && typeof component === 'object') {
147
- for (var name in component) {
148
- validatePropertyKey(name, component);
149
- }
150
- }
151
- }
64
+ var mountImageIntoNode = null;
152
65
 
153
66
  /**
154
67
  * Components are the basic units of composition in React.
@@ -177,24 +90,19 @@ function validateChildKeys(component) {
177
90
  */
178
91
  var ReactComponent = {
179
92
 
180
- /**
181
- * @param {?object} object
182
- * @return {boolean} True if `object` is a valid component.
183
- * @final
184
- */
185
- isValidComponent: function(object) {
186
- if (!object || !object.type || !object.type.prototype) {
187
- return false;
93
+ injection: {
94
+ injectEnvironment: function(ReactComponentEnvironment) {
95
+ ("production" !== process.env.NODE_ENV ? invariant(
96
+ !injected,
97
+ 'ReactComponent: injectEnvironment() can only be called once.'
98
+ ) : invariant(!injected));
99
+ mountImageIntoNode = ReactComponentEnvironment.mountImageIntoNode;
100
+ unmountIDFromEnvironment =
101
+ ReactComponentEnvironment.unmountIDFromEnvironment;
102
+ ReactComponent.BackendIDOperations =
103
+ ReactComponentEnvironment.BackendIDOperations;
104
+ injected = true;
188
105
  }
189
- // This is the safer way of duck checking the type of instance this is.
190
- // The object can be a generic descriptor but the type property refers to
191
- // the constructor and it's prototype can be used to inspect the type that
192
- // will actually get mounted.
193
- var prototype = object.type.prototype;
194
- return (
195
- typeof prototype.mountComponentIntoNode === 'function' &&
196
- typeof prototype.receiveComponent === 'function'
197
- );
198
106
  },
199
107
 
200
108
  /**
@@ -209,36 +117,7 @@ var ReactComponent = {
209
117
  *
210
118
  * @internal
211
119
  */
212
- BackendIDOperations: ReactComponentEnvironment.BackendIDOperations,
213
-
214
- /**
215
- * Optionally injectable environment dependent cleanup hook. (server vs.
216
- * browser etc). Example: A browser system caches DOM nodes based on component
217
- * ID and must remove that cache entry when this instance is unmounted.
218
- *
219
- * @private
220
- */
221
- unmountIDFromEnvironment: ReactComponentEnvironment.unmountIDFromEnvironment,
222
-
223
- /**
224
- * The "image" of a component tree, is the platform specific (typically
225
- * serialized) data that represents a tree of lower level UI building blocks.
226
- * On the web, this "image" is HTML markup which describes a construction of
227
- * low level `div` and `span` nodes. Other platforms may have different
228
- * encoding of this "image". This must be injected.
229
- *
230
- * @private
231
- */
232
- mountImageIntoNode: ReactComponentEnvironment.mountImageIntoNode,
233
-
234
- /**
235
- * React references `ReactReconcileTransaction` using this property in order
236
- * to allow dependency injection.
237
- *
238
- * @internal
239
- */
240
- ReactReconcileTransaction:
241
- ReactComponentEnvironment.ReactReconcileTransaction,
120
+ BackendIDOperations: null,
242
121
 
243
122
  /**
244
123
  * Base functionality for every ReactComponent constructor. Mixed into the
@@ -246,7 +125,7 @@ var ReactComponent = {
246
125
  *
247
126
  * @lends {ReactComponent.prototype}
248
127
  */
249
- Mixin: merge(ReactComponentEnvironment.Mixin, {
128
+ Mixin: {
250
129
 
251
130
  /**
252
131
  * Checks whether or not this component is mounted.
@@ -268,9 +147,11 @@ var ReactComponent = {
268
147
  * @public
269
148
  */
270
149
  setProps: function(partialProps, callback) {
271
- // Merge with `_pendingProps` if it exists, otherwise with existing props.
150
+ // Merge with the pending descriptor if it exists, otherwise with existing
151
+ // descriptor props.
152
+ var descriptor = this._pendingDescriptor || this._descriptor;
272
153
  this.replaceProps(
273
- merge(this._pendingProps || this.props, partialProps),
154
+ merge(descriptor.props, partialProps),
274
155
  callback
275
156
  );
276
157
  },
@@ -296,7 +177,31 @@ var ReactComponent = {
296
177
  '`render` method to pass the correct value as props to the component ' +
297
178
  'where it is created.'
298
179
  ) : invariant(this._mountDepth === 0));
299
- this._pendingProps = props;
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
+ );
300
205
  ReactUpdates.enqueueUpdate(this, callback);
301
206
  },
302
207
 
@@ -306,43 +211,30 @@ var ReactComponent = {
306
211
  * Subclasses that override this method should make sure to invoke
307
212
  * `ReactComponent.Mixin.construct.call(this, ...)`.
308
213
  *
309
- * @param {?object} initialProps
310
- * @param {*} children
214
+ * @param {ReactDescriptor} descriptor
311
215
  * @internal
312
216
  */
313
- construct: function(initialProps, children) {
314
- this.props = initialProps || {};
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;
315
222
  // Record the component responsible for creating this component.
316
- this._owner = ReactCurrentOwner.current;
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
+
317
228
  // All components start unmounted.
318
229
  this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
319
230
 
320
- this._pendingProps = null;
231
+ // See ReactUpdates.
321
232
  this._pendingCallbacks = null;
322
233
 
323
- // Unlike _pendingProps and _pendingCallbacks, we won't use null to
324
- // indicate that nothing is pending because it's possible for a component
325
- // to have a null owner. Instead, an owner change is pending when
326
- // this._owner !== this._pendingOwner.
327
- this._pendingOwner = this._owner;
328
-
329
- // Children can be more than one argument
330
- var childrenLength = arguments.length - 1;
331
- if (childrenLength === 1) {
332
- if ("production" !== process.env.NODE_ENV) {
333
- validateChildKeys(children);
334
- }
335
- this.props.children = children;
336
- } else if (childrenLength > 1) {
337
- var childArray = Array(childrenLength);
338
- for (var i = 0; i < childrenLength; i++) {
339
- if ("production" !== process.env.NODE_ENV) {
340
- validateChildKeys(arguments[i + 1]);
341
- }
342
- childArray[i] = arguments[i + 1];
343
- }
344
- this.props.children = childArray;
345
- }
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;
346
238
  },
347
239
 
348
240
  /**
@@ -354,7 +246,7 @@ var ReactComponent = {
354
246
  * `ReactComponent.Mixin.mountComponent.call(this, ...)`.
355
247
  *
356
248
  * @param {string} rootID DOM ID of the root node.
357
- * @param {ReactReconcileTransaction} transaction
249
+ * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
358
250
  * @param {number} mountDepth number of components in the owner hierarchy.
359
251
  * @return {?string} Rendered markup to be inserted into the DOM.
360
252
  * @internal
@@ -367,9 +259,10 @@ var ReactComponent = {
367
259
  'single component instance in multiple places.',
368
260
  rootID
369
261
  ) : invariant(!this.isMounted()));
370
- var props = this.props;
262
+ var props = this._descriptor.props;
371
263
  if (props.ref != null) {
372
- ReactOwner.addComponentAsRefTo(this, props.ref, this._owner);
264
+ var owner = this._descriptor._owner;
265
+ ReactOwner.addComponentAsRefTo(this, props.ref, owner);
373
266
  }
374
267
  this._rootNodeID = rootID;
375
268
  this._lifeCycleState = ComponentLifeCycle.MOUNTED;
@@ -396,7 +289,7 @@ var ReactComponent = {
396
289
  if (props.ref != null) {
397
290
  ReactOwner.removeComponentAsRefFrom(this, props.ref, this._owner);
398
291
  }
399
- ReactComponent.unmountIDFromEnvironment(this._rootNodeID);
292
+ unmountIDFromEnvironment(this._rootNodeID);
400
293
  this._rootNodeID = null;
401
294
  this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
402
295
  },
@@ -412,67 +305,70 @@ var ReactComponent = {
412
305
  * @param {ReactReconcileTransaction} transaction
413
306
  * @internal
414
307
  */
415
- receiveComponent: function(nextComponent, transaction) {
308
+ receiveComponent: function(nextDescriptor, transaction) {
416
309
  ("production" !== process.env.NODE_ENV ? invariant(
417
310
  this.isMounted(),
418
311
  'receiveComponent(...): Can only update a mounted component.'
419
312
  ) : invariant(this.isMounted()));
420
- this._pendingOwner = nextComponent._owner;
421
- this._pendingProps = nextComponent.props;
422
- this._performUpdateIfNecessary(transaction);
423
- },
424
-
425
- /**
426
- * Call `_performUpdateIfNecessary` within a new transaction.
427
- *
428
- * @param {ReactReconcileTransaction} transaction
429
- * @internal
430
- */
431
- performUpdateIfNecessary: function() {
432
- var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
433
- transaction.perform(this._performUpdateIfNecessary, this, transaction);
434
- ReactComponent.ReactReconcileTransaction.release(transaction);
313
+ this._pendingDescriptor = nextDescriptor;
314
+ this.performUpdateIfNecessary(transaction);
435
315
  },
436
316
 
437
317
  /**
438
- * If `_pendingProps` is set, update the component.
318
+ * If `_pendingDescriptor` is set, update the component.
439
319
  *
440
320
  * @param {ReactReconcileTransaction} transaction
441
321
  * @internal
442
322
  */
443
- _performUpdateIfNecessary: function(transaction) {
444
- if (this._pendingProps == null) {
323
+ performUpdateIfNecessary: function(transaction) {
324
+ if (this._pendingDescriptor == null) {
445
325
  return;
446
326
  }
447
- var prevProps = this.props;
448
- var prevOwner = this._owner;
449
- this.props = this._pendingProps;
450
- this._owner = this._pendingOwner;
451
- this._pendingProps = null;
452
- this.updateComponent(transaction, prevProps, prevOwner);
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);
453
334
  },
454
335
 
455
336
  /**
456
337
  * Updates the component's currently mounted representation.
457
338
  *
458
339
  * @param {ReactReconcileTransaction} transaction
459
- * @param {object} prevProps
340
+ * @param {object} prevDescriptor
460
341
  * @internal
461
342
  */
462
- updateComponent: function(transaction, prevProps, prevOwner) {
463
- var props = this.props;
343
+ updateComponent: function(transaction, prevDescriptor) {
344
+ var nextDescriptor = this._descriptor;
345
+
464
346
  // If either the owner or a `ref` has changed, make sure the newest owner
465
347
  // has stored a reference to `this`, and the previous owner (if different)
466
- // has forgotten the reference to `this`.
467
- if (this._owner !== prevOwner || props.ref !== prevProps.ref) {
468
- if (prevProps.ref != null) {
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) {
469
361
  ReactOwner.removeComponentAsRefFrom(
470
- this, prevProps.ref, prevOwner
362
+ this, prevDescriptor.props.ref, prevDescriptor._owner
471
363
  );
472
364
  }
473
365
  // Correct, even if the owner is the same, and only the ref has changed.
474
- if (props.ref != null) {
475
- ReactOwner.addComponentAsRefTo(this, props.ref, this._owner);
366
+ if (nextDescriptor.props.ref != null) {
367
+ ReactOwner.addComponentAsRefTo(
368
+ this,
369
+ nextDescriptor.props.ref,
370
+ nextDescriptor._owner
371
+ );
476
372
  }
477
373
  }
478
374
  },
@@ -488,7 +384,7 @@ var ReactComponent = {
488
384
  * @see {ReactMount.renderComponent}
489
385
  */
490
386
  mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) {
491
- var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
387
+ var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
492
388
  transaction.perform(
493
389
  this._mountComponentIntoNode,
494
390
  this,
@@ -497,7 +393,7 @@ var ReactComponent = {
497
393
  transaction,
498
394
  shouldReuseMarkup
499
395
  );
500
- ReactComponent.ReactReconcileTransaction.release(transaction);
396
+ ReactUpdates.ReactReconcileTransaction.release(transaction);
501
397
  },
502
398
 
503
399
  /**
@@ -514,7 +410,7 @@ var ReactComponent = {
514
410
  transaction,
515
411
  shouldReuseMarkup) {
516
412
  var markup = this.mountComponent(rootID, transaction, 0);
517
- ReactComponent.mountImageIntoNode(markup, container, shouldReuseMarkup);
413
+ mountImageIntoNode(markup, container, shouldReuseMarkup);
518
414
  },
519
415
 
520
416
  /**
@@ -544,7 +440,7 @@ var ReactComponent = {
544
440
  }
545
441
  return owner.refs[ref];
546
442
  }
547
- })
443
+ }
548
444
  };
549
445
 
550
446
  module.exports = ReactComponent;