|
|
@ -3,11 +3,11 @@ import { parseText } from './text-parser' |
|
|
|
const bindRE = /^:|^v-bind:/ |
|
|
|
const onRE = /^@|^v-on:/ |
|
|
|
const mustUsePropsRE = /^(value|selected|checked|muted)$/ |
|
|
|
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/ |
|
|
|
|
|
|
|
export function generate (ast) { |
|
|
|
const code = genElement(ast) |
|
|
|
return new Function (`with (this) { return ${code}}`) |
|
|
|
} |
|
|
|
return new Function (`with (this) { return ${code}}`)} |
|
|
|
|
|
|
|
function genElement (el, key) { |
|
|
|
let exp |
|
|
@ -18,12 +18,12 @@ function genElement (el, key) { |
|
|
|
} else if (el.tag === 'template') { |
|
|
|
return genChildren(el) |
|
|
|
} else { |
|
|
|
return `__h__('${ el.tag }', ${ genData(el, key) }, ${ genChildren(el) })` |
|
|
|
return `__h__('${el.tag}', ${genData(el, key) }, ${genChildren(el)})` |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function genIf (el, exp) { |
|
|
|
return `(${ exp }) ? ${ genElement(el) } : ''` |
|
|
|
return `(${exp}) ? ${genElement(el)} : ''` |
|
|
|
} |
|
|
|
|
|
|
|
function genFor (el, exp) { |
|
|
@ -34,7 +34,7 @@ function genFor (el, exp) { |
|
|
|
const alias = inMatch[1].trim() |
|
|
|
exp = inMatch[2].trim() |
|
|
|
const key = el.attrsMap['track-by'] || 'undefined' |
|
|
|
return `(${ exp }).map(function (${ alias }, $index) {return ${ genElement(el, key) }})` |
|
|
|
return `(${exp}).map(function (${alias}, $index) {return ${genElement(el, key) }})` |
|
|
|
} |
|
|
|
|
|
|
|
function genData (el, key) { |
|
|
@ -43,40 +43,44 @@ function genData (el, key) { |
|
|
|
} |
|
|
|
let data = '{' |
|
|
|
if (key) { |
|
|
|
data += `key:${ key },` |
|
|
|
data += `key:${key},` |
|
|
|
} |
|
|
|
if (el.attrsMap[':class']) { |
|
|
|
data += `class: ${ el.attrsMap[':class'] },` |
|
|
|
data += `class: ${el.attrsMap[':class']},` |
|
|
|
} |
|
|
|
if (el.attrsMap['class']) { |
|
|
|
data += `staticClass: "${ el.attrsMap['class'] }"` |
|
|
|
data += `staticClass: "${el.attrsMap['class']}"` |
|
|
|
} |
|
|
|
let attrs = `attrs:{` |
|
|
|
let props = `props:{` |
|
|
|
let events = `on:{` |
|
|
|
let hasAttrs = false |
|
|
|
let hasProps = false |
|
|
|
let hasEvents = false |
|
|
|
for (let i = 0, l = el.attrs.length; i < l; i++) { |
|
|
|
let attr = el.attrs[i] |
|
|
|
let name = attr.name |
|
|
|
let value = attr.value |
|
|
|
if (bindRE.test(name)) { |
|
|
|
name = name.replace(bindRE, '') |
|
|
|
if (name === 'class') { |
|
|
|
continue |
|
|
|
} else if (name === 'style') { |
|
|
|
data += `style: ${ attr.value },` |
|
|
|
data += `style: ${value},` |
|
|
|
} else if (mustUsePropsRE.test(name)) { |
|
|
|
hasProps = true |
|
|
|
props += `"${ name }": (${ attr.value }),` |
|
|
|
props += `"${name}": (${value}),` |
|
|
|
} else { |
|
|
|
hasAttrs = true |
|
|
|
attrs += `"${ name }": (${ attr.value }),` |
|
|
|
attrs += `"${name}": (${value}),` |
|
|
|
} |
|
|
|
} else if (onRE.test(name)) { |
|
|
|
hasEvents = true |
|
|
|
name = name.replace(onRE, '') |
|
|
|
// TODO
|
|
|
|
events += genEvent(name, value) |
|
|
|
} else if (name !== 'class') { |
|
|
|
hasAttrs = true |
|
|
|
attrs += `"${ name }": (${ JSON.stringify(attr.value) }),` |
|
|
|
attrs += `"${name}": (${JSON.stringify(attr.value)}),` |
|
|
|
} |
|
|
|
} |
|
|
|
if (hasAttrs) { |
|
|
@ -85,6 +89,9 @@ function genData (el, key) { |
|
|
|
if (hasProps) { |
|
|
|
data += props.slice(0, -1) + '},' |
|
|
|
} |
|
|
|
if (hasEvents) { |
|
|
|
data += events.slice(0, -1) + '},' |
|
|
|
} |
|
|
|
return data.replace(/,$/, '') + '}' |
|
|
|
} |
|
|
|
|
|
|
@ -116,6 +123,17 @@ function genText (text) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function genEvent (name, value) { |
|
|
|
// TODO support modifiers
|
|
|
|
if (!value) { |
|
|
|
return `"${name}":function(){},` |
|
|
|
} if (simplePathRE.test(value)) { |
|
|
|
return `"${name}":${value},` |
|
|
|
} else { |
|
|
|
return `"${name}":function($event){${value}},` |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function getAttr (el, attr) { |
|
|
|
let val |
|
|
|
if (val = el.attrsMap[attr]) { |
|
|
|