diff --git a/src/renderers/dom/client/eventPlugins/SimpleEventPlugin.js b/src/renderers/dom/client/eventPlugins/SimpleEventPlugin.js index f790e3fe9b44..2c2f075b4bef 100644 --- a/src/renderers/dom/client/eventPlugins/SimpleEventPlugin.js +++ b/src/renderers/dom/client/eventPlugins/SimpleEventPlugin.js @@ -487,7 +487,7 @@ var SimpleEventPlugin = { eventTypes: eventTypes, - extractEvents: function( + extractEventConstructor: function( topLevelType, targetInst, nativeEvent, @@ -604,8 +604,27 @@ var SimpleEventPlugin = { 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType ); + return EventConstructor; + }, + + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) { + var EventConstructor = SimpleEventPlugin.extractEventConstructor( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ); + if (!EventConstructor) { + return null; + } + var event = EventConstructor.getPooled( - dispatchConfig, + topLevelEventsToDispatchConfig[topLevelType], targetInst, nativeEvent, nativeEventTarget diff --git a/src/test/ReactTestUtils.js b/src/test/ReactTestUtils.js index f331bf6e22b9..28cb75eb81df 100644 --- a/src/test/ReactTestUtils.js +++ b/src/test/ReactTestUtils.js @@ -472,6 +472,12 @@ ReactShallowRenderer.prototype._render = function(element, transaction, context) * - ... (All keys from event plugin `eventTypes` objects) */ function makeSimulator(eventType) { + var dispatchConfig = EventPluginRegistry.eventNameDispatchConfigs[eventType]; + // Get the topLevelType so we can extract the right SyntheticEvent type so we + // copy properties correctly from the native event and also get our warnings + // related to pooling. + var topLevelType = EventConstants.topLevelTypes[dispatchConfig.dependencies[0]]; + return function(domComponentOrNode, eventData) { var node; invariant( @@ -485,20 +491,30 @@ function makeSimulator(eventType) { node = domComponentOrNode; } - var dispatchConfig = - EventPluginRegistry.eventNameDispatchConfigs[eventType]; + var EventPlugin = EventPluginRegistry.getPluginModuleForEvent({dispatchConfig}); + // Assign the extra event data to the native event, ensuring we copy they + // correct data over for a given event. Other fields will be dropped. var fakeNativeEvent = new Event(); - fakeNativeEvent.target = node; + Object.assign(fakeNativeEvent, {target: node}, eventData); + + var inst = ReactDOMComponentTree.getInstanceFromNode(node); + + var SyntheticEventConstructor = EventPlugin.extractEventConstructor( + topLevelType, + domComponentOrNode, + fakeNativeEvent, + node + ); + // We don't use SyntheticEvent.getPooled in order to not have to worry about // properly destroying any properties assigned from `eventData` upon release - var event = new SyntheticEvent( + var event = new SyntheticEventConstructor( dispatchConfig, - ReactDOMComponentTree.getInstanceFromNode(node), + domComponentOrNode, fakeNativeEvent, node ); - Object.assign(event, eventData); if (dispatchConfig.phasedRegistrationNames) { EventPropagators.accumulateTwoPhaseDispatches(event); diff --git a/src/test/__tests__/ReactTestUtils-test.js b/src/test/__tests__/ReactTestUtils-test.js index a7cf4ab84653..81fda9cebf65 100644 --- a/src/test/__tests__/ReactTestUtils-test.js +++ b/src/test/__tests__/ReactTestUtils-test.js @@ -474,6 +474,29 @@ describe('ReactTestUtils', function() { expect(handler).not.toHaveBeenCalled(); }); + it('should not warn when simulating events with extra properties', function() { + spyOn(console, 'error'); + + var CLIENT_X = 100; + + var Component = React.createClass({ + handleClick: function(e) { + expect(e.clientX).toBe(CLIENT_X); + }, + render: function() { + return
; + }, + }); + + var element = document.createElement('div'); + var instance = ReactDOM.render(