Skip to content

Commit

Permalink
Prevent BeforeInputPlugin from returning [null, null] (#11848)
Browse files Browse the repository at this point in the history
The BeforeInputPlugin dispatches null elements in an array if
composition or beforeInput events are not extracted. This causes a
an extra array allocation, but more importantly creates null states in
later event dispatch methods that are annoying to account for.

This commit makes it so that BeforeInputPlugin never returns a null
element inside an array.
  • Loading branch information
nhunzaker authored Dec 14, 2017
1 parent 8ec146c commit cc52e06
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 62 deletions.
37 changes: 23 additions & 14 deletions packages/react-dom/src/events/BeforeInputEventPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,20 +453,29 @@ const BeforeInputEventPlugin = {
nativeEvent,
nativeEventTarget,
) {
return [
extractCompositionEvent(
topLevelType,
targetInst,
nativeEvent,
nativeEventTarget,
),
extractBeforeInputEvent(
topLevelType,
targetInst,
nativeEvent,
nativeEventTarget,
),
];
const composition = extractCompositionEvent(
topLevelType,
targetInst,
nativeEvent,
nativeEventTarget,
);

const beforeInput = extractBeforeInputEvent(
topLevelType,
targetInst,
nativeEvent,
nativeEventTarget,
);

if (composition === null) {
return beforeInput;
}

if (beforeInput === null) {
return composition;
}

return [composition, beforeInput];
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ describe('BeforeInputEventPlugin', function() {
return function() {
const newArgs = [node].concat(Array.prototype.slice.call(arguments));
const newEvents = extract.apply(this, newArgs);
Array.prototype.push.apply(events, newEvents);

if (Array.isArray(newEvents)) {
Array.prototype.push.apply(events, newEvents);
} else if (newEvents) {
events.push(newEvents);
}
};
}

Expand Down Expand Up @@ -156,32 +161,17 @@ describe('BeforeInputEventPlugin', function() {
// keyUp.
const Expected_Webkit = () => [
{type: ModuleCache.SyntheticCompositionEvent, data: {}},
{type: null},
{type: null},
{type: ModuleCache.SyntheticInputEvent, data: {data: 'A'}},
{type: null},
{type: null}, // textinput of A
{type: null},
{type: null}, // keyUp of 65
{type: null},
// textinput of A
// keyUp of 65
{type: ModuleCache.SyntheticInputEvent, data: {data: 'abc'}},
{type: null},
{type: null}, // textinput of abc
{type: null},
{type: null}, // keyUp of 32
{type: null},
// textinput of abc
// keyUp of 32
{type: ModuleCache.SyntheticInputEvent, data: {data: 'xyz'}},
{type: null},
{type: null}, // textinput of xyz
{type: null},
{type: null}, // keyUp of 32
// textinput of xyz
// 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'}},
];

Expand All @@ -191,39 +181,22 @@ describe('BeforeInputEventPlugin', function() {
// element, not event data.
const Expected_IE11 = () => [
{type: ModuleCache.SyntheticCompositionEvent, data: {}},
{type: null},
{type: null},
{type: null}, // textInput of A
{type: null},
{type: null}, // textinput of A
{type: null},
{type: null}, // keyUp of 65
{type: null},
{type: null}, // textInput of abc
{type: null},
{type: null}, // textinput of abc

// textInput of A
// textinput of A
// keyUp of 65
// textInput of abc
// textinput of abc
// fallbackData should NOT be set at keyUp with any of END_KEYCODES
{type: null},
{type: null}, // keyUp of 32

{type: null},
{type: null}, // textInput of xyz
{type: null},
{type: null}, // textinput of xyz
{type: null},
{type: null}, // keyUp of 32

// keyUp of 32
// textInput of xyz
// textinput of xyz
// keyUp of 32
// fallbackData is retrieved from the element, which is XYZ,
// 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) {
Expand Down

0 comments on commit cc52e06

Please sign in to comment.