import { App , ComponentPublicInstance , createApp , Slot , Slots , VNode , VNodeProps } from "vue" ; import { camelize } from "./helpers" ; import { IBaseComponent } from "./component" ; import Configuration from "./configuration" ; import { IConfigurationComponent } from "./configuration-component" ; import { isFragment } from "./children-processing" ; export const VMODEL_NAME = "modelValue" ; export function getChildren ( component ) { if ( ! hasChildren ( component ) || ! component . $_config ) { return [ ] ; } const children = component . $ . subTree && component . $ . subTree . children ; if ( ! Array . isArray ( children ) ) { return [ ] ; } return children . filter ( ( child ) => { if ( ! isFragment ( child ) ) { return child as VNode ; } return ; } ) ; } export function getComponentInfo ( component ) { return getConfigurationOptions ( component ) ; } export function getComponentInstance ( component ) { return component . type && component . type . $_componentInstance ; } export function getNormalizedProps ( props ) { const result = { } ; for ( const propName in props ) { if ( props . hasOwnProperty ( propName ) ) { result [ camelize ( propName ) ] = props [ propName ] ; } } return result ; } export function configurationChildren ( component ) { if ( ! component . children || ! component . children . default ) { return [ ] ; } return findConfigurationComponents ( component . children . default ( ) ) ; } export function configurationDefaultTemplate ( node ) { if ( ! node . children || node . children === "object" || ! node . children . default ) { return ; } return hasInlineTemplate ( node . children . default ( ) ) ? node . children . default : undefined ; } export function configurationTemplate ( node ) { return configurationDefaultTemplate ( node ) ; } export function declaredTemplates ( component ) { return component . $slots ; } export function defaultSlots ( component ) { const templates = declaredTemplates ( component ) ; if ( ! templates . default ) { return [ ] ; } return templates . default ( ) ; } export function mount ( options , parent , el ) { const template = createApp ( options ) ; template . provide ( "eventBus" , parent . eventBus ) ; setAppContext ( template , parent ) ; return template . mount ( el ) ; } export function getComponentProps ( component ) { const props = component . $ . vnode . props || { } ; return getNormalizedProps ( props ) ; } export function usedConfigurationProps ( node ) { return node . props ; } export function saveComponentInstance ( component ) { const nodeOptions = getNodeTypeOfComponent ( component ) ; if ( nodeOptions ) { nodeOptions . $_componentInstance = component ; } } export function getNodeOptions ( component ) { if ( component . $ ) { return component . $ . vnode ; } return component ; } export function getNodeTypeOfComponent ( component ) { return component . $ . vnode . type ; } export function getVModelValue ( options ) { return options [ VMODEL_NAME ] ; } export function setVModel ( config ) { const eventName = `update:${ VMODEL_NAME }` ; config . model . prop = VMODEL_NAME ; config . model . event = eventName ; config . props . modelValue = { } ; config . emits = { ... config . emits , [ `${ eventName }` ] : null } ; } interface ChildConfiguration extends VNode { $_config ? : Configuration ; $_innerChanges ? : Record < string , any > ; } function setCustomPluginsData ( appContext , parentAppContext ) { for ( const prop in parentAppContext ) { if ( ! appContext . hasOwnProperty ( prop ) && parentAppContext . hasOwnProperty ( prop ) ) { appContext [ prop ] = parentAppContext [ prop ] ; } } } function setAppContext ( template , parent ) { template . _context . components = Object . assign ( parent . $ . appContext . components , template . _context . components ) ; Object . setPrototypeOf ( template . _context . provides , Object . getPrototypeOf ( parent . $ . provides ) ) ; Object . assign ( template . _context . provides , parent . $ . appContext . provides ) ; template . _context . config = parent . $ . appContext . config ; template . _context . directives = parent . $ . appContext . directives ; template . _context . mixins = parent . $ . appContext . mixins ; setCustomPluginsData ( template . _context . app , parent . $ . appContext . app ) ; } function findConfigurationComponents ( children ) { return children . filter ( ( child ) => { if ( isFragment ( child ) ) { return findConfigurationComponents ( ( child as any ) . children || [ ] ) ; } const childType = child . type as IConfigurationComponent ; if ( childType && typeof childType === "object" && childType . $_optionName ) { delete ( child as ChildConfiguration ) . $_config ; delete ( child as ChildConfiguration ) . $_innerChanges ; return child ; } return ; } ) ; } function hasInlineTemplate ( children ) { let hasTemplate = false ; children . forEach ( ( child ) => { if ( ! isConfiguration ( child ) && ! isFragment ( child ) && ! isComment ( child . type ) ) { hasTemplate = true ; } } ) ; return hasTemplate ; } function isComment ( nodeType ) { const type = typeof nodeType === "symbol" ? nodeType . toString ( ) : nodeType ; return type === "Symbol(Comment)" ; } function isConfiguration ( child ) { return child . type && typeof child . type === "object" && ( child . type as any ) . $_optionName ; } export function getConfigurationOptions ( node ) { return node . type ; } function hasChildren ( component ) { return component . $ . vnode && component . $ . vnode . children && ( component . $ . vnode . children as any ) . default ; }