Repository: facebook/react
Pull request: Support document rendering

## Hydrating into Document
This PR addressed the most fundamental issue identified in #22833. In that issue a hydration mismatch when hydrating into the Document caused a broken application because the client rendered fallback could not append any content to the Document.

This is caused by the fact that a Document can only have 1 element at a time, namely the documentElement which is usually `<html>` and by not removing it beforehand the append of a new `<html>` element fails.

Initially I looked into recycling the documentElement so it is never removed or appended but just moved around to whatever fiber needs it, staying in the Document tree as its root. This worked fine but added some code on hot paths and a bit of size.

I then looked at what would happen if we simply removed the documentElement (i.e. treat it like any other Element) and in Chrome, Safari, and Firefox (modern versions) there seems to be no issue with this. This PR is much smaller and simply updates `clearContainer` to properly clear the Document as a container so that a later appendChild of an `<html>` element will not violation Document invariants

### Hydration into Document compatibility with 3rd party scripts and Extensions

The original issue shows an extension breaking a React application. This PR does not introduce compatibility with extensions or 3rd party scripts that modify the DOM before React hydrates, it simply inverts what gets broken. This change would result in (worst case) React breaking the extension rather than the extension breaking React.

## createRoot for Document
as a consequence of the fix for hydration in Document using Document as a root should work now. This PR also adds back types for using createRoot on Document. It should be noted that doing so will effectively wipe out the entire document so third party styles and other DOM elements created by server response, 3rd party scripts, or extensions will be dropped. This is probably not that useful a feature but since it is supported by implementation with no special casing I added back in

Changed files:
filename: packages/react-dom/client.js
patch: @@ -23,7 +23,7 @@ import {
 } from './';
 
 export function createRoot(
-  container: Element | DocumentFragment,
+  container: Element | Document | DocumentFragment,
   options?: CreateRootOptions,
 ): RootType {
   if (__DEV__) {

filename: packages/react-dom/src/client/ReactDOM.js
patch: @@ -148,7 +148,7 @@ const Internals = {
 };
 
 function createRoot(
-  container: Element | DocumentFragment,
+  container: Element | Document | DocumentFragment,
   options?: CreateRootOptions,
 ): RootType {
   if (__DEV__) {

filename: packages/react-dom/src/client/ReactDOMHostConfig.js
patch: @@ -672,9 +672,8 @@ export function clearContainer(container: Container): void {
   if (container.nodeType === ELEMENT_NODE) {
     ((container: any): Element).textContent = '';
   } else if (container.nodeType === DOCUMENT_NODE) {
-    const body = ((container: any): Document).body;
-    if (body != null) {
-      body.textContent = '';
+    if (container.documentElement) {
+      container.removeChild(container.documentElement);
     }
   }
 }

filename: packages/react-dom/src/client/ReactDOMRoot.js
patch: @@ -164,7 +164,7 @@ ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = funct
 };
 
 export function createRoot(
-  container: Element | DocumentFragment,
+  container: Element | Document | DocumentFragment,
   options?: CreateRootOptions,
 ): RootType {
   if (!isValidContainer(container)) {