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

Add new textChange event: input + IE shim #75

Merged
merged 4 commits into from
Jun 12, 2013

Conversation

sophiebits
Copy link
Collaborator

IE8 doesn't support oninput and IE9 supports it badly but we can do almost a perfect shim by listening to a handful of different events (focus, blur, propertychange, selectionchange, keyup, keydown).

This always triggers event handlers during the browser's event loop (not later in a setTimeout) and after the value property has been updated.

The only case I know of where this doesn't fire the event immediately is if (in IE8) you modify the input value using JS and then the user does a key repeat, in which case we fire the event on the second keydown.

Test Plan:
Modify ballmer-peak example to add es5-shim and to use onTextChange instead of onInput. In IE8, IE9, and latest Chrome, make sure that the event is fired upon:

  • typing normally,
  • backspacing,
  • forward-deleting,
  • cutting,
  • pasting,
  • context-menu deleting,
  • dragging text to reorder characters.

After modifying the example to change .value, make sure that the event is not fired as a result of the changes from JS (even when the input box is focused).

Questions:

  • Does it make sense to pass on the native event? Since it could be one of seven different types, I'm not sure that application code would be able to do anything useful with it.
  • The propertychange event doesn't bubble so we can't just attach it to document with the other events but is it preferable to have it go through ReactEventTopLevelCallback like the other events even though we're the only ones who'll be interested? Doing so will get rid of the manual enqueueAbstractEvents/processAbstractEventQueue calls I have but I imagine it'll be slower and won't give any other advantages.
  • Is the IE9 sniffing code for isInputSupported reasonable? I don't know the preferred way here to handle situations like this.
  • IE loses the textarea cursor position when updating the textarea contents during the selectionchange event and having ReactInputSelection attempt to restore the contents doesn't seem to help so I've disabled the event on textarea for now. Ideas?

IE8 doesn't support oninput and IE9 supports it badly but we can do
almost a perfect shim by listening to a handful of different events
(focus, blur, propertychange, selectionchange, keyup, keydown).

This always triggers event handlers during the browser's event loop (not
later in a setTimeout) and after the value property has been updated.

The only case I know of where this doesn't fire the event immediately is
if (in IE8) you modify the input value using JS and then the user does a
key repeat, in which case we fire the event on the second keydown.

Test Plan:
Modify ballmer-peak example to add es5-shim and to use onTextChange
instead of onInput. In IE8, IE9, and latest Chrome, make sure that the
event is fired upon:

* typing normally,
* backspacing,
* forward-deleting,
* cutting,
* pasting,
* context-menu deleting,
* dragging text to reorder characters.

After modifying the example to change .value, make sure that the event
is not fired as a result of the changes from JS (even when the input box
is focused).
@zpao
Copy link
Member

zpao commented Jun 10, 2013

cc @yungsters


// IE9 claims to support the input event but fails to trigger it when deleting
// text, so we ignore its input events
var isInputSupported = isEventSupported('input') && (
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use ExecutionEnvironment.canUseDOM such that this module could be required and not fatal if there is no document symbol in scope. I'm not sure if it'll get required in practice or not, but a good idea nonetheless.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. (I had canUseDOM originally but lost it somewhere along the way.)

var isInputSupported;
if (ExecutionEnvironment.canUseDOM) {
isInputSupported = isEventSupported('input') && (
!("documentMode" in document) || document.documentMode > 9
Copy link
Contributor

Choose a reason for hiding this comment

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

This check looks good to me.

@yungsters
Copy link
Contributor

Does it make sense to pass on the native event? Since it could be one of seven different types, I'm not sure that application code would be able to do anything useful with it.

Yes, keep passing it along. It's up to the end user to do what they will with it, but I have a new set of "synthetic events" that will allow us to normalize the API for both DOM and custom events like the one you're adding.

nativeEvent
);
EventPropagators.accumulateTwoPhaseDispatches(abstractEvent);
EventPluginHub.enqueueAbstractEvents(abstractEvent);
Copy link
Contributor

Choose a reason for hiding this comment

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

Add a comment about how propertychange does not bubble so we cannot listen to this using top-level event delegation and have to enqueue and process manually. (By the way, @jordow, can you explain why we need two steps for enqueuing and processing instead of one?)

yungsters added a commit that referenced this pull request Jun 12, 2013
Add new textChange event: input + IE shim
@yungsters yungsters merged commit dfd76be into facebook:master Jun 12, 2013
andreypopp pushed a commit to andreypopp/jsxx that referenced this pull request Feb 2, 2014
…orm elements

Upgrade `TextChangeEventPlugin` to be the `onChange` event that React
fires. In React, `onChange` will now fire when `input` fires for form elements in
modern browsers.

Handle this for:

  input[type=text]
  input[type=password]
  input[type=checkbox]
  input[type=radio]
  textarea
  select

Support:

- OSX Chrome
- OSX Safari
- OSX Firefox
- Win 7 / IE8
- Win 7 / IE9
- Win 7 / IE10

Everything works but caret selection / placement differs from browser to
browser.

For <select> elements, the event is fired with `change`. This is a
conscious decision, even though in some browsers (OSX firefox, IE), it
can be argued that the event should fire more due to how the UI looks.

Builds on facebook/react#75, which handled only
text inputs.
bvaughn pushed a commit to bvaughn/react that referenced this pull request Aug 13, 2019
Fix double-adding fibers when traversing
taneliang referenced this pull request in MLH-Fellowship/react Aug 17, 2020
… frame type

Lays groundwork for #75 by reducing the flamechart data passed around
the app.

Was also intended to help #50 by moving some division operations from
the hot render loops into preprocessFlamechart, but any performance
gains are negligible.

* `yarn flow`: no errors in modified code
* `yarn lint`
* `yarn start`: no performance difference
taneliang referenced this pull request in MLH-Fellowship/react Aug 19, 2020
… frame type

Lays groundwork for #75 by reducing the flamechart data passed around
the app.

Was also intended to help #50 by moving some division operations from
the hot render loops into preprocessFlamechart, but any performance
gains are negligible.

* `yarn flow`: no errors in modified code
* `yarn lint`
* `yarn start`: no performance difference
toptaldev92 pushed a commit to toptaldev92/react_project that referenced this pull request Jul 28, 2021
…orm elements

Upgrade `TextChangeEventPlugin` to be the `onChange` event that React
fires. In React, `onChange` will now fire when `input` fires for form elements in
modern browsers.

Handle this for:

  input[type=text]
  input[type=password]
  input[type=checkbox]
  input[type=radio]
  textarea
  select

Support:

- OSX Chrome
- OSX Safari
- OSX Firefox
- Win 7 / IE8
- Win 7 / IE9
- Win 7 / IE10

Everything works but caret selection / placement differs from browser to
browser.

For <select> elements, the event is fired with `change`. This is a
conscious decision, even though in some browsers (OSX firefox, IE), it
can be argued that the event should fire more due to how the UI looks.

Builds on facebook/react#75, which handled only
text inputs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants