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 {ReactNodeList} from 'shared/ReactTypes';
    
  11. import type {
    
  12.   Container,
    
  13.   PublicInstance,
    
  14. } from 'react-dom-bindings/src/client/ReactFiberConfigDOM';
    
  15. import type {
    
  16.   RootType,
    
  17.   HydrateRootOptions,
    
  18.   CreateRootOptions,
    
  19. } from './ReactDOMRoot';
    
  20. 
    
  21. import {
    
  22.   findDOMNode,
    
  23.   render,
    
  24.   hydrate,
    
  25.   unstable_renderSubtreeIntoContainer,
    
  26.   unmountComponentAtNode,
    
  27. } from './ReactDOMLegacy';
    
  28. import {
    
  29.   createRoot as createRootImpl,
    
  30.   hydrateRoot as hydrateRootImpl,
    
  31.   isValidContainer,
    
  32. } from './ReactDOMRoot';
    
  33. import {createEventHandle} from 'react-dom-bindings/src/client/ReactDOMEventHandle';
    
  34. 
    
  35. import {
    
  36.   batchedUpdates,
    
  37.   flushSync as flushSyncWithoutWarningIfAlreadyRendering,
    
  38.   isAlreadyRendering,
    
  39.   injectIntoDevTools,
    
  40. } from 'react-reconciler/src/ReactFiberReconciler';
    
  41. import {runWithPriority} from 'react-reconciler/src/ReactEventPriorities';
    
  42. import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
    
  43. import {canUseDOM} from 'shared/ExecutionEnvironment';
    
  44. import ReactVersion from 'shared/ReactVersion';
    
  45. 
    
  46. import {
    
  47.   getClosestInstanceFromNode,
    
  48.   getInstanceFromNode,
    
  49.   getNodeFromInstance,
    
  50.   getFiberCurrentPropsFromNode,
    
  51. } from 'react-dom-bindings/src/client/ReactDOMComponentTree';
    
  52. import {
    
  53.   enqueueStateRestore,
    
  54.   restoreStateIfNeeded,
    
  55. } from 'react-dom-bindings/src/events/ReactDOMControlledComponent';
    
  56. import Internals from '../ReactDOMSharedInternals';
    
  57. 
    
  58. export {
    
  59.   prefetchDNS,
    
  60.   preconnect,
    
  61.   preload,
    
  62.   preloadModule,
    
  63.   preinit,
    
  64.   preinitModule,
    
  65. } from '../shared/ReactDOMFloat';
    
  66. export {
    
  67.   useFormStatus,
    
  68.   useFormState,
    
  69. } from 'react-dom-bindings/src/shared/ReactDOMFormActions';
    
  70. 
    
  71. if (__DEV__) {
    
  72.   if (
    
  73.     typeof Map !== 'function' ||
    
  74.     // $FlowFixMe[prop-missing] Flow incorrectly thinks Map has no prototype
    
  75.     Map.prototype == null ||
    
  76.     typeof Map.prototype.forEach !== 'function' ||
    
  77.     typeof Set !== 'function' ||
    
  78.     // $FlowFixMe[prop-missing] Flow incorrectly thinks Set has no prototype
    
  79.     Set.prototype == null ||
    
  80.     typeof Set.prototype.clear !== 'function' ||
    
  81.     typeof Set.prototype.forEach !== 'function'
    
  82.   ) {
    
  83.     console.error(
    
  84.       'React depends on Map and Set built-in types. Make sure that you load a ' +
    
  85.         'polyfill in older browsers. https://reactjs.org/link/react-polyfills',
    
  86.     );
    
  87.   }
    
  88. }
    
  89. 
    
  90. function createPortal(
    
  91.   children: ReactNodeList,
    
  92.   container: Element | DocumentFragment,
    
  93.   key: ?string = null,
    
  94. ): React$Portal {
    
  95.   if (!isValidContainer(container)) {
    
  96.     throw new Error('Target container is not a DOM element.');
    
  97.   }
    
  98. 
    
  99.   // TODO: pass ReactDOM portal implementation as third argument
    
  100.   // $FlowFixMe[incompatible-return] The Flow type is opaque but there's no way to actually create it.
    
  101.   return createPortalImpl(children, container, null, key);
    
  102. }
    
  103. 
    
  104. function renderSubtreeIntoContainer(
    
  105.   parentComponent: React$Component<any, any>,
    
  106.   element: React$Element<any>,
    
  107.   containerNode: Container,
    
  108.   callback: ?Function,
    
  109. ): React$Component<any, any> | PublicInstance | null {
    
  110.   return unstable_renderSubtreeIntoContainer(
    
  111.     parentComponent,
    
  112.     element,
    
  113.     containerNode,
    
  114.     callback,
    
  115.   );
    
  116. }
    
  117. 
    
  118. function createRoot(
    
  119.   container: Element | Document | DocumentFragment,
    
  120.   options?: CreateRootOptions,
    
  121. ): RootType {
    
  122.   if (__DEV__) {
    
  123.     if (!Internals.usingClientEntryPoint && !__UMD__) {
    
  124.       console.error(
    
  125.         'You are importing createRoot from "react-dom" which is not supported. ' +
    
  126.           'You should instead import it from "react-dom/client".',
    
  127.       );
    
  128.     }
    
  129.   }
    
  130.   return createRootImpl(container, options);
    
  131. }
    
  132. 
    
  133. function hydrateRoot(
    
  134.   container: Document | Element,
    
  135.   initialChildren: ReactNodeList,
    
  136.   options?: HydrateRootOptions,
    
  137. ): RootType {
    
  138.   if (__DEV__) {
    
  139.     if (!Internals.usingClientEntryPoint && !__UMD__) {
    
  140.       console.error(
    
  141.         'You are importing hydrateRoot from "react-dom" which is not supported. ' +
    
  142.           'You should instead import it from "react-dom/client".',
    
  143.       );
    
  144.     }
    
  145.   }
    
  146.   return hydrateRootImpl(container, initialChildren, options);
    
  147. }
    
  148. 
    
  149. // Overload the definition to the two valid signatures.
    
  150. // Warning, this opts-out of checking the function body.
    
  151. declare function flushSync<R>(fn: () => R): R;
    
  152. // eslint-disable-next-line no-redeclare
    
  153. declare function flushSync(): void;
    
  154. // eslint-disable-next-line no-redeclare
    
  155. function flushSync<R>(fn: (() => R) | void): R | void {
    
  156.   if (__DEV__) {
    
  157.     if (isAlreadyRendering()) {
    
  158.       console.error(
    
  159.         'flushSync was called from inside a lifecycle method. React cannot ' +
    
  160.           'flush when React is already rendering. Consider moving this call to ' +
    
  161.           'a scheduler task or micro task.',
    
  162.       );
    
  163.     }
    
  164.   }
    
  165.   return flushSyncWithoutWarningIfAlreadyRendering(fn);
    
  166. }
    
  167. 
    
  168. export {
    
  169.   createPortal,
    
  170.   batchedUpdates as unstable_batchedUpdates,
    
  171.   flushSync,
    
  172.   ReactVersion as version,
    
  173.   // Disabled behind disableLegacyReactDOMAPIs
    
  174.   findDOMNode,
    
  175.   hydrate,
    
  176.   render,
    
  177.   unmountComponentAtNode,
    
  178.   // exposeConcurrentModeAPIs
    
  179.   createRoot,
    
  180.   hydrateRoot,
    
  181.   // Disabled behind disableUnstableRenderSubtreeIntoContainer
    
  182.   renderSubtreeIntoContainer as unstable_renderSubtreeIntoContainer,
    
  183.   // enableCreateEventHandleAPI
    
  184.   createEventHandle as unstable_createEventHandle,
    
  185.   // TODO: Remove this once callers migrate to alternatives.
    
  186.   // This should only be used by React internals.
    
  187.   runWithPriority as unstable_runWithPriority,
    
  188. };
    
  189. 
    
  190. // Keep in sync with ReactTestUtils.js.
    
  191. // This is an array for better minification.
    
  192. Internals.Events = [
    
  193.   getInstanceFromNode,
    
  194.   getNodeFromInstance,
    
  195.   getFiberCurrentPropsFromNode,
    
  196.   enqueueStateRestore,
    
  197.   restoreStateIfNeeded,
    
  198.   batchedUpdates,
    
  199. ];
    
  200. 
    
  201. const foundDevTools = injectIntoDevTools({
    
  202.   findFiberByHostInstance: getClosestInstanceFromNode,
    
  203.   bundleType: __DEV__ ? 1 : 0,
    
  204.   version: ReactVersion,
    
  205.   rendererPackageName: 'react-dom',
    
  206. });
    
  207. 
    
  208. if (__DEV__) {
    
  209.   if (!foundDevTools && canUseDOM && window.top === window.self) {
    
  210.     // If we're in Chrome or Firefox, provide a download link if not installed.
    
  211.     if (
    
  212.       (navigator.userAgent.indexOf('Chrome') > -1 &&
    
  213.         navigator.userAgent.indexOf('Edge') === -1) ||
    
  214.       navigator.userAgent.indexOf('Firefox') > -1
    
  215.     ) {
    
  216.       const protocol = window.location.protocol;
    
  217.       // Don't warn in exotic cases like chrome-extension://.
    
  218.       if (/^(https?|file):$/.test(protocol)) {
    
  219.         // eslint-disable-next-line react-internal/no-production-logging
    
  220.         console.info(
    
  221.           '%cDownload the React DevTools ' +
    
  222.             'for a better development experience: ' +
    
  223.             'https://reactjs.org/link/react-devtools' +
    
  224.             (protocol === 'file:'
    
  225.               ? '\nYou might need to use a local HTTP server (instead of file://): ' +
    
  226.                 'https://reactjs.org/link/react-devtools-faq'
    
  227.               : ''),
    
  228.           'font-weight:bold',
    
  229.         );
    
  230.       }
    
  231.     }
    
  232.   }
    
  233. }