import type * as d from '../declarations' ; import { BUILD } from '@app-data' ; import { CONTENT_REF_ID , HYDRATE_CHILD_ID , HYDRATE_ID , NODE_TYPE , ORG_LOCATION_ID , SLOT_NODE_ID , TEXT_NODE_ID , } from './runtime-constants' ; import { doc , plt , supportsShadow } from '@platform' ; import { newVNode } from './vdom/h' ; import { createTime } from './profile' ; export const initializeClientHydrate = ( hostElm , tagName , hostId , hostRef ) => { const endHydrate = createTime ( 'hydrateClient' , tagName ) ; const shadowRoot = hostElm . shadowRoot ; const childRenderNodes = [ ] ; const slotNodes = [ ] ; const shadowRootNodes = BUILD . shadowDom && shadowRoot ? [ ] : null ; const vnode = ( hostRef . $vnode$ = newVNode ( tagName , null ) ) ; if ( ! plt . $orgLocNodes$ ) { initializeDocumentHydrate ( doc . body , ( plt . $orgLocNodes$ = new Map ( ) ) ) ; } hostElm [ HYDRATE_ID ] = hostId ; hostElm . removeAttribute ( HYDRATE_ID ) ; clientHydrate ( vnode , childRenderNodes , slotNodes , shadowRootNodes , hostElm , hostElm , hostId ) ; childRenderNodes . map ( ( c ) => { const orgLocationId = c . $hostId$ + '.' + c . $nodeId$ ; const orgLocationNode = plt . $orgLocNodes$ . get ( orgLocationId ) ; const node = c . $elm$ as d . RenderNode ; if ( orgLocationNode && supportsShadow && orgLocationNode [ 's-en' ] === '' ) { orgLocationNode . parentNode . insertBefore ( node , orgLocationNode . nextSibling ) ; } if ( ! shadowRoot ) { node [ 's-hn' ] = tagName ; if ( orgLocationNode ) { node [ 's-ol' ] = orgLocationNode ; node [ 's-ol' ] [ 's-nr' ] = node ; } } plt . $orgLocNodes$ . delete ( orgLocationId ) ; } ) ; if ( BUILD . shadowDom && shadowRoot ) { shadowRootNodes . map ( ( shadowRootNode ) => { if ( shadowRootNode ) { shadowRoot . appendChild ( shadowRootNode as any ) ; } } ) ; } endHydrate ( ) ; } ; const clientHydrate = ( parentVNode , childRenderNodes , slotNodes , shadowRootNodes , hostElm , node , hostId ) => { let childNodeType ; let childIdSplt ; let childVNode ; let i ; if ( node . nodeType === NODE_TYPE . ElementNode ) { childNodeType = ( node as HTMLElement ) . getAttribute ( HYDRATE_CHILD_ID ) ; if ( childNodeType ) { childIdSplt = childNodeType . split ( '.' ) ; if ( childIdSplt [ 0 ] === hostId || childIdSplt [ 0 ] === '0' ) { childVNode = { $flags$ : 0 , $hostId$ : childIdSplt [ 0 ] , $nodeId$ : childIdSplt [ 1 ] , $depth$ : childIdSplt [ 2 ] , $index$ : childIdSplt [ 3 ] , $tag$ : node . tagName . toLowerCase ( ) , $elm$ : node , $attrs$ : null , $children$ : null , $key$ : null , $name$ : null , $text$ : null , } ; childRenderNodes . push ( childVNode ) ; node . removeAttribute ( HYDRATE_CHILD_ID ) ; if ( ! parentVNode . $children$ ) { parentVNode . $children$ = [ ] ; } parentVNode . $children$ [ childVNode . $index$ as any ] = childVNode ; parentVNode = childVNode ; if ( shadowRootNodes && childVNode . $depth$ === '0' ) { shadowRootNodes [ childVNode . $index$ as any ] = childVNode . $elm$ ; } } } for ( i = node . childNodes . length - 1 ; i >= 0 ; i -- ) { clientHydrate ( parentVNode , childRenderNodes , slotNodes , shadowRootNodes , hostElm , node . childNodes [ i ] as any , hostId ) ; } if ( node . shadowRoot ) { for ( i = node . shadowRoot . childNodes . length - 1 ; i >= 0 ; i -- ) { clientHydrate ( parentVNode , childRenderNodes , slotNodes , shadowRootNodes , hostElm , node . shadowRoot . childNodes [ i ] as any , hostId ) ; } } } else if ( node . nodeType === NODE_TYPE . CommentNode ) { childIdSplt = node . nodeValue . split ( '.' ) ; if ( childIdSplt [ 1 ] === hostId || childIdSplt [ 1 ] === '0' ) { childNodeType = childIdSplt [ 0 ] ; childVNode = { $flags$ : 0 , $hostId$ : childIdSplt [ 1 ] , $nodeId$ : childIdSplt [ 2 ] , $depth$ : childIdSplt [ 3 ] , $index$ : childIdSplt [ 4 ] , $elm$ : node , $attrs$ : null , $children$ : null , $key$ : null , $name$ : null , $tag$ : null , $text$ : null , } ; if ( childNodeType === TEXT_NODE_ID ) { childVNode . $elm$ = node . nextSibling as any ; if ( childVNode . $elm$ && childVNode . $elm$ . nodeType === NODE_TYPE . TextNode ) { childVNode . $text$ = childVNode . $elm$ . textContent ; childRenderNodes . push ( childVNode ) ; node . remove ( ) ; if ( ! parentVNode . $children$ ) { parentVNode . $children$ = [ ] ; } parentVNode . $children$ [ childVNode . $index$ as any ] = childVNode ; if ( shadowRootNodes && childVNode . $depth$ === '0' ) { shadowRootNodes [ childVNode . $index$ as any ] = childVNode . $elm$ ; } } } else if ( childVNode . $hostId$ === hostId ) { if ( childNodeType === SLOT_NODE_ID ) { childVNode . $tag$ = 'slot' ; if ( childIdSplt [ 5 ] ) { node [ 's-sn' ] = childVNode . $name$ = childIdSplt [ 5 ] ; } else { node [ 's-sn' ] = '' ; } node [ 's-sr' ] = true ; if ( BUILD . shadowDom && shadowRootNodes ) { childVNode . $elm$ = doc . createElement ( childVNode . $tag$ ) ; if ( childVNode . $name$ ) { childVNode . $elm$ . setAttribute ( 'name' , childVNode . $name$ ) ; } node . parentNode . insertBefore ( childVNode . $elm$ , node ) ; node . remove ( ) ; if ( childVNode . $depth$ === '0' ) { shadowRootNodes [ childVNode . $index$ as any ] = childVNode . $elm$ ; } } slotNodes . push ( childVNode ) ; if ( ! parentVNode . $children$ ) { parentVNode . $children$ = [ ] ; } parentVNode . $children$ [ childVNode . $index$ as any ] = childVNode ; } else if ( childNodeType === CONTENT_REF_ID ) { if ( BUILD . shadowDom && shadowRootNodes ) { node . remove ( ) ; } else if ( BUILD . slotRelocation ) { hostElm [ 's-cr' ] = node ; node [ 's-cn' ] = true ; } } } } } else if ( parentVNode && parentVNode . $tag$ === 'style' ) { const vnode = newVNode ( null , node . textContent ) as any ; vnode . $elm$ = node ; vnode . $index$ = '0' ; parentVNode . $children$ = [ vnode ] ; } } ; export const initializeDocumentHydrate = ( node , orgLocNodes ) => { if ( node . nodeType === NODE_TYPE . ElementNode ) { let i = 0 ; for ( ; i < node . childNodes . length ; i ++ ) { initializeDocumentHydrate ( node . childNodes [ i ] as any , orgLocNodes ) ; } if ( node . shadowRoot ) { for ( i = 0 ; i < node . shadowRoot . childNodes . length ; i ++ ) { initializeDocumentHydrate ( node . shadowRoot . childNodes [ i ] as any , orgLocNodes ) ; } } } else if ( node . nodeType === NODE_TYPE . CommentNode ) { const childIdSplt = node . nodeValue . split ( '.' ) ; if ( childIdSplt [ 0 ] === ORG_LOCATION_ID ) { orgLocNodes . set ( childIdSplt [ 1 ] + '.' + childIdSplt [ 2 ] , node ) ; node . nodeValue = '' ; node [ 's-en' ] = childIdSplt [ 3 ] as any ; } } } ; interface RenderNodeData extends d . VNode { $hostId$ : string ; $nodeId$ : string ; $depth$ : string ; $index$ : string ; }