11import { Parser , ParserOptions } from 'htmlparser2' ;
2- import { Directive , Node , NodeTag , Options , Attributes } from '../types/index.d' ;
32import { LocationTracker } from './location-tracker' ;
43
4+ export type Directive = {
5+ name : string | RegExp ;
6+ start : string ;
7+ end : string ;
8+ } ;
9+
10+ export type Options = {
11+ directives ?: Directive [ ] ;
12+ sourceLocations ?: boolean ;
13+ } & ParserOptions ;
14+
15+ export type Tag = string | boolean ;
16+ export type Attributes = Record < string , string | number | boolean > ;
17+ // export type Content = NodeText | Node[] | Node[][];
18+ export type Content = NodeText | ( Node | Node [ ] ) [ ] ;
19+
20+ export type NodeText = string | number ;
21+ export type NodeTag = {
22+ tag ?: Tag ;
23+ attrs ?: Attributes ;
24+ content ?: Content ;
25+ location ?: SourceLocation ;
26+ } ;
27+
28+ export type Node = NodeText | NodeTag ;
29+
30+ export type SourceLocation = {
31+ start : Position ;
32+ end : Position ;
33+ } ;
34+
35+ export type Position = {
36+ line : number ;
37+ column : number ;
38+ } ;
39+
540const defaultOptions : ParserOptions = {
641 lowerCaseTags : false ,
742 lowerCaseAttributeNames : false ,
@@ -25,6 +60,25 @@ const parser = (html: string, options: Options = {}): Node[] => {
2560 return bufArray [ bufArray . length - 1 ] ;
2661 }
2762
63+ function resolveContent ( text : NodeText ) : void {
64+ const last = bufferArrayLast ( ) ;
65+
66+ if ( last === undefined ) {
67+ results . push ( text ) ;
68+ return ;
69+ }
70+
71+ if ( typeof last === 'object' ) {
72+ if ( last . content === undefined ) {
73+ last . content = [ ] ;
74+ }
75+
76+ if ( Array . isArray ( last . content ) ) {
77+ last . content . push ( text ) ;
78+ }
79+ }
80+ }
81+
2882 function isDirective ( directive : Directive , tag : string ) : boolean {
2983 if ( directive . name instanceof RegExp ) {
3084 const regex = new RegExp ( directive . name . source , 'i' ) ;
@@ -53,44 +107,20 @@ const parser = (html: string, options: Options = {}): Node[] => {
53107
54108 function onprocessinginstruction ( name : string , data : string ) {
55109 const directives = defaultDirectives . concat ( options . directives ?? [ ] ) ;
56- const last : Node = bufferArrayLast ( ) ;
57110
58111 for ( const directive of directives ) {
59112 const directiveText = directive . start + data + directive . end ;
60113
61114 if ( isDirective ( directive , name . toLowerCase ( ) ) ) {
62- if ( last === undefined ) {
63- results . push ( directiveText ) ;
64- return ;
65- }
66-
67- if ( typeof last === 'object' ) {
68- if ( last . content === undefined ) {
69- last . content = [ ] ;
70- }
71-
72- last . content . push ( directiveText ) ;
73- }
115+ resolveContent ( directiveText ) ;
74116 }
75117 }
76118 }
77119
78120 function oncomment ( data : string ) {
79121 const comment = `<!--${ data } -->` ;
80- const last = bufferArrayLast ( ) ;
81-
82- if ( last === undefined ) {
83- results . push ( comment ) ;
84- return ;
85- }
86122
87- if ( typeof last === 'object' ) {
88- if ( last . content === undefined ) {
89- last . content = [ ] ;
90- }
91-
92- last . content . push ( comment ) ;
93- }
123+ resolveContent ( comment ) ;
94124 }
95125
96126 function onopentag ( tag : string , attrs : Attributes ) {
@@ -131,7 +161,9 @@ const parser = (html: string, options: Options = {}): Node[] => {
131161 last . content = [ ] ;
132162 }
133163
134- last . content . push ( buf ) ;
164+ if ( Array . isArray ( last . content ) ) {
165+ last . content . push ( buf ) ;
166+ }
135167 }
136168 }
137169 }
@@ -145,7 +177,7 @@ const parser = (html: string, options: Options = {}): Node[] => {
145177 }
146178
147179 if ( typeof last === 'object' ) {
148- if ( last . content && last . content . length > 0 ) {
180+ if ( last . content && Array . isArray ( last . content ) && last . content . length > 0 ) {
149181 const lastContentNode = last . content [ last . content . length - 1 ] ;
150182 if ( typeof lastContentNode === 'string' && ! lastContentNode . startsWith ( '<!--' ) ) {
151183 last . content [ last . content . length - 1 ] = `${ lastContentNode } ${ text } ` ;
@@ -156,8 +188,9 @@ const parser = (html: string, options: Options = {}): Node[] => {
156188 if ( last . content === undefined ) {
157189 last . content = [ ] ;
158190 }
159-
160- last . content . push ( text ) ;
191+ if ( Array . isArray ( last . content ) ) {
192+ last . content . push ( text ) ;
193+ }
161194 }
162195 }
163196
0 commit comments