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
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Copyright 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
+ * @providesModule ReactEmptyComponent
17
+ */
18
+
19
+ "use strict";
20
+
21
+ var invariant = require("./invariant");
22
+
23
+ var component;
24
+ // This registry keeps track of the React IDs of the components that rendered to
25
+ // `null` (in reality a placeholder such as `noscript`)
26
+ var nullComponentIdsRegistry = {};
27
+
28
+ var ReactEmptyComponentInjection = {
29
+ injectEmptyComponent: function(emptyComponent) {
30
+ component = emptyComponent;
31
+ }
32
+ };
33
+
34
+ /**
35
+ * @return {ReactComponent} component The injected empty component.
36
+ */
37
+ function getEmptyComponent() {
38
+ ("production" !== process.env.NODE_ENV ? invariant(
39
+ component,
40
+ 'Trying to return null from a render, but no null placeholder component ' +
41
+ 'was injected.'
42
+ ) : invariant(component));
43
+ return component();
44
+ }
45
+
46
+ /**
47
+ * Mark the component as having rendered to null.
48
+ * @param {string} id Component's `_rootNodeID`.
49
+ */
50
+ function registerNullComponentID(id) {
51
+ nullComponentIdsRegistry[id] = true;
52
+ }
53
+
54
+ /**
55
+ * Unmark the component as having rendered to null: it renders to something now.
56
+ * @param {string} id Component's `_rootNodeID`.
57
+ */
58
+ function deregisterNullComponentID(id) {
59
+ delete nullComponentIdsRegistry[id];
60
+ }
61
+
62
+ /**
63
+ * @param {string} id Component's `_rootNodeID`.
64
+ * @return {boolean} True if the component is rendered to null.
65
+ */
66
+ function isNullComponentID(id) {
67
+ return nullComponentIdsRegistry[id];
68
+ }
69
+
70
+ var ReactEmptyComponent = {
71
+ deregisterNullComponentID: deregisterNullComponentID,
72
+ getEmptyComponent: getEmptyComponent,
73
+ injection: ReactEmptyComponentInjection,
74
+ isNullComponentID: isNullComponentID,
75
+ registerNullComponentID: registerNullComponentID
76
+ };
77
+
78
+ module.exports = ReactEmptyComponent;
@@ -19,7 +19,6 @@
19
19
  "use strict";
20
20
 
21
21
  var EventPluginHub = require("./EventPluginHub");
22
- var ReactUpdates = require("./ReactUpdates");
23
22
 
24
23
  function runEventQueueInBatch(events) {
25
24
  EventPluginHub.enqueueEvents(events);
@@ -49,8 +48,7 @@ var ReactEventEmitterMixin = {
49
48
  nativeEvent
50
49
  );
51
50
 
52
- // Event queue being processed in the same cycle allows `preventDefault`.
53
- ReactUpdates.batchedUpdates(runEventQueueInBatch, events);
51
+ runEventQueueInBatch(events);
54
52
  }
55
53
  };
56
54
 
