react 0.12.2 → 0.13.0-alpha.1

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 (77) hide show
  1. package/dist/JSXTransformer.js +6 -4
  2. package/dist/react-with-addons.js +4022 -3267
  3. package/dist/react-with-addons.min.js +6 -6
  4. package/dist/react.js +3853 -3358
  5. package/dist/react.min.js +6 -6
  6. package/lib/BeforeInputEventPlugin.js +388 -111
  7. package/lib/CSSPropertyOperations.js +20 -0
  8. package/lib/ChangeEventPlugin.js +2 -2
  9. package/lib/Danger.js +1 -1
  10. package/lib/DefaultEventPluginOrder.js +0 -1
  11. package/lib/ExecutionEnvironment.js +2 -3
  12. package/lib/FallbackCompositionState.js +87 -0
  13. package/lib/HTMLDOMPropertyConfig.js +1 -0
  14. package/lib/Object.assign.js +3 -1
  15. package/lib/React.js +14 -49
  16. package/lib/ReactBrowserComponentMixin.js +2 -12
  17. package/lib/ReactBrowserEventEmitter.js +2 -4
  18. package/lib/ReactCSSTransitionGroup.js +3 -0
  19. package/lib/ReactCSSTransitionGroupChild.js +8 -0
  20. package/lib/ReactChildReconciler.js +121 -0
  21. package/lib/ReactClass.js +916 -0
  22. package/lib/ReactComponent.js +36 -286
  23. package/lib/ReactComponentBrowserEnvironment.js +9 -82
  24. package/lib/ReactComponentEnvironment.js +57 -0
  25. package/lib/ReactCompositeComponent.js +608 -1026
  26. package/lib/ReactContext.js +5 -1
  27. package/lib/ReactDOM.js +2 -7
  28. package/lib/ReactDOMButton.js +4 -5
  29. package/lib/ReactDOMComponent.js +97 -69
  30. package/lib/ReactDOMForm.js +4 -5
  31. package/lib/ReactDOMIDOperations.js +55 -73
  32. package/lib/ReactDOMImg.js +3 -5
  33. package/lib/ReactDOMInput.js +4 -5
  34. package/lib/ReactDOMOption.js +4 -5
  35. package/lib/ReactDOMSelect.js +55 -63
  36. package/lib/ReactDOMSelection.js +5 -1
  37. package/lib/{ReactTextComponent.js → ReactDOMTextComponent.js} +54 -34
  38. package/lib/ReactDOMTextarea.js +4 -5
  39. package/lib/ReactDefaultInjection.js +13 -7
  40. package/lib/ReactDefaultPerf.js +6 -5
  41. package/lib/ReactDefaultPerfAnalysis.js +1 -1
  42. package/lib/ReactElement.js +17 -11
  43. package/lib/ReactElementValidator.js +74 -37
  44. package/lib/ReactEmptyComponent.js +17 -10
  45. package/lib/ReactInjection.js +6 -4
  46. package/lib/ReactInputSelection.js +2 -3
  47. package/lib/ReactInstanceMap.js +47 -0
  48. package/lib/ReactMount.js +193 -64
  49. package/lib/ReactMultiChild.js +32 -42
  50. package/lib/ReactNativeComponent.js +45 -8
  51. package/lib/ReactOwner.js +3 -47
  52. package/lib/ReactPerf.js +20 -0
  53. package/lib/ReactPropTransferer.js +0 -55
  54. package/lib/ReactPropTypes.js +1 -17
  55. package/lib/ReactRef.js +96 -0
  56. package/lib/ReactServerRendering.js +3 -2
  57. package/lib/ReactTestUtils.js +82 -25
  58. package/lib/ReactTransitionGroup.js +47 -6
  59. package/lib/ReactUpdates.js +43 -42
  60. package/lib/SyntheticMouseEvent.js +1 -3
  61. package/lib/ViewportMetrics.js +1 -4
  62. package/lib/accumulate.js +47 -0
  63. package/lib/cloneWithProps.js +2 -2
  64. package/lib/copyProperties.js +2 -0
  65. package/lib/createFullPageComponent.js +2 -2
  66. package/lib/findDOMNode.js +52 -0
  67. package/lib/flattenChildren.js +1 -14
  68. package/lib/getIteratorFn.js +42 -0
  69. package/lib/instantiateReactComponent.js +88 -65
  70. package/lib/isNode.js +3 -4
  71. package/lib/isTextInputElement.js +1 -2
  72. package/lib/shouldUpdateReactComponent.js +13 -5
  73. package/lib/traverseAllChildren.js +110 -54
  74. package/package.json +1 -1
  75. package/lib/CompositionEventPlugin.js +0 -257
  76. package/lib/ReactLegacyElement.js +0 -243
  77. package/lib/deprecated.js +0 -47
