88 * @flow
99 */
1010
11- import type {
12- Colors ,
13- Indent ,
14- PluginOptions ,
15- Print ,
16- Plugin ,
17- } from 'types/PrettyFormat' ;
11+ import type { Config , NewPlugin , Printer , Refs } from 'types/PrettyFormat' ;
1812
1913import escapeHTML from './lib/escape_html' ;
14+ import { printElement , printElementAsLeaf , printProps } from './lib/markup' ;
2015
2116type Attribute = {
2217 name : string ,
@@ -34,79 +29,63 @@ type HTMLText = {
3429 data : string ,
3530 nodeType : 3 ,
3631} ;
37-
3832type HTMLComment = {
3933 data : string ,
4034 nodeType : 8 ,
4135} ;
4236
4337const HTML_ELEMENT_REGEXP = / ( H T M L \w * ?E l e m e n t ) | T e x t | C o m m e n t / ;
44- export const test = isHTMLElement ;
45-
46- function isHTMLElement ( value : any ) {
47- return (
48- value !== undefined &&
49- value !== null &&
50- ( value . nodeType === 1 || value . nodeType === 3 || value . nodeType === 8 ) &&
51- value . constructor !== undefined &&
52- value . constructor . name !== undefined &&
53- HTML_ELEMENT_REGEXP . test ( value . constructor . name )
54- ) ;
55- }
56-
57- function printChildren ( flatChildren , print , indent , colors , opts ) {
58- return flatChildren
59- . map ( node => {
60- if ( typeof node === 'string' ) {
61- return colors . content . open + escapeHTML ( node ) + colors . content . close ;
62- } else {
63- return print ( node ) ;
64- }
65- } )
66- . filter ( value => value . trim ( ) . length )
67- . join ( opts . edgeSpacing ) ;
68- }
6938
70- function printAttributes (
71- attributes : Array < Attribute > ,
72- print ,
73- indent ,
74- colors ,
75- opts ,
76- ) {
77- return attributes
78- . sort (
79- ( attributeA , attributeB ) =>
80- attributeA . name === attributeB . name
81- ? 0
82- : attributeA . name < attributeB . name ? - 1 : 1 ,
39+ export const test = ( val : any ) =>
40+ val !== undefined &&
41+ val !== null &&
42+ ( val . nodeType === 1 || val . nodeType === 3 || val . nodeType === 8 ) &&
43+ val . constructor !== undefined &&
44+ val . constructor . name !== undefined &&
45+ HTML_ELEMENT_REGEXP . test ( val . constructor . name ) ;
46+
47+ // Return empty string if children is empty.
48+ function printChildren ( children , config , indentation , depth , refs , printer ) {
49+ const colors = config . colors ;
50+ return children
51+ . map (
52+ node =>
53+ typeof node === 'string'
54+ ? colors . content . open + escapeHTML ( node ) + colors . content . close
55+ : printer ( node , config , indentation , depth , refs ) ,
8356 )
84- . map ( attribute => {
85- return (
86- opts . spacing +
87- indent ( colors . prop . open + attribute . name + colors . prop . close + '=' ) +
88- colors . value . open +
89- print ( attribute . value ) +
90- colors . value . close
91- ) ;
92- } )
57+ . filter ( value => value . trim ( ) . length )
58+ . map ( value => config . spacingOuter + indentation + value )
9359 . join ( '' ) ;
9460}
9561
96- export const print = (
62+ const getType = element => element . tagName . toLowerCase ( ) ;
63+
64+ // Convert array of attribute objects to keys array and props object.
65+ const keysMapper = attribute => attribute . name ;
66+ const propsReducer = ( props , attribute ) => {
67+ props [ attribute . name ] = attribute . value ;
68+ return props ;
69+ } ;
70+
71+ export const serialize = (
9772 element : HTMLElement | HTMLText | HTMLComment ,
98- print : Print ,
99- indent : Indent ,
100- opts : PluginOptions ,
101- colors : Colors ,
73+ config : Config ,
74+ indentation : string ,
75+ depth : number ,
76+ refs : Refs ,
77+ printer : Printer ,
10278) : string => {
10379 if ( element . nodeType === 3 ) {
10480 return element . data
10581 . split ( '\n' )
10682 . map ( text => text . trimLeft ( ) )
10783 . filter ( text => text . length )
10884 . join ( ' ' ) ;
109- } else if ( element . nodeType === 8 ) {
85+ }
86+
87+ const colors = config . colors ;
88+ if ( element . nodeType === 8 ) {
11089 return (
11190 colors . comment . open +
11291 '<!-- ' +
@@ -116,43 +95,32 @@ export const print = (
11695 ) ;
11796 }
11897
119- let result = colors . tag . open + '<' ;
120- const elementName = element . tagName . toLowerCase ( ) ;
121- result += elementName + colors . tag . close ;
122-
123- const hasAttributes = element . attributes && element . attributes . length ;
124- if ( hasAttributes ) {
125- const attributes = Array . prototype . slice . call ( element . attributes ) ;
126- result += printAttributes ( attributes , print , indent , colors , opts ) ;
127- }
128-
129- const flatChildren = Array . prototype . slice . call ( element . childNodes ) ;
130- if ( ! flatChildren . length && element . textContent ) {
131- flatChildren . push ( element . textContent ) ;
98+ if ( ++ depth > config . maxDepth ) {
99+ return printElementAsLeaf ( getType ( element ) , config ) ;
132100 }
133101
134- const closeInNewLine = hasAttributes && ! opts . min ;
135- if ( flatChildren . length ) {
136- const children = printChildren ( flatChildren , print , indent , colors , opts ) ;
137- result +=
138- colors . tag . open +
139- ( closeInNewLine ? '\n' : '' ) +
140- '>' +
141- colors . tag . close +
142- opts . edgeSpacing +
143- indent ( children ) +
144- opts . edgeSpacing +
145- colors . tag . open +
146- '</' +
147- elementName +
148- '>' +
149- colors . tag . close ;
150- } else {
151- result +=
152- colors . tag . open + ( closeInNewLine ? '\n' : ' ' ) + '/>' + colors . tag . close ;
153- }
154-
155- return result ;
102+ return printElement (
103+ getType ( element ) ,
104+ printProps (
105+ Array . prototype . map . call ( element . attributes , keysMapper ) . sort ( ) ,
106+ Array . prototype . reduce . call ( element . attributes , propsReducer , { } ) ,
107+ config ,
108+ indentation + config . indent ,
109+ depth ,
110+ refs ,
111+ printer ,
112+ ) ,
113+ printChildren (
114+ Array . prototype . slice . call ( element . childNodes ) ,
115+ config ,
116+ indentation + config . indent ,
117+ depth ,
118+ refs ,
119+ printer ,
120+ ) ,
121+ config ,
122+ indentation ,
123+ ) ;
156124} ;
157125
158- export default ( { print , test} : Plugin ) ;
126+ export default ( { serialize , test} : NewPlugin ) ;
0 commit comments