@@ -0,0 +1,189 @@
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
+ * @providesModule ReactEventListener
17
+ * @typechecks static-only
18
+ */
19
+
20
+ "use strict";
21
+
22
+ var EventListener = require("./EventListener");
23
+ var ExecutionEnvironment = require("./ExecutionEnvironment");
24
+ var PooledClass = require("./PooledClass");
25
+ var ReactInstanceHandles = require("./ReactInstanceHandles");
26
+ var ReactMount = require("./ReactMount");
27
+ var ReactUpdates = require("./ReactUpdates");
28
+
29
+ var getEventTarget = require("./getEventTarget");
30
+ var getUnboundedScrollPosition = require("./getUnboundedScrollPosition");
31
+ var mixInto = require("./mixInto");
32
+
33
+ /**
34
+ * Finds the parent React component of `node`.
35
+ *
36
+ * @param {*} node
37
+ * @return {?DOMEventTarget} Parent container, or `null` if the specified node
38
+ * is not nested.
39
+ */
40
+ function findParent(node) {
41
+ // TODO: It may be a good idea to cache this to prevent unnecessary DOM
42
+ // traversal, but caching is difficult to do correctly without using a
43
+ // mutation observer to listen for all DOM changes.
44
+ var nodeID = ReactMount.getID(node);
45
+ var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);
46
+ var container = ReactMount.findReactContainerForID(rootID);
47
+ var parent = ReactMount.getFirstReactDOM(container);
48
+ return parent;
49
+ }
50
+
51
+ // Used to store ancestor hierarchy in top level callback
52
+ function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) {
53
+ this.topLevelType = topLevelType;
54
+ this.nativeEvent = nativeEvent;
55
+ this.ancestors = [];
56
+ }
57
+ mixInto(TopLevelCallbackBookKeeping, {
58
+ destructor: function() {
59
+ this.topLevelType = null;
60
+ this.nativeEvent = null;
61
+ this.ancestors.length = 0;
62
+ }
63
+ });
64
+ PooledClass.addPoolingTo(
65
+ TopLevelCallbackBookKeeping,
66
+ PooledClass.twoArgumentPooler
67
+ );
68
+
69
+ function handleTopLevelImpl(bookKeeping) {
70
+ var topLevelTarget = ReactMount.getFirstReactDOM(
71
+ getEventTarget(bookKeeping.nativeEvent)
72
+ ) || window;
73
+
74
+ // Loop through the hierarchy, in case there's any nested components.
75
+ // It's important that we build the array of ancestors before calling any
76
+ // event handlers, because event handlers can modify the DOM, leading to
77
+ // inconsistencies with ReactMount's node cache. See #1105.
78
+ var ancestor = topLevelTarget;
79
+ while (ancestor) {
80
+ bookKeeping.ancestors.push(ancestor);
81
+ ancestor = findParent(ancestor);
82
+ }
83
+
84
+ for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) {
85
+ topLevelTarget = bookKeeping.ancestors[i];
86
+ var topLevelTargetID = ReactMount.getID(topLevelTarget) || '';
87
+ ReactEventListener._handleTopLevel(
88
+ bookKeeping.topLevelType,
89
+ topLevelTarget,
90
+ topLevelTargetID,
91
+ bookKeeping.nativeEvent
92
+ );
93
+ }
94
+ }
95
+
96
+ function scrollValueMonitor(cb) {
97
+ var scrollPosition = getUnboundedScrollPosition(window);
98
+ cb(scrollPosition);
99
+ }
100
+
101
+ var ReactEventListener = {
102
+ _enabled: true,
103
+ _handleTopLevel: null,
104
+
105
+ WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null,
106
+
107
+ setHandleTopLevel: function(handleTopLevel) {
108
+ ReactEventListener._handleTopLevel = handleTopLevel;
109
+ },
110
+
111
+ setEnabled: function(enabled) {
112
+ ReactEventListener._enabled = !!enabled;
113
+ },
114
+
115
+ isEnabled: function() {
116
+ return ReactEventListener._enabled;
117
+ },
118
+
119
+
120
+ /**
121
+ * Traps top-level events by using event bubbling.
122
+ *
123
+ * @param {string} topLevelType Record from `EventConstants`.
124
+ * @param {string} handlerBaseName Event name (e.g. "click").
125
+ * @param {object} handle Element on which to attach listener.
126
+ * @return {object} An object with a remove function which will forcefully
127
+ * remove the listener.
128
+ * @internal
129
+ */
130
+ trapBubbledEvent: function(topLevelType, handlerBaseName, handle) {
131
+ var element = handle;
132
+ if (!element) {
133
+ return;
134
+ }
135
+ return EventListener.listen(
136
+ element,
137
+ handlerBaseName,
138
+ ReactEventListener.dispatchEvent.bind(null, topLevelType)
139
+ );
140
+ },
141
+
142
+ /**
143
+ * Traps a top-level event by using event capturing.
144
+ *
145
+ * @param {string} topLevelType Record from `EventConstants`.
146
+ * @param {string} handlerBaseName Event name (e.g. "click").
147
+ * @param {object} handle Element on which to attach listener.
148
+ * @return {object} An object with a remove function which will forcefully
149
+ * remove the listener.
150
+ * @internal
151
+ */
152
+ trapCapturedEvent: function(topLevelType, handlerBaseName, handle) {
153
+ var element = handle;
154
+ if (!element) {
155
+ return;
156
+ }
157
+ return EventListener.capture(
158
+ element,
159
+ handlerBaseName,
160
+ ReactEventListener.dispatchEvent.bind(null, topLevelType)
161
+ );
162
+ },
163
+
164
+ monitorScrollValue: function(refresh) {
165
+ var callback = scrollValueMonitor.bind(null, refresh);
166
+ EventListener.listen(window, 'scroll', callback);
167
+ EventListener.listen(window, 'resize', callback);
168
+ },
169
+
170
+ dispatchEvent: function(topLevelType, nativeEvent) {
171
+ if (!ReactEventListener._enabled) {
172
+ return;
173
+ }
174
+
175
+ var bookKeeping = TopLevelCallbackBookKeeping.getPooled(
176
+ topLevelType,
177
+ nativeEvent
178
+ );
179
+ try {
180
+ // Event queue being processed in the same cycle allows
181
+ // `preventDefault`.
182
+ ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
183
+ } finally {
184
+ TopLevelCallbackBookKeeping.release(bookKeeping);
185
+ }
186
+ }
187
+ };
188
+
189
+ module.exports = ReactEventListener;
@@ -20,17 +20,23 @@
20
20
 
