Skip to content

Commit a5df18a

Browse files
halvvesnhunzaker
authored andcommitted
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
1 parent f818af9 commit a5df18a

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

fixtures/dom/src/components/fixtures/textareas/index.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Fixture from '../../Fixture';
12
import FixtureSet from '../../FixtureSet';
23
import TestCase from '../../TestCase';
34

@@ -39,6 +40,44 @@ export default class TextAreaFixtures extends React.Component {
3940
<textarea placeholder="Hello, world" />
4041
</div>
4142
</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>
4281
</FixtureSet>
4382
);
4483
}

packages/react-dom/src/__tests__/ReactDOMTextarea-test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,33 @@ describe('ReactDOMTextarea', () => {
126126
expect(node.value).toEqual('gorilla');
127127
});
128128

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+
129156
it('should render defaultValue for SSR', () => {
130157
const markup = ReactDOMServer.renderToString(<textarea defaultValue="1" />);
131158
const div = document.createElement('div');

packages/react-dom/src/client/ReactDOMTextarea.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@ export function postMountWrapper(element: Element, props: Object) {
157157
// will populate textContent as well.
158158
// https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
159159
if (textContent === node._wrapperState.initialValue) {
160-
node.value = textContent;
160+
if (textContent !== '' && textContent !== null) {
161+
node.value = textContent;
162+
}
161163
}
162164
}
163165

0 commit comments

Comments
 (0)