Add new textChange event: input + IE shim

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).
This commit is contained in:
Ben Alpert committed 2013-06-09 04:18:15 -07:00
1 parent 7e7579e1ba
commit c19bf9cffe
5 files changed
+212 -3

No files matched your search

+3 -1
View File
@@ -23,6 +23,7 @@ var ReactDOMForm = require('ReactDOMForm');
var DefaultEventPluginOrder = require('DefaultEventPluginOrder');
var EnterLeaveEventPlugin = require('EnterLeaveEventPlugin');
var TextChangeEventPlugin = require('TextChangeEventPlugin');
var EventPluginHub = require('EventPluginHub');
var ReactInstanceHandles = require('ReactInstanceHandles');
var SimpleEventPlugin = require('SimpleEventPlugin');
@@ -40,7 +41,8 @@ function inject() {
*/
EventPluginHub.injection.injectEventPluginsByName({
'SimpleEventPlugin': SimpleEventPlugin,
'EnterLeaveEventPlugin': EnterLeaveEventPlugin
'EnterLeaveEventPlugin': EnterLeaveEventPlugin,
'TextChangeEventPlugin': TextChangeEventPlugin
});
/*
+5
View File
@@ -189,6 +189,11 @@ function listenAtTopLevel(touchNotMouse) {
trapBubbledEvent(topLevelTypes.topKeyDown, 'keydown', mountAt);
trapBubbledEvent(topLevelTypes.topInput, 'input', mountAt);
trapBubbledEvent(topLevelTypes.topChange, 'change', mountAt);
trapBubbledEvent(
topLevelTypes.topSelectionChange,
'selectionchange',
mountAt
);
trapBubbledEvent(
topLevelTypes.topDOMCharacterDataModified,
'DOMCharacterDataModified',