react 15.1.0 → 15.2.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 (124) hide show
  1. package/dist/react-with-addons.js +2685 -1842
  2. package/dist/react-with-addons.min.js +6 -6
  3. package/dist/react.js +2400 -1691
  4. package/dist/react.min.js +6 -6
  5. package/lib/CSSPropertyOperations.js +1 -1
  6. package/lib/CallbackQueue.js +3 -2
  7. package/lib/DOMChildrenOperations.js +9 -9
  8. package/lib/DOMLazyTree.js +3 -2
  9. package/lib/DOMProperty.js +5 -12
  10. package/lib/DOMPropertyOperations.js +21 -15
  11. package/lib/Danger.js +5 -101
  12. package/lib/DisabledInputUtils.js +5 -5
  13. package/lib/EventPluginHub.js +8 -2
  14. package/lib/EventPluginRegistry.js +13 -7
  15. package/lib/EventPluginUtils.js +3 -1
  16. package/lib/HTMLDOMPropertyConfig.js +1 -2
  17. package/lib/KeyEscapeUtils.js +2 -1
  18. package/lib/LinkedValueUtils.js +5 -3
  19. package/lib/NativeMethodsMixin.js +6 -4
  20. package/lib/PooledClass.js +4 -2
  21. package/lib/React.js +1 -1
  22. package/lib/ReactCSSTransitionGroupChild.js +15 -8
  23. package/lib/ReactChildReconciler.js +17 -8
  24. package/lib/ReactClass.js +14 -13
  25. package/lib/ReactComponent.js +3 -6
  26. package/lib/ReactComponentEnvironment.js +3 -1
  27. package/lib/ReactComponentTreeDevtool.js +89 -16
  28. package/lib/ReactComponentTreeTestUtils.js +87 -0
  29. package/lib/ReactCompositeComponent.js +87 -117
  30. package/lib/ReactDOM.js +2 -2
  31. package/lib/ReactDOMButton.js +2 -2
  32. package/lib/ReactDOMComponent.js +130 -76
  33. package/lib/ReactDOMComponentTree.js +23 -21
  34. package/lib/ReactDOMDebugTool.js +17 -11
  35. package/lib/ReactDOMEmptyComponent.js +9 -9
  36. package/lib/ReactDOMFactories.js +1 -1
  37. package/lib/ReactDOMFiber.js +78 -0
  38. package/lib/ReactDOMInput.js +64 -26
  39. package/lib/ReactDOMInstrumentation.js +7 -2
  40. package/lib/ReactDOMNullInputValuePropDevtool.js +43 -0
  41. package/lib/ReactDOMOption.js +40 -26
  42. package/lib/ReactDOMSelect.js +3 -16
  43. package/lib/ReactDOMTextComponent.js +21 -20
  44. package/lib/ReactDOMTextarea.js +59 -46
  45. package/lib/ReactDOMTreeTraversal.js +18 -16
  46. package/lib/ReactDOMUnknownPropertyDevtool.js +65 -17
  47. package/lib/ReactDebugTool.js +148 -95
  48. package/lib/ReactDefaultInjection.js +2 -2
  49. package/lib/ReactElement.js +64 -25
  50. package/lib/ReactElementValidator.js +26 -81
  51. package/lib/ReactEventListener.js +2 -2
  52. package/lib/ReactFeatureFlags.js +1 -0
  53. package/lib/ReactFragment.js +3 -1
  54. package/lib/{ReactNativeComponent.js → ReactHostComponent.js} +10 -29
  55. package/lib/{ReactNativeOperationHistoryDevtool.js → ReactHostOperationHistoryDevtool.js} +5 -5
  56. package/lib/ReactInjection.js +2 -2
  57. package/lib/ReactInstanceHandles.js +8 -6
  58. package/lib/ReactInstrumentation.js +7 -2
  59. package/lib/ReactMount.js +38 -32
  60. package/lib/ReactMultiChild.js +38 -11
  61. package/lib/ReactNativeAttributePayload.js +5 -2
  62. package/lib/ReactNativeBaseComponent.js +7 -7
  63. package/lib/ReactNativeBridgeEventPlugin.js +1 -1
  64. package/lib/ReactNativeComponentTree.js +8 -6
  65. package/lib/ReactNativeDOMIDOperations.js +1 -2
  66. package/lib/ReactNativeDefaultInjection.js +9 -7
  67. package/lib/ReactNativeGlobalResponderHandler.js +1 -1
  68. package/lib/ReactNativeMount.js +3 -14
  69. package/lib/ReactNativeReconcileTransaction.js +16 -0
  70. package/lib/ReactNativeTagHandles.js +3 -1
  71. package/lib/ReactNativeTextComponent.js +10 -9
  72. package/lib/ReactNativeTreeTraversal.js +11 -11
  73. package/lib/ReactNodeTypes.js +6 -3
  74. package/lib/ReactNoop.js +173 -0
  75. package/lib/ReactNoopUpdateQueue.js +6 -5
  76. package/lib/ReactOwner.js +4 -2
  77. package/lib/ReactPerf.js +83 -7
  78. package/lib/ReactPropTypes.js +23 -0
  79. package/lib/ReactReconcileTransaction.js +17 -1
  80. package/lib/ReactReconciler.js +12 -7
  81. package/lib/ReactServerRendering.js +5 -7
  82. package/lib/ReactServerRenderingTransaction.js +17 -0
  83. package/lib/ReactServerUpdateQueue.js +141 -0
  84. package/lib/ReactSimpleEmptyComponent.js +4 -4
  85. package/lib/ReactTestMount.js +115 -0
  86. package/lib/ReactTestReconcileTransaction.js +108 -0
  87. package/lib/ReactTestRenderer.js +133 -0
  88. package/lib/ReactTestUtils.js +17 -10
  89. package/lib/ReactTransitionChildMapping.js +7 -1
  90. package/lib/ReactTransitionGroup.js +41 -6
  91. package/lib/ReactUpdateQueue.js +13 -3
  92. package/lib/ReactUpdates.js +10 -18
  93. package/lib/ReactVersion.js +1 -1
  94. package/lib/ResponderEventPlugin.js +9 -7
  95. package/lib/ResponderTouchHistoryStore.js +99 -95
  96. package/lib/SimpleEventPlugin.js +3 -1
  97. package/lib/SyntheticEvent.js +2 -3
  98. package/lib/SyntheticUIEvent.js +1 -1
  99. package/lib/Transaction.js +4 -2
  100. package/lib/accumulate.js +17 -15
  101. package/lib/accumulateInto.js +11 -12
  102. package/lib/adler32.js +1 -0
  103. package/lib/checkReactTypeSpec.js +73 -0
  104. package/lib/createReactNativeComponentClass.js +2 -2
  105. package/lib/dangerousStyleValue.js +3 -1
  106. package/lib/deprecated.js +7 -1
  107. package/lib/escapeTextContentForBrowser.js +96 -12
  108. package/lib/findDOMNode.js +6 -4
  109. package/lib/findNodeHandle.js +5 -3
  110. package/lib/flattenChildren.js +22 -10
  111. package/lib/forEachAccumulated.js +3 -2
  112. package/lib/{getNativeComponentFromComposite.js → getHostComponentFromComposite.js} +4 -4
  113. package/lib/getIteratorFn.js +1 -0
  114. package/lib/instantiateReactComponent.js +21 -19
  115. package/lib/isTextInputElement.js +11 -1
  116. package/lib/onlyChild.js +3 -1
  117. package/lib/reactComponentExpect.js +3 -3
  118. package/lib/reactProdInvariant.js +39 -0
  119. package/lib/setInnerHTML.js +17 -1
  120. package/lib/setTextContent.js +8 -0
  121. package/lib/traverseAllChildren.js +3 -1
  122. package/lib/update.js +12 -11
  123. package/package.json +2 -2
  124. package/lib/MetaMatchers.js +0 -118
