@markuplint/html-parser 3.11.0 → 4.0.0-alpha.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.
@@ -1,1246 +0,0 @@
1
- const { attributesToDebugMaps, nodeListToDebugMaps } = require('@markuplint/parser-utils');
2
-
3
- const { isDocumentFragment, parse } = require('../lib/');
4
-
5
- describe('isDocumentFragment', () => {
6
- it('<!doctype>', () => {
7
- expect(isDocumentFragment('<!DOCTYPE html>')).toBe(false);
8
- });
9
-
10
- it('<!doctype> - 2', () => {
11
- expect(
12
- isDocumentFragment(`
13
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
14
- `),
15
- ).toBe(false);
16
- });
17
-
18
- it('<!doctype> + <html>', () => {
19
- expect(
20
- isDocumentFragment(`
21
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
22
- <html>
23
- `),
24
- ).toBe(false);
25
- });
26
-
27
- it('<!doctype> + <html></html>', () => {
28
- expect(
29
- isDocumentFragment(`
30
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
31
- <html></html>
32
- `),
33
- ).toBe(false);
34
- });
35
-
36
- it('<!doctype> + <html> - 2', () => {
37
- expect(
38
- isDocumentFragment(`
39
- <html lang="ja">
40
- `),
41
- ).toBe(false);
42
- });
43
-
44
- it('<!doctype> + <html></html> - 2', () => {
45
- expect(
46
- isDocumentFragment(`
47
- <html lang="ja"></html>
48
- `),
49
- ).toBe(false);
50
- });
51
-
52
- it('<html></html>', () => {
53
- expect(isDocumentFragment('<html lang="ja"></html>')).toBe(false);
54
- });
55
-
56
- it('<html></html> - 2', () => {
57
- expect(isDocumentFragment('<html></html>')).toBe(false);
58
- });
59
-
60
- it('<body>', () => {
61
- expect(
62
- isDocumentFragment(`
63
- <body>
64
- `),
65
- ).toBe(true);
66
- });
67
-
68
- it('<body></body>', () => {
69
- expect(isDocumentFragment('<body></body>')).toBe(true);
70
- });
71
-
72
- it('<div></div>', () => {
73
- expect(isDocumentFragment('<div></div>')).toBe(true);
74
- });
75
-
76
- it('<template></template>', () => {
77
- expect(isDocumentFragment('<template></template>')).toBe(true);
78
- });
79
-
80
- it('<head></head>', () => {
81
- expect(isDocumentFragment('<head></head>')).toBe(true);
82
- });
83
- });
84
-
85
- describe('parser', () => {
86
- it('<!DOCTYPE html>', () => {
87
- const doc = parse('<!DOCTYPE html>');
88
- expect(doc.nodeList[0].type).toBe('doctype');
89
- expect(doc.nodeList[1].nodeName).toBe('html');
90
- expect(doc.nodeList[2].nodeName).toBe('head');
91
- expect(doc.nodeList[3].nodeName).toBe('body');
92
- expect(doc.nodeList.length).toBe(4);
93
- });
94
-
95
- it('<!DOCTYPE html> ', () => {
96
- const doc = parse('<!DOCTYPE html> ');
97
- expect(doc.nodeList[0].type).toBe('doctype');
98
- expect(doc.nodeList[1].nodeName).toBe('html');
99
- expect(doc.nodeList[2].nodeName).toBe('head');
100
- expect(doc.nodeList[3].nodeName).toBe('body');
101
- expect(doc.nodeList[4].nodeName).toBe('#text');
102
- expect(doc.nodeList[4].raw).toBe(' ');
103
- expect(doc.nodeList.length).toBe(5);
104
- });
105
-
106
- it('<!DOCTYPE html>\\n', () => {
107
- const doc = parse('<!DOCTYPE html>\n');
108
- expect(doc.nodeList[0].type).toBe('doctype');
109
- expect(doc.nodeList[1].nodeName).toBe('html');
110
- expect(doc.nodeList[2].nodeName).toBe('head');
111
- expect(doc.nodeList[3].nodeName).toBe('body');
112
- expect(doc.nodeList[4].nodeName).toBe('#text');
113
- expect(doc.nodeList[4].raw).toBe('\n');
114
- expect(doc.nodeList.length).toBe(5);
115
- });
116
-
117
- it('<!DOCTYPE html>text', () => {
118
- const doc = parse('<!DOCTYPE html>text');
119
- expect(doc.nodeList[0].type).toBe('doctype');
120
- expect(doc.nodeList[1].nodeName).toBe('html');
121
- expect(doc.nodeList[2].nodeName).toBe('head');
122
- expect(doc.nodeList[3].nodeName).toBe('body');
123
- expect(doc.nodeList[4].type).toBe('text');
124
- expect(doc.nodeList[4].startCol).toBe(16);
125
- expect(doc.nodeList.length).toBe(5);
126
- });
127
-
128
- it('<!DOCTYPE html> text', () => {
129
- const doc = parse('<!DOCTYPE html> text');
130
- expect(doc.nodeList[0].type).toBe('doctype');
131
- expect(doc.nodeList[1].nodeName).toBe('html');
132
- expect(doc.nodeList[2].nodeName).toBe('head');
133
- expect(doc.nodeList[3].nodeName).toBe('body');
134
- expect(doc.nodeList[4].type).toBe('text');
135
- expect(doc.nodeList[4].raw).toBe(' text');
136
- expect(doc.nodeList[4].startCol).toBe(16);
137
- expect(doc.nodeList.length).toBe(5);
138
- });
139
-
140
- it('<!DOCTYPE html>\\ntext', () => {
141
- const doc = parse('<!DOCTYPE html>\ntext');
142
- expect(doc.nodeList[0].type).toBe('doctype');
143
- expect(doc.nodeList[1].nodeName).toBe('html');
144
- expect(doc.nodeList[2].nodeName).toBe('head');
145
- expect(doc.nodeList[3].nodeName).toBe('body');
146
- expect(doc.nodeList[4].type).toBe('text');
147
- expect(doc.nodeList[4].raw).toBe('\ntext');
148
- expect(doc.nodeList[4].startCol).toBe(16);
149
- expect(doc.nodeList.length).toBe(5);
150
- });
151
-
152
- it('<!DOCTYPE html>\\n<p>text', () => {
153
- const doc = parse('<!DOCTYPE html>\n<p>text');
154
- expect(doc.nodeList[0].type).toBe('doctype');
155
- expect(doc.nodeList[1].nodeName).toBe('html');
156
- expect(doc.nodeList[2].nodeName).toBe('head');
157
- expect(doc.nodeList[3].nodeName).toBe('body');
158
- expect(doc.nodeList[4].nodeName).toBe('#text');
159
- expect(doc.nodeList[5].nodeName).toBe('p');
160
- expect(doc.nodeList[6].type).toBe('text');
161
- expect(doc.nodeList[6].raw).toBe('text');
162
- expect(doc.nodeList[6].startCol).toBe(4);
163
- expect(doc.nodeList.length).toBe(7);
164
- });
165
-
166
- it('<!DOCTYPE html><p>\\ntext', () => {
167
- const doc = parse('<!DOCTYPE html><p>\ntext');
168
- expect(doc.nodeList[0].type).toBe('doctype');
169
- expect(doc.nodeList[1].nodeName).toBe('html');
170
- expect(doc.nodeList[2].nodeName).toBe('head');
171
- expect(doc.nodeList[3].nodeName).toBe('body');
172
- expect(doc.nodeList[4].nodeName).toBe('p');
173
- expect(doc.nodeList[5].type).toBe('text');
174
- expect(doc.nodeList[5].raw).toBe('\ntext');
175
- expect(doc.nodeList[5].startCol).toBe(19);
176
- expect(doc.nodeList.length).toBe(6);
177
- });
178
-
179
- it('<!DOCTYPE html>\\n<html>text', () => {
180
- const doc = parse('<!DOCTYPE html>\n<html>text');
181
- expect(doc.nodeList[0].type).toBe('doctype');
182
- expect(doc.nodeList[1].nodeName).toBe('#text');
183
- expect(doc.nodeList[2].nodeName).toBe('html');
184
- expect(doc.nodeList[3].nodeName).toBe('head');
185
- expect(doc.nodeList[4].nodeName).toBe('body');
186
- expect(doc.nodeList[5].type).toBe('text');
187
- expect(doc.nodeList[5].raw).toBe('text');
188
- expect(doc.nodeList[5].startCol).toBe(7);
189
- expect(doc.nodeList.length).toBe(6);
190
- });
191
-
192
- it('<!DOCTYPE html><html>\\ntext', () => {
193
- const doc = parse('<!DOCTYPE html><html>\ntext');
194
- expect(doc.nodeList[0].type).toBe('doctype');
195
- expect(doc.nodeList[1].nodeName).toBe('html');
196
- expect(doc.nodeList[2].nodeName).toBe('head');
197
- expect(doc.nodeList[3].nodeName).toBe('body');
198
- expect(doc.nodeList[4].type).toBe('text');
199
- expect(doc.nodeList[4].raw).toBe('\ntext');
200
- expect(doc.nodeList[4].startCol).toBe(22);
201
- expect(doc.nodeList.length).toBe(5);
202
- });
203
-
204
- it('empty code', () => {
205
- const doc = parse('');
206
- expect(doc.nodeList).toStrictEqual([]);
207
- expect(doc.nodeList.length).toBe(0);
208
- });
209
-
210
- it('<html>', () => {
211
- const doc = parse('<html>');
212
- expect(doc.nodeList[0].nodeName).toBe('html');
213
- expect(doc.nodeList[1].nodeName).toBe('head');
214
- expect(doc.nodeList[2].nodeName).toBe('body');
215
- expect(doc.nodeList.length).toBe(3);
216
- });
217
-
218
- it('<html></body>', () => {
219
- const doc = parse('<html></body>');
220
- expect(doc.nodeList[0].nodeName).toBe('html');
221
- expect(doc.nodeList[1].nodeName).toBe('head');
222
- expect(doc.nodeList[2].nodeName).toBe('body');
223
- expect(doc.nodeList[3].nodeName).toBe('#text');
224
- expect(doc.nodeList[3].raw).toBe('</body>');
225
- expect(doc.nodeList.length).toBe(4);
226
- });
227
-
228
- it('text only', () => {
229
- const doc = parse('text');
230
- expect(doc.nodeList[0].nodeName).toBe('#text');
231
- expect(doc.nodeList[0].raw).toBe('text');
232
- expect(doc.nodeList.length).toBe(1);
233
- });
234
-
235
- it('<html>invalid-before-text<body>text</body>invalid-after-text</html>', () => {
236
- const doc = parse('<html>invalid-before-text<body>text</body>invalid-after-text</html>');
237
- expect(doc.nodeList[0].nodeName).toBe('html');
238
- expect(doc.nodeList[1].nodeName).toBe('head');
239
- expect(doc.nodeList[2].nodeName).toBe('body');
240
- expect(doc.nodeList[3].nodeName).toBe('#text');
241
- expect(doc.nodeList[4].nodeName).toBe('html');
242
- expect(doc.nodeList.length).toBe(5);
243
- });
244
-
245
- test('a element', () => {
246
- const r = parse('<div>text</div>');
247
- const map = nodeListToDebugMaps(r.nodeList);
248
- expect(map).toStrictEqual([
249
- '[1:1]>[1:6](0,5)div: <div>',
250
- '[1:6]>[1:10](5,9)#text: text',
251
- '[1:10]>[1:16](9,15)div: </div>',
252
- ]);
253
- });
254
-
255
- it('<head><title>TITLE</title></head>', () => {
256
- const doc = parse('<head><title>TITLE</title></head>');
257
- expect(nodeListToDebugMaps(doc.nodeList)).toStrictEqual([
258
- '[1:1]>[1:7](0,6)head: <head>',
259
- '[1:7]>[1:14](6,13)title: <title>',
260
- '[1:14]>[1:19](13,18)#text: TITLE',
261
- '[1:19]>[1:27](18,26)title: </title>',
262
- '[1:27]>[1:34](26,33)head: </head>',
263
- ]);
264
- });
265
-
266
- it('<body><p>TEXT</p></body>', () => {
267
- const doc = parse('<body><p>TEXT</p></body>');
268
- expect(nodeListToDebugMaps(doc.nodeList)).toStrictEqual([
269
- '[1:1]>[1:7](0,6)body: <body>',
270
- '[1:7]>[1:10](6,9)p: <p>',
271
- '[1:10]>[1:14](9,13)#text: TEXT',
272
- '[1:14]>[1:18](13,17)p: </p>',
273
- '[1:18]>[1:25](17,24)body: </body>',
274
- ]);
275
- });
276
-
277
- it('<head><title>TITLE</title></head><body><p>TEXT</p></body>', () => {
278
- const doc = parse('<head><title>TITLE</title></head><body><p>TEXT</p></body>');
279
- expect(nodeListToDebugMaps(doc.nodeList)).toStrictEqual([
280
- '[1:1]>[1:7](0,6)head: <head>',
281
- '[1:7]>[1:14](6,13)title: <title>',
282
- '[1:14]>[1:19](13,18)#text: TITLE',
283
- '[1:19]>[1:27](18,26)title: </title>',
284
- '[1:27]>[1:34](26,33)head: </head>',
285
- '[1:34]>[1:40](33,39)body: <body>',
286
- '[1:40]>[1:43](39,42)p: <p>',
287
- '[1:43]>[1:47](42,46)#text: TEXT',
288
- '[1:47]>[1:51](46,50)p: </p>',
289
- '[1:51]>[1:58](50,57)body: </body>',
290
- ]);
291
- });
292
-
293
- it('<head><title>TITLE</title>', () => {
294
- const doc = parse('<head><title>TITLE</title>');
295
- expect(nodeListToDebugMaps(doc.nodeList)).toStrictEqual([
296
- '[1:1]>[1:7](0,6)head: <head>',
297
- '[1:7]>[1:14](6,13)title: <title>',
298
- '[1:14]>[1:19](13,18)#text: TITLE',
299
- '[1:19]>[1:27](18,26)title: </title>',
300
- ]);
301
- });
302
-
303
- it('<body><p>TEXT</p>', () => {
304
- const doc = parse('<body><p>TEXT</p>');
305
- expect(nodeListToDebugMaps(doc.nodeList)).toStrictEqual([
306
- '[1:1]>[1:7](0,6)body: <body>',
307
- '[1:7]>[1:10](6,9)p: <p>',
308
- '[1:10]>[1:14](9,13)#text: TEXT',
309
- '[1:14]>[1:18](13,17)p: </p>',
310
- ]);
311
- });
312
-
313
- it('<head><title>TITLE</title><body><p>TEXT</p>', () => {
314
- const doc = parse('<head><title>TITLE</title><body><p>TEXT</p>');
315
- expect(nodeListToDebugMaps(doc.nodeList)).toStrictEqual([
316
- '[1:1]>[1:7](0,6)head: <head>',
317
- '[1:7]>[1:14](6,13)title: <title>',
318
- '[1:14]>[1:19](13,18)#text: TITLE',
319
- '[1:19]>[1:27](18,26)title: </title>',
320
- '[1:27]>[1:33](26,32)body: <body>',
321
- '[1:33]>[1:36](32,35)p: <p>',
322
- '[1:36]>[1:40](35,39)#text: TEXT',
323
- '[1:40]>[1:44](39,43)p: </p>',
324
- ]);
325
- });
326
-
327
- it('standard code', () => {
328
- const doc = parse(`
329
- <!DOCTYPE html>
330
- <html lang="en">
331
- <head>
332
- <meta charset="UTF-8">
333
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
334
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
335
- <title>Document</title>
336
- </head>
337
- <body>
338
- <script>
339
- const i = 0;
340
- </script>
341
- <!comment-node>
342
- <!-- html-comment -->
343
- <div>
344
- text&amp;div
345
- </div>
346
- <table>
347
- <tr>
348
- <th>header</th>
349
- <td>cell</td>
350
- </tr>
351
- </table>
352
- <table>
353
- <tbody>
354
- <tr>
355
- <th>header</th>
356
- <td>cell</td>
357
- </tr>
358
- </tbody>
359
- </table>
360
- <img src="path/to" />
361
- invalid-indent
362
-
363
- <?template engine;
364
- $var = '<html attr="value">text</html>'
365
- ?>
366
-
367
- <%template engine;
368
- $var = '<html attr="value">text</html>'
369
- %>
370
-
371
- </expected>
372
- <div>
373
- text-node
374
- </body>
375
- </html>
376
- `);
377
- const map = nodeListToDebugMaps(doc.nodeList);
378
- expect(map).toStrictEqual([
379
- '[1:1]>[2:2](0,2)#text: ⏎→',
380
- '[2:2]>[2:17](2,17)#doctype: <!DOCTYPE␣html>',
381
- '[2:17]>[3:2](17,19)#text: ⏎→',
382
- '[3:2]>[3:18](19,35)html: <html␣lang="en">',
383
- '[3:18]>[4:2](35,37)#text: ⏎→',
384
- '[4:2]>[4:8](37,43)head: <head>',
385
- '[4:8]>[5:3](43,46)#text: ⏎→→',
386
- '[5:3]>[5:25](46,68)meta: <meta␣charset="UTF-8">',
387
- '[5:25]>[6:3](68,71)#text: ⏎→→',
388
- '[6:3]>[6:73](71,141)meta: <meta␣name="viewport"␣content="width=device-width,␣initial-scale=1.0">',
389
- '[6:73]>[7:3](141,144)#text: ⏎→→',
390
- '[7:3]>[7:56](144,197)meta: <meta␣http-equiv="X-UA-Compatible"␣content="ie=edge">',
391
- '[7:56]>[8:3](197,200)#text: ⏎→→',
392
- '[8:3]>[8:10](200,207)title: <title>',
393
- '[8:10]>[8:18](207,215)#text: Document',
394
- '[8:18]>[8:26](215,223)title: </title>',
395
- '[8:26]>[9:2](223,225)#text: ⏎→',
396
- '[9:2]>[9:9](225,232)head: </head>',
397
- '[9:9]>[10:2](232,234)#text: ⏎→',
398
- '[10:2]>[10:8](234,240)body: <body>',
399
- '[10:8]>[11:3](240,243)#text: ⏎→→',
400
- '[11:3]>[11:11](243,251)script: <script>',
401
- '[11:11]>[13:3](251,270)#text: ⏎→→→const␣i␣=␣0;⏎→→',
402
- '[13:3]>[13:12](270,279)script: </script>',
403
- '[13:12]>[14:3](279,282)#text: ⏎→→',
404
- '[14:3]>[14:18](282,297)#comment: <!comment-node>',
405
- '[14:18]>[15:3](297,300)#text: ⏎→→',
406
- '[15:3]>[15:24](300,321)#comment: <!--␣html-comment␣-->',
407
- '[15:24]>[16:3](321,324)#text: ⏎→→',
408
- '[16:3]>[16:8](324,329)div: <div>',
409
- '[16:8]>[18:3](329,348)#text: ⏎→→→text&amp;div⏎→→',
410
- '[18:3]>[18:9](348,354)div: </div>',
411
- '[18:9]>[19:3](354,357)#text: ⏎→→',
412
- '[19:3]>[19:10](357,364)table: <table>',
413
- '[19:10]>[20:4](364,368)#text: ⏎→→→',
414
- '[N/A]>[N/A](N/A)tbody: ',
415
- '[20:4]>[20:8](368,372)tr: <tr>',
416
- '[20:8]>[21:5](372,377)#text: ⏎→→→→',
417
- '[21:5]>[21:9](377,381)th: <th>',
418
- '[21:9]>[21:15](381,387)#text: header',
419
- '[21:15]>[21:20](387,392)th: </th>',
420
- '[21:20]>[22:5](392,397)#text: ⏎→→→→',
421
- '[22:5]>[22:9](397,401)td: <td>',
422
- '[22:9]>[22:13](401,405)#text: cell',
423
- '[22:13]>[22:18](405,410)td: </td>',
424
- '[22:18]>[23:4](410,414)#text: ⏎→→→',
425
- '[23:4]>[23:9](414,419)tr: </tr>',
426
- '[23:9]>[24:3](419,422)#text: ⏎→→',
427
- '[24:3]>[24:11](422,430)table: </table>',
428
- '[24:11]>[25:3](430,433)#text: ⏎→→',
429
- '[25:3]>[25:10](433,440)table: <table>',
430
- '[25:10]>[26:4](440,444)#text: ⏎→→→',
431
- '[26:4]>[26:11](444,451)tbody: <tbody>',
432
- '[26:11]>[27:5](451,456)#text: ⏎→→→→',
433
- '[27:5]>[27:9](456,460)tr: <tr>',
434
- '[27:9]>[28:6](460,466)#text: ⏎→→→→→',
435
- '[28:6]>[28:10](466,470)th: <th>',
436
- '[28:10]>[28:16](470,476)#text: header',
437
- '[28:16]>[28:21](476,481)th: </th>',
438
- '[28:21]>[29:6](481,487)#text: ⏎→→→→→',
439
- '[29:6]>[29:10](487,491)td: <td>',
440
- '[29:10]>[29:14](491,495)#text: cell',
441
- '[29:14]>[29:19](495,500)td: </td>',
442
- '[29:19]>[30:5](500,505)#text: ⏎→→→→',
443
- '[30:5]>[30:10](505,510)tr: </tr>',
444
- '[30:10]>[31:4](510,514)#text: ⏎→→→',
445
- '[31:4]>[31:12](514,522)tbody: </tbody>',
446
- '[31:12]>[32:3](522,525)#text: ⏎→→',
447
- '[32:3]>[32:11](525,533)table: </table>',
448
- '[32:11]>[33:3](533,536)#text: ⏎→→',
449
- '[33:3]>[33:24](536,557)img: <img␣src="path/to"␣/>',
450
- '[33:24]>[36:3](557,580)#text: ⏎→→→→invalid-indent⏎⏎→→',
451
- '[36:3]>[37:31](580,629)#comment: <?template␣engine;⏎→→→$var␣=␣\'<html␣attr="value">',
452
- "[37:31]>[45:3](629,734)#text: text</html>'⏎→→?>⏎⏎→→<%template␣engine;⏎→→→$var␣=␣'<html␣attr=\"value\">text</html>'⏎→→%>⏎⏎→→</expected>⏎→→",
453
- '[45:3]>[45:8](734,739)div: <div>',
454
- '[45:8]>[47:2](739,752)#text: ⏎→text-node⏎→',
455
- '[47:2]>[47:9](752,759)body: </body>',
456
- '[47:9]>[48:2](759,761)#text: ⏎→',
457
- '[48:2]>[48:9](761,768)html: </html>',
458
- '[48:9]>[49:2](768,770)#text: ⏎→',
459
- ]);
460
- });
461
-
462
- it('<template>', () => {
463
- const doc = parse(`
464
- <template>
465
- <script>
466
- const i = 0;
467
- </script>
468
- <!comment-node>
469
- <!-- html-comment -->
470
- <div>
471
- text&amp;div
472
- </div>
473
- <table>
474
- <tr>
475
- <th>header</th>
476
- <td>cell</td>
477
- </tr>
478
- </table>
479
- <table>
480
- <tbody>
481
- <tr>
482
- <th>header</th>
483
- <td>cell</td>
484
- </tr>
485
- </tbody>
486
- </table>
487
- <img src="path/to" />
488
- invalid-indent
489
-
490
- <?template engine;
491
- $var = '<html attr="value">text</html>'
492
- ?>
493
-
494
- <%template engine;
495
- $var = '<html attr="value">text</html>'
496
- %>
497
-
498
- </expected>
499
- <div>
500
- text-node
501
- </template>
502
- `);
503
- const map = nodeListToDebugMaps(doc.nodeList);
504
- expect(map).toStrictEqual([
505
- '[1:1]>[2:2](0,2)#text: ⏎→',
506
- '[2:2]>[2:12](2,12)template: <template>',
507
- '[2:12]>[3:3](12,15)#text: ⏎→→',
508
- '[3:3]>[3:11](15,23)script: <script>',
509
- '[3:11]>[5:3](23,42)#text: ⏎→→→const␣i␣=␣0;⏎→→',
510
- '[5:3]>[5:12](42,51)script: </script>',
511
- '[5:12]>[6:3](51,54)#text: ⏎→→',
512
- '[6:3]>[6:18](54,69)#comment: <!comment-node>',
513
- '[6:18]>[7:3](69,72)#text: ⏎→→',
514
- '[7:3]>[7:24](72,93)#comment: <!--␣html-comment␣-->',
515
- '[7:24]>[8:3](93,96)#text: ⏎→→',
516
- '[8:3]>[8:8](96,101)div: <div>',
517
- '[8:8]>[10:3](101,120)#text: ⏎→→→text&amp;div⏎→→',
518
- '[10:3]>[10:9](120,126)div: </div>',
519
- '[10:9]>[11:3](126,129)#text: ⏎→→',
520
- '[11:3]>[11:10](129,136)table: <table>',
521
- '[11:10]>[12:4](136,140)#text: ⏎→→→',
522
- '[N/A]>[N/A](N/A)tbody: ',
523
- '[12:4]>[12:8](140,144)tr: <tr>',
524
- '[12:8]>[13:5](144,149)#text: ⏎→→→→',
525
- '[13:5]>[13:9](149,153)th: <th>',
526
- '[13:9]>[13:15](153,159)#text: header',
527
- '[13:15]>[13:20](159,164)th: </th>',
528
- '[13:20]>[14:5](164,169)#text: ⏎→→→→',
529
- '[14:5]>[14:9](169,173)td: <td>',
530
- '[14:9]>[14:13](173,177)#text: cell',
531
- '[14:13]>[14:18](177,182)td: </td>',
532
- '[14:18]>[15:4](182,186)#text: ⏎→→→',
533
- '[15:4]>[15:9](186,191)tr: </tr>',
534
- '[15:9]>[16:3](191,194)#text: ⏎→→',
535
- '[16:3]>[16:11](194,202)table: </table>',
536
- '[16:11]>[17:3](202,205)#text: ⏎→→',
537
- '[17:3]>[17:10](205,212)table: <table>',
538
- '[17:10]>[18:4](212,216)#text: ⏎→→→',
539
- '[18:4]>[18:11](216,223)tbody: <tbody>',
540
- '[18:11]>[19:5](223,228)#text: ⏎→→→→',
541
- '[19:5]>[19:9](228,232)tr: <tr>',
542
- '[19:9]>[20:6](232,238)#text: ⏎→→→→→',
543
- '[20:6]>[20:10](238,242)th: <th>',
544
- '[20:10]>[20:16](242,248)#text: header',
545
- '[20:16]>[20:21](248,253)th: </th>',
546
- '[20:21]>[21:6](253,259)#text: ⏎→→→→→',
547
- '[21:6]>[21:10](259,263)td: <td>',
548
- '[21:10]>[21:14](263,267)#text: cell',
549
- '[21:14]>[21:19](267,272)td: </td>',
550
- '[21:19]>[22:5](272,277)#text: ⏎→→→→',
551
- '[22:5]>[22:10](277,282)tr: </tr>',
552
- '[22:10]>[23:4](282,286)#text: ⏎→→→',
553
- '[23:4]>[23:12](286,294)tbody: </tbody>',
554
- '[23:12]>[24:3](294,297)#text: ⏎→→',
555
- '[24:3]>[24:11](297,305)table: </table>',
556
- '[24:11]>[25:3](305,308)#text: ⏎→→',
557
- '[25:3]>[25:24](308,329)img: <img␣src="path/to"␣/>',
558
- '[25:24]>[28:3](329,352)#text: ⏎→→→→invalid-indent⏎⏎→→',
559
- '[28:3]>[29:31](352,401)#comment: <?template␣engine;⏎→→→$var␣=␣\'<html␣attr="value">',
560
- "[29:31]>[37:3](401,506)#text: text</html>'⏎→→?>⏎⏎→→<%template␣engine;⏎→→→$var␣=␣'<html␣attr=\"value\">text</html>'⏎→→%>⏎⏎→→</expected>⏎→→",
561
- '[37:3]>[37:8](506,511)div: <div>',
562
- '[37:8]>[39:2](511,524)#text: ⏎→text-node⏎→',
563
- '[39:2]>[39:13](524,535)template: </template>',
564
- '[39:13]>[40:2](535,537)#text: ⏎→',
565
- ]);
566
- });
567
-
568
- it('<noscript>', () => {
569
- const doc = parse(`
570
- <noscript>
571
- <div>test</div>
572
- <expected>
573
- </expected2>
574
- </noscript>
575
- `);
576
- const map = nodeListToDebugMaps(doc.nodeList);
577
- expect(map).toStrictEqual([
578
- '[1:1]>[2:2](0,2)#text: ⏎→',
579
- '[2:2]>[2:12](2,12)noscript: <noscript>',
580
- '[2:12]>[3:3](12,15)#text: ⏎→→',
581
- '[3:3]>[3:8](15,20)div: <div>',
582
- '[3:8]>[3:12](20,24)#text: test',
583
- '[3:12]>[3:18](24,30)div: </div>',
584
- '[3:18]>[4:3](30,33)#text: ⏎→→',
585
- '[4:3]>[4:13](33,43)expected: <expected>',
586
- '[4:13]>[6:2](43,60)#text: ⏎→→</expected2>⏎→',
587
- '[6:2]>[6:13](60,71)noscript: </noscript>',
588
- '[6:13]>[7:2](71,73)#text: ⏎→',
589
- ]);
590
- });
591
-
592
- /**
593
- * https://github.com/markuplint/markuplint/issues/219
594
- */
595
- it('<noscript> (Issue: #219)', () => {
596
- const doc = parse('<html><body><body><noscript data-xxx><iframe ></iframe></noscript></body></html>');
597
- const map = nodeListToDebugMaps(doc.nodeList);
598
- expect(map).toStrictEqual([
599
- '[1:1]>[1:7](0,6)html: <html>',
600
- '[N/A]>[N/A](N/A)head: ',
601
- '[1:7]>[1:13](6,12)body: <body>',
602
- '[1:19]>[1:38](18,37)noscript: <noscript␣data-xxx>',
603
- '[1:38]>[1:47](37,46)iframe: <iframe␣>',
604
- '[1:47]>[1:56](46,55)iframe: </iframe>',
605
- '[1:56]>[1:67](55,66)noscript: </noscript>',
606
- '[1:67]>[1:74](66,73)body: </body>',
607
- '[1:74]>[1:81](73,80)html: </html>',
608
- ]);
609
- });
610
-
611
- /**
612
- * https://github.com/markuplint/markuplint/issues/737
613
- */
614
- it('<noscript> (Issue: #737)', () => {
615
- const doc = parse('<html><body><noscript>\r\n<div>text</div>\r\n</noscript></body></html>');
616
- const map = nodeListToDebugMaps(doc.nodeList);
617
- expect(map).toStrictEqual([
618
- '[1:1]>[1:7](0,6)html: <html>',
619
- '[N/A]>[N/A](N/A)head: ',
620
- '[1:7]>[1:13](6,12)body: <body>',
621
- '[1:13]>[1:23](12,22)noscript: <noscript>',
622
- '[1:23]>[2:1](22,24)#text: ␣⏎',
623
- '[2:1]>[2:6](24,29)div: <div>',
624
- '[2:6]>[2:10](29,33)#text: text',
625
- '[2:10]>[2:16](33,39)div: </div>',
626
- '[2:16]>[3:1](39,41)#text: ␣⏎',
627
- '[3:1]>[3:12](41,52)noscript: </noscript>',
628
- '[3:12]>[3:19](52,59)body: </body>',
629
- '[3:19]>[3:26](59,66)html: </html>',
630
- ]);
631
- });
632
-
633
- it('<form>', () => {
634
- const doc = parse(`
635
- <div>
636
- <form novalidate>
637
- <input type="text" name="foo">
638
- <input type="checkbox" name="bar">
639
- </form>
640
- </div>
641
- `);
642
- const map = nodeListToDebugMaps(doc.nodeList);
643
- expect(map).toStrictEqual([
644
- '[1:1]>[2:2](0,2)#text: ⏎→',
645
- '[2:2]>[2:7](2,7)div: <div>',
646
- '[2:7]>[3:3](7,10)#text: ⏎→→',
647
- '[3:3]>[3:20](10,27)form: <form␣novalidate>',
648
- '[3:20]>[4:4](27,31)#text: ⏎→→→',
649
- '[4:4]>[4:34](31,61)input: <input␣type="text"␣name="foo">',
650
- '[4:34]>[5:4](61,65)#text: ⏎→→→',
651
- '[5:4]>[5:38](65,99)input: <input␣type="checkbox"␣name="bar">',
652
- '[5:38]>[6:3](99,102)#text: ⏎→→',
653
- '[6:3]>[6:10](102,109)form: </form>',
654
- '[6:10]>[7:2](109,111)#text: ⏎→',
655
- '[7:2]>[7:8](111,117)div: </div>',
656
- '[7:8]>[8:2](117,119)#text: ⏎→',
657
- ]);
658
- });
659
-
660
- it('<form> in <form>', () => {
661
- const doc = parse(`
662
- <form>
663
- <form novalidate>
664
- <input type="text" name="foo">
665
- <input type="checkbox" name="bar">
666
- </form>
667
- </form>
668
- `);
669
- const map = nodeListToDebugMaps(doc.nodeList);
670
- expect(map).toStrictEqual([
671
- '[1:1]>[2:2](0,2)#text: ⏎→',
672
- '[2:2]>[2:8](2,8)form: <form>',
673
- '[2:8]>[4:4](8,32)#text: ⏎→→<form␣novalidate>⏎→→→',
674
- '[4:4]>[4:34](32,62)input: <input␣type="text"␣name="foo">',
675
- '[4:34]>[5:4](62,66)#text: ⏎→→→',
676
- '[5:4]>[5:38](66,100)input: <input␣type="checkbox"␣name="bar">',
677
- '[5:38]>[6:3](100,103)#text: ⏎→→',
678
- '[6:3]>[6:10](103,110)form: </form>',
679
- '[6:10]>[8:2](110,121)#text: ⏎→</form>⏎→',
680
- ]);
681
- });
682
-
683
- it('UUID', () => {
684
- const doc = parse('<html><head><title>title</title></head><body><div>test</div></body></html>');
685
- // const map = nodeListToDebugMaps(doc.nodeList);
686
- // console.log(map);
687
- // console.log(doc.nodeList.map((n, i) => `${i}: ${n.uuid} ${n.raw.trim()}`));
688
-
689
- // <html>
690
- expect(doc.nodeList[0].parentNode).toEqual(null);
691
- expect(doc.nodeList[0].prevNode).toEqual(null);
692
- expect(doc.nodeList[0].nextNode).toEqual(null);
693
- // @ts-ignore
694
- expect(doc.nodeList[0].pearNode.uuid).toEqual(doc.nodeList[11].uuid);
695
-
696
- // </html>
697
- expect(doc.nodeList[11].parentNode).toEqual(null);
698
- // @ts-ignore
699
- expect(doc.nodeList[11].pearNode.uuid).toEqual(doc.nodeList[0].uuid);
700
-
701
- // <head>
702
- // @ts-ignore
703
- expect(doc.nodeList[1].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
704
- // @ts-ignore
705
- expect(doc.nodeList[1].prevNode).toEqual(null);
706
- // @ts-ignore
707
- expect(doc.nodeList[1].nextNode.uuid).toEqual(doc.nodeList[6].uuid);
708
- // @ts-ignore
709
- expect(doc.nodeList[1].pearNode.uuid).toEqual(doc.nodeList[5].uuid);
710
-
711
- // </head>
712
- // @ts-ignore
713
- expect(doc.nodeList[5].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
714
- // @ts-ignore
715
- expect(doc.nodeList[5].pearNode.uuid).toEqual(doc.nodeList[1].uuid);
716
-
717
- // <body>
718
- // @ts-ignore
719
- expect(doc.nodeList[6].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
720
- // @ts-ignore
721
- expect(doc.nodeList[6].prevNode.uuid).toEqual(doc.nodeList[1].uuid);
722
- // @ts-ignore
723
- expect(doc.nodeList[6].nextNode).toEqual(null);
724
- // @ts-ignore
725
- expect(doc.nodeList[6].pearNode.uuid).toEqual(doc.nodeList[10].uuid);
726
-
727
- // </body>
728
- // @ts-ignore
729
- expect(doc.nodeList[10].parentNode.uuid).toEqual(doc.nodeList[0].uuid);
730
- // @ts-ignore
731
- expect(doc.nodeList[10].pearNode.uuid).toEqual(doc.nodeList[6].uuid);
732
- });
733
-
734
- it('UUID', () => {
735
- const doc = parse(`
736
- <!DOCTYPE html>
737
- <html lang="en">
738
- <head>
739
- <meta charset="UTF-8">
740
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
741
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
742
- <title>Document</title>
743
- </head>
744
- <body>
745
- <h1>Title</h1>
746
- </body>
747
- </html>
748
- `);
749
- // const map = nodeListToDebugMaps(doc.nodeList);
750
- // console.log(map);
751
- // console.log(doc.nodeList.map((n, i) => `${i}: ${n.uuid} ${n.raw.trim()}`));
752
-
753
- // #text ⏎
754
- expect(doc.nodeList[0].parentNode).toEqual(null);
755
- expect(doc.nodeList[0].prevNode).toEqual(null);
756
- // @ts-ignore
757
- expect(doc.nodeList[0].nextNode.uuid).toEqual(doc.nodeList[1].uuid);
758
-
759
- // Doctype <!DOCTYPE␣html>
760
- expect(doc.nodeList[1].parentNode).toEqual(null);
761
- // @ts-ignore
762
- expect(doc.nodeList[1].prevNode.uuid).toEqual(doc.nodeList[0].uuid);
763
- // @ts-ignore
764
- expect(doc.nodeList[1].nextNode.uuid).toEqual(doc.nodeList[2].uuid);
765
-
766
- // #text ⏎
767
- expect(doc.nodeList[2].parentNode).toEqual(null);
768
- // @ts-ignore
769
- expect(doc.nodeList[2].prevNode.uuid).toEqual(doc.nodeList[1].uuid);
770
- // @ts-ignore
771
- expect(doc.nodeList[2].nextNode.uuid).toEqual(doc.nodeList[3].uuid);
772
-
773
- // html <html␣lang="en">
774
- expect(doc.nodeList[3].parentNode).toEqual(null);
775
- // @ts-ignore
776
- expect(doc.nodeList[3].prevNode.uuid).toEqual(doc.nodeList[2].uuid);
777
- // @ts-ignore
778
- expect(doc.nodeList[3].nextNode.uuid).toEqual(doc.nodeList[28].uuid);
779
- // @ts-ignore
780
- expect(doc.nodeList[3].pearNode.uuid).toEqual(doc.nodeList[27].uuid);
781
-
782
- {
783
- // @ts-ignore
784
- expect(doc.nodeList[3].childNodes[0].uuid).toEqual(doc.nodeList[4].uuid);
785
- // @ts-ignore
786
- expect(doc.nodeList[3].childNodes[1].uuid).toEqual(doc.nodeList[5].uuid);
787
- // @ts-ignore
788
- expect(doc.nodeList[3].childNodes[2].uuid).toEqual(doc.nodeList[18].uuid);
789
- // @ts-ignore
790
- expect(doc.nodeList[3].childNodes[3].uuid).toEqual(doc.nodeList[19].uuid);
791
- // @ts-ignore
792
- expect(doc.nodeList[3].childNodes[4].uuid).toEqual(doc.nodeList[26].uuid);
793
- }
794
-
795
- // #text ⏎
796
- // @ts-ignore
797
- expect(doc.nodeList[4].parentNode.uuid).toEqual(doc.nodeList[3].uuid);
798
- // @ts-ignore
799
- expect(doc.nodeList[4].prevNode).toEqual(null);
800
- // @ts-ignore
801
- expect(doc.nodeList[4].nextNode.uuid).toEqual(doc.nodeList[5].uuid);
802
-
803
- // head <head>
804
- // @ts-ignore
805
- expect(doc.nodeList[5].parentNode.uuid).toEqual(doc.nodeList[3].uuid);
806
- // @ts-ignore
807
- expect(doc.nodeList[5].prevNode.uuid).toEqual(doc.nodeList[4].uuid);
808
- // @ts-ignore
809
- expect(doc.nodeList[5].nextNode.uuid).toEqual(doc.nodeList[18].uuid);
810
- // @ts-ignore
811
- expect(doc.nodeList[5].pearNode.uuid).toEqual(doc.nodeList[17].uuid);
812
-
813
- {
814
- // @ts-ignore
815
- expect(doc.nodeList[5].childNodes[0].uuid).toEqual(doc.nodeList[6].uuid);
816
- // @ts-ignore
817
- expect(doc.nodeList[5].childNodes[1].uuid).toEqual(doc.nodeList[7].uuid);
818
- // @ts-ignore
819
- expect(doc.nodeList[5].childNodes[2].uuid).toEqual(doc.nodeList[8].uuid);
820
- // @ts-ignore
821
- expect(doc.nodeList[5].childNodes[3].uuid).toEqual(doc.nodeList[9].uuid);
822
- // @ts-ignore
823
- expect(doc.nodeList[5].childNodes[4].uuid).toEqual(doc.nodeList[10].uuid);
824
- // @ts-ignore
825
- expect(doc.nodeList[5].childNodes[5].uuid).toEqual(doc.nodeList[11].uuid);
826
- // @ts-ignore
827
- expect(doc.nodeList[5].childNodes[6].uuid).toEqual(doc.nodeList[12].uuid);
828
- // @ts-ignore
829
- expect(doc.nodeList[5].childNodes[7].uuid).toEqual(doc.nodeList[13].uuid);
830
- // @ts-ignore
831
- expect(doc.nodeList[5].childNodes[8].uuid).toEqual(doc.nodeList[16].uuid);
832
- }
833
-
834
- // #text ⏎→
835
- // @ts-ignore
836
- expect(doc.nodeList[6].parentNode.uuid).toEqual(doc.nodeList[5].uuid);
837
- // @ts-ignore
838
- expect(doc.nodeList[6].prevNode).toEqual(null);
839
- // @ts-ignore
840
- expect(doc.nodeList[6].nextNode.uuid).toEqual(doc.nodeList[7].uuid);
841
-
842
- // meta <meta␣charset="UTF-8">
843
- // @ts-ignore
844
- expect(doc.nodeList[7].parentNode.uuid).toEqual(doc.nodeList[5].uuid);
845
- // @ts-ignore
846
- expect(doc.nodeList[7].prevNode.uuid).toEqual(doc.nodeList[6].uuid);
847
- // @ts-ignore
848
- expect(doc.nodeList[7].nextNode.uuid).toEqual(doc.nodeList[8].uuid);
849
- // @ts-ignore
850
- expect(doc.nodeList[7].pearNode).toEqual(null);
851
-
852
- // #text ⏎→
853
- // @ts-ignore
854
- expect(doc.nodeList[8].parentNode.uuid).toEqual(doc.nodeList[5].uuid);
855
- // @ts-ignore
856
- expect(doc.nodeList[8].prevNode.uuid).toEqual(doc.nodeList[7].uuid);
857
- // @ts-ignore
858
- expect(doc.nodeList[8].nextNode.uuid).toEqual(doc.nodeList[9].uuid);
859
-
860
- // meta <meta␣name="viewport"␣content="width=device-width,␣initial-scale=1.0">
861
- // @ts-ignore
862
- expect(doc.nodeList[9].parentNode.uuid).toEqual(doc.nodeList[5].uuid);
863
- // @ts-ignore
864
- expect(doc.nodeList[9].prevNode.uuid).toEqual(doc.nodeList[8].uuid);
865
- // @ts-ignore
866
- expect(doc.nodeList[9].nextNode.uuid).toEqual(doc.nodeList[10].uuid);
867
- // @ts-ignore
868
- expect(doc.nodeList[9].pearNode).toEqual(null);
869
-
870
- // #text ⏎→
871
- // @ts-ignore
872
- expect(doc.nodeList[10].parentNode.uuid).toEqual(doc.nodeList[5].uuid);
873
- // @ts-ignore
874
- expect(doc.nodeList[10].prevNode.uuid).toEqual(doc.nodeList[9].uuid);
875
- // @ts-ignore
876
- expect(doc.nodeList[10].nextNode.uuid).toEqual(doc.nodeList[11].uuid);
877
-
878
- // meta <meta␣http-equiv="X-UA-Compatible"␣content="ie=edge">
879
- // @ts-ignore
880
- expect(doc.nodeList[11].parentNode.uuid).toEqual(doc.nodeList[5].uuid);
881
- // @ts-ignore
882
- expect(doc.nodeList[11].prevNode.uuid).toEqual(doc.nodeList[10].uuid);
883
- // @ts-ignore
884
- expect(doc.nodeList[11].nextNode.uuid).toEqual(doc.nodeList[12].uuid);
885
- // @ts-ignore
886
- expect(doc.nodeList[11].pearNode).toEqual(null);
887
-
888
- // #text ⏎→
889
- // @ts-ignore
890
- expect(doc.nodeList[12].parentNode.uuid).toEqual(doc.nodeList[5].uuid);
891
- // @ts-ignore
892
- expect(doc.nodeList[12].prevNode.uuid).toEqual(doc.nodeList[11].uuid);
893
- // @ts-ignore
894
- expect(doc.nodeList[12].nextNode.uuid).toEqual(doc.nodeList[13].uuid);
895
-
896
- // meta <title>
897
- // @ts-ignore
898
- expect(doc.nodeList[13].parentNode.uuid).toEqual(doc.nodeList[5].uuid);
899
- // @ts-ignore
900
- expect(doc.nodeList[13].prevNode.uuid).toEqual(doc.nodeList[12].uuid);
901
- // @ts-ignore
902
- expect(doc.nodeList[13].nextNode.uuid).toEqual(doc.nodeList[16].uuid);
903
- // @ts-ignore
904
- expect(doc.nodeList[13].pearNode.uuid).toEqual(doc.nodeList[15].uuid);
905
-
906
- {
907
- // @ts-ignore
908
- expect(doc.nodeList[13].childNodes[0].uuid).toEqual(doc.nodeList[14].uuid);
909
- }
910
-
911
- // #text Document
912
- // @ts-ignore
913
- expect(doc.nodeList[14].parentNode.uuid).toEqual(doc.nodeList[13].uuid);
914
- // @ts-ignore
915
- expect(doc.nodeList[14].prevNode).toEqual(null);
916
- // @ts-ignore
917
- expect(doc.nodeList[14].nextNode).toEqual(null);
918
-
919
- // meta </title>
920
- // @ts-ignore
921
- expect(doc.nodeList[15].parentNode.uuid).toEqual(doc.nodeList[5].uuid);
922
- // @ts-ignore
923
- expect(doc.nodeList[15].prevNode.uuid).toEqual(doc.nodeList[12].uuid);
924
- // @ts-ignore
925
- expect(doc.nodeList[15].nextNode.uuid).toEqual(doc.nodeList[16].uuid);
926
- // @ts-ignore
927
- expect(doc.nodeList[15].pearNode.uuid).toEqual(doc.nodeList[13].uuid);
928
-
929
- // #text ⏎
930
- // @ts-ignore
931
- expect(doc.nodeList[16].parentNode.uuid).toEqual(doc.nodeList[5].uuid);
932
- // @ts-ignore
933
- expect(doc.nodeList[16].prevNode.uuid).toEqual(doc.nodeList[13].uuid);
934
- // @ts-ignore
935
- expect(doc.nodeList[16].nextNode).toEqual(null);
936
-
937
- // meta </head>
938
- // @ts-ignore
939
- expect(doc.nodeList[17].parentNode.uuid).toEqual(doc.nodeList[3].uuid);
940
- // @ts-ignore
941
- expect(doc.nodeList[17].prevNode.uuid).toEqual(doc.nodeList[4].uuid);
942
- // @ts-ignore
943
- expect(doc.nodeList[17].nextNode.uuid).toEqual(doc.nodeList[18].uuid);
944
- // @ts-ignore
945
- expect(doc.nodeList[17].pearNode.uuid).toEqual(doc.nodeList[5].uuid);
946
-
947
- // #text ⏎
948
- // @ts-ignore
949
- expect(doc.nodeList[18].parentNode.uuid).toEqual(doc.nodeList[3].uuid);
950
- // @ts-ignore
951
- expect(doc.nodeList[18].prevNode.uuid).toEqual(doc.nodeList[5].uuid);
952
- // @ts-ignore
953
- expect(doc.nodeList[18].nextNode.uuid).toEqual(doc.nodeList[19].uuid);
954
-
955
- // head <body>
956
- // @ts-ignore
957
- expect(doc.nodeList[19].parentNode.uuid).toEqual(doc.nodeList[3].uuid);
958
- // @ts-ignore
959
- expect(doc.nodeList[19].prevNode.uuid).toEqual(doc.nodeList[18].uuid);
960
- // @ts-ignore
961
- expect(doc.nodeList[19].nextNode.uuid).toEqual(doc.nodeList[26].uuid);
962
- // @ts-ignore
963
- expect(doc.nodeList[19].pearNode.uuid).toEqual(doc.nodeList[25].uuid);
964
-
965
- {
966
- // @ts-ignore
967
- expect(doc.nodeList[19].childNodes[0].uuid).toEqual(doc.nodeList[20].uuid);
968
- // @ts-ignore
969
- expect(doc.nodeList[19].childNodes[1].uuid).toEqual(doc.nodeList[21].uuid);
970
- // @ts-ignore
971
- expect(doc.nodeList[19].childNodes[2].uuid).toEqual(doc.nodeList[24].uuid);
972
- }
973
-
974
- // #text ⏎→
975
- // @ts-ignore
976
- expect(doc.nodeList[20].parentNode.uuid).toEqual(doc.nodeList[19].uuid);
977
- // @ts-ignore
978
- expect(doc.nodeList[20].prevNode).toEqual(null);
979
- // @ts-ignore
980
- expect(doc.nodeList[20].nextNode.uuid).toEqual(doc.nodeList[21].uuid);
981
-
982
- // head <h1>
983
- // @ts-ignore
984
- expect(doc.nodeList[21].parentNode.uuid).toEqual(doc.nodeList[19].uuid);
985
- // @ts-ignore
986
- expect(doc.nodeList[21].prevNode.uuid).toEqual(doc.nodeList[20].uuid);
987
- // @ts-ignore
988
- expect(doc.nodeList[21].nextNode.uuid).toEqual(doc.nodeList[24].uuid);
989
- // @ts-ignore
990
- expect(doc.nodeList[21].pearNode.uuid).toEqual(doc.nodeList[23].uuid);
991
-
992
- {
993
- // @ts-ignore
994
- expect(doc.nodeList[21].childNodes[0].uuid).toEqual(doc.nodeList[22].uuid);
995
- }
996
-
997
- // #text Title
998
- // @ts-ignore
999
- expect(doc.nodeList[22].parentNode.uuid).toEqual(doc.nodeList[21].uuid);
1000
- // @ts-ignore
1001
- expect(doc.nodeList[22].prevNode).toEqual(null);
1002
- // @ts-ignore
1003
- expect(doc.nodeList[22].nextNode).toEqual(null);
1004
-
1005
- // head </h1>
1006
- // @ts-ignore
1007
- expect(doc.nodeList[23].parentNode.uuid).toEqual(doc.nodeList[19].uuid);
1008
- // @ts-ignore
1009
- expect(doc.nodeList[23].prevNode.uuid).toEqual(doc.nodeList[20].uuid);
1010
- // @ts-ignore
1011
- expect(doc.nodeList[23].nextNode.uuid).toEqual(doc.nodeList[24].uuid);
1012
- // @ts-ignore
1013
- expect(doc.nodeList[23].pearNode.uuid).toEqual(doc.nodeList[21].uuid);
1014
-
1015
- // #text ⏎
1016
- // @ts-ignore
1017
- expect(doc.nodeList[24].parentNode.uuid).toEqual(doc.nodeList[19].uuid);
1018
- // @ts-ignore
1019
- expect(doc.nodeList[24].prevNode.uuid).toEqual(doc.nodeList[21].uuid);
1020
- // @ts-ignore
1021
- expect(doc.nodeList[24].nextNode).toEqual(null);
1022
-
1023
- // </body>
1024
- // @ts-ignore
1025
- expect(doc.nodeList[25].parentNode.uuid).toEqual(doc.nodeList[3].uuid);
1026
- // @ts-ignore
1027
- expect(doc.nodeList[25].prevNode.uuid).toEqual(doc.nodeList[18].uuid);
1028
- // @ts-ignore
1029
- expect(doc.nodeList[25].nextNode.uuid).toEqual(doc.nodeList[26].uuid);
1030
- // @ts-ignore
1031
- expect(doc.nodeList[25].pearNode.uuid).toEqual(doc.nodeList[19].uuid);
1032
-
1033
- // #text ⏎
1034
- // @ts-ignore
1035
- expect(doc.nodeList[26].parentNode.uuid).toEqual(doc.nodeList[3].uuid);
1036
- // @ts-ignore
1037
- expect(doc.nodeList[26].prevNode.uuid).toEqual(doc.nodeList[25].uuid);
1038
- // @ts-ignore
1039
- expect(doc.nodeList[26].nextNode).toEqual(null);
1040
-
1041
- // </html>
1042
- expect(doc.nodeList[27].parentNode).toEqual(null);
1043
- // @ts-ignore
1044
- expect(doc.nodeList[27].prevNode.uuid).toEqual(doc.nodeList[2].uuid);
1045
- // @ts-ignore
1046
- expect(doc.nodeList[27].nextNode.uuid).toEqual(doc.nodeList[28].uuid);
1047
- // @ts-ignore
1048
- expect(doc.nodeList[27].pearNode.uuid).toEqual(doc.nodeList[3].uuid);
1049
-
1050
- // #text ⏎
1051
- // @ts-ignore
1052
- expect(doc.nodeList[28].parentNode).toEqual(null);
1053
- // @ts-ignore
1054
- expect(doc.nodeList[28].prevNode.uuid).toEqual(doc.nodeList[27].uuid);
1055
- // @ts-ignore
1056
- expect(doc.nodeList[28].nextNode).toEqual(null);
1057
- });
1058
-
1059
- it('UUID', () => {
1060
- const doc = parse(`<html>
1061
- <body></body>
1062
- </html>`);
1063
- // const map = nodeListToDebugMaps(doc.nodeList);
1064
- // console.log(map);
1065
-
1066
- // @ts-ignore
1067
- expect(doc.nodeList[3].nextNode.uuid).toEqual(doc.nodeList[5].uuid);
1068
- // @ts-ignore
1069
- expect(doc.nodeList[4].nextNode.uuid).toEqual(doc.nodeList[5].uuid);
1070
- });
1071
-
1072
- it('Offset', () => {
1073
- const doc = parse(
1074
- `<span>
1075
- <img src="path/to">
1076
- </span>
1077
- `,
1078
- {
1079
- offsetOffset: 15,
1080
- offsetLine: 2,
1081
- offsetColumn: 2,
1082
- },
1083
- );
1084
- const map = nodeListToDebugMaps(doc.nodeList);
1085
- expect(map).toStrictEqual([
1086
- '[3:3]>[3:9](15,21)span: <span>',
1087
- '[3:9]>[4:4](21,25)#text: ⏎→→→',
1088
- '[4:4]>[4:25](25,44)img: <img␣src="path/to">',
1089
- '[4:23]>[5:3](44,47)#text: ⏎→→',
1090
- '[5:3]>[5:10](47,54)span: </span>',
1091
- '[5:10]>[6:4](54,58)#text: ⏎→→→',
1092
- ]);
1093
-
1094
- // @ts-ignore
1095
- expect(doc.nodeList[2].attributes[0].startOffset).toBe(30);
1096
- // @ts-ignore
1097
- expect(doc.nodeList[2].attributes[0].endOffset).toBe(43);
1098
- // @ts-ignore
1099
- expect(doc.nodeList[2].attributes[0].startLine).toBe(4);
1100
- // @ts-ignore
1101
- expect(doc.nodeList[2].attributes[0].endLine).toBe(4);
1102
- // @ts-ignore
1103
- expect(doc.nodeList[2].attributes[0].startCol).toBe(9);
1104
- // @ts-ignore
1105
- expect(doc.nodeList[2].attributes[0].endCol).toBe(22);
1106
- });
1107
-
1108
- it('The fragment tree', () => {
1109
- const doc = parse('<audio><source media="print"></audio>');
1110
- // const map = nodeListToDebugMaps(doc.nodeList);
1111
- // console.log(map);
1112
-
1113
- expect(doc.nodeList[0].parentNode).toEqual(null);
1114
- expect(doc.nodeList[1].parentNode.parentNode).toEqual(null);
1115
- });
1116
-
1117
- it('code in script', () => {
1118
- const doc = parse("<script>const $span = '<span>text</span>';</script>");
1119
- const map = nodeListToDebugMaps(doc.nodeList);
1120
- expect(doc.unknownParseError).toBeUndefined();
1121
- expect(map).toStrictEqual([
1122
- '[1:1]>[1:9](0,8)script: <script>',
1123
- "[1:9]>[1:43](8,42)#text: const␣$span␣=␣'<span>text</span>';",
1124
- '[1:43]>[1:52](42,51)script: </script>',
1125
- ]);
1126
- });
1127
-
1128
- it('With frontmatter', () => {
1129
- const doc = parse('===\np: v\n===\n<html></html>', { ignoreFrontMatter: true });
1130
- expect(doc.nodeList[0].nodeName).toBe('html');
1131
-
1132
- const doc2 = parse('===\np: v\n===\n<html></html>', { ignoreFrontMatter: false });
1133
- expect(doc2.nodeList[0].nodeName).toBe('html');
1134
- expect(doc2.nodeList[0].isGhost).toBe(true);
1135
-
1136
- const doc3 = parse('===\np: v\n===\n<div></div>', { ignoreFrontMatter: true });
1137
- expect(doc3.nodeList[0].nodeName).toBe('#text');
1138
- expect(doc3.nodeList[1].nodeName).toBe('div');
1139
-
1140
- const doc4 = parse('===\np: v\n===\n<div></div>', { ignoreFrontMatter: false });
1141
- expect(doc4.nodeList[0].nodeName).toBe('#text');
1142
- expect(doc4.nodeList[1].nodeName).toBe('div');
1143
- });
1144
-
1145
- it('Static attribute', () => {
1146
- const ast = parse('<a href=""/>');
1147
- // @ts-ignore
1148
- const attrMaps = attributesToDebugMaps(ast.nodeList[0].attributes);
1149
- expect(attrMaps).toStrictEqual([
1150
- [
1151
- '[1:4]>[1:11](3,10)href: href=""',
1152
- ' [1:3]>[1:4](2,3)bN: ␣',
1153
- ' [1:4]>[1:8](3,7)name: href',
1154
- ' [1:8]>[1:8](7,7)bE: ',
1155
- ' [1:8]>[1:9](7,8)equal: =',
1156
- ' [1:9]>[1:9](8,8)aE: ',
1157
- ' [1:9]>[1:10](8,9)sQ: "',
1158
- ' [1:10]>[1:10](9,9)value: ',
1159
- ' [1:10]>[1:11](9,10)eQ: "',
1160
- ' isDirective: false',
1161
- ' isDynamicValue: false',
1162
- ],
1163
- ]);
1164
- });
1165
-
1166
- it('svg', () => {
1167
- const doc = parse(`<div>
1168
- <svg>
1169
- <a></a>
1170
- <switch>
1171
- <g>
1172
- <rect />
1173
- </g>
1174
- <foreignObject>
1175
- <div></div>
1176
- </foreignObject>
1177
- </switch>
1178
- </svg>
1179
- </div>
1180
- `);
1181
- const map = nodeListToDebugMaps(doc.nodeList);
1182
- expect(map).toStrictEqual([
1183
- '[1:1]>[1:6](0,5)div: <div>',
1184
- '[1:6]>[2:2](5,7)#text: ⏎→',
1185
- '[2:2]>[2:7](7,12)svg: <svg>',
1186
- '[2:7]>[3:3](12,15)#text: ⏎→→',
1187
- '[3:3]>[3:6](15,18)a: <a>',
1188
- '[3:6]>[3:10](18,22)a: </a>',
1189
- '[3:10]>[4:3](22,25)#text: ⏎→→',
1190
- '[4:3]>[4:11](25,33)switch: <switch>',
1191
- '[4:11]>[5:4](33,37)#text: ⏎→→→',
1192
- '[5:4]>[5:7](37,40)g: <g>',
1193
- '[5:7]>[6:5](40,45)#text: ⏎→→→→',
1194
- '[6:5]>[6:13](45,53)rect: <rect␣/>',
1195
- '[6:13]>[7:4](53,57)#text: ⏎→→→',
1196
- '[7:4]>[7:8](57,61)g: </g>',
1197
- '[7:8]>[8:4](61,65)#text: ⏎→→→',
1198
- '[8:4]>[8:19](65,80)foreignObject: <foreignObject>',
1199
- '[8:19]>[9:5](80,85)#text: ⏎→→→→',
1200
- '[9:5]>[9:10](85,90)div: <div>',
1201
- '[9:10]>[9:16](90,96)div: </div>',
1202
- '[9:16]>[10:4](96,100)#text: ⏎→→→',
1203
- '[10:4]>[10:20](100,116)foreignObject: </foreignObject>',
1204
- '[10:20]>[11:3](116,119)#text: ⏎→→',
1205
- '[11:3]>[11:12](119,128)switch: </switch>',
1206
- '[11:12]>[12:2](128,130)#text: ⏎→',
1207
- '[12:2]>[12:8](130,136)svg: </svg>',
1208
- '[12:8]>[13:1](136,137)#text: ⏎',
1209
- '[13:1]>[13:7](137,143)div: </div>',
1210
- '[13:7]>[14:1](143,144)#text: ⏎',
1211
- ]);
1212
- });
1213
- });
1214
-
1215
- describe('Issues', () => {
1216
- test('#775', () => {
1217
- expect(nodeListToDebugMaps(parse('<pre>text</pre>').nodeList)).toStrictEqual([
1218
- '[1:1]>[1:6](0,5)pre: <pre>',
1219
- '[1:6]>[1:10](5,9)#text: text',
1220
- '[1:10]>[1:16](9,15)pre: </pre>',
1221
- ]);
1222
-
1223
- const nodes = parse('<pre>\ntext</pre>').nodeList;
1224
-
1225
- expect(nodeListToDebugMaps(nodes)).toStrictEqual([
1226
- '[1:1]>[1:6](0,5)pre: <pre>',
1227
- '[1:6]>[2:5](5,10)#text: ⏎text',
1228
- '[2:5]>[2:11](10,16)pre: </pre>',
1229
- ]);
1230
-
1231
- expect(nodes[0].childNodes?.[0]?.raw).toBe('\ntext');
1232
-
1233
- /**
1234
- * Test for `<textarea>`
1235
- *
1236
- * @see https://html.spec.whatwg.org/multipage/syntax.html#element-restrictions
1237
- */
1238
- const textarea = parse('<textarea>\ntext</textarea>').nodeList;
1239
- expect(nodeListToDebugMaps(textarea)).toStrictEqual([
1240
- '[1:1]>[1:11](0,10)textarea: <textarea>',
1241
- '[1:11]>[2:5](10,15)#text: ⏎text',
1242
- '[2:5]>[2:16](15,26)textarea: </textarea>',
1243
- ]);
1244
- expect(textarea[0].childNodes?.[0]?.raw).toBe('\ntext');
1245
- });
1246
- });