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
Josh Duck committed
Sep 19, 2013 at 14:00 UTC
578863881f50dbd1ce59c4ee453f51ce895b57b0
4 files changed
+97
src/core/ReactEventEmitter.js
+16
@@ -263,6 +263,22 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
263
mountAt
264
);
265
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
+
282
if (isEventSupported('drag')) {
283
trapBubbledEvent(topLevelTypes.topDrag, 'drag', mountAt);
284
trapBubbledEvent(topLevelTypes.topDragEnd, 'dragend', mountAt);
src/event/EventConstants.js
+3
@@ -29,6 +29,9 @@ var topLevelTypes = keyMirror({
29
topBlur: null,
30
topChange: null,
31
topClick: null,
32
+ topCompositionEnd: null,
33
+ topCompositionStart: null,
34
+ topCompositionUpdate: null,
35
topCopy: null,
36
topCut: null,
37
topDOMCharacterDataModified: null,
src/event/synthetic/SyntheticCompositionEvent.js
new
+51
@@ -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
+27
@@ -21,6 +21,7 @@
21
var EventConstants = require('EventConstants');
22
var EventPropagators = require('EventPropagators');
23
var SyntheticClipboardEvent = require('SyntheticClipboardEvent');
24
+var SyntheticCompositionEvent = require('SyntheticCompositionEvent');
25
var SyntheticEvent = require('SyntheticEvent');
26
var SyntheticFocusEvent = require('SyntheticFocusEvent');
27
var SyntheticKeyboardEvent = require('SyntheticKeyboardEvent');
@@ -48,6 +49,24 @@ var eventTypes = {
49
captured: keyOf({onClickCapture: true})
50
}
51
},
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
+ },
70
copy: {
71
phasedRegistrationNames: {
72
bubbled: keyOf({onCopy: true}),
@@ -225,6 +244,9 @@ var topLevelEventsToDispatchConfig = {
244
topClick: eventTypes.click,
245
topCopy: eventTypes.copy,
246
topCut: eventTypes.cut,
247
+ topCompositionEnd: eventTypes.compositionEnd,
248
+ topCompositionStart: eventTypes.compositionStart,
249
+ topCompositionUpdate: eventTypes.compositionUpdate,
250
topDoubleClick: eventTypes.doubleClick,
251
topDOMCharacterDataModified: eventTypes.DOMCharacterDataModified,
252
topDrag: eventTypes.drag,
@@ -342,6 +364,11 @@ var SimpleEventPlugin = {
364
case topLevelTypes.topPaste:
365
EventConstructor = SyntheticClipboardEvent;
366
break;
367
+ case topLevelTypes.topCompositionStart:
368
+ case topLevelTypes.topCompositionEnd:
369
+ case topLevelTypes.topCompositionUpdate:
370
+ EventConstructor = SyntheticCompositionEvent;
371
+ break;
372
}
373
invariant(
374
EventConstructor,