/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * Shared logic for Fragment Ref operations for DOM and Fabric configs * * @flow */ import type {Fiber} from 'react-reconciler/src/ReactInternalTypes'; import {getNextSiblingHostFiber} from 'react-reconciler/src/ReactFiberTreeReflection'; export function compareDocumentPositionForEmptyFragment( fragmentFiber: Fiber, parentHostInstance: TPublicInstance, otherNode: TPublicInstance, getPublicInstance: (fiber: Fiber) => TPublicInstance, ): number { let result; // If the fragment has no children, we can use the parent and // siblings to determine a position. // $FlowFixMe[incompatible-use] Fabric PublicInstance is opaque // $FlowFixMe[prop-missing] const parentResult = parentHostInstance.compareDocumentPosition(otherNode); result = parentResult; if (parentHostInstance === otherNode) { result = Node.DOCUMENT_POSITION_CONTAINS; } else { if (parentResult & Node.DOCUMENT_POSITION_CONTAINED_BY) { // otherNode is one of the fragment's siblings. Use the next // sibling to determine if its preceding or following. const nextSiblingFiber = getNextSiblingHostFiber(fragmentFiber); if (nextSiblingFiber === null) { result = Node.DOCUMENT_POSITION_PRECEDING; } else { const nextSiblingInstance = getPublicInstance(nextSiblingFiber); const nextSiblingResult = // $FlowFixMe[incompatible-use] Fabric PublicInstance is opaque // $FlowFixMe[prop-missing] nextSiblingInstance.compareDocumentPosition(otherNode); if ( nextSiblingResult === 0 || nextSiblingResult & Node.DOCUMENT_POSITION_FOLLOWING ) { result = Node.DOCUMENT_POSITION_FOLLOWING; } else { result = Node.DOCUMENT_POSITION_PRECEDING; } } } } result |= Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; return result; }