@@ -31,9 +31,8 @@ var ReactInputSelection = {
31
31
 
32
32
  hasSelectionCapabilities: function(elem) {
33
33
  return elem && (
34
- (elem.nodeName === 'INPUT' && elem.type === 'text') ||
35
- elem.nodeName === 'TEXTAREA' ||
36
- elem.contentEditable === 'true'
34
+ ((elem.nodeName === 'INPUT' && elem.type === 'text') ||
35
+ elem.nodeName === 'TEXTAREA' || elem.contentEditable === 'true')
37
36
  );
38
37
  },
39
38
 
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Copyright 2013-2014, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactInstanceMap
10
+ */
11
+
12
+ "use strict";
13
+
14
+ /**
15
+ * `ReactInstanceMap` maintains a mapping from a public facing stateful
16
+ * instance (key) and the internal representation (value). This allows public
17
+ * methods to accept the user facing instance as an argument and map them back
18
+ * to internal methods.
19
+ */
20
+
21
+ // TODO: Replace this with ES6: var ReactInstanceMap = new Map();
22
+ var ReactInstanceMap = {
23
+
24
+ /**
25
+ * This API should be called `delete` but we'd have to make sure to always
26
+ * transform these to strings for IE support. When this transform is fully
27
+ * supported we can rename it.
28
+ */
29
+ remove: function(key) {
30
+ key._reactInternalInstance = undefined;
31
+ },
32
+
33
+ get: function(key) {
34
+ return key._reactInternalInstance;
35
+ },
36
+
37
+ has: function(key) {
38
+ return key._reactInternalInstance !== undefined;
39
+ },
40
+
41
+ set: function(key, value) {
42
+ key._reactInternalInstance = value;
43
+ }
44
+
45
+ };
46
+
47
+ module.exports = ReactInstanceMap;
package/lib/ReactMount.js CHANGED
@@ -15,22 +15,22 @@ var DOMProperty = require("./DOMProperty");
15
15
  var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
16
16
  var ReactCurrentOwner = require("./ReactCurrentOwner");
17
17
  var ReactElement = require("./ReactElement");
18
- var ReactLegacyElement = require("./ReactLegacyElement");
18
+ var ReactEmptyComponent = require("./ReactEmptyComponent");
19
19
  var ReactInstanceHandles = require("./ReactInstanceHandles");
20
+ var ReactInstanceMap = require("./ReactInstanceMap");
21
+ var ReactMarkupChecksum = require("./ReactMarkupChecksum");
20
22
  var ReactPerf = require("./ReactPerf");
23
+ var ReactUpdates = require("./ReactUpdates");
21
24
 
25
+ var emptyObject = require("./emptyObject");
22
26
  var containsNode = require("./containsNode");
23
- var deprecated = require("./deprecated");
24
27
  var getReactRootElementInContainer = require("./getReactRootElementInContainer");
25
28
  var instantiateReactComponent = require("./instantiateReactComponent");
26
29
  var invariant = require("./invariant");
30
+ var setInnerHTML = require("./setInnerHTML");
27
31
  var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
28
32
  var warning = require("./warning");
29
33
 
30
- var createElement = ReactLegacyElement.wrapCreateElement(
31
- ReactElement.createElement
32
- );
33
-
34
34
  var SEPARATOR = ReactInstanceHandles.SEPARATOR;
35
35
 
36
36
  var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
@@ -53,6 +53,22 @@ if ("production" !== process.env.NODE_ENV) {
53
53
  // Used to store breadth-first search state in findComponentRoot.
54
54
  var findComponentRootReusableArray = [];
55
55
 
56
+ /**
57
+ * Finds the index of the first character
58
+ * that's not common between the two given strings.
59
+ *
60
+ * @return {number} the index of the character where the strings diverge
61
+ */
62
+ function firstDifferenceIndex(string1, string2) {
63
+ var minLen = Math.min(string1.length, string2.length);
64
+ for (var i = 0; i < minLen; i++) {
65
+ if (string1.charAt(i) !== string2.charAt(i)) {
66
+ return i;
67
+ }
68
+ }
69
+ return string1.length === string2.length ? -1 : minLen;
70
+ }
71
+
56
72
  /**
57
73
  * @param {DOMElement} container DOM element that may contain a React component.
58
74
  * @return {?string} A "reactRoot" ID, if a React component is rendered.
@@ -130,6 +146,24 @@ function getNode(id) {
130
146
  return nodeCache[id];
131
147
  }
132
148
 
149
+ /**
150
+ * Finds the node with the supplied public React instance.
151
+ *
152
+ * @param {*} instance A public React instance.
153
+ * @return {?DOMElement} DOM node with the suppled `id`.
154
+ * @internal
155
+ */
156
+ function getNodeFromInstance(instance) {
157
+ var id = ReactInstanceMap.get(instance)._rootNodeID;
158
+ if (ReactEmptyComponent.isNullComponentID(id)) {
159
+ return null;
160
+ }
161
+ if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
162
+ nodeCache[id] = ReactMount.findReactNodeByID(id);
163
+ }
164
+ return nodeCache[id];
165
+ }
166
+
133
167
  /**
134
168
  * A node is "valid" if it is contained by a currently mounted container.
135
169
  *
@@ -193,6 +227,24 @@ function findDeepestCachedAncestor(targetID) {
193
227
  return foundNode;
194
228
  }
195
229
 
230
+ /**
231
+ * Mounts this component and inserts it into the DOM.
232
+ *
233
+ * @param {string} rootID DOM ID of the root node.
234
+ * @param {DOMElement} container DOM element to mount into.
235
+ * @param {ReactReconcileTransaction} transaction
236
+ * @param {boolean} shouldReuseMarkup If true, do not insert markup
237
+ */
238
+ function mountComponentIntoNode(
239
+ rootID,
240
+ container,
241
+ transaction,
242
+ shouldReuseMarkup) {
243
+ var markup = this.mountComponent(rootID, transaction, emptyObject);
244
+ this._isTopLevel = true;
245
+ ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup);
246
+ }
247
+
196
248
  /**
197
249
  * Mounting is the process of initializing a React component by creatings its
198
250
  * representative DOM elements and inserting them into a supplied `container`.
@@ -230,16 +282,16 @@ var ReactMount = {
230
282
  /**
231
283
  * Take a component that's already mounted into the DOM and replace its props
232
284
  * @param {ReactComponent} prevComponent component instance already in the DOM
233
- * @param {ReactComponent} nextComponent component instance to render
285
+ * @param {ReactElement} nextElement component instance to render
234
286
  * @param {DOMElement} container container to render into
235
287
  * @param {?function} callback function triggered on completion
236
288
  */
