@@ -90,100 +90,80 @@ function getAttributes(
9090 *
9191 * @param {array } styleElements
9292 */
93- function getStyleContents ( styleElements : IHtmlNode [ ] ) : IHtmlNode [ ] {
94- return styleElements . map ( ( element : IHtmlNode ) => {
95- const styleContents = element . children
96- . filter ( ( x : IHtmlNode ) => ( x . type = 'text' ) )
97- . map ( ( x : IHtmlNode ) => x . content )
98- . join ( '' )
99-
100- return < IHtmlNode > ( < unknown > {
101- tagName : 'style' ,
102- text : 'STYLE' ,
103- filterAttributes : {
104- style : styleContents ,
105- } ,
106- } )
93+ function getStyleContents ( element : IHtmlNode ) : IHtmlNode {
94+ return < IHtmlNode > ( < unknown > {
95+ tagName : 'style' ,
96+ text : 'STYLE' ,
97+ filterAttributes : {
98+ style : element . content ,
99+ } ,
107100 } )
108101}
109102
103+ let styles : IHtmlNode [ ] = [ ]
104+
110105/**
111106 * Filter IHtmlNode array by node type and tagName
112107 *
113108 * @param {string } htmlJson
114109 *
115110 * @returns Object
116111 */
117- function filterHtmlData (
118- htmlJson : IHtmlNode [ ] | IHtmlNode ,
119- nestedOrder = 1
120- ) : IHtmlNode [ ] | null {
121- if ( htmlJson && Array . isArray ( htmlJson ) ) {
122- const parentNode = htmlJson . filter (
123- ( x : IHtmlNode ) =>
124- ( x . type == 'element' || x . type == 'comment' ) && x . tagName != 'style'
125- ) ,
126- styleElements = htmlJson . filter ( ( x ) => x . tagName == 'style' )
127-
128- let styleList : IHtmlNode [ ] = [ ]
129-
130- if ( styleElements && styleElements . length ) {
131- styleList = getStyleContents ( styleElements )
132- }
112+ function filterHtmlData ( nodeTree : IHtmlNode [ ] , deepth = 0 ) : IHtmlNode [ ] {
113+ if ( nodeTree . length > 0 ) {
114+ // we do need to empty or doctype declaration
115+ nodeTree = nodeTree . filter (
116+ ( x : IHtmlNode ) => x . content !== ' ' && x . tagName != '!doctype'
117+ )
133118
134- if ( parentNode && parentNode . length ) {
119+ if ( nodeTree && nodeTree . length ) {
135120 const elementList : IHtmlNode [ ] | null = [ ]
136121
137- parentNode . forEach ( ( node : IHtmlNode ) => {
138- if ( Array . isArray ( node . children ) ) {
139- // find previous comment
140- for ( let i = 0 ; i < parentNode . length ; i ++ ) {
141- if ( parentNode [ i ] == node ) {
142- const _node = parentNode [ i - 1 ]
143-
144- if ( node ) {
145- node . comment =
146- _node && _node . type == 'comment' && _node . content
147- ? Utils . cleanText ( _node . content , true )
148- : null
149- }
150-
151- break
152- }
122+ nodeTree . forEach ( ( node : IHtmlNode , index ) => {
123+ if ( node . type == 'element' ) {
124+ if ( node . tagName == 'style' ) {
125+ styles . push ( getStyleContents ( node ) )
126+ } else {
127+ node . filterAttributes = getAttributes ( node . attributes , [
128+ 'class' ,
129+ 'style' ,
130+ ] )
153131 }
154132
155- node . order = nestedOrder
156-
157- const children : IHtmlNode [ ] | null = filterHtmlData (
158- node . children ,
159- nestedOrder + 1
160- )
133+ // find element's comment in previous node
134+ node . comment =
135+ nodeTree [ index - 1 ] && nodeTree [ index - 1 ] . type == 'comment'
136+ ? Utils . cleanText ( nodeTree [ index - 1 ] . content , true )
137+ : null
138+ }
161139
162- if ( children && children . length ) {
163- node . children = children . filter (
164- ( x : IHtmlNode ) => x . type == 'element'
165- )
166- }
140+ // allow only html elements and texts
141+ if ( node . type != 'comment' && node . tagName !== 'style' ) {
142+ elementList . push ( node )
167143 }
168144
169- // get only class and inline style attributes
170- node . filterAttributes = getAttributes ( node . attributes , [
171- 'class' ,
172- 'style' ,
173- ] )
145+ // let's go deeper
146+ if ( Array . isArray ( node . children ) && node . children . length > 0 ) {
147+ node . order = ++ deepth
174148
175- if ( node . filterAttributes !== null || node . children !== null ) {
176- elementList ?. push ( node )
149+ const childNodes : IHtmlNode [ ] = filterHtmlData ( node . children , deepth )
150+
151+ if ( childNodes && childNodes . length ) {
152+ node . children = childNodes . filter (
153+ ( x : IHtmlNode ) => x . tagName != 'style' && x . type != 'comment'
154+ )
155+
156+ node . hasElementChildren =
157+ node . children . filter ( ( x ) => x . type == 'element' ) . length > 0
158+ }
177159 }
178160 } )
179161
180- if ( elementList && elementList . length ) {
181- return [ ...styleList , ...elementList ]
182- }
162+ return nodeTree
183163 }
184164 }
185165
186- return null
166+ return [ ]
187167}
188168
189169/**
@@ -197,6 +177,8 @@ function filterHtmlData(
197177function getClassName ( node : IHtmlNode , deepth : number ) : string {
198178 let className = ''
199179
180+ const exceptTagNames = [ 'html' , 'head' , 'body' , 'style' ]
181+
200182 if ( node . comment && _defaultOptions . useCommentBlocksAsClassName ) {
201183 let classSlug = _defaultOptions . classNameOptions . prefix
202184
@@ -213,7 +195,11 @@ function getClassName(node: IHtmlNode, deepth: number): string {
213195 classSlug += _defaultOptions . classNameOptions . suffix
214196
215197 className = '.' + classSlug
216- } else if ( node . tagName != 'div' ) {
198+ } else if (
199+ exceptTagNames . indexOf ( node . tagName ) > - 1 ||
200+ ( ! node . hasElementChildren && node . tagName != 'div' )
201+ ) {
202+ // TODO: add excape option for tag names
217203 className = `${ node . tagName } `
218204 } else {
219205 className = `.class-${ node . tagName } -${ deepth } `
@@ -243,10 +229,6 @@ function getSassTree(nodeTree: IHtmlNode[] | IHtmlNode, deepth = 0) {
243229 let treeString = '' ,
244230 subTreeString = ''
245231
246- if ( node . filterAttributes === null && node . children === null ) {
247- return ''
248- }
249-
250232 if ( Array . isArray ( node . children ) && node . children . length ) {
251233 ++ deepth
252234 subTreeString = getSassTree ( node , deepth )
@@ -311,16 +293,11 @@ function getSassTree(nodeTree: IHtmlNode[] | IHtmlNode, deepth = 0) {
311293 */
312294function getHtmlTree ( nodeTree : IHtmlNode [ ] , deepth = 0 ) : string {
313295 if ( nodeTree ) {
314- if ( ! Array . isArray ( nodeTree ) ) {
315- // nodeTree = nodeTree.children
316- }
317-
318296 let htmlTree = ''
319297
320298 nodeTree . forEach ( function ( node : IHtmlNode , index ) {
299+ const className = getClassName ( node , deepth )
321300 if ( node . type == 'element' ) {
322- const className = getClassName ( node , deepth )
323-
324301 if ( _defaultOptions . printComments ) {
325302 if ( node . comment ) {
326303 htmlTree += `\n<!-- ${ node . comment . trim ( ) } -->`
@@ -352,10 +329,16 @@ function getHtmlTree(nodeTree: IHtmlNode[], deepth = 0): string {
352329 } >`
353330 }
354331
355- const innerText = node . children
356- ?. filter ( ( child ) => child . type === 'text' )
357- . map ( ( child ) => child . content )
358- . join ( '' )
332+ // inner text
333+
334+ const textChildNodes = node . children ?. filter (
335+ ( child ) => child . type === 'text'
336+ )
337+
338+ const innerText =
339+ node . children ?. length == textChildNodes ?. length
340+ ? textChildNodes . map ( ( child ) => child . content ) . join ( '' )
341+ : ''
359342
360343 // inner text
361344 htmlTree += innerText ? `\n${ innerText } \n` : ''
@@ -381,6 +364,9 @@ function getHtmlTree(nodeTree: IHtmlNode[], deepth = 0): string {
381364 htmlTree +=
382365 ( ! isVoidElement ? `</${ node . tagName } >` : '' ) +
383366 ( ! isNextNodeSibling ? '\n' : '' )
367+ } else if ( node . type == 'text' ) {
368+ // inner text
369+ htmlTree += node . content ? `\n${ node . content } \n` : ''
384370 }
385371 } )
386372
@@ -402,6 +388,8 @@ export function convertToSass(
402388 html : string ,
403389 options : ITwToSassOptions | null = defaultOptions
404390) : null | IConverterResult {
391+ styles = [ ]
392+
405393 if ( html && html . length ) {
406394 if ( options ) {
407395 _defaultOptions = {
@@ -412,7 +400,7 @@ export function convertToSass(
412400
413401 html = Utils . cleanText ( html )
414402
415- const htmlJson : IHtmlNode [ ] | IHtmlNode = parse ( html )
403+ const htmlJson : IHtmlNode [ ] = parse ( html )
416404
417405 const filteredHtmlData = filterHtmlData ( htmlJson )
418406
0 commit comments