separate template-parser and html-parser

This commit is contained in:
Evan You 2016-04-13 14:55:32 -04:00
parent adb81363dd
commit 1af8c6fc11
3 changed files with 79 additions and 78 deletions

View File

@ -1,77 +1,3 @@
import { decodeHTML } from 'entities'
/**
* Convert HTML string to AST
*
* @param {String} html
* @return {Object}
*/
export function parse (html, preserveWhiteSpace) {
let root
let currentParent
let stack = []
HTMLParser(html, {
html5: true,
start (tag, attrs, unary) {
let element = {
tag,
attrs,
attrsMap: makeAttrsMap(attrs),
parent: currentParent,
children: []
}
if (!root) {
root = element
} else if (process.env.NODE_ENV !== 'production' && !stack.length) {
console.error(
'Component template should contain exactly one root element:\n\n' + html
)
}
if (currentParent) {
currentParent.children.push(element)
}
if (!unary) {
currentParent = element
stack.push(element)
}
},
end () {
stack.length -= 1
currentParent = stack[stack.length - 1]
},
chars (text) {
if (!currentParent) {
if (process.env.NODE_ENV !== 'production' && !root) {
console.error(
'Component template should contain exactly one root element:\n\n' + html
)
}
return
}
text = currentParent.tag === 'pre'
? decodeHTML(text)
: text.trim()
? decodeHTML(text)
: preserveWhiteSpace
? ' '
: null
if (text) {
currentParent.children.push(text)
}
}
})
return root
}
function makeAttrsMap (attrs) {
const map = {}
for (let i = 0, l = attrs.length; i < l; i++) {
map[attrs[i].name] = attrs[i].value
}
return map
}
/*!
* HTML Parser By John Resig (ejohn.org)
* Modified by Juriy "kangax" Zaytsev

View File

@ -1,12 +1,12 @@
import { parse } from './html-parser'
import { parse } from './template-parser'
import { generate } from './codegen/index'
const cache1 = Object.create(null)
const cache2 = Object.create(null)
export function compile (html, preserveWhiteSpace) {
export function compile (html, preserveWhitespace) {
html = html.trim()
const cache = preserveWhiteSpace ? cache1 : cache2
const cache = preserveWhitespace ? cache1 : cache2
const hit = cache[html]
return hit || (cache[html] = generate(parse(html, preserveWhiteSpace)))
return hit || (cache[html] = generate(parse(html, preserveWhitespace)))
}

View File

@ -0,0 +1,75 @@
import { decodeHTML } from 'entities'
import HTMLParser from './html-parser'
/**
* Convert HTML string to AST
*
* @param {String} template
* @param {Boolean} preserveWhitespace
* @return {Object}
*/
export function parse (template, preserveWhitespace) {
let root
let currentParent
let stack = []
HTMLParser(template, {
html5: true,
start (tag, attrs, unary) {
let element = {
tag,
attrs,
attrsMap: makeAttrsMap(attrs),
parent: currentParent,
children: []
}
if (!root) {
root = element
} else if (process.env.NODE_ENV !== 'production' && !stack.length) {
console.error(
'Component template should contain exactly one root element:\n\n' + template
)
}
if (currentParent) {
currentParent.children.push(element)
}
if (!unary) {
currentParent = element
stack.push(element)
}
},
end () {
stack.length -= 1
currentParent = stack[stack.length - 1]
},
chars (text) {
if (!currentParent) {
if (process.env.NODE_ENV !== 'production' && !root) {
console.error(
'Component template should contain exactly one root element:\n\n' + template
)
}
return
}
text = currentParent.tag === 'pre'
? decodeHTML(text)
: text.trim()
? decodeHTML(text)
: preserveWhitespace
? ' '
: null
if (text) {
currentParent.children.push(text)
}
}
})
return root
}
function makeAttrsMap (attrs) {
const map = {}
for (let i = 0, l = attrs.length; i < l; i++) {
map[attrs[i].name] = attrs[i].value
}
return map
}