react 0.7.1 → 0.8.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 (203) hide show
  1. package/README.md +15 -228
  2. package/ReactJSErrors.js +40 -0
  3. package/addons.js +4 -0
  4. package/lib/$.js +46 -0
  5. package/lib/CSSCore.js +114 -0
  6. package/lib/CSSProperty.js +90 -0
  7. package/lib/CSSPropertyOperations.js +97 -0
  8. package/lib/CallbackRegistry.js +91 -0
  9. package/lib/ChangeEventPlugin.js +365 -0
  10. package/lib/CompositionEventPlugin.js +212 -0
  11. package/lib/DOMChildrenOperations.js +135 -0
  12. package/lib/DOMProperty.js +266 -0
  13. package/lib/DOMPropertyOperations.js +168 -0
  14. package/lib/Danger.js +186 -0
  15. package/lib/DefaultDOMPropertyConfig.js +187 -0
  16. package/lib/DefaultEventPluginOrder.js +44 -0
  17. package/lib/EnterLeaveEventPlugin.js +112 -0
  18. package/lib/EventConstants.js +73 -0
  19. package/lib/EventListener.js +61 -0
  20. package/lib/EventPluginHub.js +190 -0
  21. package/lib/EventPluginRegistry.js +237 -0
  22. package/lib/EventPluginUtils.js +185 -0
  23. package/lib/EventPropagators.js +179 -0
  24. package/lib/ExecutionEnvironment.js +41 -0
  25. package/lib/LinkedStateMixin.js +46 -0
  26. package/lib/LinkedValueMixin.js +68 -0
  27. package/lib/MobileSafariClickEventPlugin.js +63 -0
  28. package/lib/PooledClass.js +113 -0
  29. package/lib/React.js +71 -0
  30. package/lib/ReactChildren.js +132 -0
  31. package/lib/ReactComponent.js +515 -0
  32. package/lib/ReactComponentBrowserEnvironment.js +140 -0
  33. package/lib/ReactComponentEnvironment.js +24 -0
  34. package/lib/ReactCompositeComponent.js +1020 -0
  35. package/lib/ReactCurrentOwner.js +39 -0
  36. package/lib/ReactDOM.js +194 -0
  37. package/lib/ReactDOMButton.js +64 -0
  38. package/lib/ReactDOMComponent.js +374 -0
  39. package/lib/ReactDOMForm.js +52 -0
  40. package/lib/ReactDOMIDOperations.js +173 -0
  41. package/lib/ReactDOMInput.js +169 -0
  42. package/lib/ReactDOMOption.js +50 -0
  43. package/lib/ReactDOMSelect.js +160 -0
  44. package/lib/ReactDOMSelection.js +189 -0
  45. package/lib/ReactDOMTextarea.js +136 -0
  46. package/lib/ReactDefaultBatchingStrategy.js +75 -0
  47. package/lib/ReactDefaultInjection.js +91 -0
  48. package/lib/ReactDefaultPerf.js +407 -0
  49. package/lib/ReactErrorUtils.js +46 -0
  50. package/lib/ReactEventEmitter.js +341 -0
  51. package/lib/ReactEventEmitterMixin.js +89 -0
  52. package/lib/ReactEventTopLevelCallback.js +89 -0
  53. package/lib/ReactInputSelection.js +140 -0
  54. package/lib/ReactInstanceHandles.js +322 -0
  55. package/lib/ReactLink.js +54 -0
  56. package/lib/ReactMarkupChecksum.js +53 -0
  57. package/lib/ReactMount.js +617 -0
  58. package/lib/ReactMountReady.js +95 -0
  59. package/lib/ReactMultiChild.js +441 -0
  60. package/lib/ReactMultiChildUpdateTypes.js +36 -0
  61. package/lib/ReactOwner.js +146 -0
  62. package/lib/ReactPerf.js +88 -0
  63. package/lib/ReactPropTransferer.js +128 -0
  64. package/lib/ReactPropTypes.js +158 -0
  65. package/lib/ReactReconcileTransaction.js +161 -0
  66. package/lib/ReactServerRendering.js +62 -0
  67. package/lib/ReactStateSetters.js +111 -0
  68. package/lib/ReactTextComponent.js +94 -0
  69. package/lib/ReactTransitionEvents.js +97 -0
  70. package/lib/ReactTransitionGroup.js +112 -0
  71. package/lib/ReactTransitionKeySet.js +111 -0
  72. package/lib/ReactTransitionableChild.js +152 -0
  73. package/lib/ReactUpdates.js +145 -0
  74. package/lib/ReactWithAddons.js +41 -0
  75. package/lib/SelectEventPlugin.js +217 -0
  76. package/lib/SimpleEventPlugin.js +365 -0
  77. package/lib/SyntheticClipboardEvent.js +45 -0
  78. package/lib/SyntheticCompositionEvent.js +51 -0
  79. package/lib/SyntheticEvent.js +163 -0
  80. package/lib/SyntheticFocusEvent.js +44 -0
  81. package/lib/SyntheticKeyboardEvent.js +56 -0
  82. package/lib/SyntheticMouseEvent.js +85 -0
  83. package/lib/SyntheticTouchEvent.js +50 -0
  84. package/lib/SyntheticUIEvent.js +45 -0
  85. package/lib/SyntheticWheelEvent.js +63 -0
  86. package/lib/Transaction.js +251 -0
  87. package/lib/ViewportMetrics.js +37 -0
  88. package/lib/accumulate.js +54 -0
  89. package/lib/adler32.js +39 -0
  90. package/lib/containsNode.js +49 -0
  91. package/lib/copyProperties.js +54 -0
  92. package/lib/createArrayFrom.js +94 -0
  93. package/lib/createNodesFromMarkup.js +93 -0
  94. package/lib/createObjectFrom.js +61 -0
  95. package/lib/cx.js +44 -0
  96. package/lib/dangerousStyleValue.js +57 -0
  97. package/lib/emptyFunction.js +43 -0
  98. package/lib/escapeTextForBrowser.js +47 -0
  99. package/lib/ex.js +49 -0
  100. package/lib/filterAttributes.js +45 -0
  101. package/lib/flattenChildren.js +54 -0
  102. package/lib/forEachAccumulated.js +36 -0
  103. package/lib/ge.js +76 -0
  104. package/lib/getActiveElement.js +33 -0
  105. package/lib/getEventTarget.js +36 -0
  106. package/lib/getMarkupWrap.js +108 -0
  107. package/lib/getNodeForCharacterOffset.js +80 -0
  108. package/lib/getReactRootElementInContainer.js +40 -0
  109. package/lib/getTextContentAccessor.js +40 -0
  110. package/lib/getUnboundedScrollPosition.js +45 -0
  111. package/lib/hyphenate.js +35 -0
  112. package/lib/invariant.js +54 -0
  113. package/lib/isEventSupported.js +74 -0
  114. package/lib/isNode.js +33 -0
  115. package/lib/isTextInputElement.js +49 -0
  116. package/lib/isTextNode.js +30 -0
  117. package/lib/joinClasses.js +44 -0
  118. package/lib/keyMirror.js +58 -0
  119. package/lib/keyOf.js +41 -0
  120. package/lib/memoizeStringOnly.js +39 -0
  121. package/lib/merge.js +37 -0
  122. package/lib/mergeHelpers.js +137 -0
  123. package/lib/mergeInto.js +45 -0
  124. package/lib/mixInto.js +34 -0
  125. package/lib/mutateHTMLNodeWithMarkup.js +100 -0
  126. package/lib/objMap.js +47 -0
  127. package/lib/objMapKeyVal.js +47 -0
  128. package/lib/performanceNow.js +42 -0
  129. package/lib/shallowEqual.js +49 -0
  130. package/lib/traverseAllChildren.js +127 -0
  131. package/package.json +33 -31
  132. package/react.js +4 -0
  133. package/.npmignore +0 -7
  134. package/.travis.yml +0 -7
  135. package/Jakefile.js +0 -39
  136. package/LICENSE +0 -19
  137. package/browser-test/dist.html +0 -90
  138. package/browser-test/index.html +0 -86
  139. package/browser-test/min.html +0 -90
  140. package/dist/react.js +0 -3141
  141. package/dist/react.min.js +0 -22
  142. package/doc/advanced.md +0 -175
  143. package/doc/color-def.graffle +0 -938
  144. package/doc/color-def.png +0 -0
  145. package/doc/simple.dot +0 -25
  146. package/doc/simple.png +0 -0
  147. package/examples/longer-example.js +0 -41
  148. package/examples/simple.js +0 -45
  149. package/examples/using-ast-directly.js +0 -30
  150. package/examples/using-events1.js +0 -79
  151. package/examples/using-log-events.js +0 -43
  152. package/lib/base-task.js +0 -120
  153. package/lib/cb-task.js +0 -84
  154. package/lib/core.js +0 -138
  155. package/lib/dsl.js +0 -138
  156. package/lib/error.js +0 -55
  157. package/lib/event-collector.js +0 -81
  158. package/lib/event-manager.js +0 -89
  159. package/lib/eventemitter.js +0 -20
  160. package/lib/finalcb-first-task.js +0 -68
  161. package/lib/finalcb-task.js +0 -65
  162. package/lib/id.js +0 -22
  163. package/lib/input-parser.js +0 -56
  164. package/lib/log-events.js +0 -101
  165. package/lib/parse.js +0 -41
  166. package/lib/promise-resolve.js +0 -50
  167. package/lib/promise-task.js +0 -93
  168. package/lib/react.js +0 -59
  169. package/lib/ret-task.js +0 -71
  170. package/lib/sprintf.js +0 -18
  171. package/lib/status.js +0 -14
  172. package/lib/task.js +0 -251
  173. package/lib/track-tasks.js +0 -74
  174. package/lib/validate.js +0 -159
  175. package/lib/vcon.js +0 -113
  176. package/lib/when-task.js +0 -84
  177. package/src/dist.build.requirejs +0 -20
  178. package/test/ast.mocha.js +0 -136
  179. package/test/cb-task.mocha.js +0 -220
  180. package/test/core-deferred.mocha.js +0 -143
  181. package/test/core-when.mocha.js +0 -96
  182. package/test/core.mocha.js +0 -589
  183. package/test/dsl.mocha.js +0 -352
  184. package/test/event-manager.mocha.js +0 -119
  185. package/test/exec-options.mocha.js +0 -48
  186. package/test/finalcb-task.mocha.js +0 -58
  187. package/test/input-parser.mocha.js +0 -86
  188. package/test/log-events.mocha.js +0 -88
  189. package/test/mocha.opts +0 -2
  190. package/test/module-use.mocha.js +0 -164
  191. package/test/promise-auto-resolve.mocha.js +0 -68
  192. package/test/ret-task.mocha.js +0 -220
  193. package/test/task.mocha.js +0 -42
  194. package/test/validate-cb-task.mocha.js +0 -100
  195. package/test/validate-ret-task.mocha.js +0 -110
  196. package/test/validate.mocha.js +0 -324
  197. package/test/vcon.mocha.js +0 -193
  198. package/vendor/chai/chai.js +0 -4251
  199. package/vendor/jquery/jquery-1.7.1.js +0 -9266
  200. package/vendor/jquery/jquery-1.7.1.min.js +0 -4
  201. package/vendor/node/util.js +0 -531
  202. package/vendor/requirejs/require.js +0 -2045
  203. package/vendor/requirejs/require.min.js +0 -36
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Copyright 2013 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 ReactMountReady
17
+ */
18
+
19
+ "use strict";
20
+
21
+ var PooledClass = require("./PooledClass");
22
+
23
+ var mixInto = require("./mixInto");
24
+
25
+ /**
26
+ * A specialized pseudo-event module to help keep track of components waiting to
27
+ * be notified when their DOM representations are available for use.
28
+ *
29
+ * This implements `PooledClass`, so you should never need to instantiate this.
30
+ * Instead, use `ReactMountReady.getPooled()`.
31
+ *
32
+ * @param {?array<function>} initialCollection
33
+ * @class ReactMountReady
34
+ * @implements PooledClass
35
+ * @internal
36
+ */
37
+ function ReactMountReady(initialCollection) {
38
+ this._queue = initialCollection || null;
39
+ }
40
+
41
+ mixInto(ReactMountReady, {
42
+
43
+ /**
44
+ * Enqueues a callback to be invoked when `notifyAll` is invoked. This is used
45
+ * to enqueue calls to `componentDidMount` and `componentDidUpdate`.
46
+ *
47
+ * @param {ReactComponent} component Component being rendered.
48
+ * @param {function(DOMElement)} callback Invoked when `notifyAll` is invoked.
49
+ * @internal
50
+ */
51
+ enqueue: function(component, callback) {
52
+ this._queue = this._queue || [];
53
+ this._queue.push({component: component, callback: callback});
54
+ },
55
+
56
+ /**
57
+ * Invokes all enqueued callbacks and clears the queue. This is invoked after
58
+ * the DOM representation of a component has been created or updated.
59
+ *
60
+ * @internal
61
+ */
62
+ notifyAll: function() {
63
+ var queue = this._queue;
64
+ if (queue) {
65
+ this._queue = null;
66
+ for (var i = 0, l = queue.length; i < l; i++) {
67
+ var component = queue[i].component;
68
+ var callback = queue[i].callback;
69
+ callback.call(component, component.getDOMNode());
70
+ }
71
+ queue.length = 0;
72
+ }
73
+ },
74
+
75
+ /**
76
+ * Resets the internal queue.
77
+ *
78
+ * @internal
79
+ */
80
+ reset: function() {
81
+ this._queue = null;
82
+ },
83
+
84
+ /**
85
+ * `PooledClass` looks for this.
86
+ */
87
+ destructor: function() {
88
+ this.reset();
89
+ }
90
+
91
+ });
92
+
93
+ PooledClass.addPoolingTo(ReactMountReady);
94
+
95
+ module.exports = ReactMountReady;
@@ -0,0 +1,441 @@
1
+ /**
2
+ * Copyright 2013 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 ReactMultiChild
17
+ * @typechecks static-only
18
+ */
19
+
20
+ "use strict";
21
+
22
+ var ReactComponent = require("./ReactComponent");
23
+ var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
24
+
25
+ var flattenChildren = require("./flattenChildren");
26
+
27
+ /**
28
+ * Given a `curChild` and `newChild`, determines if `curChild` should be
29
+ * updated as opposed to being destroyed or replaced.
30
+ *
31
+ * @param {?ReactComponent} curChild
32
+ * @param {?ReactComponent} newChild
33
+ * @return {boolean} True if `curChild` should be updated with `newChild`.
34
+ * @protected
35
+ */
36
+ function shouldUpdateChild(curChild, newChild) {
37
+ return curChild && newChild && curChild.constructor === newChild.constructor;
38
+ }
39
+
40
+ /**
41
+ * Updating children of a component may trigger recursive updates. The depth is
42
+ * used to batch recursive updates to render markup more efficiently.
43
+ *
44
+ * @type {number}
45
+ * @private
46
+ */
47
+ var updateDepth = 0;
48
+
49
+ /**
50
+ * Queue of update configuration objects.
51
+ *
52
+ * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`.
53
+ *
54
+ * @type {array<object>}
55
+ * @private
56
+ */
57
+ var updateQueue = [];
58
+
59
+ /**
60
+ * Queue of markup to be rendered.
61
+ *
62
+ * @type {array<string>}
63
+ * @private
64
+ */
65
+ var markupQueue = [];
66
+
67
+ /**
68
+ * Enqueues markup to be rendered and inserted at a supplied index.
69
+ *
70
+ * @param {string} parentID ID of the parent component.
71
+ * @param {string} markup Markup that renders into an element.
72
+ * @param {number} toIndex Destination index.
73
+ * @private
74
+ */
75
+ function enqueueMarkup(parentID, markup, toIndex) {
76
+ // NOTE: Null values reduce hidden classes.
77
+ updateQueue.push({
78
+ parentID: parentID,
79
+ parentNode: null,
80
+ type: ReactMultiChildUpdateTypes.INSERT_MARKUP,
81
+ markupIndex: markupQueue.push(markup) - 1,
82
+ textContent: null,
83
+ fromIndex: null,
84
+ toIndex: toIndex
85
+ });
86
+ }
87
+
88
+ /**
89
+ * Enqueues moving an existing element to another index.
90
+ *
91
+ * @param {string} parentID ID of the parent component.
92
+ * @param {number} fromIndex Source index of the existing element.
93
+ * @param {number} toIndex Destination index of the element.
94
+ * @private
95
+ */
96
+ function enqueueMove(parentID, fromIndex, toIndex) {
97
+ // NOTE: Null values reduce hidden classes.
98
+ updateQueue.push({
99
+ parentID: parentID,
100
+ parentNode: null,
101
+ type: ReactMultiChildUpdateTypes.MOVE_EXISTING,
102
+ markupIndex: null,
103
+ textContent: null,
104
+ fromIndex: fromIndex,
105
+ toIndex: toIndex
106
+ });
107
+ }
108
+
109
+ /**
110
+ * Enqueues removing an element at an index.
111
+ *
112
+ * @param {string} parentID ID of the parent component.
113
+ * @param {number} fromIndex Index of the element to remove.
114
+ * @private
115
+ */
116
+ function enqueueRemove(parentID, fromIndex) {
117
+ // NOTE: Null values reduce hidden classes.
118
+ updateQueue.push({
119
+ parentID: parentID,
120
+ parentNode: null,
121
+ type: ReactMultiChildUpdateTypes.REMOVE_NODE,
122
+ markupIndex: null,
123
+ textContent: null,
124
+ fromIndex: fromIndex,
125
+ toIndex: null
126
+ });
127
+ }
128
+
129
+ /**
130
+ * Enqueues setting the text content.
131
+ *
132
+ * @param {string} parentID ID of the parent component.
133
+ * @param {string} textContent Text content to set.
134
+ * @private
135
+ */
136
+ function enqueueTextContent(parentID, textContent) {
137
+ // NOTE: Null values reduce hidden classes.
138
+ updateQueue.push({
139
+ parentID: parentID,
140
+ parentNode: null,
141
+ type: ReactMultiChildUpdateTypes.TEXT_CONTENT,
142
+ markupIndex: null,
143
+ textContent: textContent,
144
+ fromIndex: null,
145
+ toIndex: null
146
+ });
147
+ }
148
+
149
+ /**
150
+ * Processes any enqueued updates.
151
+ *
152
+ * @private
153
+ */
154
+ function processQueue() {
155
+ if (updateQueue.length) {
156
+ ReactComponent.DOMIDOperations.dangerouslyProcessChildrenUpdates(
157
+ updateQueue,
158
+ markupQueue
159
+ );
160
+ clearQueue();
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Clears any enqueued updates.
166
+ *
167
+ * @private
168
+ */
169
+ function clearQueue() {
170
+ updateQueue.length = 0;
171
+ markupQueue.length = 0;
172
+ }
173
+
174
+ /**
175
+ * ReactMultiChild are capable of reconciling multiple children.
176
+ *
177
+ * @class ReactMultiChild
178
+ * @internal
179
+ */
180
+ var ReactMultiChild = {
181
+
182
+ /**
183
+ * Provides common functionality for components that must reconcile multiple
184
+ * children. This is used by `ReactDOMComponent` to mount, update, and
185
+ * unmount child components.
186
+ *
187
+ * @lends {ReactMultiChild.prototype}
188
+ */
189
+ Mixin: {
190
+
191
+ /**
192
+ * Generates a "mount image" for each of the supplied children. In the case
193
+ * of `ReactDOMComponent`, a mount image is a string of markup.
194
+ *
195
+ * @param {?object} nestedChildren Nested child maps.
196
+ * @return {array} An array of mounted representations.
197
+ * @internal
198
+ */
199
+ mountChildren: function(nestedChildren, transaction) {
200
+ var children = flattenChildren(nestedChildren);
201
+ var mountImages = [];
202
+ var index = 0;
203
+ this._renderedChildren = children;
204
+ for (var name in children) {
205
+ var child = children[name];
206
+ if (children.hasOwnProperty(name) && child) {
207
+ // Inlined for performance, see `ReactInstanceHandles.createReactID`.
208
+ var rootID = this._rootNodeID + '.' + name;
209
+ var mountImage = child.mountComponent(
210
+ rootID,
211
+ transaction,
212
+ this._mountDepth + 1
213
+ );
214
+ child._mountImage = mountImage;
215
+ child._mountIndex = index;
216
+ mountImages.push(mountImage);
217
+ index++;
218
+ }
219
+ }
220
+ return mountImages;
221
+ },
222
+
223
+ /**
224
+ * Replaces any rendered children with a text content string.
225
+ *
226
+ * @param {string} nextContent String of content.
227
+ * @internal
228
+ */
229
+ updateTextContent: function(nextContent) {
230
+ updateDepth++;
231
+ try {
232
+ var prevChildren = this._renderedChildren;
233
+ // Remove any rendered children.
234
+ for (var name in prevChildren) {
235
+ if (prevChildren.hasOwnProperty(name) &&
236
+ prevChildren[name]) {
237
+ this._unmountChildByName(prevChildren[name], name);
238
+ }
239
+ }
240
+ // Set new text content.
241
+ this.setTextContent(nextContent);
242
+ } catch (error) {
243
+ updateDepth--;
244
+ updateDepth || clearQueue();
245
+ throw error;
246
+ }
247
+ updateDepth--;
248
+ updateDepth || processQueue();
249
+ },
250
+
251
+ /**
252
+ * Updates the rendered children with new children.
253
+ *
254
+ * @param {?object} nextNestedChildren Nested child maps.
255
+ * @param {ReactReconcileTransaction} transaction
256
+ * @internal
257
+ */
258
+ updateChildren: function(nextNestedChildren, transaction) {
259
+ updateDepth++;
260
+ try {
261
+ this._updateChildren(nextNestedChildren, transaction);
262
+ } catch (error) {
263
+ updateDepth--;
264
+ updateDepth || clearQueue();
265
+ throw error;
266
+ }
267
+ updateDepth--;
268
+ updateDepth || processQueue();
269
+ },
270
+
271
+ /**
272
+ * Improve performance by isolating this hot code path from the try/catch
273
+ * block in `updateChildren`.
274
+ *
275
+ * @param {?object} nextNestedChildren Nested child maps.
276
+ * @param {ReactReconcileTransaction} transaction
277
+ * @final
278
+ * @protected
279
+ */
280
+ _updateChildren: function(nextNestedChildren, transaction) {
281
+ var nextChildren = flattenChildren(nextNestedChildren);
282
+ var prevChildren = this._renderedChildren;
283
+ if (!nextChildren && !prevChildren) {
284
+ return;
285
+ }
286
+ var name;
287
+ // `nextIndex` will increment for each child in `nextChildren`, but
288
+ // `lastIndex` will be the last index visited in `prevChildren`.
289
+ var lastIndex = 0;
290
+ var nextIndex = 0;
291
+ for (name in nextChildren) {
292
+ if (!nextChildren.hasOwnProperty(name)) {
293
+ continue;
294
+ }
295
+ var prevChild = prevChildren && prevChildren[name];
296
+ var nextChild = nextChildren[name];
297
+ if (shouldUpdateChild(prevChild, nextChild)) {
298
+ this.moveChild(prevChild, nextIndex, lastIndex);
299
+ lastIndex = Math.max(prevChild._mountIndex, lastIndex);
300
+ prevChild.receiveComponent(nextChild, transaction);
301
+ prevChild._mountIndex = nextIndex;
302
+ } else {
303
+ if (prevChild) {
304
+ // Update `lastIndex` before `_mountIndex` gets unset by unmounting.
305
+ lastIndex = Math.max(prevChild._mountIndex, lastIndex);
306
+ this._unmountChildByName(prevChild, name);
307
+ }
308
+ if (nextChild) {
309
+ this._mountChildByNameAtIndex(
310
+ nextChild, name, nextIndex, transaction
311
+ );
312
+ }
313
+ }
314
+ if (nextChild) {
315
+ nextIndex++;
316
+ }
317
+ }
318
+ // Remove children that are no longer present.
319
+ for (name in prevChildren) {
320
+ if (prevChildren.hasOwnProperty(name) &&
321
+ prevChildren[name] &&
322
+ !(nextChildren && nextChildren[name])) {
323
+ this._unmountChildByName(prevChildren[name], name);
324
+ }
325
+ }
326
+ },
327
+
328
+ /**
329
+ * Unmounts all rendered children. This should be used to clean up children
330
+ * when this component is unmounted.
331
+ *
332
+ * @internal
333
+ */
334
+ unmountChildren: function() {
335
+ var renderedChildren = this._renderedChildren;
336
+ for (var name in renderedChildren) {
337
+ var renderedChild = renderedChildren[name];
338
+ if (renderedChild && renderedChild.unmountComponent) {
339
+ renderedChild.unmountComponent();
340
+ }
341
+ }
342
+ this._renderedChildren = null;
343
+ },
344
+
345
+ /**
346
+ * Moves a child component to the supplied index.
347
+ *
348
+ * @param {ReactComponent} child Component to move.
349
+ * @param {number} toIndex Destination index of the element.
350
+ * @param {number} lastIndex Last index visited of the siblings of `child`.
351
+ * @protected
352
+ */
353
+ moveChild: function(child, toIndex, lastIndex) {
354
+ // If the index of `child` is less than `lastIndex`, then it needs to
355
+ // be moved. Otherwise, we do not need to move it because a child will be
356
+ // inserted or moved before `child`.
357
+ if (child._mountIndex < lastIndex) {
358
+ enqueueMove(this._rootNodeID, child._mountIndex, toIndex);
359
+ }
360
+ },
361
+
362
+ /**
363
+ * Creates a child component.
364
+ *
365
+ * @param {ReactComponent} child Component to create.
366
+ * @protected
367
+ */
368
+ createChild: function(child) {
369
+ enqueueMarkup(this._rootNodeID, child._mountImage, child._mountIndex);
370
+ },
371
+
372
+ /**
373
+ * Removes a child component.
374
+ *
375
+ * @param {ReactComponent} child Child to remove.
376
+ * @protected
377
+ */
378
+ removeChild: function(child) {
379
+ enqueueRemove(this._rootNodeID, child._mountIndex);
380
+ },
381
+
382
+ /**
383
+ * Sets this text content string.
384
+ *
385
+ * @param {string} textContent Text content to set.
386
+ * @protected
387
+ */
388
+ setTextContent: function(textContent) {
389
+ enqueueTextContent(this._rootNodeID, textContent);
390
+ },
391
+
392
+ /**
393
+ * Mounts a child with the supplied name.
394
+ *
395
+ * NOTE: This is part of `updateChildren` and is here for readability.
396
+ *
397
+ * @param {ReactComponent} child Component to mount.
398
+ * @param {string} name Name of the child.
399
+ * @param {number} index Index at which to insert the child.
400
+ * @param {ReactReconcileTransaction} transaction
401
+ * @private
402
+ */
403
+ _mountChildByNameAtIndex: function(child, name, index, transaction) {
404
+ // Inlined for performance, see `ReactInstanceHandles.createReactID`.
405
+ var rootID = this._rootNodeID + '.' + name;
406
+ var mountImage = child.mountComponent(
407
+ rootID,
408
+ transaction,
409
+ this._mountDepth + 1
410
+ );
411
+ child._mountImage = mountImage;
412
+ child._mountIndex = index;
413
+ this.createChild(child);
414
+ this._renderedChildren = this._renderedChildren || {};
415
+ this._renderedChildren[name] = child;
416
+ },
417
+
418
+ /**
419
+ * Unmounts a rendered child by name.
420
+ *
421
+ * NOTE: This is part of `updateChildren` and is here for readability.
422
+ *
423
+ * @param {ReactComponent} child Component to unmount.
424
+ * @param {string} name Name of the child in `this._renderedChildren`.
425
+ * @private
426
+ */
427
+ _unmountChildByName: function(child, name) {
428
+ if (ReactComponent.isValidComponent(child)) {
429
+ this.removeChild(child);
430
+ child._mountImage = null;
431
+ child._mountIndex = null;
432
+ child.unmountComponent();
433
+ delete this._renderedChildren[name];
434
+ }
435
+ }
436
+
437
+ }
438
+
439
+ };
440
+
441
+ module.exports = ReactMultiChild;