Skip to content

Commit

Permalink
Set currentTarget on synthetic events
Browse files Browse the repository at this point in the history
  • Loading branch information
sophiebits committed Jan 4, 2014
1 parent 80d7d2d commit 33dcf8a
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 10 deletions.
4 changes: 3 additions & 1 deletion src/core/ReactDefaultInjection.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var ReactDOMSelect = require('ReactDOMSelect');
var ReactDOMTextarea = require('ReactDOMTextarea');
var ReactEventEmitter = require('ReactEventEmitter');
var ReactEventTopLevelCallback = require('ReactEventTopLevelCallback');
var ReactMount = require('ReactMount');
var ReactPerf = require('ReactPerf');
var ReactRootIndex = require('ReactRootIndex');

Expand All @@ -53,10 +54,11 @@ var ReactUpdates = require('ReactUpdates');
function inject() {
ReactEventEmitter.TopLevelCallbackCreator = ReactEventTopLevelCallback;
/**
* Inject module for resolving DOM hierarchy and plugin ordering.
* Inject modules for resolving DOM hierarchy and plugin ordering.
*/
EventPluginHub.injection.injectEventPluginOrder(DefaultEventPluginOrder);
EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles);
EventPluginHub.injection.injectMount(ReactMount);

/**
* Some important event plugins included by default (without having to require
Expand Down
51 changes: 47 additions & 4 deletions src/core/__tests__/ReactEventEmitter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,16 @@ require('mock-modules')
var keyOf = require('keyOf');
var mocks = require('mocks');

var EventPluginHub;
var ReactMount = require('ReactMount');
var idToNode = {};
var getID = ReactMount.getID;
var setID = ReactMount.setID;
var setID = function(el, id) {
ReactMount.setID(el, id);
idToNode[id] = el;
};
var oldGetNode = ReactMount.getNode;

var EventPluginHub;
var ReactEventEmitter;
var ReactTestUtils;
var TapEventPlugin;
Expand Down Expand Up @@ -93,17 +99,22 @@ describe('ReactEventEmitter', function() {
TapEventPlugin = require('TapEventPlugin');
ReactMount = require('ReactMount');
EventListener = require('EventListener');
getID = ReactMount.getID;
setID = ReactMount.setID;
ReactEventEmitter = require('ReactEventEmitter');
ReactTestUtils = require('ReactTestUtils');
ReactMount.getNode = function(id) {
return idToNode[id];
};
idCallOrder = [];
tapMoveThreshold = TapEventPlugin.tapMoveThreshold;
EventPluginHub.injection.injectEventPluginsByName({
TapEventPlugin: TapEventPlugin
});
});

afterEach(function() {
ReactMount.getNode = oldGetNode;
});

it('should store a listener correctly', function() {
registerSimpleTestHandler();
var listener = ReactEventEmitter.getListener(getID(CHILD), ON_CLICK_KEY);
Expand Down Expand Up @@ -162,6 +173,38 @@ describe('ReactEventEmitter', function() {
expect(idCallOrder[2]).toBe(getID(GRANDPARENT));
});

it('should set currentTarget', function() {
ReactEventEmitter.putListener(
getID(CHILD),
ON_CLICK_KEY,
function(event) {
recordID(getID(CHILD));
expect(event.currentTarget).toBe(CHILD);
}
);
ReactEventEmitter.putListener(
getID(PARENT),
ON_CLICK_KEY,
function(event) {
recordID(getID(PARENT));
expect(event.currentTarget).toBe(PARENT);
}
);
ReactEventEmitter.putListener(
getID(GRANDPARENT),
ON_CLICK_KEY,
function(event) {
recordID(getID(GRANDPARENT));
expect(event.currentTarget).toBe(GRANDPARENT);
}
);
ReactTestUtils.Simulate.click(CHILD);
expect(idCallOrder.length).toBe(3);
expect(idCallOrder[0]).toBe(getID(CHILD));
expect(idCallOrder[1]).toBe(getID(PARENT));
expect(idCallOrder[2]).toBe(getID(GRANDPARENT));
});

it('should support stopPropagation()', function() {
ReactEventEmitter.putListener(
getID(CHILD),
Expand Down
6 changes: 6 additions & 0 deletions src/event/EventPluginHub.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ var EventPluginHub = {
*/
injection: {

/**
* @param {object} InjectedMount
* @public
*/
injectMount: EventPluginUtils.injection.injectMount,

/**
* @param {object} InjectedInstanceHandle
* @public
Expand Down
34 changes: 31 additions & 3 deletions src/event/EventPluginUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,28 @@ var EventConstants = require('EventConstants');

var invariant = require('invariant');

/**
* Injected dependencies:
*/

/**
* - `Mount`: [required] Module that can convert between React dom IDs and
* actual node references.
*/
var injection = {
Mount: null,
injectMount: function(InjectedMount) {
injection.Mount = InjectedMount;
if (__DEV__) {
invariant(
InjectedMount && InjectedMount.getNode,
'EventPluginUtils.injection.injectMount(...): Injected Mount module ' +
'is missing getNode.'
);
}
}
};

var topLevelTypes = EventConstants.topLevelTypes;

function isEndish(topLevelType) {
Expand All @@ -39,6 +61,7 @@ function isStartish(topLevelType) {
topLevelType === topLevelTypes.topTouchStart;
}


var validateEventDispatches;
if (__DEV__) {
validateEventDispatches = function(event) {
Expand Down Expand Up @@ -90,7 +113,10 @@ function forEachEventDispatch(event, cb) {
* @param {string} domID DOM id to pass to the callback.
*/
function executeDispatch(event, listener, domID) {
listener(event, domID);
event.currentTarget = injection.Mount.getNode(domID);
var returnValue = listener(event, domID);
event.currentTarget = null;
return returnValue;
}

/**
Expand Down Expand Up @@ -175,11 +201,13 @@ var EventPluginUtils = {
isEndish: isEndish,
isMoveish: isMoveish,
isStartish: isStartish,

executeDirectDispatch: executeDirectDispatch,
executeDispatch: executeDispatch,
executeDispatchesInOrder: executeDispatchesInOrder,
executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue,
executeDirectDispatch: executeDirectDispatch,
hasDispatches: hasDispatches,
executeDispatch: executeDispatch,
injection: injection,
useTouchEvents: false
};

Expand Down
3 changes: 2 additions & 1 deletion src/event/synthetic/SyntheticEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ var mergeInto = require('mergeInto');
var EventInterface = {
type: null,
target: getEventTarget,
currentTarget: null,
// currentTarget is set when dispatching; no use in copying it here
currentTarget: emptyFunction.thatReturnsNull,
eventPhase: null,
bubbles: null,
cancelable: null,
Expand Down
3 changes: 2 additions & 1 deletion src/eventPlugins/SimpleEventPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"use strict";

var EventConstants = require('EventConstants');
var EventPluginUtils = require('EventPluginUtils');
var EventPropagators = require('EventPropagators');
var SyntheticClipboardEvent = require('SyntheticClipboardEvent');
var SyntheticEvent = require('SyntheticEvent');
Expand Down Expand Up @@ -270,7 +271,7 @@ var SimpleEventPlugin = {
* @param {string} domID DOM ID to pass to the callback.
*/
executeDispatch: function(event, listener, domID) {
var returnValue = listener(event, domID);
var returnValue = EventPluginUtils.executeDispatch(event, listener, domID);
if (returnValue === false) {
event.stopPropagation();
event.preventDefault();
Expand Down

0 comments on commit 33dcf8a

Please sign in to comment.