import * as Vue from 'vue' ; import { CreateVNodeHelper , VNodeHelper , VNodeThunk , VNodeData , VNodeChildren , VNodeChild , ScopedSlot } from './declarations' ; import { kebabToCamel , isThunk , isScopedSlot , isSelector , isObject } from './utils' ; export const createHelper = tagName => { return ( a ? , b ? , c ? ) => { const { selector , data , children } = extractArguments ( a , b , c ) ; if ( selector ) { insertSelectorToData ( data , selector ) ; } const thunk = ( h ) => h ( tagName , data , applyChildren ( h , children ) ) ; thunk . _thunk = true ; return thunk ; } ; } ; export function createHelpers ( names ) { const helpers = { } ; names . forEach ( name => { helpers [ kebabToCamel ( name ) ] = createHelper ( name ) ; } ) ; return helpers ; } export function tag ( head ) ; export function tag ( head , children ) ; export function tag ( head , data , children ? ) ; export function tag ( head , selector , children ) ; export function tag ( head , selector , data ? , children ? ) ; export function tag ( head , a ? , b ? , c ? ) { return createHelper ( head ) ( a , b , c ) ; } export function apply ( h , node ) { return isThunk ( node ) ? node ( h ) : node ; } function applyChildren ( h , children ) { if ( Array . isArray ( children ) ) { const cs = children ; if ( isScopedSlot ( cs ) ) { return [ ( props ) => applyChildren ( h , cs [ 0 ] ( props ) ) as Vue . VNodeChildrenArrayContents ] ; } return cs . map ( c => { if ( Array . isArray ( c ) ) { return applyChildren ( h , c ) ! ; } return apply ( h , c ) ; } ) ; } return children ; } /**
 * It is not care about null or undefined value
 *
 *    selector -> data -> children
 * or selector -> data
 * or selector -> children
 * or data     -> children
 * or selector
 * or data
 * or children
 */ export function extractArguments ( a ? , b ? , c ? ) { if ( ! isSelector ( a ) ) { c = b ; b = a ; a = null ; } if ( ! isObject ( b ) ) { c = b ; b = null ; } return { selector : a , data : b || { } , children : c } ; } function insertSelectorToData ( data , selector ) { const { id , staticClass } = parseSelector ( selector ) ; if ( staticClass ) { data . staticClass = staticClass ; } if ( id ) { if ( ! isObject ( data . attrs ) ) { data . attrs = { } ; } data . attrs [ 'id' ] = id ; } } export function parseSelector ( selector ) { const selectorRegexp = /([\.#][^\s.#]+)/ ; const items = selector . split ( selectorRegexp ) ; const ids = [ ] ; const staticClasses = [ ] ; items . forEach ( item => { if ( item [ 0 ] === '.' ) { staticClasses . push ( item . slice ( 1 ) ) ; } else if ( item [ 0 ] === '#' ) { ids . push ( item . slice ( 1 ) ) ; } } ) ; return { id : ids [ 0 ] || null , staticClass : staticClasses . join ( ' ' ) || null } ; }