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,11 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- var ReactDOMDebugTool = require('./ReactDOMDebugTool');
14
+ var debugTool = null;
15
15
 
16
- module.exports = { debugTool: ReactDOMDebugTool };
16
+ if (process.env.NODE_ENV !== 'production') {
17
+ var ReactDOMDebugTool = require('./ReactDOMDebugTool');
18
+ debugTool = ReactDOMDebugTool;
19
+ }
20
+
21
+ module.exports = { debugTool: debugTool };
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Copyright 2013-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 ReactDOMNullInputValuePropDevtool
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var ReactComponentTreeDevtool = require('./ReactComponentTreeDevtool');
15
+
16
+ var warning = require('fbjs/lib/warning');
17
+
18
+ var didWarnValueNull = false;
19
+
20
+ function handleElement(debugID, element) {
21
+ if (element == null) {
22
+ return;
23
+ }
24
+ if (element.type !== 'input' && element.type !== 'textarea' && element.type !== 'select') {
25
+ return;
26
+ }
27
+ if (element.props != null && element.props.value === null && !didWarnValueNull) {
28
+ process.env.NODE_ENV !== 'production' ? warning(false, '`value` prop on `%s` should not be null. ' + 'Consider using the empty string to clear the component or `undefined` ' + 'for uncontrolled components.%s', element.type, ReactComponentTreeDevtool.getStackAddendumByID(debugID)) : void 0;
29
+
30
+ didWarnValueNull = true;
31
+ }
32
+ }
33
+
34
+ var ReactDOMUnknownPropertyDevtool = {
35
+ onBeforeMountComponent: function (debugID, element) {
36
+ handleElement(debugID, element);
37
+ },
38
+ onBeforeUpdateComponent: function (debugID, element) {
39
+ handleElement(debugID, element);
40
+ }
41
+ };
42
+
43
+ module.exports = ReactDOMUnknownPropertyDevtool;
@@ -18,12 +18,33 @@ var ReactDOMComponentTree = require('./ReactDOMComponentTree');
18
18
  var ReactDOMSelect = require('./ReactDOMSelect');
19
19
 
20
20
  var warning = require('fbjs/lib/warning');
21
+ var didWarnInvalidOptionChildren = false;
22
+
23
+ function flattenChildren(children) {
24
+ var content = '';
25
+
26
+ // Flatten children and warn if they aren't strings or numbers;
27
+ // invalid types are ignored.
28
+ ReactChildren.forEach(children, function (child) {
29
+ if (child == null) {
30
+ return;
31
+ }
32
+ if (typeof child === 'string' || typeof child === 'number') {
33
+ content += child;
34
+ } else if (!didWarnInvalidOptionChildren) {
35
+ didWarnInvalidOptionChildren = true;
36
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Only strings and numbers are supported as <option> children.') : void 0;
37
+ }
38
+ });
39
+
40
+ return content;
41
+ }
21
42
 
22
43
  /**
23
- * Implements an <option> native component that warns when `selected` is set.
44
+ * Implements an <option> host component that warns when `selected` is set.
24
45
  */
