@@ -17,8 +17,13 @@ interface HtmlTag {
17
17
/**
18
18
* Something like the DOCTYPE for the document, or comments.
19
19
*/
20
- interface HtmlDeclaration {
21
- type : 'declaration' ;
20
+ interface HtmlDoctype {
21
+ type : 'doctype' ;
22
+ content : string ;
23
+ }
24
+
25
+ interface HtmlComment {
26
+ type : 'comment' ;
22
27
content : string ;
23
28
}
24
29
@@ -27,7 +32,7 @@ interface HtmlText {
27
32
content : string ;
28
33
}
29
34
30
- type HtmlNode = HtmlTag | HtmlDeclaration | HtmlText ;
35
+ type HtmlNode = HtmlTag | HtmlDoctype | HtmlComment | HtmlText ;
31
36
32
37
export const lenientParse = ( html : string ) : HtmlNode [ ] => {
33
38
const result : HtmlNode [ ] = [ ] ;
@@ -59,19 +64,33 @@ export const lenientParse = (html: string): HtmlNode[] => {
59
64
index = htmlObjectStart ;
60
65
}
61
66
62
- if ( html . startsWith ( '<!' , index ) ) {
63
- // an HTML declaration, i.e. a comment or a DOCTYPE
64
- const declEnd = html . indexOf ( '>' , index + 2 ) ;
67
+ if ( html . startsWith ( '<!--' , index ) ) {
68
+ const commentEnd = html . indexOf ( '-->' , index + '<!--' . length ) ;
69
+ if ( commentEnd === - 1 ) {
70
+ // Assumes the rest of the document is part of this comment
71
+ const content = html . slice ( index + '<!--' . length ) ;
72
+ addToTree ( { type : 'comment' , content } ) ;
73
+ break ;
74
+ }
75
+
76
+ const content = html . substring ( index + '<!--' . length , commentEnd ) ;
77
+ addToTree ( { type : 'comment' , content } ) ;
78
+ index = commentEnd + '-->' . length ;
79
+ continue ;
80
+ }
81
+
82
+ if ( html . startsWith ( '<!DOCTYPE' , index ) ) {
83
+ const declEnd = html . indexOf ( '>' , index + '<!DOCTYPE' . length ) ;
65
84
if ( declEnd === - 1 ) {
66
- // Assumes the rest of the document is part of this declaration
67
- const content = html . slice ( index ) ;
68
- addToTree ( { type : 'declaration ' , content } ) ;
85
+ // Assumes the rest of the document is part of this doctype
86
+ const content = html . slice ( index + '<!DOCTYPE' . length ) ;
87
+ addToTree ( { type : 'doctype ' , content } ) ;
69
88
break ;
70
89
}
71
90
72
- const content = html . substring ( index , declEnd + 1 ) ;
73
- addToTree ( { type : 'declaration ' , content } ) ;
74
- index = declEnd + 1 ;
91
+ const content = html . substring ( index + '<!DOCTYPE' . length , declEnd ) ;
92
+ addToTree ( { type : 'doctype ' , content } ) ;
93
+ index = declEnd + '>' . length ;
75
94
continue ;
76
95
}
77
96
@@ -270,8 +289,10 @@ const prettyNodes = (
270
289
271
290
formatted += `</${ node . name } >${ lineBreak } ` ;
272
291
}
273
- } else if ( node . type === 'declaration' ) {
274
- formatted += `${ indentation } ${ node . content } ${ lineBreak } ` ;
292
+ } else if ( node . type === 'comment' ) {
293
+ formatted += `${ indentation } <!--${ node . content } -->${ lineBreak } ` ;
294
+ } else if ( node . type === 'doctype' ) {
295
+ formatted += `${ indentation } <!DOCTYPE${ node . content } >${ lineBreak } ` ;
275
296
}
276
297
}
277
298
return formatted ;
0 commit comments