@samitouri / QOS-React-2 / commits / b83076468d

Improve normalization of charCode, fix FF not reporting Enter

Andreas Svensson committed Jul 30, 2014 at 00:34 UTC b83076468da57e2fcaf18f2f21c20bc34a0aa077
4 files changed +78 -18
src/browser/eventPlugins/SimpleEventPlugin.js
+5 -2
@@ -31,6 +31,8 @@ var SyntheticTouchEvent = require('SyntheticTouchEvent');
31 var SyntheticUIEvent = require('SyntheticUIEvent');
32 var SyntheticWheelEvent = require('SyntheticWheelEvent');
33
34 +var getEventCharCode = require('getEventCharCode');
35 +
36 var invariant = require('invariant');
37 var keyOf = require('keyOf');
38
@@ -343,8 +345,9 @@ var SimpleEventPlugin = {
345 break;
346 case topLevelTypes.topKeyPress:
347 // FireFox creates a keypress event for function keys too. This removes
346 - // the unwanted keypress events.
347 - if (nativeEvent.charCode === 0) {
348 + // the unwanted keypress events. Enter is however both printable and
349 + // non-printable. One would expect Tab to be as well (but it isn't).
350 + if (getEventCharCode(nativeEvent) === 0) {
351 return null;
352 }
353 /* falls through */
src/browser/syntheticEvents/SyntheticKeyboardEvent.js
+12 -7
@@ -21,6 +21,7 @@
21
22 var SyntheticUIEvent = require('SyntheticUIEvent');
23
24 +var getEventCharCode = require('getEventCharCode');
25 var getEventKey = require('getEventKey');
26 var getEventModifierState = require('getEventModifierState');
27
@@ -43,11 +44,10 @@ var KeyboardEventInterface = {
44 // `charCode` is the result of a KeyPress event and represents the value of
45 // the actual printable character.
46
46 - // KeyPress is deprecated but its replacement is not yet final and not
47 - // implemented in any major browser.
47 + // KeyPress is deprecated, but its replacement is not yet final and not
48 + // implemented in any major browser. Only KeyPress has charCode.
49 if (event.type === 'keypress') {
49 - // IE8 does not implement "charCode", but "keyCode" has the correct value.
50 - return 'charCode' in event ? event.charCode : event.keyCode;
50 + return getEventCharCode(event);
51 }
52 return 0;
53 },
@@ -66,9 +66,14 @@ var KeyboardEventInterface = {
66 },
67 which: function(event) {
68 // `which` is an alias for either `keyCode` or `charCode` depending on the
69 - // type of the event. There is no need to determine the type of the event
70 - // as `keyCode` and `charCode` are either aliased or default to zero.
71 - return event.keyCode || event.charCode;
69 + // type of the event.
70 + if (event.type === 'keypress') {
71 + return getEventCharCode(event);
72 + }
73 + if (event.type === 'keydown' || event.type === 'keyup') {
74 + return event.keyCode;
75 + }
76 + return 0;
77 }
78 };
79
src/browser/ui/dom/getEventCharCode.js new
+57
@@ -0,0 +1,57 @@
1 +/**
2 + * Copyright 2013-2014 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 getEventCharCode
17 + * @typechecks static-only
18 + */
19 +
20 +"use strict";
21 +
22 +/**
23 + * `charCode` represents the actual "character code" and is safe to use with
24 + * `String.fromCharCode`. As such, only keys that correspond to printable
25 + * characters produce a valid `charCode`, the only exception to this is Enter.
26 + * The Tab-key is considered non-printable and does not have a `charCode`,
27 + * presumably because it does not produce a tab-character in browsers.
28 + *
29 + * @param {object} nativeEvent Native browser event.
30 + * @return {string} Normalized `charCode` property.
31 + */
32 +function getEventCharCode(nativeEvent) {
33 + var charCode;
34 + var keyCode = nativeEvent.keyCode;
35 +
36 + if ('charCode' in nativeEvent) {
37 + charCode = nativeEvent.charCode;
38 +
39 + // FF does not set `charCode` for the Enter-key, check against `keyCode`.
40 + if (charCode === 0 && keyCode === 13) {
41 + charCode = 13;
42 + }
43 + } else {
44 + // IE8 does not implement `charCode`, but `keyCode` has the correct value.
45 + charCode = keyCode;
46 + }
47 +
48 + // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
49 + // Must not discard the (non-)printable Enter-key.
50 + if (charCode >= 32 || charCode === 13) {
51 + return charCode;
52 + }
53 +
54 + return 0;
55 +}
56 +
57 +module.exports = getEventCharCode;
src/browser/ui/dom/getEventKey.js
+4 -9
@@ -19,7 +19,7 @@
19
20 "use strict";
21
22 -var invariant = require('invariant');
22 +var getEventCharCode = require('getEventCharCode');
23
24 /**
25 * Normalization of deprecated HTML5 `key` values
@@ -41,7 +41,7 @@ var normalizeKey = {
41 };
42
43 /**
44 - * Translation from legacy `which`/`keyCode` to HTML5 `key`
44 + * Translation from legacy `keyCode` to HTML5 `key`
45 * Only special keys supported, all others depend on keyboard layout or browser
46 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
47 */
@@ -93,11 +93,7 @@ function getEventKey(nativeEvent) {
93
94 // Browser does not implement `key`, polyfill as much of it as we can.
95 if (nativeEvent.type === 'keypress') {
96 - // Create the character from the `charCode` ourselves and use as an almost
97 - // perfect replacement.
98 - var charCode = 'charCode' in nativeEvent ?
99 - nativeEvent.charCode :
100 - nativeEvent.keyCode;
96 + var charCode = getEventCharCode(nativeEvent);
97
98 // The enter-key is technically both printable and non-printable and can
99 // thus be captured by `keypress`, no other non-printable key should.
@@ -108,8 +104,7 @@ function getEventKey(nativeEvent) {
104 // `keyCode` value, almost all function keys have a universal value.
105 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
106 }
111 -
112 - invariant(false, "Unexpected keyboard event type: %s", nativeEvent.type);
107 + return '';
108 }
109
110 module.exports = getEventKey;