UNPKG

react-native

Version:

A framework for building native apps using React

174 lines (150 loc) 6.16 kB
/** * 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. * * @flow strict-local * @format */ import type {InternalInstanceHandle} from '../../../../../../Libraries/Renderer/shims/ReactNativeTypes'; import type ReactNativeDocument from '../ReactNativeDocument'; import type ReadOnlyCharacterData from '../ReadOnlyCharacterData'; import type ReadOnlyElement from '../ReadOnlyElement'; import type ReadOnlyNode from '../ReadOnlyNode'; import type { NativeElementReference, NativeNodeReference, NativeTextReference, } from '../specs/NativeDOM'; import type {ReactNativeDocumentElementInstanceHandle} from './ReactNativeDocumentElementInstanceHandle'; import type {ReactNativeDocumentInstanceHandle} from './ReactNativeDocumentInstanceHandle'; import { getNativeElementReferenceFromReactNativeDocumentElementInstanceHandle, getPublicInstanceFromReactNativeDocumentElementInstanceHandle, isReactNativeDocumentElementInstanceHandle, } from './ReactNativeDocumentElementInstanceHandle'; import { getNativeNodeReferenceFromReactNativeDocumentInstanceHandle, getPublicInstanceFromReactNativeDocumentInstanceHandle, isReactNativeDocumentInstanceHandle, } from './ReactNativeDocumentInstanceHandle'; export type InstanceHandle = | InternalInstanceHandle // component managed by React | ReactNativeDocumentElementInstanceHandle // root element managed by React Native | ReactNativeDocumentInstanceHandle; // document node managed by React Native let cachedGetNodeFromInternalInstanceHandle; function getNodeFromInternalInstanceHandle( instanceHandle: InternalInstanceHandle, ) { if (cachedGetNodeFromInternalInstanceHandle == null) { // Lazy import Fabric here to avoid DOM Node APIs classes from having side-effects. // With a static import we can't use these classes for Paper-only variants. cachedGetNodeFromInternalInstanceHandle = require('../../../../../../Libraries/ReactNative/RendererProxy').getNodeFromInternalInstanceHandle; } return cachedGetNodeFromInternalInstanceHandle(instanceHandle); } let cachedGetPublicInstanceFromInternalInstanceHandle; function getPublicInstanceFromInternalInstanceHandle( instanceHandle: InternalInstanceHandle, ) { if (cachedGetPublicInstanceFromInternalInstanceHandle == null) { // Lazy import Fabric here to avoid DOM Node APIs classes from having side-effects. // With a static import we can't use these classes for Paper-only variants. cachedGetPublicInstanceFromInternalInstanceHandle = require('../../../../../../Libraries/ReactNative/RendererProxy').getPublicInstanceFromInternalInstanceHandle; } return cachedGetPublicInstanceFromInternalInstanceHandle(instanceHandle); } const INSTANCE_HANDLE_KEY = Symbol('internalInstanceHandle'); const OWNER_DOCUMENT_KEY = Symbol('ownerDocument'); export function getInstanceHandle(node: ReadOnlyNode): InstanceHandle { // $FlowExpectedError[prop-missing] return node[INSTANCE_HANDLE_KEY]; } export function setInstanceHandle( node: ReadOnlyNode, instanceHandle: InstanceHandle, ): void { // $FlowExpectedError[prop-missing] node[INSTANCE_HANDLE_KEY] = instanceHandle; } export function getOwnerDocument( node: ReadOnlyNode, ): ReactNativeDocument | null { // $FlowExpectedError[prop-missing] return node[OWNER_DOCUMENT_KEY] ?? null; } export function setOwnerDocument( node: ReadOnlyNode, ownerDocument: ReactNativeDocument | null, ): void { // $FlowExpectedError[prop-missing] node[OWNER_DOCUMENT_KEY] = ownerDocument; } export function getPublicInstanceFromInstanceHandle( instanceHandle: InstanceHandle, ): ?ReadOnlyNode { const mixedPublicInstance = // $FlowExpectedError[incompatible-type] getPublicInstanceFromInternalInstanceHandle(instanceHandle); if (mixedPublicInstance != null) { // $FlowExpectedError[incompatible-type] React defines public instances as "mixed" because it can't access the definition from React Native. return mixedPublicInstance; } if (isReactNativeDocumentInstanceHandle(instanceHandle)) { return getPublicInstanceFromReactNativeDocumentInstanceHandle( instanceHandle, ); } if (isReactNativeDocumentElementInstanceHandle(instanceHandle)) { return getPublicInstanceFromReactNativeDocumentElementInstanceHandle( instanceHandle, ); } } export function getNativeNodeReference( node: ReadOnlyNode, ): ?NativeNodeReference { const instanceHandle = getInstanceHandle(node); // Try React nodes first const nativeReference = // $FlowExpectedError[incompatible-type] getNodeFromInternalInstanceHandle(instanceHandle); if (nativeReference != null) { // $FlowExpectedError[incompatible-type] return nativeReference; } if (isReactNativeDocumentInstanceHandle(instanceHandle)) { return getNativeNodeReferenceFromReactNativeDocumentInstanceHandle( instanceHandle, ); } if (isReactNativeDocumentElementInstanceHandle(instanceHandle)) { return getNativeElementReferenceFromReactNativeDocumentElementInstanceHandle( instanceHandle, ); } } export function getNativeElementReference( node: ReadOnlyElement, ): ?NativeElementReference { // $FlowExpectedError[incompatible-type] We know ReadOnlyElement instances provide InternalInstanceHandle const instanceHandle = getInstanceHandle(node) as InternalInstanceHandle; if (isReactNativeDocumentElementInstanceHandle(instanceHandle)) { return getNativeElementReferenceFromReactNativeDocumentElementInstanceHandle( instanceHandle, ); } // $FlowExpectedError[incompatible-type] return getNodeFromInternalInstanceHandle(instanceHandle); } export function getNativeTextReference( node: ReadOnlyCharacterData, ): ?NativeTextReference { // $FlowExpectedError[incompatible-type] We know ReadOnlyText instances provide InternalInstanceHandle const instanceHandle = getInstanceHandle(node) as InternalInstanceHandle; // $FlowExpectedError[incompatible-type] return getNodeFromInternalInstanceHandle(instanceHandle); }