Skip to content

Commit

Permalink
prevent firefox marking required textareas invalid (#16578)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
halvves authored and nhunzaker committed Sep 18, 2019
1 parent f818af9 commit a5df18a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
39 changes: 39 additions & 0 deletions fixtures/dom/src/components/fixtures/textareas/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Fixture from '../../Fixture';
import FixtureSet from '../../FixtureSet';
import TestCase from '../../TestCase';

Expand Down Expand Up @@ -39,6 +40,44 @@ export default class TextAreaFixtures extends React.Component {
<textarea placeholder="Hello, world" />
</div>
</TestCase>

<TestCase
title="Required Textareas"
affectedBrowsers="Firefox"
relatedIssues="16402">
<TestCase.Steps>
<li>View this test in Firefox</li>
</TestCase.Steps>

<TestCase.ExpectedResult>
You should{' '}
<b>
<i>not</i>
</b>{' '}
see a red aura on initial page load, indicating the textarea is
invalid.
<br />
This aura looks roughly like:
<textarea style={{boxShadow: '0 0 1px 1px red', marginLeft: 8}} />
</TestCase.ExpectedResult>

<Fixture>
<form className="control-box">
<fieldset>
<legend>Empty value prop string</legend>
<textarea value="" required={true} />
</fieldset>
<fieldset>
<legend>No value prop</legend>
<textarea required={true} />
</fieldset>
<fieldset>
<legend>Empty defaultValue prop string</legend>
<textarea required={true} defaultValue="" />
</fieldset>
</form>
</Fixture>
</TestCase>
</FixtureSet>
);
}
Expand Down
27 changes: 27 additions & 0 deletions packages/react-dom/src/__tests__/ReactDOMTextarea-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,33 @@ describe('ReactDOMTextarea', () => {
expect(node.value).toEqual('gorilla');
});

it('will not initially assign an empty value (covers case where firefox throws a validation error when required attribute is set)', () => {
const container = document.createElement('div');

let counter = 0;
const originalCreateElement = document.createElement;
spyOnDevAndProd(document, 'createElement').and.callFake(function(type) {
const el = originalCreateElement.apply(this, arguments);
let value = '';
if (type === 'textarea') {
Object.defineProperty(el, 'value', {
get: function() {
return value;
},
set: function(val) {
value = '' + val;
counter++;
},
});
}
return el;
});

ReactDOM.render(<textarea value="" readOnly={true} />, container);

expect(counter).toEqual(0);
});

it('should render defaultValue for SSR', () => {
const markup = ReactDOMServer.renderToString(<textarea defaultValue="1" />);
const div = document.createElement('div');
Expand Down
4 changes: 3 additions & 1 deletion packages/react-dom/src/client/ReactDOMTextarea.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ export function postMountWrapper(element: Element, props: Object) {
// will populate textContent as well.
// https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
if (textContent === node._wrapperState.initialValue) {
node.value = textContent;
if (textContent !== '' && textContent !== null) {
node.value = textContent;
}
}
}

Expand Down

0 comments on commit a5df18a

Please sign in to comment.