diff --git a/src/isomorphic/classic/element/ReactCurrentOwner.js b/src/isomorphic/classic/element/ReactCurrentOwner.js index fe90c214ef553..720de0acc4806 100644 --- a/src/isomorphic/classic/element/ReactCurrentOwner.js +++ b/src/isomorphic/classic/element/ReactCurrentOwner.js @@ -10,7 +10,6 @@ 'use strict'; -import type {ReactInstance} from 'ReactInstanceType'; import type {Fiber} from 'ReactFiber'; /** @@ -24,7 +23,7 @@ var ReactCurrentOwner = { * @internal * @type {ReactComponent} */ - current: (null: null | ReactInstance | Fiber), + current: (null: null | Fiber), }; module.exports = ReactCurrentOwner; diff --git a/src/renderers/dom/fiber/ReactDOMFiberEntry.js b/src/renderers/dom/fiber/ReactDOMFiberEntry.js index 7edda99d997f9..aca08cbb0d29e 100644 --- a/src/renderers/dom/fiber/ReactDOMFiberEntry.js +++ b/src/renderers/dom/fiber/ReactDOMFiberEntry.js @@ -229,7 +229,7 @@ var DOMRenderer = ReactFiberReconciler({ if (__DEV__) { // TODO: take namespace into account when validating. const hostContextDev = ((hostContext: any): HostContextDev); - validateDOMNesting(type, null, null, hostContextDev.ancestorInfo); + validateDOMNesting(type, null, hostContextDev.ancestorInfo); if ( typeof props.children === 'string' || typeof props.children === 'number' @@ -240,7 +240,7 @@ var DOMRenderer = ReactFiberReconciler({ type, null, ); - validateDOMNesting(null, string, null, ownAncestorInfo); + validateDOMNesting(null, string, ownAncestorInfo); } parentNamespace = hostContextDev.namespace; } else { @@ -295,7 +295,7 @@ var DOMRenderer = ReactFiberReconciler({ type, null, ); - validateDOMNesting(null, string, null, ownAncestorInfo); + validateDOMNesting(null, string, ownAncestorInfo); } } return diffProperties( @@ -362,7 +362,7 @@ var DOMRenderer = ReactFiberReconciler({ ): TextInstance { if (__DEV__) { const hostContextDev = ((hostContext: any): HostContextDev); - validateDOMNesting(null, text, null, hostContextDev.ancestorInfo); + validateDOMNesting(null, text, hostContextDev.ancestorInfo); } var textNode: TextInstance = createTextNode(text, rootContainerInstance); precacheFiberNode(internalInstanceHandle, textNode); diff --git a/src/renderers/dom/shared/ReactDOMComponentFlags.js b/src/renderers/dom/shared/ReactDOMComponentFlags.js deleted file mode 100644 index bc40a5a560f28..0000000000000 --- a/src/renderers/dom/shared/ReactDOMComponentFlags.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @providesModule ReactDOMComponentFlags - */ - -'use strict'; - -var ReactDOMComponentFlags = { - hasCachedChildNodes: 1 << 0, -}; - -module.exports = ReactDOMComponentFlags; diff --git a/src/renderers/dom/shared/ReactDOMComponentTree.js b/src/renderers/dom/shared/ReactDOMComponentTree.js index abcb36b31f50f..e8969c183a14a 100644 --- a/src/renderers/dom/shared/ReactDOMComponentTree.js +++ b/src/renderers/dom/shared/ReactDOMComponentTree.js @@ -9,116 +9,18 @@ 'use strict'; -var DOMProperty = require('DOMProperty'); -var ReactDOMComponentFlags = require('ReactDOMComponentFlags'); var {HostComponent, HostText} = require('ReactTypeOfWork'); -var {ELEMENT_NODE, COMMENT_NODE} = require('HTMLNodeType'); var invariant = require('fbjs/lib/invariant'); -var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; -var Flags = ReactDOMComponentFlags; - var randomKey = Math.random().toString(36).slice(2); - var internalInstanceKey = '__reactInternalInstance$' + randomKey; - var internalEventHandlersKey = '__reactEventHandlers$' + randomKey; -/** - * Check if a given node should be cached. - */ -function shouldPrecacheNode(node, nodeID) { - return ( - (node.nodeType === ELEMENT_NODE && - node.getAttribute(ATTR_NAME) === '' + nodeID) || - (node.nodeType === COMMENT_NODE && - node.nodeValue === ' react-text: ' + nodeID + ' ') || - (node.nodeType === COMMENT_NODE && - node.nodeValue === ' react-empty: ' + nodeID + ' ') - ); -} - -/** - * Drill down (through composites and empty components) until we get a host or - * host text component. - * - * This is pretty polymorphic but unavoidable with the current structure we have - * for `_renderedChildren`. - */ -function getRenderedHostOrTextFromComponent(component) { - var rendered; - while ((rendered = component._renderedComponent)) { - component = rendered; - } - return component; -} - -/** - * Populate `_hostNode` on the rendered host/text component with the given - * DOM node. The passed `inst` can be a composite. - */ -function precacheNode(inst, node) { - var hostInst = getRenderedHostOrTextFromComponent(inst); - hostInst._hostNode = node; - node[internalInstanceKey] = hostInst; -} - function precacheFiberNode(hostInst, node) { node[internalInstanceKey] = hostInst; } -function uncacheNode(inst) { - var node = inst._hostNode; - if (node) { - delete node[internalInstanceKey]; - inst._hostNode = null; - } -} - -/** - * Populate `_hostNode` on each child of `inst`, assuming that the children - * match up with the DOM (element) children of `node`. - * - * We cache entire levels at once to avoid an n^2 problem where we access the - * children of a node sequentially and have to walk from the start to our target - * node every time. - * - * Since we update `_renderedChildren` and the actual DOM at (slightly) - * different times, we could race here and see a newer `_renderedChildren` than - * the DOM nodes we see. To avoid this, ReactMultiChild calls - * `prepareToManageChildren` before we change `_renderedChildren`, at which - * time the container's child nodes are always cached (until it unmounts). - */ -function precacheChildNodes(inst, node) { - if (inst._flags & Flags.hasCachedChildNodes) { - return; - } - var children = inst._renderedChildren; - var childNode = node.firstChild; - outer: for (var name in children) { - if (!children.hasOwnProperty(name)) { - continue; - } - var childInst = children[name]; - var childID = getRenderedHostOrTextFromComponent(childInst)._domID; - if (childID === 0) { - // We're currently unmounting this child in ReactMultiChild; skip it. - continue; - } - // We assume the child nodes are in the same order as the child instances. - for (; childNode !== null; childNode = childNode.nextSibling) { - if (shouldPrecacheNode(childNode, childID)) { - precacheNode(childInst, childNode); - continue outer; - } - } - // We reached the end of the DOM children without finding an ID match. - invariant(false, 'Unable to find element with ID %s.', childID); - } - inst._flags |= Flags.hasCachedChildNodes; -} - /** * Given a DOM node, return the closest ReactDOMComponent or * ReactDOMTextComponent instance ancestor. @@ -149,9 +51,6 @@ function getClosestInstanceFromNode(node) { } for (; node && (inst = node[internalInstanceKey]); node = parents.pop()) { closest = inst; - if (parents.length) { - precacheChildNodes(inst, node); - } } return closest; @@ -166,18 +65,11 @@ function getInstanceFromNode(node) { if (inst) { if (inst.tag === HostComponent || inst.tag === HostText) { return inst; - } else if (inst._hostNode === node) { - return inst; } else { return null; } } - inst = getClosestInstanceFromNode(node); - if (inst != null && inst._hostNode === node) { - return inst; - } else { - return null; - } + return null; } /** @@ -193,33 +85,7 @@ function getNodeFromInstance(inst) { // Without this first invariant, passing a non-DOM-component triggers the next // invariant for a missing parent, which is super confusing. - invariant( - inst._hostNode !== undefined, - 'getNodeFromInstance: Invalid argument.', - ); - - if (inst._hostNode) { - return inst._hostNode; - } - - // Walk up the tree until we find an ancestor whose DOM node we have cached. - var parents = []; - while (!inst._hostNode) { - parents.push(inst); - invariant( - inst._hostParent, - 'React DOM tree root should always have a node reference.', - ); - inst = inst._hostParent; - } - - // Now parents contains each ancestor that does *not* have a cached native - // node, and `inst` is the deepest ancestor that does. - for (; parents.length; inst = parents.pop()) { - precacheChildNodes(inst, inst._hostNode); - } - - return inst._hostNode; + invariant(false, 'getNodeFromInstance: Invalid argument.'); } function getFiberCurrentPropsFromNode(node) { @@ -234,9 +100,6 @@ var ReactDOMComponentTree = { getClosestInstanceFromNode: getClosestInstanceFromNode, getInstanceFromNode: getInstanceFromNode, getNodeFromInstance: getNodeFromInstance, - precacheChildNodes: precacheChildNodes, - precacheNode: precacheNode, - uncacheNode: uncacheNode, precacheFiberNode: precacheFiberNode, getFiberCurrentPropsFromNode, updateFiberProps, diff --git a/src/renderers/dom/shared/ReactDOMEventListener.js b/src/renderers/dom/shared/ReactDOMEventListener.js index 03f9bb1ddeafe..6950f06acae2a 100644 --- a/src/renderers/dom/shared/ReactDOMEventListener.js +++ b/src/renderers/dom/shared/ReactDOMEventListener.js @@ -31,22 +31,14 @@ function findRootContainerNode(inst) { // TODO: It may be a good idea to cache this to prevent unnecessary DOM // traversal, but caching is difficult to do correctly without using a // mutation observer to listen for all DOM changes. - if (typeof inst.tag === 'number') { - while (inst.return) { - inst = inst.return; - } - if (inst.tag !== HostRoot) { - // This can happen if we're in a detached tree. - return null; - } - return inst.stateNode.containerInfo; - } else { - while (inst._hostParent) { - inst = inst._hostParent; - } - var rootNode = ReactDOMComponentTree.getNodeFromInstance(inst); - return rootNode.parentNode; + while (inst.return) { + inst = inst.return; + } + if (inst.tag !== HostRoot) { + // This can happen if we're in a detached tree. + return null; } + return inst.stateNode.containerInfo; } // Used to store ancestor hierarchy in top level callback diff --git a/src/renderers/dom/shared/ReactDOMFeatureFlags.js b/src/renderers/dom/shared/ReactDOMFeatureFlags.js index 03ab7534ad331..43f4085015b2e 100644 --- a/src/renderers/dom/shared/ReactDOMFeatureFlags.js +++ b/src/renderers/dom/shared/ReactDOMFeatureFlags.js @@ -11,7 +11,6 @@ var ReactDOMFeatureFlags = { fiberAsyncScheduling: false, - useFiber: true, }; module.exports = ReactDOMFeatureFlags; diff --git a/src/renderers/dom/shared/__tests__/ReactDOMComponentTree-test.js b/src/renderers/dom/shared/__tests__/ReactDOMComponentTree-test.js index 147b6ba9ac84b..c3cf73bd457a9 100644 --- a/src/renderers/dom/shared/__tests__/ReactDOMComponentTree-test.js +++ b/src/renderers/dom/shared/__tests__/ReactDOMComponentTree-test.js @@ -23,17 +23,11 @@ describe('ReactDOMComponentTree', () => { } function getTypeOf(instance) { - if (typeof instance.tag === 'number') { - return instance.type; - } - return instance._currentElement.type; + return instance.type; } function getTextOf(instance) { - if (typeof instance.tag === 'number') { - return instance.memoizedProps; - } - return instance._stringText; + return instance.memoizedProps; } beforeEach(() => { diff --git a/src/renderers/dom/shared/eventPlugins/SimpleEventPlugin.js b/src/renderers/dom/shared/eventPlugins/SimpleEventPlugin.js index 8c53cf882b3d3..d33e45b936ba9 100644 --- a/src/renderers/dom/shared/eventPlugins/SimpleEventPlugin.js +++ b/src/renderers/dom/shared/eventPlugins/SimpleEventPlugin.js @@ -34,7 +34,7 @@ import type { DispatchConfig, ReactSyntheticEvent, } from 'ReactSyntheticEventType'; -import type {ReactInstance} from 'ReactInstanceType'; +import type {Fiber} from 'ReactFiber'; import type {EventTypes, PluginModule} from 'PluginModuleType'; /** @@ -179,7 +179,7 @@ var SimpleEventPlugin: PluginModule = { extractEvents: function( topLevelType: TopLevelTypes, - targetInst: ReactInstance, + targetInst: Fiber, nativeEvent: MouseEvent, nativeEventTarget: EventTarget, ): null | ReactSyntheticEvent { diff --git a/src/renderers/dom/shared/validateDOMNesting.js b/src/renderers/dom/shared/validateDOMNesting.js index 7a153f264af94..ba6d55d813881 100644 --- a/src/renderers/dom/shared/validateDOMNesting.js +++ b/src/renderers/dom/shared/validateDOMNesting.js @@ -10,7 +10,6 @@ 'use strict'; var emptyFunction = require('fbjs/lib/emptyFunction'); -var getComponentName = require('getComponentName'); var validateDOMNesting = emptyFunction; @@ -405,83 +404,9 @@ if (__DEV__) { return null; }; - /** - * Given a ReactCompositeComponent instance, return a list of its recursive - * owners, starting at the root and ending with the instance itself. - */ - var findOwnerStack = function(instance) { - if (!instance) { - return []; - } - - var stack = []; - do { - stack.push(instance); - } while ((instance = instance._currentElement._owner)); - stack.reverse(); - return stack; - }; - - var getOwnerInfo = function( - childInstance, - childTag, - ancestorInstance, - ancestorTag, - isParent, - ) { - var childOwner = childInstance && childInstance._currentElement._owner; - var ancestorOwner = - ancestorInstance && ancestorInstance._currentElement._owner; - - var childOwners = findOwnerStack(childOwner); - var ancestorOwners = findOwnerStack(ancestorOwner); - - var minStackLen = Math.min(childOwners.length, ancestorOwners.length); - var i; - - var deepestCommon = -1; - for (i = 0; i < minStackLen; i++) { - if (childOwners[i] === ancestorOwners[i]) { - deepestCommon = i; - } else { - break; - } - } - - var UNKNOWN = '(unknown)'; - var childOwnerNames = childOwners - .slice(deepestCommon + 1) - .map(inst => getComponentName(inst) || UNKNOWN); - var ancestorOwnerNames = ancestorOwners - .slice(deepestCommon + 1) - .map(inst => getComponentName(inst) || UNKNOWN); - var ownerInfo = [] - .concat( - // If the parent and child instances have a common owner ancestor, start - // with that -- otherwise we just start with the parent's owners. - deepestCommon !== -1 - ? getComponentName(childOwners[deepestCommon]) || UNKNOWN - : [], - ancestorOwnerNames, - ancestorTag, - // If we're warning about an invalid (non-parent) ancestry, add '...' - isParent ? [] : ['...'], - childOwnerNames, - childTag, - ) - .join(' > '); - - return ownerInfo; - }; - var didWarn = {}; - validateDOMNesting = function( - childTag, - childText, - childInstance, - ancestorInfo, - ) { + validateDOMNesting = function(childTag, childText, ancestorInfo) { ancestorInfo = ancestorInfo || emptyAncestorInfo; var parentInfo = ancestorInfo.current; var parentTag = parentInfo && parentInfo.tag; @@ -505,24 +430,8 @@ if (__DEV__) { return; } - var ancestorInstance = invalidParentOrAncestor.instance; var ancestorTag = invalidParentOrAncestor.tag; - var addendum; - - if (childInstance != null) { - addendum = - ' See ' + - getOwnerInfo( - childInstance, - childTag, - ancestorInstance, - ancestorTag, - !!invalidParent, - ) + - '.'; - } else { - addendum = getCurrentFiberStackAddendum(); - } + var addendum = getCurrentFiberStackAddendum(); var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum; diff --git a/src/renderers/dom/shared/warnValidStyle.js b/src/renderers/dom/shared/warnValidStyle.js index 590c36f980db2..7a711e4a660cf 100644 --- a/src/renderers/dom/shared/warnValidStyle.js +++ b/src/renderers/dom/shared/warnValidStyle.js @@ -15,7 +15,6 @@ var warnValidStyle = emptyFunction; if (__DEV__) { var camelizeStyleName = require('fbjs/lib/camelizeStyleName'); - var getComponentName = require('getComponentName'); var warning = require('fbjs/lib/warning'); var {getCurrentFiberOwnerName} = require('ReactDebugCurrentFiber'); @@ -30,7 +29,7 @@ if (__DEV__) { var warnedForNaNValue = false; var warnedForInfinityValue = false; - var warnHyphenatedStyleName = function(name, owner) { + var warnHyphenatedStyleName = function(name) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } @@ -41,11 +40,11 @@ if (__DEV__) { 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName(name), - checkRenderMessage(owner), + checkRenderMessage(), ); }; - var warnBadVendoredStyleName = function(name, owner) { + var warnBadVendoredStyleName = function(name) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } @@ -56,11 +55,11 @@ if (__DEV__) { 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), - checkRenderMessage(owner), + checkRenderMessage(), ); }; - var warnStyleValueWithSemicolon = function(name, value, owner) { + var warnStyleValueWithSemicolon = function(name, value) { if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { return; } @@ -70,13 +69,13 @@ if (__DEV__) { false, "Style property values shouldn't contain a semicolon.%s " + 'Try "%s: %s" instead.', - checkRenderMessage(owner), + checkRenderMessage(), name, value.replace(badStyleValueWithSemicolonPattern, ''), ); }; - var warnStyleValueIsNaN = function(name, value, owner) { + var warnStyleValueIsNaN = function(name, value) { if (warnedForNaNValue) { return; } @@ -86,11 +85,11 @@ if (__DEV__) { false, '`NaN` is an invalid value for the `%s` css style property.%s', name, - checkRenderMessage(owner), + checkRenderMessage(), ); }; - var warnStyleValueIsInfinity = function(name, value, owner) { + var warnStyleValueIsInfinity = function(name, value) { if (warnedForInfinityValue) { return; } @@ -100,21 +99,16 @@ if (__DEV__) { false, '`Infinity` is an invalid value for the `%s` css style property.%s', name, - checkRenderMessage(owner), + checkRenderMessage(), ); }; - var checkRenderMessage = function(owner) { + var checkRenderMessage = function() { var ownerName; - if (owner != null) { - // Stack passes the owner manually all the way to CSSPropertyOperations. - ownerName = getComponentName(owner); - } else { - // Fiber doesn't pass it but uses ReactDebugCurrentFiber to track it. - // It is only enabled in development and tracks host components too. - ownerName = getCurrentFiberOwnerName(); - // TODO: also report the stack. - } + // Fiber doesn't pass it but uses ReactDebugCurrentFiber to track it. + // It is only enabled in development and tracks host components too. + ownerName = getCurrentFiberOwnerName(); + // TODO: also report the stack. if (ownerName) { return '\n\nCheck the render method of `' + ownerName + '`.'; } @@ -122,24 +116,19 @@ if (__DEV__) { }; warnValidStyle = function(name, value, component) { - var owner; - if (component) { - // TODO: this only works with Stack. Seems like we need to add unit tests? - owner = component._currentElement._owner; - } if (name.indexOf('-') > -1) { - warnHyphenatedStyleName(name, owner); + warnHyphenatedStyleName(name); } else if (badVendoredStyleNamePattern.test(name)) { - warnBadVendoredStyleName(name, owner); + warnBadVendoredStyleName(name); } else if (badStyleValueWithSemicolonPattern.test(value)) { - warnStyleValueWithSemicolon(name, value, owner); + warnStyleValueWithSemicolon(name, value); } if (typeof value === 'number') { if (isNaN(value)) { - warnStyleValueIsNaN(name, value, owner); + warnStyleValueIsNaN(name, value); } else if (!isFinite(value)) { - warnStyleValueIsInfinity(name, value, owner); + warnStyleValueIsInfinity(name, value); } } }; diff --git a/src/renderers/dom/test/ReactTestUtilsEntry.js b/src/renderers/dom/test/ReactTestUtilsEntry.js index dd19f45b8881d..16247a23e9647 100644 --- a/src/renderers/dom/test/ReactTestUtilsEntry.js +++ b/src/renderers/dom/test/ReactTestUtilsEntry.js @@ -43,35 +43,6 @@ function Event(suffix) {} * @class ReactTestUtils */ -function findAllInRenderedStackTreeInternal(inst, test) { - if (!inst || !inst.getPublicInstance) { - return []; - } - var publicInst = inst.getPublicInstance(); - var ret = test(publicInst) ? [publicInst] : []; - var currentElement = inst._currentElement; - if (ReactTestUtils.isDOMComponent(publicInst)) { - var renderedChildren = inst._renderedChildren; - var key; - for (key in renderedChildren) { - if (!renderedChildren.hasOwnProperty(key)) { - continue; - } - ret = ret.concat( - findAllInRenderedStackTreeInternal(renderedChildren[key], test), - ); - } - } else if ( - React.isValidElement(currentElement) && - typeof currentElement.type === 'function' - ) { - ret = ret.concat( - findAllInRenderedStackTreeInternal(inst._renderedComponent, test), - ); - } - return ret; -} - function findAllInRenderedFiberTreeInternal(fiber, test) { if (!fiber) { return []; @@ -169,10 +140,7 @@ var ReactTestUtils = { return false; } var internalInstance = ReactInstanceMap.get(inst); - var constructor = typeof internalInstance.tag === 'number' - ? internalInstance.type // Fiber reconciler - : internalInstance._currentElement.type; // Stack reconciler - + var constructor = internalInstance.type; return constructor === type; }, @@ -185,11 +153,7 @@ var ReactTestUtils = { 'findAllInRenderedTree(...): instance must be a composite component', ); var internalInstance = ReactInstanceMap.get(inst); - if (internalInstance && typeof internalInstance.tag === 'number') { - return findAllInRenderedFiberTreeInternal(internalInstance, test); - } else { - return findAllInRenderedStackTreeInternal(internalInstance, test); - } + return findAllInRenderedFiberTreeInternal(internalInstance, test); }, /** diff --git a/src/renderers/native/ReactNativeComponentTree.js b/src/renderers/native/ReactNativeComponentTree.js index 0103da214859b..a67da6213bc68 100644 --- a/src/renderers/native/ReactNativeComponentTree.js +++ b/src/renderers/native/ReactNativeComponentTree.js @@ -14,41 +14,10 @@ var invariant = require('fbjs/lib/invariant'); var instanceCache = {}; var instanceProps = {}; -/** - * Drill down (through composites and empty components) until we get a host or - * host text component. - * - * This is pretty polymorphic but unavoidable with the current structure we have - * for `_renderedChildren`. - */ -function getRenderedHostOrTextFromComponent(component) { - var rendered; - while ((rendered = component._renderedComponent)) { - component = rendered; - } - return component; -} - -/** - * Populate `_hostNode` on the rendered host/text component with the given - * DOM node. The passed `inst` can be a composite. - */ -function precacheNode(inst, tag) { - var nativeInst = getRenderedHostOrTextFromComponent(inst); - instanceCache[tag] = nativeInst; -} - function precacheFiberNode(hostInst, tag) { instanceCache[tag] = hostInst; } -function uncacheNode(inst) { - var tag = inst._rootNodeID; - if (tag) { - delete instanceCache[tag]; - } -} - function uncacheFiberNode(tag) { delete instanceCache[tag]; delete instanceProps[tag]; @@ -77,9 +46,7 @@ var ReactNativeComponentTree = { getInstanceFromNode: getInstanceFromTag, getNodeFromInstance: getTagFromInstance, precacheFiberNode, - precacheNode, uncacheFiberNode, - uncacheNode, getFiberCurrentPropsFromNode, updateFiberProps, }; diff --git a/src/renderers/native/__tests__/ReactNativeEvents-test.js b/src/renderers/native/__tests__/ReactNativeEvents-test.js index 8c4cc735e0d07..d56d79d8407b9 100644 --- a/src/renderers/native/__tests__/ReactNativeEvents-test.js +++ b/src/renderers/native/__tests__/ReactNativeEvents-test.js @@ -250,9 +250,7 @@ it('handles when a responder is unmounted while a touch sequence is in progress' if (responder === null) { return null; } - const props = typeof responder.tag === 'number' - ? responder.memoizedProps - : responder._currentElement.props; + const props = responder.memoizedProps; return props ? props.id : null; } @@ -342,9 +340,7 @@ it('handles events without target', () => { if (responder === null) { return null; } - const props = typeof responder.tag === 'number' - ? responder.memoizedProps - : responder._currentElement.props; + const props = responder.memoizedProps; return props ? props.id : null; } diff --git a/src/renderers/shared/fiber/ReactChildFiber.js b/src/renderers/shared/fiber/ReactChildFiber.js index bb5564f9f2c31..8eae6f410090d 100644 --- a/src/renderers/shared/fiber/ReactChildFiber.js +++ b/src/renderers/shared/fiber/ReactChildFiber.js @@ -13,7 +13,6 @@ import type {ReactElement} from 'ReactElementType'; import type {ReactCoroutine, ReactPortal, ReactYield} from 'ReactTypes'; import type {Fiber} from 'ReactFiber'; -import type {ReactInstance} from 'ReactInstanceType'; import type {PriorityLevel} from 'ReactPriorityLevel'; var {REACT_COROUTINE_TYPE, REACT_YIELD_TYPE} = require('ReactCoroutine'); @@ -120,20 +119,15 @@ function coerceRef(current: Fiber | null, element: ReactElement) { let mixedRef = element.ref; if (mixedRef !== null && typeof mixedRef !== 'function') { if (element._owner) { - const owner: ?(Fiber | ReactInstance) = (element._owner: any); + const owner: ?Fiber = (element._owner: any); let inst; if (owner) { - if (typeof owner.tag === 'number') { - const ownerFiber = ((owner: any): Fiber); - invariant( - ownerFiber.tag === ClassComponent, - 'Stateless function components cannot have refs.', - ); - inst = ownerFiber.stateNode; - } else { - // Stack - inst = (owner: any).getPublicInstance(); - } + const ownerFiber = ((owner: any): Fiber); + invariant( + ownerFiber.tag === ClassComponent, + 'Stateless function components cannot have refs.', + ); + inst = ownerFiber.stateNode; } invariant( inst, diff --git a/src/renderers/shared/fiber/ReactDebugCurrentFiber.js b/src/renderers/shared/fiber/ReactDebugCurrentFiber.js index 16a4096bd7282..92b3fa26f1441 100644 --- a/src/renderers/shared/fiber/ReactDebugCurrentFiber.js +++ b/src/renderers/shared/fiber/ReactDebugCurrentFiber.js @@ -29,8 +29,9 @@ function getCurrentFiberOwnerName(): string | null { if (fiber === null) { return null; } - if (fiber._debugOwner != null) { - return getComponentName(fiber._debugOwner); + const owner = fiber._debugOwner; + if (owner !== null && typeof owner !== 'undefined') { + return getComponentName(owner); } } return null; diff --git a/src/renderers/shared/fiber/ReactFiber.js b/src/renderers/shared/fiber/ReactFiber.js index 7fbb3a8af1170..dae77d55cc79b 100644 --- a/src/renderers/shared/fiber/ReactFiber.js +++ b/src/renderers/shared/fiber/ReactFiber.js @@ -11,7 +11,6 @@ 'use strict'; import type {ReactElement, Source} from 'ReactElementType'; -import type {ReactInstance, DebugID} from 'ReactInstanceType'; import type { ReactCoroutine, ReactFragment, @@ -147,9 +146,9 @@ export type Fiber = {| // workInProgress : Fiber -> alternate The alternate used for reuse happens // to be the same as work in progress. // __DEV__ only - _debugID?: DebugID, + _debugID?: number, _debugSource?: Source | null, - _debugOwner?: Fiber | ReactInstance | null, // Stack compatible + _debugOwner?: Fiber | null, _debugIsCurrentlyTiming?: boolean, |}; @@ -349,7 +348,7 @@ function createFiberFromElementType( type: mixed, key: null | string, internalContextTag: TypeOfInternalContext, - debugOwner: null | Fiber | ReactInstance, + debugOwner: null | Fiber, ): Fiber { let fiber; if (typeof type === 'function') { diff --git a/src/renderers/shared/fiber/ReactFiberReconciler.js b/src/renderers/shared/fiber/ReactFiberReconciler.js index 23738f3c40143..eafa87add0c78 100644 --- a/src/renderers/shared/fiber/ReactFiberReconciler.js +++ b/src/renderers/shared/fiber/ReactFiberReconciler.js @@ -25,7 +25,9 @@ var { } = require('ReactFiberContext'); var {createFiberRoot} = require('ReactFiberRoot'); var ReactFiberScheduler = require('ReactFiberScheduler'); +var ReactInstanceMap = require('ReactInstanceMap'); var {HostComponent} = require('ReactTypeOfWork'); +var emptyObject = require('fbjs/lib/emptyObject'); if (__DEV__) { var warning = require('fbjs/lib/warning'); @@ -39,8 +41,6 @@ var { findCurrentHostFiberWithNoPortals, } = require('ReactFiberTreeReflection'); -var getContextForSubtree = require('getContextForSubtree'); - export type Deadline = { timeRemaining: () => number, }; @@ -178,12 +178,19 @@ export type Reconciler = { findHostInstanceWithNoPortals(component: Fiber): I | TI | null, }; -getContextForSubtree._injectFiber(function(fiber: Fiber) { +function getContextForSubtree( + parentComponent: ?React$Component, +): Object { + if (!parentComponent) { + return emptyObject; + } + + const fiber = ReactInstanceMap.get(parentComponent); const parentContext = findCurrentUnmaskedContext(fiber); return isContextProvider(fiber) ? processChildContext(fiber, parentContext) : parentContext; -}); +} module.exports = function( config: HostConfig, diff --git a/src/renderers/shared/hooks/ReactHostOperationHistoryHook.js b/src/renderers/shared/hooks/ReactHostOperationHistoryHook.js deleted file mode 100644 index 4b6142ba2792d..0000000000000 --- a/src/renderers/shared/hooks/ReactHostOperationHistoryHook.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2016-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @providesModule ReactHostOperationHistoryHook - * @flow - */ - -'use strict'; - -import type {DebugID} from 'ReactInstanceType'; - -export type Operation = {instanceID: DebugID} & ( - | {type: 'mount', payload: string} - | {type: 'insert child', payload: {toIndex: number, content: string}} - | {type: 'move child', payload: {fromIndex: number, toIndex: number}} - | {type: 'replace children', payload: string} - | {type: 'replace text', payload: string} - | {type: 'replace with', payload: string} - | {type: 'update styles', payload: mixed /* Style Object */} - | {type: 'update attribute', payload: {[name: string]: string}} - | {type: 'remove attribute', payload: string}); - -// Trust the developer to only use this with a __DEV__ check -var ReactHostOperationHistoryHook = ((null: any): typeof ReactHostOperationHistoryHook); - -if (__DEV__) { - var history: Array = []; - - ReactHostOperationHistoryHook = { - onHostOperation(operation: Operation) { - history.push(operation); - }, - - clearHistory(): void { - if (ReactHostOperationHistoryHook._preventClearing) { - // Should only be used for tests. - return; - } - - history = []; - }, - - getHistory(): Array { - return history; - }, - }; -} - -module.exports = ReactHostOperationHistoryHook; diff --git a/src/renderers/shared/hooks/ReactInvalidSetStateWarningHook.js b/src/renderers/shared/hooks/ReactInvalidSetStateWarningHook.js deleted file mode 100644 index eed4c066926cb..0000000000000 --- a/src/renderers/shared/hooks/ReactInvalidSetStateWarningHook.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2016-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @providesModule ReactInvalidSetStateWarningHook - * @flow - */ - -'use strict'; - -var ReactInvalidSetStateWarningHook = {}; - -if (__DEV__) { - var warning = require('fbjs/lib/warning'); - var processingChildContext = false; - - var warnInvalidSetState = function() { - warning( - !processingChildContext, - 'setState(...): Cannot call setState() inside getChildContext()', - ); - }; - - ReactInvalidSetStateWarningHook = { - onBeginProcessingChildContext(): void { - processingChildContext = true; - }, - onEndProcessingChildContext(): void { - processingChildContext = false; - }, - onSetState(): void { - warnInvalidSetState(); - }, - }; -} - -module.exports = ReactInvalidSetStateWarningHook; diff --git a/src/renderers/shared/shared/ReactTreeTraversal.js b/src/renderers/shared/shared/ReactTreeTraversal.js index 1e73b8e199de6..8b58d7b10b758 100644 --- a/src/renderers/shared/shared/ReactTreeTraversal.js +++ b/src/renderers/shared/shared/ReactTreeTraversal.js @@ -12,21 +12,16 @@ var {HostComponent} = require('ReactTypeOfWork'); function getParent(inst) { - if (inst._hostParent !== undefined) { - return inst._hostParent; - } - if (typeof inst.tag === 'number') { - do { - inst = inst.return; - // TODO: If this is a HostRoot we might want to bail out. - // That is depending on if we want nested subtrees (layers) to bubble - // events to their parent. We could also go through parentNode on the - // host node but that wouldn't work for React Native and doesn't let us - // do the portal feature. - } while (inst && inst.tag !== HostComponent); - if (inst) { - return inst; - } + do { + inst = inst.return; + // TODO: If this is a HostRoot we might want to bail out. + // That is depending on if we want nested subtrees (layers) to bubble + // events to their parent. We could also go through parentNode on the + // host node but that wouldn't work for React Native and doesn't let us + // do the portal feature. + } while (inst && inst.tag !== HostComponent); + if (inst) { + return inst; } return null; } diff --git a/src/renderers/shared/shared/event/EventPluginHub.js b/src/renderers/shared/shared/event/EventPluginHub.js index 975166553b613..7238b3ec773a0 100644 --- a/src/renderers/shared/shared/event/EventPluginHub.js +++ b/src/renderers/shared/shared/event/EventPluginHub.js @@ -122,43 +122,20 @@ var EventPluginHub = { // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not // live here; needs to be moved to a better place soon - if (typeof inst.tag === 'number') { - const stateNode = inst.stateNode; - if (!stateNode) { - // Work in progress (ex: onload events in incremental mode). - return null; - } - const props = EventPluginUtils.getFiberCurrentPropsFromNode(stateNode); - if (!props) { - // Work in progress. - return null; - } - listener = props[registrationName]; - if (shouldPreventMouseEvent(registrationName, inst.type, props)) { - return null; - } - } else { - const currentElement = inst._currentElement; - if ( - typeof currentElement === 'string' || - typeof currentElement === 'number' - ) { - // Text node, let it bubble through. - return null; - } - if (!inst._rootNodeID) { - // If the instance is already unmounted, we have no listeners. - return null; - } - const props = currentElement.props; - listener = props[registrationName]; - if ( - shouldPreventMouseEvent(registrationName, currentElement.type, props) - ) { - return null; - } + const stateNode = inst.stateNode; + if (!stateNode) { + // Work in progress (ex: onload events in incremental mode). + return null; + } + const props = EventPluginUtils.getFiberCurrentPropsFromNode(stateNode); + if (!props) { + // Work in progress. + return null; + } + listener = props[registrationName]; + if (shouldPreventMouseEvent(registrationName, inst.type, props)) { + return null; } - invariant( !listener || typeof listener === 'function', 'Expected `%s` listener to be a function, instead got a value of `%s` type.', diff --git a/src/renderers/shared/shared/event/PluginModuleType.js b/src/renderers/shared/shared/event/PluginModuleType.js index c6e0bcf4ad13f..ad9b90e78d735 100644 --- a/src/renderers/shared/shared/event/PluginModuleType.js +++ b/src/renderers/shared/shared/event/PluginModuleType.js @@ -10,7 +10,7 @@ 'use strict'; -import type {ReactInstance} from 'ReactInstanceType'; +import type {Fiber} from 'ReactFiber'; import type { DispatchConfig, ReactSyntheticEvent, @@ -26,7 +26,7 @@ export type PluginModule = { eventTypes: EventTypes, extractEvents: ( topLevelType: string, - targetInst: ReactInstance, + targetInst: Fiber, nativeTarget: NativeEvent, nativeEventTarget: EventTarget, ) => null | ReactSyntheticEvent, diff --git a/src/renderers/shared/shared/event/ReactControlledComponent.js b/src/renderers/shared/shared/event/ReactControlledComponent.js index 520a4e8e65190..45eec0c89eb6d 100644 --- a/src/renderers/shared/shared/event/ReactControlledComponent.js +++ b/src/renderers/shared/shared/event/ReactControlledComponent.js @@ -36,30 +36,20 @@ function restoreStateOfTarget(target) { // Unmounted return; } - if (typeof internalInstance.tag === 'number') { - invariant( - fiberHostComponent && - typeof fiberHostComponent.restoreControlledState === 'function', - 'Fiber needs to be injected to handle a fiber target for controlled ' + - 'events. This error is likely caused by a bug in React. Please file an issue.', - ); - const props = EventPluginUtils.getFiberCurrentPropsFromNode( - internalInstance.stateNode, - ); - fiberHostComponent.restoreControlledState( - internalInstance.stateNode, - internalInstance.type, - props, - ); - return; - } invariant( - typeof internalInstance.restoreControlledState === 'function', - 'The internal instance must be a React host component. ' + - 'This error is likely caused by a bug in React. Please file an issue.', + fiberHostComponent && + typeof fiberHostComponent.restoreControlledState === 'function', + 'Fiber needs to be injected to handle a fiber target for controlled ' + + 'events. This error is likely caused by a bug in React. Please file an issue.', + ); + const props = EventPluginUtils.getFiberCurrentPropsFromNode( + internalInstance.stateNode, + ); + fiberHostComponent.restoreControlledState( + internalInstance.stateNode, + internalInstance.type, + props, ); - // If it is not a Fiber, we can just use dynamic dispatch. - internalInstance.restoreControlledState(); } var ReactControlledComponent = { diff --git a/src/renderers/shared/shared/event/ReactSyntheticEventType.js b/src/renderers/shared/shared/event/ReactSyntheticEventType.js index f60f3d670aecf..86c8a711aeb58 100644 --- a/src/renderers/shared/shared/event/ReactSyntheticEventType.js +++ b/src/renderers/shared/shared/event/ReactSyntheticEventType.js @@ -12,7 +12,7 @@ 'use strict'; -import type {ReactInstance} from 'ReactInstanceType'; +import type {Fiber} from 'ReactFiber'; export type DispatchConfig = { dependencies: Array, @@ -27,7 +27,7 @@ export type ReactSyntheticEvent = { dispatchConfig: DispatchConfig, getPooled: ( dispatchConfig: DispatchConfig, - targetInst: ReactInstance, + targetInst: Fiber, nativeTarget: Event, nativeEventTarget: EventTarget, ) => ReactSyntheticEvent, 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 cb6fafdb7764c..90a7ad6d43865 100644 --- a/src/renderers/shared/shared/event/eventPlugins/__tests__/ResponderEventPlugin-test.js +++ b/src/renderers/shared/shared/event/eventPlugins/__tests__/ResponderEventPlugin-test.js @@ -9,6 +9,8 @@ 'use strict'; +var {HostComponent} = require('ReactTypeOfWork'); + var EventPluginHub; var ResponderEventPlugin; @@ -318,35 +320,37 @@ var PARENT_HOST_NODE = {}; var CHILD_HOST_NODE = {}; var CHILD_HOST_NODE2 = {}; +// These intentionally look like Fibers. ReactTreeTraversal depends on their field names. +// TODO: we could test this with regular DOM nodes (and real fibers) instead. var GRANDPARENT_INST = { - _hostParent: null, - _rootNodeID: '1', - _hostNode: GRANDPARENT_HOST_NODE, - _currentElement: {props: {}}, + return: null, + tag: HostComponent, + stateNode: GRANDPARENT_HOST_NODE, + memoizedProps: {}, }; var PARENT_INST = { - _hostParent: GRANDPARENT_INST, - _rootNodeID: '2', - _hostNode: PARENT_HOST_NODE, - _currentElement: {props: {}}, + return: GRANDPARENT_INST, + tag: HostComponent, + stateNode: PARENT_HOST_NODE, + memoizedProps: {}, }; var CHILD_INST = { - _hostParent: PARENT_INST, - _rootNodeID: '3', - _hostNode: CHILD_HOST_NODE, - _currentElement: {props: {}}, + return: PARENT_INST, + tag: HostComponent, + stateNode: CHILD_HOST_NODE, + memoizedProps: {}, }; var CHILD_INST2 = { - _hostParent: PARENT_INST, - _rootNodeID: '4', - _hostNode: CHILD_HOST_NODE2, - _currentElement: {props: {}}, + return: PARENT_INST, + tag: HostComponent, + stateNode: CHILD_HOST_NODE2, + memoizedProps: {}, }; -GRANDPARENT_HOST_NODE._reactInstance = GRANDPARENT_INST; -PARENT_HOST_NODE._reactInstance = PARENT_INST; -CHILD_HOST_NODE._reactInstance = CHILD_INST; -CHILD_HOST_NODE2._reactInstance = CHILD_INST2; +GRANDPARENT_HOST_NODE.testInstance = GRANDPARENT_INST; +PARENT_HOST_NODE.testInstance = PARENT_INST; +CHILD_HOST_NODE.testInstance = CHILD_INST; +CHILD_HOST_NODE2.testInstance = CHILD_INST2; var three = { grandParent: GRANDPARENT_HOST_NODE, @@ -361,19 +365,23 @@ var siblings = { }; function getInstanceFromNode(node) { - return node._reactInstance; + return node.testInstance; } function getNodeFromInstance(inst) { - return inst._hostNode; + return inst.stateNode; +} + +function getFiberCurrentPropsFromNode(node) { + return node.testInstance.memoizedProps; } -function putListener(node, registrationName, handler) { - node._currentElement.props[registrationName] = handler; +function putListener(instance, registrationName, handler) { + instance.memoizedProps[registrationName] = handler; } -function deleteAllListeners(node) { - node._currentElement.props = {}; +function deleteAllListeners(instance) { + instance.memoizedProps = {}; } describe('ResponderEventPlugin', () => { @@ -398,6 +406,7 @@ describe('ResponderEventPlugin', () => { injectComponentTree({ getInstanceFromNode, getNodeFromInstance, + getFiberCurrentPropsFromNode, }); }); diff --git a/src/renderers/shared/shared/getContextForSubtree.js b/src/renderers/shared/shared/getContextForSubtree.js deleted file mode 100644 index 027e63a2e5f69..0000000000000 --- a/src/renderers/shared/shared/getContextForSubtree.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @providesModule getContextForSubtree - * @flow - */ - -const ReactInstanceMap = require('ReactInstanceMap'); - -const emptyObject = require('fbjs/lib/emptyObject'); -const invariant = require('fbjs/lib/invariant'); - -let getContextFiber = function(arg) { - invariant(false, 'Missing injection for fiber getContextForSubtree'); -}; - -function getContextForSubtree( - parentComponent: ?React$Component, -): Object { - if (!parentComponent) { - return emptyObject; - } - - const instance = ReactInstanceMap.get(parentComponent); - if (typeof instance.tag === 'number') { - return getContextFiber(instance); - } else { - return instance._processChildContext(instance._context); - } -} - -getContextForSubtree._injectFiber = function(fn) { - getContextFiber = fn; -}; - -module.exports = getContextForSubtree; diff --git a/src/shared/ReactInstanceType.js b/src/shared/ReactInstanceType.js deleted file mode 100644 index ed29794f1ba32..0000000000000 --- a/src/shared/ReactInstanceType.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2016-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @providesModule ReactInstanceType - * @flow - */ - -'use strict'; - -// TODO: delete this file. -// It was only necessary for Stack. - -import type {ReactElement} from 'ReactElementType'; - -export type DebugID = number; - -export type ReactInstance = { - mountComponent: any, - unmountComponent: any, - receiveComponent: any, - getName: () => string, - getPublicInstance: any, - _currentElement: ReactElement, -}; diff --git a/src/shared/utils/getComponentName.js b/src/shared/utils/getComponentName.js index 772949d19d599..5a3b00ec29f90 100644 --- a/src/shared/utils/getComponentName.js +++ b/src/shared/utils/getComponentName.js @@ -10,27 +10,15 @@ 'use strict'; -import type {ReactInstance} from 'ReactInstanceType'; import type {Fiber} from 'ReactFiber'; -function getComponentName( - instanceOrFiber: ReactInstance | Fiber, -): string | null { - if (typeof instanceOrFiber.getName === 'function') { - // Stack reconciler - const instance = ((instanceOrFiber: any): ReactInstance); - return instance.getName(); +function getComponentName(fiber: Fiber): string | null { + const {type} = fiber; + if (typeof type === 'string') { + return type; } - if (typeof instanceOrFiber.tag === 'number') { - // Fiber reconciler - const fiber = ((instanceOrFiber: any): Fiber); - const {type} = fiber; - if (typeof type === 'string') { - return type; - } - if (typeof type === 'function') { - return type.displayName || type.name; - } + if (typeof type === 'function') { + return type.displayName || type.name; } return null; }