21
21
  var DOMProperty = require("./DOMProperty");
22
22
  var EventPluginHub = require("./EventPluginHub");
23
+ var ReactComponent = require("./ReactComponent");
24
+ var ReactCompositeComponent = require("./ReactCompositeComponent");
23
25
  var ReactDOM = require("./ReactDOM");
24
- var ReactEventEmitter = require("./ReactEventEmitter");
26
+ var ReactEmptyComponent = require("./ReactEmptyComponent");
27
+ var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
25
28
  var ReactPerf = require("./ReactPerf");
26
29
  var ReactRootIndex = require("./ReactRootIndex");
27
30
  var ReactUpdates = require("./ReactUpdates");
28
31
 
29
32
  var ReactInjection = {
33
+ Component: ReactComponent.injection,
34
+ CompositeComponent: ReactCompositeComponent.injection,
30
35
  DOMProperty: DOMProperty.injection,
36
+ EmptyComponent: ReactEmptyComponent.injection,
31
37
  EventPluginHub: EventPluginHub.injection,
32
38
  DOM: ReactDOM.injection,
33
- EventEmitter: ReactEventEmitter.injection,
39
+ EventEmitter: ReactBrowserEventEmitter.injection,
34
40
  Perf: ReactPerf.injection,
35
41
  RootIndex: ReactRootIndex.injection,
36
42
  Updates: ReactUpdates.injection
@@ -21,6 +21,7 @@
21
21
  var ReactDOMSelection = require("./ReactDOMSelection");
22
22
 
23
23
  var containsNode = require("./containsNode");
24
+ var focusNode = require("./focusNode");
24
25
  var getActiveElement = require("./getActiveElement");
25
26
 
26
27
  function isInDocument(node) {
@@ -71,7 +72,7 @@ var ReactInputSelection = {
71
72
  priorSelectionRange
72
73
  );
73
74
  }
74
- priorFocusedElem.focus();
75
+ focusNode(priorFocusedElem);
75
76
  }
76
77
  },
77
78
 
package/lib/ReactLink.js CHANGED
@@ -42,6 +42,8 @@
42
42
  * consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin.
43
43
  */
44
44
 
45
+ var React = require("./React");
46
+
45
47
  /**
46
48
  * @param {*} value current value of the link
47
49
  * @param {function} requestChange callback to request a change
@@ -51,4 +53,26 @@ function ReactLink(value, requestChange) {
51
53
  this.requestChange = requestChange;
52
54
  }
53
55
 
56
+ /**
57
+ * Creates a PropType that enforces the ReactLink API and optionally checks the
58
+ * type of the value being passed inside the link. Example:
59
+ *
60
+ * MyComponent.propTypes = {
61
+ * tabIndexLink: ReactLink.PropTypes.link(React.PropTypes.number)
62
+ * }
63
+ */
64
+ function createLinkTypeChecker(linkType) {
65
+ var shapes = {
66
+ value: typeof linkType === 'undefined' ?
67
+ React.PropTypes.any.isRequired :
68
+ linkType.isRequired,
69
+ requestChange: React.PropTypes.func.isRequired
70
+ };
71
+ return React.PropTypes.shape(shapes);
72
+ }
73
+
74
+ ReactLink.PropTypes = {
75
+ link: createLinkTypeChecker
76
+ };
77
+
54
78
  module.exports = ReactLink;
