react 15.0.3-alpha.2 → 15.2.0-rc.2

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 (121) hide show
  1. package/dist/react-with-addons.js +3324 -2009
  2. package/dist/react-with-addons.min.js +7 -6
  3. package/dist/react.js +2736 -2005
  4. package/dist/react.min.js +6 -6
  5. package/lib/CSSPropertyOperations.js +5 -5
  6. package/lib/CallbackQueue.js +3 -2
  7. package/lib/DOMChildrenOperations.js +42 -7
  8. package/lib/DOMLazyTree.js +9 -3
  9. package/lib/DOMProperty.js +6 -4
  10. package/lib/DOMPropertyOperations.js +35 -12
  11. package/lib/Danger.js +10 -8
  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/LinkedStateMixin.js +1 -0
  18. package/lib/LinkedValueUtils.js +5 -3
  19. package/lib/NativeMethodsMixin.js +6 -4
  20. package/lib/PooledClass.js +3 -1
  21. package/lib/React.js +1 -1
  22. package/lib/ReactCSSTransitionGroup.js +5 -0
  23. package/lib/ReactCSSTransitionGroupChild.js +15 -8
  24. package/lib/ReactChildReconciler.js +15 -6
  25. package/lib/ReactChildren.js +9 -1
  26. package/lib/ReactClass.js +15 -13
  27. package/lib/ReactComponent.js +3 -6
  28. package/lib/ReactComponentBrowserEnvironment.js +0 -5
  29. package/lib/ReactComponentEnvironment.js +3 -1
  30. package/lib/ReactComponentTreeDevtool.js +223 -0
  31. package/lib/ReactComponentTreeTestUtils.js +87 -0
  32. package/lib/ReactComponentWithPureRenderMixin.js +2 -0
  33. package/lib/ReactCompositeComponent.js +208 -119
  34. package/lib/ReactDOM.js +3 -6
  35. package/lib/ReactDOMButton.js +2 -2
  36. package/lib/ReactDOMComponent.js +162 -68
  37. package/lib/ReactDOMComponentTree.js +23 -21
  38. package/lib/ReactDOMDebugTool.js +7 -1
  39. package/lib/ReactDOMEmptyComponent.js +9 -9
  40. package/lib/ReactDOMFactories.js +1 -1
  41. package/lib/ReactDOMIDOperations.js +0 -5
  42. package/lib/ReactDOMInput.js +56 -18
  43. package/lib/ReactDOMOption.js +40 -26
  44. package/lib/ReactDOMSelect.js +3 -3
  45. package/lib/ReactDOMTextComponent.js +28 -26
  46. package/lib/ReactDOMTextarea.js +59 -32
  47. package/lib/ReactDOMTreeTraversal.js +18 -16
  48. package/lib/ReactDOMUnknownPropertyDevtool.js +65 -17
  49. package/lib/ReactDebugTool.js +250 -11
  50. package/lib/ReactDefaultInjection.js +2 -11
  51. package/lib/ReactElement.js +90 -25
  52. package/lib/ReactElementValidator.js +26 -81
  53. package/lib/ReactEventListener.js +2 -2
  54. package/lib/ReactFragment.js +8 -3
  55. package/lib/{ReactNativeComponent.js → ReactHostComponent.js} +10 -29
  56. package/lib/ReactHostOperationHistoryDevtool.js +37 -0
  57. package/lib/ReactInjection.js +2 -4
  58. package/lib/ReactInstanceHandles.js +8 -6
  59. package/lib/ReactLink.js +3 -0
  60. package/lib/ReactMount.js +43 -20
  61. package/lib/ReactMultiChild.js +51 -8
  62. package/lib/ReactNativeAttributePayload.js +5 -2
  63. package/lib/ReactNativeBaseComponent.js +7 -7
  64. package/lib/ReactNativeBridgeEventPlugin.js +1 -1
  65. package/lib/ReactNativeComponentTree.js +8 -6
  66. package/lib/ReactNativeDOMIDOperations.js +4 -8
  67. package/lib/ReactNativeDefaultInjection.js +9 -7
  68. package/lib/ReactNativeGlobalResponderHandler.js +1 -1
  69. package/lib/ReactNativeMount.js +25 -8
  70. package/lib/ReactNativeTagHandles.js +3 -1
  71. package/lib/ReactNativeTextComponent.js +18 -9
  72. package/lib/ReactNativeTreeTraversal.js +11 -11
  73. package/lib/ReactNodeTypes.js +5 -3
  74. package/lib/ReactNoop.js +76 -0
  75. package/lib/ReactOwner.js +4 -2
  76. package/lib/ReactPerf.js +473 -75
  77. package/lib/ReactPropTypes.js +23 -0
  78. package/lib/ReactReconcileTransaction.js +1 -1
  79. package/lib/ReactReconciler.js +57 -11
  80. package/lib/ReactServerRendering.js +24 -3
  81. package/lib/ReactSimpleEmptyComponent.js +4 -4
  82. package/lib/ReactTestMount.js +126 -0
  83. package/lib/ReactTestReconcileTransaction.js +100 -0
  84. package/lib/ReactTestRenderer.js +133 -0
  85. package/lib/ReactTestUtils.js +25 -10
  86. package/lib/ReactTransitionChildMapping.js +7 -1
  87. package/lib/ReactTransitionGroup.js +44 -5
  88. package/lib/ReactUpdateQueue.js +9 -1
  89. package/lib/ReactUpdates.js +30 -11
  90. package/lib/ReactVersion.js +1 -1
  91. package/lib/ReactWithAddons.js +1 -1
  92. package/lib/ResponderEventPlugin.js +8 -6
  93. package/lib/ResponderTouchHistoryStore.js +6 -4
  94. package/lib/SimpleEventPlugin.js +3 -1
  95. package/lib/SyntheticEvent.js +2 -3
  96. package/lib/SyntheticUIEvent.js +1 -1
  97. package/lib/Transaction.js +4 -2
  98. package/lib/accumulate.js +3 -1
  99. package/lib/accumulateInto.js +3 -1
  100. package/lib/checkReactTypeSpec.js +71 -0
  101. package/lib/createReactNativeComponentClass.js +2 -2
  102. package/lib/dangerousStyleValue.js +3 -1
  103. package/lib/escapeTextContentForBrowser.js +96 -12
  104. package/lib/findDOMNode.js +8 -4
  105. package/lib/findNodeHandle.js +5 -3
  106. package/lib/flattenChildren.js +13 -4
  107. package/lib/{getNativeComponentFromComposite.js → getHostComponentFromComposite.js} +4 -4
  108. package/lib/instantiateReactComponent.js +44 -10
  109. package/lib/onlyChild.js +10 -5
  110. package/lib/reactComponentExpect.js +3 -3
  111. package/lib/reactProdInvariant.js +38 -0
  112. package/lib/setInnerHTML.js +17 -1
  113. package/lib/setTextContent.js +8 -0
  114. package/lib/shallowCompare.js +1 -0
  115. package/lib/traverseAllChildren.js +3 -1
  116. package/lib/update.js +16 -11
  117. package/package.json +2 -2
  118. package/lib/MetaMatchers.js +0 -118
  119. package/lib/ReactDebugInstanceMap.js +0 -102
  120. package/lib/ReactDefaultPerf.js +0 -316
  121. package/lib/ReactDefaultPerfAnalysis.js +0 -210
