mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Convert ReactDOMTextarea to not be a wrapper
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var AutoFocusUtils = require('AutoFocusUtils');
|
||||
var ReactDOMIDOperations = require('ReactDOMIDOperations');
|
||||
var LinkedValueUtils = require('LinkedValueUtils');
|
||||
var ReactMount = require('ReactMount');
|
||||
@@ -78,15 +77,6 @@ var ReactDOMInput = {
|
||||
instancesByReactID[inst._rootNodeID] = inst;
|
||||
},
|
||||
|
||||
postMountWrapper: function(inst, transaction, props) {
|
||||
if (props.autoFocus) {
|
||||
transaction.getReactMountReady().enqueue(
|
||||
AutoFocusUtils.focusDOMComponent,
|
||||
inst
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
unmountWrapper: function(inst) {
|
||||
delete instancesByReactID[inst._rootNodeID];
|
||||
},
|
||||
|
||||
@@ -11,26 +11,18 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var AutoFocusUtils = require('AutoFocusUtils');
|
||||
var DOMPropertyOperations = require('DOMPropertyOperations');
|
||||
var LinkedValueUtils = require('LinkedValueUtils');
|
||||
var ReactBrowserComponentMixin = require('ReactBrowserComponentMixin');
|
||||
var ReactClass = require('ReactClass');
|
||||
var ReactElement = require('ReactElement');
|
||||
var ReactInstanceMap = require('ReactInstanceMap');
|
||||
var ReactDOMIDOperations = require('ReactDOMIDOperations');
|
||||
var ReactUpdates = require('ReactUpdates');
|
||||
|
||||
var assign = require('Object.assign');
|
||||
var findDOMNode = require('findDOMNode');
|
||||
var invariant = require('invariant');
|
||||
|
||||
var warning = require('warning');
|
||||
|
||||
var textarea = ReactElement.createFactory('textarea');
|
||||
|
||||
function forceUpdateIfMounted() {
|
||||
if (this.isMounted()) {
|
||||
this.forceUpdate();
|
||||
if (this._rootNodeID) {
|
||||
// DOM component is still mounted; update
|
||||
ReactDOMTextarea.updateWrapper(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,24 +41,35 @@ function forceUpdateIfMounted() {
|
||||
* The rendered element will be initialized with an empty value, the prop
|
||||
* `defaultValue` if specified, or the children content (deprecated).
|
||||
*/
|
||||
var ReactDOMTextarea = ReactClass.createClass({
|
||||
displayName: 'ReactDOMTextarea',
|
||||
tagName: 'TEXTAREA',
|
||||
|
||||
mixins: [AutoFocusUtils.Mixin, ReactBrowserComponentMixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
LinkedValueUtils.checkPropTypes(
|
||||
'textarea',
|
||||
this.props,
|
||||
ReactInstanceMap.get(this)._currentElement._owner
|
||||
var ReactDOMTextarea = {
|
||||
getNativeProps: function(inst, props, context) {
|
||||
invariant(
|
||||
props.dangerouslySetInnerHTML == null,
|
||||
'`dangerouslySetInnerHTML` does not make sense on <textarea>.'
|
||||
);
|
||||
|
||||
// Always set children to the same thing. In IE9, the selection range will
|
||||
// get reset if `textContent` is mutated.
|
||||
var nativeProps = assign({}, props, {
|
||||
defaultValue: undefined,
|
||||
value: undefined,
|
||||
children: inst._wrapperState.initialValue,
|
||||
onChange: inst._wrapperState.onChange,
|
||||
});
|
||||
|
||||
return nativeProps;
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var defaultValue = this.props.defaultValue;
|
||||
mountWrapper: function(inst, props) {
|
||||
LinkedValueUtils.checkPropTypes(
|
||||
'textarea',
|
||||
props,
|
||||
inst._currentElement._owner
|
||||
);
|
||||
|
||||
var defaultValue = props.defaultValue;
|
||||
// TODO (yungsters): Remove support for children content in <textarea>.
|
||||
var children = this.props.children;
|
||||
var children = props.children;
|
||||
if (children != null) {
|
||||
if (__DEV__) {
|
||||
warning(
|
||||
@@ -92,50 +95,38 @@ var ReactDOMTextarea = ReactClass.createClass({
|
||||
if (defaultValue == null) {
|
||||
defaultValue = '';
|
||||
}
|
||||
var value = LinkedValueUtils.getValue(this.props);
|
||||
return {
|
||||
var value = LinkedValueUtils.getValue(props);
|
||||
|
||||
inst._wrapperState = {
|
||||
// We save the initial value so that `ReactDOMComponent` doesn't update
|
||||
// `textContent` (unnecessary since we update value).
|
||||
// The initial value can be a boolean or object so that's why it's
|
||||
// forced to be a string.
|
||||
initialValue: '' + (value != null ? value : defaultValue),
|
||||
onChange: _handleChange.bind(inst),
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// Clone `this.props` so we don't mutate the input.
|
||||
var props = assign({}, this.props);
|
||||
|
||||
invariant(
|
||||
props.dangerouslySetInnerHTML == null,
|
||||
'`dangerouslySetInnerHTML` does not make sense on <textarea>.'
|
||||
);
|
||||
|
||||
props.defaultValue = null;
|
||||
props.value = null;
|
||||
props.onChange = this._handleChange;
|
||||
|
||||
// Always set children to the same thing. In IE9, the selection range will
|
||||
// get reset if `textContent` is mutated.
|
||||
return textarea(props, this.state.initialValue);
|
||||
},
|
||||
|
||||
componentDidUpdate: function(prevProps, prevState, prevContext) {
|
||||
var value = LinkedValueUtils.getValue(this.props);
|
||||
updateWrapper: function(inst) {
|
||||
var props = inst._currentElement.props;
|
||||
var value = LinkedValueUtils.getValue(props);
|
||||
if (value != null) {
|
||||
var rootNode = findDOMNode(this);
|
||||
// Cast `value` to a string to ensure the value is set correctly. While
|
||||
// browsers typically do this as necessary, jsdom doesn't.
|
||||
DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value);
|
||||
ReactDOMIDOperations.updatePropertyByID(
|
||||
inst._rootNodeID,
|
||||
'value',
|
||||
'' + value
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
_handleChange: function(event) {
|
||||
var returnValue = LinkedValueUtils.executeOnChange(this.props, event);
|
||||
ReactUpdates.asap(forceUpdateIfMounted, this);
|
||||
return returnValue;
|
||||
},
|
||||
|
||||
});
|
||||
function _handleChange(event) {
|
||||
var props = this._currentElement.props;
|
||||
var returnValue = LinkedValueUtils.executeOnChange(props, event);
|
||||
ReactUpdates.asap(forceUpdateIfMounted, this);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
module.exports = ReactDOMTextarea;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var AutoFocusUtils = require('AutoFocusUtils');
|
||||
var CSSPropertyOperations = require('CSSPropertyOperations');
|
||||
var DOMProperty = require('DOMProperty');
|
||||
var DOMPropertyOperations = require('DOMPropertyOperations');
|
||||
@@ -21,6 +22,7 @@ var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');
|
||||
var ReactComponentBrowserEnvironment =
|
||||
require('ReactComponentBrowserEnvironment');
|
||||
var ReactDOMInput = require('ReactDOMInput');
|
||||
var ReactDOMTextarea = require('ReactDOMTextarea');
|
||||
var ReactMount = require('ReactMount');
|
||||
var ReactMultiChild = require('ReactMultiChild');
|
||||
var ReactPerf = require('ReactPerf');
|
||||
@@ -286,6 +288,10 @@ ReactDOMComponent.Mixin = {
|
||||
ReactDOMInput.mountWrapper(this, props);
|
||||
props = ReactDOMInput.getNativeProps(this, props, context);
|
||||
break;
|
||||
case 'textarea':
|
||||
ReactDOMTextarea.mountWrapper(this, props);
|
||||
props = ReactDOMTextarea.getNativeProps(this, props, context);
|
||||
break;
|
||||
}
|
||||
|
||||
assertValidProps(this, props);
|
||||
@@ -304,7 +310,13 @@ ReactDOMComponent.Mixin = {
|
||||
|
||||
switch (this._tag) {
|
||||
case 'input':
|
||||
ReactDOMInput.postMountWrapper(this, transaction, props);
|
||||
case 'textarea':
|
||||
if (props.autoFocus) {
|
||||
transaction.getReactMountReady().enqueue(
|
||||
AutoFocusUtils.focusDOMComponent,
|
||||
this
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -458,6 +470,11 @@ ReactDOMComponent.Mixin = {
|
||||
lastProps = ReactDOMInput.getNativeProps(this, lastProps);
|
||||
nextProps = ReactDOMInput.getNativeProps(this, nextProps);
|
||||
break;
|
||||
case 'textarea':
|
||||
ReactDOMTextarea.updateWrapper(this);
|
||||
lastProps = ReactDOMTextarea.getNativeProps(this, lastProps);
|
||||
nextProps = ReactDOMTextarea.getNativeProps(this, nextProps);
|
||||
break;
|
||||
}
|
||||
|
||||
assertValidProps(this, nextProps);
|
||||
@@ -656,6 +673,9 @@ ReactDOMComponent.Mixin = {
|
||||
case 'input':
|
||||
ReactDOMInput.unmountWrapper(this);
|
||||
break;
|
||||
case 'textarea':
|
||||
ReactDOMTextarea.unmountWrapper(this);
|
||||
break;
|
||||
case 'html':
|
||||
case 'head':
|
||||
case 'body':
|
||||
|
||||
@@ -31,7 +31,6 @@ var ReactDOMIDOperations = require('ReactDOMIDOperations');
|
||||
var ReactDOMIframe = require('ReactDOMIframe');
|
||||
var ReactDOMOption = require('ReactDOMOption');
|
||||
var ReactDOMSelect = require('ReactDOMSelect');
|
||||
var ReactDOMTextarea = require('ReactDOMTextarea');
|
||||
var ReactDOMTextComponent = require('ReactDOMTextComponent');
|
||||
var ReactElement = require('ReactElement');
|
||||
var ReactEventListener = require('ReactEventListener');
|
||||
@@ -117,7 +116,6 @@ function inject() {
|
||||
'img': ReactDOMImg,
|
||||
'option': ReactDOMOption,
|
||||
'select': ReactDOMSelect,
|
||||
'textarea': ReactDOMTextarea,
|
||||
});
|
||||
|
||||
ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
|
||||
|
||||
Reference in New Issue
Block a user