react 0.13.2 → 0.14.0-alpha3
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.
- package/README.md +1 -1
- package/addons.js +7 -0
- package/addons/CSSTransitionGroup.js +1 -0
- package/addons/LinkedStateMixin.js +1 -0
- package/addons/Perf.js +1 -0
- package/addons/PureRenderMixin.js +1 -0
- package/addons/TestUtils.js +1 -0
- package/addons/TransitionGroup.js +1 -0
- package/addons/batchedUpdates.js +1 -0
- package/addons/cloneWithProps.js +1 -0
- package/addons/createFragment.js +1 -0
- package/addons/renderSubtreeIntoContainer.js +1 -0
- package/addons/shallowCompare.js +1 -0
- package/addons/update.js +1 -0
- package/dist/JSXTransformer.js +3355 -1685
- package/dist/react-with-addons.js +3320 -5133
- package/dist/react-with-addons.min.js +6 -7
- package/dist/react.js +2962 -4548
- package/dist/react.min.js +5 -5
- package/lib/AutoFocusMixin.js +4 -3
- package/lib/BeforeInputEventPlugin.js +30 -118
- package/lib/CSSCore.js +12 -23
- package/lib/CSSProperty.js +4 -3
- package/lib/CSSPropertyOperations.js +14 -30
- package/lib/CallbackQueue.js +7 -10
- package/lib/ChangeEventPlugin.js +24 -88
- package/lib/ClientReactRootIndex.js +2 -2
- package/lib/DOMChildrenOperations.js +13 -33
- package/lib/DOMProperty.js +41 -67
- package/lib/DOMPropertyOperations.js +30 -51
- package/lib/Danger.js +19 -62
- package/lib/DefaultEventPluginOrder.js +2 -12
- package/lib/EnterLeaveEventPlugin.js +11 -33
- package/lib/EventConstants.js +2 -2
- package/lib/EventListener.js +11 -13
- package/lib/EventPluginHub.js +44 -47
- package/lib/EventPluginRegistry.js +18 -74
- package/lib/EventPluginUtils.js +27 -38
- package/lib/EventPropagators.js +23 -26
- package/lib/ExecutionEnvironment.js +4 -8
- package/lib/FallbackCompositionState.js +3 -3
- package/lib/HTMLDOMPropertyConfig.js +7 -19
- package/lib/LinkedStateMixin.js +3 -6
- package/lib/LinkedValueUtils.js +34 -64
- package/lib/LocalEventTrapMixin.js +9 -16
- package/lib/Object.assign.js +1 -1
- package/lib/PooledClass.js +8 -11
- package/lib/React.js +9 -129
- package/lib/ReactBrowserComponentMixin.js +9 -2
- package/lib/ReactBrowserEventEmitter.js +26 -82
- package/lib/ReactCSSTransitionGroup.js +13 -24
- package/lib/ReactCSSTransitionGroupChild.js +18 -28
- package/lib/ReactChildReconciler.js +11 -19
- package/lib/ReactChildren.js +21 -28
- package/lib/ReactClass.js +81 -234
- package/lib/ReactComponent.js +17 -33
- package/lib/ReactComponentBrowserEnvironment.js +4 -8
- package/lib/ReactComponentEnvironment.js +6 -12
- package/lib/ReactComponentWithPureRenderMixin.js +4 -5
- package/lib/ReactCompositeComponent.js +87 -311
- package/lib/ReactContext.js +2 -44
- package/lib/ReactCurrentOwner.js +1 -3
- package/lib/ReactDOM.js +4 -2
- package/lib/ReactDOMButton.js +3 -4
- package/lib/ReactDOMClient.js +85 -0
- package/lib/ReactDOMComponent.js +182 -146
- package/lib/ReactDOMForm.js +3 -3
- package/lib/ReactDOMIDOperations.js +11 -22
- package/lib/ReactDOMIframe.js +3 -3
- package/lib/ReactDOMImg.js +3 -3
- package/lib/ReactDOMInput.js +22 -35
- package/lib/ReactDOMOption.js +67 -10
- package/lib/ReactDOMSelect.js +50 -28
- package/lib/ReactDOMSelection.js +5 -20
- package/lib/ReactDOMServer.js +24 -0
- package/lib/ReactDOMTextComponent.js +17 -18
- package/lib/ReactDOMTextarea.js +15 -27
- package/lib/ReactDefaultBatchingStrategy.js +9 -13
- package/lib/ReactDefaultInjection.js +31 -40
- package/lib/ReactDefaultPerf.js +36 -69
- package/lib/ReactDefaultPerfAnalysis.js +8 -14
- package/lib/ReactElement.js +24 -57
- package/lib/ReactElementValidator.js +38 -105
- package/lib/ReactEmptyComponent.js +7 -11
- package/lib/ReactErrorUtils.js +2 -2
- package/lib/ReactEventEmitterMixin.js +3 -12
- package/lib/ReactEventListener.js +16 -38
- package/lib/ReactFragment.js +23 -54
- package/lib/ReactInjection.js +1 -1
- package/lib/ReactInputSelection.js +11 -21
- package/lib/ReactInstanceHandles.js +27 -57
- package/lib/ReactInstanceMap.js +5 -5
- package/lib/ReactIsomorphic.js +70 -0
- package/lib/ReactLifeCycle.js +1 -1
- package/lib/ReactLink.js +2 -4
- package/lib/ReactMarkupChecksum.js +5 -10
- package/lib/ReactMount.js +137 -260
- package/lib/ReactMultiChild.js +19 -45
- package/lib/ReactMultiChildUpdateTypes.js +1 -1
- package/lib/ReactNativeComponent.js +7 -11
- package/lib/ReactOwner.js +7 -24
- package/lib/ReactPerf.js +8 -12
- package/lib/ReactPropTransferer.js +4 -4
- package/lib/ReactPropTypeLocationNames.js +2 -2
- package/lib/ReactPropTypeLocations.js +1 -1
- package/lib/ReactPropTypes.js +41 -61
- package/lib/ReactReconcileTransaction.js +9 -34
- package/lib/ReactReconciler.js +9 -19
- package/lib/ReactRef.js +5 -8
- package/lib/ReactRootIndex.js +2 -2
- package/lib/ReactServerRendering.js +7 -15
- package/lib/ReactServerRenderingTransaction.js +7 -32
- package/lib/ReactStateSetters.js +6 -6
- package/lib/ReactTestUtils.js +93 -165
- package/lib/ReactTransitionChildMapping.js +5 -7
- package/lib/ReactTransitionEvents.js +5 -5
- package/lib/ReactTransitionGroup.js +30 -52
- package/lib/ReactUpdateQueue.js +27 -90
- package/lib/ReactUpdates.js +27 -79
- package/lib/ReactWithAddons.js +7 -6
- package/lib/SVGDOMPropertyConfig.js +41 -4
- package/lib/SelectEventPlugin.js +28 -29
- package/lib/ServerReactRootIndex.js +2 -2
- package/lib/SimpleEventPlugin.js +136 -128
- package/lib/SyntheticClipboardEvent.js +3 -7
- package/lib/SyntheticCompositionEvent.js +3 -9
- package/lib/SyntheticDragEvent.js +1 -1
- package/lib/SyntheticEvent.js +8 -10
- package/lib/SyntheticFocusEvent.js +1 -1
- package/lib/SyntheticInputEvent.js +3 -9
- package/lib/SyntheticKeyboardEvent.js +4 -4
- package/lib/SyntheticMouseEvent.js +8 -14
- package/lib/SyntheticTouchEvent.js +1 -1
- package/lib/SyntheticUIEvent.js +3 -3
- package/lib/SyntheticWheelEvent.js +11 -15
- package/lib/Transaction.js +12 -24
- package/lib/ViewportMetrics.js +2 -2
- package/lib/accumulateInto.js +2 -5
- package/lib/adler32.js +2 -4
- package/lib/camelize.js +4 -2
- package/lib/camelizeStyleName.js +2 -2
- package/lib/cloneWithProps.js +5 -11
- package/lib/containsNode.js +29 -16
- package/lib/createArrayFromMixed.js +17 -16
- package/lib/createFullPageComponent.js +4 -11
- package/lib/createNodesFromMarkup.js +6 -8
- package/lib/dangerousStyleValue.js +2 -3
- package/lib/emptyFunction.js +10 -4
- package/lib/emptyObject.js +1 -1
- package/lib/escapeTextContentForBrowser.js +1 -1
- package/lib/findDOMNode.js +5 -24
- package/lib/flattenChildren.js +4 -10
- package/lib/focusNode.js +2 -3
- package/lib/forEachAccumulated.js +2 -2
- package/lib/getActiveElement.js +4 -2
- package/lib/getEventCharCode.js +1 -1
- package/lib/getEventKey.js +1 -1
- package/lib/getEventModifierState.js +1 -1
- package/lib/getEventTarget.js +1 -1
- package/lib/getIteratorFn.js +2 -4
- package/lib/getMarkupWrap.js +7 -5
- package/lib/getNodeForCharacterOffset.js +1 -1
- package/lib/getTextContentAccessor.js +2 -4
- package/lib/getUnboundedScrollPosition.js +1 -1
- package/lib/hyphenate.js +3 -1
- package/lib/hyphenateStyleName.js +2 -2
- package/lib/instantiateReactComponent.js +14 -38
- package/lib/invariant.js +8 -12
- package/lib/isEventSupported.js +7 -10
- package/lib/isNode.js +4 -6
- package/lib/isTextInputElement.js +2 -4
- package/lib/isTextNode.js +3 -1
- package/lib/joinClasses.js +2 -2
- package/lib/keyMirror.js +3 -6
- package/lib/keyOf.js +4 -3
- package/lib/mapObject.js +1 -1
- package/lib/memoizeStringOnly.js +2 -2
- package/lib/onlyChild.js +2 -5
- package/lib/performance.js +2 -5
- package/lib/performanceNow.js +3 -1
- package/lib/quoteAttributeValueForBrowser.js +1 -1
- package/lib/renderSubtreeIntoContainer.js +16 -0
- package/lib/setInnerHTML.js +11 -8
- package/lib/setTextContent.js +3 -3
- package/lib/shallowCompare.js +24 -0
- package/lib/shallowEqual.js +17 -11
- package/lib/shouldUpdateReactComponent.js +3 -64
- package/lib/toArray.js +8 -19
- package/lib/traverseAllChildren.js +22 -89
- package/lib/update.js +25 -85
- package/lib/validateDOMNesting.js +363 -0
- package/lib/warning.js +17 -15
- package/package.json +3 -3
- package/lib/MobileSafariClickEventPlugin.js +0 -56
- package/lib/ReactPutListenerQueue.js +0 -54
- package/lib/cx.js +0 -52
- package/lib/getReactRootElementInContainer.js +0 -33
package/lib/ReactDOMForm.js
CHANGED
|
@@ -31,17 +31,17 @@ var ReactDOMForm = ReactClass.createClass({
|
|
|
31
31
|
|
|
32
32
|
mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin],
|
|
33
33
|
|
|
34
|
-
render: function() {
|
|
34
|
+
render: function () {
|
|
35
35
|
// TODO: Instead of using `ReactDOM` directly, we should use JSX. However,
|
|
36
36
|
// `jshint` fails to parse JSX so in order for linting to work in the open
|
|
37
37
|
// source repo, we need to just use `ReactDOM.form`.
|
|
38
38
|
return form(this.props);
|
|
39
39
|
},
|
|
40
40
|
|
|
41
|
-
componentDidMount: function() {
|
|
41
|
+
componentDidMount: function () {
|
|
42
42
|
this.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset');
|
|
43
43
|
this.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit');
|
|
44
44
|
}
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
module.exports = ReactDOMForm;
|
|
47
|
+
module.exports = ReactDOMForm;
|
|
@@ -10,8 +10,6 @@
|
|
|
10
10
|
* @typechecks static-only
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
/*jslint evil: true */
|
|
14
|
-
|
|
15
13
|
'use strict';
|
|
16
14
|
|
|
17
15
|
var CSSPropertyOperations = require("./CSSPropertyOperations");
|
|
@@ -30,8 +28,7 @@ var setInnerHTML = require("./setInnerHTML");
|
|
|
30
28
|
* @private
|
|
31
29
|
*/
|
|
32
30
|
var INVALID_PROPERTY_ERRORS = {
|
|
33
|
-
dangerouslySetInnerHTML:
|
|
34
|
-
'`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',
|
|
31
|
+
dangerouslySetInnerHTML: '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.',
|
|
35
32
|
style: '`style` must be set using `updateStylesByID()`.'
|
|
36
33
|
};
|
|
37
34
|
|
|
@@ -50,13 +47,9 @@ var ReactDOMIDOperations = {
|
|
|
50
47
|
* @param {*} value New value of the property.
|
|
51
48
|
* @internal
|
|
52
49
|
*/
|
|
53
|
-
updatePropertyByID: function(id, name, value) {
|
|
50
|
+
updatePropertyByID: function (id, name, value) {
|
|
54
51
|
var node = ReactMount.getNode(id);
|
|
55
|
-
(
|
|
56
|
-
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
|
|
57
|
-
'updatePropertyByID(...): %s',
|
|
58
|
-
INVALID_PROPERTY_ERRORS[name]
|
|
59
|
-
) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name)));
|
|
52
|
+
!!INVALID_PROPERTY_ERRORS.hasOwnProperty(name) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name]) : invariant(false) : undefined;
|
|
60
53
|
|
|
61
54
|
// If we're updating to null or undefined, we should remove the property
|
|
62
55
|
// from the DOM node instead of inadvertantly setting to a string. This
|
|
@@ -76,13 +69,9 @@ var ReactDOMIDOperations = {
|
|
|
76
69
|
* @param {string} name A property name to remove, see `DOMProperty`.
|
|
77
70
|
* @internal
|
|
78
71
|
*/
|
|
79
|
-
deletePropertyByID: function(id, name, value) {
|
|
72
|
+
deletePropertyByID: function (id, name, value) {
|
|
80
73
|
var node = ReactMount.getNode(id);
|
|
81
|
-
(
|
|
82
|
-
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
|
|
83
|
-
'updatePropertyByID(...): %s',
|
|
84
|
-
INVALID_PROPERTY_ERRORS[name]
|
|
85
|
-
) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name)));
|
|
74
|
+
!!INVALID_PROPERTY_ERRORS.hasOwnProperty(name) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name]) : invariant(false) : undefined;
|
|
86
75
|
DOMPropertyOperations.deleteValueForProperty(node, name, value);
|
|
87
76
|
},
|
|
88
77
|
|
|
@@ -94,7 +83,7 @@ var ReactDOMIDOperations = {
|
|
|
94
83
|
* @param {object} styles Mapping from styles to values.
|
|
95
84
|
* @internal
|
|
96
85
|
*/
|
|
97
|
-
updateStylesByID: function(id, styles) {
|
|
86
|
+
updateStylesByID: function (id, styles) {
|
|
98
87
|
var node = ReactMount.getNode(id);
|
|
99
88
|
CSSPropertyOperations.setValueForStyles(node, styles);
|
|
100
89
|
},
|
|
@@ -106,7 +95,7 @@ var ReactDOMIDOperations = {
|
|
|
106
95
|
* @param {string} html An HTML string.
|
|
107
96
|
* @internal
|
|
108
97
|
*/
|
|
109
|
-
updateInnerHTMLByID: function(id, html) {
|
|
98
|
+
updateInnerHTMLByID: function (id, html) {
|
|
110
99
|
var node = ReactMount.getNode(id);
|
|
111
100
|
setInnerHTML(node, html);
|
|
112
101
|
},
|
|
@@ -118,7 +107,7 @@ var ReactDOMIDOperations = {
|
|
|
118
107
|
* @param {string} content Text content.
|
|
119
108
|
* @internal
|
|
120
109
|
*/
|
|
121
|
-
updateTextContentByID: function(id, content) {
|
|
110
|
+
updateTextContentByID: function (id, content) {
|
|
122
111
|
var node = ReactMount.getNode(id);
|
|
123
112
|
DOMChildrenOperations.updateTextContent(node, content);
|
|
124
113
|
},
|
|
@@ -131,7 +120,7 @@ var ReactDOMIDOperations = {
|
|
|
131
120
|
* @internal
|
|
132
121
|
* @see {Danger.dangerouslyReplaceNodeWithMarkup}
|
|
133
122
|
*/
|
|
134
|
-
dangerouslyReplaceNodeWithMarkupByID: function(id, markup) {
|
|
123
|
+
dangerouslyReplaceNodeWithMarkupByID: function (id, markup) {
|
|
135
124
|
var node = ReactMount.getNode(id);
|
|
136
125
|
DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
|
|
137
126
|
},
|
|
@@ -143,7 +132,7 @@ var ReactDOMIDOperations = {
|
|
|
143
132
|
* @param {array<string>} markup List of markup strings.
|
|
144
133
|
* @internal
|
|
145
134
|
*/
|
|
146
|
-
dangerouslyProcessChildrenUpdates: function(updates, markup) {
|
|
135
|
+
dangerouslyProcessChildrenUpdates: function (updates, markup) {
|
|
147
136
|
for (var i = 0; i < updates.length; i++) {
|
|
148
137
|
updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
|
|
149
138
|
}
|
|
@@ -161,4 +150,4 @@ ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', {
|
|
|
161
150
|
dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates'
|
|
162
151
|
});
|
|
163
152
|
|
|
164
|
-
module.exports = ReactDOMIDOperations;
|
|
153
|
+
module.exports = ReactDOMIDOperations;
|
package/lib/ReactDOMIframe.js
CHANGED
|
@@ -31,13 +31,13 @@ var ReactDOMIframe = ReactClass.createClass({
|
|
|
31
31
|
|
|
32
32
|
mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin],
|
|
33
33
|
|
|
34
|
-
render: function() {
|
|
34
|
+
render: function () {
|
|
35
35
|
return iframe(this.props);
|
|
36
36
|
},
|
|
37
37
|
|
|
38
|
-
componentDidMount: function() {
|
|
38
|
+
componentDidMount: function () {
|
|
39
39
|
this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load');
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
module.exports = ReactDOMIframe;
|
|
43
|
+
module.exports = ReactDOMIframe;
|
package/lib/ReactDOMImg.js
CHANGED
|
@@ -31,14 +31,14 @@ var ReactDOMImg = ReactClass.createClass({
|
|
|
31
31
|
|
|
32
32
|
mixins: [ReactBrowserComponentMixin, LocalEventTrapMixin],
|
|
33
33
|
|
|
34
|
-
render: function() {
|
|
34
|
+
render: function () {
|
|
35
35
|
return img(this.props);
|
|
36
36
|
},
|
|
37
37
|
|
|
38
|
-
componentDidMount: function() {
|
|
38
|
+
componentDidMount: function () {
|
|
39
39
|
this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load');
|
|
40
40
|
this.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error');
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
module.exports = ReactDOMImg;
|
|
44
|
+
module.exports = ReactDOMImg;
|
package/lib/ReactDOMInput.js
CHANGED
|
@@ -21,6 +21,7 @@ var ReactMount = require("./ReactMount");
|
|
|
21
21
|
var ReactUpdates = require("./ReactUpdates");
|
|
22
22
|
|
|
23
23
|
var assign = require("./Object.assign");
|
|
24
|
+
var findDOMNode = require("./findDOMNode");
|
|
24
25
|
var invariant = require("./invariant");
|
|
25
26
|
|
|
26
27
|
var input = ReactElement.createFactory('input');
|
|
@@ -56,7 +57,7 @@ var ReactDOMInput = ReactClass.createClass({
|
|
|
56
57
|
|
|
57
58
|
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
|
|
58
59
|
|
|
59
|
-
getInitialState: function() {
|
|
60
|
+
getInitialState: function () {
|
|
60
61
|
var defaultValue = this.props.defaultValue;
|
|
61
62
|
return {
|
|
62
63
|
initialChecked: this.props.defaultChecked || false,
|
|
@@ -64,17 +65,17 @@ var ReactDOMInput = ReactClass.createClass({
|
|
|
64
65
|
};
|
|
65
66
|
},
|
|
66
67
|
|
|
67
|
-
render: function() {
|
|
68
|
+
render: function () {
|
|
68
69
|
// Clone `this.props` so we don't mutate the input.
|
|
69
70
|
var props = assign({}, this.props);
|
|
70
71
|
|
|
71
72
|
props.defaultChecked = null;
|
|
72
73
|
props.defaultValue = null;
|
|
73
74
|
|
|
74
|
-
var value = LinkedValueUtils.getValue(this);
|
|
75
|
+
var value = LinkedValueUtils.getValue(this.props);
|
|
75
76
|
props.value = value != null ? value : this.state.initialValue;
|
|
76
77
|
|
|
77
|
-
var checked = LinkedValueUtils.getChecked(this);
|
|
78
|
+
var checked = LinkedValueUtils.getChecked(this.props);
|
|
78
79
|
props.checked = checked != null ? checked : this.state.initialChecked;
|
|
79
80
|
|
|
80
81
|
props.onChange = this._handleChange;
|
|
@@ -82,28 +83,24 @@ var ReactDOMInput = ReactClass.createClass({
|
|
|
82
83
|
return input(props, this.props.children);
|
|
83
84
|
},
|
|
84
85
|
|
|
85
|
-
componentDidMount: function() {
|
|
86
|
-
var id = ReactMount.getID(this
|
|
86
|
+
componentDidMount: function () {
|
|
87
|
+
var id = ReactMount.getID(findDOMNode(this));
|
|
87
88
|
instancesByReactID[id] = this;
|
|
88
89
|
},
|
|
89
90
|
|
|
90
|
-
componentWillUnmount: function() {
|
|
91
|
-
var rootNode = this
|
|
91
|
+
componentWillUnmount: function () {
|
|
92
|
+
var rootNode = findDOMNode(this);
|
|
92
93
|
var id = ReactMount.getID(rootNode);
|
|
93
94
|
delete instancesByReactID[id];
|
|
94
95
|
},
|
|
95
96
|
|
|
96
|
-
componentDidUpdate: function(prevProps, prevState, prevContext) {
|
|
97
|
-
var rootNode = this
|
|
97
|
+
componentDidUpdate: function (prevProps, prevState, prevContext) {
|
|
98
|
+
var rootNode = findDOMNode(this);
|
|
98
99
|
if (this.props.checked != null) {
|
|
99
|
-
DOMPropertyOperations.setValueForProperty(
|
|
100
|
-
rootNode,
|
|
101
|
-
'checked',
|
|
102
|
-
this.props.checked || false
|
|
103
|
-
);
|
|
100
|
+
DOMPropertyOperations.setValueForProperty(rootNode, 'checked', this.props.checked || false);
|
|
104
101
|
}
|
|
105
102
|
|
|
106
|
-
var value = LinkedValueUtils.getValue(this);
|
|
103
|
+
var value = LinkedValueUtils.getValue(this.props);
|
|
107
104
|
if (value != null) {
|
|
108
105
|
// Cast `value` to a string to ensure the value is set correctly. While
|
|
109
106
|
// browsers typically do this as necessary, jsdom doesn't.
|
|
@@ -111,9 +108,9 @@ var ReactDOMInput = ReactClass.createClass({
|
|
|
111
108
|
}
|
|
112
109
|
},
|
|
113
110
|
|
|
114
|
-
_handleChange: function(event) {
|
|
111
|
+
_handleChange: function (event) {
|
|
115
112
|
var returnValue;
|
|
116
|
-
var onChange = LinkedValueUtils.getOnChange(this);
|
|
113
|
+
var onChange = LinkedValueUtils.getOnChange(this.props);
|
|
117
114
|
if (onChange) {
|
|
118
115
|
returnValue = onChange.call(this, event);
|
|
119
116
|
}
|
|
@@ -124,7 +121,7 @@ var ReactDOMInput = ReactClass.createClass({
|
|
|
124
121
|
|
|
125
122
|
var name = this.props.name;
|
|
126
123
|
if (this.props.type === 'radio' && name != null) {
|
|
127
|
-
var rootNode = this
|
|
124
|
+
var rootNode = findDOMNode(this);
|
|
128
125
|
var queryRoot = rootNode;
|
|
129
126
|
|
|
130
127
|
while (queryRoot.parentNode) {
|
|
@@ -137,27 +134,17 @@ var ReactDOMInput = ReactClass.createClass({
|
|
|
137
134
|
// and won't include inputs that use the HTML5 `form=` attribute. Since
|
|
138
135
|
// the input might not even be in a form, let's just use the global
|
|
139
136
|
// `querySelectorAll` to ensure we don't miss anything.
|
|
140
|
-
var group = queryRoot.querySelectorAll(
|
|
141
|
-
'input[name=' + JSON.stringify('' + name) + '][type="radio"]');
|
|
137
|
+
var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
|
|
142
138
|
|
|
143
|
-
for (var i = 0
|
|
139
|
+
for (var i = 0; i < group.length; i++) {
|
|
144
140
|
var otherNode = group[i];
|
|
145
|
-
if (otherNode === rootNode ||
|
|
146
|
-
otherNode.form !== rootNode.form) {
|
|
141
|
+
if (otherNode === rootNode || otherNode.form !== rootNode.form) {
|
|
147
142
|
continue;
|
|
148
143
|
}
|
|
149
144
|
var otherID = ReactMount.getID(otherNode);
|
|
150
|
-
|
|
151
|
-
otherID,
|
|
152
|
-
'ReactDOMInput: Mixing React and non-React radio inputs with the ' +
|
|
153
|
-
'same `name` is not supported.'
|
|
154
|
-
) : invariant(otherID));
|
|
145
|
+
!otherID ? 'production' !== process.env.NODE_ENV ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.') : invariant(false) : undefined;
|
|
155
146
|
var otherInstance = instancesByReactID[otherID];
|
|
156
|
-
|
|
157
|
-
otherInstance,
|
|
158
|
-
'ReactDOMInput: Unknown radio button ID %s.',
|
|
159
|
-
otherID
|
|
160
|
-
) : invariant(otherInstance));
|
|
147
|
+
!otherInstance ? 'production' !== process.env.NODE_ENV ? invariant(false, 'ReactDOMInput: Unknown radio button ID %s.', otherID) : invariant(false) : undefined;
|
|
161
148
|
// If this is a controlled radio button group, forcing the input that
|
|
162
149
|
// was previously checked to update will cause it to be come re-checked
|
|
163
150
|
// as appropriate.
|
|
@@ -170,4 +157,4 @@ var ReactDOMInput = ReactClass.createClass({
|
|
|
170
157
|
|
|
171
158
|
});
|
|
172
159
|
|
|
173
|
-
module.exports = ReactDOMInput;
|
|
160
|
+
module.exports = ReactDOMInput;
|
package/lib/ReactDOMOption.js
CHANGED
|
@@ -12,13 +12,19 @@
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
14
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
15
|
+
var ReactChildren = require("./ReactChildren");
|
|
15
16
|
var ReactClass = require("./ReactClass");
|
|
17
|
+
var ReactDOMSelect = require("./ReactDOMSelect");
|
|
16
18
|
var ReactElement = require("./ReactElement");
|
|
19
|
+
var ReactPropTypes = require("./ReactPropTypes");
|
|
17
20
|
|
|
21
|
+
var assign = require("./Object.assign");
|
|
18
22
|
var warning = require("./warning");
|
|
19
23
|
|
|
20
24
|
var option = ReactElement.createFactory('option');
|
|
21
25
|
|
|
26
|
+
var valueContextKey = ReactDOMSelect.valueContextKey;
|
|
27
|
+
|
|
22
28
|
/**
|
|
23
29
|
* Implements an <option> native component that warns when `selected` is set.
|
|
24
30
|
*/
|
|
@@ -28,21 +34,72 @@ var ReactDOMOption = ReactClass.createClass({
|
|
|
28
34
|
|
|
29
35
|
mixins: [ReactBrowserComponentMixin],
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
getInitialState: function () {
|
|
38
|
+
return { selected: null };
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
contextTypes: (function () {
|
|
42
|
+
var obj = {};
|
|
43
|
+
obj[valueContextKey] = ReactPropTypes.any;
|
|
44
|
+
return obj;
|
|
45
|
+
})(),
|
|
46
|
+
|
|
47
|
+
componentWillMount: function () {
|
|
32
48
|
// TODO (yungsters): Remove support for `selected` in <option>.
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
49
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
50
|
+
'production' !== process.env.NODE_ENV ? warning(this.props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Look up whether this option is 'selected' via parent-based context
|
|
54
|
+
var context = this.context;
|
|
55
|
+
var selectValue = context[valueContextKey];
|
|
56
|
+
|
|
57
|
+
// If context key is null (e.g., no specified value or after initial mount)
|
|
58
|
+
// or missing (e.g., for <datalist>) skip props
|
|
59
|
+
if (selectValue != null) {
|
|
60
|
+
var selected = false;
|
|
61
|
+
if (Array.isArray(selectValue)) {
|
|
62
|
+
// multiple
|
|
63
|
+
for (var i = 0; i < selectValue.length; i++) {
|
|
64
|
+
if ('' + selectValue[i] === '' + this.props.value) {
|
|
65
|
+
selected = true;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
selected = '' + selectValue === '' + this.props.value;
|
|
71
|
+
}
|
|
72
|
+
this.setState({ selected: selected });
|
|
39
73
|
}
|
|
40
74
|
},
|
|
41
75
|
|
|
42
|
-
render: function() {
|
|
43
|
-
|
|
76
|
+
render: function () {
|
|
77
|
+
var props = this.props;
|
|
78
|
+
|
|
79
|
+
// Read state only from initial mount because <select> updates value
|
|
80
|
+
// manually; we need the initial state only for server rendering
|
|
81
|
+
if (this.state.selected != null) {
|
|
82
|
+
props = assign({}, props, { selected: this.state.selected });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
var content = '';
|
|
86
|
+
|
|
87
|
+
// Flatten children and warn if they aren't strings or numbers;
|
|
88
|
+
// invalid types are ignored.
|
|
89
|
+
ReactChildren.forEach(this.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
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'Only strings and numbers are supported as <option> children.') : undefined;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
return option(props, content);
|
|
44
101
|
}
|
|
45
102
|
|
|
46
103
|
});
|
|
47
104
|
|
|
48
|
-
module.exports = ReactDOMOption;
|
|
105
|
+
module.exports = ReactDOMOption;
|
package/lib/ReactDOMSelect.js
CHANGED
|
@@ -17,16 +17,20 @@ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
|
17
17
|
var ReactClass = require("./ReactClass");
|
|
18
18
|
var ReactElement = require("./ReactElement");
|
|
19
19
|
var ReactUpdates = require("./ReactUpdates");
|
|
20
|
+
var ReactPropTypes = require("./ReactPropTypes");
|
|
20
21
|
|
|
21
22
|
var assign = require("./Object.assign");
|
|
23
|
+
var findDOMNode = require("./findDOMNode");
|
|
22
24
|
|
|
23
25
|
var select = ReactElement.createFactory('select');
|
|
24
26
|
|
|
27
|
+
var valueContextKey = '__ReactDOMSelect_value$' + Math.random().toString(36).slice(2);
|
|
28
|
+
|
|
25
29
|
function updateOptionsIfPendingUpdateAndMounted() {
|
|
26
30
|
/*jshint validthis:true */
|
|
27
31
|
if (this._pendingUpdate) {
|
|
28
32
|
this._pendingUpdate = false;
|
|
29
|
-
var value = LinkedValueUtils.getValue(this);
|
|
33
|
+
var value = LinkedValueUtils.getValue(this.props);
|
|
30
34
|
if (value != null && this.isMounted()) {
|
|
31
35
|
updateOptions(this, value);
|
|
32
36
|
}
|
|
@@ -43,17 +47,11 @@ function selectValueType(props, propName, componentName) {
|
|
|
43
47
|
}
|
|
44
48
|
if (props.multiple) {
|
|
45
49
|
if (!Array.isArray(props[propName])) {
|
|
46
|
-
return new Error(
|
|
47
|
-
("The `" + propName + "` prop supplied to <select> must be an array if ") +
|
|
48
|
-
("`multiple` is true.")
|
|
49
|
-
);
|
|
50
|
+
return new Error('The `' + propName + '` prop supplied to <select> must be an array if ' + '`multiple` is true.');
|
|
50
51
|
}
|
|
51
52
|
} else {
|
|
52
53
|
if (Array.isArray(props[propName])) {
|
|
53
|
-
return new Error(
|
|
54
|
-
("The `" + propName + "` prop supplied to <select> must be a scalar ") +
|
|
55
|
-
("value if `multiple` is false.")
|
|
56
|
-
);
|
|
54
|
+
return new Error('The `' + propName + '` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.');
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
57
|
}
|
|
@@ -64,15 +62,15 @@ function selectValueType(props, propName, componentName) {
|
|
|
64
62
|
* @private
|
|
65
63
|
*/
|
|
66
64
|
function updateOptions(component, propValue) {
|
|
67
|
-
var selectedValue, i
|
|
68
|
-
var options = component
|
|
65
|
+
var selectedValue, i;
|
|
66
|
+
var options = findDOMNode(component).options;
|
|
69
67
|
|
|
70
68
|
if (component.props.multiple) {
|
|
71
69
|
selectedValue = {};
|
|
72
|
-
for (i = 0
|
|
70
|
+
for (i = 0; i < propValue.length; i++) {
|
|
73
71
|
selectedValue['' + propValue[i]] = true;
|
|
74
72
|
}
|
|
75
|
-
for (i = 0
|
|
73
|
+
for (i = 0; i < options.length; i++) {
|
|
76
74
|
var selected = selectedValue.hasOwnProperty(options[i].value);
|
|
77
75
|
if (options[i].selected !== selected) {
|
|
78
76
|
options[i].selected = selected;
|
|
@@ -82,7 +80,7 @@ function updateOptions(component, propValue) {
|
|
|
82
80
|
// Do not set `select.value` as exact behavior isn't consistent across all
|
|
83
81
|
// browsers for all cases.
|
|
84
82
|
selectedValue = '' + propValue;
|
|
85
|
-
for (i = 0
|
|
83
|
+
for (i = 0; i < options.length; i++) {
|
|
86
84
|
if (options[i].value === selectedValue) {
|
|
87
85
|
options[i].selected = true;
|
|
88
86
|
return;
|
|
@@ -115,12 +113,39 @@ var ReactDOMSelect = ReactClass.createClass({
|
|
|
115
113
|
|
|
116
114
|
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
|
|
117
115
|
|
|
116
|
+
statics: {
|
|
117
|
+
valueContextKey: valueContextKey
|
|
118
|
+
},
|
|
119
|
+
|
|
118
120
|
propTypes: {
|
|
119
121
|
defaultValue: selectValueType,
|
|
120
122
|
value: selectValueType
|
|
121
123
|
},
|
|
122
124
|
|
|
123
|
-
|
|
125
|
+
getInitialState: function () {
|
|
126
|
+
// Pass down initial value so initial generated markup has correct
|
|
127
|
+
// `selected` attributes
|
|
128
|
+
var value = LinkedValueUtils.getValue(this.props);
|
|
129
|
+
if (value != null) {
|
|
130
|
+
return { initialValue: value };
|
|
131
|
+
} else {
|
|
132
|
+
return { initialValue: this.props.defaultValue };
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
childContextTypes: (function () {
|
|
137
|
+
var obj = {};
|
|
138
|
+
obj[valueContextKey] = ReactPropTypes.any;
|
|
139
|
+
return obj;
|
|
140
|
+
})(),
|
|
141
|
+
|
|
142
|
+
getChildContext: function () {
|
|
143
|
+
var obj = {};
|
|
144
|
+
obj[valueContextKey] = this.state.initialValue;
|
|
145
|
+
return obj;
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
render: function () {
|
|
124
149
|
// Clone `this.props` so we don't mutate the input.
|
|
125
150
|
var props = assign({}, this.props);
|
|
126
151
|
|
|
@@ -130,21 +155,18 @@ var ReactDOMSelect = ReactClass.createClass({
|
|
|
130
155
|
return select(props, this.props.children);
|
|
131
156
|
},
|
|
132
157
|
|
|
133
|
-
componentWillMount: function() {
|
|
158
|
+
componentWillMount: function () {
|
|
134
159
|
this._pendingUpdate = false;
|
|
135
160
|
},
|
|
136
161
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
} else if (this.props.defaultValue != null) {
|
|
142
|
-
updateOptions(this, this.props.defaultValue);
|
|
143
|
-
}
|
|
162
|
+
componentWillReceiveProps: function (nextProps) {
|
|
163
|
+
// After the initial mount, we control selected-ness manually so don't pass
|
|
164
|
+
// the context value down
|
|
165
|
+
this.setState({ initialValue: null });
|
|
144
166
|
},
|
|
145
167
|
|
|
146
|
-
componentDidUpdate: function(prevProps) {
|
|
147
|
-
var value = LinkedValueUtils.getValue(this);
|
|
168
|
+
componentDidUpdate: function (prevProps) {
|
|
169
|
+
var value = LinkedValueUtils.getValue(this.props);
|
|
148
170
|
if (value != null) {
|
|
149
171
|
this._pendingUpdate = false;
|
|
150
172
|
updateOptions(this, value);
|
|
@@ -159,9 +181,9 @@ var ReactDOMSelect = ReactClass.createClass({
|
|
|
159
181
|
}
|
|
160
182
|
},
|
|
161
183
|
|
|
162
|
-
_handleChange: function(event) {
|
|
184
|
+
_handleChange: function (event) {
|
|
163
185
|
var returnValue;
|
|
164
|
-
var onChange = LinkedValueUtils.getOnChange(this);
|
|
186
|
+
var onChange = LinkedValueUtils.getOnChange(this.props);
|
|
165
187
|
if (onChange) {
|
|
166
188
|
returnValue = onChange.call(this, event);
|
|
167
189
|
}
|
|
@@ -173,4 +195,4 @@ var ReactDOMSelect = ReactClass.createClass({
|
|
|
173
195
|
|
|
174
196
|
});
|
|
175
197
|
|
|
176
|
-
module.exports = ReactDOMSelect;
|
|
198
|
+
module.exports = ReactDOMSelect;
|