@markuplint/vue-parser 3.6.1 → 3.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +5 -5
  2. package/test/index.spec.js +455 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/vue-parser",
3
- "version": "3.6.1",
3
+ "version": "3.6.2",
4
4
  "description": "Vue parser for markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
@@ -16,11 +16,11 @@
16
16
  "clean": "tsc --build --clean"
17
17
  },
18
18
  "dependencies": {
19
- "@markuplint/html-parser": "3.6.1",
19
+ "@markuplint/html-parser": "3.7.0",
20
20
  "@markuplint/ml-ast": "3.1.0",
21
- "@markuplint/parser-utils": "3.6.1",
21
+ "@markuplint/parser-utils": "3.7.0",
22
22
  "tslib": "^2.4.1",
23
- "vue-eslint-parser": "^9.1.0"
23
+ "vue-eslint-parser": "^9.1.1"
24
24
  },
25
- "gitHead": "3cdf5a088b2da03773d5d4461d0e65ec32290a00"
25
+ "gitHead": "adc6e432cccba7cfad0dc8bf9f92e5aaf1107359"
26
26
  }
@@ -0,0 +1,455 @@
1
+ const { nodeListToDebugMaps } = require('@markuplint/parser-utils');
2
+
3
+ const { parse } = require('../lib/');
4
+
5
+ describe('parser', () => {
6
+ it('empty', () => {
7
+ const doc = parse('');
8
+ expect(doc.nodeList).toStrictEqual([]);
9
+ expect(doc.nodeList.length).toBe(0);
10
+ });
11
+
12
+ it('syntax error', () => {
13
+ expect(() => {
14
+ parse('"');
15
+ }).toThrow('Unterminated string constant');
16
+ });
17
+
18
+ it('silent syntax error', () => {
19
+ const doc = parse('<!--');
20
+ expect(doc.nodeList).toStrictEqual([]);
21
+ expect(doc.nodeList.length).toBe(0);
22
+ });
23
+
24
+ it('template empty', () => {
25
+ const doc = parse('<template></template>');
26
+ expect(doc.nodeList).toStrictEqual([]);
27
+ expect(doc.nodeList.length).toBe(0);
28
+ });
29
+
30
+ it('<div />', () => {
31
+ const doc = parse('<template><div /></template>');
32
+ expect(doc.nodeList[0].nodeName).toBe('div');
33
+ expect(doc.nodeList.length).toBe(1);
34
+ });
35
+
36
+ it('<div></div>', () => {
37
+ const doc = parse('<template><div></div></template>');
38
+ expect(doc.nodeList[0].nodeName).toBe('div');
39
+ expect(doc.nodeList[1].nodeName).toBe('div');
40
+ expect(doc.nodeList.length).toBe(2);
41
+ });
42
+
43
+ it('text only', () => {
44
+ const doc = parse('<template>text</template>');
45
+ expect(doc.nodeList[0].nodeName).toBe('#text');
46
+ expect(doc.nodeList[0].raw).toBe('text');
47
+ expect(doc.nodeList.length).toBe(1);
48
+ });
49
+
50
+ it('fragments', () => {
51
+ const doc = parse('<template><header></header><main></main><footer></footer></template>');
52
+ expect(doc.nodeList[0].nodeName).toBe('header');
53
+ expect(doc.nodeList[1].nodeName).toBe('header');
54
+ expect(doc.nodeList[2].nodeName).toBe('main');
55
+ expect(doc.nodeList[3].nodeName).toBe('main');
56
+ expect(doc.nodeList[4].nodeName).toBe('footer');
57
+ expect(doc.nodeList[5].nodeName).toBe('footer');
58
+ expect(doc.nodeList.length).toBe(6);
59
+ });
60
+
61
+ it('standard code', () => {
62
+ const doc = parse(`
63
+ <template>
64
+ <script>
65
+ const i = 0;
66
+ </script>
67
+ <!comment-node>
68
+ {{ CodeExpression }}
69
+ <div>
70
+ text&amp;div
71
+ </div>
72
+ <table>
73
+ <tr>
74
+ <th>header</th>
75
+ <td>cell</td>
76
+ </tr>
77
+ </table>
78
+ <table>
79
+ <tbody>
80
+ <tr>
81
+ <th>header</th>
82
+ <td>cell</td>
83
+ </tr>
84
+ </tbody>
85
+ </table>
86
+ <img src="path/to" />
87
+ invalid-indent
88
+
89
+ <?template engine;
90
+ $var = '<html attr="value">text</html>'
91
+ ?>
92
+
93
+ <%template engine;
94
+ $var = '<html attr="value">text</html>'
95
+ %>
96
+
97
+ </expected>
98
+ <div>
99
+ text-node
100
+ </template>
101
+ `);
102
+ const map = nodeListToDebugMaps(doc.nodeList);
103
+ expect(map).toStrictEqual([
104
+ '[2:12]>[3:3](12,15)#text: ⏎→→',
105
+ '[3:3]>[3:11](15,23)script: <script>',
106
+ '[3:11]>[5:3](23,42)#text: ⏎→→→const␣i␣=␣0;⏎→→',
107
+ '[5:3]>[5:12](42,51)script: </script>',
108
+ '[5:12]>[7:3](51,72)#text: ⏎→→⏎→→',
109
+ '[7:3]>[7:23](72,92)#vue-expression-container: {{␣CodeExpression␣}}',
110
+ '[7:23]>[8:3](92,95)#text: ⏎→→',
111
+ '[8:3]>[8:8](95,100)div: <div>',
112
+ '[8:8]>[10:3](100,119)#text: ⏎→→→text&amp;div⏎→→',
113
+ '[10:3]>[10:9](119,125)div: </div>',
114
+ '[10:9]>[11:3](125,128)#text: ⏎→→',
115
+ '[11:3]>[11:10](128,135)table: <table>',
116
+ '[11:10]>[12:4](135,139)#text: ⏎→→→',
117
+ '[12:4]>[12:8](139,143)tr: <tr>',
118
+ '[12:8]>[13:5](143,148)#text: ⏎→→→→',
119
+ '[13:5]>[13:9](148,152)th: <th>',
120
+ '[13:9]>[13:15](152,158)#text: header',
121
+ '[13:15]>[13:20](158,163)th: </th>',
122
+ '[13:20]>[14:5](163,168)#text: ⏎→→→→',
123
+ '[14:5]>[14:9](168,172)td: <td>',
124
+ '[14:9]>[14:13](172,176)#text: cell',
125
+ '[14:13]>[14:18](176,181)td: </td>',
126
+ '[14:18]>[15:4](181,185)#text: ⏎→→→',
127
+ '[15:4]>[15:9](185,190)tr: </tr>',
128
+ '[15:9]>[16:3](190,193)#text: ⏎→→',
129
+ '[16:3]>[16:11](193,201)table: </table>',
130
+ '[16:11]>[17:3](201,204)#text: ⏎→→',
131
+ '[17:3]>[17:10](204,211)table: <table>',
132
+ '[17:10]>[18:4](211,215)#text: ⏎→→→',
133
+ '[18:4]>[18:11](215,222)tbody: <tbody>',
134
+ '[18:11]>[19:5](222,227)#text: ⏎→→→→',
135
+ '[19:5]>[19:9](227,231)tr: <tr>',
136
+ '[19:9]>[20:6](231,237)#text: ⏎→→→→→',
137
+ '[20:6]>[20:10](237,241)th: <th>',
138
+ '[20:10]>[20:16](241,247)#text: header',
139
+ '[20:16]>[20:21](247,252)th: </th>',
140
+ '[20:21]>[21:6](252,258)#text: ⏎→→→→→',
141
+ '[21:6]>[21:10](258,262)td: <td>',
142
+ '[21:10]>[21:14](262,266)#text: cell',
143
+ '[21:14]>[21:19](266,271)td: </td>',
144
+ '[21:19]>[22:5](271,276)#text: ⏎→→→→',
145
+ '[22:5]>[22:10](276,281)tr: </tr>',
146
+ '[22:10]>[23:4](281,285)#text: ⏎→→→',
147
+ '[23:4]>[23:12](285,293)tbody: </tbody>',
148
+ '[23:12]>[24:3](293,296)#text: ⏎→→',
149
+ '[24:3]>[24:11](296,304)table: </table>',
150
+ '[24:11]>[25:3](304,307)#text: ⏎→→',
151
+ '[25:3]>[25:24](307,328)img: <img␣src="path/to"␣/>',
152
+ "[25:24]>[33:12](328,451)#text: ⏎→→→→invalid-indent⏎⏎→→text'⏎→→?>⏎⏎→→<%template␣engine;⏎→→→$var␣=␣'",
153
+ '[33:12]>[33:31](451,470)html: <html␣attr="value">',
154
+ '[33:31]>[33:35](470,474)#text: text',
155
+ '[33:35]>[33:42](474,481)html: </html>',
156
+ "[33:42]>[37:3](481,505)#text: '⏎→→%>⏎⏎→→⏎→→",
157
+ '[37:3]>[37:8](505,510)div: <div>',
158
+ '[37:8]>[39:2](510,523)#text: ⏎→text-node⏎→',
159
+ ]);
160
+ });
161
+
162
+ it('<template>', () => {
163
+ const doc = parse(`
164
+ <template>
165
+ <script>
166
+ const i = 0;
167
+ </script>
168
+ <!comment-node>
169
+ <!-- html-comment -->
170
+ <div>
171
+ text&amp;div
172
+ </div>
173
+ <table>
174
+ <tr>
175
+ <th>header</th>
176
+ <td>cell</td>
177
+ </tr>
178
+ </table>
179
+ <table>
180
+ <tbody>
181
+ <tr>
182
+ <th>header</th>
183
+ <td>cell</td>
184
+ </tr>
185
+ </tbody>
186
+ </table>
187
+ <img src="path/to" />
188
+ invalid-indent
189
+
190
+ <?template engine;
191
+ $var = '<html attr="value">text</html>'
192
+ ?>
193
+
194
+ <%template engine;
195
+ $var = '<html attr="value">text</html>'
196
+ %>
197
+
198
+ </expected>
199
+ <div>
200
+ text-node
201
+ </template>
202
+ `);
203
+ const map = nodeListToDebugMaps(doc.nodeList);
204
+ expect(map).toStrictEqual([
205
+ '[2:12]>[3:3](12,15)#text: ⏎→→',
206
+ '[3:3]>[3:11](15,23)script: <script>',
207
+ '[3:11]>[5:3](23,42)#text: ⏎→→→const␣i␣=␣0;⏎→→',
208
+ '[5:3]>[5:12](42,51)script: </script>',
209
+ '[5:12]>[8:3](51,96)#text: ⏎→→⏎→→⏎→→',
210
+ '[8:3]>[8:8](96,101)div: <div>',
211
+ '[8:8]>[10:3](101,120)#text: ⏎→→→text&amp;div⏎→→',
212
+ '[10:3]>[10:9](120,126)div: </div>',
213
+ '[10:9]>[11:3](126,129)#text: ⏎→→',
214
+ '[11:3]>[11:10](129,136)table: <table>',
215
+ '[11:10]>[12:4](136,140)#text: ⏎→→→',
216
+ '[12:4]>[12:8](140,144)tr: <tr>',
217
+ '[12:8]>[13:5](144,149)#text: ⏎→→→→',
218
+ '[13:5]>[13:9](149,153)th: <th>',
219
+ '[13:9]>[13:15](153,159)#text: header',
220
+ '[13:15]>[13:20](159,164)th: </th>',
221
+ '[13:20]>[14:5](164,169)#text: ⏎→→→→',
222
+ '[14:5]>[14:9](169,173)td: <td>',
223
+ '[14:9]>[14:13](173,177)#text: cell',
224
+ '[14:13]>[14:18](177,182)td: </td>',
225
+ '[14:18]>[15:4](182,186)#text: ⏎→→→',
226
+ '[15:4]>[15:9](186,191)tr: </tr>',
227
+ '[15:9]>[16:3](191,194)#text: ⏎→→',
228
+ '[16:3]>[16:11](194,202)table: </table>',
229
+ '[16:11]>[17:3](202,205)#text: ⏎→→',
230
+ '[17:3]>[17:10](205,212)table: <table>',
231
+ '[17:10]>[18:4](212,216)#text: ⏎→→→',
232
+ '[18:4]>[18:11](216,223)tbody: <tbody>',
233
+ '[18:11]>[19:5](223,228)#text: ⏎→→→→',
234
+ '[19:5]>[19:9](228,232)tr: <tr>',
235
+ '[19:9]>[20:6](232,238)#text: ⏎→→→→→',
236
+ '[20:6]>[20:10](238,242)th: <th>',
237
+ '[20:10]>[20:16](242,248)#text: header',
238
+ '[20:16]>[20:21](248,253)th: </th>',
239
+ '[20:21]>[21:6](253,259)#text: ⏎→→→→→',
240
+ '[21:6]>[21:10](259,263)td: <td>',
241
+ '[21:10]>[21:14](263,267)#text: cell',
242
+ '[21:14]>[21:19](267,272)td: </td>',
243
+ '[21:19]>[22:5](272,277)#text: ⏎→→→→',
244
+ '[22:5]>[22:10](277,282)tr: </tr>',
245
+ '[22:10]>[23:4](282,286)#text: ⏎→→→',
246
+ '[23:4]>[23:12](286,294)tbody: </tbody>',
247
+ '[23:12]>[24:3](294,297)#text: ⏎→→',
248
+ '[24:3]>[24:11](297,305)table: </table>',
249
+ '[24:11]>[25:3](305,308)#text: ⏎→→',
250
+ '[25:3]>[25:24](308,329)img: <img␣src="path/to"␣/>',
251
+ "[25:24]>[33:12](329,452)#text: ⏎→→→→invalid-indent⏎⏎→→text'⏎→→?>⏎⏎→→<%template␣engine;⏎→→→$var␣=␣'",
252
+ '[33:12]>[33:31](452,471)html: <html␣attr="value">',
253
+ '[33:31]>[33:35](471,475)#text: text',
254
+ '[33:35]>[33:42](475,482)html: </html>',
255
+ "[33:42]>[37:3](482,506)#text: '⏎→→%>⏎⏎→→⏎→→",
256
+ '[37:3]>[37:8](506,511)div: <div>',
257
+ '[37:8]>[39:2](511,524)#text: ⏎→text-node⏎→',
258
+ ]);
259
+ });
260
+
261
+ it('<noscript>', () => {
262
+ const doc = parse(`
263
+ <template>
264
+ <noscript>
265
+ <div>test</div>
266
+ <expected>
267
+ </expected2>
268
+ </noscript>
269
+ </template>
270
+ `);
271
+ const map = nodeListToDebugMaps(doc.nodeList);
272
+ expect(map).toStrictEqual([
273
+ '[2:12]>[3:2](12,14)#text: ⏎→',
274
+ '[3:2]>[3:12](14,24)noscript: <noscript>',
275
+ '[3:12]>[7:2](24,72)#text: ⏎→→<div>test</div>⏎→→<expected>⏎→→</expected2>⏎→',
276
+ '[7:2]>[7:13](72,83)noscript: </noscript>',
277
+ '[7:13]>[8:2](83,85)#text: ⏎→',
278
+ ]);
279
+ });
280
+
281
+ it('UUID', () => {
282
+ const doc = parse(
283
+ '<template><x-wrap><x-before><span>title</span></x-before><x-after><div>test</div></x-after></x-wrap></template>',
284
+ );
285
+ // const map = nodeListToDebugMaps(doc.nodeList);
286
+ // console.log(map);
287
+ // console.log(doc.nodeList.map((n, i) => `${i}: ${n.uuid} ${n.raw.trim()}`));
288
+
289
+ // <x-wrap>
290
+ expect(doc.nodeList[0].parentNode).toEqual(null);
291
+ expect(doc.nodeList[0].prevNode).toEqual(null);
292
+ expect(doc.nodeList[0].nextNode).toEqual(null);
293
+ // @ts-ignore
294
+ expect(doc.nodeList[0].pearNode.uuid).toEqual(doc.nodeList[11].uuid);
295
+
296
+ // </x-wrap>
297
+ expect(doc.nodeList[11].parentNode).toEqual(null);
298
+ // @ts-ignore
299
+ expect(doc.nodeList[11].pearNode.uuid).toEqual(doc.nodeList[0].uuid);
300
+
301
+ // <x-before>
302
+ // @ts-ignore
303
+ expect(doc.nodeList[1].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
304
+ // @ts-ignore
305
+ expect(doc.nodeList[1].prevNode).toEqual(null);
306
+ // @ts-ignore
307
+ expect(doc.nodeList[1].nextNode.uuid).toEqual(doc.nodeList[6].uuid);
308
+ // @ts-ignore
309
+ expect(doc.nodeList[1].pearNode.uuid).toEqual(doc.nodeList[5].uuid);
310
+
311
+ // </x-before>
312
+ // @ts-ignore
313
+ expect(doc.nodeList[5].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
314
+ // @ts-ignore
315
+ expect(doc.nodeList[5].pearNode.uuid).toEqual(doc.nodeList[1].uuid);
316
+
317
+ // <x-after>
318
+ // @ts-ignore
319
+ expect(doc.nodeList[6].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
320
+ // @ts-ignore
321
+ expect(doc.nodeList[6].prevNode.uuid).toEqual(doc.nodeList[1].uuid);
322
+ // @ts-ignore
323
+ expect(doc.nodeList[6].nextNode).toEqual(null);
324
+ // @ts-ignore
325
+ expect(doc.nodeList[6].pearNode.uuid).toEqual(doc.nodeList[10].uuid);
326
+
327
+ // </x-after>
328
+ // @ts-ignore
329
+ expect(doc.nodeList[10].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
330
+ // @ts-ignore
331
+ expect(doc.nodeList[10].pearNode.uuid).toEqual(doc.nodeList[6].uuid);
332
+ });
333
+
334
+ it('attributes', () => {
335
+ const doc = parse(
336
+ '<template><div v-if="bool" data-attr v-bind:data-attr2="variable" @click.once="event" v-on:click.foobar="event"></div></template>',
337
+ );
338
+ // @ts-ignore
339
+ expect(doc.nodeList[0].attributes[0].raw).toBe('v-if="bool"');
340
+ // @ts-ignore
341
+ expect(doc.nodeList[0].attributes[0].isDirective).toBeTruthy();
342
+ // @ts-ignore
343
+ expect(doc.nodeList[0].attributes[1].raw).toBe('data-attr');
344
+ // @ts-ignore
345
+ expect(doc.nodeList[0].attributes[1].isDirective).toBeUndefined();
346
+ // @ts-ignore
347
+ expect(doc.nodeList[0].attributes[2].raw).toBe('v-bind:data-attr2="variable"');
348
+ // @ts-ignore
349
+ expect(doc.nodeList[0].attributes[2].potentialName).toBe('data-attr2');
350
+ // @ts-ignore
351
+ expect(doc.nodeList[0].attributes[3].isDirective).toBeFalsy();
352
+ // @ts-ignore
353
+ expect(doc.nodeList[0].attributes[4].isDirective).toBeFalsy();
354
+ });
355
+
356
+ it('namespace', () => {
357
+ const doc = parse('<template><div><svg><text /></svg></div></template>');
358
+ expect(doc.nodeList[0].nodeName).toBe('div');
359
+ expect(doc.nodeList[0].namespace).toBe('http://www.w3.org/1999/xhtml');
360
+ expect(doc.nodeList[1].nodeName).toBe('svg');
361
+ expect(doc.nodeList[1].namespace).toBe('http://www.w3.org/2000/svg');
362
+ expect(doc.nodeList[2].nodeName).toBe('text');
363
+ expect(doc.nodeList[2].namespace).toBe('http://www.w3.org/2000/svg');
364
+ });
365
+
366
+ it('elementType', () => {
367
+ expect(parse('<template><div/></template>').nodeList[0].elementType).toBe('html');
368
+ expect(parse('<template><Div/></template>').nodeList[0].elementType).toBe('authored');
369
+ expect(parse('<template><x-div/></template>').nodeList[0].elementType).toBe('web-component');
370
+ expect(parse('<template><foo/></template>').nodeList[0].elementType).toBe('html');
371
+ expect(parse('<template><Foo/></template>').nodeList[0].elementType).toBe('authored');
372
+ expect(parse('<template><div><Foo/></div></template>').nodeList[1].elementType).toBe('authored');
373
+ expect(parse('<template><div><Component/></div></template>').nodeList[1].elementType).toBe('authored');
374
+ expect(parse('<template><svg><Component/></svg></template>').nodeList[1].elementType).toBe('authored');
375
+ expect(parse('<template><svg><feBlend/></svg></template>').nodeList[1].elementType).toBe('html');
376
+ expect(parse('<template><component/></template>').nodeList[0].elementType).toBe('authored');
377
+ expect(parse('<template><slot/></template>').nodeList[0].elementType).toBe('authored');
378
+ expect(parse('<template><Transition/></template>').nodeList[0].elementType).toBe('authored');
379
+ expect(parse('<template><transition/></template>').nodeList[0].elementType).toBe('html');
380
+ });
381
+
382
+ it('Directives', () => {
383
+ const doc = parse(`
384
+ <template>
385
+ <div>
386
+ <template #header></template>
387
+ </div>
388
+ </template>
389
+ `);
390
+ const map = nodeListToDebugMaps(doc.nodeList, true);
391
+ expect(map).toStrictEqual([
392
+ '[2:12]>[3:3](12,15)#text: ⏎→→',
393
+ '[3:3]>[3:8](15,20)div: <div>',
394
+ '[3:8]>[4:4](20,24)#text: ⏎→→→',
395
+ '[4:4]>[4:22](24,42)template: <template␣#header>',
396
+ '[4:14]>[4:21](34,41)v-slot:header: #header',
397
+ ' [4:13]>[4:14](33,34)bN: ␣',
398
+ ' [4:14]>[4:21](34,41)name: #header',
399
+ ' [4:21]>[4:21](41,41)bE: ',
400
+ ' [4:21]>[4:21](41,41)equal: ',
401
+ ' [4:21]>[4:21](41,41)aE: ',
402
+ ' [4:21]>[4:21](41,41)sQ: ',
403
+ ' [4:21]>[4:21](41,41)value: ',
404
+ ' [4:21]>[4:21](41,41)eQ: ',
405
+ ' isDirective: true',
406
+ ' isDynamicValue: false',
407
+ ' potentialName: v-slot:header',
408
+ '[4:33]>[5:3](53,56)#text: ⏎→→',
409
+ '[5:3]>[5:9](56,62)div: </div>',
410
+ '[5:9]>[6:2](62,64)#text: ⏎→',
411
+ ]);
412
+ });
413
+ });
414
+
415
+ describe('Issues', () => {
416
+ test('#783', () => {
417
+ const doc = parse(`
418
+ <template>
419
+ <button @click.stop="foo" v-on:click.stop="bar">...</button>
420
+ </template>
421
+ `);
422
+ const map = nodeListToDebugMaps(doc.nodeList, true);
423
+ expect(map).toStrictEqual([
424
+ '[2:12]>[3:3](12,15)#text: ⏎→→',
425
+ '[3:3]>[3:51](15,63)button: <button␣@click.stop="foo"␣v-on:click.stop="bar">',
426
+ '[3:11]>[3:28](23,40)onclick: @click.stop="foo"',
427
+ ' [3:10]>[3:11](22,23)bN: ␣',
428
+ ' [3:11]>[3:22](23,34)name: @click.stop',
429
+ ' [3:22]>[3:22](34,34)bE: ',
430
+ ' [3:22]>[3:23](34,35)equal: =',
431
+ ' [3:23]>[3:23](35,35)aE: ',
432
+ ' [3:23]>[3:24](35,36)sQ: "',
433
+ ' [3:24]>[3:27](36,39)value: foo',
434
+ ' [3:27]>[3:28](39,40)eQ: "',
435
+ ' isDirective: false',
436
+ ' isDynamicValue: true',
437
+ ' potentialName: onclick',
438
+ '[3:29]>[3:50](41,62)onclick: v-on:click.stop="bar"',
439
+ ' [3:28]>[3:29](40,41)bN: ␣',
440
+ ' [3:29]>[3:44](41,56)name: v-on:click.stop',
441
+ ' [3:44]>[3:44](56,56)bE: ',
442
+ ' [3:44]>[3:45](56,57)equal: =',
443
+ ' [3:45]>[3:45](57,57)aE: ',
444
+ ' [3:45]>[3:46](57,58)sQ: "',
445
+ ' [3:46]>[3:49](58,61)value: bar',
446
+ ' [3:49]>[3:50](61,62)eQ: "',
447
+ ' isDirective: false',
448
+ ' isDynamicValue: true',
449
+ ' potentialName: onclick',
450
+ '[3:51]>[3:54](63,66)#text: ...',
451
+ '[3:54]>[3:63](66,75)button: </button>',
452
+ '[3:63]>[4:2](75,77)#text: ⏎→',
453
+ ]);
454
+ });
455
+ });