@samitouri / QOS-React-2 / commits / 578863881f

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,