package/lib/ReactMount.js CHANGED
@@ -19,14 +19,18 @@
19
19
  "use strict";
20
20
 
21
21
  var DOMProperty = require("./DOMProperty");
22
- var ReactEventEmitter = require("./ReactEventEmitter");
22
+ var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
23
+ var ReactCurrentOwner = require("./ReactCurrentOwner");
24
+ var ReactDescriptor = require("./ReactDescriptor");
23
25
  var ReactInstanceHandles = require("./ReactInstanceHandles");
24
26
  var ReactPerf = require("./ReactPerf");
25
27
 
26
28
  var containsNode = require("./containsNode");
27
29
  var getReactRootElementInContainer = require("./getReactRootElementInContainer");
30
+ var instantiateReactComponent = require("./instantiateReactComponent");
28
31
  var invariant = require("./invariant");
29
32
  var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
33
+ var warning = require("./warning");
30
34
 
31
35
  var SEPARATOR = ReactInstanceHandles.SEPARATOR;
32
36
 
@@ -209,15 +213,6 @@ function findDeepestCachedAncestor(targetID) {
209
213
  * Inside of `container`, the first element rendered is the "reactRoot".
210
214
  */
211
215
  var ReactMount = {
212
- /** Time spent generating markup. */
213
- totalInstantiationTime: 0,
214
-
215
- /** Time spent inserting markup into the DOM. */
216
- totalInjectionTime: 0,
217
-
218
- /** Whether support for touch events should be initialized. */
219
- useTouchEvents: false,
220
-
221
216
  /** Exposed for debugging purposes **/
222
217
  _instancesByReactRootID: instancesByReactRootID,
223
218
 
@@ -278,7 +273,7 @@ var ReactMount = {
278
273
  container.nodeType === DOC_NODE_TYPE
279
274
  )));
280
275
 
281
- ReactEventEmitter.ensureScrollValueMonitoring();
276
+ ReactBrowserEventEmitter.ensureScrollValueMonitoring();
282
277
 
283
278
  var reactRootID = ReactMount.registerContainer(container);
284
279
  instancesByReactRootID[reactRootID] = nextComponent;
