react 0.8.0 → 0.10.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 (160) hide show
  1. package/README.md +0 -8
  2. package/addons.js +0 -3
  3. package/lib/AutoFocusMixin.js +32 -0
  4. package/lib/CSSCore.js +23 -22
  5. package/lib/CSSProperty.js +32 -1
  6. package/lib/CSSPropertyOperations.js +1 -1
  7. package/lib/ChangeEventPlugin.js +27 -5
  8. package/lib/ClientReactRootIndex.js +30 -0
  9. package/lib/CompositionEventPlugin.js +58 -10
  10. package/lib/DOMChildrenOperations.js +39 -3
  11. package/lib/DOMProperty.js +9 -5
  12. package/lib/DOMPropertyOperations.js +21 -8
  13. package/lib/Danger.js +9 -8
  14. package/lib/DefaultDOMPropertyConfig.js +23 -14
  15. package/lib/DefaultEventPluginOrder.js +1 -1
  16. package/lib/EnterLeaveEventPlugin.js +38 -5
  17. package/lib/EventConstants.js +4 -1
  18. package/lib/EventListener.js +42 -34
  19. package/lib/EventPluginHub.js +118 -13
  20. package/lib/EventPluginRegistry.js +62 -18
  21. package/lib/EventPluginUtils.js +33 -4
  22. package/lib/EventPropagators.js +7 -43
  23. package/lib/ExecutionEnvironment.js +4 -1
  24. package/lib/LinkedStateMixin.js +1 -1
  25. package/lib/LinkedValueUtils.js +160 -0
  26. package/lib/MobileSafariClickEventPlugin.js +1 -1
  27. package/lib/PooledClass.js +7 -1
  28. package/lib/React.js +30 -4
  29. package/lib/ReactBrowserComponentMixin.js +42 -0
  30. package/lib/ReactCSSTransitionGroup.js +65 -0
  31. package/lib/{ReactTransitionableChild.js → ReactCSSTransitionGroupChild.js} +22 -36
  32. package/lib/ReactChildren.js +4 -4
  33. package/lib/ReactComponent.js +163 -83
  34. package/lib/ReactComponentBrowserEnvironment.js +55 -71
  35. package/lib/ReactCompositeComponent.js +686 -119
  36. package/lib/ReactContext.js +67 -0
  37. package/lib/ReactCurrentOwner.js +1 -1
  38. package/lib/ReactDOM.js +19 -6
  39. package/lib/ReactDOMButton.js +6 -1
  40. package/lib/ReactDOMComponent.js +66 -24
  41. package/lib/ReactDOMForm.js +13 -3
  42. package/lib/ReactDOMIDOperations.js +106 -61
  43. package/lib/ReactDOMImg.js +61 -0
  44. package/lib/ReactDOMInput.js +28 -15
  45. package/lib/ReactDOMOption.js +13 -8
  46. package/lib/ReactDOMSelect.js +38 -18
  47. package/lib/ReactDOMSelection.js +1 -1
  48. package/lib/ReactDOMTextarea.js +19 -11
  49. package/lib/ReactDefaultBatchingStrategy.js +1 -1
  50. package/lib/ReactDefaultInjection.js +60 -26
  51. package/lib/ReactDefaultPerf.js +208 -371
  52. package/lib/ReactDefaultPerfAnalysis.js +199 -0
  53. package/lib/ReactErrorUtils.js +6 -15
  54. package/lib/ReactEventEmitter.js +144 -146
  55. package/lib/ReactEventEmitterMixin.js +1 -33
  56. package/lib/ReactEventTopLevelCallback.js +75 -15
  57. package/lib/ReactInjection.js +43 -0
  58. package/lib/ReactInputSelection.js +3 -2
  59. package/lib/ReactInstanceHandles.js +36 -20
  60. package/lib/ReactLink.js +2 -2
  61. package/lib/ReactMarkupChecksum.js +1 -1
  62. package/lib/ReactMount.js +136 -104
  63. package/lib/ReactMountReady.js +2 -2
  64. package/lib/ReactMultiChild.js +40 -49
  65. package/lib/ReactMultiChildUpdateTypes.js +3 -1
  66. package/lib/ReactOwner.js +17 -4
  67. package/lib/ReactPerf.js +6 -9
  68. package/lib/ReactPropTransferer.js +41 -22
  69. package/lib/ReactPropTypeLocationNames.js +31 -0
  70. package/lib/{ReactComponentEnvironment.js → ReactPropTypeLocations.js} +11 -6
  71. package/lib/ReactPropTypes.js +249 -48
  72. package/lib/ReactPutListenerQueue.js +61 -0
  73. package/lib/ReactReconcileTransaction.js +28 -7
  74. package/lib/ReactRootIndex.js +36 -0
  75. package/lib/ReactServerRendering.js +46 -19
  76. package/lib/ReactServerRenderingTransaction.js +116 -0
  77. package/lib/ReactStateSetters.js +1 -1
  78. package/lib/ReactTestUtils.js +394 -0
  79. package/lib/ReactTextComponent.js +33 -6
  80. package/lib/{ReactTransitionKeySet.js → ReactTransitionChildMapping.js} +43 -48
  81. package/lib/ReactTransitionEvents.js +1 -1
  82. package/lib/ReactTransitionGroup.js +133 -58
  83. package/lib/ReactUpdates.js +15 -12
  84. package/lib/ReactWithAddons.js +15 -3
  85. package/lib/SelectEventPlugin.js +23 -40
  86. package/lib/ServerReactRootIndex.js +36 -0
  87. package/lib/SimpleEventPlugin.js +55 -7
  88. package/lib/SyntheticClipboardEvent.js +8 -2
  89. package/lib/SyntheticCompositionEvent.js +1 -1
  90. package/lib/SyntheticDragEvent.js +44 -0
  91. package/lib/SyntheticEvent.js +3 -2
  92. package/lib/SyntheticFocusEvent.js +1 -1
  93. package/lib/SyntheticKeyboardEvent.js +5 -3
  94. package/lib/SyntheticMouseEvent.js +1 -1
  95. package/lib/SyntheticTouchEvent.js +1 -1
  96. package/lib/SyntheticUIEvent.js +1 -1
  97. package/lib/SyntheticWheelEvent.js +11 -8
  98. package/lib/Transaction.js +62 -37
  99. package/lib/ViewportMetrics.js +1 -1
  100. package/lib/accumulate.js +1 -1
  101. package/lib/adler32.js +1 -1
  102. package/lib/cloneWithProps.js +59 -0
  103. package/lib/containsNode.js +1 -1
  104. package/lib/copyProperties.js +1 -1
  105. package/lib/createArrayFrom.js +11 -14
  106. package/lib/createFullPageComponent.js +63 -0
  107. package/lib/createNodesFromMarkup.js +1 -1
  108. package/lib/createObjectFrom.js +1 -1
  109. package/lib/cx.js +3 -3
  110. package/lib/dangerousStyleValue.js +1 -1
  111. package/lib/emptyFunction.js +1 -1
  112. package/lib/emptyObject.js +27 -0
  113. package/lib/escapeTextForBrowser.js +1 -1
  114. package/lib/flattenChildren.js +6 -3
  115. package/lib/focusNode.js +33 -0
  116. package/lib/forEachAccumulated.js +1 -1
  117. package/lib/getActiveElement.js +5 -4
  118. package/lib/getEventKey.js +85 -0
  119. package/lib/getEventTarget.js +1 -1
  120. package/lib/getMarkupWrap.js +11 -1
  121. package/lib/getNodeForCharacterOffset.js +1 -1
  122. package/lib/getReactRootElementInContainer.js +1 -1
  123. package/lib/getTextContentAccessor.js +6 -4
  124. package/lib/getUnboundedScrollPosition.js +3 -3
  125. package/lib/hyphenate.js +1 -1
  126. package/lib/instantiateReactComponent.js +70 -0
  127. package/lib/invariant.js +20 -12
  128. package/lib/isEventSupported.js +8 -12
  129. package/lib/isNode.js +2 -2
  130. package/lib/isTextInputElement.js +1 -1
  131. package/lib/isTextNode.js +1 -1
  132. package/lib/joinClasses.js +1 -1
  133. package/lib/keyMirror.js +1 -1
  134. package/lib/keyOf.js +1 -1
  135. package/lib/memoizeStringOnly.js +1 -1
  136. package/lib/merge.js +1 -1
  137. package/lib/mergeHelpers.js +6 -7
  138. package/lib/mergeInto.js +1 -1
  139. package/lib/mixInto.js +1 -1
  140. package/lib/monitorCodeUse.js +37 -0
  141. package/lib/objMap.js +1 -1
  142. package/lib/objMapKeyVal.js +1 -1
  143. package/lib/onlyChild.js +43 -0
  144. package/lib/performanceNow.js +1 -1
  145. package/lib/shallowEqual.js +1 -1
  146. package/lib/shouldUpdateReactComponent.js +61 -0
  147. package/lib/toArray.js +75 -0
  148. package/lib/traverseAllChildren.js +72 -9
  149. package/lib/update.js +159 -0
  150. package/lib/warning.js +48 -0
  151. package/package.json +3 -3
  152. package/react.js +0 -3
  153. package/ReactJSErrors.js +0 -40
  154. package/lib/$.js +0 -46
  155. package/lib/CallbackRegistry.js +0 -91
  156. package/lib/LinkedValueMixin.js +0 -68
  157. package/lib/ex.js +0 -49
  158. package/lib/filterAttributes.js +0 -45
  159. package/lib/ge.js +0 -76
  160. package/lib/mutateHTMLNodeWithMarkup.js +0 -100
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -33,7 +33,8 @@ var mergeInto = require("./mergeInto");
33
33
  var EventInterface = {
34
34
  type: null,
35
35
  target: getEventTarget,
36
- currentTarget: null,
36
+ // currentTarget is set when dispatching; no use in copying it here
37
+ currentTarget: emptyFunction.thatReturnsNull,
37
38
  eventPhase: null,
38
39
  bubbles: null,
39
40
  cancelable: null,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -21,13 +21,14 @@
21
21
 
22
22
  var SyntheticUIEvent = require("./SyntheticUIEvent");
23
23
 
24
+ var getEventKey = require("./getEventKey");
25
+
24
26
  /**
25
27
  * @interface KeyboardEvent
26
28
  * @see http://www.w3.org/TR/DOM-Level-3-Events/
27
29
  */
28
30
  var KeyboardEventInterface = {
29
- 'char': null,
30
- key: null,
31
+ key: getEventKey,
31
32
  location: null,
32
33
  ctrlKey: null,
33
34
  shiftKey: null,
@@ -36,6 +37,7 @@ var KeyboardEventInterface = {
36
37
  repeat: null,
37
38
  locale: null,
38
39
  // Legacy Interface
40
+ 'char': null,
39
41
  charCode: null,
40
42
  keyCode: null,
41
43
  which: null
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -27,7 +27,6 @@ var SyntheticMouseEvent = require("./SyntheticMouseEvent");
27
27
  */
28
28
  var WheelEventInterface = {
29
29
  deltaX: function(event) {
30
- // NOTE: IE<9 does not support x-axis delta.
31
30
  return (
32
31
  'deltaX' in event ? event.deltaX :
33
32
  // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
@@ -36,15 +35,19 @@ var WheelEventInterface = {
36
35
  },
37
36
  deltaY: function(event) {
38
37
  return (
39
- // Normalize (up is positive).
40
- 'deltaY' in event ? -event.deltaY :
41
- // Fallback to `wheelDeltaY` for Webkit.
42
- 'wheelDeltaY' in event ? event.wheelDeltaY :
43
- // Fallback to `wheelDelta` for IE<9.
44
- 'wheelDelta' in event ? event.wheelDelta : 0
38
+ 'deltaY' in event ? event.deltaY :
39
+ // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
40
+ 'wheelDeltaY' in event ? -event.wheelDeltaY :
41
+ // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
42
+ 'wheelDelta' in event ? -event.wheelDelta : 0
45
43
  );
46
44
  },
47
45
  deltaZ: null,
46
+
47
+ // Browsers without "deltaMode" is reporting in raw wheel delta where one
48
+ // notch on the scroll is always +/- 120, roughly equivalent to pixels.
49
+ // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
50
+ // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
48
51
  deltaMode: null
49
52
  };
50
53
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ var invariant = require("./invariant");
27
27
  * instantiates a transaction can provide enforcers of the invariants at
28
28
  * creation time. The `Transaction` class itself will supply one additional
29
29
  * automatic invariant for you - the invariant that any transaction instance
30
- * should not be ran while it is already being ran. You would typically create a
30
+ * should not be run while it is already being run. You would typically create a
31
31
  * single instance of a `Transaction` for reuse multiple times, that potentially
32
32
  * is used to wrap several different methods. Wrappers are extremely simple -
33
33
  * they only require implementing two methods.
@@ -67,7 +67,7 @@ var invariant = require("./invariant");
67
67
  * while guaranteeing that afterwards, the event system is reactivated.
68
68
  * - Flushing a queue of collected DOM mutations to the main UI thread after a
69
69
  * reconciliation takes place in a worker thread.
70
- * - Invoking any collected `componentDidRender` callbacks after rendering new
70
+ * - Invoking any collected `componentDidUpdate` callbacks after rendering new
71
71
  * content.
72
72
  * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue
73
73
  * to preserve the `scrollTop` (an automatic scroll aware DOM).
@@ -146,56 +146,72 @@ var Mixin = {
146
146
  'is already an outstanding transaction.'
147
147
  ) : invariant(!this.isInTransaction()));
148
148
  var memberStart = Date.now();
149
- var errorToThrow = null;
149
+ var errorThrown;
150
150
  var ret;
151
151
  try {
152
- this.initializeAll();
152
+ this._isInTransaction = true;
153
+ // Catching errors makes debugging more difficult, so we start with
154
+ // errorThrown set to true before setting it to false after calling
155
+ // close -- if it's still set to true in the finally block, it means
156
+ // one of these calls threw.
157
+ errorThrown = true;
158
+ this.initializeAll(0);
153
159
  ret = method.call(scope, a, b, c, d, e, f);
154
- } catch (error) {
155
- // IE8 requires `catch` in order to use `finally`.
156
- errorToThrow = error;
160
+ errorThrown = false;
157
161
  } finally {
158
162
  var memberEnd = Date.now();
159
163
  this.methodInvocationTime += (memberEnd - memberStart);
160
164
  try {
161
- this.closeAll();
162
- } catch (closeError) {
163
- // If `method` throws, prefer to show that stack trace over any thrown
164
- // by invoking `closeAll`.
165
- errorToThrow = errorToThrow || closeError;
165
+ if (errorThrown) {
166
+ // If `method` throws, prefer to show that stack trace over any thrown
167
+ // by invoking `closeAll`.
168
+ try {
169
+ this.closeAll(0);
170
+ } catch (err) {
171
+ }
172
+ } else {
173
+ // Since `method` didn't throw, we don't want to silence the exception
174
+ // here.
175
+ this.closeAll(0);
176
+ }
177
+ } finally {
178
+ this._isInTransaction = false;
166
179
  }
167
180
  }
168
- if (errorToThrow) {
169
- throw errorToThrow;
170
- }
171
181
  return ret;
172
182
  },
173
183
 
174
- initializeAll: function() {
175
- this._isInTransaction = true;
184
+ initializeAll: function(startIndex) {
176
185
  var transactionWrappers = this.transactionWrappers;
177
186
  var wrapperInitTimes = this.timingMetrics.wrapperInitTimes;
178
- var errorToThrow = null;
179
- for (var i = 0; i < transactionWrappers.length; i++) {
187
+ for (var i = startIndex; i < transactionWrappers.length; i++) {
180
188
  var initStart = Date.now();
181
189
  var wrapper = transactionWrappers[i];
182
190
  try {
191
+ // Catching errors makes debugging more difficult, so we start with the
192
+ // OBSERVED_ERROR state before overwriting it with the real return value
193
+ // of initialize -- if it's still set to OBSERVED_ERROR in the finally
194
+ // block, it means wrapper.initialize threw.
195
+ this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
183
196
  this.wrapperInitData[i] = wrapper.initialize ?
184
197
  wrapper.initialize.call(this) :
185
198
  null;
186
- } catch (initError) {
187
- // Prefer to show the stack trace of the first error.
188
- errorToThrow = errorToThrow || initError;
189
- this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
190
199
  } finally {
191
200
  var curInitTime = wrapperInitTimes[i];
192
201
  var initEnd = Date.now();
193
202
  wrapperInitTimes[i] = (curInitTime || 0) + (initEnd - initStart);
203
+
204
+ if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) {
205
+ // The initializer for wrapper i threw an error; initialize the
206
+ // remaining wrappers but silence any exceptions from them to ensure
207
+ // that the first error is the one to bubble up.
208
+ try {
209
+ this.initializeAll(i + 1);
210
+ } catch (err) {
211
+ }
212
+ }
194
213
  }
195
214
  }
196
- if (errorToThrow) {
197
- throw errorToThrow;
198
- }
199
215
  },
200
216
 
201
217
  /**
@@ -204,36 +220,45 @@ var Mixin = {
204
220
  * (`close`rs that correspond to initializers that failed will not be
205
221
  * invoked).
206
222
  */
207
- closeAll: function() {
223
+ closeAll: function(startIndex) {
208
224
  ("production" !== process.env.NODE_ENV ? invariant(
209
225
  this.isInTransaction(),
210
226
  'Transaction.closeAll(): Cannot close transaction when none are open.'
211
227
  ) : invariant(this.isInTransaction()));
212
228
  var transactionWrappers = this.transactionWrappers;
213
229
  var wrapperCloseTimes = this.timingMetrics.wrapperCloseTimes;
214
- var errorToThrow = null;
215
- for (var i = 0; i < transactionWrappers.length; i++) {
230
+ for (var i = startIndex; i < transactionWrappers.length; i++) {
216
231
  var wrapper = transactionWrappers[i];
217
232
  var closeStart = Date.now();
218
233
  var initData = this.wrapperInitData[i];
234
+ var errorThrown;
219
235
  try {
236
+ // Catching errors makes debugging more difficult, so we start with
237
+ // errorThrown set to true before setting it to false after calling
238
+ // close -- if it's still set to true in the finally block, it means
239
+ // wrapper.close threw.
240
+ errorThrown = true;
220
241
  if (initData !== Transaction.OBSERVED_ERROR) {
221
242
  wrapper.close && wrapper.close.call(this, initData);
222
243
  }
223
- } catch (closeError) {
224
- // Prefer to show the stack trace of the first error.
225
- errorToThrow = errorToThrow || closeError;
244
+ errorThrown = false;
226
245
  } finally {
227
246
  var closeEnd = Date.now();
228
247
  var curCloseTime = wrapperCloseTimes[i];
229
248
  wrapperCloseTimes[i] = (curCloseTime || 0) + (closeEnd - closeStart);
249
+
250
+ if (errorThrown) {
251
+ // The closer for wrapper i threw an error; close the remaining
252
+ // wrappers but silence any exceptions from them to ensure that the
253
+ // first error is the one to bubble up.
254
+ try {
255
+ this.closeAll(i + 1);
256
+ } catch (e) {
257
+ }
258
+ }
230
259
  }
231
260
  }
232
261
  this.wrapperInitData.length = 0;
233
- this._isInTransaction = false;
234
- if (errorToThrow) {
235
- throw errorToThrow;
236
- }
237
262
  }
238
263
  };
239
264
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
package/lib/accumulate.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
package/lib/adler32.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Copyright 2013-2014 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @typechecks
17
+ * @providesModule cloneWithProps
18
+ */
19
+
20
+ "use strict";
21
+
22
+ var ReactPropTransferer = require("./ReactPropTransferer");
23
+
24
+ var keyOf = require("./keyOf");
25
+ var warning = require("./warning");
26
+
27
+ var CHILDREN_PROP = keyOf({children: null});
28
+
29
+ /**
30
+ * Sometimes you want to change the props of a child passed to you. Usually
31
+ * this is to add a CSS class.
32
+ *
33
+ * @param {object} child child component you'd like to clone
34
+ * @param {object} props props you'd like to modify. They will be merged
35
+ * as if you used `transferPropsTo()`.
36
+ * @return {object} a clone of child with props merged in.
37
+ */
38
+ function cloneWithProps(child, props) {
39
+ if ("production" !== process.env.NODE_ENV) {
40
+ ("production" !== process.env.NODE_ENV ? warning(
41
+ !child.props.ref,
42
+ 'You are calling cloneWithProps() on a child with a ref. This is ' +
43
+ 'dangerous because you\'re creating a new child which will not be ' +
44
+ 'added as a ref to its parent.'
45
+ ) : null);
46
+ }
47
+
48
+ var newProps = ReactPropTransferer.mergeProps(props, child.props);
49
+
50
+ // Use `child.props.children` if it is provided.
51
+ if (!newProps.hasOwnProperty(CHILDREN_PROP) &&
52
+ child.props.hasOwnProperty(CHILDREN_PROP)) {
53
+ newProps.children = child.props.children;
54
+ }
55
+
56
+ return child.constructor.ConvenienceConstructor(newProps);
57
+ }
58
+
59
+ module.exports = cloneWithProps;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013 Facebook, Inc.
2
+ * Copyright 2013-2014 Facebook, Inc.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -17,11 +17,9 @@
17
17
  * @typechecks
18
18
  */
19
19
 
20
+ var toArray = require("./toArray");
21
+
20
22
  /**
21
- * NOTE: if you are a previous user of this function, it has been considered
22
- * unsafe because it's inconsistent across browsers for some inputs.
23
- * Instead use `Array.isArray()`.
24
- *
25
23
  * Perform a heuristic test to determine if an object is "array-like".
26
24
  *
27
25
  * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
@@ -31,6 +29,8 @@
31
29
  * true if the argument is an actual array, an `arguments' object, or an
32
30
  * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
33
31
  *
32
+ * It will return false for other array-like objects like Filelist.
33
+ *
34
34
  * @param {*} obj
35
35
  * @return {boolean}
36
36
  */
@@ -72,8 +72,8 @@ function hasArrayNature(obj) {
72
72
  *
73
73
  * This allows you to treat `things' as an array, but accept scalars in the API.
74
74
  *
75
- * This is also good for converting certain pseudo-arrays, like `arguments` or
76
- * HTMLCollections, into arrays.
75
+ * If you need to convert an array-like object, like `arguments`, into an array
76
+ * use toArray instead.
77
77
  *
78
78
  * @param {*} obj
79
79
  * @return {array}
@@ -81,14 +81,11 @@ function hasArrayNature(obj) {
81
81
  function createArrayFrom(obj) {
82
82
  if (!hasArrayNature(obj)) {
83
83
  return [obj];
84
+ } else if (Array.isArray(obj)) {
85
+ return obj.slice();
86
+ } else {
87
+ return toArray(obj);
84
88
  }
85
- if (obj.item) {
86
- // IE does not support Array#slice on HTMLCollections
87
- var l = obj.length, ret = new Array(l);
88
- while (l--) { ret[l] = obj[l]; }
89
- return ret;
90
- }
91
- return Array.prototype.slice.call(obj);
92
89
  }
93
90
 
94
91
  module.exports = createArrayFrom;