import { NodeTypes } from './parse'; import { isArray } from '@sugar/sugar-shared'; import { toAst } from './toAst'; import { transform } from './transform'; import { sIf } from './transform/sIf'; let key = 0; export function generate(ast: any) { const genElmChildren = (children = []) => { let str = '['; children.forEach((child: any, i) => { if ( child.type === NodeTypes.ELEMENT || child.type === NodeTypes.INTERPOLATION || child.type === NodeTypes.SLOT ) { str += getElm(child) + `${i === children.length - 1 ? '' : ','}`; } else if (child.type === NodeTypes.TEXT && !!child.content.trim()) { str += getElm(child) + `${i === children.length - 1 ? '' : ','}`; } }); return str + ']'; }; function getElm(ast: any) { let str = ''; const props = ast.props; if (ast.type === 1 || ast.type === NodeTypes.SLOT) { let elStr = ''; let ex = false; elStr += `_ctx_._SUGAR._c('${ast.tag}',{ `; elStr += '"attrs":{'; elStr += dealAttr(props); elStr += '},"on":{'; elStr += dealEvent(props); elStr += '}},'; if (ast.children) { elStr += genElmChildren(ast.children); } else { elStr += '[]'; } elStr += ')'; if (ast.forStatment) { ex = true; str += transformFor(ast); } if (ast.if && !ast.forStatment) { ex = true; str = `${ast.if.value} ? ${str + elStr} : _ctx_._SUGAR._e()`; } if (ast.loading && !ast.forStatment) { ex = true; const loadingRender = generate( transform( toAst(`
`), { sIf, }, ), ); str = `_ctx_._SUGAR._c('div',{attrs:{style:'position:relative'},on:{}},[${ str + (!ast.if ? elStr : '') },${loadingRender}])`; } if (ast.htmlStatment) { ex = true; str = `_ctx_._SUGAR._c('div',{attrs:{${dealAttr(props)}},on:{${dealEvent(props)}}},[_ctx_._SUGAR._html(${ast.htmlStatment.value.content})])`; } if (!ex) { str += elStr; } } else if (ast.type === NodeTypes.INTERPOLATION) { str += `_ctx_._SUGAR._v(_ctx_._SUGAR._s(${ast.content.content}))`; } else if (ast.type === NodeTypes.TEXT) { str += `_ctx_._SUGAR._v(decodeURIComponent("${encodeURIComponent(ast.content)}"))`; } return str; } return getElm(ast); function createElementString(tag: any, props: any, children: any) { let element = `_ctx_._SUGAR._c('${tag}',{`; element += '"attrs":{'; element += dealAttr(props); element += '},"on":{'; element += dealEvent(props); element += '}},['; children.forEach((child: any, index: any) => { element += generate(child); if (index < children.length - 1) { element += ','; } }); element += '])'; // Handle s-if and s-loading directives props.forEach((prop: any) => { if (prop.name === 's-if') { element = `${prop.value.content} ? ${element} : _ctx_._SUGAR._e()`; } if (prop.name === 's-loading' && prop.value) { const loadingRender = generate( transform( toAst(`
`), { sIf }, ), ); element = `_ctx_._SUGAR._c('div',{attrs:{style:'position:relative'},on:{}},[${element},${loadingRender}])`; } }); return element; } function transformFor(ast: any) { const forStatment = ast.forStatment; const elementStr = createElementString(ast.tag, ast.props, ast.children); return `..._ctx_._SUGAR._loop((${forStatment.item}${ forStatment.index ? ',' + forStatment.index : '' })=>{ return ${elementStr} },${forStatment.exp})`; } } function dealAttr(props: any) { let str = ''; props = props.filter((prop: any) => { return ( prop.name !== 's-if' && prop.name !== 's-for' && prop.name !== 'on' && prop.name !== 's-loading' && prop.name !== 's-html' ); }); props.forEach((prop: any, index: number) => { if ( prop.name !== 's-if' && prop.name !== 's-for' && prop.name !== 'on' && prop.name !== 'bind' && prop.name !== 'slot' && prop.name !== 's-html' ) { str += `"${prop.name}":"${prop.value.content}"`; } else if (prop.name === 'bind') { str += `"${prop.arg.content}":${prop.exp.content}`; } else if (prop.name === 'slot') { str += `"slot":"${prop.arg.content}"`; } if ( prop.name !== 's-if' && prop.name !== 's-for' && prop.name !== 'on' && index < props.length - 1 ) { str += ','; } }); return str; } function dealEvent(props: any) { let str = ''; props = props.filter((prop: any) => { return prop.name === 'on'; }); props.forEach((prop: any, index: number) => { if (prop.name === 'on') { let funString = `${prop.exp.content}`; if (prop.exp.isStatic) { funString = `(e)=>{${prop.exp.content}}`; } str += `"${prop.arg.content}":{"value":${funString},"isStatic":${prop.exp.isStatic},"modifiers":[${Array2String(prop.modifiers)}]}`; if (prop.name === 'on' && index < props.length - 1) { str += ','; } } }); return str; } function Array2String(arr: any) { if (!isArray(arr)) { return ''; } return arr.map((a: any) => { return `"${a}"`; }); }