diff --git a/src/renderers/dom/shared/ReactDOMInjection.js b/src/renderers/dom/shared/ReactDOMInjection.js index b9058b8602..24ffdae8da 100644 --- a/src/renderers/dom/shared/ReactDOMInjection.js +++ b/src/renderers/dom/shared/ReactDOMInjection.js @@ -22,7 +22,6 @@ var EventPluginUtils = require('EventPluginUtils'); var HTMLDOMPropertyConfig = require('HTMLDOMPropertyConfig'); var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter'); var ReactDOMComponentTree = require('ReactDOMComponentTree'); -var ReactDOMTreeTraversal = require('ReactDOMTreeTraversal'); var ReactEventListener = require('ReactEventListener'); var SVGDOMPropertyConfig = require('SVGDOMPropertyConfig'); var SelectEventPlugin = require('SelectEventPlugin'); @@ -48,7 +47,6 @@ function inject() { */ EventPluginHub.injection.injectEventPluginOrder(DOMEventPluginOrder); EventPluginUtils.injection.injectComponentTree(ReactDOMComponentTree); - EventPluginUtils.injection.injectTreeTraversal(ReactDOMTreeTraversal); /** * Some important event plugins included by default (without having to require diff --git a/src/renderers/dom/shared/ReactDOMTreeTraversal.js b/src/renderers/dom/shared/ReactDOMTreeTraversal.js deleted file mode 100644 index 72cb838035..0000000000 --- a/src/renderers/dom/shared/ReactDOMTreeTraversal.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ReactDOMTreeTraversal - */ - -'use strict'; - -var invariant = require('invariant'); - -/** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. - */ -function getLowestCommonAncestor(instA, instB) { - invariant('_hostNode' in instA, 'getNodeFromInstance: Invalid argument.'); - invariant('_hostNode' in instB, 'getNodeFromInstance: Invalid argument.'); - - var depthA = 0; - for (var tempA = instA; tempA; tempA = tempA._hostParent) { - depthA++; - } - var depthB = 0; - for (var tempB = instB; tempB; tempB = tempB._hostParent) { - depthB++; - } - - // If A is deeper, crawl up. - while (depthA - depthB > 0) { - instA = instA._hostParent; - depthA--; - } - - // If B is deeper, crawl up. - while (depthB - depthA > 0) { - instB = instB._hostParent; - depthB--; - } - - // Walk in lockstep until we find a match. - var depth = depthA; - while (depth--) { - if (instA === instB) { - return instA; - } - instA = instA._hostParent; - instB = instB._hostParent; - } - return null; -} - -/** - * Return if A is an ancestor of B. - */ -function isAncestor(instA, instB) { - invariant('_hostNode' in instA, 'isAncestor: Invalid argument.'); - invariant('_hostNode' in instB, 'isAncestor: Invalid argument.'); - - while (instB) { - if (instB === instA) { - return true; - } - instB = instB._hostParent; - } - return false; -} - -/** - * Return the parent instance of the passed-in instance. - */ -function getParentInstance(inst) { - invariant('_hostNode' in inst, 'getParentInstance: Invalid argument.'); - - return inst._hostParent; -} - -/** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. - */ -function traverseTwoPhase(inst, fn, arg) { - var path = []; - while (inst) { - path.push(inst); - inst = inst._hostParent; - } - var i; - for (i = path.length; i-- > 0;) { - fn(path[i], 'captured', arg); - } - for (i = 0; i < path.length; i++) { - fn(path[i], 'bubbled', arg); - } -} - -/** - * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that - * should would receive a `mouseEnter` or `mouseLeave` event. - * - * Does not invoke the callback on the nearest common ancestor because nothing - * "entered" or "left" that element. - */ -function traverseEnterLeave(from, to, fn, argFrom, argTo) { - var common = from && to ? getLowestCommonAncestor(from, to) : null; - var pathFrom = []; - while (from && from !== common) { - pathFrom.push(from); - from = from._hostParent; - } - var pathTo = []; - while (to && to !== common) { - pathTo.push(to); - to = to._hostParent; - } - var i; - for (i = 0; i < pathFrom.length; i++) { - fn(pathFrom[i], 'bubbled', argFrom); - } - for (i = pathTo.length; i-- > 0;) { - fn(pathTo[i], 'captured', argTo); - } -} - -module.exports = { - isAncestor: isAncestor, - getLowestCommonAncestor: getLowestCommonAncestor, - getParentInstance: getParentInstance, - traverseTwoPhase: traverseTwoPhase, - traverseEnterLeave: traverseEnterLeave, -}; diff --git a/src/renderers/native/ReactNativeInjection.js b/src/renderers/native/ReactNativeInjection.js index 6f6293fde3..16b8564b58 100644 --- a/src/renderers/native/ReactNativeInjection.js +++ b/src/renderers/native/ReactNativeInjection.js @@ -27,7 +27,6 @@ var ReactNativeComponentTree = require('ReactNativeComponentTree'); var ReactNativeEventEmitter = require('ReactNativeEventEmitter'); var ReactNativeEventPluginOrder = require('ReactNativeEventPluginOrder'); var ReactNativeGlobalResponderHandler = require('ReactNativeGlobalResponderHandler'); -var ReactNativeTreeTraversal = require('ReactNativeTreeTraversal'); var ResponderEventPlugin = require('ResponderEventPlugin'); function inject() { @@ -41,7 +40,6 @@ function inject() { */ EventPluginHub.injection.injectEventPluginOrder(ReactNativeEventPluginOrder); EventPluginUtils.injection.injectComponentTree(ReactNativeComponentTree); - EventPluginUtils.injection.injectTreeTraversal(ReactNativeTreeTraversal); ResponderEventPlugin.injection.injectGlobalResponderHandler( ReactNativeGlobalResponderHandler diff --git a/src/renderers/native/ReactNativeTreeTraversal.js b/src/renderers/shared/shared/ReactTreeTraversal.js similarity index 96% rename from src/renderers/native/ReactNativeTreeTraversal.js rename to src/renderers/shared/shared/ReactTreeTraversal.js index 4e98fa8950..6a2f8b7b8a 100644 --- a/src/renderers/native/ReactNativeTreeTraversal.js +++ b/src/renderers/shared/shared/ReactTreeTraversal.js @@ -6,13 +6,11 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactNativeTreeTraversal + * @providesModule ReactTreeTraversal */ 'use strict'; -// Same as ReactDOMTreeTraversal without the invariants. - /** * Return the lowest common ancestor of A and B, or null if they are in * different trees. diff --git a/src/renderers/dom/shared/__tests__/ReactDOMTreeTraversal-test.js b/src/renderers/shared/shared/__tests__/ReactTreeTraversal-test.js similarity index 91% rename from src/renderers/dom/shared/__tests__/ReactDOMTreeTraversal-test.js rename to src/renderers/shared/shared/__tests__/ReactTreeTraversal-test.js index d68855d30c..1164111544 100644 --- a/src/renderers/dom/shared/__tests__/ReactDOMTreeTraversal-test.js +++ b/src/renderers/shared/shared/__tests__/ReactTreeTraversal-test.js @@ -50,8 +50,8 @@ function renderParentIntoDocument() { return ReactTestUtils.renderIntoDocument(); } -describe('ReactDOMTreeTraversal', () => { - var ReactDOMTreeTraversal; +describe('ReactTreeTraversal', () => { + var ReactTreeTraversal; var aggregatedArgs; function argAggregator(inst, phase, arg) { @@ -67,14 +67,14 @@ describe('ReactDOMTreeTraversal', () => { } beforeEach(() => { - ReactDOMTreeTraversal = require('ReactDOMTreeTraversal'); + ReactTreeTraversal = require('ReactTreeTraversal'); aggregatedArgs = []; }); describe('traverseTwoPhase', () => { it('should not traverse when traversing outside DOM', () => { var expectedAggregation = []; - ReactDOMTreeTraversal.traverseTwoPhase(null, argAggregator, ARG); + ReactTreeTraversal.traverseTwoPhase(null, argAggregator, ARG); expect(aggregatedArgs).toEqual(expectedAggregation); }); @@ -92,7 +92,7 @@ describe('ReactDOMTreeTraversal', () => { {node: parent.refs.P_P1, phase: 'bubbled', arg: ARG}, {node: parent.refs.P, phase: 'bubbled', arg: ARG}, ]; - ReactDOMTreeTraversal.traverseTwoPhase(target, argAggregator, ARG); + ReactTreeTraversal.traverseTwoPhase(target, argAggregator, ARG); expect(aggregatedArgs).toEqual(expectedAggregation); }); @@ -103,7 +103,7 @@ describe('ReactDOMTreeTraversal', () => { {node: parent.refs.P, phase: 'captured', arg: ARG}, {node: parent.refs.P, phase: 'bubbled', arg: ARG}, ]; - ReactDOMTreeTraversal.traverseTwoPhase(target, argAggregator, ARG); + ReactTreeTraversal.traverseTwoPhase(target, argAggregator, ARG); expect(aggregatedArgs).toEqual(expectedAggregation); }); }); @@ -112,7 +112,7 @@ describe('ReactDOMTreeTraversal', () => { it('should not traverse when enter/leaving outside DOM', () => { var target = null; var expectedAggregation = []; - ReactDOMTreeTraversal.traverseEnterLeave( + ReactTreeTraversal.traverseEnterLeave( target, target, argAggregator, ARG, ARG2 ); expect(aggregatedArgs).toEqual(expectedAggregation); @@ -123,7 +123,7 @@ describe('ReactDOMTreeTraversal', () => { var leave = getInst(parent.refs.P_P1_C1.refs.DIV_1); var enter = getInst(parent.refs.P_P1_C1.refs.DIV_1); var expectedAggregation = []; - ReactDOMTreeTraversal.traverseEnterLeave( + ReactTreeTraversal.traverseEnterLeave( leave, enter, argAggregator, ARG, ARG2 ); expect(aggregatedArgs).toEqual(expectedAggregation); @@ -138,7 +138,7 @@ describe('ReactDOMTreeTraversal', () => { // enter/leave shouldn't fire anything on the parent {node: parent.refs.P_P1_C1.refs.DIV_2, phase: 'captured', arg: ARG2}, ]; - ReactDOMTreeTraversal.traverseEnterLeave( + ReactTreeTraversal.traverseEnterLeave( leave, enter, argAggregator, ARG, ARG2 ); expect(aggregatedArgs).toEqual(expectedAggregation); @@ -151,7 +151,7 @@ describe('ReactDOMTreeTraversal', () => { var expectedAggregation = [ {node: parent.refs.P_P1_C1.refs.DIV_1, phase: 'bubbled', arg: ARG}, ]; - ReactDOMTreeTraversal.traverseEnterLeave( + ReactTreeTraversal.traverseEnterLeave( leave, enter, argAggregator, ARG, ARG2 ); expect(aggregatedArgs).toEqual(expectedAggregation); @@ -166,7 +166,7 @@ describe('ReactDOMTreeTraversal', () => { {node: parent.refs.P_P1, phase: 'captured', arg: ARG2}, {node: parent.refs.P_P1_C1.refs.DIV, phase: 'captured', arg: ARG2}, ]; - ReactDOMTreeTraversal.traverseEnterLeave( + ReactTreeTraversal.traverseEnterLeave( leave, enter, argAggregator, ARG, ARG2 ); expect(aggregatedArgs).toEqual(expectedAggregation); @@ -179,7 +179,7 @@ describe('ReactDOMTreeTraversal', () => { var expectedAggregation = [ {node: parent.refs.P, phase: 'captured', arg: ARG2}, ]; - ReactDOMTreeTraversal.traverseEnterLeave( + ReactTreeTraversal.traverseEnterLeave( leave, enter, argAggregator, ARG, ARG2 ); expect(aggregatedArgs).toEqual(expectedAggregation); @@ -194,7 +194,7 @@ describe('ReactDOMTreeTraversal', () => { {node: parent.refs.P_P1, phase: 'bubbled', arg: ARG}, {node: parent.refs.P, phase: 'bubbled', arg: ARG}, ]; - ReactDOMTreeTraversal.traverseEnterLeave( + ReactTreeTraversal.traverseEnterLeave( leave, enter, argAggregator, ARG, ARG2 ); expect(aggregatedArgs).toEqual(expectedAggregation); @@ -209,7 +209,7 @@ describe('ReactDOMTreeTraversal', () => { {node: parent.refs.P_P1, phase: 'bubbled', arg: ARG}, {node: parent.refs.P, phase: 'bubbled', arg: ARG}, ]; - ReactDOMTreeTraversal.traverseEnterLeave( + ReactTreeTraversal.traverseEnterLeave( leave, enter, argAggregator, ARG, ARG2 ); expect(aggregatedArgs).toEqual(expectedAggregation); @@ -261,7 +261,7 @@ describe('ReactDOMTreeTraversal', () => { var i; for (i = 0; i < ancestors.length; i++) { var plan = ancestors[i]; - var firstCommon = ReactDOMTreeTraversal.getLowestCommonAncestor( + var firstCommon = ReactTreeTraversal.getLowestCommonAncestor( getInst(plan.one), getInst(plan.two) ); diff --git a/src/renderers/shared/shared/event/EventPluginUtils.js b/src/renderers/shared/shared/event/EventPluginUtils.js index 4bad7e316d..c2861ddbf5 100644 --- a/src/renderers/shared/shared/event/EventPluginUtils.js +++ b/src/renderers/shared/shared/event/EventPluginUtils.js @@ -11,6 +11,7 @@ 'use strict'; +var ReactTreeTraversal = require('ReactTreeTraversal'); var ReactErrorUtils = require('ReactErrorUtils'); var invariant = require('invariant'); @@ -25,7 +26,6 @@ var warning = require('warning'); * and actual node references. */ var ComponentTree; -var TreeTraversal; var injection = { injectComponentTree: function(Injected) { ComponentTree = Injected; @@ -39,16 +39,6 @@ var injection = { ); } }, - injectTreeTraversal: function(Injected) { - TreeTraversal = Injected; - if (__DEV__) { - warning( - Injected && Injected.isAncestor && Injected.getLowestCommonAncestor, - 'EventPluginUtils.injection.injectTreeTraversal(...): Injected ' + - 'module is missing isAncestor or getLowestCommonAncestor.' - ); - } - }, }; function isEndish(topLevelType) { @@ -237,19 +227,19 @@ var EventPluginUtils = { return ComponentTree.getNodeFromInstance(node); }, isAncestor: function(a, b) { - return TreeTraversal.isAncestor(a, b); + return ReactTreeTraversal.isAncestor(a, b); }, getLowestCommonAncestor: function(a, b) { - return TreeTraversal.getLowestCommonAncestor(a, b); + return ReactTreeTraversal.getLowestCommonAncestor(a, b); }, getParentInstance: function(inst) { - return TreeTraversal.getParentInstance(inst); + return ReactTreeTraversal.getParentInstance(inst); }, traverseTwoPhase: function(target, fn, arg) { - return TreeTraversal.traverseTwoPhase(target, fn, arg); + return ReactTreeTraversal.traverseTwoPhase(target, fn, arg); }, traverseEnterLeave: function(from, to, fn, argFrom, argTo) { - return TreeTraversal.traverseEnterLeave(from, to, fn, argFrom, argTo); + return ReactTreeTraversal.traverseEnterLeave(from, to, fn, argFrom, argTo); }, injection: injection, diff --git a/src/renderers/shared/shared/event/eventPlugins/__tests__/ResponderEventPlugin-test.js b/src/renderers/shared/shared/event/eventPlugins/__tests__/ResponderEventPlugin-test.js index 584863a10f..4c95a3e316 100644 --- a/src/renderers/shared/shared/event/eventPlugins/__tests__/ResponderEventPlugin-test.js +++ b/src/renderers/shared/shared/event/eventPlugins/__tests__/ResponderEventPlugin-test.js @@ -408,20 +408,9 @@ describe('ResponderEventPlugin', () => { beforeEach(() => { jest.resetModuleRegistry(); - EventPluginHub = require('EventPluginHub'); - EventPluginUtils = require('EventPluginUtils'); - ResponderEventPlugin = require('ResponderEventPlugin'); - - EventPluginUtils.injection.injectComponentTree({ - getInstanceFromNode: function(id) { - return idToInstance[id]; - }, - getNodeFromInstance: function(inst) { - return inst._rootNodeID; - }, - }); - - EventPluginUtils.injection.injectTreeTraversal({ + // Inline mock + const ReactTreeTraversal = require('ReactTreeTraversal'); + Object.assign(ReactTreeTraversal, { isAncestor: function(a, b) { return isAncestorIDOf(a._rootNodeID, b._rootNodeID); }, @@ -443,6 +432,19 @@ describe('ResponderEventPlugin', () => { ); }, }); + + EventPluginHub = require('EventPluginHub'); + EventPluginUtils = require('EventPluginUtils'); + ResponderEventPlugin = require('ResponderEventPlugin'); + + EventPluginUtils.injection.injectComponentTree({ + getInstanceFromNode: function(id) { + return idToInstance[id]; + }, + getNodeFromInstance: function(inst) { + return inst._rootNodeID; + }, + }); }); it('should do nothing when no one wants to respond', () => {