11import { BUILD } from '@app-data' ;
2- import { plt , win } from '@platform' ;
2+ import { getHostRef , plt , win } from '@platform' ;
33import { parsePropertyValue } from '@runtime' ;
44import { CMP_FLAGS , MEMBER_FLAGS } from '@utils' ;
55
66import type * as d from '../declarations' ;
7- import { patchSlottedNode } from './dom-extras' ;
7+ import { internalCall , patchSlottedNode } from './dom-extras' ;
88import { createTime } from './profile' ;
99import {
1010 COMMENT_NODE_ID ,
@@ -18,6 +18,7 @@ import {
1818 VNODE_FLAGS ,
1919} from './runtime-constants' ;
2020import { addSlotRelocateNode , patchSlotNode } from './slot-polyfill-utils' ;
21+ import { getScopeId } from './styles' ;
2122import { newVNode } from './vdom/h' ;
2223
2324/**
@@ -129,6 +130,19 @@ export const initializeClientHydrate = (
129130 // If we don't, `vdom-render.ts` will try to add nodes to it (and because it may be a comment node, it will error)
130131 node [ 's-cr' ] = hostElm [ 's-cr' ] ;
131132 }
133+ } else if ( childRenderNode . $tag$ ?. toString ( ) . includes ( '-' ) && ! childRenderNode . $elm$ . shadowRoot ) {
134+ // if this child is a non-shadow component being added to a shadowDOM,
135+ // let's find and add its styles to the shadowRoot, so we don't get a visual flicker
136+ const cmpMeta = getHostRef ( childRenderNode . $elm$ ) ;
137+ const scopeId = getScopeId (
138+ cmpMeta . $cmpMeta$ ,
139+ BUILD . mode ? childRenderNode . $elm$ . getAttribute ( 's-mode' ) : undefined ,
140+ ) ;
141+ const styleSheet = win . document . querySelector ( `style[sty-id="${ scopeId } "]` ) ;
142+
143+ if ( styleSheet ) {
144+ hostElm . shadowRoot . append ( styleSheet . cloneNode ( true ) ) ;
145+ }
132146 }
133147
134148 if ( childRenderNode . $tag$ === 'slot' ) {
@@ -150,7 +164,7 @@ export const initializeClientHydrate = (
150164 }
151165
152166 if ( orgLocationNode && orgLocationNode . isConnected ) {
153- if ( shadowRoot && orgLocationNode [ 's-en' ] === '' ) {
167+ if ( orgLocationNode . parentElement . shadowRoot && orgLocationNode [ 's-en' ] === '' ) {
154168 // if this node is within a shadowDOM, with an original location home
155169 // we're safe to move it now
156170 orgLocationNode . parentNode . insertBefore ( node , orgLocationNode . nextSibling ) ;
@@ -166,7 +180,9 @@ export const initializeClientHydrate = (
166180 }
167181 }
168182 // Remove the original location from the map
169- plt . $orgLocNodes$ . delete ( orgLocationId ) ;
183+ if ( orgLocationNode && ! orgLocationNode [ 's-id' ] ) {
184+ plt . $orgLocNodes$ . delete ( orgLocationId ) ;
185+ }
170186 }
171187
172188 const hosts : d . HostElement [ ] = [ ] ;
@@ -203,16 +219,18 @@ export const initializeClientHydrate = (
203219 if ( ! hostEle . shadowRoot || ! shadowRoot ) {
204220 // Try to set an appropriate Content-position Reference (CR) node for this host element
205221
206- // Is a CR already set on the host?
207- slottedItem . slot [ 's-cr' ] = hostEle [ 's-cr' ] ;
208-
209- if ( ! slottedItem . slot [ 's-cr' ] && hostEle . shadowRoot ) {
210- // Host has shadowDOM - just use the host itself as the CR for native slotting
211- slottedItem . slot [ 's-cr' ] = hostEle ;
212- } else {
213- // If all else fails - just set the CR as the first child
214- // (9/10 if node['s-cr'] hasn't been set, the node will be at the element root)
215- slottedItem . slot [ 's-cr' ] = ( ( hostEle as any ) . __childNodes || hostEle . childNodes ) [ 0 ] ;
222+ if ( ! slottedItem . slot [ 's-cr' ] ) {
223+ // Is a CR already set on the host?
224+ slottedItem . slot [ 's-cr' ] = hostEle [ 's-cr' ] ;
225+
226+ if ( ! slottedItem . slot [ 's-cr' ] && hostEle . shadowRoot ) {
227+ // Host has shadowDOM - just use the host itself as the CR for native slotting
228+ slottedItem . slot [ 's-cr' ] = hostEle ;
229+ } else {
230+ // If all else fails - just set the CR as the first child
231+ // (9/10 if node['s-cr'] hasn't been set, the node will be at the element root)
232+ slottedItem . slot [ 's-cr' ] = ( ( hostEle as any ) . __childNodes || hostEle . childNodes ) [ 0 ] ;
233+ }
216234 }
217235 // Create our 'Original Location' node
218236 addSlotRelocateNode ( slottedItem . node , slottedItem . slot , false , slottedItem . node [ 's-oo' ] ) ;
@@ -237,7 +255,7 @@ export const initializeClientHydrate = (
237255 } ) ;
238256 }
239257
240- if ( BUILD . shadowDom && shadowRoot && ! shadowRoot . childNodes . length ) {
258+ if ( BUILD . shadowDom && shadowRoot ) {
241259 // For `scoped` shadowDOM rendering (not DSD);
242260 // Add all the root nodes in the shadowDOM (a root node can have a whole nested DOM tree)
243261 let rnIdex = 0 ;
@@ -255,7 +273,7 @@ export const initializeClientHydrate = (
255273 // we can safely leave it be, native behavior will mean it's hidden
256274 ( node as HTMLElement ) . removeAttribute ( 'hidden' ) ;
257275 } else if (
258- node . nodeType === NODE_TYPE . CommentNode ||
276+ ( node . nodeType === NODE_TYPE . CommentNode && ! node . nodeValue ) ||
259277 ( node . nodeType === NODE_TYPE . TextNode && ! ( node as Text ) . wholeText . trim ( ) )
260278 ) {
261279 // During `scoped` shadowDOM rendering, there's a bunch of comment nodes used for positioning / empty text nodes.
@@ -267,7 +285,6 @@ export const initializeClientHydrate = (
267285 }
268286 }
269287
270- plt . $orgLocNodes$ . delete ( hostElm [ 's-id' ] ) ;
271288 hostRef . $hostElement$ = hostElm ;
272289 endHydrate ( ) ;
273290} ;
@@ -336,7 +353,7 @@ const clientHydrate = (
336353 parentVNode . $children$ = [ ] ;
337354 }
338355
339- if ( BUILD . scoped && scopeId ) {
356+ if ( BUILD . scoped && scopeId && childIdSplt [ 0 ] === hostId ) {
340357 // Host is `scoped: true` - add that flag to the child.
341358 // It's used in 'set-accessor.ts' to make sure our scoped class is present
342359 node [ 's-si' ] = scopeId ;
@@ -509,7 +526,7 @@ const clientHydrate = (
509526 vnode . $index$ = '0' ;
510527 parentVNode . $children$ = [ vnode ] ;
511528 } else {
512- if ( node . nodeType === NODE_TYPE . TextNode && ! ( node as unknown as Text ) . wholeText . trim ( ) ) {
529+ if ( node . nodeType === NODE_TYPE . TextNode && ! ( node as unknown as Text ) . wholeText . trim ( ) && ! node [ 's-nr' ] ) {
513530 // empty white space is never accounted for from SSR so there's
514531 // no corresponding comment node giving it a position in the DOM.
515532 // It therefore gets slotted / clumped together at the end of the host.
@@ -613,13 +630,13 @@ function addSlot(
613630 childVNode . $elm$ . setAttribute ( 'name' , slotName ) ;
614631 }
615632
616- if ( parentNodeId && parentNodeId !== childVNode . $hostId$ ) {
633+ if ( parentVNode . $elm$ . shadowRoot && parentNodeId && parentNodeId !== childVNode . $hostId$ ) {
617634 // Shadow component's slot is placed inside a nested component's shadowDOM; it doesn't belong to this host - it was forwarded by the SSR markup.
618635 // Insert it in the root of this host; it's lightDOM. It doesn't really matter where in the host root; the component will take care of it.
619- parentVNode . $elm$ . insertBefore ( slot , parentVNode . $elm$ . children [ 0 ] ) ;
636+ internalCall ( parentVNode . $elm$ , ' insertBefore' ) ( slot , internalCall ( parentVNode . $elm$ , ' children' ) [ 0 ] ) ;
620637 } else {
621638 // Insert the new slot element before the slot comment
622- node . parentNode . insertBefore ( slot , node ) ;
639+ internalCall ( internalCall ( node , ' parentNode' ) as d . RenderNode , ' insertBefore' ) ( slot , node ) ;
623640 }
624641 addSlottedNodes ( slottedNodes , slotId , slotName , node , childVNode . $hostId$ ) ;
625642
@@ -684,8 +701,9 @@ const addSlottedNodes = (
684701 ( ( ( slottedNode [ 'getAttribute' ] && slottedNode . getAttribute ( 'slot' ) ) || slottedNode [ 's-sn' ] ) === slotName ||
685702 ( slotName === '' &&
686703 ! slottedNode [ 's-sn' ] &&
687- ( ( slottedNode . nodeType === NODE_TYPE . CommentNode && slottedNode . nodeValue . indexOf ( '.' ) !== 1 ) ||
688- slottedNode . nodeType === NODE_TYPE . TextNode ) ) )
704+ ( slottedNode . nodeType === NODE_TYPE . CommentNode ||
705+ slottedNode . nodeType === NODE_TYPE . TextNode ||
706+ slottedNode . tagName === 'SLOT' ) ) )
689707 ) {
690708 slottedNode [ 's-sn' ] = slotName ;
691709 slottedNodes [ slotNodeId as any ] . push ( { slot : slotNode , node : slottedNode , hostId } ) ;
0 commit comments