Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81165 views
1
/**
2
* Copyright 2013-2014, 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 ReactDOMTextarea
10
*/
11
12
"use strict";
13
14
var AutoFocusMixin = require('AutoFocusMixin');
15
var DOMPropertyOperations = require('DOMPropertyOperations');
16
var LinkedValueUtils = require('LinkedValueUtils');
17
var ReactBrowserComponentMixin = require('ReactBrowserComponentMixin');
18
var ReactCompositeComponent = require('ReactCompositeComponent');
19
var ReactElement = require('ReactElement');
20
var ReactDOM = require('ReactDOM');
21
var ReactUpdates = require('ReactUpdates');
22
23
var assign = require('Object.assign');
24
var invariant = require('invariant');
25
26
var warning = require('warning');
27
28
// Store a reference to the <textarea> `ReactDOMComponent`. TODO: use string
29
var textarea = ReactElement.createFactory(ReactDOM.textarea.type);
30
31
function forceUpdateIfMounted() {
32
/*jshint validthis:true */
33
if (this.isMounted()) {
34
this.forceUpdate();
35
}
36
}
37
38
/**
39
* Implements a <textarea> native component that allows setting `value`, and
40
* `defaultValue`. This differs from the traditional DOM API because value is
41
* usually set as PCDATA children.
42
*
43
* If `value` is not supplied (or null/undefined), user actions that affect the
44
* value will trigger updates to the element.
45
*
46
* If `value` is supplied (and not null/undefined), the rendered element will
47
* not trigger updates to the element. Instead, the `value` prop must change in
48
* order for the rendered element to be updated.
49
*
50
* The rendered element will be initialized with an empty value, the prop
51
* `defaultValue` if specified, or the children content (deprecated).
52
*/
53
var ReactDOMTextarea = ReactCompositeComponent.createClass({
54
displayName: 'ReactDOMTextarea',
55
56
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
57
58
getInitialState: function() {
59
var defaultValue = this.props.defaultValue;
60
// TODO (yungsters): Remove support for children content in <textarea>.
61
var children = this.props.children;
62
if (children != null) {
63
if (__DEV__) {
64
warning(
65
false,
66
'Use the `defaultValue` or `value` props instead of setting ' +
67
'children on <textarea>.'
68
);
69
}
70
invariant(
71
defaultValue == null,
72
'If you supply `defaultValue` on a <textarea>, do not pass children.'
73
);
74
if (Array.isArray(children)) {
75
invariant(
76
children.length <= 1,
77
'<textarea> can only have at most one child.'
78
);
79
children = children[0];
80
}
81
82
defaultValue = '' + children;
83
}
84
if (defaultValue == null) {
85
defaultValue = '';
86
}
87
var value = LinkedValueUtils.getValue(this);
88
return {
89
// We save the initial value so that `ReactDOMComponent` doesn't update
90
// `textContent` (unnecessary since we update value).
91
// The initial value can be a boolean or object so that's why it's
92
// forced to be a string.
93
initialValue: '' + (value != null ? value : defaultValue)
94
};
95
},
96
97
render: function() {
98
// Clone `this.props` so we don't mutate the input.
99
var props = assign({}, this.props);
100
101
invariant(
102
props.dangerouslySetInnerHTML == null,
103
'`dangerouslySetInnerHTML` does not make sense on <textarea>.'
104
);
105
106
props.defaultValue = null;
107
props.value = null;
108
props.onChange = this._handleChange;
109
110
// Always set children to the same thing. In IE9, the selection range will
111
// get reset if `textContent` is mutated.
112
return textarea(props, this.state.initialValue);
113
},
114
115
componentDidUpdate: function(prevProps, prevState, prevContext) {
116
var value = LinkedValueUtils.getValue(this);
117
if (value != null) {
118
var rootNode = this.getDOMNode();
119
// Cast `value` to a string to ensure the value is set correctly. While
120
// browsers typically do this as necessary, jsdom doesn't.
121
DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value);
122
}
123
},
124
125
_handleChange: function(event) {
126
var returnValue;
127
var onChange = LinkedValueUtils.getOnChange(this);
128
if (onChange) {
129
returnValue = onChange.call(this, event);
130
}
131
ReactUpdates.asap(forceUpdateIfMounted, this);
132
return returnValue;
133
}
134
135
});
136
137
module.exports = ReactDOMTextarea;
138
139