react-native-get-pixel_edit/node_modules/react-native/Libraries/DOM/Nodes/ReactNativeElement.js
2025-07-09 11:41:52 +09:00

193 lines
5.3 KiB
JavaScript

/**
* 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.
*
* @format
* @flow strict-local
*/
// flowlint unsafe-getters-setters:off
import type {
HostComponent,
INativeMethods,
InternalInstanceHandle,
MeasureInWindowOnSuccessCallback,
MeasureLayoutOnSuccessCallback,
MeasureOnSuccessCallback,
ViewConfig,
} from '../../Renderer/shims/ReactNativeTypes';
import type {ElementRef} from 'react';
import TextInputState from '../../Components/TextInput/TextInputState';
import {getFabricUIManager} from '../../ReactNative/FabricUIManager';
import {create as createAttributePayload} from '../../ReactNative/ReactFabricPublicInstance/ReactNativeAttributePayload';
import warnForStyleProps from '../../ReactNative/ReactFabricPublicInstance/warnForStyleProps';
import ReadOnlyElement, {getBoundingClientRect} from './ReadOnlyElement';
import ReadOnlyNode from './ReadOnlyNode';
import {
getPublicInstanceFromInternalInstanceHandle,
getShadowNode,
} from './ReadOnlyNode';
import nullthrows from 'nullthrows';
const noop = () => {};
export default class ReactNativeElement
extends ReadOnlyElement
implements INativeMethods
{
// These need to be accessible from `ReactFabricPublicInstanceUtils`.
__nativeTag: number;
__internalInstanceHandle: InternalInstanceHandle;
_viewConfig: ViewConfig;
constructor(
tag: number,
viewConfig: ViewConfig,
internalInstanceHandle: InternalInstanceHandle,
) {
super(internalInstanceHandle);
this.__nativeTag = tag;
this.__internalInstanceHandle = internalInstanceHandle;
this._viewConfig = viewConfig;
}
get offsetHeight(): number {
return Math.round(
getBoundingClientRect(this, {includeTransform: false}).height,
);
}
get offsetLeft(): number {
const node = getShadowNode(this);
if (node != null) {
const offset = nullthrows(getFabricUIManager()).getOffset(node);
if (offset != null) {
return Math.round(offset[2]);
}
}
return 0;
}
get offsetParent(): ReadOnlyElement | null {
const node = getShadowNode(this);
if (node != null) {
const offset = nullthrows(getFabricUIManager()).getOffset(node);
// For children of the root node we currently return offset data
// but a `null` parent because the root node is not accessible
// in JavaScript yet.
if (offset != null && offset[0] != null) {
const offsetParentInstanceHandle = offset[0];
const offsetParent = getPublicInstanceFromInternalInstanceHandle(
offsetParentInstanceHandle,
);
// $FlowExpectedError[incompatible-type] The value returned by `getOffset` is always an instance handle for `ReadOnlyElement`.
const offsetParentElement: ReadOnlyElement = offsetParent;
return offsetParentElement;
}
}
return null;
}
get offsetTop(): number {
const node = getShadowNode(this);
if (node != null) {
const offset = nullthrows(getFabricUIManager()).getOffset(node);
if (offset != null) {
return Math.round(offset[1]);
}
}
return 0;
}
get offsetWidth(): number {
return Math.round(
getBoundingClientRect(this, {includeTransform: false}).width,
);
}
/**
* React Native compatibility methods
*/
blur(): void {
// $FlowFixMe[incompatible-exact] Migrate all usages of `NativeMethods` to an interface to fix this.
TextInputState.blurTextInput(this);
}
focus() {
// $FlowFixMe[incompatible-exact] Migrate all usages of `NativeMethods` to an interface to fix this.
TextInputState.focusTextInput(this);
}
measure(callback: MeasureOnSuccessCallback) {
const node = getShadowNode(this);
if (node != null) {
nullthrows(getFabricUIManager()).measure(node, callback);
}
}
measureInWindow(callback: MeasureInWindowOnSuccessCallback) {
const node = getShadowNode(this);
if (node != null) {
nullthrows(getFabricUIManager()).measureInWindow(node, callback);
}
}
measureLayout(
relativeToNativeNode: number | ElementRef<HostComponent<mixed>>,
onSuccess: MeasureLayoutOnSuccessCallback,
onFail?: () => void /* currently unused */,
) {
if (!(relativeToNativeNode instanceof ReadOnlyNode)) {
if (__DEV__) {
console.error(
'Warning: ref.measureLayout must be called with a ref to a native component.',
);
}
return;
}
const toStateNode = getShadowNode(this);
const fromStateNode = getShadowNode(relativeToNativeNode);
if (toStateNode != null && fromStateNode != null) {
nullthrows(getFabricUIManager()).measureLayout(
toStateNode,
fromStateNode,
onFail != null ? onFail : noop,
onSuccess != null ? onSuccess : noop,
);
}
}
setNativeProps(nativeProps: {...}): void {
if (__DEV__) {
warnForStyleProps(nativeProps, this._viewConfig.validAttributes);
}
const updatePayload = createAttributePayload(
nativeProps,
this._viewConfig.validAttributes,
);
const node = getShadowNode(this);
if (node != null && updatePayload != null) {
nullthrows(getFabricUIManager()).setNativeProps(node, updatePayload);
}
}
}