Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend input type check in selection capabilities (#12062) #12135

Merged
merged 3 commits into from May 30, 2018

Conversation

spirosikmd
Copy link
Contributor

@spirosikmd spirosikmd commented Feb 1, 2018

restoreSelection did not account for input elements that have changed
type after the commit phase. The new text input supported selection
but the old email did not and setSelection was incorrectly trying to
restore null selection state.

We also extend input type check in selection capabilities to cover cases
where input type is search, tel, url, or password.

Fix #12062

@@ -110,6 +114,37 @@ class TextInputFixtures extends React.Component {
<InputTestCase type="url" defaultValue="" />
</TestCase>

<TestCase
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For new test cases that are stateful, can you break it out into it's own component? See NumberInputExtraZeroes.js as an example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was in doubt about the implementation. Thanks for the guideline!

@@ -26,7 +26,8 @@ export function hasSelectionCapabilities(elem) {
const nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
return (
nodeName &&
((nodeName === 'input' && elem.type === 'text') ||
((nodeName === 'input' &&
['text', 'email', 'tel'].indexOf(elem.type) >= 0) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of defining an inline array, let's just add some additional cases to the boolean expression.

(
nodeName === 'input' &&
(elem.type === 'text' || elem.type === 'email' || elem.type === 'tel')
)

Copy link
Contributor

@aweary aweary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this @spirosikmd!

@spirosikmd spirosikmd force-pushed the email-input-selection branch 2 times, most recently from 14771a7 to aa115f7 Compare February 2, 2018 22:34
@spirosikmd
Copy link
Contributor Author

Hi @aweary! It would be great if you can have another look at this one!

Copy link
Contributor

@aweary aweary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @spirosikmd,

Circling back to this, this change isn't correct. hasSelectionCapabilities should only return true if the element actually has selection capabilities and email inputs do not.

This is clearly stated in the "do not apply" table in the HTML spec. The only inputs that have selection capabilities are text, search, password, and tel. We don't account for any of those except text so we're potentially missing out on restoring selection information in some cases. Let's add those types to account for that.

The root issue of the bug reported in #12062 is that restoreSelection does not account for input elements that may have changed type after the commit phase. If the new input type supports selection state (text) but the old type didn't (email) it will incorrectly attempt to restore null selection state

if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
if (hasSelectionCapabilities(priorFocusedElem)) {
setSelection(priorFocusedElem, priorSelectionRange);
}

What we need to do is also check if priorSelectionRange isn't null before calling setSelection

if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
      setSelection(priorFocusedElem, priorSelectionRange);
    }

Could you make these changes please @spirosikmd? Thanks!

@spirosikmd
Copy link
Contributor Author

Hey @aweary!

Thank you for the tip! I added the url type as well. According to the HTML spec, url does have selection capabilities.

Regarding the scripts/rollup/results.json. Should I revert my changes to avoid conflicts? Or is it a requirement for each PR to update this file?

@aweary aweary requested review from jquense and nhunzaker April 7, 2018 00:34
@aweary
Copy link
Contributor

aweary commented Apr 7, 2018

Thanks @spirosikmd, this looks good to me. I'd like to hear from @nhunzaker and/or @jquense on this as well before merging.

Regarding the scripts/rollup/results.json. Should I revert my changes to avoid conflicts? Or is it a requirement for each PR to update this file?

You should try rebasing and running the build command again, to get an updated report without conflicts.

elem.type === 'search' ||
elem.type === 'tel' ||
elem.type === 'url' ||
elem.type === 'password')) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is email not in this list?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. That was very blunt! Should email be in here? I found a neat table from a spec:
https://html.spec.whatwg.org/multipage/input.html#concept-input-apply

So this matches up with the setSelectionRange column? Dang. I really want to know the reasoning behind not supporting this for all text based input.

Would it be possible to add a comment at the top of this block that references this table for future contributors?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add a comment containing the link as well. As far as I can see we are only using the selectionStart and selectionEnd in the code. So I guess we match up with these two rows.

Copy link
Contributor

@nhunzaker nhunzaker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I think it would be great to leave a comment about why we specifically compare these input types, but I'm happy with the approach.

@pull-bot
Copy link

pull-bot commented Apr 12, 2018

ReactDOM: size: 🔺+0.1%, gzip: 🔺+0.1%

Details of bundled changes.

Comparing: 5dfbfe9...3425970

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom.development.js +0.1% +0.1% 609.28 KB 609.6 KB 140.41 KB 140.52 KB UMD_DEV
react-dom.production.min.js 🔺+0.1% 🔺+0.1% 100.18 KB 100.26 KB 31.97 KB 31.99 KB UMD_PROD
react-dom.development.js +0.1% +0.1% 593.65 KB 593.97 KB 136.25 KB 136.37 KB NODE_DEV
react-dom.production.min.js 🔺+0.1% 🔺+0.1% 98.64 KB 98.72 KB 31.11 KB 31.13 KB NODE_PROD
ReactDOM-dev.js +0.1% +0.1% 618.04 KB 618.42 KB 139.01 KB 139.12 KB FB_DEV
ReactDOM-prod.js 🔺+0.1% 🔺+0.1% 284.83 KB 285.02 KB 52.32 KB 52.35 KB FB_PROD

Generated by 🚫 dangerJS

"size": 467421,
"gzip": 99671
"size": 467747,
"gzip": 99762
},
{
"filename": "ReactNativeRenderer-prod.js",
"bundleType": "RN_PROD",
"packageName": "react-native-renderer",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please revert this file?

`restoreSelection` did not account for input elements that have changed
type after the commit phase. The new `text` input supported selection
but the old `email` did not and `setSelection` was incorrectly trying to
restore `null` selection state.

We also extend input type check in selection capabilities to cover cases
where input type is `search`, `tel`, `url`, or `password`.
@spirosikmd
Copy link
Contributor Author

Hi @aweary! This should be ready to merge!

@nhunzaker
Copy link
Contributor

The requested feedback checks out for me. @aweary what say you?

@nhunzaker
Copy link
Contributor

@spirosikmd I'll check in to make sure this is still on the team's radar if we haven't come to consensus by next week.

Thanks for your contribution!

This commit adds a button to restore the original state of the
ReplaceEmailInput fixture so that it can be run multiple times without
refreshing the page.
@nhunzaker
Copy link
Contributor

This looks great to me. I pushed a commit that adds a reset button to the test fixture so that the test can be run multiple times without refreshing the page. That also covers the inverse case.

I'll wait for CI, then merge.

@spirosikmd
Copy link
Contributor Author

Great! Thank you @nhunzaker!

@nhunzaker nhunzaker merged commit e0a03c1 into facebook:master May 30, 2018
@nhunzaker
Copy link
Contributor

nhunzaker commented May 30, 2018

Thanks, @spirosikmd!

@spirosikmd spirosikmd deleted the email-input-selection branch May 30, 2018 11:12
bors bot added a commit to mozilla/delivery-console that referenced this pull request Jun 13, 2018
193: Update dependency react to v16.4.1 r=magopian a=renovate[bot]

This Pull Request updates dependency [react](https://github.com/facebook/react) from `v16.4.0` to `v16.4.1`



<details>
<summary>Release Notes</summary>

### [`v16.4.1`](https://github.com/facebook/react/blob/master/CHANGELOG.md#&#8203;1641-June-13-2018)
[Compare Source](facebook/react@v16.4.0...v16.4.1)
##### React

* You can now assign `propTypes` to components returned by `React.ForwardRef`. ([@&#8203;bvaughn] in [#&#8203;12911](`facebook/react#12911))
##### React DOM

* Fix a crash when the input `type` changes from some other types to `text`. ([@&#8203;spirosikmd] in [#&#8203;12135](`facebook/react#12135))
* Fix a crash in IE11 when restoring focus to an SVG element. ([@&#8203;ThaddeusJiang] in [#&#8203;12996](`facebook/react#12996))
* Fix a range input not updating in some cases. ([@&#8203;Illu] in [#&#8203;12939](`facebook/react#12939))
* Fix input validation triggering unnecessarily in Firefox. ([@&#8203;nhunzaker] in [#&#8203;12925](`facebook/react#12925))
* Fix an incorrect `event.target` value for the `onChange` event in IE9. ([@&#8203;nhunzaker] in [#&#8203;12976](`facebook/react#12976))
* Fix a false positive error when returning an empty `<React.Fragment />` from a component. ([@&#8203;philipp-spiess] in [#&#8203;12966](`facebook/react#12966))
##### React DOM Server

* Fix an incorrect value being provided by new context API. ([@&#8203;ericsoderberghp] in [#&#8203;12985](`facebook/react#12985), [@&#8203;gaearon] in [#&#8203;13019](`facebook/react#13019))
##### React Test Renderer

* Allow multiple root children in test renderer traversal API. ([@&#8203;gaearon] in [#&#8203;13017](`facebook/react#13017))
* Fix `getDerivedStateFromProps()` in the shallow renderer to not discard the pending state. ([@&#8203;fatfisz] in [#&#8203;13030](`facebook/react#13030))

---

</details>




---

This PR has been generated by [Renovate Bot](https://renovatebot.com).

Co-authored-by: Renovate Bot <bot@renovateapp.com>
bors bot added a commit to mythmon/corsica-tree-status that referenced this pull request Jun 14, 2018
25: Update react monorepo to v16.4.1 r=renovate[bot] a=renovate[bot]

This Pull Request renovates the package group "react monorepo".


-   [react-dom](https://github.com/facebook/react) (`dependencies`): from `16.4.0` to `16.4.1`
-   [react](https://github.com/facebook/react) (`dependencies`): from `16.4.0` to `16.4.1`

# Release Notes
<details>
<summary>facebook/react</summary>

### [`v16.4.1`](https://github.com/facebook/react/blob/master/CHANGELOG.md#&#8203;1641-June-13-2018)
[Compare Source](facebook/react@v16.4.0...v16.4.1)
##### React

* You can now assign `propTypes` to components returned by `React.ForwardRef`. ([@&#8203;bvaughn] in [#&#8203;12911](`facebook/react#12911))
##### React DOM

* Fix a crash when the input `type` changes from some other types to `text`. ([@&#8203;spirosikmd] in [#&#8203;12135](`facebook/react#12135))
* Fix a crash in IE11 when restoring focus to an SVG element. ([@&#8203;ThaddeusJiang] in [#&#8203;12996](`facebook/react#12996))
* Fix a range input not updating in some cases. ([@&#8203;Illu] in [#&#8203;12939](`facebook/react#12939))
* Fix input validation triggering unnecessarily in Firefox. ([@&#8203;nhunzaker] in [#&#8203;12925](`facebook/react#12925))
* Fix an incorrect `event.target` value for the `onChange` event in IE9. ([@&#8203;nhunzaker] in [#&#8203;12976](`facebook/react#12976))
* Fix a false positive error when returning an empty `<React.Fragment />` from a component. ([@&#8203;philipp-spiess] in [#&#8203;12966](`facebook/react#12966))
##### React DOM Server

* Fix an incorrect value being provided by new context API. ([@&#8203;ericsoderberghp] in [#&#8203;12985](`facebook/react#12985), [@&#8203;gaearon] in [#&#8203;13019](`facebook/react#13019))
##### React Test Renderer

* Allow multiple root children in test renderer traversal API. ([@&#8203;gaearon] in [#&#8203;13017](`facebook/react#13017))
* Fix `getDerivedStateFromProps()` in the shallow renderer to not discard the pending state. ([@&#8203;fatfisz] in [#&#8203;13030](`facebook/react#13030))

---


</details>




---

This PR has been generated by [Renovate Bot](https://renovatebot.com).

Co-authored-by: Renovate Bot <bot@renovateapp.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants