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 {
    
  11.   getInstanceFromNode,
    
  12.   getFiberCurrentPropsFromNode,
    
  13. } from '../client/ReactDOMComponentTree';
    
  14. 
    
  15. import {restoreControlledState} from 'react-dom-bindings/src/client/ReactDOMComponent';
    
  16. 
    
  17. // Use to restore controlled state after a change event has fired.
    
  18. 
    
  19. let restoreTarget = null;
    
  20. let restoreQueue = null;
    
  21. 
    
  22. function restoreStateOfTarget(target: Node) {
    
  23.   // We perform this translation at the end of the event loop so that we
    
  24.   // always receive the correct fiber here
    
  25.   const internalInstance = getInstanceFromNode(target);
    
  26.   if (!internalInstance) {
    
  27.     // Unmounted
    
  28.     return;
    
  29.   }
    
  30. 
    
  31.   const stateNode = internalInstance.stateNode;
    
  32.   // Guard against Fiber being unmounted.
    
  33.   if (stateNode) {
    
  34.     const props = getFiberCurrentPropsFromNode(stateNode);
    
  35.     restoreControlledState(
    
  36.       internalInstance.stateNode,
    
  37.       internalInstance.type,
    
  38.       props,
    
  39.     );
    
  40.   }
    
  41. }
    
  42. 
    
  43. export function enqueueStateRestore(target: Node): void {
    
  44.   if (restoreTarget) {
    
  45.     if (restoreQueue) {
    
  46.       restoreQueue.push(target);
    
  47.     } else {
    
  48.       restoreQueue = [target];
    
  49.     }
    
  50.   } else {
    
  51.     restoreTarget = target;
    
  52.   }
    
  53. }
    
  54. 
    
  55. export function needsStateRestore(): boolean {
    
  56.   return restoreTarget !== null || restoreQueue !== null;
    
  57. }
    
  58. 
    
  59. export function restoreStateIfNeeded() {
    
  60.   if (!restoreTarget) {
    
  61.     return;
    
  62.   }
    
  63.   const target = restoreTarget;
    
  64.   const queuedTargets = restoreQueue;
    
  65.   restoreTarget = null;
    
  66.   restoreQueue = null;
    
  67. 
    
  68.   restoreStateOfTarget(target);
    
  69.   if (queuedTargets) {
    
  70.     for (let i = 0; i < queuedTargets.length; i++) {
    
  71.       restoreStateOfTarget(queuedTargets[i]);
    
  72.     }
    
  73.   }
    
  74. }