import { RootNode , ExpressionNode , TemplateChildNode , NodeTypes , SimpleExpressionNode , CompoundExpressionNode , InterpolationNode , TextNode } from './types' ; export interface TemplateCalls { name : string ; } export const isString = ( val ) : val is string => typeof val === 'string' ; export const isObject = ( val ) : val is object => toString . call ( val ) === '[object Object]' ; /**
 * Get the context for the current node
 */ function getContext ( exp , name , ctx ) { if ( exp . type === NodeTypes . SIMPLE_EXPRESSION ) { if ( name === 'for' ) { const [ bound , binder ] = exp . content . includes ( 'in' ) ? exp . content . split ( 'in' ) : exp . content . includes ( 'of' ) ? exp . content . split ( 'of' ) : [ '' , '' ] ; if ( ctx ) { return [ binder . trim ( ) . replace ( ctx [ 1 ] , ctx [ 0 ] ) , bound . trim ( ) , ] ; } return [ binder . trim ( ) , bound . trim ( ) ] ; } } return ctx ; } function mapCompound ( nodes ) { const data = [ '' ] ; const whitelist = [ '.' , '].' , '?.' ] ; nodes . forEach ( ( node , i ) => { if ( isObject ( node ) ) { if ( node . type === NodeTypes . SIMPLE_EXPRESSION ) { data [ data . length - 1 ] += node . content ; if ( isString ( nodes [ i + 1 ] ) ) { if ( whitelist . includes ( ( nodes [ i + 1 ] as string ) . trim ( ) ) ) data [ data . length - 1 ] += '.' ; else data . push ( '' ) ; } } } } ) ; return data . filter ( i => i ) ; } function addExpression ( exp , name , context ) { if ( exp . type === NodeTypes . COMPOUND_EXPRESSION ) { const nodes = mapCompound ( exp . children ) ; return nodes . map ( n => context ? n . replace ( context [ 1 ] , context [ 0 ] ) : n ) ; } else if ( exp . type === NodeTypes . SIMPLE_EXPRESSION ) { if ( name === 'for' ) { } else { return [ exp . content ] . map ( n => context ? n . replace ( context [ 1 ] , context [ 0 ] ) : n ) ; } } return [ ] ; } function compileChild ( child , ctx = null ) { const data = [ ] ; if ( 'props' in child ) { child . props . forEach ( ( prop ) => { if ( prop . type === NodeTypes . DIRECTIVE && prop . exp ) { ctx = getContext ( prop . exp , prop . name , ctx ) ; data . push ( ... addExpression ( prop . exp , prop . name , ctx ) ) ; } } ) ; } if ( child . type === NodeTypes . INTERPOLATION ) { ctx = getContext ( child . content , 'INTERPOLATION' , ctx ) ; data . push ( ... addExpression ( child . content , 'INTERPOLATION' , ctx ) ) ; } if ( child . type === NodeTypes . ELEMENT || child . type === NodeTypes . IF_BRANCH || child . type === NodeTypes . FOR ) child . children . forEach ( children => data . push ( ... compileChild ( children , ctx ) ) ) ; return data ; } function processChildren ( children ) { const data = [ ] ; children . forEach ( ( child ) => { data . push ( ... compileChild ( child ) ) ; } ) ; return data . filter ( x => x ) ; } export function useTemplateProps ( template ) { return processChildren ( template . children ) . map ( i => i . replace ( '_ctx.' , '' ) ) ; }