237
289
  _updateRootComponent: function(
238
290
  prevComponent,
239
- nextComponent,
291
+ nextElement,
240
292
  container,
241
293
  callback) {
242
- var nextProps = nextComponent.props;
294
+ var nextProps = nextElement.props;
243
295
  ReactMount.scrollMonitor(container, function() {
244
296
  prevComponent.replaceProps(nextProps, callback);
245
297
  });
@@ -263,13 +315,11 @@ var ReactMount = {
263
315
  _registerComponent: function(nextComponent, container) {
264
316
  ("production" !== process.env.NODE_ENV ? invariant(
265
317
  container && (
266
- container.nodeType === ELEMENT_NODE_TYPE ||
267
- container.nodeType === DOC_NODE_TYPE
318
+ (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
268
319
  ),
269
320
  '_registerComponent(...): Target container is not a DOM element.'
270
321
  ) : invariant(container && (
271
- container.nodeType === ELEMENT_NODE_TYPE ||
272
- container.nodeType === DOC_NODE_TYPE
322
+ (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
273
323
  )));
274
324
 
275
325
  ReactBrowserEventEmitter.ensureScrollValueMonitoring();
@@ -286,44 +336,47 @@ var ReactMount = {
286
336
  * @param {boolean} shouldReuseMarkup if we should skip the markup insertion
287
337
  * @return {ReactComponent} nextComponent
288
338
  */
289
- _renderNewRootComponent: ReactPerf.measure(
290
- 'ReactMount',
291
- '_renderNewRootComponent',
292
- function(
293
- nextComponent,
294
- container,
295
- shouldReuseMarkup) {
296
- // Various parts of our code (such as ReactCompositeComponent's
297
- // _renderValidatedComponent) assume that calls to render aren't nested;
298
- // verify that that's the case.
299
- ("production" !== process.env.NODE_ENV ? warning(
300
- ReactCurrentOwner.current == null,
301
- '_renderNewRootComponent(): Render methods should be a pure function ' +
302
- 'of props and state; triggering nested component updates from ' +
303
- 'render is not allowed. If necessary, trigger nested updates in ' +
304
- 'componentDidUpdate.'
305
- ) : null);
306
-
307
- var componentInstance = instantiateReactComponent(nextComponent, null);
308
- var reactRootID = ReactMount._registerComponent(
309
- componentInstance,
310
- container
311
- );
312
- componentInstance.mountComponentIntoNode(
313
- reactRootID,
314
- container,
315
- shouldReuseMarkup
316
- );
317
-
318
- if ("production" !== process.env.NODE_ENV) {
319
- // Record the root element in case it later gets transplanted.
320
- rootElementsByReactRootID[reactRootID] =
321
- getReactRootElementInContainer(container);
322
- }
339
+ _renderNewRootComponent: function(
340
+ nextComponent,
341
+ container,
342
+ shouldReuseMarkup
343
+ ) {
344
+ // Various parts of our code (such as ReactCompositeComponent's
345
+ // _renderValidatedComponent) assume that calls to render aren't nested;
346
+ // verify that that's the case.
347
+ ("production" !== process.env.NODE_ENV ? warning(
348
+ ReactCurrentOwner.current == null,
349
+ '_renderNewRootComponent(): Render methods should be a pure function ' +
350
+ 'of props and state; triggering nested component updates from ' +
351
+ 'render is not allowed. If necessary, trigger nested updates in ' +
352
+ 'componentDidUpdate.'
353
+ ) : null);
323
354
 
324
- return componentInstance;
355
+ var componentInstance = instantiateReactComponent(nextComponent, null);
356
+ var reactRootID = ReactMount._registerComponent(
357
+ componentInstance,
358
+ container
359
+ );
360
+
361
+ var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
362
+ transaction.perform(
363
+ mountComponentIntoNode,
364
+ componentInstance,
365
+ reactRootID,
366
+ container,
367
+ transaction,
368
+ shouldReuseMarkup
369
+ );
370
+ ReactUpdates.ReactReconcileTransaction.release(transaction);
371
+
372
+ if ("production" !== process.env.NODE_ENV) {
373
+ // Record the root element in case it later gets transplanted.
374
+ rootElementsByReactRootID[reactRootID] =
375
+ getReactRootElementInContainer(container);
325
376
  }
326
- ),
377
+
378
+ return componentInstance;
379
+ },
327
380
 
328
381
  /**
329
382
  * Renders a React component into the DOM in the supplied `container`.
@@ -340,16 +393,16 @@ var ReactMount = {
340
393
  render: function(nextElement, container, callback) {
341
394
  ("production" !== process.env.NODE_ENV ? invariant(
342
395
  ReactElement.isValidElement(nextElement),
343
- 'renderComponent(): Invalid component element.%s',
396
+ 'React.render(): Invalid component element.%s',
344
397
  (
345
398
  typeof nextElement === 'string' ?
346
399
  ' Instead of passing an element string, make sure to instantiate ' +
347
400
  'it by passing it to React.createElement.' :
348
- ReactLegacyElement.isValidFactory(nextElement) ?
401
+ typeof nextElement === 'function' ?
349
402
  ' Instead of passing a component class, make sure to instantiate ' +
350
403
  'it by passing it to React.createElement.' :
351
- // Check if it quacks like a element
352
- typeof nextElement.props !== "undefined" ?
404
+ // Check if it quacks like an element
405
+ nextElement != null && nextElement.props !== undefined ?
353
406
  ' This may be caused by unintentionally loading two independent ' +
354
407
  'copies of React.' :
355
408
  ''
@@ -366,7 +419,7 @@ var ReactMount = {
366
419
  nextElement,
367
420
  container,
368
421
  callback
369
- );
422
+ ).getPublicInstance();
370
423
  } else {
371
424
  ReactMount.unmountComponentAtNode(container);
372
425
  }
@@ -382,7 +435,7 @@ var ReactMount = {
382
435
  nextElement,
383
436
  container,
384
437
  shouldReuseMarkup
385
- );
438
+ ).getPublicInstance();
386
439
  callback && callback.call(component);
387
440
  return component;
388
441
  },
@@ -397,7 +450,7 @@ var ReactMount = {
397
450
  * @return {ReactComponent} Component instance rendered in `container`.
398
451
  */
399
452
  constructAndRenderComponent: function(constructor, props, container) {
400
- var element = createElement(constructor, props);
453
+ var element = ReactElement.createElement(constructor, props);
401
454
  return ReactMount.render(element, container);
402
455
  },
403
456
 
@@ -462,6 +515,15 @@ var ReactMount = {
462
515
  'componentDidUpdate.'
463
516
  ) : null);
464
517
 
518
+ ("production" !== process.env.NODE_ENV ? invariant(
519
+ container && (
520
+ (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
521
+ ),
522
+ 'unmountComponentAtNode(...): Target container is not a DOM element.'
523
+ ) : invariant(container && (
524
+ (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
525
+ )));
526
+
465
527
  var reactRootID = getReactRootID(container);
466
528
  var component = instancesByReactRootID[reactRootID];
467
529
  if (!component) {
@@ -666,6 +728,75 @@ var ReactMount = {
666
728
  ) : invariant(false));
667
729
  },
668
730
 
731
+ _mountImageIntoNode: function(markup, container, shouldReuseMarkup) {
732
+ ("production" !== process.env.NODE_ENV ? invariant(
733
+ container && (
734
+ (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
735
+ ),
736
+ 'mountComponentIntoNode(...): Target container is not valid.'
737
+ ) : invariant(container && (
738
+ (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
739
+ )));
740
+
741
+ if (shouldReuseMarkup) {
742
+ var rootElement = getReactRootElementInContainer(container);
743
+ if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) {
744
+ return;
745
+ } else {
746
+ var checksum = rootElement.getAttribute(
747
+ ReactMarkupChecksum.CHECKSUM_ATTR_NAME
748
+ );
749
+ rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);
750
+
751
+ var rootMarkup = rootElement.outerHTML;
752
+ rootElement.setAttribute(
753
+ ReactMarkupChecksum.CHECKSUM_ATTR_NAME,
754
+ checksum
755
+ );
756
+
757
+ var diffIndex = firstDifferenceIndex(markup, rootMarkup);
758
+ var difference = ' (client) ' +
759
+ markup.substring(diffIndex - 20, diffIndex + 20) +
760
+ '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20);
761
+
762
+ ("production" !== process.env.NODE_ENV ? invariant(
763
+ container.nodeType !== DOC_NODE_TYPE,
764
+ 'You\'re trying to render a component to the document using ' +
765
+ 'server rendering but the checksum was invalid. This usually ' +
766
+ 'means you rendered a different component type or props on ' +
767
+ 'the client from the one on the server, or your render() ' +
768
+ 'methods are impure. React cannot handle this case due to ' +
769
+ 'cross-browser quirks by rendering at the document root. You ' +
770
+ 'should look for environment dependent code in your components ' +
771
+ 'and ensure the props are the same client and server side:\n%s',
772
+ difference
773
+ ) : invariant(container.nodeType !== DOC_NODE_TYPE));
774
+
775
+ if ("production" !== process.env.NODE_ENV) {
776
+ console.warn(
777
+ 'React attempted to use reuse markup in a container but the ' +
778
+ 'checksum was invalid. This generally means that you are ' +
779
+ 'using server rendering and the markup generated on the ' +
780
+ 'server was not what the client was expecting. React injected ' +
781
+ 'new markup to compensate which works but you have lost many ' +
782
+ 'of the benefits of server rendering. Instead, figure out ' +
783
+ 'why the markup being generated is different on the client ' +
784
+ 'or server:\n' + difference
785
+ );
786
+ }
787
+ }
788
+ }
789
+
790
+ ("production" !== process.env.NODE_ENV ? invariant(
791
+ container.nodeType !== DOC_NODE_TYPE,
792
+ 'You\'re trying to render a component to the document but ' +
793
+ 'you didn\'t use server rendering. We can\'t do this ' +
794
+ 'without using server rendering due to cross-browser quirks. ' +
795
+ 'See React.renderToString() for server rendering.'
796
+ ) : invariant(container.nodeType !== DOC_NODE_TYPE));
797
+
798
+ setInnerHTML(container, markup);
799
+ },
669
800
 
670
801
  /**
671
802
  * React ID utilities.
@@ -679,16 +810,14 @@ var ReactMount = {
679
810
 
680
811
  getNode: getNode,
681
812
 
813
+ getNodeFromInstance: getNodeFromInstance,
814
+
682
815
  purgeID: purgeID
683
816
  };
684
817
 
685
- // Deprecations (remove for 0.13)
686
- ReactMount.renderComponent = deprecated(
687
- 'ReactMount',
688
- 'renderComponent',
689
- 'render',
690
- this,
691
- ReactMount.render
692
- );
818
+ ReactPerf.measureMethods(ReactMount, 'ReactMount', {
819
+ _renderNewRootComponent: '_renderNewRootComponent',
820
+ _mountImageIntoNode: '_mountImageIntoNode'
821
+ });
693
822
 
694
823
  module.exports = ReactMount;
@@ -12,12 +12,10 @@
12
12
 
13
13
  "use strict";
14
14
 
15
- var ReactComponent = require("./ReactComponent");
15
+ var ReactComponentEnvironment = require("./ReactComponentEnvironment");
16
16
  var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
17
17
 
18
- var flattenChildren = require("./flattenChildren");
19
- var instantiateReactComponent = require("./instantiateReactComponent");
20
- var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
18
+ var ReactChildReconciler = require("./ReactChildReconciler");
21
19
 
22
20
  /**
23
21
  * Updating children of a component may trigger recursive updates. The depth is
@@ -135,7 +133,7 @@ function enqueueTextContent(parentID, textContent) {
135
133
  */
136
134
  function processQueue() {
137
135
  if (updateQueue.length) {
138
- ReactComponent.BackendIDOperations.dangerouslyProcessChildrenUpdates(
136
+ ReactComponentEnvironment.processChildrenUpdates(
139
137
  updateQueue,
140
138
  markupQueue
141
139
  );
@@ -178,26 +176,24 @@ var ReactMultiChild = {
178
176
  * @return {array} An array of mounted representations.
179
177
  * @internal
180
178
  */
181
- mountChildren: function(nestedChildren, transaction) {
182
- var children = flattenChildren(nestedChildren);
179
+ mountChildren: function(nestedChildren, transaction, context) {
180
+ var children = ReactChildReconciler.instantiateChildren(
181
+ nestedChildren, transaction, context
182
+ );
183
+ this._renderedChildren = children;
183
184
  var mountImages = [];
184
185
  var index = 0;
185
- this._renderedChildren = children;
186
186
  for (var name in children) {
187
187
  var child = children[name];
188
188
  if (children.hasOwnProperty(name)) {
189
- // The rendered children must be turned into instances as they're
190
- // mounted.
191
- var childInstance = instantiateReactComponent(child, null);
192
- children[name] = childInstance;
193
189
  // Inlined for performance, see `ReactInstanceHandles.createReactID`.
194
190
  var rootID = this._rootNodeID + name;
195
- var mountImage = childInstance.mountComponent(
191
+ var mountImage = child.mountComponent(
196
192
  rootID,
197
193
  transaction,
198
- this._mountDepth + 1
194
+ context
199
195
  );
200
- childInstance._mountIndex = index;
196
+ child._mountIndex = index;
201
197
  mountImages.push(mountImage);
202
198
  index++;
203
199
  }
@@ -217,6 +213,8 @@ var ReactMultiChild = {
217
213
  try {
218
214
  var prevChildren = this._renderedChildren;
219
215
  // Remove any rendered children.
216
+ ReactChildReconciler.unmountChildren(prevChildren);
217
+ // TODO: The setTextContent operation should be enough
220
218
  for (var name in prevChildren) {
221
219
  if (prevChildren.hasOwnProperty(name)) {
222
220
  this._unmountChildByName(prevChildren[name], name);
@@ -240,11 +238,11 @@ var ReactMultiChild = {
240
238
  * @param {ReactReconcileTransaction} transaction
241
239
  * @internal
242
240
  */
243
- updateChildren: function(nextNestedChildren, transaction) {
241
+ updateChildren: function(nextNestedChildren, transaction, context) {
244
242
  updateDepth++;
245
243
  var errorThrown = true;
246
244
  try {
247
- this._updateChildren(nextNestedChildren, transaction);
245
+ this._updateChildren(nextNestedChildren, transaction, context);
248
246
  errorThrown = false;
249
247
  } finally {
250
248
  updateDepth--;
@@ -263,9 +261,12 @@ var ReactMultiChild = {
263
261
  * @final
264
262
  * @protected
265
263
  */
266
- _updateChildren: function(nextNestedChildren, transaction) {
267
- var nextChildren = flattenChildren(nextNestedChildren);
264
+ _updateChildren: function(nextNestedChildren, transaction, context) {
268
265
  var prevChildren = this._renderedChildren;
266
+ var nextChildren = ReactChildReconciler.updateChildren(
267
+ prevChildren, nextNestedChildren, transaction, context
268
+ );
269
+ this._renderedChildren = nextChildren;
269
270
  if (!nextChildren && !prevChildren) {
270
271
  return;
271
272
  }
@@ -279,12 +280,10 @@ var ReactMultiChild = {
279
280
  continue;
280
281
  }
281
282
  var prevChild = prevChildren && prevChildren[name];
282
- var prevElement = prevChild && prevChild._currentElement;
283
- var nextElement = nextChildren[name];
284
- if (shouldUpdateReactComponent(prevElement, nextElement)) {
283
+ var nextChild = nextChildren[name];
284
+ if (prevChild === nextChild) {
285
285
  this.moveChild(prevChild, nextIndex, lastIndex);
286
286
  lastIndex = Math.max(prevChild._mountIndex, lastIndex);
287
- prevChild.receiveComponent(nextElement, transaction);
288
287
  prevChild._mountIndex = nextIndex;
289
288
  } else {
290
289
  if (prevChild) {
@@ -293,12 +292,8 @@ var ReactMultiChild = {
293
292
  this._unmountChildByName(prevChild, name);
294
293
  }
295
294
  // The child must be instantiated before it's mounted.
296
- var nextChildInstance = instantiateReactComponent(
297
- nextElement,
298
- null
299
- );
300
295
  this._mountChildByNameAtIndex(
301
- nextChildInstance, name, nextIndex, transaction
296
+ nextChild, name, nextIndex, transaction, context
302
297
  );
303
298
  }
304
299
  nextIndex++;
@@ -306,7 +301,7 @@ var ReactMultiChild = {
306
301
  // Remove children that are no longer present.
307
302
  for (name in prevChildren) {
308
303
  if (prevChildren.hasOwnProperty(name) &&
309
- !(nextChildren && nextChildren[name])) {
304
+ !(nextChildren && nextChildren.hasOwnProperty(name))) {
310
305
  this._unmountChildByName(prevChildren[name], name);
311
306
  }
312
307
  }
@@ -320,13 +315,7 @@ var ReactMultiChild = {
320
315
  */
321
316
  unmountChildren: function() {
322
317
  var renderedChildren = this._renderedChildren;
323
- for (var name in renderedChildren) {
324
- var renderedChild = renderedChildren[name];
325
- // TODO: When is this not true?
326
- if (renderedChild.unmountComponent) {
327
- renderedChild.unmountComponent();
328
- }
329
- }
318
+ ReactChildReconciler.unmountChildren(renderedChildren);
330
319
  this._renderedChildren = null;
331
320
  },
332
321
 
@@ -389,18 +378,21 @@ var ReactMultiChild = {
389
378
  * @param {ReactReconcileTransaction} transaction
390
379
  * @private
391
380
  */
392
- _mountChildByNameAtIndex: function(child, name, index, transaction) {
381
+ _mountChildByNameAtIndex: function(
382
+ child,
383
+ name,
384
+ index,
385
+ transaction,
386
+ context) {
393
387
  // Inlined for performance, see `ReactInstanceHandles.createReactID`.
394
388
  var rootID = this._rootNodeID + name;
395
389
  var mountImage = child.mountComponent(
396
390
  rootID,
397
391
  transaction,
398
- this._mountDepth + 1
392
+ context
399
393
  );
400
394
  child._mountIndex = index;
401
395
  this.createChild(child, mountImage);
402
- this._renderedChildren = this._renderedChildren || {};
403
- this._renderedChildren[name] = child;
404
396
  },
405
397
 
406
398
  /**
@@ -415,8 +407,6 @@ var ReactMultiChild = {
415
407
  _unmountChildByName: function(child, name) {
416
408
  this.removeChild(child);
417
409
  child._mountIndex = null;
418
- child.unmountComponent();
419
- delete this._renderedChildren[name];
420
410
  }
421
411
 
422
412
  }