25
46
  var ReactDOMOption = {
26
- mountWrapper: function (inst, props, nativeParent) {
47
+ mountWrapper: function (inst, props, hostParent) {
27
48
  // TODO (yungsters): Remove support for `selected` in <option>.
28
49
  if (process.env.NODE_ENV !== 'production') {
29
50
  process.env.NODE_ENV !== 'production' ? warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : void 0;
@@ -31,11 +52,11 @@ var ReactDOMOption = {
31
52
 
32
53
  // Look up whether this option is 'selected'
33
54
  var selectValue = null;
34
- if (nativeParent != null) {
35
- var selectParent = nativeParent;
55
+ if (hostParent != null) {
56
+ var selectParent = hostParent;
36
57
 
37
58
  if (selectParent._tag === 'optgroup') {
38
- selectParent = selectParent._nativeParent;
59
+ selectParent = selectParent._hostParent;
39
60
  }
40
61
 
41
62
  if (selectParent != null && selectParent._tag === 'select') {
@@ -47,17 +68,23 @@ var ReactDOMOption = {
47
68
  // or missing (e.g., for <datalist>), we don't change props.selected
48
69
  var selected = null;
49
70
  if (selectValue != null) {
71
+ var value;
72
+ if (props.value != null) {
73
+ value = props.value + '';
74
+ } else {
75
+ value = flattenChildren(props.children);
76
+ }
50
77
  selected = false;
51
78
  if (Array.isArray(selectValue)) {
52
79
  // multiple
53
80
  for (var i = 0; i < selectValue.length; i++) {
54
- if ('' + selectValue[i] === '' + props.value) {
81
+ if ('' + selectValue[i] === value) {
55
82
  selected = true;
56
83
  break;
57
84
  }
58
85
  }
59
86
  } else {
60
- selected = '' + selectValue === '' + props.value;
87
+ selected = '' + selectValue === value;
61
88
  }
62
89
  }
63
90
 
@@ -73,35 +100,22 @@ var ReactDOMOption = {
73
100
  }
74
101
  },
75
102
 
76
- getNativeProps: function (inst, props) {
77
- var nativeProps = _assign({ selected: undefined, children: undefined }, props);
103
+ getHostProps: function (inst, props) {
104
+ var hostProps = _assign({ selected: undefined, children: undefined }, props);
78
105
 
79
106
  // Read state only from initial mount because <select> updates value
80
107
  // manually; we need the initial state only for server rendering
81
108
  if (inst._wrapperState.selected != null) {
82
- nativeProps.selected = inst._wrapperState.selected;
109
+ hostProps.selected = inst._wrapperState.selected;
83
110
  }
84
111
 
85
- var content = '';
86
-
87
- // Flatten children and warn if they aren't strings or numbers;
88
- // invalid types are ignored.
89
- ReactChildren.forEach(props.children, function (child) {
90
- if (child == null) {
91
- return;
92
- }
93
- if (typeof child === 'string' || typeof child === 'number') {
94
- content += child;
95
- } else {
96
- process.env.NODE_ENV !== 'production' ? warning(false, 'Only strings and numbers are supported as <option> children.') : void 0;
97
- }
98
- });
112
+ var content = flattenChildren(props.children);
99
113
 
100
114
  if (content) {
101
- nativeProps.children = content;
115
+ hostProps.children = content;
102
116
  }
103
117
 
104
- return nativeProps;
118
+ return hostProps;
105
119
  }
106
120
 
107
121
  };
@@ -21,7 +21,6 @@ var ReactUpdates = require('./ReactUpdates');
21
21
  var warning = require('fbjs/lib/warning');
22
22
 
23
23
  var didWarnValueLink = false;
24
- var didWarnValueNull = false;
25
24
  var didWarnValueDefaultValue = false;
26
25
 
27
26
  function updateOptionsIfPendingUpdateAndMounted() {
@@ -47,14 +46,6 @@ function getDeclarationErrorAddendum(owner) {
47
46
  return '';
48
47
  }
49
48
 
50
- function warnIfValueIsNull(props) {
51
- if (props != null && props.value === null && !didWarnValueNull) {
52
- process.env.NODE_ENV !== 'production' ? warning(false, '`value` prop on `select` should not be null. ' + 'Consider using the empty string to clear the component or `undefined` ' + 'for uncontrolled components.') : void 0;
53
-
54
- didWarnValueNull = true;
55
- }
56
- }
57
-
58
49
  var valuePropNames = ['value', 'defaultValue'];
59
50
 
60
51
  /**
@@ -121,7 +112,7 @@ function updateOptions(inst, multiple, propValue) {
121
112
  }
122
113
 
123
114
  /**
124
- * Implements a <select> native component that allows optionally setting the
115
+ * Implements a <select> host component that allows optionally setting the
125
116
  * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
126
117
  * stringable. If `multiple` is true, the prop must be an array of stringables.
127
118
  *
@@ -136,8 +127,8 @@ function updateOptions(inst, multiple, propValue) {
136
127
  * selected.
137
128
  */
138
129
  var ReactDOMSelect = {
139
- getNativeProps: function (inst, props) {
140
- return _assign({}, DisabledInputUtils.getNativeProps(inst, props), {
130
+ getHostProps: function (inst, props) {
131
+ return _assign({}, DisabledInputUtils.getHostProps(inst, props), {
141
132
  onChange: inst._wrapperState.onChange,
142
133
  value: undefined
143
134
  });
@@ -146,7 +137,6 @@ var ReactDOMSelect = {
146
137
  mountWrapper: function (inst, props) {
147
138
  if (process.env.NODE_ENV !== 'production') {
148
139
  checkSelectPropTypes(inst, props);
149
- warnIfValueIsNull(props);
150
140
  }
151
141
 
152
142
  var value = LinkedValueUtils.getValue(props);
@@ -172,9 +162,6 @@ var ReactDOMSelect = {
172
162
 
173
163
  postUpdateWrapper: function (inst) {
174
164
  var props = inst._currentElement.props;
175
- if (process.env.NODE_ENV !== 'production') {
176
- warnIfValueIsNull(props);
177
- }
178
165
 
179
166
  // After the initial mount, we control selected-ness manually so don't pass
180
167
  // this value down
@@ -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');
@@ -23,7 +23,6 @@ var invariant = require('fbjs/lib/invariant');
23
23
  var warning = require('fbjs/lib/warning');
24
24
 
25
25
  var didWarnValueLink = false;
26
- var didWarnValueNull = false;
27
26
  var didWarnValDefaultVal = false;
28
27
 
29
28
  function forceUpdateIfMounted() {
@@ -33,16 +32,8 @@ function forceUpdateIfMounted() {
33
32
  }
34
33
  }
35
34
 
36
- function warnIfValueIsNull(props) {
37
- if (props != null && props.value === null && !didWarnValueNull) {
38
- process.env.NODE_ENV !== 'production' ? warning(false, '`value` prop on `textarea` should not be null. ' + 'Consider using the empty string to clear the component or `undefined` ' + 'for uncontrolled components.') : void 0;
39
-
40
- didWarnValueNull = true;
41
- }
42
- }
43
-
44
35
  /**
45
- * Implements a <textarea> native component that allows setting `value`, and
36
+ * Implements a <textarea> host component that allows setting `value`, and
46
37
  * `defaultValue`. This differs from the traditional DOM API because value is
47
38
  * usually set as PCDATA children.
48
39
  *
@@ -57,19 +48,22 @@ function warnIfValueIsNull(props) {
57
48
  * `defaultValue` if specified, or the children content (deprecated).
58
49
  */
59
50
  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;
51
+ getHostProps: function (inst, props) {
52
+ !(props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : _prodInvariant('91') : void 0;
62
53
 
63
54
  // 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,
55
+ // get reset if `textContent` is mutated. We could add a check in setTextContent
56
+ // to only set the value if/when the value differs from the node value (which would
57
+ // completely solve this IE9 bug), but Sebastian+Ben seemed to like this solution.
58
+ // The value can be a boolean or object so that's why it's forced to be a string.
59
+ var hostProps = _assign({}, DisabledInputUtils.getHostProps(inst, props), {
67
60
  value: undefined,
68
- children: inst._wrapperState.initialValue,
61
+ defaultValue: undefined,
62
+ children: '' + inst._wrapperState.initialValue,
69
63
  onChange: inst._wrapperState.onChange
70
64
  });
71
65
 
72
- return nativeProps;
66
+ return hostProps;
73
67
  },
74
68
 
75
69
  mountWrapper: function (inst, props) {
@@ -83,34 +77,36 @@ var ReactDOMTextarea = {
83
77
  process.env.NODE_ENV !== 'production' ? warning(false, 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0;
84
78
  didWarnValDefaultVal = true;
85
79
  }
86
- warnIfValueIsNull(props);
87
80
  }
88
81
 
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;
82
+ var value = LinkedValueUtils.getValue(props);
83
+ var initialValue = value;
84
+
85
+ // Only bother fetching default value if we're going to use it
86
+ if (value == null) {
87
+ var defaultValue = props.defaultValue;
88
+ // TODO (yungsters): Remove support for children content in <textarea>.
89
+ var children = props.children;
90
+ if (children != null) {
91
+ if (process.env.NODE_ENV !== 'production') {
92
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : void 0;
93
+ }
94
+ !(defaultValue == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : _prodInvariant('92') : void 0;
95
+ if (Array.isArray(children)) {
96
+ !(children.length <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, '<textarea> can only have at most one child.') : _prodInvariant('93') : void 0;
97
+ children = children[0];
98
+ }
99
+
100
+ defaultValue = '' + children;
95
101
  }
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];
102
+ if (defaultValue == null) {
103
+ defaultValue = '';
100
104
  }
101
-
102
- defaultValue = '' + children;
103
- }
104
- if (defaultValue == null) {
105
- defaultValue = '';
105
+ initialValue = defaultValue;
106
106
  }
107
- var value = LinkedValueUtils.getValue(props);
107
+
108
108
  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),
109
+ initialValue: '' + initialValue,
114
110
  listeners: null,
115
111
  onChange: _handleChange.bind(inst)
116
112
  };
@@ -119,16 +115,33 @@ var ReactDOMTextarea = {
119
115
  updateWrapper: function (inst) {
120
116
  var props = inst._currentElement.props;
121
117
 
122
- if (process.env.NODE_ENV !== 'production') {
123
- warnIfValueIsNull(props);
124
- }
125
-
118
+ var node = ReactDOMComponentTree.getNodeFromInstance(inst);
126
119
  var value = LinkedValueUtils.getValue(props);
127
120
  if (value != null) {
128
121
  // Cast `value` to a string to ensure the value is set correctly. While
129
122
  // browsers typically do this as necessary, jsdom doesn't.
130
- DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'value', '' + value);
123
+ var newValue = '' + value;
124
+
125
+ // To avoid side effects (such as losing text selection), only set value if changed
126
+ if (newValue !== node.value) {
127
+ node.value = newValue;
128
+ }
129
+ if (props.defaultValue == null) {
130
+ node.defaultValue = newValue;
131
+ }
132
+ }
133
+ if (props.defaultValue != null) {
134
+ node.defaultValue = props.defaultValue;
131
135
  }
136
+ },
137
+
138
+ postMountWrapper: function (inst) {
139
+ // This is in postMount because we need access to the DOM node, which is not
140
+ // available until after the component has mounted.
141
+ var node = ReactDOMComponentTree.getNodeFromInstance(inst);
142
+
143
+ // Warning: node.value may be the empty string at this point (IE11) if placeholder is set.
144
+ node.value = node.textContent; // Detach value from defaultValue
132
145
  }
133
146
  };
134
147