react 0.13.3 → 0.14.0-beta1
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 +5 -2
- package/addons.js +7 -0
- package/dist/JSXTransformer.js +4101 -2432
- package/dist/react-with-addons.js +4389 -6277
- package/dist/react-with-addons.min.js +6 -8
- package/dist/react.js +4028 -5697
- package/dist/react.min.js +5 -6
- package/lib/{AutoFocusMixin.js → AutoFocusUtils.js} +16 -5
- 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 +26 -88
- package/lib/ClientReactRootIndex.js +2 -2
- package/lib/DOMChildrenOperations.js +13 -33
- package/lib/DOMProperty.js +86 -147
- package/lib/DOMPropertyOperations.js +91 -67
- 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 +33 -44
- package/lib/EventPropagators.js +23 -26
- package/lib/ExecutionEnvironment.js +4 -8
- package/lib/FallbackCompositionState.js +3 -3
- package/lib/HTMLDOMPropertyConfig.js +15 -20
- package/lib/LinkedStateMixin.js +3 -6
- package/lib/LinkedValueUtils.js +71 -89
- package/lib/Object.assign.js +1 -1
- package/lib/PooledClass.js +20 -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 +26 -28
- package/lib/ReactChildReconciler.js +11 -19
- package/lib/ReactChildren.js +24 -31
- package/lib/ReactClass.js +96 -267
- package/lib/ReactComponent.js +28 -57
- package/lib/ReactComponentBrowserEnvironment.js +4 -8
- package/lib/ReactComponentEnvironment.js +6 -12
- package/lib/ReactComponentWithPureRenderMixin.js +6 -7
- package/lib/ReactCompositeComponent.js +115 -381
- package/lib/ReactCurrentOwner.js +1 -3
- package/lib/ReactDOM.js +4 -2
- package/lib/ReactDOMButton.js +16 -28
- package/lib/ReactDOMClient.js +90 -0
- package/lib/ReactDOMComponent.js +468 -156
- package/lib/ReactDOMIDOperations.js +25 -22
- package/lib/ReactDOMInput.js +79 -108
- package/lib/ReactDOMOption.js +58 -20
- package/lib/ReactDOMSelect.js +95 -83
- package/lib/ReactDOMSelection.js +5 -20
- package/lib/ReactDOMServer.js +24 -0
- package/lib/ReactDOMTextComponent.js +17 -18
- package/lib/ReactDOMTextarea.js +44 -69
- package/lib/ReactDefaultBatchingStrategy.js +9 -13
- package/lib/ReactDefaultInjection.js +20 -76
- package/lib/ReactDefaultPerf.js +36 -69
- package/lib/ReactDefaultPerfAnalysis.js +8 -14
- package/lib/ReactElement.js +26 -120
- package/lib/ReactElementValidator.js +56 -192
- package/lib/ReactEmptyComponent.js +7 -11
- package/lib/ReactErrorUtils.js +3 -3
- package/lib/ReactEventEmitterMixin.js +3 -13
- package/lib/ReactEventListener.js +58 -40
- package/lib/ReactFragment.js +33 -59
- package/lib/ReactInjection.js +1 -1
- package/lib/ReactInputSelection.js +14 -23
- package/lib/ReactInstanceHandles.js +29 -58
- package/lib/ReactInstanceMap.js +5 -5
- package/lib/ReactIsomorphic.js +70 -0
- package/lib/ReactLink.js +2 -4
- package/lib/ReactMarkupChecksum.js +5 -10
- package/lib/ReactMount.js +142 -285
- package/lib/ReactMultiChild.js +19 -45
- package/lib/ReactMultiChildUpdateTypes.js +1 -1
- package/lib/ReactNativeComponent.js +6 -15
- package/lib/ReactNoopUpdateQueue.js +118 -0
- 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 +11 -36
- package/lib/ReactReconciler.js +14 -26
- package/lib/ReactRef.js +5 -8
- package/lib/ReactRootIndex.js +2 -2
- package/lib/ReactServerBatchingStrategy.js +23 -0
- package/lib/ReactServerRendering.js +20 -15
- package/lib/ReactServerRenderingTransaction.js +9 -34
- package/lib/ReactStateSetters.js +6 -6
- package/lib/ReactTestUtils.js +137 -190
- package/lib/ReactTransitionChildMapping.js +5 -7
- package/lib/ReactTransitionEvents.js +5 -5
- package/lib/ReactTransitionGroup.js +30 -52
- package/lib/ReactUpdateQueue.js +69 -107
- package/lib/ReactUpdates.js +26 -81
- package/lib/ReactWithAddons.js +5 -6
- package/lib/SVGDOMPropertyConfig.js +39 -4
- package/lib/SelectEventPlugin.js +31 -33
- package/lib/ServerReactRootIndex.js +2 -2
- package/lib/SimpleEventPlugin.js +138 -130
- package/lib/SyntheticClipboardEvent.js +5 -9
- package/lib/SyntheticCompositionEvent.js +4 -10
- package/lib/SyntheticDragEvent.js +3 -3
- package/lib/SyntheticEvent.js +14 -15
- package/lib/SyntheticFocusEvent.js +3 -3
- package/lib/SyntheticInputEvent.js +4 -10
- package/lib/SyntheticKeyboardEvent.js +6 -6
- package/lib/SyntheticMouseEvent.js +10 -16
- package/lib/SyntheticTouchEvent.js +3 -3
- package/lib/SyntheticUIEvent.js +5 -5
- package/lib/SyntheticWheelEvent.js +13 -17
- package/lib/Transaction.js +22 -28
- 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 +6 -12
- package/lib/containsNode.js +29 -16
- package/lib/createArrayFromMixed.js +17 -16
- package/lib/createNodesFromMarkup.js +6 -8
- package/lib/dangerousStyleValue.js +2 -3
- package/lib/deprecated.js +47 -0
- package/lib/emptyFunction.js +10 -4
- package/lib/emptyObject.js +1 -1
- package/lib/escapeTextContentForBrowser.js +1 -1
- package/lib/findDOMNode.js +7 -27
- package/lib/flattenChildren.js +4 -10
- package/lib/focusNode.js +2 -3
- package/lib/forEachAccumulated.js +3 -3
- package/lib/getActiveElement.js +4 -2
- package/lib/getEventCharCode.js +2 -2
- package/lib/getEventKey.js +1 -1
- package/lib/getEventModifierState.js +1 -2
- package/lib/getEventTarget.js +1 -1
- package/lib/getIteratorFn.js +2 -4
- package/lib/getMarkupWrap.js +18 -40
- 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 +23 -43
- package/lib/invariant.js +8 -12
- package/lib/isEventSupported.js +7 -10
- package/lib/isNode.js +4 -6
- package/lib/isTextInputElement.js +3 -4
- package/lib/isTextNode.js +3 -1
- package/lib/joinClasses.js +3 -3
- 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 +23 -90
- package/lib/update.js +25 -85
- package/lib/validateDOMNesting.js +363 -0
- package/lib/warning.js +15 -17
- package/package.json +3 -3
- package/react.js +53 -1
- package/lib/LocalEventTrapMixin.js +0 -53
- package/lib/MobileSafariClickEventPlugin.js +0 -56
- package/lib/ReactContext.js +0 -74
- package/lib/ReactDOMForm.js +0 -47
- package/lib/ReactDOMIframe.js +0 -43
- package/lib/ReactDOMImg.js +0 -44
- package/lib/ReactLifeCycle.js +0 -35
- package/lib/ReactPutListenerQueue.js +0 -54
- package/lib/createFullPageComponent.js +0 -58
- package/lib/cx.js +0 -52
- package/lib/getReactRootElementInContainer.js +0 -33
|
@@ -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
|
|
@@ -68,6 +61,20 @@ var ReactDOMIDOperations = {
|
|
|
68
61
|
}
|
|
69
62
|
},
|
|
70
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Updates a DOM node with new property values.
|
|
66
|
+
*
|
|
67
|
+
* @param {string} id ID of the node to update.
|
|
68
|
+
* @param {string} name A valid property name.
|
|
69
|
+
* @param {*} value New value of the property.
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
updateAttributeByID: function (id, name, value) {
|
|
73
|
+
var node = ReactMount.getNode(id);
|
|
74
|
+
!!INVALID_PROPERTY_ERRORS.hasOwnProperty(name) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name]) : invariant(false) : undefined;
|
|
75
|
+
DOMPropertyOperations.setValueForAttribute(node, name, value);
|
|
76
|
+
},
|
|
77
|
+
|
|
71
78
|
/**
|
|
72
79
|
* Updates a DOM node to remove a property. This should only be used to remove
|
|
73
80
|
* DOM properties in `DOMProperty`.
|
|
@@ -76,13 +83,9 @@ var ReactDOMIDOperations = {
|
|
|
76
83
|
* @param {string} name A property name to remove, see `DOMProperty`.
|
|
77
84
|
* @internal
|
|
78
85
|
*/
|
|
79
|
-
deletePropertyByID: function(id, name, value) {
|
|
86
|
+
deletePropertyByID: function (id, name, value) {
|
|
80
87
|
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)));
|
|
88
|
+
!!INVALID_PROPERTY_ERRORS.hasOwnProperty(name) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name]) : invariant(false) : undefined;
|
|
86
89
|
DOMPropertyOperations.deleteValueForProperty(node, name, value);
|
|
87
90
|
},
|
|
88
91
|
|
|
@@ -94,7 +97,7 @@ var ReactDOMIDOperations = {
|
|
|
94
97
|
* @param {object} styles Mapping from styles to values.
|
|
95
98
|
* @internal
|
|
96
99
|
*/
|
|
97
|
-
updateStylesByID: function(id, styles) {
|
|
100
|
+
updateStylesByID: function (id, styles) {
|
|
98
101
|
var node = ReactMount.getNode(id);
|
|
99
102
|
CSSPropertyOperations.setValueForStyles(node, styles);
|
|
100
103
|
},
|
|
@@ -106,7 +109,7 @@ var ReactDOMIDOperations = {
|
|
|
106
109
|
* @param {string} html An HTML string.
|
|
107
110
|
* @internal
|
|
108
111
|
*/
|
|
109
|
-
updateInnerHTMLByID: function(id, html) {
|
|
112
|
+
updateInnerHTMLByID: function (id, html) {
|
|
110
113
|
var node = ReactMount.getNode(id);
|
|
111
114
|
setInnerHTML(node, html);
|
|
112
115
|
},
|
|
@@ -118,7 +121,7 @@ var ReactDOMIDOperations = {
|
|
|
118
121
|
* @param {string} content Text content.
|
|
119
122
|
* @internal
|
|
120
123
|
*/
|
|
121
|
-
updateTextContentByID: function(id, content) {
|
|
124
|
+
updateTextContentByID: function (id, content) {
|
|
122
125
|
var node = ReactMount.getNode(id);
|
|
123
126
|
DOMChildrenOperations.updateTextContent(node, content);
|
|
124
127
|
},
|
|
@@ -131,7 +134,7 @@ var ReactDOMIDOperations = {
|
|
|
131
134
|
* @internal
|
|
132
135
|
* @see {Danger.dangerouslyReplaceNodeWithMarkup}
|
|
133
136
|
*/
|
|
134
|
-
dangerouslyReplaceNodeWithMarkupByID: function(id, markup) {
|
|
137
|
+
dangerouslyReplaceNodeWithMarkupByID: function (id, markup) {
|
|
135
138
|
var node = ReactMount.getNode(id);
|
|
136
139
|
DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
|
|
137
140
|
},
|
|
@@ -143,7 +146,7 @@ var ReactDOMIDOperations = {
|
|
|
143
146
|
* @param {array<string>} markup List of markup strings.
|
|
144
147
|
* @internal
|
|
145
148
|
*/
|
|
146
|
-
dangerouslyProcessChildrenUpdates: function(updates, markup) {
|
|
149
|
+
dangerouslyProcessChildrenUpdates: function (updates, markup) {
|
|
147
150
|
for (var i = 0; i < updates.length; i++) {
|
|
148
151
|
updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
|
|
149
152
|
}
|
|
@@ -161,4 +164,4 @@ ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', {
|
|
|
161
164
|
dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates'
|
|
162
165
|
});
|
|
163
166
|
|
|
164
|
-
module.exports = ReactDOMIDOperations;
|
|
167
|
+
module.exports = ReactDOMIDOperations;
|
package/lib/ReactDOMInput.js
CHANGED
|
@@ -11,26 +11,20 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
-
var
|
|
15
|
-
var DOMPropertyOperations = require("./DOMPropertyOperations");
|
|
14
|
+
var ReactDOMIDOperations = require("./ReactDOMIDOperations");
|
|
16
15
|
var LinkedValueUtils = require("./LinkedValueUtils");
|
|
17
|
-
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
18
|
-
var ReactClass = require("./ReactClass");
|
|
19
|
-
var ReactElement = require("./ReactElement");
|
|
20
16
|
var ReactMount = require("./ReactMount");
|
|
21
17
|
var ReactUpdates = require("./ReactUpdates");
|
|
22
18
|
|
|
23
19
|
var assign = require("./Object.assign");
|
|
24
20
|
var invariant = require("./invariant");
|
|
25
21
|
|
|
26
|
-
var input = ReactElement.createFactory('input');
|
|
27
|
-
|
|
28
22
|
var instancesByReactID = {};
|
|
29
23
|
|
|
30
24
|
function forceUpdateIfMounted() {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
if (this._rootNodeID) {
|
|
26
|
+
// DOM component is still mounted; update
|
|
27
|
+
ReactDOMInput.updateWrapper(this);
|
|
34
28
|
}
|
|
35
29
|
}
|
|
36
30
|
|
|
@@ -50,124 +44,101 @@ function forceUpdateIfMounted() {
|
|
|
50
44
|
*
|
|
51
45
|
* @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
|
|
52
46
|
*/
|
|
53
|
-
var ReactDOMInput =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
};
|
|
47
|
+
var ReactDOMInput = {
|
|
48
|
+
getNativeProps: function (inst, props, context) {
|
|
49
|
+
var value = LinkedValueUtils.getValue(props);
|
|
50
|
+
var checked = LinkedValueUtils.getChecked(props);
|
|
51
|
+
|
|
52
|
+
var nativeProps = assign({}, props, {
|
|
53
|
+
defaultChecked: undefined,
|
|
54
|
+
defaultValue: undefined,
|
|
55
|
+
value: value != null ? value : inst._wrapperState.initialValue,
|
|
56
|
+
checked: checked != null ? checked : inst._wrapperState.initialChecked,
|
|
57
|
+
onChange: inst._wrapperState.onChange
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return nativeProps;
|
|
65
61
|
},
|
|
66
62
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
var props = assign({}, this.props);
|
|
70
|
-
|
|
71
|
-
props.defaultChecked = null;
|
|
72
|
-
props.defaultValue = null;
|
|
63
|
+
mountWrapper: function (inst, props) {
|
|
64
|
+
LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner);
|
|
73
65
|
|
|
74
|
-
var
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
props.onChange = this._handleChange;
|
|
66
|
+
var defaultValue = props.defaultValue;
|
|
67
|
+
inst._wrapperState = {
|
|
68
|
+
initialChecked: props.defaultChecked || false,
|
|
69
|
+
initialValue: defaultValue != null ? defaultValue : null,
|
|
70
|
+
onChange: _handleChange.bind(inst)
|
|
71
|
+
};
|
|
81
72
|
|
|
82
|
-
|
|
73
|
+
instancesByReactID[inst._rootNodeID] = inst;
|
|
83
74
|
},
|
|
84
75
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
instancesByReactID[id] = this;
|
|
76
|
+
unmountWrapper: function (inst) {
|
|
77
|
+
delete instancesByReactID[inst._rootNodeID];
|
|
88
78
|
},
|
|
89
79
|
|
|
90
|
-
|
|
91
|
-
var
|
|
92
|
-
var id = ReactMount.getID(rootNode);
|
|
93
|
-
delete instancesByReactID[id];
|
|
94
|
-
},
|
|
80
|
+
updateWrapper: function (inst) {
|
|
81
|
+
var props = inst._currentElement.props;
|
|
95
82
|
|
|
96
|
-
|
|
97
|
-
var
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
rootNode,
|
|
101
|
-
'checked',
|
|
102
|
-
this.props.checked || false
|
|
103
|
-
);
|
|
83
|
+
// TODO: Shouldn't this be getChecked(props)?
|
|
84
|
+
var checked = props.checked;
|
|
85
|
+
if (checked != null) {
|
|
86
|
+
ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'checked', checked || false);
|
|
104
87
|
}
|
|
105
88
|
|
|
106
|
-
var value = LinkedValueUtils.getValue(
|
|
89
|
+
var value = LinkedValueUtils.getValue(props);
|
|
107
90
|
if (value != null) {
|
|
108
91
|
// Cast `value` to a string to ensure the value is set correctly. While
|
|
109
92
|
// browsers typically do this as necessary, jsdom doesn't.
|
|
110
|
-
|
|
93
|
+
ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value);
|
|
111
94
|
}
|
|
112
|
-
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
function _handleChange(event) {
|
|
99
|
+
var props = this._currentElement.props;
|
|
100
|
+
|
|
101
|
+
var returnValue = LinkedValueUtils.executeOnChange(props, event);
|
|
102
|
+
|
|
103
|
+
// Here we use asap to wait until all updates have propagated, which
|
|
104
|
+
// is important when using controlled components within layers:
|
|
105
|
+
// https://github.com/facebook/react/issues/1698
|
|
106
|
+
ReactUpdates.asap(forceUpdateIfMounted, this);
|
|
113
107
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
var
|
|
117
|
-
|
|
118
|
-
|
|
108
|
+
var name = props.name;
|
|
109
|
+
if (props.type === 'radio' && name != null) {
|
|
110
|
+
var rootNode = ReactMount.getNode(this._rootNodeID);
|
|
111
|
+
var queryRoot = rootNode;
|
|
112
|
+
|
|
113
|
+
while (queryRoot.parentNode) {
|
|
114
|
+
queryRoot = queryRoot.parentNode;
|
|
119
115
|
}
|
|
120
|
-
// Here we use asap to wait until all updates have propagated, which
|
|
121
|
-
// is important when using controlled components within layers:
|
|
122
|
-
// https://github.com/facebook/react/issues/1698
|
|
123
|
-
ReactUpdates.asap(forceUpdateIfMounted, this);
|
|
124
|
-
|
|
125
|
-
var name = this.props.name;
|
|
126
|
-
if (this.props.type === 'radio' && name != null) {
|
|
127
|
-
var rootNode = this.getDOMNode();
|
|
128
|
-
var queryRoot = rootNode;
|
|
129
|
-
|
|
130
|
-
while (queryRoot.parentNode) {
|
|
131
|
-
queryRoot = queryRoot.parentNode;
|
|
132
|
-
}
|
|
133
116
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
otherNode.form !== rootNode.form) {
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
var otherID = ReactMount.getID(otherNode);
|
|
150
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
151
|
-
otherID,
|
|
152
|
-
'ReactDOMInput: Mixing React and non-React radio inputs with the ' +
|
|
153
|
-
'same `name` is not supported.'
|
|
154
|
-
) : invariant(otherID));
|
|
155
|
-
var otherInstance = instancesByReactID[otherID];
|
|
156
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
157
|
-
otherInstance,
|
|
158
|
-
'ReactDOMInput: Unknown radio button ID %s.',
|
|
159
|
-
otherID
|
|
160
|
-
) : invariant(otherInstance));
|
|
161
|
-
// If this is a controlled radio button group, forcing the input that
|
|
162
|
-
// was previously checked to update will cause it to be come re-checked
|
|
163
|
-
// as appropriate.
|
|
164
|
-
ReactUpdates.asap(forceUpdateIfMounted, otherInstance);
|
|
117
|
+
// If `rootNode.form` was non-null, then we could try `form.elements`,
|
|
118
|
+
// but that sometimes behaves strangely in IE8. We could also try using
|
|
119
|
+
// `form.getElementsByName`, but that will only return direct children
|
|
120
|
+
// and won't include inputs that use the HTML5 `form=` attribute. Since
|
|
121
|
+
// the input might not even be in a form, let's just use the global
|
|
122
|
+
// `querySelectorAll` to ensure we don't miss anything.
|
|
123
|
+
var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
|
|
124
|
+
|
|
125
|
+
for (var i = 0; i < group.length; i++) {
|
|
126
|
+
var otherNode = group[i];
|
|
127
|
+
if (otherNode === rootNode || otherNode.form !== rootNode.form) {
|
|
128
|
+
continue;
|
|
165
129
|
}
|
|
130
|
+
var otherID = ReactMount.getID(otherNode);
|
|
131
|
+
!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;
|
|
132
|
+
var otherInstance = instancesByReactID[otherID];
|
|
133
|
+
!otherInstance ? 'production' !== process.env.NODE_ENV ? invariant(false, 'ReactDOMInput: Unknown radio button ID %s.', otherID) : invariant(false) : undefined;
|
|
134
|
+
// If this is a controlled radio button group, forcing the input that
|
|
135
|
+
// was previously checked to update will cause it to be come re-checked
|
|
136
|
+
// as appropriate.
|
|
137
|
+
ReactUpdates.asap(forceUpdateIfMounted, otherInstance);
|
|
166
138
|
}
|
|
167
|
-
|
|
168
|
-
return returnValue;
|
|
169
139
|
}
|
|
170
140
|
|
|
171
|
-
|
|
141
|
+
return returnValue;
|
|
142
|
+
}
|
|
172
143
|
|
|
173
|
-
module.exports = ReactDOMInput;
|
|
144
|
+
module.exports = ReactDOMInput;
|
package/lib/ReactDOMOption.js
CHANGED
|
@@ -11,38 +11,76 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
-
var
|
|
15
|
-
var
|
|
16
|
-
var ReactElement = require("./ReactElement");
|
|
14
|
+
var ReactChildren = require("./ReactChildren");
|
|
15
|
+
var ReactDOMSelect = require("./ReactDOMSelect");
|
|
17
16
|
|
|
17
|
+
var assign = require("./Object.assign");
|
|
18
18
|
var warning = require("./warning");
|
|
19
19
|
|
|
20
|
-
var
|
|
20
|
+
var valueContextKey = ReactDOMSelect.valueContextKey;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Implements an <option> native component that warns when `selected` is set.
|
|
24
24
|
*/
|
|
25
|
-
var ReactDOMOption =
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
var ReactDOMOption = {
|
|
26
|
+
mountWrapper: function (inst, props, context) {
|
|
27
|
+
// TODO (yungsters): Remove support for `selected` in <option>.
|
|
28
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
29
|
+
'production' !== process.env.NODE_ENV ? warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : undefined;
|
|
30
|
+
}
|
|
28
31
|
|
|
29
|
-
|
|
32
|
+
// Look up whether this option is 'selected' via context
|
|
33
|
+
var selectValue = context[valueContextKey];
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
// If context key is null (e.g., no specified value or after initial mount)
|
|
36
|
+
// or missing (e.g., for <datalist>), we don't change props.selected
|
|
37
|
+
var selected = null;
|
|
38
|
+
if (selectValue != null) {
|
|
39
|
+
selected = false;
|
|
40
|
+
if (Array.isArray(selectValue)) {
|
|
41
|
+
// multiple
|
|
42
|
+
for (var i = 0; i < selectValue.length; i++) {
|
|
43
|
+
if ('' + selectValue[i] === '' + props.value) {
|
|
44
|
+
selected = true;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
selected = '' + selectValue === '' + props.value;
|
|
50
|
+
}
|
|
39
51
|
}
|
|
52
|
+
|
|
53
|
+
inst._wrapperState = { selected: selected };
|
|
40
54
|
},
|
|
41
55
|
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
getNativeProps: function (inst, props, context) {
|
|
57
|
+
var nativeProps = assign({ selected: undefined, children: undefined }, props);
|
|
58
|
+
|
|
59
|
+
// Read state only from initial mount because <select> updates value
|
|
60
|
+
// manually; we need the initial state only for server rendering
|
|
61
|
+
if (inst._wrapperState.selected != null) {
|
|
62
|
+
nativeProps.selected = inst._wrapperState.selected;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
var content = '';
|
|
66
|
+
|
|
67
|
+
// Flatten children and warn if they aren't strings or numbers;
|
|
68
|
+
// invalid types are ignored.
|
|
69
|
+
ReactChildren.forEach(props.children, function (child) {
|
|
70
|
+
if (child == null) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (typeof child === 'string' || typeof child === 'number') {
|
|
74
|
+
content += child;
|
|
75
|
+
} else {
|
|
76
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'Only strings and numbers are supported as <option> children.') : undefined;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
nativeProps.children = content;
|
|
81
|
+
return nativeProps;
|
|
44
82
|
}
|
|
45
83
|
|
|
46
|
-
}
|
|
84
|
+
};
|
|
47
85
|
|
|
48
|
-
module.exports = ReactDOMOption;
|
|
86
|
+
module.exports = ReactDOMOption;
|
package/lib/ReactDOMSelect.js
CHANGED
|
@@ -11,68 +11,77 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
-
var AutoFocusMixin = require("./AutoFocusMixin");
|
|
15
14
|
var LinkedValueUtils = require("./LinkedValueUtils");
|
|
16
|
-
var
|
|
17
|
-
var ReactClass = require("./ReactClass");
|
|
18
|
-
var ReactElement = require("./ReactElement");
|
|
15
|
+
var ReactMount = require("./ReactMount");
|
|
19
16
|
var ReactUpdates = require("./ReactUpdates");
|
|
20
17
|
|
|
21
18
|
var assign = require("./Object.assign");
|
|
19
|
+
var warning = require("./warning");
|
|
22
20
|
|
|
23
|
-
var
|
|
21
|
+
var valueContextKey = '__ReactDOMSelect_value$' + Math.random().toString(36).slice(2);
|
|
24
22
|
|
|
25
23
|
function updateOptionsIfPendingUpdateAndMounted() {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
var
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
if (this._wrapperState.pendingUpdate && this._rootNodeID) {
|
|
25
|
+
this._wrapperState.pendingUpdate = false;
|
|
26
|
+
|
|
27
|
+
var props = this._currentElement.props;
|
|
28
|
+
var value = LinkedValueUtils.getValue(props);
|
|
29
|
+
|
|
30
|
+
if (value != null) {
|
|
31
|
+
updateOptions(this, props, value);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getDeclarationErrorAddendum(owner) {
|
|
37
|
+
if (owner) {
|
|
38
|
+
var name = owner.getName();
|
|
39
|
+
if (name) {
|
|
40
|
+
return ' Check the render method of `' + name + '`.';
|
|
32
41
|
}
|
|
33
42
|
}
|
|
43
|
+
return '';
|
|
34
44
|
}
|
|
35
45
|
|
|
46
|
+
var valuePropNames = ['value', 'defaultValue'];
|
|
47
|
+
|
|
36
48
|
/**
|
|
37
49
|
* Validation function for `value` and `defaultValue`.
|
|
38
50
|
* @private
|
|
39
51
|
*/
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
("`multiple` is true.")
|
|
49
|
-
);
|
|
52
|
+
function checkSelectPropTypes(inst, props) {
|
|
53
|
+
var owner = inst._currentElement._owner;
|
|
54
|
+
LinkedValueUtils.checkPropTypes('select', props, owner);
|
|
55
|
+
|
|
56
|
+
for (var i = 0; i < valuePropNames.length; i++) {
|
|
57
|
+
var propName = valuePropNames[i];
|
|
58
|
+
if (props[propName] == null) {
|
|
59
|
+
continue;
|
|
50
60
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
("value if `multiple` is false.")
|
|
56
|
-
);
|
|
61
|
+
if (props.multiple) {
|
|
62
|
+
'production' !== process.env.NODE_ENV ? warning(Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)) : undefined;
|
|
63
|
+
} else {
|
|
64
|
+
'production' !== process.env.NODE_ENV ? 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;
|
|
57
65
|
}
|
|
58
66
|
}
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
/**
|
|
62
|
-
* @param {
|
|
70
|
+
* @param {ReactDOMComponent} inst
|
|
71
|
+
* @param {boolean} multiple
|
|
63
72
|
* @param {*} propValue A stringable (with `multiple`, a list of stringables).
|
|
64
73
|
* @private
|
|
65
74
|
*/
|
|
66
|
-
function updateOptions(
|
|
67
|
-
var selectedValue, i
|
|
68
|
-
var options =
|
|
75
|
+
function updateOptions(inst, multiple, propValue) {
|
|
76
|
+
var selectedValue, i;
|
|
77
|
+
var options = ReactMount.getNode(inst._rootNodeID).options;
|
|
69
78
|
|
|
70
|
-
if (
|
|
79
|
+
if (multiple) {
|
|
71
80
|
selectedValue = {};
|
|
72
|
-
for (i = 0
|
|
81
|
+
for (i = 0; i < propValue.length; i++) {
|
|
73
82
|
selectedValue['' + propValue[i]] = true;
|
|
74
83
|
}
|
|
75
|
-
for (i = 0
|
|
84
|
+
for (i = 0; i < options.length; i++) {
|
|
76
85
|
var selected = selectedValue.hasOwnProperty(options[i].value);
|
|
77
86
|
if (options[i].selected !== selected) {
|
|
78
87
|
options[i].selected = selected;
|
|
@@ -82,7 +91,7 @@ function updateOptions(component, propValue) {
|
|
|
82
91
|
// Do not set `select.value` as exact behavior isn't consistent across all
|
|
83
92
|
// browsers for all cases.
|
|
84
93
|
selectedValue = '' + propValue;
|
|
85
|
-
for (i = 0
|
|
94
|
+
for (i = 0; i < options.length; i++) {
|
|
86
95
|
if (options[i].value === selectedValue) {
|
|
87
96
|
options[i].selected = true;
|
|
88
97
|
return;
|
|
@@ -109,68 +118,71 @@ function updateOptions(component, propValue) {
|
|
|
109
118
|
* If `defaultValue` is provided, any options with the supplied values will be
|
|
110
119
|
* selected.
|
|
111
120
|
*/
|
|
112
|
-
var ReactDOMSelect =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
value: selectValueType
|
|
121
|
+
var ReactDOMSelect = {
|
|
122
|
+
valueContextKey: valueContextKey,
|
|
123
|
+
|
|
124
|
+
getNativeProps: function (inst, props, context) {
|
|
125
|
+
return assign({}, props, {
|
|
126
|
+
onChange: inst._wrapperState.onChange,
|
|
127
|
+
value: undefined
|
|
128
|
+
});
|
|
121
129
|
},
|
|
122
130
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
props.onChange = this._handleChange;
|
|
128
|
-
props.value = null;
|
|
131
|
+
mountWrapper: function (inst, props) {
|
|
132
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
133
|
+
checkSelectPropTypes(inst, props);
|
|
134
|
+
}
|
|
129
135
|
|
|
130
|
-
|
|
136
|
+
var value = LinkedValueUtils.getValue(props);
|
|
137
|
+
inst._wrapperState = {
|
|
138
|
+
pendingUpdate: false,
|
|
139
|
+
initialValue: value != null ? value : props.defaultValue,
|
|
140
|
+
onChange: _handleChange.bind(inst),
|
|
141
|
+
wasMultiple: Boolean(props.multiple)
|
|
142
|
+
};
|
|
131
143
|
},
|
|
132
144
|
|
|
133
|
-
|
|
134
|
-
|
|
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;
|
|
135
151
|
},
|
|
136
152
|
|
|
137
|
-
|
|
138
|
-
var
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
153
|
+
postUpdateWrapper: function (inst) {
|
|
154
|
+
var props = inst._currentElement.props;
|
|
155
|
+
|
|
156
|
+
// After the initial mount, we control selected-ness manually so don't pass
|
|
157
|
+
// the context value down
|
|
158
|
+
inst._wrapperState.initialValue = undefined;
|
|
159
|
+
|
|
160
|
+
var wasMultiple = inst._wrapperState.wasMultiple;
|
|
161
|
+
inst._wrapperState.wasMultiple = Boolean(props.multiple);
|
|
145
162
|
|
|
146
|
-
|
|
147
|
-
var value = LinkedValueUtils.getValue(this);
|
|
163
|
+
var value = LinkedValueUtils.getValue(props);
|
|
148
164
|
if (value != null) {
|
|
149
|
-
|
|
150
|
-
updateOptions(
|
|
151
|
-
} else if (
|
|
165
|
+
inst._wrapperState.pendingUpdate = false;
|
|
166
|
+
updateOptions(inst, Boolean(props.multiple), value);
|
|
167
|
+
} else if (wasMultiple !== Boolean(props.multiple)) {
|
|
152
168
|
// For simplicity, reapply `defaultValue` if `multiple` is toggled.
|
|
153
|
-
if (
|
|
154
|
-
updateOptions(
|
|
169
|
+
if (props.defaultValue != null) {
|
|
170
|
+
updateOptions(inst, Boolean(props.multiple), props.defaultValue);
|
|
155
171
|
} else {
|
|
156
172
|
// Revert the select back to its default unselected state.
|
|
157
|
-
updateOptions(
|
|
173
|
+
updateOptions(inst, Boolean(props.multiple), props.multiple ? [] : '');
|
|
158
174
|
}
|
|
159
175
|
}
|
|
160
|
-
},
|
|
161
|
-
|
|
162
|
-
_handleChange: function(event) {
|
|
163
|
-
var returnValue;
|
|
164
|
-
var onChange = LinkedValueUtils.getOnChange(this);
|
|
165
|
-
if (onChange) {
|
|
166
|
-
returnValue = onChange.call(this, event);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
this._pendingUpdate = true;
|
|
170
|
-
ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this);
|
|
171
|
-
return returnValue;
|
|
172
176
|
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
function _handleChange(event) {
|
|
180
|
+
var props = this._currentElement.props;
|
|
181
|
+
var returnValue = LinkedValueUtils.executeOnChange(props, event);
|
|
173
182
|
|
|
174
|
-
|
|
183
|
+
this._wrapperState.pendingUpdate = true;
|
|
184
|
+
ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this);
|
|
185
|
+
return returnValue;
|
|
186
|
+
}
|
|
175
187
|
|
|
176
|
-
module.exports = ReactDOMSelect;
|
|
188
|
+
module.exports = ReactDOMSelect;
|