Skip to content

Commit 5788638

Browse files
joshduckzpao
authored andcommitted
Add composition events to React.
Composition events make it possible to detect IME entry/exit. https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
1 parent 8875e1d commit 5788638

File tree

4 files changed

+97
-0
lines changed

4 files changed

+97
-0
lines changed

src/core/ReactEventEmitter.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,22 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
263263
mountAt
264264
);
265265

266+
trapBubbledEvent(
267+
topLevelTypes.topCompositionEnd,
268+
'compositionend',
269+
mountAt
270+
);
271+
trapBubbledEvent(
272+
topLevelTypes.topCompositionStart,
273+
'compositionstart',
274+
mountAt
275+
);
276+
trapBubbledEvent(
277+
topLevelTypes.topCompositionUpdate,
278+
'compositionupdate',
279+
mountAt
280+
);
281+
266282
if (isEventSupported('drag')) {
267283
trapBubbledEvent(topLevelTypes.topDrag, 'drag', mountAt);
268284
trapBubbledEvent(topLevelTypes.topDragEnd, 'dragend', mountAt);

src/event/EventConstants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ var topLevelTypes = keyMirror({
2929
topBlur: null,
3030
topChange: null,
3131
topClick: null,
32+
topCompositionEnd: null,
33+
topCompositionStart: null,
34+
topCompositionUpdate: null,
3235
topCopy: null,
3336
topCut: null,
3437
topDOMCharacterDataModified: null,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Copyright 2013 Facebook, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* @providesModule SyntheticCompositionEvent
17+
* @typechecks static-only
18+
*/
19+
20+
"use strict";
21+
22+
var SyntheticEvent = require('SyntheticEvent');
23+
24+
/**
25+
* @interface Event
26+
* @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
27+
*/
28+
var CompositionEventInterface = {
29+
data: null
30+
};
31+
32+
/**
33+
* @param {object} dispatchConfig Configuration used to dispatch this event.
34+
* @param {string} dispatchMarker Marker identifying the event target.
35+
* @param {object} nativeEvent Native browser event.
36+
* @extends {SyntheticUIEvent}
37+
*/
38+
function SyntheticCompositionEvent(
39+
dispatchConfig,
40+
dispatchMarker,
41+
nativeEvent) {
42+
SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
43+
}
44+
45+
SyntheticEvent.augmentClass(
46+
SyntheticCompositionEvent,
47+
CompositionEventInterface
48+
);
49+
50+
module.exports = SyntheticCompositionEvent;
51+

src/eventPlugins/SimpleEventPlugin.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
var EventConstants = require('EventConstants');
2222
var EventPropagators = require('EventPropagators');
2323
var SyntheticClipboardEvent = require('SyntheticClipboardEvent');
24+
var SyntheticCompositionEvent = require('SyntheticCompositionEvent');
2425
var SyntheticEvent = require('SyntheticEvent');
2526
var SyntheticFocusEvent = require('SyntheticFocusEvent');
2627
var SyntheticKeyboardEvent = require('SyntheticKeyboardEvent');
@@ -48,6 +49,24 @@ var eventTypes = {
4849
captured: keyOf({onClickCapture: true})
4950
}
5051
},
52+
compositionEnd: {
53+
phasedRegistrationNames: {
54+
bubbled: keyOf({onCompositionEnd: true}),
55+
captured: keyOf({onCompositionEndCapture: true})
56+
}
57+
},
58+
compositionStart: {
59+
phasedRegistrationNames: {
60+
bubbled: keyOf({onCompositionStart: true}),
61+
captured: keyOf({onCompositionStartCapture: true})
62+
}
63+
},
64+
compositionUpdate: {
65+
phasedRegistrationNames: {
66+
bubbled: keyOf({onCompositionUpdate: true}),
67+
captured: keyOf({onCompositionUpdateCapture: true})
68+
}
69+
},
5170
copy: {
5271
phasedRegistrationNames: {
5372
bubbled: keyOf({onCopy: true}),
@@ -225,6 +244,9 @@ var topLevelEventsToDispatchConfig = {
225244
topClick: eventTypes.click,
226245
topCopy: eventTypes.copy,
227246
topCut: eventTypes.cut,
247+
topCompositionEnd: eventTypes.compositionEnd,
248+
topCompositionStart: eventTypes.compositionStart,
249+
topCompositionUpdate: eventTypes.compositionUpdate,
228250
topDoubleClick: eventTypes.doubleClick,
229251
topDOMCharacterDataModified: eventTypes.DOMCharacterDataModified,
230252
topDrag: eventTypes.drag,
@@ -342,6 +364,11 @@ var SimpleEventPlugin = {
342364
case topLevelTypes.topPaste:
343365
EventConstructor = SyntheticClipboardEvent;
344366
break;
367+
case topLevelTypes.topCompositionStart:
368+
case topLevelTypes.topCompositionEnd:
369+
case topLevelTypes.topCompositionUpdate:
370+
EventConstructor = SyntheticCompositionEvent;
371+
break;
345372
}
346373
invariant(
347374
EventConstructor,

0 commit comments

Comments
 (0)