react 0.14.10 → 15.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/LICENSE +1 -1
  2. package/dist/react-with-addons.js +4900 -4627
  3. package/dist/react-with-addons.min.js +7 -7
  4. package/dist/react.js +4556 -4059
  5. package/dist/react.min.js +7 -7
  6. package/lib/AutoFocusUtils.js +3 -15
  7. package/lib/BeforeInputEventPlugin.js +8 -25
  8. package/lib/CSSProperty.js +10 -1
  9. package/lib/CSSPropertyOperations.js +49 -19
  10. package/lib/CallbackQueue.js +16 -4
  11. package/lib/ChangeEventPlugin.js +58 -54
  12. package/lib/DOMChildrenOperations.js +91 -61
  13. package/lib/DOMLazyTree.js +105 -0
  14. package/lib/{ClientReactRootIndex.js → DOMNamespaces.js} +7 -10
  15. package/lib/DOMProperty.js +18 -39
  16. package/lib/DOMPropertyOperations.js +42 -53
  17. package/lib/Danger.js +13 -14
  18. package/lib/DefaultEventPluginOrder.js +1 -1
  19. package/lib/EnterLeaveEventPlugin.js +24 -43
  20. package/lib/EventConstants.js +6 -1
  21. package/lib/EventPluginHub.js +22 -66
  22. package/lib/EventPluginRegistry.js +30 -9
  23. package/lib/EventPluginUtils.js +61 -36
  24. package/lib/EventPropagators.js +19 -17
  25. package/lib/FallbackCompositionState.js +4 -4
  26. package/lib/HTMLDOMPropertyConfig.js +131 -152
  27. package/lib/LinkedStateMixin.js +1 -2
  28. package/lib/LinkedValueUtils.js +6 -7
  29. package/lib/MetaMatchers.js +2 -2
  30. package/lib/OrderedMap.js +17 -16
  31. package/lib/PooledClass.js +2 -2
  32. package/lib/React.js +50 -20
  33. package/lib/ReactBrowserEventEmitter.js +19 -26
  34. package/lib/ReactCSSTransitionGroup.js +4 -5
  35. package/lib/ReactCSSTransitionGroupChild.js +1 -6
  36. package/lib/ReactChildReconciler.js +15 -13
  37. package/lib/ReactChildren.js +5 -4
  38. package/lib/ReactClass.js +44 -92
  39. package/lib/ReactComponent.js +9 -10
  40. package/lib/ReactComponentBrowserEnvironment.js +9 -6
  41. package/lib/ReactComponentEnvironment.js +4 -4
  42. package/lib/ReactComponentWithPureRenderMixin.js +2 -2
  43. package/lib/ReactCompositeComponent.js +166 -74
  44. package/lib/ReactCurrentOwner.js +2 -1
  45. package/lib/ReactDOM.js +27 -15
  46. package/lib/ReactDOMButton.js +2 -2
  47. package/lib/ReactDOMComponent.js +186 -250
  48. package/lib/ReactDOMComponentFlags.js +18 -0
  49. package/lib/ReactDOMComponentTree.js +186 -0
  50. package/lib/ReactDOMContainerInfo.js +32 -0
  51. package/lib/ReactDOMDebugTool.js +61 -0
  52. package/lib/ReactDOMEmptyComponent.js +60 -0
  53. package/lib/ReactDOMFactories.js +1 -2
  54. package/lib/ReactDOMFeatureFlags.js +2 -2
  55. package/lib/ReactDOMIDOperations.js +5 -60
  56. package/lib/ReactDOMInput.js +73 -23
  57. package/lib/ReactDOMInstrumentation.js +16 -0
  58. package/lib/ReactDOMOption.js +14 -12
  59. package/lib/ReactDOMSelect.js +43 -19
  60. package/lib/ReactDOMSelection.js +4 -4
  61. package/lib/ReactDOMServer.js +1 -1
  62. package/lib/ReactDOMTextComponent.js +87 -45
  63. package/lib/ReactDOMTextarea.js +39 -11
  64. package/lib/ReactDOMTreeTraversal.js +134 -0
  65. package/lib/ReactDOMUnknownPropertyDevtool.js +64 -0
  66. package/lib/ReactDebugInstanceMap.js +102 -0
  67. package/lib/ReactDebugTool.js +72 -0
  68. package/lib/ReactDefaultBatchingStrategy.js +4 -3
  69. package/lib/ReactDefaultInjection.js +11 -15
  70. package/lib/ReactDefaultPerf.js +105 -26
  71. package/lib/ReactDefaultPerfAnalysis.js +23 -15
  72. package/lib/ReactElement.js +63 -23
  73. package/lib/ReactElementValidator.js +9 -9
  74. package/lib/ReactEmptyComponent.js +8 -33
  75. package/lib/ReactErrorUtils.js +1 -2
  76. package/lib/ReactEventEmitterMixin.js +3 -8
  77. package/lib/ReactEventListener.js +23 -77
  78. package/lib/ReactFeatureFlags.js +21 -0
  79. package/lib/ReactFragment.js +6 -6
  80. package/lib/ReactInjection.js +3 -3
  81. package/lib/ReactInputSelection.js +4 -4
  82. package/lib/ReactInstanceHandles.js +10 -12
  83. package/lib/ReactInstanceMap.js +2 -1
  84. package/lib/ReactInstrumentation.js +16 -0
  85. package/lib/ReactInvalidSetStateWarningDevTool.js +36 -0
  86. package/lib/ReactLink.js +2 -3
  87. package/lib/ReactMarkupChecksum.js +8 -3
  88. package/lib/ReactMount.js +88 -460
  89. package/lib/ReactMultiChild.js +106 -200
  90. package/lib/ReactMultiChildUpdateTypes.js +1 -1
  91. package/lib/ReactNativeComponent.js +6 -5
  92. package/lib/ReactNodeTypes.js +37 -0
  93. package/lib/ReactNoopUpdateQueue.js +2 -25
  94. package/lib/ReactOwner.js +7 -6
  95. package/lib/ReactPerf.js +2 -2
  96. package/lib/ReactPropTransferer.js +5 -4
  97. package/lib/ReactPropTypeLocationNames.js +1 -1
  98. package/lib/ReactPropTypeLocations.js +1 -1
  99. package/lib/ReactPropTypes.js +31 -7
  100. package/lib/ReactReconcileTransaction.js +20 -9
  101. package/lib/ReactReconciler.js +29 -6
  102. package/lib/ReactRef.js +1 -1
  103. package/lib/ReactServerBatchingStrategy.js +1 -2
  104. package/lib/ReactServerRendering.js +17 -35
  105. package/lib/ReactServerRenderingTransaction.js +11 -29
  106. package/lib/ReactSimpleEmptyComponent.js +36 -0
  107. package/lib/ReactStateSetters.js +1 -1
  108. package/lib/ReactTestUtils.js +47 -28
  109. package/lib/ReactTransitionChildMapping.js +1 -2
  110. package/lib/ReactTransitionEvents.js +8 -44
  111. package/lib/ReactTransitionGroup.js +4 -3
  112. package/lib/ReactUMDEntry.js +26 -0
  113. package/lib/ReactUpdateQueue.js +24 -66
  114. package/lib/ReactUpdates.js +29 -11
  115. package/lib/ReactVersion.js +2 -2
  116. package/lib/ReactWithAddons.js +1 -21
  117. package/lib/ReactWithAddonsUMDEntry.js +26 -0
  118. package/lib/ResponderEventPlugin.js +54 -66
  119. package/lib/ResponderSyntheticEvent.js +2 -3
  120. package/lib/ResponderTouchHistoryStore.js +5 -5
  121. package/lib/SVGDOMPropertyConfig.js +267 -94
  122. package/lib/SelectEventPlugin.js +13 -18
  123. package/lib/SimpleEventPlugin.js +57 -17
  124. package/lib/SyntheticAnimationEvent.js +39 -0
  125. package/lib/SyntheticClipboardEvent.js +2 -3
  126. package/lib/SyntheticCompositionEvent.js +2 -3
  127. package/lib/SyntheticDragEvent.js +2 -3
  128. package/lib/SyntheticEvent.js +102 -21
  129. package/lib/SyntheticFocusEvent.js +2 -3
  130. package/lib/SyntheticInputEvent.js +2 -3
  131. package/lib/SyntheticKeyboardEvent.js +2 -3
  132. package/lib/SyntheticMouseEvent.js +2 -3
  133. package/lib/SyntheticTouchEvent.js +2 -3
  134. package/lib/SyntheticTransitionEvent.js +39 -0
  135. package/lib/SyntheticUIEvent.js +2 -3
  136. package/lib/SyntheticWheelEvent.js +2 -3
  137. package/lib/TapEventPlugin.js +3 -12
  138. package/lib/Transaction.js +3 -3
  139. package/lib/ViewportMetrics.js +1 -1
  140. package/lib/accumulate.js +2 -2
  141. package/lib/accumulateInto.js +2 -2
  142. package/lib/adler32.js +3 -2
  143. package/lib/canDefineProperty.js +1 -1
  144. package/lib/createHierarchyRenderer.js +1 -1
  145. package/lib/createMicrosoftUnsafeLocalFunction.js +32 -0
  146. package/lib/dangerousStyleValue.js +25 -3
  147. package/lib/deprecated.js +7 -4
  148. package/lib/escapeTextContentForBrowser.js +1 -1
  149. package/lib/findDOMNode.js +15 -8
  150. package/lib/flattenChildren.js +2 -2
  151. package/lib/forEachAccumulated.js +2 -1
  152. package/lib/getEventCharCode.js +2 -2
  153. package/lib/getEventKey.js +1 -2
  154. package/lib/getEventModifierState.js +1 -2
  155. package/lib/getEventTarget.js +8 -2
  156. package/lib/getIteratorFn.js +2 -2
  157. package/lib/getNativeComponentFromComposite.js +30 -0
  158. package/lib/getNodeForCharacterOffset.js +2 -1
  159. package/lib/getTestDocument.js +1 -1
  160. package/lib/getTextContentAccessor.js +1 -1
  161. package/lib/getVendorPrefixedEventName.js +101 -0
  162. package/lib/instantiateReactComponent.js +12 -13
  163. package/lib/isEventSupported.js +2 -2
  164. package/lib/isTextInputElement.js +2 -1
  165. package/lib/onlyChild.js +2 -2
  166. package/lib/quoteAttributeValueForBrowser.js +1 -1
  167. package/lib/reactComponentExpect.js +5 -4
  168. package/lib/renderSubtreeIntoContainer.js +1 -1
  169. package/lib/setInnerHTML.js +6 -14
  170. package/lib/setTextContent.js +1 -1
  171. package/lib/shallowCompare.js +1 -1
  172. package/lib/shouldUpdateReactComponent.js +2 -3
  173. package/lib/sliceChildren.js +1 -1
  174. package/lib/traverseAllChildren.js +8 -8
  175. package/lib/update.js +16 -15
  176. package/lib/validateDOMNesting.js +18 -13
  177. package/package.json +23 -32
  178. package/addons.js +0 -13
  179. package/cjs/react-jsx-dev-runtime.development.js +0 -861
  180. package/cjs/react-jsx-dev-runtime.production.min.js +0 -9
  181. package/cjs/react-jsx-runtime.development.js +0 -883
  182. package/cjs/react-jsx-runtime.production.min.js +0 -10
  183. package/jsx-dev-runtime.js +0 -7
  184. package/jsx-runtime.js +0 -7
  185. package/lib/Object.assign.js +0 -47
  186. package/lib/React.native.js +0 -5
  187. package/lib/ReactBrowserComponentMixin.js +0 -36
  188. package/lib/ReactEmptyComponentRegistry.js +0 -48
  189. package/lib/ReactIsomorphic.js +0 -74
  190. package/lib/ReactRootIndex.js +0 -29
  191. package/lib/ServerReactRootIndex.js +0 -29
  192. package/lib/cloneWithProps.js +0 -54
  193. package/lib/webcomponents.js +0 -6379
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013-2015, Facebook, Inc.
2
+ * Copyright 2013-present, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
@@ -11,15 +11,23 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- var ReactDOMIDOperations = require('./ReactDOMIDOperations');
14
+ var _assign = require('object-assign');
15
+
16
+ var DOMPropertyOperations = require('./DOMPropertyOperations');
15
17
  var LinkedValueUtils = require('./LinkedValueUtils');
