(targetNode)
| 7959 | // The same thing applies to Suspense boundaries. |
| 7960 | |
| 7961 | function getClosestInstanceFromNode(targetNode) { |
| 7962 | var targetInst = targetNode[internalInstanceKey]; |
| 7963 | |
| 7964 | if (targetInst) { |
| 7965 | // Don't return HostRoot or SuspenseComponent here. |
| 7966 | return targetInst; |
| 7967 | } // If the direct event target isn't a React owned DOM node, we need to look |
| 7968 | // to see if one of its parents is a React owned DOM node. |
| 7969 | |
| 7970 | |
| 7971 | var parentNode = targetNode.parentNode; |
| 7972 | |
| 7973 | while (parentNode) { |
| 7974 | // We'll check if this is a container root that could include |
| 7975 | // React nodes in the future. We need to check this first because |
| 7976 | // if we're a child of a dehydrated container, we need to first |
| 7977 | // find that inner container before moving on to finding the parent |
| 7978 | // instance. Note that we don't check this field on the targetNode |
| 7979 | // itself because the fibers are conceptually between the container |
| 7980 | // node and the first child. It isn't surrounding the container node. |
| 7981 | // If it's not a container, we check if it's an instance. |
| 7982 | targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey]; |
| 7983 | |
| 7984 | if (targetInst) { |
| 7985 | // Since this wasn't the direct target of the event, we might have |
| 7986 | // stepped past dehydrated DOM nodes to get here. However they could |
| 7987 | // also have been non-React nodes. We need to answer which one. |
| 7988 | // If we the instance doesn't have any children, then there can't be |
| 7989 | // a nested suspense boundary within it. So we can use this as a fast |
| 7990 | // bailout. Most of the time, when people add non-React children to |
| 7991 | // the tree, it is using a ref to a child-less DOM node. |
| 7992 | // Normally we'd only need to check one of the fibers because if it |
| 7993 | // has ever gone from having children to deleting them or vice versa |
| 7994 | // it would have deleted the dehydrated boundary nested inside already. |
| 7995 | // However, since the HostRoot starts out with an alternate it might |
| 7996 | // have one on the alternate so we need to check in case this was a |
| 7997 | // root. |
| 7998 | var alternate = targetInst.alternate; |
| 7999 | |
| 8000 | if (targetInst.child !== null || alternate !== null && alternate.child !== null) { |
| 8001 | // Next we need to figure out if the node that skipped past is |
| 8002 | // nested within a dehydrated boundary and if so, which one. |
| 8003 | var suspenseInstance = getParentSuspenseInstance(targetNode); |
| 8004 | |
| 8005 | while (suspenseInstance !== null) { |
| 8006 | // We found a suspense instance. That means that we haven't |
| 8007 | // hydrated it yet. Even though we leave the comments in the |
| 8008 | // DOM after hydrating, and there are boundaries in the DOM |
| 8009 | // that could already be hydrated, we wouldn't have found them |
| 8010 | // through this pass since if the target is hydrated it would |
| 8011 | // have had an internalInstanceKey on it. |
| 8012 | // Let's get the fiber associated with the SuspenseComponent |
| 8013 | // as the deepest instance. |
| 8014 | var targetSuspenseInst = suspenseInstance[internalInstanceKey]; |
| 8015 | |
| 8016 | if (targetSuspenseInst) { |
| 8017 | return targetSuspenseInst; |
| 8018 | } // If we don't find a Fiber on the comment, it might be because |
no test coverage detected