Fix ResponderEventPlugin to work in core React again
Test Plan: jest, grunt fasttest
Ben Alpert committed
Mar 31, 2015 at 15:26 UTC
5a01f5f6a9b55b1771fa5ebb2aa5d3ab1afc0297
8 files changed
+41
-49
src/core/ReactInstanceHandles.js
+3
-6
@@ -115,7 +115,8 @@ function getNextDescendantID(ancestorID, destinationID) {
115
// Skip over the ancestor and the immediate separator. Traverse until we hit
116
// another separator or we reach the end of `destinationID`.
117
var start = ancestorID.length + SEPARATOR_LENGTH;
118
- for (var i = start; i < destinationID.length; i++) {
118
+ var i;
119
+ for (i = start; i < destinationID.length; i++) {
120
if (isBoundary(destinationID, i)) {
121
break;
122
}
@@ -320,11 +321,7 @@ var ReactInstanceHandles = {
321
traverseParentPath('', targetID, cb, arg, true, false);
322
},
323
323
- /**
324
- * Exposed for unit testing.
325
- * @private
326
- */
327
- _getFirstCommonAncestorID: getFirstCommonAncestorID,
324
+ getFirstCommonAncestorID: getFirstCommonAncestorID,
325
326
/**
327
* Exposed for unit testing.
src/core/__tests__/ReactInstanceHandles-test.js
+1
-1
@@ -408,7 +408,7 @@ describe('ReactInstanceHandles', function() {
408
var i;
409
for (i = 0; i < ancestors.length; i++) {
410
var plan = ancestors[i];
411
- var firstCommon = ReactInstanceHandles._getFirstCommonAncestorID(
411
+ var firstCommon = ReactInstanceHandles.getFirstCommonAncestorID(
412
getNodeID(plan.one),
413
getNodeID(plan.two)
414
);
src/event/EventPluginUtils.js
+10
-2
@@ -30,9 +30,9 @@ var injection = {
30
injection.Mount = InjectedMount;
31
if (__DEV__) {
32
warning(
33
- InjectedMount && InjectedMount.getNode,
33
+ InjectedMount && InjectedMount.getNode && InjectedMount.getID,
34
'EventPluginUtils.injection.injectMount(...): Injected Mount ' +
35
- 'module is missing getNode.'
35
+ 'module is missing getNode or getID.'
36
);
37
}
38
}
@@ -211,6 +211,14 @@ var EventPluginUtils = {
211
executeDispatchesInOrder: executeDispatchesInOrder,
212
executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue,
213
hasDispatches: hasDispatches,
214
+
215
+ getNode: function(id) {
216
+ return injection.Mount.getNode(id);
217
+ },
218
+ getID: function(node) {
219
+ return injection.Mount.getID(node);
220
+ },
221
+
222
injection: injection
223
};
224
src/event/EventPropagators.js
+6
-3
@@ -14,6 +14,8 @@
14
var EventConstants = require('EventConstants');
15
var EventPluginHub = require('EventPluginHub');
16
17
+var warning = require('warning');
18
+
19
var accumulateInto = require('accumulateInto');
20
var forEachAccumulated = require('forEachAccumulated');
21
@@ -38,9 +40,10 @@ function listenerAtPhase(id, event, propagationPhase) {
40
*/
41
function accumulateDirectionalDispatches(domID, upwards, event) {
42
if (__DEV__) {
41
- if (!domID) {
42
- throw new Error('Dispatching id must not be null');
43
- }
43
+ warning(
44
+ domID,
45
+ 'Dispatching id must not be null'
46
+ );
47
}
48
var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured;
49
var listener = listenerAtPhase(domID, event, phase);
src/event/eventPlugins/ResponderEventPlugin.js
+7
-8
@@ -14,7 +14,6 @@
14
var EventConstants = require('EventConstants');
15
var EventPluginUtils = require('EventPluginUtils');
16
var EventPropagators = require('EventPropagators');
17
-var NodeHandle = require('NodeHandle');
17
var ReactInstanceHandles = require('ReactInstanceHandles');
18
var ResponderSyntheticEvent = require('ResponderSyntheticEvent');
19
var ResponderTouchHistoryStore = require('ResponderTouchHistoryStore');
@@ -133,7 +132,7 @@ var eventTypes = {
132
* ----------------
133
*
134
* - A global, solitary "interaction lock" on a view.
136
- * - If a `NodeHandle` becomes the responder, it should convey visual feedback
135
+ * - If a node becomes the responder, it should convey visual feedback
136
* immediately to indicate so, either by highlighting or moving accordingly.
137
* - To be the responder means, that touches are exclusively important to that
138
* responder view, and no other view.
@@ -337,7 +336,7 @@ function setResponderAndExtractTransfer(
336
// TODO: stop one short of the the current responder.
337
var bubbleShouldSetFrom = !responderID ?
338
topLevelTargetID :
340
- ReactInstanceHandles._getFirstCommonAncestorID(responderID, topLevelTargetID);
339
+ ReactInstanceHandles.getFirstCommonAncestorID(responderID, topLevelTargetID);
340
341
// When capturing/bubbling the "shouldSet" event, we want to skip the target
342
// (deepest ID) if it happens to be the current responder. The reasoning:
@@ -450,12 +449,12 @@ function noResponderTouches(nativeEvent) {
449
var target = activeTouch.target;
450
if (target !== null && target !== undefined && target !== 0) {
451
// Is the original touch location inside of the current responder?
453
- var commonAncestor =
454
- ReactInstanceHandles._getFirstCommonAncestorID(
452
+ var isAncestor =
453
+ ReactInstanceHandles.isAncestorIDOf(
454
responderID,
456
- NodeHandle.getRootNodeID(target)
455
+ EventPluginUtils.getID(target)
456
);
458
- if (commonAncestor === responderID) {
457
+ if (isAncestor) {
458
return false;
459
}
460
}
@@ -585,7 +584,7 @@ var ResponderEventPlugin = {
584
*/
585
injectGlobalInteractionHandler: function(GlobalInteractionHandler) {
586
ResponderEventPlugin.GlobalInteractionHandler = GlobalInteractionHandler;
588
- },
587
+ }
588
}
589
};
590
src/event/eventPlugins/ResponderSyntheticEvent.js
+2
-2
@@ -10,7 +10,7 @@
10
* @typechecks static-only
11
*/
12
13
-"use strict";
13
+'use strict';
14
15
var SyntheticEvent = require('SyntheticEvent');
16
@@ -22,7 +22,7 @@ var SyntheticEvent = require('SyntheticEvent');
22
var ResponderEventInterface = {
23
touchHistory: function(nativeEvent) {
24
return null; // Actually doesn't even look at the native event.
25
- },
25
+ }
26
};
27
28
/**
src/event/eventPlugins/ResponderTouchHistoryStore.js
+4
-4
@@ -9,7 +9,7 @@
9
* @providesModule ResponderTouchHistoryStore
10
*/
11
12
-"use strict";
12
+'use strict';
13
14
var EventPluginUtils = require('EventPluginUtils');
15
@@ -43,7 +43,7 @@ var touchHistory = {
43
// us having to loop through all of the touches all the time in the most
44
// common case.
45
indexOfSingleActiveTouch: -1,
46
- mostRecentTimeStamp: 0,
46
+ mostRecentTimeStamp: 0
47
};
48
49
var timestampForTouch = function(touch) {
@@ -69,7 +69,7 @@ var initializeTouchData = function(touch) {
69
currentTimeStamp: timestampForTouch(touch),
70
previousPageX: touch.pageX,
71
previousPageY: touch.pageY,
72
- previousTimeStamp: timestampForTouch(touch),
72
+ previousTimeStamp: timestampForTouch(touch)
73
};
74
};
75
@@ -178,7 +178,7 @@ var ResponderTouchHistoryStore = {
178
}
179
},
180
181
- touchHistory: touchHistory,
181
+ touchHistory: touchHistory
182
};
183
184
src/event/eventPlugins/__tests__/ResponderEventPlugin-test.js
+8
-23
@@ -11,12 +11,9 @@
11
12
'use strict';
13
14
-jest.autoMockOff();
15
-
14
var EventPluginHub;
15
var EventConstants;
16
var EventPropagators;
19
-var NodeHandle;
17
var ReactInstanceHandles;
18
var ResponderEventPlugin;
19
var SyntheticEvent;
@@ -30,8 +27,6 @@ var CHILD_ID2 = '.0.0.1';
27
var topLevelTypes;
28
var responderEventTypes;
29
33
-var eachKeyVal = require('eachKeyVal');
34
-
30
var touch = function(nodeHandle, i) {
31
return {target: nodeHandle, identifier: i};
32
};
@@ -92,7 +87,7 @@ var _touchConfig =
87
changedTouchObjects
88
),
89
topLevelType: topType,
95
- target: targetNodeHandle, // Because of our injected `NodeHandle` impl.
90
+ target: targetNodeHandle,
91
targetID: targetNodeHandle,
92
};
93
};
@@ -240,7 +235,8 @@ var registerTestHandlers = function(eventTestConfig, readableIDToID) {
235
EventPluginHub.putListener(id, registrationName, handler);
236
}
237
};
243
- eachKeyVal(eventTestConfig, function(eventName, oneEventTypeTestConfig) {
238
+ for (var eventName in eventTestConfig) {
239
+ var oneEventTypeTestConfig = eventTestConfig[eventName];
240
var hasTwoPhase = !!oneEventTypeTestConfig.bubbled;
241
if (hasTwoPhase) {
242
registerOneEventType(
@@ -257,7 +253,7 @@ var registerTestHandlers = function(eventTestConfig, readableIDToID) {
253
oneEventTypeTestConfig
254
);
255
}
260
- });
256
+ }
257
return runs;
258
};
259
@@ -321,36 +317,25 @@ var siblings = {
317
318
describe('ResponderEventPlugin', function() {
319
beforeEach(function() {
324
- jest.resetModuleRegistry();
320
+ require('mock-modules').dumpCache();
321
322
EventConstants = require('EventConstants');
323
EventPluginHub = require('EventPluginHub');
324
EventPluginUtils = require('EventPluginUtils');
325
EventPropagators = require('EventPropagators');
330
- NodeHandle = require('NodeHandle');
326
ReactInstanceHandles = require('ReactInstanceHandles');
327
ResponderEventPlugin = require('ResponderEventPlugin');
328
SyntheticEvent = require('SyntheticEvent');
329
330
EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles);
331
337
- // dumpCache, in open-source tests, only resets existing mocks. It does not
338
- // reset module-state though -- so we need to do this explicitly in the test
339
- // for now. Once that's no longer the case, we can delete this line.
340
- EventPluginHub.__purge();
332
// Only needed because SyntheticEvent supports the `currentTarget`
333
// property.
334
EventPluginUtils.injection.injectMount({
335
getNode: function(id) {
345
- return id + '_thisDoesntReallyMatterForThisTestCase';
346
- }
347
- });
348
-
349
- // Raw event stream event `.target`s must be `NodeHandle`s. For these test
350
- // cases, we'll assume that we create the node handles as the exact IDs
351
- // they represent.
352
- NodeHandle.injection.injectImplementation({
353
- getRootNodeID: function(nodeHandle) {
336
+ return id;
337
+ },
338
+ getID: function(nodeHandle) {
339
return nodeHandle;
340
}
341
});