1
+
2
+ // ast语法树 vnode
3
+ //<div id="app">hello {{name}}</div>
4
+
5
+ /**
6
+ * {
7
+ * tag:'div',
8
+ * attrs:[{id:'app'}],
9
+ * children:[
10
+ * {tag:null,text:"hello"}
11
+ * ]
12
+ * }
13
+ *
14
+ */
15
+ // 标签名称
16
+ const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z]*`
17
+ //<span:xx>
18
+ const qnameCapture = `((?:${ ncname } \\:)?${ ncname } )`
19
+ // 标签开头正则,捕获的内容是标签名
20
+ const startTagOpen = new RegExp ( `^<${ qnameCapture } ` )
21
+ // 匹配标签结尾的</div>
22
+ const endTag = new RegExp ( `^<\\/${ qnameCapture } [^>]*>` )
23
+ //<div id="app"></div> 属性
24
+ const attribute = / ^ \s * ( [ ^ \s " ' < > \/ = ] + ) (?: \s * ( = ) \s * (?: " ( [ ^ " ] * ) " + | ' ( [ ^ ' ] * ) ' + | ( [ ^ \s " ' = < > ` ] + ) ) ) ? /
25
+ // 匹配标签结束的 >
26
+ const startTagClose = / ^ \s * ( \/ ? ) > /
27
+ var defaultTagRE = / \{ \{ ( (?: .| \n ) + ?) \} \} / g
28
+
29
+ // 开始标签
30
+ function start ( tag , attrs ) {
31
+ console . log ( tag , attrs )
32
+ }
33
+ // 获取文本
34
+ function charts ( text ) {
35
+ console . log ( text )
36
+ }
37
+ function end ( tag ) {
38
+ console . log ( tag )
39
+ }
40
+
41
+ // 遍历
42
+ function parseHTML ( html ) {
43
+ //<div id="app">hello {{name}}</div>
44
+ while ( html ) {
45
+ // 判断标签<>
46
+ let textEnd = html . indexOf ( '<' )
47
+ if ( textEnd === 0 ) {
48
+ // 开始标签
49
+ const startTagMatch = parseStartTag ( html )
50
+ if ( startTagMatch ) {
51
+
52
+ start ( startTagMatch . tagName , startTagMatch . attrs )
53
+ continue
54
+ }
55
+
56
+ // 结束标签
57
+ let endTagMatch = html . match ( endTag )
58
+ if ( endTagMatch ) {
59
+ advance ( endTagMatch [ 0 ] . length )
60
+ end ( endTagMatch [ 1 ] )
61
+ continue
62
+ }
63
+ }
64
+ // 文本
65
+ let text
66
+ if ( textEnd > 0 ) {
67
+ text = html . substring ( textEnd )
68
+ // console.log(text)
69
+ }
70
+ if ( text ) {
71
+ advance ( text . length )
72
+ charts ( text )
73
+ }
74
+ }
75
+ function parseStartTag ( ) {
76
+ // debugger
77
+ const start = html . match ( startTagOpen )
78
+ if ( start ) {
79
+
80
+ // console.log(start)
81
+ //创建ast语法树
82
+ let match = {
83
+ tagName : start [ 1 ] ,
84
+ attrs : [ ]
85
+ }
86
+ // 刪除开始标签
87
+ advance ( start [ 0 ] . length )
88
+ //属性
89
+ //注意多个遍历
90
+ //注意 >
91
+ let attr
92
+ let end
93
+ while ( ! ( end = html . match ( startTagClose ) ) && ( attr = html . match ( attribute ) ) ) {
94
+ // console.log(attr)
95
+ match . attrs . push ( { name : attr [ 1 ] , value : attr [ 3 ] || attr [ 4 ] || attr [ 5 ] } )
96
+ advance ( attr [ 0 ] . length )
97
+
98
+ }
99
+ if ( end ) {
100
+ // console.log(end)
101
+ advance ( end [ 0 ] . length )
102
+ return match
103
+ }
104
+ }
105
+
106
+ }
107
+ function advance ( n ) {
108
+ html = html . substring ( n )
109
+ // console.log(html)
110
+ }
111
+ }
112
+
113
+ export function compileToFunction ( el ) {
114
+ let ast = parseHTML ( el )
115
+ }
0 commit comments