1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow
    
  8.  */
    
  9. 
    
  10. import type {ElementRef} from 'react';
    
  11. import type {
    
  12.   HostComponent,
    
  13.   MeasureInWindowOnSuccessCallback,
    
  14.   MeasureLayoutOnSuccessCallback,
    
  15.   MeasureOnSuccessCallback,
    
  16.   INativeMethods,
    
  17.   ViewConfig,
    
  18. } from './ReactNativeTypes';
    
  19. import type {Instance} from './ReactFiberConfigNative';
    
  20. 
    
  21. // Modules provided by RN:
    
  22. import {
    
  23.   TextInputState,
    
  24.   UIManager,
    
  25. } from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
    
  26. 
    
  27. import {create} from './ReactNativeAttributePayload';
    
  28. import {
    
  29.   mountSafeCallback_NOT_REALLY_SAFE,
    
  30.   warnForStyleProps,
    
  31. } from './NativeMethodsMixinUtils';
    
  32. 
    
  33. class ReactNativeFiberHostComponent implements INativeMethods {
    
  34.   _children: Array<Instance | number>;
    
  35.   _nativeTag: number;
    
  36.   _internalFiberInstanceHandleDEV: Object;
    
  37.   viewConfig: ViewConfig;
    
  38. 
    
  39.   constructor(
    
  40.     tag: number,
    
  41.     viewConfig: ViewConfig,
    
  42.     internalInstanceHandleDEV: Object,
    
  43.   ) {
    
  44.     this._nativeTag = tag;
    
  45.     this._children = [];
    
  46.     this.viewConfig = viewConfig;
    
  47.     if (__DEV__) {
    
  48.       this._internalFiberInstanceHandleDEV = internalInstanceHandleDEV;
    
  49.     }
    
  50.   }
    
  51. 
    
  52.   blur() {
    
  53.     TextInputState.blurTextInput(this);
    
  54.   }
    
  55. 
    
  56.   focus() {
    
  57.     TextInputState.focusTextInput(this);
    
  58.   }
    
  59. 
    
  60.   measure(callback: MeasureOnSuccessCallback) {
    
  61.     UIManager.measure(
    
  62.       this._nativeTag,
    
  63.       mountSafeCallback_NOT_REALLY_SAFE(this, callback),
    
  64.     );
    
  65.   }
    
  66. 
    
  67.   measureInWindow(callback: MeasureInWindowOnSuccessCallback) {
    
  68.     UIManager.measureInWindow(
    
  69.       this._nativeTag,
    
  70.       mountSafeCallback_NOT_REALLY_SAFE(this, callback),
    
  71.     );
    
  72.   }
    
  73. 
    
  74.   measureLayout(
    
  75.     relativeToNativeNode: number | ElementRef<HostComponent<mixed>>,
    
  76.     onSuccess: MeasureLayoutOnSuccessCallback,
    
  77.     onFail?: () => void /* currently unused */,
    
  78.   ) {
    
  79.     let relativeNode: ?number;
    
  80. 
    
  81.     if (typeof relativeToNativeNode === 'number') {
    
  82.       // Already a node handle
    
  83.       relativeNode = relativeToNativeNode;
    
  84.     } else {
    
  85.       const nativeNode: ReactNativeFiberHostComponent =
    
  86.         (relativeToNativeNode: any);
    
  87.       if (nativeNode._nativeTag) {
    
  88.         relativeNode = nativeNode._nativeTag;
    
  89.       }
    
  90.     }
    
  91. 
    
  92.     if (relativeNode == null) {
    
  93.       if (__DEV__) {
    
  94.         console.error(
    
  95.           'Warning: ref.measureLayout must be called with a node handle or a ref to a native component.',
    
  96.         );
    
  97.       }
    
  98. 
    
  99.       return;
    
  100.     }
    
  101. 
    
  102.     UIManager.measureLayout(
    
  103.       this._nativeTag,
    
  104.       relativeNode,
    
  105.       mountSafeCallback_NOT_REALLY_SAFE(this, onFail),
    
  106.       mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess),
    
  107.     );
    
  108.   }
    
  109. 
    
  110.   setNativeProps(nativeProps: Object) {
    
  111.     if (__DEV__) {
    
  112.       warnForStyleProps(nativeProps, this.viewConfig.validAttributes);
    
  113.     }
    
  114. 
    
  115.     const updatePayload = create(nativeProps, this.viewConfig.validAttributes);
    
  116. 
    
  117.     // Avoid the overhead of bridge calls if there's no update.
    
  118.     // This is an expensive no-op for Android, and causes an unnecessary
    
  119.     // view invalidation for certain components (eg RCTTextInput) on iOS.
    
  120.     if (updatePayload != null) {
    
  121.       UIManager.updateView(
    
  122.         this._nativeTag,
    
  123.         this.viewConfig.uiViewClassName,
    
  124.         updatePayload,
    
  125.       );
    
  126.     }
    
  127.   }
    
  128. }
    
  129. 
    
  130. export default ReactNativeFiberHostComponent;