@@ -299,8 +294,23 @@ var ReactMount = {
299
294
  nextComponent,
300
295
  container,
301
296
  shouldReuseMarkup) {
302
- var reactRootID = ReactMount._registerComponent(nextComponent, container);
303
- nextComponent.mountComponentIntoNode(
297
+ // Various parts of our code (such as ReactCompositeComponent's
298
+ // _renderValidatedComponent) assume that calls to render aren't nested;
299
+ // verify that that's the case.
300
+ ("production" !== process.env.NODE_ENV ? warning(
301
+ ReactCurrentOwner.current == null,
302
+ '_renderNewRootComponent(): Render methods should be a pure function ' +
303
+ 'of props and state; triggering nested component updates from ' +
304
+ 'render is not allowed. If necessary, trigger nested updates in ' +
305
+ 'componentDidUpdate.'
306
+ ) : null);
307
+
308
+ var componentInstance = instantiateReactComponent(nextComponent);
309
+ var reactRootID = ReactMount._registerComponent(
310
+ componentInstance,
311
+ container
312
+ );
313
+ componentInstance.mountComponentIntoNode(
304
314
  reactRootID,
305
315
  container,
306
316
  shouldReuseMarkup
@@ -312,7 +322,7 @@ var ReactMount = {
312
322
  getReactRootElementInContainer(container);
313
323
  }
314
324
 
315
- return nextComponent;
325
+ return componentInstance;
316
326
  }
317
327
  ),
318
328
 
@@ -323,19 +333,35 @@ var ReactMount = {
323
333
  * perform an update on it and only mutate the DOM as necessary to reflect the
324
334
  * latest React component.
325
335
  *
326
- * @param {ReactComponent} nextComponent Component instance to render.
336
+ * @param {ReactDescriptor} nextDescriptor Component descriptor to render.
327
337
  * @param {DOMElement} container DOM element to render into.
328
338
  * @param {?function} callback function triggered on completion
329
339
  * @return {ReactComponent} Component instance rendered in `container`.
330
340
  */
331
- renderComponent: function(nextComponent, container, callback) {
341
+ renderComponent: function(nextDescriptor, container, callback) {
342
+ ("production" !== process.env.NODE_ENV ? invariant(
343
+ ReactDescriptor.isValidDescriptor(nextDescriptor),
344
+ 'renderComponent(): Invalid component descriptor.%s',
345
+ (
346
+ ReactDescriptor.isValidFactory(nextDescriptor) ?
347
+ ' Instead of passing a component class, make sure to instantiate ' +
348
+ 'it first by calling it with props.' :
349
+ // Check if it quacks like a descriptor
350
+ typeof nextDescriptor.props !== "undefined" ?
351
+ ' This may be caused by unintentionally loading two independent ' +
352
+ 'copies of React.' :
353
+ ''
354
+ )
355
+ ) : invariant(ReactDescriptor.isValidDescriptor(nextDescriptor)));
356
+
332
357
  var prevComponent = instancesByReactRootID[getReactRootID(container)];
333
358
 
334
359
  if (prevComponent) {
335
- if (shouldUpdateReactComponent(prevComponent, nextComponent)) {
360
+ var prevDescriptor = prevComponent._descriptor;
361
+ if (shouldUpdateReactComponent(prevDescriptor, nextDescriptor)) {
336
362
  return ReactMount._updateRootComponent(
337
363
  prevComponent,
338
- nextComponent,
364
+ nextDescriptor,
339
365
  container,
340
366
  callback
341
367
  );
@@ -351,7 +377,7 @@ var ReactMount = {
351
377
  var shouldReuseMarkup = containerHasReactMarkup && !prevComponent;
352
378
 
353
379
  var component = ReactMount._renderNewRootComponent(
354
- nextComponent,
380
+ nextDescriptor,
355
381
  container,
356
382
  shouldReuseMarkup
357
383
  );
@@ -421,6 +447,18 @@ var ReactMount = {
421
447
  * `container`
422
448
  */
423
449
  unmountComponentAtNode: function(container) {
450
+ // Various parts of our code (such as ReactCompositeComponent's
451
+ // _renderValidatedComponent) assume that calls to render aren't nested;
452
+ // verify that that's the case. (Strictly speaking, unmounting won't cause a
453
+ // render but we still don't expect to be in a render call here.)
454
+ ("production" !== process.env.NODE_ENV ? warning(
455
+ ReactCurrentOwner.current == null,
456
+ 'unmountComponentAtNode(): Render methods should be a pure function of ' +
457
+ 'props and state; triggering nested component updates from render is ' +
458
+ 'not allowed. If necessary, trigger nested updates in ' +
459
+ 'componentDidUpdate.'
460
+ ) : null);
461
+
424
462
  var reactRootID = getReactRootID(container);
425
463
  var component = instancesByReactRootID[reactRootID];
426
464
  if (!component) {
@@ -615,8 +653,10 @@ var ReactMount = {
615
653
  ("production" !== process.env.NODE_ENV ? invariant(
616
654
  false,
617
655
  'findComponentRoot(..., %s): Unable to find element. This probably ' +
618
- 'means the DOM was unexpectedly mutated (e.g., by the browser). ' +
619
- 'Try inspecting the child nodes of the element with React ID `%s`.',
656
+ 'means the DOM was unexpectedly mutated (e.g., by the browser), ' +
657
+ 'usually due to forgetting a <tbody> when using tables, nesting <p> ' +
658
+ 'or <a> tags, or using non-SVG elements in an <svg> parent. Try ' +
659
+ 'inspecting the child nodes of the element with React ID `%s`.',
620
660
  targetID,
621
661
  ReactMount.getID(ancestorNode)
622
662
  ) : invariant(false));