11import { assert } from 'vitest' ;
22
3- /** @param {Element } node */
4- function clean_children ( node ) {
3+ /**
4+ * @param {Element } node
5+ * @param {{ preserveComments: boolean } } opts
6+ */
7+ function clean_children ( node , opts ) {
58 let previous = null ;
9+ let has_element_children = false ;
10+ let template =
11+ node . nodeName === 'TEMPLATE' ? /** @type {HTMLTemplateElement } */ ( node ) : undefined ;
12+
13+ if ( template ) {
14+ const div = document . createElement ( 'div' ) ;
15+ div . append ( template . content ) ;
16+ node = div ;
17+ }
618
719 // sort attributes
820 const attributes = Array . from ( node . attributes ) . sort ( ( a , b ) => {
@@ -14,6 +26,10 @@ function clean_children(node) {
1426 } ) ;
1527
1628 attributes . forEach ( ( attr ) => {
29+ if ( ( attr . name === 'onload' || attr . name === 'onerror' ) && attr . value === 'this.__e=event' ) {
30+ return ;
31+ }
32+
1733 node . setAttribute ( attr . name , attr . value ) ;
1834 } ) ;
1935
@@ -27,24 +43,42 @@ function clean_children(node) {
2743 node . tagName !== 'tspan'
2844 ) {
2945 node . removeChild ( child ) ;
46+ continue ;
3047 }
3148
32- text . data = text . data . replace ( / [ \t \n \r \f ] + / g, '\n ' ) ;
49+ text . data = text . data . replace ( / [ ^ \S ] + / g, ' ' ) ;
3350
3451 if ( previous && previous . nodeType === 3 ) {
3552 const prev = /** @type {Text } */ ( previous ) ;
3653
3754 prev . data += text . data ;
38- prev . data = prev . data . replace ( / [ \t \n \r \f ] + / g, '\n' ) ;
39-
4055 node . removeChild ( text ) ;
56+
4157 text = prev ;
58+ text . data = text . data . replace ( / [ ^ \S ] + / g, ' ' ) ;
59+
60+ continue ;
4261 }
43- } else if ( child . nodeType === 8 ) {
62+ }
63+
64+ if ( child . nodeType === 8 && ! opts . preserveComments ) {
4465 // comment
45- // do nothing
46- } else {
47- clean_children ( /** @type {Element } */ ( child ) ) ;
66+ child . remove ( ) ;
67+ continue ;
68+ }
69+
70+ if ( child . nodeType === 1 || child . nodeType === 8 ) {
71+ if ( previous ?. nodeType === 3 ) {
72+ const prev = /** @type {Text } */ ( previous ) ;
73+ prev . data = prev . data . replace ( / ^ [ ^ \S ] + $ / , '\n' ) ;
74+ } else if ( previous ?. nodeType === 1 || previous ?. nodeType === 8 ) {
75+ node . insertBefore ( document . createTextNode ( '\n' ) , child ) ;
76+ }
77+
78+ if ( child . nodeType === 1 ) {
79+ has_element_children = true ;
80+ clean_children ( /** @type {Element } */ ( child ) , opts ) ;
81+ }
4882 }
4983
5084 previous = child ;
@@ -53,37 +87,35 @@ function clean_children(node) {
5387 // collapse whitespace
5488 if ( node . firstChild && node . firstChild . nodeType === 3 ) {
5589 const text = /** @type {Text } */ ( node . firstChild ) ;
56- text . data = text . data . replace ( / ^ [ \t \n \r \f ] + / , '' ) ;
57- if ( ! text . data . length ) node . removeChild ( text ) ;
90+ text . data = text . data . trimStart ( ) ;
5891 }
5992
6093 if ( node . lastChild && node . lastChild . nodeType === 3 ) {
6194 const text = /** @type {Text } */ ( node . lastChild ) ;
62- text . data = text . data . replace ( / [ \t \n \r \f ] + $ / , '' ) ;
63- if ( ! text . data . length ) node . removeChild ( text ) ;
95+ text . data = text . data . trimEnd ( ) ;
96+ }
97+
98+ if ( has_element_children && node . parentNode ) {
99+ node . innerHTML = `\n\t${ node . innerHTML . replace ( / \n / g, '\n\t' ) } \n` ;
100+ }
101+
102+ if ( template ) {
103+ template . innerHTML = node . innerHTML ;
64104 }
65105}
66106
67107/**
68108 * @param {Window } window
69109 * @param {string } html
70- * @param {{ removeDataSvelte?: boolean, preserveComments?: boolean } } param2
110+ * @param {{ preserveComments?: boolean } } opts
71111 */
72- export function normalize_html (
73- window ,
74- html ,
75- { removeDataSvelte = false , preserveComments = false }
76- ) {
112+ export function normalize_html ( window , html , { preserveComments = false } = { } ) {
77113 try {
78114 const node = window . document . createElement ( 'div' ) ;
79- node . innerHTML = html
80- . replace ( / ( < ! ( - - ) ? .* ?\2> ) / g, preserveComments ? '$1' : '' )
81- . replace ( / ( d a t a - s v e l t e - h = " [ ^ " ] + " ) / g, removeDataSvelte ? '' : '$1' )
82- . replace ( / > [ \t \n \r \f ] + < / g, '><' )
83- // Strip out the special onload/onerror hydration events from the test output
84- . replace ( / \s ? o n e r r o r = " t h i s ._ _ e = e v e n t " | \s ? o n l o a d = " t h i s ._ _ e = e v e n t " / g, '' )
85- . trim ( ) ;
86- clean_children ( node ) ;
115+
116+ node . innerHTML = html . trim ( ) ;
117+ clean_children ( node , { preserveComments } ) ;
118+
87119 return node . innerHTML ;
88120 } catch ( err ) {
89121 throw new Error ( `Failed to normalize HTML:\n${ html } \nCause: ${ err } ` ) ;
@@ -99,67 +131,52 @@ export function normalize_new_line(html) {
99131}
100132
101133/**
102- * @param {{ removeDataSvelte?: boolean } } options
134+ * @param {string } actual
135+ * @param {string } expected
136+ * @param {string } [message]
103137 */
104- export function setup_html_equal ( options = { } ) {
105- /**
106- * @param {string } actual
107- * @param {string } expected
108- * @param {string } [message]
109- */
110- const assert_html_equal = ( actual , expected , message ) => {
111- try {
112- assert . deepEqual (
113- normalize_html ( window , actual , options ) ,
114- normalize_html ( window , expected , options ) ,
115- message
116- ) ;
117- } catch ( e ) {
118- if ( Error . captureStackTrace )
119- Error . captureStackTrace ( /** @type {Error } */ ( e ) , assert_html_equal ) ;
120- throw e ;
121- }
122- } ;
123-
124- /**
125- *
126- * @param {string } actual
127- * @param {string } expected
128- * @param {{ preserveComments?: boolean, withoutNormalizeHtml?: boolean } } param2
129- * @param {string } [message]
130- */
131- const assert_html_equal_with_options = (
132- actual ,
133- expected ,
134- { preserveComments, withoutNormalizeHtml } ,
135- message
136- ) => {
137- try {
138- assert . deepEqual (
139- withoutNormalizeHtml
140- ? normalize_new_line ( actual . trim ( ) )
141- . replace ( / ( \s d a t a - s v e l t e - h = " [ ^ " ] + " ) / g, options . removeDataSvelte ? '' : '$1' )
142- . replace ( / ( < ! ( - - ) ? .* ?\2> ) / g, preserveComments !== false ? '$1' : '' )
143- : normalize_html ( window , actual . trim ( ) , { ...options , preserveComments } ) ,
144- withoutNormalizeHtml
145- ? normalize_new_line ( expected . trim ( ) )
146- . replace ( / ( \s d a t a - s v e l t e - h = " [ ^ " ] + " ) / g, options . removeDataSvelte ? '' : '$1' )
147- . replace ( / ( < ! ( - - ) ? .* ?\2> ) / g, preserveComments !== false ? '$1' : '' )
148- : normalize_html ( window , expected . trim ( ) , { ...options , preserveComments } ) ,
149- message
150- ) ;
151- } catch ( e ) {
152- if ( Error . captureStackTrace )
153- Error . captureStackTrace ( /** @type {Error } */ ( e ) , assert_html_equal_with_options ) ;
154- throw e ;
155- }
156- } ;
157-
158- return {
159- assert_html_equal,
160- assert_html_equal_with_options
161- } ;
162- }
138+ export const assert_html_equal = ( actual , expected , message ) => {
139+ try {
140+ assert . deepEqual ( normalize_html ( window , actual ) , normalize_html ( window , expected ) , message ) ;
141+ } catch ( e ) {
142+ if ( Error . captureStackTrace )
143+ Error . captureStackTrace ( /** @type {Error } */ ( e ) , assert_html_equal ) ;
144+ throw e ;
145+ }
146+ } ;
163147
164- // Common case without options
165- export const { assert_html_equal, assert_html_equal_with_options } = setup_html_equal ( ) ;
148+ /**
149+ *
150+ * @param {string } actual
151+ * @param {string } expected
152+ * @param {{ preserveComments?: boolean, withoutNormalizeHtml?: boolean } } param2
153+ * @param {string } [message]
154+ */
155+ export const assert_html_equal_with_options = (
156+ actual ,
157+ expected ,
158+ { preserveComments, withoutNormalizeHtml } ,
159+ message
160+ ) => {
161+ try {
162+ assert . deepEqual (
163+ withoutNormalizeHtml
164+ ? normalize_new_line ( actual . trim ( ) ) . replace (
165+ / ( < ! ( - - ) ? .* ?\2> ) / g,
166+ preserveComments !== false ? '$1' : ''
167+ )
168+ : normalize_html ( window , actual . trim ( ) , { preserveComments } ) ,
169+ withoutNormalizeHtml
170+ ? normalize_new_line ( expected . trim ( ) ) . replace (
171+ / ( < ! ( - - ) ? .* ?\2> ) / g,
172+ preserveComments !== false ? '$1' : ''
173+ )
174+ : normalize_html ( window , expected . trim ( ) , { preserveComments } ) ,
175+ message
176+ ) ;
177+ } catch ( e ) {
178+ if ( Error . captureStackTrace )
179+ Error . captureStackTrace ( /** @type {Error } */ ( e ) , assert_html_equal_with_options ) ;
180+ throw e ;
181+ }
182+ } ;
0 commit comments