import { ComponentInternalInstance , Slots } from 'vue' ; import { Props , PushFn , renderVNodeChildren , SSRBufferItem } from '../render' ; import { isArray } from '@vue/shared' ; export type SSRSlots = Record < string , SSRSlot > ; export type SSRSlot = ( props : Props , push : PushFn , parentComponent : ComponentInternalInstance | null , scopeId : string | null ) => void ; export function ssrRenderSlot ( slots , slotName , slotProps , fallbackRenderFn , push , parentComponent , slotScopeId ? ) { push ( `<!--[-->` ) ; const slotFn = slots [ slotName ] ; if ( slotFn ) { const slotBuffer = [ ] ; const bufferedPush = ( item ) => { slotBuffer . push ( item ) ; } ; const ret = slotFn ( slotProps , bufferedPush , parentComponent , slotScopeId ? ' ' + slotScopeId : '' ) ; if ( isArray ( ret ) ) { renderVNodeChildren ( push , ret , parentComponent , slotScopeId ) ; } else { let isEmptySlot = true ; for ( let i = 0 ; i < slotBuffer . length ; i ++ ) { if ( ! isComment ( slotBuffer [ i ] ) ) { isEmptySlot = false ; break ; } } if ( isEmptySlot ) { if ( fallbackRenderFn ) { fallbackRenderFn ( ) ; } } else { for ( let i = 0 ; i < slotBuffer . length ; i ++ ) { push ( slotBuffer [ i ] ) ; } } } } else if ( fallbackRenderFn ) { fallbackRenderFn ( ) ; } push ( `<!--]-->` ) ; } const commentRE = /^<!--.*-->$/ ; function isComment ( item ) { return typeof item === 'string' && commentRE . test ( item ) ; }