react 15.1.0 → 15.2.0-rc.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 (109) hide show
  1. package/dist/react-with-addons.js +2034 -1313
  2. package/dist/react-with-addons.min.js +7 -6
  3. package/dist/react.js +1832 -1244
  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 +6 -4
  10. package/lib/DOMPropertyOperations.js +17 -3
  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/LinkedValueUtils.js +5 -3
  18. package/lib/NativeMethodsMixin.js +6 -4
  19. package/lib/PooledClass.js +3 -1
  20. package/lib/React.js +1 -1
  21. package/lib/ReactCSSTransitionGroupChild.js +15 -8
  22. package/lib/ReactChildReconciler.js +15 -6
  23. package/lib/ReactClass.js +14 -13
  24. package/lib/ReactComponent.js +3 -6
  25. package/lib/ReactComponentEnvironment.js +3 -1
  26. package/lib/ReactComponentTreeDevtool.js +94 -16
  27. package/lib/ReactComponentTreeTestUtils.js +87 -0
  28. package/lib/ReactCompositeComponent.js +66 -106
  29. package/lib/ReactDOM.js +2 -2
  30. package/lib/ReactDOMButton.js +2 -2
  31. package/lib/ReactDOMComponent.js +130 -76
  32. package/lib/ReactDOMComponentTree.js +23 -21
  33. package/lib/ReactDOMDebugTool.js +7 -1
  34. package/lib/ReactDOMEmptyComponent.js +9 -9
  35. package/lib/ReactDOMFactories.js +1 -1
  36. package/lib/ReactDOMInput.js +52 -16
  37. package/lib/ReactDOMOption.js +40 -26
  38. package/lib/ReactDOMSelect.js +3 -3
  39. package/lib/ReactDOMTextComponent.js +21 -20
  40. package/lib/ReactDOMTextarea.js +59 -32
  41. package/lib/ReactDOMTreeTraversal.js +18 -16
  42. package/lib/ReactDOMUnknownPropertyDevtool.js +41 -15
  43. package/lib/ReactDebugTool.js +88 -27
  44. package/lib/ReactDefaultInjection.js +2 -2
  45. package/lib/ReactElement.js +64 -25
  46. package/lib/ReactElementValidator.js +26 -81
  47. package/lib/ReactEventListener.js +2 -2
  48. package/lib/ReactFragment.js +3 -1
  49. package/lib/{ReactNativeComponent.js → ReactHostComponent.js} +10 -29
  50. package/lib/{ReactNativeOperationHistoryDevtool.js → ReactHostOperationHistoryDevtool.js} +5 -5
  51. package/lib/ReactInjection.js +2 -2
  52. package/lib/ReactInstanceHandles.js +8 -6
  53. package/lib/ReactMount.js +24 -16
  54. package/lib/ReactMultiChild.js +31 -9
  55. package/lib/ReactNativeAttributePayload.js +5 -2
  56. package/lib/ReactNativeBaseComponent.js +7 -7
  57. package/lib/ReactNativeBridgeEventPlugin.js +1 -1
  58. package/lib/ReactNativeComponentTree.js +8 -6
  59. package/lib/ReactNativeDOMIDOperations.js +1 -2
  60. package/lib/ReactNativeDefaultInjection.js +9 -7
  61. package/lib/ReactNativeGlobalResponderHandler.js +1 -1
  62. package/lib/ReactNativeMount.js +1 -1
  63. package/lib/ReactNativeTagHandles.js +3 -1
  64. package/lib/ReactNativeTextComponent.js +10 -9
  65. package/lib/ReactNativeTreeTraversal.js +11 -11
  66. package/lib/ReactNodeTypes.js +5 -3
  67. package/lib/ReactNoop.js +76 -0
  68. package/lib/ReactOwner.js +4 -2
  69. package/lib/ReactPerf.js +83 -7
  70. package/lib/ReactPropTypes.js +23 -0
  71. package/lib/ReactReconcileTransaction.js +1 -1
  72. package/lib/ReactReconciler.js +12 -7
  73. package/lib/ReactServerRendering.js +4 -2
  74. package/lib/ReactSimpleEmptyComponent.js +4 -4
  75. package/lib/ReactTestMount.js +126 -0
  76. package/lib/ReactTestReconcileTransaction.js +100 -0
  77. package/lib/ReactTestRenderer.js +133 -0
  78. package/lib/ReactTestUtils.js +17 -10
  79. package/lib/ReactTransitionChildMapping.js +7 -1
  80. package/lib/ReactTransitionGroup.js +40 -6
  81. package/lib/ReactUpdateQueue.js +9 -1
  82. package/lib/ReactUpdates.js +9 -8
  83. package/lib/ReactVersion.js +1 -1
  84. package/lib/ResponderEventPlugin.js +8 -6
  85. package/lib/ResponderTouchHistoryStore.js +6 -4
  86. package/lib/SimpleEventPlugin.js +3 -1
  87. package/lib/SyntheticEvent.js +2 -3
  88. package/lib/SyntheticUIEvent.js +1 -1
  89. package/lib/Transaction.js +4 -2
  90. package/lib/accumulate.js +3 -1
  91. package/lib/accumulateInto.js +3 -1
  92. package/lib/checkReactTypeSpec.js +71 -0
  93. package/lib/createReactNativeComponentClass.js +2 -2
  94. package/lib/dangerousStyleValue.js +3 -1
  95. package/lib/escapeTextContentForBrowser.js +96 -12
  96. package/lib/findDOMNode.js +6 -4
  97. package/lib/findNodeHandle.js +5 -3
  98. package/lib/flattenChildren.js +13 -4
  99. package/lib/{getNativeComponentFromComposite.js → getHostComponentFromComposite.js} +4 -4
  100. package/lib/instantiateReactComponent.js +13 -12
  101. package/lib/onlyChild.js +3 -1
  102. package/lib/reactComponentExpect.js +3 -3
  103. package/lib/reactProdInvariant.js +38 -0
  104. package/lib/setInnerHTML.js +17 -1
  105. package/lib/setTextContent.js +8 -0
  106. package/lib/traverseAllChildren.js +3 -1
  107. package/lib/update.js +12 -11
  108. package/package.json +2 -2
  109. package/lib/MetaMatchers.js +0 -118