@@ -121,7 +121,7 @@ function updateOptions(inst, multiple, propValue) {
121
121
  }
122
122
 
123
123
  /**
124
- * Implements a <select> native component that allows optionally setting the
124
+ * Implements a <select> host component that allows optionally setting the
125
125
  * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
126
126
  * stringable. If `multiple` is true, the prop must be an array of stringables.
127
127
  *
@@ -136,8 +136,8 @@ function updateOptions(inst, multiple, propValue) {
136
136
  * selected.
137
137
  */
138
138
  var ReactDOMSelect = {
139
- getNativeProps: function (inst, props) {
140
- return _assign({}, DisabledInputUtils.getNativeProps(inst, props), {
139
+ getHostProps: function (inst, props) {
140
+ return _assign({}, DisabledInputUtils.getHostProps(inst, props), {
141
141
  onChange: inst._wrapperState.onChange,
142
142
  value: undefined
143
143
  });
@@ -11,12 +11,13 @@
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 DOMChildrenOperations = require('./DOMChildrenOperations');
17
18
  var DOMLazyTree = require('./DOMLazyTree');
18
19
  var ReactDOMComponentTree = require('./ReactDOMComponentTree');
19
- var ReactPerf = require('./ReactPerf');
20
+ var ReactInstrumentation = require('./ReactInstrumentation');
20
21
 
21
22
  var escapeTextContentForBrowser = require('./escapeTextContentForBrowser');
22
23
  var invariant = require('fbjs/lib/invariant');
@@ -42,8 +43,8 @@ var ReactDOMTextComponent = function (text) {
42
43
  this._currentElement = text;
43
44
  this._stringText = '' + text;
44
45
  // ReactDOMComponentTree uses these:
45
- this._nativeNode = null;
46
- this._nativeParent = null;
46
+ this._hostNode = null;
47
+ this._hostParent = null;
47
48
 
48
49
  // Properties
49
50
  this._domID = null;
@@ -62,13 +63,15 @@ _assign(ReactDOMTextComponent.prototype, {
62
63
  * @return {string} Markup for this text node.
63
64
  * @internal
64
65
  */
65
- mountComponent: function (transaction, nativeParent, nativeContainerInfo, context) {
66
+ mountComponent: function (transaction, hostParent, hostContainerInfo, context) {
66
67
  if (process.env.NODE_ENV !== 'production') {
68
+ ReactInstrumentation.debugTool.onSetText(this._debugID, this._stringText);
69
+
67
70
  var parentInfo;
68
- if (nativeParent != null) {
69
- parentInfo = nativeParent._ancestorInfo;
70
- } else if (nativeContainerInfo != null) {
71
- parentInfo = nativeContainerInfo._ancestorInfo;
71
+ if (hostParent != null) {
72
+ parentInfo = hostParent._ancestorInfo;
73
+ } else if (hostContainerInfo != null) {
74
+ parentInfo = hostContainerInfo._ancestorInfo;
72
75
  }
73
76
  if (parentInfo) {
74
77
  // parentInfo should always be present except for the top-level
@@ -77,13 +80,13 @@ _assign(ReactDOMTextComponent.prototype, {
77
80
  }
78
81
  }
79
82
 
80
- var domID = nativeContainerInfo._idCounter++;
83
+ var domID = hostContainerInfo._idCounter++;
81
84
  var openingValue = ' react-text: ' + domID + ' ';
82
85
  var closingValue = ' /react-text ';
83
86
  this._domID = domID;
84
- this._nativeParent = nativeParent;
87
+ this._hostParent = hostParent;
85
88
  if (transaction.useCreateElement) {
86
- var ownerDocument = nativeContainerInfo._ownerDocument;
89
+ var ownerDocument = hostContainerInfo._ownerDocument;
87
90
  var openingComment = ownerDocument.createComment(openingValue);
88
91
  var closingComment = ownerDocument.createComment(closingValue);
89
92
  var lazyTree = DOMLazyTree(ownerDocument.createDocumentFragment());
@@ -125,22 +128,26 @@ _assign(ReactDOMTextComponent.prototype, {
125
128
  // and/or updateComponent to do the actual update for consistency with
126
129
  // other component types?
127
130
  this._stringText = nextStringText;
128
- var commentNodes = this.getNativeNode();
131
+ var commentNodes = this.getHostNode();
129
132
  DOMChildrenOperations.replaceDelimitedText(commentNodes[0], commentNodes[1], nextStringText);
133
+
134
+ if (process.env.NODE_ENV !== 'production') {
135
+ ReactInstrumentation.debugTool.onSetText(this._debugID, nextStringText);
136
+ }
130
137
  }
131
138
  }
132
139
  },
133
140
 
134
- getNativeNode: function () {
135
- var nativeNode = this._commentNodes;
136
- if (nativeNode) {
137
- return nativeNode;
141
+ getHostNode: function () {
142
+ var hostNode = this._commentNodes;
143
+ if (hostNode) {
144
+ return hostNode;
138
145
  }
139
146
  if (!this._closingComment) {
140
147
  var openingComment = ReactDOMComponentTree.getNodeFromInstance(this);
141
148
  var node = openingComment.nextSibling;
142
149
  while (true) {
143
- !(node != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Missing closing comment for text component %s', this._domID) : invariant(false) : void 0;
150
+ !(node != null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Missing closing comment for text component %s', this._domID) : _prodInvariant('67', this._domID) : void 0;
144
151
  if (node.nodeType === 8 && node.nodeValue === ' /react-text ') {
145
152
  this._closingComment = node;
146
153
  break;
@@ -148,9 +155,9 @@ _assign(ReactDOMTextComponent.prototype, {
148
155
  node = node.nextSibling;
149
156
  }
150
157
  }
151
- nativeNode = [this._nativeNode, this._closingComment];
152
- this._commentNodes = nativeNode;
153
- return nativeNode;
158
+ hostNode = [this._hostNode, this._closingComment];
159
+ this._commentNodes = hostNode;
160
+ return hostNode;
154
161
  },
155
162
 
156
163
  unmountComponent: function () {
@@ -161,9 +168,4 @@ _assign(ReactDOMTextComponent.prototype, {
161
168
 
162
169
  });
163
170
 
164
- ReactPerf.measureMethods(ReactDOMTextComponent.prototype, 'ReactDOMTextComponent', {
165
- mountComponent: 'mountComponent',
166
- receiveComponent: 'receiveComponent'
167
- });
168
-
169
171
  module.exports = ReactDOMTextComponent;
@@ -11,10 +11,10 @@
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 DisabledInputUtils = require('./DisabledInputUtils');
17
- var DOMPropertyOperations = require('./DOMPropertyOperations');
18
18
  var LinkedValueUtils = require('./LinkedValueUtils');
19
19
  var ReactDOMComponentTree = require('./ReactDOMComponentTree');
20
20
  var ReactUpdates = require('./ReactUpdates');
@@ -42,7 +42,7 @@ function warnIfValueIsNull(props) {
42
42
  }
43
43
 
44
44
  /**
45
- * Implements a <textarea> native component that allows setting `value`, and
45
+ * Implements a <textarea> host component that allows setting `value`, and
46
46
  * `defaultValue`. This differs from the traditional DOM API because value is
47
47
  * usually set as PCDATA children.
48
48
  *
@@ -57,19 +57,22 @@ function warnIfValueIsNull(props) {
57
57
  * `defaultValue` if specified, or the children content (deprecated).
58
58
  */
59
59
  var ReactDOMTextarea = {
60
- getNativeProps: function (inst, props) {
61
- !(props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : invariant(false) : void 0;
60
+ getHostProps: function (inst, props) {
61
+ !(props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : _prodInvariant('91') : void 0;
62
62
 
63
63
  // Always set children to the same thing. In IE9, the selection range will
64
- // get reset if `textContent` is mutated.
65
- var nativeProps = _assign({}, DisabledInputUtils.getNativeProps(inst, props), {
66
- defaultValue: undefined,
64
+ // get reset if `textContent` is mutated. We could add a check in setTextContent
65
+ // to only set the value if/when the value differs from the node value (which would
66
+ // completely solve this IE9 bug), but Sebastian+Ben seemed to like this solution.
67
+ // The value can be a boolean or object so that's why it's forced to be a string.
68
+ var hostProps = _assign({}, DisabledInputUtils.getHostProps(inst, props), {
67
69
  value: undefined,
68
- children: inst._wrapperState.initialValue,
70
+ defaultValue: undefined,
71
+ children: '' + inst._wrapperState.initialValue,
69
72
  onChange: inst._wrapperState.onChange
70
73
  });
71
74
 
72
- return nativeProps;
75
+ return hostProps;
73
76
  },
74
77
 
75
78
  mountWrapper: function (inst, props) {
@@ -86,31 +89,34 @@ var ReactDOMTextarea = {
86
89
  warnIfValueIsNull(props);
87
90
  }
88
91
 
89
- var defaultValue = props.defaultValue;
90
- // TODO (yungsters): Remove support for children content in <textarea>.
91
- var children = props.children;
92
- if (children != null) {
93
- if (process.env.NODE_ENV !== 'production') {
94
- process.env.NODE_ENV !== 'production' ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : void 0;
92
+ var value = LinkedValueUtils.getValue(props);
93
+ var initialValue = value;
94
+
95
+ // Only bother fetching default value if we're going to use it
96
+ if (value == null) {
97
+ var defaultValue = props.defaultValue;
98
+ // TODO (yungsters): Remove support for children content in <textarea>.
99
+ var children = props.children;
100
+ if (children != null) {
101
+ if (process.env.NODE_ENV !== 'production') {
102
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : void 0;
103
+ }
104
+ !(defaultValue == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : _prodInvariant('92') : void 0;
105
+ if (Array.isArray(children)) {
106
+ !(children.length <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, '<textarea> can only have at most one child.') : _prodInvariant('93') : void 0;
107
+ children = children[0];
108
+ }
109
+
110
+ defaultValue = '' + children;
95
111
  }
96
- !(defaultValue == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : invariant(false) : void 0;
97
- if (Array.isArray(children)) {
98
- !(children.length <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, '<textarea> can only have at most one child.') : invariant(false) : void 0;
99
- children = children[0];
112
+ if (defaultValue == null) {
113
+ defaultValue = '';
100
114
  }
101
-
102
- defaultValue = '' + children;
115
+ initialValue = defaultValue;
103
116
  }
104
- if (defaultValue == null) {
105
- defaultValue = '';
106
- }
107
- var value = LinkedValueUtils.getValue(props);
117
+
108
118
  inst._wrapperState = {
109
- // We save the initial value so that `ReactDOMComponent` doesn't update
110
- // `textContent` (unnecessary since we update value).
111
- // The initial value can be a boolean or object so that's why it's
112
- // forced to be a string.
113
- initialValue: '' + (value != null ? value : defaultValue),
119
+ initialValue: '' + initialValue,
114
120
  listeners: null,
115
121
  onChange: _handleChange.bind(inst)
116
122
  };
@@ -123,12 +129,33 @@ var ReactDOMTextarea = {
123
129
  warnIfValueIsNull(props);
124
130
  }
125
131
 
132
+ var node = ReactDOMComponentTree.getNodeFromInstance(inst);
126
133
  var value = LinkedValueUtils.getValue(props);
127
134
  if (value != null) {
128
135
  // Cast `value` to a string to ensure the value is set correctly. While
129
136
  // browsers typically do this as necessary, jsdom doesn't.
130
- DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'value', '' + value);
137
+ var newValue = '' + value;
138
+
139
+ // To avoid side effects (such as losing text selection), only set value if changed
140
+ if (newValue !== node.value) {
141
+ node.value = newValue;
142
+ }
143
+ if (props.defaultValue == null) {
144
+ node.defaultValue = newValue;
145
+ }
146
+ }
147
+ if (props.defaultValue != null) {
148
+ node.defaultValue = props.defaultValue;
131
149
  }
150
+ },
151
+
152
+ postMountWrapper: function (inst) {
153
+ // This is in postMount because we need access to the DOM node, which is not
154
+ // available until after the component has mounted.
155
+ var node = ReactDOMComponentTree.getNodeFromInstance(inst);
156
+
157
+ // Warning: node.value may be the empty string at this point (IE11) if placeholder is set.
158
+ node.value = node.textContent; // Detach value from defaultValue
132
159
  }
133
160
  };
134
161
 
@@ -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
  /**
@@ -18,27 +20,27 @@ var invariant = require('fbjs/lib/invariant');
18
20
  * different trees.
19
21
  */
20
22
  function getLowestCommonAncestor(instA, instB) {
21
- !('_nativeNode' in instA) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : invariant(false) : void 0;
22
- !('_nativeNode' in instB) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : invariant(false) : void 0;
23
+ !('_hostNode' in instA) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0;
24
+ !('_hostNode' in instB) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0;
23
25
 
24
26
  var depthA = 0;
25
- for (var tempA = instA; tempA; tempA = tempA._nativeParent) {
27
+ for (var tempA = instA; tempA; tempA = tempA._hostParent) {
26
28
  depthA++;
27
29
  }
28
30
  var depthB = 0;
29
- for (var tempB = instB; tempB; tempB = tempB._nativeParent) {
31
+ for (var tempB = instB; tempB; tempB = tempB._hostParent) {
30
32
  depthB++;
31
33
  }
32
34
 
33
35
  // If A is deeper, crawl up.
34
36
  while (depthA - depthB > 0) {
35
- instA = instA._nativeParent;
37
+ instA = instA._hostParent;
36
38
  depthA--;
37
39
  }
38
40
 
39
41
  // If B is deeper, crawl up.
40
42
  while (depthB - depthA > 0) {
41
- instB = instB._nativeParent;
43
+ instB = instB._hostParent;
42
44
  depthB--;
43
45
  }
44
46
 
@@ -48,8 +50,8 @@ function getLowestCommonAncestor(instA, instB) {
48
50
  if (instA === instB) {
49
51
  return instA;
50
52
  }
51
- instA = instA._nativeParent;
52
- instB = instB._nativeParent;
53
+ instA = instA._hostParent;
54
+ instB = instB._hostParent;
53
55
  }
54
56
  return null;
55
57
  }
@@ -58,14 +60,14 @@ function getLowestCommonAncestor(instA, instB) {
58
60
  * Return if A is an ancestor of B.
59
61
  */
60
62
  function isAncestor(instA, instB) {
61
- !('_nativeNode' in instA) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : invariant(false) : void 0;
62
- !('_nativeNode' in instB) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : invariant(false) : void 0;
63
+ !('_hostNode' in instA) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0;
64
+ !('_hostNode' in instB) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0;
63
65
 
64
66
  while (instB) {
65
67
  if (instB === instA) {
66
68
  return true;
67
69
  }
68
- instB = instB._nativeParent;
70
+ instB = instB._hostParent;
69
71
  }
70
72
  return false;
71
73
  }
@@ -74,9 +76,9 @@ function isAncestor(instA, instB) {
74
76
  * Return the parent instance of the passed-in instance.
75
77
  */
76
78
  function getParentInstance(inst) {
77
- !('_nativeNode' in inst) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getParentInstance: Invalid argument.') : invariant(false) : void 0;
79
+ !('_hostNode' in inst) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getParentInstance: Invalid argument.') : _prodInvariant('36') : void 0;
78
80
 
79
- return inst._nativeParent;
81
+ return inst._hostParent;
80
82
  }
81
83
 
82
84
  /**
@@ -86,7 +88,7 @@ function traverseTwoPhase(inst, fn, arg) {
86
88
  var path = [];
87
89
  while (inst) {
88
90
  path.push(inst);
89
- inst = inst._nativeParent;
91
+ inst = inst._hostParent;
90
92
  }
91
93
  var i;
92
94
  for (i = path.length; i-- > 0;) {
@@ -109,12 +111,12 @@ function traverseEnterLeave(from, to, fn, argFrom, argTo) {
109
111
  var pathFrom = [];
110
112
  while (from && from !== common) {
111
113
  pathFrom.push(from);
112
- from = from._nativeParent;
114
+ from = from._hostParent;
113
115
  }
114
116
  var pathTo = [];
115
117
  while (to && to !== common) {
116
118
  pathTo.push(to);
117
- to = to._nativeParent;
119
+ to = to._hostParent;
118
120
  }
119
121
  var i;
120
122
  for (i = 0; i < pathFrom.length; i++) {
@@ -13,6 +13,7 @@
13
13
 
14
14
  var DOMProperty = require('./DOMProperty');
15
15
  var EventPluginRegistry = require('./EventPluginRegistry');
16
+ var ReactComponentTreeDevtool = require('./ReactComponentTreeDevtool');
16
17
 
17
18
  var warning = require('fbjs/lib/warning');
18
19
 
@@ -21,43 +22,90 @@ if (process.env.NODE_ENV !== 'production') {
21
22
  children: true,
22
23
  dangerouslySetInnerHTML: true,
23
24
  key: true,
24
- ref: true
25
+ ref: true,
26
+
27
+ autoFocus: true,
28
+ defaultValue: true,
29
+ valueLink: true,
30
+ defaultChecked: true,
31
+ checkedLink: true,
32
+ innerHTML: true,
33
+ suppressContentEditableWarning: true,
34
+ onFocusIn: true,
35
+ onFocusOut: true
25
36
  };
26
37
  var warnedProperties = {};
27
38
 
28
- var warnUnknownProperty = function (name) {
39
+ var validateProperty = function (tagName, name, debugID) {
29
40
  if (DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name)) {
30
- return;
41
+ return true;
31
42
  }
32
43
  if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) {
33
- return;
44
+ return true;
45
+ }
46
+ if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) {
47
+ return true;
34
48
  }
35
-
36
49
  warnedProperties[name] = true;
37
50
  var lowerCasedName = name.toLowerCase();
38
51
 
39
52
  // data-* attributes should be lowercase; suggest the lowercase version
40
53
  var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null;
41
54
 
42
- // For now, only warn when we have a suggested correction. This prevents
43
- // logging too much when using transferPropsTo.
44
- process.env.NODE_ENV !== 'production' ? warning(standardName == null, 'Unknown DOM property %s. Did you mean %s?', name, standardName) : void 0;
45
-
46
55
  var registrationName = EventPluginRegistry.possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null;
47
56
 
48
- process.env.NODE_ENV !== 'production' ? warning(registrationName == null, 'Unknown event handler property %s. Did you mean `%s`?', name, registrationName) : void 0;
57
+ if (standardName != null) {
58
+ process.env.NODE_ENV !== 'production' ? warning(standardName == null, 'Unknown DOM property %s. Did you mean %s?%s', name, standardName, ReactComponentTreeDevtool.getStackAddendumByID(debugID)) : void 0;
59
+ return true;
60
+ } else if (registrationName != null) {
61
+ process.env.NODE_ENV !== 'production' ? warning(registrationName == null, 'Unknown event handler property %s. Did you mean `%s`?%s', name, registrationName, ReactComponentTreeDevtool.getStackAddendumByID(debugID)) : void 0;
62
+ return true;
63
+ } else {
64
+ // We were unable to guess which prop the user intended.
65
+ // It is likely that the user was just blindly spreading/forwarding props
66
+ // Components should be careful to only render valid props/attributes.
67
+ // Warning will be invoked in warnUnknownProperties to allow grouping.
68
+ return false;
69
+ }
49
70
  };
50
71
  }
51
72
 
73
+ var warnUnknownProperties = function (debugID, element) {
74
+ var unknownProps = [];
75
+ for (var key in element.props) {
76
+ var isValid = validateProperty(element.type, key, debugID);
77
+ if (!isValid) {
78
+ unknownProps.push(key);
79
+ }
80
+ }
81
+
82
+ var unknownPropString = unknownProps.map(function (prop) {
83
+ return '`' + prop + '`';
84
+ }).join(', ');
85
+
86
+ if (unknownProps.length === 1) {
87
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown prop %s on <%s> tag. Remove this prop from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeDevtool.getStackAddendumByID(debugID)) : void 0;
88
+ } else if (unknownProps.length > 1) {
89
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Unknown props %s on <%s> tag. Remove these props from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeDevtool.getStackAddendumByID(debugID)) : void 0;
90
+ }
91
+ };
92
+
93
+ function handleElement(debugID, element) {
94
+ if (element == null || typeof element.type !== 'string') {
95
+ return;
96
+ }
97
+ if (element.type.indexOf('-') >= 0 || element.props.is) {
98
+ return;
99
+ }
100
+ warnUnknownProperties(debugID, element);
101
+ }
102
+
52
103
  var ReactDOMUnknownPropertyDevtool = {
53
- onCreateMarkupForProperty: function (name, value) {
54
- warnUnknownProperty(name);
55
- },
56
- onSetValueForProperty: function (node, name, value) {
57
- warnUnknownProperty(name);
104
+ onBeforeMountComponent: function (debugID, element) {
105
+ handleElement(debugID, element);
58
106
  },
59
- onDeleteValueForProperty: function (node, name) {
60
- warnUnknownProperty(name);
107
+ onBeforeUpdateComponent: function (debugID, element) {
108
+ handleElement(debugID, element);
61
109
  }
62
110
  };
63
111