@@ -32,6 +32,8 @@ pub struct CodegenConfig<'a> {
32
32
/// Don't print optional tags (only when `minify` enabled)
33
33
/// By default `true` when `minify` enabled, otherwise `false`
34
34
pub tag_omission : Option < bool > ,
35
+ /// Keep <head> tags and </body> closing tag when `tag_omission` is enabled
36
+ pub keep_head_and_body : Option < bool > ,
35
37
/// Making SVG and MathML elements self-closing where possible (only when
36
38
/// `minify` enabled) By default `false` when `minify` enabled,
37
39
/// otherwise `true`
58
60
// For legacy `<plaintext>`
59
61
is_plaintext : bool ,
60
62
tag_omission : bool ,
63
+ keep_head_and_body : bool ,
61
64
self_closing_void_elements : bool ,
62
65
quotes : bool ,
63
66
}
68
71
{
69
72
pub fn new ( wr : W , config : CodegenConfig < ' a > ) -> Self {
70
73
let tag_omission = config. tag_omission . unwrap_or ( config. minify ) ;
74
+ let keep_head_and_body = config. keep_head_and_body . unwrap_or ( false ) ;
71
75
let self_closing_void_elements = config. tag_omission . unwrap_or ( !config. minify ) ;
72
76
let quotes = config. quotes . unwrap_or ( !config. minify ) ;
73
77
77
81
ctx : Default :: default ( ) ,
78
82
is_plaintext : false ,
79
83
tag_omission,
84
+ keep_head_and_body,
80
85
self_closing_void_elements,
81
86
quotes,
82
87
}
@@ -227,49 +232,56 @@ where
227
232
// A head element's start tag can be omitted if the element is empty, or if the
228
233
// first thing inside the head element is an element.
229
234
"head"
230
- if n. children . is_empty ( )
231
- || matches ! ( n. children. first( ) , Some ( Child :: Element ( ..) ) ) =>
235
+ if !self . keep_head_and_body
236
+ && ( n. children . is_empty ( )
237
+ || matches ! ( n. children. first( ) , Some ( Child :: Element ( ..) ) ) ) =>
232
238
{
233
239
true
234
240
}
235
241
// A body element's start tag can be omitted if the element is empty, or if the
236
242
// first thing inside the body element is not ASCII whitespace or a comment, except
237
243
// if the first thing inside the body element would be parsed differently outside.
238
244
"body"
239
- if n. children . is_empty ( )
240
- || ( match n. children . first ( ) {
241
- Some ( Child :: Text ( text) )
242
- if !text. data . is_empty ( )
243
- && text. data . chars ( ) . next ( ) . unwrap ( ) . is_ascii_whitespace ( ) =>
244
- {
245
- false
246
- }
247
- Some ( Child :: Comment ( ..) ) => false ,
248
- Some ( Child :: Element ( Element {
249
- namespace,
250
- tag_name,
251
- ..
252
- } ) ) if * namespace == Namespace :: HTML
253
- && matches ! (
254
- & * * tag_name,
255
- "base"
256
- | "basefont"
257
- | "bgsound"
258
- | "frameset"
259
- | "link"
260
- | "meta"
261
- | "noframes"
262
- | "noscript"
263
- | "script"
264
- | "style"
265
- | "template"
266
- | "title"
267
- ) =>
268
- {
269
- false
270
- }
271
- _ => true ,
272
- } ) =>
245
+ if !self . keep_head_and_body
246
+ && ( n. children . is_empty ( )
247
+ || ( match n. children . first ( ) {
248
+ Some ( Child :: Text ( text) )
249
+ if !text. data . is_empty ( )
250
+ && text
251
+ . data
252
+ . chars ( )
253
+ . next ( )
254
+ . unwrap ( )
255
+ . is_ascii_whitespace ( ) =>
256
+ {
257
+ false
258
+ }
259
+ Some ( Child :: Comment ( ..) ) => false ,
260
+ Some ( Child :: Element ( Element {
261
+ namespace,
262
+ tag_name,
263
+ ..
264
+ } ) ) if * namespace == Namespace :: HTML
265
+ && matches ! (
266
+ & * * tag_name,
267
+ "base"
268
+ | "basefont"
269
+ | "bgsound"
270
+ | "frameset"
271
+ | "link"
272
+ | "meta"
273
+ | "noframes"
274
+ | "noscript"
275
+ | "script"
276
+ | "style"
277
+ | "template"
278
+ | "title"
279
+ ) =>
280
+ {
281
+ false
282
+ }
283
+ _ => true ,
284
+ } ) ) =>
273
285
{
274
286
true
275
287
}
@@ -432,10 +444,11 @@ where
432
444
//
433
445
// A body element's end tag can be omitted if the body element is not
434
446
// immediately followed by a comment.
435
- "html" | "body" => !matches ! ( next, Some ( Child :: Comment ( ..) ) ) ,
447
+ "html" => !matches ! ( next, Some ( Child :: Comment ( ..) ) ) ,
448
+ "body" if !self . keep_head_and_body => !matches ! ( next, Some ( Child :: Comment ( ..) ) ) ,
436
449
// A head element's end tag can be omitted if the head element is not
437
450
// immediately followed by ASCII whitespace or a comment.
438
- "head" => match next {
451
+ "head" if ! self . keep_head_and_body => match next {
439
452
Some ( Child :: Text ( text) )
440
453
if text. data . chars ( ) . next ( ) . unwrap ( ) . is_ascii_whitespace ( ) =>
441
454
{
0 commit comments