mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
Use KeyboardEvent.char in the fallback logic if available (#9792)
When a user types an emoji via Touch keyboard in IE, React's fallback logic creates the `BeforeInput` event based on the `keypress`. However, the length of an emoji character (e.g. `\uD83D\uDE0A`) is two, so the `which` property does not represent an emoji correctly. Because IE's KeyboardEvent has the `char` property holding an entire emoji, we can use it directly instead of converting from the `which`.
This commit is contained in:
@@ -374,8 +374,18 @@ function getFallbackBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
|
||||
* being used. Ex: `Cmd+C`. No character is inserted, and no
|
||||
* `input` event will occur.
|
||||
*/
|
||||
if (nativeEvent.which && !isKeypressCommand(nativeEvent)) {
|
||||
return String.fromCharCode(nativeEvent.which);
|
||||
if (!isKeypressCommand(nativeEvent)) {
|
||||
// IE fires the `keypress` event when a user types an emoji via
|
||||
// Touch keyboard of Windows. In such a case, the `char` property
|
||||
// holds an emoji character like `\uD83D\uDE0A`. Because its length
|
||||
// is 2, the property `which` does not represent an emoji correctly.
|
||||
// In such a case, we directly return the `char` property instead of
|
||||
// using `which`.
|
||||
if (nativeEvent.char && nativeEvent.char.length > 1) {
|
||||
return nativeEvent.char;
|
||||
} else if (nativeEvent.which) {
|
||||
return String.fromCharCode(nativeEvent.which);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
case 'topCompositionEnd':
|
||||
|
||||
@@ -19,6 +19,7 @@ var EventMapping = {
|
||||
compositionend: 'topCompositionEnd',
|
||||
keyup: 'topKeyUp',
|
||||
keydown: 'topKeyDown',
|
||||
keypress: 'topKeyPress',
|
||||
textInput: 'topTextInput',
|
||||
textinput: null, // Not defined now
|
||||
};
|
||||
@@ -122,7 +123,8 @@ describe('BeforeInputEventPlugin', function() {
|
||||
// instead of a standard name `textInput`. As of now, React does not have
|
||||
// a corresponding topEvent to IE's textinput, but both events are added to
|
||||
// this scenario data for future use.
|
||||
var Scenario_Composition = [
|
||||
var Test_Scenario = [
|
||||
// Composition test
|
||||
{run: accumulateEvents, arg: ['compositionstart', {data: ''}]},
|
||||
{run: accumulateEvents, arg: ['textInput', {data: 'A'}]},
|
||||
{run: accumulateEvents, arg: ['textinput', {data: 'A'}]},
|
||||
@@ -136,6 +138,13 @@ describe('BeforeInputEventPlugin', function() {
|
||||
{run: accumulateEvents, arg: ['textinput', {data: 'xyz'}]},
|
||||
{run: accumulateEvents, arg: ['keyup', {keyCode: 32}]},
|
||||
{run: accumulateEvents, arg: ['compositionend', {data: 'Hello'}]},
|
||||
|
||||
// Emoji test
|
||||
{
|
||||
run: accumulateEvents,
|
||||
arg: ['keypress', {char: '\uD83D\uDE0A', which: 65}],
|
||||
},
|
||||
{run: accumulateEvents, arg: ['textInput', {data: '\uD83D\uDE0A'}]},
|
||||
];
|
||||
|
||||
/* Defined expected results as a factory of result data because we need
|
||||
@@ -170,6 +179,12 @@ describe('BeforeInputEventPlugin', function() {
|
||||
{type: null}, // keyUp of 32
|
||||
{type: ModuleCache.SyntheticCompositionEvent, data: {data: 'Hello'}},
|
||||
{type: null},
|
||||
|
||||
// Emoji test
|
||||
{type: null},
|
||||
{type: null},
|
||||
{type: null},
|
||||
{type: ModuleCache.SyntheticInputEvent, data: {data: '\uD83D\uDE0A'}},
|
||||
];
|
||||
|
||||
// For IE11, we use fallback data instead of IE's textinput events.
|
||||
@@ -205,6 +220,12 @@ describe('BeforeInputEventPlugin', function() {
|
||||
// at a time of compositionend
|
||||
{type: ModuleCache.SyntheticCompositionEvent, data: {}},
|
||||
{type: ModuleCache.SyntheticInputEvent, data: {data: 'XYZ'}},
|
||||
|
||||
// Emoji test
|
||||
{type: null},
|
||||
{type: ModuleCache.SyntheticInputEvent, data: {data: '\uD83D\uDE0A'}},
|
||||
{type: null},
|
||||
{type: null},
|
||||
];
|
||||
|
||||
function TestEditableReactComponent(Emulator, Scenario, ExpectedResult) {
|
||||
@@ -225,18 +246,10 @@ describe('BeforeInputEventPlugin', function() {
|
||||
}
|
||||
|
||||
it('extract onBeforeInput from native textinput events', function() {
|
||||
TestEditableReactComponent(
|
||||
simulateWebkit,
|
||||
Scenario_Composition,
|
||||
Expected_Webkit,
|
||||
);
|
||||
TestEditableReactComponent(simulateWebkit, Test_Scenario, Expected_Webkit);
|
||||
});
|
||||
|
||||
it('extract onBeforeInput from fallback objects', function() {
|
||||
TestEditableReactComponent(
|
||||
simulateIE11,
|
||||
Scenario_Composition,
|
||||
Expected_IE11,
|
||||
);
|
||||
TestEditableReactComponent(simulateIE11, Test_Scenario, Expected_IE11);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user