prevent firefox marking required textareas invalid (#16578)
* prevent firefox marking required textareas invalid Bug was caused by an IE10/IE11 bugfix dealing with the placeholder attribute and textContent. Solved by avoiding the IE bugfix when textContent was empty. Closes #16402 * more explicit conditional check for textContent re: @philipp-spiess code review * clarify textarea test fixture's expected result better describe the behavior we are testing for re: @philipp-spiess code review
halvves committed
Sep 18, 2019 at 14:38 UTC
a5df18a9e5d7cc70c30ce144dcc291e9f64cb451
3 files changed
+69
-1
fixtures/dom/src/components/fixtures/textareas/index.js
+39
@@ -1,3 +1,4 @@
1
+import Fixture from '../../Fixture';
2
import FixtureSet from '../../FixtureSet';
3
import TestCase from '../../TestCase';
4
@@ -39,6 +40,44 @@ export default class TextAreaFixtures extends React.Component {
40
<textarea placeholder="Hello, world" />
41
</div>
42
</TestCase>
43
+
44
+ <TestCase
45
+ title="Required Textareas"
46
+ affectedBrowsers="Firefox"
47
+ relatedIssues="16402">
48
+ <TestCase.Steps>
49
+ <li>View this test in Firefox</li>
50
+ </TestCase.Steps>
51
+
52
+ <TestCase.ExpectedResult>
53
+ You should{' '}
54
+ <b>
55
+ <i>not</i>
56
+ </b>{' '}
57
+ see a red aura on initial page load, indicating the textarea is
58
+ invalid.
59
+ <br />
60
+ This aura looks roughly like:
61
+ <textarea style={{boxShadow: '0 0 1px 1px red', marginLeft: 8}} />
62
+ </TestCase.ExpectedResult>
63
+
64
+ <Fixture>
65
+ <form className="control-box">
66
+ <fieldset>
67
+ <legend>Empty value prop string</legend>
68
+ <textarea value="" required={true} />
69
+ </fieldset>
70
+ <fieldset>
71
+ <legend>No value prop</legend>
72
+ <textarea required={true} />
73
+ </fieldset>
74
+ <fieldset>
75
+ <legend>Empty defaultValue prop string</legend>
76
+ <textarea required={true} defaultValue="" />
77
+ </fieldset>
78
+ </form>
79
+ </Fixture>
80
+ </TestCase>
81
</FixtureSet>
82
);
83
}
packages/react-dom/src/__tests__/ReactDOMTextarea-test.js
+27
@@ -126,6 +126,33 @@ describe('ReactDOMTextarea', () => {
126
expect(node.value).toEqual('gorilla');
127
});
128
129
+ it('will not initially assign an empty value (covers case where firefox throws a validation error when required attribute is set)', () => {
130
+ const container = document.createElement('div');
131
+
132
+ let counter = 0;
133
+ const originalCreateElement = document.createElement;
134
+ spyOnDevAndProd(document, 'createElement').and.callFake(function(type) {
135
+ const el = originalCreateElement.apply(this, arguments);
136
+ let value = '';
137
+ if (type === 'textarea') {
138
+ Object.defineProperty(el, 'value', {
139
+ get: function() {
140
+ return value;
141
+ },
142
+ set: function(val) {
143
+ value = '' + val;
144
+ counter++;
145
+ },
146
+ });
147
+ }
148
+ return el;
149
+ });
150
+
151
+ ReactDOM.render(<textarea value="" readOnly={true} />, container);
152
+
153
+ expect(counter).toEqual(0);
154
+ });
155
+
156
it('should render defaultValue for SSR', () => {
157
const markup = ReactDOMServer.renderToString(<textarea defaultValue="1" />);
158
const div = document.createElement('div');
packages/react-dom/src/client/ReactDOMTextarea.js
+3
-1
@@ -157,7 +157,9 @@ export function postMountWrapper(element: Element, props: Object) {
157
// will populate textContent as well.
158
// https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
159
if (textContent === node._wrapperState.initialValue) {
160
- node.value = textContent;
160
+ if (textContent !== '' && textContent !== null) {
161
+ node.value = textContent;
162
+ }
163
}
164
}
165