02 生成语法树
xwjie opened this issue · 1 comments
xwjie commented
采用了 jQuery 作者 John Resig 的 HTML Parser ,(VUE也是用了这个),然后生成语法树,非常少的代码,语法树的结构参考了VUE的,目前只用了几个字段,不够后面再加。
生成语法树就是生成一颗树,比较麻烦的是父节点的处理,这里用一个栈来存放(就是一个数组,采用push和pop方法),代码非常简单,自己写的话10行左右就生成了语法树。
type1 表示dom节点,2表示表达式(未实现)3表示文本/注释,
/* @flow */
import { log } from '../util'
import { HTMLParser, HTMLtoXML, HTMLtoDOM } from './htmlparser'
//D:\OutPut\VUE\vue\src\compiler\parser\index.js
function html2ast(templte: string, data: Object): ?ASTElement {
let root: ?ASTElement;
let parent: ASTElement;
let parentStack = [];
HTMLParser(templte, {
start: function (tag, attrs, unary) {
//
if (false === unary && parent) {
parentStack.push(parent);
}
let e = createASTElement(tag, attrs, parent);
if (!root) {
root = e;
}
if(false === unary){
parent = e;
}
},
end: function (tag) {
parent = parentStack.pop();
},
chars: function (text) {
createTextlement(text, parent);
},
comment: function (text) {
createCommentlement(text, parent);
}
});
log('htmlparser ast', root);
log('htmlparser parentStack', parentStack);
return root;
}
function createASTElement(
tag: string,
attrs: Array<Attr>,
parent: ?ASTElement
): ASTElement {
let e = {
type: 1,
tag,
//attrsList: attrs,
attrsMap: makeAttrsMap(attrs),
//parent,
children: []
}
if (parent) {
parent.children.push(e);
}
return e;
}
function createTextlement(
text: string,
parent: ASTElement
): ASTText {
let e = {
type: 3,
text,
//parent
}
parent.children.push(e);
return e;
}
function createCommentlement(
text: string,
parent: ASTElement
): ASTText {
let e = {
type: 3,
text,
isComment: true,
//parent
}
parent.children.push(e);
return e;
}
function makeAttrsMap(attrs: Array<Object>): Object {
const map = {}
for (let i = 0, l = attrs.length; i < l; i++) {
map[attrs[i].name] = attrs[i].value
}
return map
}
export { html2ast }
fhyoga commented