diff --git a/fixtures/dom/src/components/fixtures/text-inputs/ReplaceEmailInput.js b/fixtures/dom/src/components/fixtures/text-inputs/ReplaceEmailInput.js new file mode 100644 index 0000000000000..264be16085a4b --- /dev/null +++ b/fixtures/dom/src/components/fixtures/text-inputs/ReplaceEmailInput.js @@ -0,0 +1,40 @@ +import Fixture from '../../Fixture'; + +const React = window.React; + +class ReplaceEmailInput extends React.Component { + state = { + formSubmitted: false, + }; + + onReset = () => { + this.setState({formSubmitted: false}); + }; + + onSubmit = event => { + event.preventDefault(); + this.setState({formSubmitted: true}); + }; + + render() { + return ( + +
+
+ Email + {!this.state.formSubmitted ? ( + + ) : ( + + )} +
+
+ +
+ ); + } +} + +export default ReplaceEmailInput; diff --git a/fixtures/dom/src/components/fixtures/text-inputs/index.js b/fixtures/dom/src/components/fixtures/text-inputs/index.js index 33639686a311d..54026257fd986 100644 --- a/fixtures/dom/src/components/fixtures/text-inputs/index.js +++ b/fixtures/dom/src/components/fixtures/text-inputs/index.js @@ -2,6 +2,7 @@ import Fixture from '../../Fixture'; import FixtureSet from '../../FixtureSet'; import TestCase from '../../TestCase'; import InputTestCase from './InputTestCase'; +import ReplaceEmailInput from './ReplaceEmailInput'; const React = window.React; @@ -125,6 +126,21 @@ class TextInputFixtures extends React.Component { + + +
  • Type "test@test.com"
  • +
  • Press enter
  • +
    + + + There should be no selection-related error in the console. + + + +
    + diff --git a/packages/react-dom/src/client/ReactInputSelection.js b/packages/react-dom/src/client/ReactInputSelection.js index 506153a118053..d4b47b992ce86 100644 --- a/packages/react-dom/src/client/ReactInputSelection.js +++ b/packages/react-dom/src/client/ReactInputSelection.js @@ -22,11 +22,21 @@ function isInDocument(node) { * Input selection module for React. */ +/** + * @hasSelectionCapabilities: we get the element types that support selection + * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart` + * and `selectionEnd` rows. + */ export function hasSelectionCapabilities(elem) { const nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); return ( nodeName && - ((nodeName === 'input' && elem.type === 'text') || + ((nodeName === 'input' && + (elem.type === 'text' || + elem.type === 'search' || + elem.type === 'tel' || + elem.type === 'url' || + elem.type === 'password')) || nodeName === 'textarea' || elem.contentEditable === 'true') ); @@ -52,7 +62,10 @@ export function restoreSelection(priorSelectionInformation) { const priorFocusedElem = priorSelectionInformation.focusedElem; const priorSelectionRange = priorSelectionInformation.selectionRange; if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { - if (hasSelectionCapabilities(priorFocusedElem)) { + if ( + priorSelectionRange !== null && + hasSelectionCapabilities(priorFocusedElem) + ) { setSelection(priorFocusedElem, priorSelectionRange); }