16
- var ReactMount = require('./ReactMount');
18
+ var ReactDOMComponentTree = require('./ReactDOMComponentTree');
17
19
  var ReactUpdates = require('./ReactUpdates');
18
20
 
19
- var assign = require('./Object.assign');
20
21
  var invariant = require('fbjs/lib/invariant');
22
+ var warning = require('fbjs/lib/warning');
21
23
 
22
- var instancesByReactID = {};
24
+ var didWarnValueLink = false;
25
+ var didWarnCheckedLink = false;
26
+ var didWarnValueNull = false;
27
+ var didWarnValueDefaultValue = false;
28
+ var didWarnCheckedDefaultChecked = false;
29
+ var didWarnControlledToUncontrolled = false;
30
+ var didWarnUncontrolledToControlled = false;
23
31
 
24
32
  function forceUpdateIfMounted() {
25
33
  if (this._rootNodeID) {
@@ -28,6 +36,14 @@ function forceUpdateIfMounted() {
28
36
  }
29
37
  }
30
38
 
39
+ function warnIfValueIsNull(props) {
40
+ if (props != null && props.value === null && !didWarnValueNull) {
41
+ process.env.NODE_ENV !== 'production' ? warning(false, '`value` prop on `input` should not be null. ' + 'Consider using the empty string to clear the component or `undefined` ' + 'for uncontrolled components.') : void 0;
42
+
43
+ didWarnValueNull = true;
44
+ }
45
+ }
46
+
31
47
  /**
32
48
  * Implements an <input> native component that allows setting these optional
33
49
  * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
@@ -45,11 +61,15 @@ function forceUpdateIfMounted() {
45
61
  * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
46
62
  */
47
63
  var ReactDOMInput = {
48
- getNativeProps: function (inst, props, context) {
64
+ getNativeProps: function (inst, props) {
49
65
  var value = LinkedValueUtils.getValue(props);
50
66
  var checked = LinkedValueUtils.getChecked(props);
51
67
 
52
- var nativeProps = assign({}, props, {
68
+ var nativeProps = _assign({
69
+ // Make sure we set .type before any other properties (setting .value
70
+ // before .type means .value is lost in IE11 and below)
71
+ type: undefined
72
+ }, props, {
53
73
  defaultChecked: undefined,
54
74
  defaultValue: undefined,
55
75
  value: value != null ? value : inst._wrapperState.initialValue,
@@ -63,39 +83,71 @@ var ReactDOMInput = {
63
83
  mountWrapper: function (inst, props) {
64
84
  if (process.env.NODE_ENV !== 'production') {
65
85
  LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner);
86
+
87
+ if (props.valueLink !== undefined && !didWarnValueLink) {
88
+ process.env.NODE_ENV !== 'production' ? warning(false, '`valueLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0;
89
+ didWarnValueLink = true;
90
+ }
91
+ if (props.checkedLink !== undefined && !didWarnCheckedLink) {
92
+ process.env.NODE_ENV !== 'production' ? warning(false, '`checkedLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0;
93
+ didWarnCheckedLink = true;
94
+ }
95
+ if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
96
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0;
97
+ didWarnCheckedDefaultChecked = true;
98
+ }
99
+ if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
100
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Input 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 input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0;
101
+ didWarnValueDefaultValue = true;
102
+ }
103
+ warnIfValueIsNull(props);
66
104
  }
67
105
 
68
106
  var defaultValue = props.defaultValue;
69
107
  inst._wrapperState = {
70
108
  initialChecked: props.defaultChecked || false,
71
109
  initialValue: defaultValue != null ? defaultValue : null,
110
+ listeners: null,
72
111
  onChange: _handleChange.bind(inst)
73
112
  };
74
- },
75
113
 
76
- mountReadyWrapper: function (inst) {
77
- // Can't be in mountWrapper or else server rendering leaks.
78
- instancesByReactID[inst._rootNodeID] = inst;
79
- },
80
-
81
- unmountWrapper: function (inst) {
82
- delete instancesByReactID[inst._rootNodeID];
114
+ if (process.env.NODE_ENV !== 'production') {
115
+ inst._wrapperState.controlled = props.checked !== undefined || props.value !== undefined;
116
+ }
83
117
  },
84
118
 
85
119
  updateWrapper: function (inst) {
86
120
  var props = inst._currentElement.props;
87
121
 
122
+ if (process.env.NODE_ENV !== 'production') {
123
+ warnIfValueIsNull(props);
124
+
125
+ var initialValue = inst._wrapperState.initialChecked || inst._wrapperState.initialValue;
126
+ var defaultValue = props.defaultChecked || props.defaultValue;
127
+ var controlled = props.checked !== undefined || props.value !== undefined;
128
+ var owner = inst._currentElement._owner;
129
+
130
+ if ((initialValue || !inst._wrapperState.controlled) && controlled && !didWarnUncontrolledToControlled) {
131
+ process.env.NODE_ENV !== 'production' ? warning(false, '%s is changing a uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0;
132
+ didWarnUncontrolledToControlled = true;
133
+ }
134
+ if (inst._wrapperState.controlled && (defaultValue || !controlled) && !didWarnControlledToUncontrolled) {
135
+ process.env.NODE_ENV !== 'production' ? warning(false, '%s is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0;
136
+ didWarnControlledToUncontrolled = true;
137
+ }
138
+ }
139
+
88
140
  // TODO: Shouldn't this be getChecked(props)?
89
141
  var checked = props.checked;
90
142
  if (checked != null) {
91
- ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'checked', checked || false);
143
+ DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'checked', checked || false);
92
144
  }
93
145
 
94
146
  var value = LinkedValueUtils.getValue(props);
95
147
  if (value != null) {
96
148
  // Cast `value` to a string to ensure the value is set correctly. While
97
149
  // browsers typically do this as necessary, jsdom doesn't.
98
- ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value);
150
+ DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'value', '' + value);
99
151
  }
100
152
  }
101
153
  };
@@ -112,7 +164,7 @@ function _handleChange(event) {
112
164
 
113
165
  var name = props.name;
114
166
  if (props.type === 'radio' && name != null) {
115
- var rootNode = ReactMount.getNode(this._rootNodeID);
167
+ var rootNode = ReactDOMComponentTree.getNodeFromInstance(this);
116
168
  var queryRoot = rootNode;
117
169
 
118
170
  while (queryRoot.parentNode) {
@@ -135,11 +187,9 @@ function _handleChange(event) {
135
187
  // This will throw if radio buttons rendered by different copies of React
136
188
  // and the same name are rendered into the same form (same as #1939).
137
189
  // That's probably okay; we don't support it just as we don't support
138
- // mixing React with non-React.
139
- var otherID = ReactMount.getID(otherNode);
140
- !otherID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.') : invariant(false) : undefined;
141
- var otherInstance = instancesByReactID[otherID];
142
- !otherInstance ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Unknown radio button ID %s.', otherID) : invariant(false) : undefined;
190
+ // mixing React radio buttons with non-React ones.
191
+ var otherInstance = ReactDOMComponentTree.getInstanceFromNode(otherNode);
192
+ !otherInstance ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.') : invariant(false) : void 0;
143
193
  // If this is a controlled radio button group, forcing the input that
144
194
  // was previously checked to update will cause it to be come re-checked
145
195
  // as appropriate.
@@ -0,0 +1,16 @@
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 ReactDOMInstrumentation
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var ReactDOMDebugTool = require('./ReactDOMDebugTool');
15
+
16
+ module.exports = { debugTool: ReactDOMDebugTool };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013-2015, Facebook, Inc.
2
+ * Copyright 2013-present, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
@@ -11,28 +11,30 @@
11
11
 
12
12
  'use strict';
13
13
 
14
+ var _assign = require('object-assign');
15
+
14
16
  var ReactChildren = require('./ReactChildren');
15
17
  var ReactDOMSelect = require('./ReactDOMSelect');
16
18
 
17
- var assign = require('./Object.assign');
18
19
  var warning = require('fbjs/lib/warning');
19
20
 
20
- var valueContextKey = ReactDOMSelect.valueContextKey;
21
-
22
21
  /**
23
22
  * Implements an <option> native component that warns when `selected` is set.
24
23
  */
25
24
  var ReactDOMOption = {
26
- mountWrapper: function (inst, props, context) {
25
+ mountWrapper: function (inst, props, nativeParent) {
27
26
  // TODO (yungsters): Remove support for `selected` in <option>.
28
27
  if (process.env.NODE_ENV !== 'production') {
29
- process.env.NODE_ENV !== 'production' ? warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : undefined;
28
+ 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;
30
29
  }
31
30
 
32
- // Look up whether this option is 'selected' via context
33
- var selectValue = context[valueContextKey];
31
+ // Look up whether this option is 'selected'
32
+ var selectValue = null;
33
+ if (nativeParent != null && nativeParent._tag === 'select') {
34
+ selectValue = ReactDOMSelect.getSelectValueContext(nativeParent);
35
+ }
34
36
 
35
- // If context key is null (e.g., no specified value or after initial mount)
37
+ // If the value is null (e.g., no specified value or after initial mount)
36
38
  // or missing (e.g., for <datalist>), we don't change props.selected
37
39
  var selected = null;
38
40
  if (selectValue != null) {
@@ -53,8 +55,8 @@ var ReactDOMOption = {
53
55
  inst._wrapperState = { selected: selected };
54
56
  },
55
57
 
56
- getNativeProps: function (inst, props, context) {
57
- var nativeProps = assign({ selected: undefined, children: undefined }, props);
58
+ getNativeProps: function (inst, props) {
59
+ var nativeProps = _assign({ selected: undefined, children: undefined }, props);
58
60
 
59
61
  // Read state only from initial mount because <select> updates value
60
62
  // manually; we need the initial state only for server rendering
@@ -73,7 +75,7 @@ var ReactDOMOption = {
73
75
  if (typeof child === 'string' || typeof child === 'number') {
74
76
  content += child;
75
77
  } else {
76
- process.env.NODE_ENV !== 'production' ? warning(false, 'Only strings and numbers are supported as <option> children.') : undefined;
78
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Only strings and numbers are supported as <option> children.') : void 0;
77
79
  }
78
80
  });
79
81
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013-2015, Facebook, Inc.
2
+ * Copyright 2013-present, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
@@ -11,14 +11,17 @@
11
11
 
12
12
  'use strict';
13
13
 
14
+ var _assign = require('object-assign');
15
+
14
16
  var LinkedValueUtils = require('./LinkedValueUtils');
15
- var ReactMount = require('./ReactMount');
17
+ var ReactDOMComponentTree = require('./ReactDOMComponentTree');
16
18
  var ReactUpdates = require('./ReactUpdates');
17
19
 
18
- var assign = require('./Object.assign');
19
20
  var warning = require('fbjs/lib/warning');
20
21
 
21
- var valueContextKey = '__ReactDOMSelect_value$' + Math.random().toString(36).slice(2);
22
+ var didWarnValueLink = false;
23
+ var didWarnValueNull = false;
24
+ var didWarnValueDefaultValue = false;
22
25
 
23
26
  function updateOptionsIfPendingUpdateAndMounted() {
24
27
  if (this._rootNodeID && this._wrapperState.pendingUpdate) {
@@ -43,6 +46,14 @@ function getDeclarationErrorAddendum(owner) {
43
46
  return '';
44
47
  }
45
48
 
49
+ function warnIfValueIsNull(props) {
50
+ if (props != null && props.value === null && !didWarnValueNull) {
51
+ 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;
52
+
53
+ didWarnValueNull = true;
54
+ }
55
+ }
56
+
46
57
  var valuePropNames = ['value', 'defaultValue'];
47
58
 
48
59
  /**
@@ -53,15 +64,20 @@ function checkSelectPropTypes(inst, props) {
53
64
  var owner = inst._currentElement._owner;
54
65
  LinkedValueUtils.checkPropTypes('select', props, owner);
55
66
 
67
+ if (props.valueLink !== undefined && !didWarnValueLink) {
68
+ process.env.NODE_ENV !== 'production' ? warning(false, '`valueLink` prop on `select` is deprecated; set `value` and `onChange` instead.') : void 0;
69
+ didWarnValueLink = true;
70
+ }
71
+
56
72
  for (var i = 0; i < valuePropNames.length; i++) {
57
73
  var propName = valuePropNames[i];
58
74
  if (props[propName] == null) {
59
75
  continue;
60
76
  }
61
77
  if (props.multiple) {
62
- process.env.NODE_ENV !== 'production' ? warning(Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)) : undefined;
78
+ process.env.NODE_ENV !== 'production' ? warning(Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)) : void 0;
63
79
  } else {
64
- process.env.NODE_ENV !== 'production' ? warning(!Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum(owner)) : undefined;
80
+ process.env.NODE_ENV !== 'production' ? warning(!Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum(owner)) : void 0;
65
81
  }
66
82
  }
67
83
  }
@@ -74,7 +90,7 @@ function checkSelectPropTypes(inst, props) {
74
90
  */
75
91
  function updateOptions(inst, multiple, propValue) {
76
92
  var selectedValue, i;
77
- var options = ReactMount.getNode(inst._rootNodeID).options;
93
+ var options = ReactDOMComponentTree.getNodeFromInstance(inst).options;
78
94
 
79
95
  if (multiple) {
80
96
  selectedValue = {};
@@ -119,10 +135,8 @@ function updateOptions(inst, multiple, propValue) {
119
135
  * selected.
120
136
  */
121
137
  var ReactDOMSelect = {
122
- valueContextKey: valueContextKey,
123
-
124
- getNativeProps: function (inst, props, context) {
125
- return assign({}, props, {
138
+ getNativeProps: function (inst, props) {
139
+ return _assign({}, props, {
126
140
  onChange: inst._wrapperState.onChange,
127
141
  value: undefined
128
142
  });
@@ -131,30 +145,38 @@ var ReactDOMSelect = {
131
145
  mountWrapper: function (inst, props) {
132
146
  if (process.env.NODE_ENV !== 'production') {
133
147
  checkSelectPropTypes(inst, props);
148
+ warnIfValueIsNull(props);
134
149
  }
135
150
 
136
151
  var value = LinkedValueUtils.getValue(props);
137
152
  inst._wrapperState = {
138
153
  pendingUpdate: false,
139
154
  initialValue: value != null ? value : props.defaultValue,
155
+ listeners: null,
140
156
  onChange: _handleChange.bind(inst),
141
157
  wasMultiple: Boolean(props.multiple)
142
158
  };
159
+
160
+ if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
161
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Select 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 select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0;
162
+ didWarnValueDefaultValue = true;
163
+ }
143
164
  },
144
165
 
145
- processChildContext: function (inst, props, context) {
146
- // Pass down initial value so initial generated markup has correct
147
- // `selected` attributes
148
- var childContext = assign({}, context);
149
- childContext[valueContextKey] = inst._wrapperState.initialValue;
150
- return childContext;
166
+ getSelectValueContext: function (inst) {
167
+ // ReactDOMOption looks at this initial value so the initial generated
168
+ // markup has correct `selected` attributes
169
+ return inst._wrapperState.initialValue;
151
170
  },
152
171
 
153
172
  postUpdateWrapper: function (inst) {
154
173
  var props = inst._currentElement.props;
174
+ if (process.env.NODE_ENV !== 'production') {
175
+ warnIfValueIsNull(props);
176
+ }
155
177
 
156
178
  // After the initial mount, we control selected-ness manually so don't pass
157
- // the context value down
179
+ // this value down
158
180
  inst._wrapperState.initialValue = undefined;
159
181
 
160
182
  var wasMultiple = inst._wrapperState.wasMultiple;
@@ -180,7 +202,9 @@ function _handleChange(event) {
180
202
  var props = this._currentElement.props;
181
203
  var returnValue = LinkedValueUtils.executeOnChange(props, event);
182
204
 
183
- this._wrapperState.pendingUpdate = true;
205
+ if (this._rootNodeID) {
206
+ this._wrapperState.pendingUpdate = true;
207
+ }
184
208
  ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this);
185
209
  return returnValue;
186
210
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013-2015, Facebook, Inc.
2
+ * Copyright 2013-present, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
@@ -128,7 +128,7 @@ function setIEOffsets(node, offsets) {
128
128
  var range = document.selection.createRange().duplicate();
129
129
  var start, end;
130
130
 
131
- if (typeof offsets.end === 'undefined') {
131
+ if (offsets.end === undefined) {
132
132
  start = offsets.start;
133
133
  end = start;
134
134
  } else if (offsets.start > offsets.end) {
@@ -152,7 +152,7 @@ function setIEOffsets(node, offsets) {
152
152
  *
153
153
  * Note: IE10+ supports the Selection object, but it does not support
154
154
  * the `extend` method, which means that even in modern IE, it's not possible
155
- * to programatically create a backward selection. Thus, for all IE
155
+ * to programmatically create a backward selection. Thus, for all IE
156
156
  * versions, we use the old IE API to create our selections.
157
157
  *
158
158
  * @param {DOMElement|DOMTextNode} node
@@ -166,7 +166,7 @@ function setModernOffsets(node, offsets) {
166
166
  var selection = window.getSelection();
167
167
  var length = node[getTextContentAccessor()].length;
168
168
  var start = Math.min(offsets.start, length);
169
- var end = typeof offsets.end === 'undefined' ? start : Math.min(offsets.end, length);
169
+ var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
170
170
 
171
171
  // IE 11 uses modern selection, but doesn't support the extend method.
172
172
  // Flip backward selections, so we can set with a single range.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013-2015, Facebook, Inc.
2
+ * Copyright 2013-present, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2013-2015, Facebook, Inc.
2
+ * Copyright 2013-present, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
@@ -7,19 +7,19 @@
7
7
  * of patent rights can be found in the PATENTS file in the same directory.
8
8
  *
9
9
  * @providesModule ReactDOMTextComponent
10
- * @typechecks static-only
11
10
  */
12
11
 
13
12
  'use strict';
14
13
 
14
+ var _assign = require('object-assign');
15
+
15
16
  var DOMChildrenOperations = require('./DOMChildrenOperations');
16
- var DOMPropertyOperations = require('./DOMPropertyOperations');
17
- var ReactComponentBrowserEnvironment = require('./ReactComponentBrowserEnvironment');
18
- var ReactMount = require('./ReactMount');
17
+ var DOMLazyTree = require('./DOMLazyTree');
18
+ var ReactDOMComponentTree = require('./ReactDOMComponentTree');
19
+ var ReactPerf = require('./ReactPerf');
19
20
 
20
- var assign = require('./Object.assign');
21
21
  var escapeTextContentForBrowser = require('./escapeTextContentForBrowser');
22
- var setTextContent = require('./setTextContent');
22
+ var invariant = require('fbjs/lib/invariant');
23
23
  var validateDOMNesting = require('./validateDOMNesting');
24
24
 
25
25
  /**
@@ -28,8 +28,8 @@ var validateDOMNesting = require('./validateDOMNesting');
28
28
  * - When mounting text into the DOM, adjacent text nodes are merged.
29
29
  * - Text nodes cannot be assigned a React root ID.
30
30
  *
31
- * This component is used to wrap strings in elements so that they can undergo
32
- * the same reconciliation that is applied to elements.
31
+ * This component is used to wrap strings between comment nodes so that they
32
+ * can undergo the same reconciliation that is applied to elements.
33
33
  *
34
34
  * TODO: Investigate representing React components in the DOM with text nodes.
35
35
  *
@@ -37,62 +37,75 @@ var validateDOMNesting = require('./validateDOMNesting');
37
37
  * @extends ReactComponent
38
38
  * @internal
39
39
  */
40
- var ReactDOMTextComponent = function (props) {
41
- // This constructor and its argument is currently used by mocks.
42
- };
40
+ var ReactDOMTextComponent = function (text) {
41
+ // TODO: This is really a ReactText (ReactNode), not a ReactElement
42
+ this._currentElement = text;
43
+ this._stringText = '' + text;
44
+ // ReactDOMComponentTree uses these:
45
+ this._nativeNode = null;
46
+ this._nativeParent = null;
43
47
 
44
- assign(ReactDOMTextComponent.prototype, {
48
+ // Properties
49
+ this._domID = null;
50
+ this._mountIndex = 0;
51
+ this._closingComment = null;
52
+ this._commentNodes = null;
53
+ };
45
54
 
46
- /**
47
- * @param {ReactText} text
48
- * @internal
49
- */
50
- construct: function (text) {
51
- // TODO: This is really a ReactText (ReactNode), not a ReactElement
52
- this._currentElement = text;
53
- this._stringText = '' + text;
54
-
55
- // Properties
56
- this._rootNodeID = null;
57
- this._mountIndex = 0;
58
- },
55
+ _assign(ReactDOMTextComponent.prototype, {
59
56
 
60
57
  /**
61
58
  * Creates the markup for this text node. This node is not intended to have
62
59
  * any features besides containing text content.
63
60
  *
64
- * @param {string} rootID DOM ID of the root node.
65
61
  * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
66
62
  * @return {string} Markup for this text node.
67
63
  * @internal
68
64
  */
69
- mountComponent: function (rootID, transaction, context) {
65
+ mountComponent: function (transaction, nativeParent, nativeContainerInfo, context) {
70
66
  if (process.env.NODE_ENV !== 'production') {
71
- if (context[validateDOMNesting.ancestorInfoContextKey]) {
72
- validateDOMNesting('span', null, context[validateDOMNesting.ancestorInfoContextKey]);
67
+ var parentInfo;
68
+ if (nativeParent != null) {
69
+ parentInfo = nativeParent._ancestorInfo;
70
+ } else if (nativeContainerInfo != null) {
71
+ parentInfo = nativeContainerInfo._ancestorInfo;
72
+ }
73
+ if (parentInfo) {
74
+ // parentInfo should always be present except for the top-level
75
+ // component when server rendering
76
+ validateDOMNesting('#text', this, parentInfo);
73
77
  }
74
78
  }
75
79
 
76
- this._rootNodeID = rootID;
80
+ var domID = nativeContainerInfo._idCounter++;
81
+ var openingValue = ' react-text: ' + domID + ' ';
82
+ var closingValue = ' /react-text ';
83
+ this._domID = domID;
84
+ this._nativeParent = nativeParent;
77
85
  if (transaction.useCreateElement) {
78
- var ownerDocument = context[ReactMount.ownerDocumentContextKey];
79
- var el = ownerDocument.createElement('span');
80
- DOMPropertyOperations.setAttributeForID(el, rootID);
81
- // Populate node cache
82
- ReactMount.getID(el);
83
- setTextContent(el, this._stringText);
84
- return el;
86
+ var ownerDocument = nativeContainerInfo._ownerDocument;
87
+ var openingComment = ownerDocument.createComment(openingValue);
88
+ var closingComment = ownerDocument.createComment(closingValue);
89
+ var lazyTree = DOMLazyTree(ownerDocument.createDocumentFragment());
90
+ DOMLazyTree.queueChild(lazyTree, DOMLazyTree(openingComment));
91
+ if (this._stringText) {
92
+ DOMLazyTree.queueChild(lazyTree, DOMLazyTree(ownerDocument.createTextNode(this._stringText)));
93
+ }
94
+ DOMLazyTree.queueChild(lazyTree, DOMLazyTree(closingComment));
95
+ ReactDOMComponentTree.precacheNode(this, openingComment);
96
+ this._closingComment = closingComment;
97
+ return lazyTree;
85
98
  } else {
86
99
  var escapedText = escapeTextContentForBrowser(this._stringText);
87
100
 
88
101
  if (transaction.renderToStaticMarkup) {
89
- // Normally we'd wrap this in a `span` for the reasons stated above, but
90
- // since this is a situation where React won't take over (static pages),
91
- // we can simply return the text as it is.
102
+ // Normally we'd wrap this between comment nodes for the reasons stated
103
+ // above, but since this is a situation where React won't take over
104
+ // (static pages), we can simply return the text as it is.
92
105
  return escapedText;
93
106
  }
94
107
 
95
- return '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' + escapedText + '</span>';
108
+ return '<!--' + openingValue + '-->' + escapedText + '<!--' + closingValue + '-->';
96
109
  }
97
110
  },
98
111
 
@@ -112,16 +125,45 @@ assign(ReactDOMTextComponent.prototype, {
112
125
  // and/or updateComponent to do the actual update for consistency with
113
126
  // other component types?
114
127
  this._stringText = nextStringText;
115
- var node = ReactMount.getNode(this._rootNodeID);
116
- DOMChildrenOperations.updateTextContent(node, nextStringText);
128
+ var commentNodes = this.getNativeNode();
129
+ DOMChildrenOperations.replaceDelimitedText(commentNodes[0], commentNodes[1], nextStringText);
130
+ }
131
+ }
132
+ },
133
+
134
+ getNativeNode: function () {
135
+ var nativeNode = this._commentNodes;
136
+ if (nativeNode) {
137
+ return nativeNode;
138
+ }
139
+ if (!this._closingComment) {
140
+ var openingComment = ReactDOMComponentTree.getNodeFromInstance(this);
141
+ var node = openingComment.nextSibling;
142
+ 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;
144
+ if (node.nodeType === 8 && node.nodeValue === ' /react-text ') {
145
+ this._closingComment = node;
146
+ break;
147
+ }
148
+ node = node.nextSibling;
117
149
  }
118
150
  }
151
+ nativeNode = [this._nativeNode, this._closingComment];
152
+ this._commentNodes = nativeNode;
153
+ return nativeNode;
119
154
  },
120
155
 
121
156
  unmountComponent: function () {
122
- ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);
157
+ this._closingComment = null;
158
+ this._commentNodes = null;
159
+ ReactDOMComponentTree.uncacheNode(this);
123
160
  }
124
161
 
125
162
  });
126
163
 
164
+ ReactPerf.measureMethods(ReactDOMTextComponent.prototype, 'ReactDOMTextComponent', {
165
+ mountComponent: 'mountComponent',
166
+ receiveComponent: 'receiveComponent'
167
+ });
168
+
127
169
  module.exports = ReactDOMTextComponent;