@@ -11,6 +11,8 @@
11
11
 
12
12
  'use strict';
13
13
 
14
+ var _prodInvariant = require('./reactProdInvariant');
15
+
14
16
  var invariant = require('fbjs/lib/invariant');
15
17
 
16
18
  var injected = false;
@@ -38,7 +40,7 @@ var ReactComponentEnvironment = {
38
40
 
39
41
  injection: {
40
42
  injectEnvironment: function (environment) {
41
- !!injected ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : invariant(false) : void 0;
43
+ !!injected ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : _prodInvariant('104') : void 0;
42
44
  ReactComponentEnvironment.unmountIDFromEnvironment = environment.unmountIDFromEnvironment;
43
45
  ReactComponentEnvironment.replaceNodeWithMarkup = environment.replaceNodeWithMarkup;
44
46
  ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates;
@@ -11,14 +11,21 @@
11
11
 
12
12
  'use strict';
13
13
 
14
+ var _prodInvariant = require('./reactProdInvariant');
15
+
16
+ var ReactCurrentOwner = require('./ReactCurrentOwner');
17
+
14
18
  var invariant = require('fbjs/lib/invariant');
19
+ var warning = require('fbjs/lib/warning');
15
20
 
16
21
  var tree = {};
17
- var rootIDs = [];
22
+ var unmountedIDs = {};
23
+ var rootIDs = {};
18
24
 
19
25
  function updateTree(id, update) {
20
26
  if (!tree[id]) {
21
27
  tree[id] = {
28
+ element: null,
22
29
  parentID: null,
23
30
  ownerID: null,
24
31
  text: null,
@@ -41,6 +48,22 @@ function purgeDeep(id) {
41
48
  }
42
49
  }
43
50
 
51
+ function describeComponentFrame(name, source, ownerName) {
52
+ return '\n in ' + name + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : '');
53
+ }
54
+
55
+ function describeID(id) {
56
+ var name = ReactComponentTreeDevtool.getDisplayName(id);
57
+ var element = ReactComponentTreeDevtool.getElement(id);
58
+ var ownerID = ReactComponentTreeDevtool.getOwnerID(id);
59
+ var ownerName;
60
+ if (ownerID) {
61
+ ownerName = ReactComponentTreeDevtool.getDisplayName(ownerID);
62
+ }
63
+ process.env.NODE_ENV !== 'production' ? warning(element, 'ReactComponentTreeDevtool: Missing React element for debugID %s when ' + 'building stack', id) : void 0;
64
+ return describeComponentFrame(name, element && element._source, ownerName);
65
+ }
66
+
44
67
  var ReactComponentTreeDevtool = {
45
68
  onSetDisplayName: function (id, displayName) {
46
69
  updateTree(id, function (item) {
@@ -49,19 +72,21 @@ var ReactComponentTreeDevtool = {
49
72
  },
50
73
  onSetChildren: function (id, nextChildIDs) {
51
74
  updateTree(id, function (item) {
52
- var prevChildIDs = item.childIDs;
53
75
  item.childIDs = nextChildIDs;
54
76
 
55
77
  nextChildIDs.forEach(function (nextChildID) {
56
78
  var nextChild = tree[nextChildID];
57
- !nextChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected devtool events to fire for the child ' + 'before its parent includes it in onSetChildren().') : invariant(false) : void 0;
58
- !(nextChild.displayName != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetDisplayName() to fire for the child ' + 'before its parent includes it in onSetChildren().') : invariant(false) : void 0;
59
- !(nextChild.childIDs != null || nextChild.text != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetChildren() or onSetText() to fire for the child ' + 'before its parent includes it in onSetChildren().') : invariant(false) : void 0;
60
- !nextChild.isMounted ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onMountComponent() to fire for the child ' + 'before its parent includes it in onSetChildren().') : invariant(false) : void 0;
61
-
62
- if (prevChildIDs.indexOf(nextChildID) === -1) {
79
+ !nextChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected devtool events to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('68') : void 0;
80
+ !(nextChild.displayName != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetDisplayName() to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('69') : void 0;
81
+ !(nextChild.childIDs != null || nextChild.text != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetChildren() or onSetText() to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('70') : void 0;
82
+ !nextChild.isMounted ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onMountComponent() to fire for the child before its parent includes it in onSetChildren().') : _prodInvariant('71') : void 0;
83
+ if (nextChild.parentID == null) {
63
84
  nextChild.parentID = id;
85
+ // TODO: This shouldn't be necessary but mounting a new root during in
86
+ // componentWillMount currently causes not-yet-mounted components to
87
+ // be purged from our tree data so their parent ID is missing.
64
88
  }
89
+ !(nextChild.parentID === id) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected onSetParent() and onSetChildren() to be consistent (%s has parents %s and %s).', nextChildID, nextChild.parentID, id) : _prodInvariant('72', nextChildID, nextChild.parentID, id) : void 0;
65
90
  });
66
91
  });
67
92
  },
@@ -70,18 +95,33 @@ var ReactComponentTreeDevtool = {
70
95
  return item.ownerID = ownerID;
71
96
  });
72
97
  },
98
+ onSetParent: function (id, parentID) {
99
+ updateTree(id, function (item) {
100
+ return item.parentID = parentID;
101
+ });
102
+ },
73
103
  onSetText: function (id, text) {
74
104
  updateTree(id, function (item) {
75
105
  return item.text = text;
76
106
  });
77
107
  },
108
+ onBeforeMountComponent: function (id, element) {
109
+ updateTree(id, function (item) {
110
+ return item.element = element;
111
+ });
112
+ },
113
+ onBeforeUpdateComponent: function (id, element) {
114
+ updateTree(id, function (item) {
115
+ return item.element = element;
116
+ });
117
+ },
78
118
  onMountComponent: function (id) {
79
119
  updateTree(id, function (item) {
80
120
  return item.isMounted = true;
81
121
  });
82
122
  },
83
123
  onMountRootComponent: function (id) {
84
- rootIDs.push(id);
124
+ rootIDs[id] = true;
85
125
  },
86
126
  onUpdateComponent: function (id) {
87
127
  updateTree(id, function (item) {
@@ -92,9 +132,8 @@ var ReactComponentTreeDevtool = {
92
132
  updateTree(id, function (item) {
93
133
  return item.isMounted = false;
94
134
  });
95
- rootIDs = rootIDs.filter(function (rootID) {
96
- return rootID !== id;
97
- });
135
+ unmountedIDs[id] = true;
136
+ delete rootIDs[id];
98
137
  },
99
138
  purgeUnmountedComponents: function () {
100
139
  if (ReactComponentTreeDevtool._preventPurging) {
@@ -102,14 +141,38 @@ var ReactComponentTreeDevtool = {
102
141
  return;
103
142
  }
104
143
 
105
- Object.keys(tree).filter(function (id) {
106
- return !tree[id].isMounted;
107
- }).forEach(purgeDeep);
144
+ for (var id in unmountedIDs) {
145
+ purgeDeep(id);
146
+ }
147
+ unmountedIDs = {};
108
148
  },
109
149
  isMounted: function (id) {
110
150
  var item = tree[id];
111
151
  return item ? item.isMounted : false;
112
152
  },
153
+ getCurrentStackAddendum: function (topElement) {
154
+ var info = '';
155
+ if (topElement) {
156
+ var type = topElement.type;
157
+ var name = typeof type === 'function' ? type.displayName || type.name : type;
158
+ var owner = topElement._owner;
159
+ info += describeComponentFrame(name || 'Unknown', topElement._source, owner && owner.getName());
160
+ }
161
+
162
+ var currentOwner = ReactCurrentOwner.current;
163
+ var id = currentOwner && currentOwner._debugID;
164
+
165
+ info += ReactComponentTreeDevtool.getStackAddendumByID(id);
166
+ return info;
167
+ },
168
+ getStackAddendumByID: function (id) {
169
+ var info = '';
170
+ while (id) {
171
+ info += describeID(id);
172
+ id = ReactComponentTreeDevtool.getParentID(id);
173
+ }
174
+ return info;
175
+ },
113
176
  getChildIDs: function (id) {
114
177
  var item = tree[id];
115
178
  return item ? item.childIDs : [];
@@ -118,6 +181,10 @@ var ReactComponentTreeDevtool = {
118
181
  var item = tree[id];
119
182
  return item ? item.displayName : 'Unknown';
120
183
  },
184
+ getElement: function (id) {
185
+ var item = tree[id];
186
+ return item ? item.element : null;
187
+ },
121
188
  getOwnerID: function (id) {
122
189
  var item = tree[id];
123
190
  return item ? item.ownerID : null;
@@ -126,6 +193,12 @@ var ReactComponentTreeDevtool = {
126
193
  var item = tree[id];
127
194
  return item ? item.parentID : null;
128
195
  },
196
+ getSource: function (id) {
197
+ var item = tree[id];
198
+ var element = item ? item.element : null;
199
+ var source = element != null ? element._source : null;
200
+ return source;
201
+ },
129
202
  getText: function (id) {
130
203
  var item = tree[id];
131
204
  return item ? item.text : null;
@@ -135,7 +208,7 @@ var ReactComponentTreeDevtool = {
135
208
  return item ? item.updateCount : 0;
136
209
  },
137
210
  getRootIDs: function () {
138
- return rootIDs;
211
+ return Object.keys(rootIDs);
139
212
  },
140
213
  getRegisteredIDs: function () {
141
214
  return Object.keys(tree);
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Copyright 2016-present, 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 ReactComponentTreeTestUtils
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var _assign = require('object-assign');
15
+
16
+ var _extends = _assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
17
+
18
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
19
+
20
+ var ReactComponentTreeDevtool = require('./ReactComponentTreeDevtool');
21
+
22
+ function getRootDisplayNames() {
23
+ return ReactComponentTreeDevtool.getRootIDs().map(ReactComponentTreeDevtool.getDisplayName);
24
+ }
25
+
26
+ function getRegisteredDisplayNames() {
27
+ return ReactComponentTreeDevtool.getRegisteredIDs().map(ReactComponentTreeDevtool.getDisplayName);
28
+ }
29
+
30
+ function expectTree(rootID, expectedTree, parentPath) {
31
+ var displayName = ReactComponentTreeDevtool.getDisplayName(rootID);
32
+ var ownerID = ReactComponentTreeDevtool.getOwnerID(rootID);
33
+ var parentID = ReactComponentTreeDevtool.getParentID(rootID);
34
+ var childIDs = ReactComponentTreeDevtool.getChildIDs(rootID);
35
+ var text = ReactComponentTreeDevtool.getText(rootID);
36
+ var element = ReactComponentTreeDevtool.getElement(rootID);
37
+ var path = parentPath ? parentPath + ' > ' + displayName : displayName;
38
+
39
+ function expectEqual(actual, expected, name) {
40
+ // Get Jasmine to print descriptive error messages.
41
+ // We pass path so that we know where the mismatch occurred.
42
+ expect(_defineProperty({
43
+ path: path
44
+ }, name, actual)).toEqual(_defineProperty({
45
+ path: path
46
+ }, name, expected));
47
+ }
48
+
49
+ if (expectedTree.parentDisplayName !== undefined) {
50
+ expectEqual(ReactComponentTreeDevtool.getDisplayName(parentID), expectedTree.parentDisplayName, 'parentDisplayName');
51
+ }
52
+ if (expectedTree.ownerDisplayName !== undefined) {
53
+ expectEqual(ReactComponentTreeDevtool.getDisplayName(ownerID), expectedTree.ownerDisplayName, 'ownerDisplayName');
54
+ }
55
+ if (expectedTree.parentID !== undefined) {
56
+ expectEqual(parentID, expectedTree.parentID, 'parentID');
57
+ }
58
+ if (expectedTree.text !== undefined) {
59
+ expectEqual(text, expectedTree.text, 'text');
60
+ expectEqual('' + element, expectedTree.text, 'element.toString()');
61
+ } else {
62
+ expectEqual(text, null, 'text');
63
+ }
64
+ if (expectedTree.element !== undefined) {
65
+ // TODO: Comparing elements makes tests run out of memory on errors.
66
+ // For now, compare just types.
67
+ expectEqual(element && element.type, expectedTree.element && expectedTree.element.type, 'element.type');
68
+ } else if (text == null) {
69
+ expectEqual(typeof element, 'object', 'typeof element');
70
+ }
71
+ if (expectedTree.children !== undefined) {
72
+ expectEqual(childIDs.length, expectedTree.children.length, 'children.length');
73
+ for (var i = 0; i < childIDs.length; i++) {
74
+ expectTree(childIDs[i], _extends({ parentID: rootID }, expectedTree.children[i]), path);
75
+ }
76
+ } else {
77
+ expectEqual(childIDs, [], 'childIDs');
78
+ }
79
+ }
80
+
81
+ var ReactComponentTreeTestUtils = {
82
+ expectTree: expectTree,
83
+ getRootDisplayNames: getRootDisplayNames,
84
+ getRegisteredDisplayNames: getRegisteredDisplayNames
85
+ };
86
+
87
+ module.exports = ReactComponentTreeTestUtils;
@@ -11,7 +11,8 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- var _assign = require('object-assign');
14
+ var _prodInvariant = require('./reactProdInvariant'),
15
+ _assign = require('object-assign');
15
16
 
16
17
  var ReactComponentEnvironment = require('./ReactComponentEnvironment');
17
18
  var ReactCurrentOwner = require('./ReactCurrentOwner');
@@ -21,26 +22,15 @@ var ReactInstanceMap = require('./ReactInstanceMap');
21
22
  var ReactInstrumentation = require('./ReactInstrumentation');
22
23
  var ReactNodeTypes = require('./ReactNodeTypes');
23
24
  var ReactPropTypeLocations = require('./ReactPropTypeLocations');
24
- var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');
25
25
  var ReactReconciler = require('./ReactReconciler');
26
- var ReactUpdateQueue = require('./ReactUpdateQueue');
26
+
27
+ var checkReactTypeSpec = require('./checkReactTypeSpec');
27
28
 
28
29
  var emptyObject = require('fbjs/lib/emptyObject');
29
30
  var invariant = require('fbjs/lib/invariant');
30
31
  var shouldUpdateReactComponent = require('./shouldUpdateReactComponent');
31
32
  var warning = require('fbjs/lib/warning');
32
33
 
33
- function getDeclarationErrorAddendum(component) {
34
- var owner = component._currentElement._owner || null;
35
- if (owner) {
36
- var name = owner.getName();
37
- if (name) {
38
- return ' Check the render method of `' + name + '`.';
39
- }
40
- }
41
- return '';
42
- }
43
-
44
34
  function StatelessComponent(Component) {}
45
35
  StatelessComponent.prototype.render = function () {
46
36
  var Component = ReactInstanceMap.get(this)._currentElement.type;
@@ -52,6 +42,7 @@ StatelessComponent.prototype.render = function () {
52
42
  function warnIfInvalidElement(Component, element) {
53
43
  if (process.env.NODE_ENV !== 'production') {
54
44
  process.env.NODE_ENV !== 'production' ? warning(element === null || element === false || ReactElement.isValidElement(element), '%s(...): A valid React element (or null) must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : void 0;
45
+ process.env.NODE_ENV !== 'production' ? warning(!Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', Component.displayName || Component.name || 'Component') : void 0;
55
46
  }
56
47
  }
57
48
 
@@ -132,8 +123,8 @@ var ReactCompositeComponentMixin = {
132
123
  this._currentElement = element;
133
124
  this._rootNodeID = null;
134
125
  this._instance = null;
135
- this._nativeParent = null;
136
- this._nativeContainerInfo = null;
126
+ this._hostParent = null;
127
+ this._hostContainerInfo = null;
137
128
 
138
129
  // See ReactUpdateQueue
139
130
  this._updateBatchNumber = null;
@@ -153,39 +144,45 @@ var ReactCompositeComponentMixin = {
153
144
 
154
145
  // ComponentWillUnmount shall only be called once
155
146
  this._calledComponentWillUnmount = false;
147
+
148
+ if (process.env.NODE_ENV !== 'production') {
149
+ this._warnedAboutRefsInRender = false;
150
+ }
156
151
  },
157
152
 
158
153
  /**
159
154
  * Initializes the component, renders markup, and registers event listeners.
160
155
  *
161
156
  * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
162
- * @param {?object} nativeParent
163
- * @param {?object} nativeContainerInfo
157
+ * @param {?object} hostParent
158
+ * @param {?object} hostContainerInfo
164
159
  * @param {?object} context
165
160
  * @return {?string} Rendered markup to be inserted into the DOM.
166
161
  * @final
167
162
  * @internal
168
163
  */
169
- mountComponent: function (transaction, nativeParent, nativeContainerInfo, context) {
164
+ mountComponent: function (transaction, hostParent, hostContainerInfo, context) {
170
165
  this._context = context;
171
166
  this._mountOrder = nextMountID++;
172
- this._nativeParent = nativeParent;
173
- this._nativeContainerInfo = nativeContainerInfo;
167
+ this._hostParent = hostParent;
168
+ this._hostContainerInfo = hostContainerInfo;
174
169
 
175
- var publicProps = this._processProps(this._currentElement.props);
170
+ var publicProps = this._currentElement.props;
176
171
  var publicContext = this._processContext(context);
177
172
 
178
173
  var Component = this._currentElement.type;
179
174
 
175
+ var updateQueue = transaction.getUpdateQueue();
176
+
180
177
  // Initialize the public class
181
- var inst = this._constructComponent(publicProps, publicContext);
178
+ var inst = this._constructComponent(publicProps, publicContext, updateQueue);
182
179
  var renderedElement;
183
180
 
184
181
  // Support functional components
185
182
  if (!shouldConstruct(Component) && (inst == null || inst.render == null)) {
186
183
  renderedElement = inst;
187
184
  warnIfInvalidElement(Component, renderedElement);
188
- !(inst === null || inst === false || ReactElement.isValidElement(inst)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s(...): A valid React element (or null) must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : invariant(false) : void 0;
185
+ !(inst === null || inst === false || ReactElement.isValidElement(inst)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : _prodInvariant('105', Component.displayName || Component.name || 'Component') : void 0;
189
186
  inst = new StatelessComponent(Component);
190
187
  }
191
188
 
@@ -207,7 +204,7 @@ var ReactCompositeComponentMixin = {
207
204
  inst.props = publicProps;
208
205
  inst.context = publicContext;
209
206
  inst.refs = emptyObject;
210
- inst.updater = ReactUpdateQueue;
207
+ inst.updater = updateQueue;
211
208
 
212
209
  this._instance = inst;
213
210
 
@@ -231,7 +228,7 @@ var ReactCompositeComponentMixin = {
231
228
  if (initialState === undefined) {
232
229
  inst.state = initialState = null;
233
230
  }
234
- !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.state: must be set to an object or null', this.getName() || 'ReactCompositeComponent') : invariant(false) : void 0;
231
+ !(typeof initialState === 'object' && !Array.isArray(initialState)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.state: must be set to an object or null', this.getName() || 'ReactCompositeComponent') : _prodInvariant('106', this.getName() || 'ReactCompositeComponent') : void 0;
235
232
 
236
233
  this._pendingStateQueue = null;
237
234
  this._pendingReplaceState = false;
@@ -239,9 +236,9 @@ var ReactCompositeComponentMixin = {
239
236
 
240
237
  var markup;
241
238
  if (inst.unstable_handleError) {
242
- markup = this.performInitialMountWithErrorHandling(renderedElement, nativeParent, nativeContainerInfo, transaction, context);
239
+ markup = this.performInitialMountWithErrorHandling(renderedElement, hostParent, hostContainerInfo, transaction, context);
243
240
  } else {
244
- markup = this.performInitialMount(renderedElement, nativeParent, nativeContainerInfo, transaction, context);
241
+ markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
245
242
  }
246
243
 
247
244
  if (inst.componentDidMount) {
@@ -255,20 +252,20 @@ var ReactCompositeComponentMixin = {
255
252
  return markup;
256
253
  },
257
254
 
258
- _constructComponent: function (publicProps, publicContext) {
255
+ _constructComponent: function (publicProps, publicContext, updateQueue) {
259
256
  if (process.env.NODE_ENV !== 'production') {
260
257
  ReactCurrentOwner.current = this;
261
258
  try {
262
- return this._constructComponentWithoutOwner(publicProps, publicContext);
259
+ return this._constructComponentWithoutOwner(publicProps, publicContext, updateQueue);
263
260
  } finally {
264
261
  ReactCurrentOwner.current = null;
265
262
  }
266
263
  } else {
267
- return this._constructComponentWithoutOwner(publicProps, publicContext);
264
+ return this._constructComponentWithoutOwner(publicProps, publicContext, updateQueue);
268
265
  }
269
266
  },
270
267
 
271
- _constructComponentWithoutOwner: function (publicProps, publicContext) {
268
+ _constructComponentWithoutOwner: function (publicProps, publicContext, updateQueue) {
272
269
  var Component = this._currentElement.type;
273
270
  var instanceOrElement;
274
271
  if (shouldConstruct(Component)) {
@@ -277,7 +274,7 @@ var ReactCompositeComponentMixin = {
277
274
  ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'ctor');
278
275
  }
279
276
  }
280
- instanceOrElement = new Component(publicProps, publicContext, ReactUpdateQueue);
277
+ instanceOrElement = new Component(publicProps, publicContext, updateQueue);
281
278
  if (process.env.NODE_ENV !== 'production') {
282
279
  if (this._debugID !== 0) {
283
280
  ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'ctor');
@@ -291,7 +288,7 @@ var ReactCompositeComponentMixin = {
291
288
  ReactInstrumentation.debugTool.onBeginLifeCycleTimer(this._debugID, 'render');
292
289
  }
293
290
  }
294
- instanceOrElement = Component(publicProps, publicContext, ReactUpdateQueue);
291
+ instanceOrElement = Component(publicProps, publicContext, updateQueue);
295
292
  if (process.env.NODE_ENV !== 'production') {
296
293
  if (this._debugID !== 0) {
297
294
  ReactInstrumentation.debugTool.onEndLifeCycleTimer(this._debugID, 'render');
@@ -301,12 +298,17 @@ var ReactCompositeComponentMixin = {
301
298
  return instanceOrElement;
302
299
  },
303
300
 
304
- performInitialMountWithErrorHandling: function (renderedElement, nativeParent, nativeContainerInfo, transaction, context) {
301
+ performInitialMountWithErrorHandling: function (renderedElement, hostParent, hostContainerInfo, transaction, context) {
305
302
  var markup;
306
303
  var checkpoint = transaction.checkpoint();
307
304
  try {
308
- markup = this.performInitialMount(renderedElement, nativeParent, nativeContainerInfo, transaction, context);
305
+ markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
309
306
  } catch (e) {
307
+ if (process.env.NODE_ENV !== 'production') {
308
+ if (this._debugID !== 0) {
309
+ ReactInstrumentation.debugTool.onError();
310
+ }
311
+ }
310
312
  // Roll back to checkpoint, handle error (which may add items to the transaction), and take a new checkpoint
311
313
  transaction.rollback(checkpoint);
312
314
  this._instance.unstable_handleError(e);
@@ -320,12 +322,12 @@ var ReactCompositeComponentMixin = {
320
322
 
321
323
  // Try again - we've informed the component about the error, so they can render an error message this time.
322
324
  // If this throws again, the error will bubble up (and can be caught by a higher error boundary).
323
- markup = this.performInitialMount(renderedElement, nativeParent, nativeContainerInfo, transaction, context);
325
+ markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
324
326
  }
325
327
  return markup;
326
328
  },
327
329
 
328
- performInitialMount: function (renderedElement, nativeParent, nativeContainerInfo, transaction, context) {
330
+ performInitialMount: function (renderedElement, hostParent, hostContainerInfo, transaction, context) {
329
331
  var inst = this._instance;
330
332
  if (inst.componentWillMount) {
331
333
  if (process.env.NODE_ENV !== 'production') {
@@ -351,22 +353,30 @@ var ReactCompositeComponentMixin = {
351
353
  renderedElement = this._renderValidatedComponent();
352
354
  }
353
355
 
354
- this._renderedNodeType = ReactNodeTypes.getType(renderedElement);
355
- this._renderedComponent = this._instantiateReactComponent(renderedElement);
356
+ var nodeType = ReactNodeTypes.getType(renderedElement);
357
+ this._renderedNodeType = nodeType;
358
+ var child = this._instantiateReactComponent(renderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */
359
+ );
360
+ this._renderedComponent = child;
361
+ if (process.env.NODE_ENV !== 'production') {
362
+ if (child._debugID !== 0 && this._debugID !== 0) {
363
+ ReactInstrumentation.debugTool.onSetParent(child._debugID, this._debugID);
364
+ }
365
+ }
356
366
 
357
- var markup = ReactReconciler.mountComponent(this._renderedComponent, transaction, nativeParent, nativeContainerInfo, this._processChildContext(context));
367
+ var markup = ReactReconciler.mountComponent(child, transaction, hostParent, hostContainerInfo, this._processChildContext(context));
358
368
 
359
369
  if (process.env.NODE_ENV !== 'production') {
360
370
  if (this._debugID !== 0) {
361
- ReactInstrumentation.debugTool.onSetChildren(this._debugID, this._renderedComponent._debugID !== 0 ? [this._renderedComponent._debugID] : []);
371
+ ReactInstrumentation.debugTool.onSetChildren(this._debugID, child._debugID !== 0 ? [child._debugID] : []);
362
372
  }
363
373
  }
364
374
 
365
375
  return markup;
366
376
  },
367
377
 
368
- getNativeNode: function () {
369
- return ReactReconciler.getNativeNode(this._renderedComponent);
378
+ getHostNode: function () {
379
+ return ReactReconciler.getHostNode(this._renderedComponent);
370
380
  },
371
381
 
372
382
  /**
@@ -469,7 +479,7 @@ var ReactCompositeComponentMixin = {
469
479
  if (process.env.NODE_ENV !== 'production') {
470
480
  var Component = this._currentElement.type;
471
481
  if (Component.contextTypes) {
472
- this._checkPropTypes(Component.contextTypes, maskedContext, ReactPropTypeLocations.context);
482
+ this._checkContextTypes(Component.contextTypes, maskedContext, ReactPropTypeLocations.context);
473
483
  }
474
484
  }
475
485
  return maskedContext;
@@ -491,12 +501,12 @@ var ReactCompositeComponentMixin = {
491
501
  ReactInstrumentation.debugTool.onEndProcessingChildContext();
492
502
  }
493
503
  if (childContext) {
494
- !(typeof Component.childContextTypes === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', this.getName() || 'ReactCompositeComponent') : invariant(false) : void 0;
504
+ !(typeof Component.childContextTypes === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().', this.getName() || 'ReactCompositeComponent') : _prodInvariant('107', this.getName() || 'ReactCompositeComponent') : void 0;
495
505
  if (process.env.NODE_ENV !== 'production') {
496
- this._checkPropTypes(Component.childContextTypes, childContext, ReactPropTypeLocations.childContext);
506
+ this._checkContextTypes(Component.childContextTypes, childContext, ReactPropTypeLocations.childContext);
497
507
  }
498
508
  for (var name in childContext) {
499
- !(name in Component.childContextTypes) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : invariant(false) : void 0;
509
+ !(name in Component.childContextTypes) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : _prodInvariant('108', this.getName() || 'ReactCompositeComponent', name) : void 0;
500
510
  }
501
511
  return _assign({}, currentContext, childContext);
502
512
  }
@@ -504,62 +514,15 @@ var ReactCompositeComponentMixin = {
504
514
  },
505
515
 
506
516
  /**
507
- * Processes props by setting default values for unspecified props and
508
- * asserting that the props are valid. Does not mutate its argument; returns
509
- * a new props object with defaults merged in.
517
+ * Assert that the context types are valid
510
518
  *
511
- * @param {object} newProps
512
- * @return {object}
513
- * @private
514
- */
515
- _processProps: function (newProps) {
516
- if (process.env.NODE_ENV !== 'production') {
517
- var Component = this._currentElement.type;
518
- if (Component.propTypes) {
519
- this._checkPropTypes(Component.propTypes, newProps, ReactPropTypeLocations.prop);
520
- }
521
- }
522
- return newProps;
523
- },
524
-
525
- /**
526
- * Assert that the props are valid
527
- *
528
- * @param {object} propTypes Map of prop name to a ReactPropType
529
- * @param {object} props
519
+ * @param {object} typeSpecs Map of context field to a ReactPropType
520
+ * @param {object} values Runtime values that need to be type-checked
530
521
  * @param {string} location e.g. "prop", "context", "child context"
531
522
  * @private
532
523
  */
533
- _checkPropTypes: function (propTypes, props, location) {
534
- // TODO: Stop validating prop types here and only use the element
535
- // validation.
536
- var componentName = this.getName();
537
- for (var propName in propTypes) {
538
- if (propTypes.hasOwnProperty(propName)) {
539
- var error;
540
- try {
541
- // This is intentionally an invariant that gets caught. It's the same
542
- // behavior as without this statement except with a better message.
543
- !(typeof propTypes[propName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually ' + 'from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], propName) : invariant(false) : void 0;
544
- error = propTypes[propName](props, propName, componentName, location);
545
- } catch (ex) {
546
- error = ex;
547
- }
548
- if (error instanceof Error) {
549
- // We may want to extend this logic for similar errors in
550
- // top-level render calls, so I'm abstracting it away into
551
- // a function to minimize refactoring in the future
552
- var addendum = getDeclarationErrorAddendum(this);
553
-
554
- if (location === ReactPropTypeLocations.prop) {
555
- // Preface gives us something to blacklist in warning module
556
- process.env.NODE_ENV !== 'production' ? warning(false, 'Failed Composite propType: %s%s', error.message, addendum) : void 0;
557
- } else {
558
- process.env.NODE_ENV !== 'production' ? warning(false, 'Failed Context Types: %s%s', error.message, addendum) : void 0;
559
- }
560
- }
561
- }
562
- }
524
+ _checkContextTypes: function (typeSpecs, values, location) {
525
+ checkReactTypeSpec(typeSpecs, values, location, this.getName(), null, this._debugID);
563
526
  },
564
527
 
565
528
  receiveComponent: function (nextElement, transaction, nextContext) {
@@ -605,6 +568,8 @@ var ReactCompositeComponentMixin = {
605
568
  */
606
569
  updateComponent: function (transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext) {
607
570
  var inst = this._instance;
571
+ !(inst != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Attempted to update component `%s` that has already been unmounted (or failed to mount).', this.getName() || 'ReactCompositeComponent') : _prodInvariant('136', this.getName() || 'ReactCompositeComponent') : void 0;
572
+
608
573
  var willReceive = false;
609
574
  var nextContext;
610
575
  var nextProps;
@@ -617,13 +582,10 @@ var ReactCompositeComponentMixin = {
617
582
  willReceive = true;
618
583
  }
619
584
 
620
- // Distinguish between a props update versus a simple state update
621
- if (prevParentElement === nextParentElement) {
622
- // Skip checking prop types again -- we don't read inst.props to avoid
623
- // warning for DOM component props in this upgrade
624
- nextProps = nextParentElement.props;
625
- } else {
626
- nextProps = this._processProps(nextParentElement.props);
585
+ nextProps = nextParentElement.props;
586
+
587
+ // Not a simple state update but a props update
588
+ if (prevParentElement !== nextParentElement) {
627
589
  willReceive = true;
628
590
  }
629
591
 
@@ -774,21 +736,29 @@ var ReactCompositeComponentMixin = {
774
736
  if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) {
775
737
  ReactReconciler.receiveComponent(prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context));
776
738
  } else {
777
- var oldNativeNode = ReactReconciler.getNativeNode(prevComponentInstance);
739
+ var oldHostNode = ReactReconciler.getHostNode(prevComponentInstance);
778
740
  ReactReconciler.unmountComponent(prevComponentInstance, false);
779
741
 
780
- this._renderedNodeType = ReactNodeTypes.getType(nextRenderedElement);
781
- this._renderedComponent = this._instantiateReactComponent(nextRenderedElement);
742
+ var nodeType = ReactNodeTypes.getType(nextRenderedElement);
743
+ this._renderedNodeType = nodeType;
744
+ var child = this._instantiateReactComponent(nextRenderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */
745
+ );
746
+ this._renderedComponent = child;
747
+ if (process.env.NODE_ENV !== 'production') {
748
+ if (child._debugID !== 0 && this._debugID !== 0) {
749
+ ReactInstrumentation.debugTool.onSetParent(child._debugID, this._debugID);
750
+ }
751
+ }
782
752
 
783
- var nextMarkup = ReactReconciler.mountComponent(this._renderedComponent, transaction, this._nativeParent, this._nativeContainerInfo, this._processChildContext(context));
753
+ var nextMarkup = ReactReconciler.mountComponent(child, transaction, this._hostParent, this._hostContainerInfo, this._processChildContext(context));
784
754
 
785
755
  if (process.env.NODE_ENV !== 'production') {
786
756
  if (this._debugID !== 0) {
787
- ReactInstrumentation.debugTool.onSetChildren(this._debugID, this._renderedComponent._debugID !== 0 ? [this._renderedComponent._debugID] : []);
757
+ ReactInstrumentation.debugTool.onSetChildren(this._debugID, child._debugID !== 0 ? [child._debugID] : []);
788
758
  }
789
759
  }
790
760
 
791
- this._replaceNodeWithMarkup(oldNativeNode, nextMarkup, prevComponentInstance);
761
+ this._replaceNodeWithMarkup(oldHostNode, nextMarkup, prevComponentInstance);
792
762
  }
793
763
  },
794
764
 
@@ -797,8 +767,8 @@ var ReactCompositeComponentMixin = {
797
767
  *
798
768
  * @protected
799
769
  */
800
- _replaceNodeWithMarkup: function (oldNativeNode, nextMarkup, prevInstance) {
801
- ReactComponentEnvironment.replaceNodeWithMarkup(oldNativeNode, nextMarkup, prevInstance);
770
+ _replaceNodeWithMarkup: function (oldHostNode, nextMarkup, prevInstance) {
771
+ ReactComponentEnvironment.replaceNodeWithMarkup(oldHostNode, nextMarkup, prevInstance);
802
772
  },
803
773
 
804
774
  /**
@@ -844,7 +814,7 @@ var ReactCompositeComponentMixin = {
844
814
  }
845
815
  !(
846
816
  // TODO: An `isValidNode` function would probably be more appropriate
847
- renderedComponent === null || renderedComponent === false || ReactElement.isValidElement(renderedComponent)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.render(): A valid React element (or null) must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : invariant(false) : void 0;
817
+ renderedComponent === null || renderedComponent === false || ReactElement.isValidElement(renderedComponent)) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : _prodInvariant('109', this.getName() || 'ReactCompositeComponent') : void 0;
848
818
 
849
819
  return renderedComponent;
850
820
  },
@@ -859,7 +829,7 @@ var ReactCompositeComponentMixin = {
859
829
  */
860
830
  attachRef: function (ref, component) {
861
831
  var inst = this.getPublicInstance();
862
- !(inst != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Stateless function components cannot have refs.') : invariant(false) : void 0;
832
+ !(inst != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Stateless function components cannot have refs.') : _prodInvariant('110') : void 0;
863
833
  var publicComponentInstance = component.getPublicInstance();
864
834
  if (process.env.NODE_ENV !== 'production') {
865
835
  var componentName = component && component.getName ? component.getName() : 'a component';