@@ -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,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 DOMChildrenOperations = require('./DOMChildrenOperations');
17
18
  var DOMLazyTree = require('./DOMLazyTree');
@@ -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,15 +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') {
67
68
  ReactInstrumentation.debugTool.onSetText(this._debugID, this._stringText);
68
69
 
69
70
  var parentInfo;
70
- if (nativeParent != null) {
71
- parentInfo = nativeParent._ancestorInfo;
72
- } else if (nativeContainerInfo != null) {
73
- parentInfo = nativeContainerInfo._ancestorInfo;
71
+ if (hostParent != null) {
72
+ parentInfo = hostParent._ancestorInfo;
73
+ } else if (hostContainerInfo != null) {
74
+ parentInfo = hostContainerInfo._ancestorInfo;
74
75
  }
75
76
  if (parentInfo) {
76
77
  // parentInfo should always be present except for the top-level
@@ -79,13 +80,13 @@ _assign(ReactDOMTextComponent.prototype, {
79
80
  }
80
81
  }
81
82
 
82
- var domID = nativeContainerInfo._idCounter++;
83
+ var domID = hostContainerInfo._idCounter++;
83
84
  var openingValue = ' react-text: ' + domID + ' ';
84
85
  var closingValue = ' /react-text ';
85
86
  this._domID = domID;
86
- this._nativeParent = nativeParent;
87
+ this._hostParent = hostParent;
87
88
  if (transaction.useCreateElement) {
88
- var ownerDocument = nativeContainerInfo._ownerDocument;
89
+ var ownerDocument = hostContainerInfo._ownerDocument;
89
90
  var openingComment = ownerDocument.createComment(openingValue);
90
91
  var closingComment = ownerDocument.createComment(closingValue);
91
92
  var lazyTree = DOMLazyTree(ownerDocument.createDocumentFragment());
@@ -127,7 +128,7 @@ _assign(ReactDOMTextComponent.prototype, {
127
128
  // and/or updateComponent to do the actual update for consistency with
128
129
  // other component types?
129
130
  this._stringText = nextStringText;
130
- var commentNodes = this.getNativeNode();
131
+ var commentNodes = this.getHostNode();
131
132
  DOMChildrenOperations.replaceDelimitedText(commentNodes[0], commentNodes[1], nextStringText);
132
133
 
133
134
  if (process.env.NODE_ENV !== 'production') {
@@ -137,16 +138,16 @@ _assign(ReactDOMTextComponent.prototype, {
137
138
  }
138
139
  },
139
140
 
140
- getNativeNode: function () {
141
- var nativeNode = this._commentNodes;
142
- if (nativeNode) {
143
- return nativeNode;
141
+ getHostNode: function () {
142
+ var hostNode = this._commentNodes;
143
+ if (hostNode) {
144
+ return hostNode;
144
145
  }
145
146
  if (!this._closingComment) {
146
147
  var openingComment = ReactDOMComponentTree.getNodeFromInstance(this);
147
148
  var node = openingComment.nextSibling;
148
149
  while (true) {
149
- !(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;
150
151
  if (node.nodeType === 8 && node.nodeValue === ' /react-text ') {
151
152
  this._closingComment = node;
152
153
  break;
@@ -154,9 +155,9 @@ _assign(ReactDOMTextComponent.prototype, {
154
155
  node = node.nextSibling;
155
156
  }
156
157
  }
157
- nativeNode = [this._nativeNode, this._closingComment];
158
- this._commentNodes = nativeNode;
159
- return nativeNode;
158
+ hostNode = [this._hostNode, this._closingComment];
159
+ this._commentNodes = hostNode;
160
+ return hostNode;
160
161
  },
161
162
 
162
163
  unmountComponent: function () {
@@ -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,68 @@ 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
+ defaultValue: true,
28
+ valueLink: true,
29
+ defaultChecked: true,
30
+ checkedLink: true,
31
+ innerHTML: true,
32
+ suppressContentEditableWarning: true,
33
+ onFocusIn: true,
34
+ onFocusOut: true
25
35
  };
26
36
  var warnedProperties = {};
27
37
 
28
- var warnUnknownProperty = function (name) {
38
+ var warnUnknownProperty = function (tagName, name, debugID) {
29
39
  if (DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name)) {
30
40
  return;
31
41
  }
32
42
  if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) {
33
43
  return;
34
44
  }
35
-
45
+ if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) {
46
+ return;
47
+ }
36
48
  warnedProperties[name] = true;
37
49
  var lowerCasedName = name.toLowerCase();
38
50
 
39
51
  // data-* attributes should be lowercase; suggest the lowercase version
40
52
  var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null;
41
53
 
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
54
  var registrationName = EventPluginRegistry.possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null;
47
55
 
48
- process.env.NODE_ENV !== 'production' ? warning(registrationName == null, 'Unknown event handler property %s. Did you mean `%s`?', name, registrationName) : void 0;
56
+ if (standardName != null) {
57
+ process.env.NODE_ENV !== 'production' ? warning(standardName == null, 'Unknown DOM property %s. Did you mean %s?%s', name, standardName, ReactComponentTreeDevtool.getStackAddendumByID(debugID)) : void 0;
58
+ } else if (registrationName != null) {
59
+ 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;
60
+ } else {
61
+ // We were unable to guess which prop the user intended.
62
+ // It is likely that the user was just blindly spreading/forwarding props
63
+ // Components should be careful to only render valid props/attributes.
64
+ 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', name, tagName, ReactComponentTreeDevtool.getStackAddendumByID(debugID)) : void 0;
65
+ }
49
66
  };
50
67
  }
51
68
 
69
+ function handleElement(debugID, element) {
70
+ if (element == null || typeof element.type !== 'string') {
71
+ return;
72
+ }
73
+ if (element.type.indexOf('-') >= 0 || element.props.is) {
74
+ return;
75
+ }
76
+ for (var key in element.props) {
77
+ warnUnknownProperty(element.type, key, debugID);
78
+ }
79
+ }
80
+
52
81
  var ReactDOMUnknownPropertyDevtool = {
53
- onCreateMarkupForProperty: function (name, value) {
54
- warnUnknownProperty(name);
55
- },
56
- onSetValueForProperty: function (node, name, value) {
57
- warnUnknownProperty(name);
82
+ onBeforeMountComponent: function (debugID, element) {
83
+ handleElement(debugID, element);
58
84
  },
59
- onDeleteValueForProperty: function (node, name) {
60
- warnUnknownProperty(name);
85
+ onBeforeUpdateComponent: function (debugID, element) {
86
+ handleElement(debugID, element);
61
87
  }
62
88
  };
63
89