const defautTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g;
function genProps(attrs) {
//属性处理 将属性的键值拼接成字符串
let str = "";
for (let i = 0; i < attrs.length; i++) {
let attr = attrs[i];
if (attr.name == "style") {
//如果属性的名称是style 那么可能会有多个键值 如 style="{color:red;background:green}"
let obj = {};
attr.value.split(";").forEach((item) => {
let [key, value] = item.split(":");
obj[key] = value;
});
attr.value = obj;
}
str += `${attr.name}:${JSON.stringify(attr.value)},`;
}
return `{${str.slice(0, -1)}}`;
}
function genChildren(el) {
const children = el.children;
console.log("children", children);
if (children) {
return children.map((child) => gen(child)).join(",");
}
}
function gen(node) {
console.log("node", node);
if (node.type == 1) {
return generate(node);//如果是元素节点,递归处理
} else {
// 文本 逻辑 不能用 _c 处理
// 有{{}}普通文本 混合文本 {{aa}} aa{{bbb}} cccss
let text = node.text;
if (defautTagRE.test(text)) {//由于索引后移动
let tokens = [];
let match;
let index = 0;
let lastIndex = (defautTagRE.lastIndex = 0);//将索引重置为0
while ((match = defautTagRE.exec(text))) {
index = match.index;
if (index > lastIndex) {
//匹配到的正则的索引
tokens.push(JSON.stringify(text.slice(lastIndex, index)));
}
tokens.push(`_s(${match[1].trim()})`);
// 索引往后移
lastIndex = index + match[0].length;
}
if (lastIndex < text.length) {
tokens.push(JSON.stringify(text.slice(lastIndex, index)));
}
return `_v(${tokens.join("+")})`;
//是带有{{}} 的
} else {
return `_v(${JSON.stringify(text)})`;
}
}
}
export function generate(el) {
console.log(el); //转换成 render代码
let children = genChildren(el);
console.log(children);
let code = `_c('${el.tag}',${
el.attrs.length ? genProps(el.attrs) : "undefined"
}${children ? "," + children : ""})`;
return code;
}
export function compileToFunctions(template) {
console.log("tmplate", template);
let ast = parseHTML(template);
// 每解析一块就删除一块
console.log("ast", ast);
let code = generate(ast);
console.log("code000", code);
let render = new Function(`with(this){return ${code}}`);
console.log(render);
return render;//render函数 已经ok
}