@@ -32,7 +32,6 @@ import {
32
32
setInitialProperties ,
33
33
diffProperties ,
34
34
updateProperties ,
35
- resetProperties ,
36
35
diffHydratedProperties ,
37
36
diffHydratedText ,
38
37
trapClickOnNonInteractiveElement ,
@@ -124,7 +123,6 @@ export type Container =
124
123
| interface extends Document { _reactRootContainer ? : FiberRoot }
125
124
| interface extends DocumentFragment { _reactRootContainer ? : FiberRoot } ;
126
125
export type Instance = Element ;
127
- export type InstanceSibling = Node ;
128
126
export type TextInstance = Text ;
129
127
export interface SuspenseInstance extends Comment {
130
128
_reactRetry ?: ( ) => void ;
@@ -552,15 +550,15 @@ export function appendChildToContainer(
552
550
export function insertBefore (
553
551
parentInstance : Instance ,
554
552
child : Instance | TextInstance ,
555
- beforeChild : InstanceSibling ,
553
+ beforeChild : Instance ,
556
554
) : void {
557
555
parentInstance. insertBefore ( child , beforeChild ) ;
558
556
}
559
557
560
558
export function insertInContainerBefore (
561
559
container : Container ,
562
560
child : Instance | TextInstance ,
563
- beforeChild : InstanceSibling ,
561
+ beforeChild : Instance ,
564
562
) : void {
565
563
if ( container . nodeType === COMMENT_NODE ) {
566
564
( container . parentNode : any ) . insertBefore ( child , beforeChild ) ;
@@ -717,15 +715,32 @@ export function clearContainer(container: Container): void {
717
715
case 'html' :
718
716
case 'head' :
719
717
case 'body' : {
720
- clearSingletonInstance ( element ) ;
721
- break ;
718
+ let node = element . firstChild ;
719
+ while ( node ) {
720
+ const nextNode = node . nextSibling ;
721
+ const nodeName = node . nodeName ;
722
+ if (
723
+ nodeName === 'HEAD' ||
724
+ nodeName === 'BODY' ||
725
+ nodeName === 'STYLE' ||
726
+ ( nodeName === 'LINK' &&
727
+ ( ( node : any ) : HTMLLinkElement ) . rel . toLowerCase ( ) ===
728
+ 'stylesheet' )
729
+ ) {
730
+ // retain these nodes
731
+ } else {
732
+ element . removeChild ( node ) ;
733
+ }
734
+ node = nextNode ;
735
+ }
736
+ return ;
722
737
}
723
738
default : {
724
739
element . textContent = '' ;
725
740
}
726
741
}
727
742
}
728
- // Implicitly if the container is of type Document we rely on the Persistent HostComponent
743
+ // Implicitly if the container is of type Document we rely on the HostSingleton
729
744
// semantics to clear these nodes appropriately when being placed so no ahead of time
730
745
// clearing is necessary
731
746
} else {
@@ -1246,7 +1261,7 @@ export function errorHydratingContainer(parentContainer: Container): void {
1246
1261
}
1247
1262
}
1248
1263
1249
- export function acquireSingletonInstance (
1264
+ export function resolveSingletonInstance (
1250
1265
type : string ,
1251
1266
props : Props ,
1252
1267
rootContainerInstance : Container ,
@@ -1262,50 +1277,51 @@ export function acquireSingletonInstance(
1262
1277
const ownerDocument = getOwnerDocumentFromRootContainer (
1263
1278
rootContainerInstance ,
1264
1279
) ;
1265
- // For the three persistent Host Components that exist in DOM it is necessary for there to
1266
- // always be a documentElement. With normal html parsing this will always be the case but
1267
- // with pathological manipulation the document can end up in a state where no documentElement
1268
- // exists. We create it here if missing so we can treat it as an invariant.
1269
- // It is important to note that this dom mutation and others in this function happen
1270
- // in render rather than commit. This is tolerable because they only happen in degenerate cases
1271
- let htmlElement = ownerDocument . documentElement ;
1272
- if ( ! htmlElement ) {
1273
- htmlElement = ownerDocument . appendChild (
1274
- ownerDocument . createElement ( 'html' ) ,
1275
- ) ;
1276
- }
1277
1280
switch ( type ) {
1278
1281
case 'html ': {
1279
- return htmlElement ;
1282
+ const documentElement = ownerDocument . documentElement ;
1283
+ if ( ! documentElement ) {
1284
+ throw new Error (
1285
+ 'React expected an <html> element (document.documentElement) to exist in the Document but one was' +
1286
+ ' not found. React never removes the documentElement for any Document it renders into so' +
1287
+ ' the cause is likely in some other script running on this page.' ,
1288
+ ) ;
1289
+ }
1290
+ return documentElement ;
1280
1291
}
1281
1292
case 'head ': {
1282
- let head = ownerDocument . head ;
1293
+ const head = ownerDocument . head ;
1283
1294
if ( ! head ) {
1284
- head = htmlElement . insertBefore (
1285
- ownerDocument . createElement ( 'head' ) ,
1286
- ownerDocument . firstChild ,
1295
+ throw new Error (
1296
+ 'React expected a <head> element (document.head) to exist in the Document but one was' +
1297
+ ' not found. React never removes the head for any Document it renders into so' +
1298
+ ' the cause is likely in some other script running on this page.' ,
1287
1299
) ;
1288
1300
}
1289
1301
// We ensure this exists just above
1290
1302
return head ;
1291
1303
}
1292
1304
case 'body ': {
1293
- let body = ownerDocument . body ;
1305
+ const body = ownerDocument . body ;
1294
1306
if ( ! body ) {
1295
- body = htmlElement . appendChild ( ownerDocument . createElement ( 'body' ) ) ;
1307
+ throw new Error (
1308
+ 'React expected a <body> element (document.body) to exist in the Document but one was' +
1309
+ ' not found. React never removes the body for any Document it renders into so' +
1310
+ ' the cause is likely in some other script running on this page.' ,
1311
+ ) ;
1296
1312
}
1297
1313
// We ensure this exists just above
1298
1314
return body ;
1299
1315
}
1300
1316
default : {
1301
1317
throw new Error (
1302
- 'acquireSingletonInstance was called with an element type that is not supported. This is a bug in React.' ,
1318
+ 'resolveSingletonInstance was called with an element type that is not supported. This is a bug in React.' ,
1303
1319
) ;
1304
1320
}
1305
1321
}
1306
1322
}
1307
1323
1308
- export function resetSingletonInstance (
1324
+ export function acquireSingletonInstance (
1309
1325
type : string ,
1310
1326
props : Props ,
1311
1327
instance : Instance ,
@@ -1320,51 +1336,17 @@ export function resetSingletonInstance(
1320
1336
}
1321
1337
default : {
1322
1338
console . error (
1323
- 'resetSingletonInstance was called with an element type that is not supported. This is a bug in React.' ,
1339
+ 'acquireSingletonInstance was called with an element type that is not supported. This is a bug in React.' ,
1324
1340
) ;
1325
1341
}
1326
1342
}
1327
1343
}
1328
1344
1329
- clearSingletonInstance ( instance ) ;
1330
- resetProperties ( instance , type , props ) ;
1345
+ setInitialProperties ( instance , type , props ) ;
1331
1346
precacheFiberNode ( internalInstanceHandle , instance ) ;
1332
1347
updateFiberProps ( instance , props ) ;
1333
1348
}
1334
1349
1335
- export function clearSingletonInstance ( instance : Instance ) {
1336
- const tagName = instance . tagName . toLowerCase ( ) ;
1337
- switch ( tagName ) {
1338
- case 'html ': {
1339
- return ;
1340
- }
1341
- case 'head ':
1342
- case 'body ': {
1343
- let node = instance . firstChild ;
1344
- while ( node ) {
1345
- const nextNode = node . nextSibling ;
1346
- const nodeName = node . nodeName ;
1347
- if (
1348
- nodeName === 'STYLE' ||
1349
- ( nodeName === 'LINK' &&
1350
- ( ( node : any ) : HTMLLinkElement ) . rel . toLowerCase ( ) === 'stylesheet' )
1351
- ) {
1352
- // retain these nodes
1353
- } else {
1354
- instance . removeChild ( node ) ;
1355
- }
1356
- node = nextNode ;
1357
- }
1358
- return ;
1359
- }
1360
- default : {
1361
- throw new Error (
1362
- 'clearSingletonInstance was called with an element type that is not supported. this is a bug in React.' ,
1363
- ) ;
1364
- }
1365
- }
1366
- }
1367
-
1368
1350
// -------------------
1369
1351
// Test Selectors
1370
1352
// -------------------
0 commit comments