@@ -93,17 +93,20 @@ findDOMNode._injectFiber(function(fiber: Fiber) {
93
93
94
94
type DOMContainer =
95
95
| ( Element & {
96
- _reactRootContainer : ? Object ,
96
+ _reactRootContainer ?: Object | null ,
97
97
} )
98
98
| ( Document & {
99
- _reactRootContainer : ? Object ,
99
+ _reactRootContainer ?: Object | null ,
100
100
} ) ;
101
101
102
- type Container =
103
- | Element
104
- | Document
105
- // If the DOM container is lazily provided, the container is the namespace uri
106
- | string ;
102
+ type LazyContainer = {
103
+ namespace : string ,
104
+ ownerDocument : Document ,
105
+ getContainer : ( ) => Element | DOMContainer ,
106
+ _reactRootContainer ?: Object | null ,
107
+ } ;
108
+
109
+ type Container = DOMContainer | LazyContainer ;
107
110
108
111
type Props = {
109
112
autoFocus ?: boolean ,
@@ -123,10 +126,15 @@ type HostContext = HostContextDev | HostContextProd;
123
126
let eventsEnabled : ?boolean = null ;
124
127
let selectionInformation : ?mixed = null ;
125
128
129
+ function isLazyContainer ( container : Container ) : boolean {
130
+ return typeof ( container : any ) . getContainer === 'function' ;
131
+ }
132
+
126
133
function getOwnerDocument ( container : Container ) : Document {
127
134
let ownerDocument ;
128
- if ( typeof container === 'string' ) {
129
- ownerDocument = document ;
135
+ if ( isLazyContainer ( container ) ) {
136
+ const lazyContainer : LazyContainer = ( container : any ) ;
137
+ ownerDocument = lazyContainer . ownerDocument ;
130
138
} else if (
131
139
container . nodeType === DOCUMENT_NODE ||
132
140
container . nodeType === DOCUMENT_FRAGMENT_NODE
@@ -138,14 +146,17 @@ function getOwnerDocument(container: Container): Document {
138
146
return ownerDocument ;
139
147
}
140
148
141
- function ensureDOMContainer ( container : Container ) : Element | Document {
149
+ function ensureDOMContainer ( container : Container ) : DOMContainer {
150
+ if ( ! isLazyContainer ( container ) ) {
151
+ return ( ( container : any ) : DOMContainer ) ;
152
+ }
153
+ const lazyContainer : LazyContainer = ( container : any ) ;
154
+ const domContainer = lazyContainer . getContainer ( ) ;
142
155
invariant (
143
- typeof container !== 'string' ,
144
- // TODO: Better error message. Probably should have errored already, when
145
- // validating the result of getContainer.
156
+ container !== null && container !== undefined ,
157
+ // TODO: Better error message.
146
158
'Container should have resolved by now' ,
147
159
) ;
148
- const domContainer : Element | Document = ( container : any ) ;
149
160
return domContainer ;
150
161
}
151
162
@@ -200,8 +211,8 @@ var DOMRenderer = ReactFiberReconciler({
200
211
let type ;
201
212
let namespace ;
202
213
203
- if ( typeof rootContainerInstance === 'string' ) {
204
- namespace = rootContainerInstance ;
214
+ if ( isLazyContainer ( rootContainerInstance ) ) {
215
+ namespace = ( ( rootContainerInstance : any ) : LazyContainer ) . namespace ;
205
216
if ( __DEV__ ) {
206
217
return { namespace, ancestorInfo : null } ;
207
218
}
@@ -212,7 +223,7 @@ var DOMRenderer = ReactFiberReconciler({
212
223
namespace = root ? root . namespaceURI : getChildNamespace ( null , '' ) ;
213
224
} else {
214
225
const container : any = rootContainerInstance . nodeType === COMMENT_NODE
215
- ? rootContainerInstance . parentNode
226
+ ? ( rootContainerInstance : any ) . parentNode
216
227
: rootContainerInstance ;
217
228
const ownNamespace = container . namespaceURI || null ;
218
229
type = container . tagName ;
@@ -724,28 +735,21 @@ type PublicRoot = {
724
735
unmount ( callback : ?( ) = > mixed ) : void ,
725
736
726
737
_reactRootContainer : * ,
727
- _getComponent : ( ) => DOMContainer ,
728
738
} ;
729
739
730
- function PublicRootNode (
731
- container : DOMContainer | ( ( ) => DOMContainer ) ,
740
+ type RootOptions = {
741
+ hydrate ?: boolean ,
742
+ } ;
743
+
744
+ type LazyRootOptions = {
732
745
namespace ?: string ,
733
- ) {
734
- if ( typeof container === 'function' ) {
735
- if ( typeof namespace !== 'string' ) {
736
- // Default to HTML namespace
737
- namespace = DOMNamespaces . html ;
738
- }
739
- this . _reactRootContainer = DOMRenderer . createContainer ( namespace ) ;
740
- this . _getComponent = container ;
741
- } else {
742
- // Assume this is a DOM container
743
- const domContainer : DOMContainer = ( container : any ) ;
744
- this . _reactRootContainer = DOMRenderer . createContainer ( domContainer ) ;
745
- this . _getComponent = function ( ) {
746
- return domContainer ;
747
- } ;
748
- }
746
+ ownerDocument ?: Document ,
747
+ } ;
748
+
749
+ function PublicRootNode ( container : Container , hydrate : boolean ) {
750
+ const root = DOMRenderer . createContainer ( container ) ;
751
+ root . hydrate = hydrate ;
752
+ this . _reactRootContainer = root ;
749
753
}
750
754
PublicRootNode . prototype . render = function (
751
755
children : ReactNodeList ,
@@ -776,10 +780,38 @@ PublicRootNode.prototype.unmount = function(callback) {
776
780
777
781
var ReactDOMFiber = {
778
782
unstable_createRoot (
779
- container : DOMContainer | ( ( ) => DOMContainer ) ,
780
- namespace ? : string ,
783
+ container : DOMContainer ,
784
+ options ? : RootOptions ,
785
+ ) : PublicRoot {
786
+ let hydrate = false ;
787
+ if ( options != null && options . hydrate !== undefined ) {
788
+ hydrate = options . hydrate ;
789
+ }
790
+ return new PublicRootNode ( container , hydrate ) ;
791
+ } ,
792
+
793
+ unstable_createLazyRoot (
794
+ getContainer : ( ) = > DOMContainer ,
795
+ options ? : LazyRootOptions ,
781
796
) : PublicRoot {
782
- return new PublicRootNode ( container , namespace ) ;
797
+ // Default to HTML namespace
798
+ let namespace = DOMNamespaces . html ;
799
+ // Default to global document
800
+ let ownerDocument = document ;
801
+ if ( options != null ) {
802
+ if ( options . namespace != null ) {
803
+ namespace = options . namespace ;
804
+ }
805
+ if ( options . ownerDocument != null ) {
806
+ ownerDocument = options . ownerDocument ;
807
+ }
808
+ }
809
+ const container = {
810
+ getContainer,
811
+ namespace,
812
+ ownerDocument,
813
+ } ;
814
+ return new PublicRootNode ( container , false ) ;
783
815
} ,
784
816
785
817
createPortal ,
0 commit comments