@@ -5,7 +5,7 @@ import { minify as terser } from 'terser';
5
5
6
6
import { HTMLParser , endTag } from './htmlparser.js' ;
7
7
import TokenChain from './tokenchain.js' ;
8
- import { createMapFromString , createMap , replaceAsync } from './utils.js' ;
8
+ import { replaceAsync } from './utils.js' ;
9
9
10
10
function trimWhitespace ( str ) {
11
11
return str && str . replace ( / ^ [ \n \r \t \f ] + / , '' ) . replace ( / [ \n \r \t \f ] + $ / , '' ) ;
@@ -62,20 +62,20 @@ function collapseWhitespace(str, options, trimLeft, trimRight, collapseAll) {
62
62
}
63
63
64
64
// non-empty tags that will maintain whitespace around them
65
- const inlineTags = createMapFromString ( 'a, abbr, acronym,b, bdi, bdo, big, button, cite, code, del, dfn,em, font,i, ins, kbd, label, mark, math, nobr, object,q,rp,rt, rtc, ruby,s, samp, select, small, span, strike, strong, sub, sup, svg, textarea, time,tt,u, var') ;
65
+ const inlineTags = new Set ( [ 'a' , ' abbr' , ' acronym' , 'b' , ' bdi' , ' bdo' , ' big' , ' button' , ' cite' , ' code' , ' del' , ' dfn' , 'em' , ' font' , 'i' , ' ins' , ' kbd' , ' label' , ' mark' , ' math' , ' nobr' , ' object' , 'q' , 'rp' , 'rt' , ' rtc' , ' ruby' , 's' , ' samp' , ' select' , ' small' , ' span' , ' strike' , ' strong' , ' sub' , ' sup' , ' svg' , ' textarea' , ' time' , 'tt' , 'u' , ' var'] ) ;
66
66
// non-empty tags that will maintain whitespace within them
67
- const inlineTextTags = createMapFromString ( 'a, abbr, acronym,b, big, del,em, font,i, ins, kbd, mark, nobr,rp,s, samp, small, span, strike, strong, sub, sup, time,tt,u, var') ;
67
+ const inlineTextTags = new Set ( [ 'a' , ' abbr' , ' acronym' , 'b' , ' big' , ' del' , 'em' , ' font' , 'i' , ' ins' , ' kbd' , ' mark' , ' nobr' , 'rp' , 's' , ' samp' , ' small' , ' span' , ' strike' , ' strong' , ' sub' , ' sup' , ' time' , 'tt' , 'u' , ' var'] ) ;
68
68
// self-closing tags that will maintain whitespace around them
69
- const selfClosingInlineTags = createMapFromString ( 'comment, img, input, wbr' ) ;
69
+ const selfClosingInlineTags = new Set ( [ 'comment' , ' img' , ' input' , ' wbr'] ) ;
70
70
71
71
function collapseWhitespaceSmart ( str , prevTag , nextTag , options ) {
72
- let trimLeft = prevTag && ! selfClosingInlineTags ( prevTag ) ;
72
+ let trimLeft = prevTag && ! selfClosingInlineTags . has ( prevTag ) ;
73
73
if ( trimLeft && ! options . collapseInlineTagWhitespace ) {
74
- trimLeft = prevTag . charAt ( 0 ) === '/' ? ! inlineTags ( prevTag . slice ( 1 ) ) : ! inlineTextTags ( prevTag ) ;
74
+ trimLeft = prevTag . charAt ( 0 ) === '/' ? ! inlineTags . has ( prevTag . slice ( 1 ) ) : ! inlineTextTags . has ( prevTag ) ;
75
75
}
76
- let trimRight = nextTag && ! selfClosingInlineTags ( nextTag ) ;
76
+ let trimRight = nextTag && ! selfClosingInlineTags . has ( nextTag ) ;
77
77
if ( trimRight && ! options . collapseInlineTagWhitespace ) {
78
- trimRight = nextTag . charAt ( 0 ) === '/' ? ! inlineTextTags ( nextTag . slice ( 1 ) ) : ! inlineTags ( nextTag ) ;
78
+ trimRight = nextTag . charAt ( 0 ) === '/' ? ! inlineTextTags . has ( nextTag . slice ( 1 ) ) : ! inlineTags . has ( nextTag ) ;
79
79
}
80
80
return collapseWhitespace ( str , options , trimLeft , trimRight , prevTag && nextTag ) ;
81
81
}
@@ -152,7 +152,7 @@ function isAttributeRedundant(tag, attrName, attrValue, attrs) {
152
152
153
153
// https://mathiasbynens.be/demo/javascript-mime-type
154
154
// https://developer.mozilla.org/en/docs/Web/HTML/Element/script#attr-type
155
- const executableScriptsMimetypes = createMap ( [
155
+ const executableScriptsMimetypes = new Set ( [
156
156
'text/javascript' ,
157
157
'text/ecmascript' ,
158
158
'text/jscript' ,
@@ -162,18 +162,18 @@ const executableScriptsMimetypes = createMap([
162
162
'module'
163
163
] ) ;
164
164
165
- const keepScriptsMimetypes = createMap ( [
165
+ const keepScriptsMimetypes = new Set ( [
166
166
'module'
167
167
] ) ;
168
168
169
169
function isScriptTypeAttribute ( attrValue ) {
170
170
attrValue = trimWhitespace ( attrValue . split ( / ; / , 2 ) [ 0 ] ) . toLowerCase ( ) ;
171
- return attrValue === '' || executableScriptsMimetypes ( attrValue ) ;
171
+ return attrValue === '' || executableScriptsMimetypes . has ( attrValue ) ;
172
172
}
173
173
174
174
function keepScriptTypeAttribute ( attrValue ) {
175
175
attrValue = trimWhitespace ( attrValue . split ( / ; / , 2 ) [ 0 ] ) . toLowerCase ( ) ;
176
- return keepScriptsMimetypes ( attrValue ) ;
176
+ return keepScriptsMimetypes . has ( attrValue ) ;
177
177
}
178
178
179
179
function isExecutableScript ( tag , attrs ) {
@@ -207,11 +207,11 @@ function isStyleSheet(tag, attrs) {
207
207
return true ;
208
208
}
209
209
210
- const isSimpleBoolean = createMapFromString ( 'allowfullscreen, async, autofocus, autoplay, checked, compact, controls, declare, default, defaultchecked, defaultmuted, defaultselected, defer, disabled, enabled, formnovalidate, hidden, indeterminate, inert, ismap, itemscope, loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open, pauseonexit, readonly, required, reversed, scoped, seamless, selected, sortable, truespeed, typemustmatch, visible' ) ;
211
- const isBooleanValue = createMapFromString ( 'true, false' ) ;
210
+ const isSimpleBoolean = new Set ( [ 'allowfullscreen' , ' async' , ' autofocus' , ' autoplay' , ' checked' , ' compact' , ' controls' , ' declare' , ' default' , ' defaultchecked' , ' defaultmuted' , ' defaultselected' , ' defer' , ' disabled' , ' enabled' , ' formnovalidate' , ' hidden' , ' indeterminate' , ' inert' , ' ismap' , ' itemscope' , ' loop' , ' multiple' , ' muted' , ' nohref' , ' noresize' , ' noshade' , ' novalidate' , ' nowrap' , ' open' , ' pauseonexit' , ' readonly' , ' required' , ' reversed' , ' scoped' , ' seamless' , ' selected' , ' sortable' , ' truespeed' , ' typemustmatch' , ' visible'] ) ;
211
+ const isBooleanValue = new Set ( [ 'true' , ' false'] ) ;
212
212
213
213
function isBooleanAttribute ( attrName , attrValue ) {
214
- return isSimpleBoolean ( attrName ) || ( attrName === 'draggable' && ! isBooleanValue ( attrValue ) ) ;
214
+ return isSimpleBoolean . has ( attrName ) || ( attrName === 'draggable' && ! isBooleanValue . has ( attrValue ) ) ;
215
215
}
216
216
217
217
function isUriTypeAttribute ( attrName , tag ) {
@@ -256,10 +256,10 @@ function isMediaQuery(tag, attrs, attrName) {
256
256
return attrName === 'media' && ( isLinkType ( tag , attrs , 'stylesheet' ) || isStyleSheet ( tag , attrs ) ) ;
257
257
}
258
258
259
- const srcsetTags = createMapFromString ( 'img, source' ) ;
259
+ const srcsetTags = new Set ( [ 'img' , ' source'] ) ;
260
260
261
261
function isSrcset ( attrName , tag ) {
262
- return attrName === 'srcset' && srcsetTags ( tag ) ;
262
+ return attrName === 'srcset' && srcsetTags . has ( tag ) ;
263
263
}
264
264
265
265
async function cleanAttributeValue ( tag , attrName , attrValue , options , attrs ) {
@@ -399,31 +399,31 @@ async function processScript(text, options, currentAttrs) {
399
399
// - retain <body> if followed by <noscript>
400
400
// - </rb>, </rt>, </rtc>, </rp> & </tfoot> follow https://www.w3.org/TR/html5/syntax.html#optional-tags
401
401
// - retain all tags which are adjacent to non-standard HTML tags
402
- const optionalStartTags = createMapFromString ( 'html, head, body, colgroup, tbody' ) ;
403
- const optionalEndTags = createMapFromString ( 'html, head, body,li,dt,dd,p,rb,rt, rtc,rp, optgroup, option, colgroup, caption, thead, tbody, tfoot,tr,td, th' ) ;
404
- const headerTags = createMapFromString ( 'meta, link, script, style, template, noscript' ) ;
405
- const descriptionTags = createMapFromString ( 'dt, dd' ) ;
406
- const pBlockTags = createMapFromString ( 'address, article, aside, blockquote, details, div,dl, fieldset, figcaption, figure, footer, form,h1,h2,h3,h4,h5,h6, header, hgroup,hr, main, menu, nav,ol,p, pre, section, table, ul' ) ;
407
- const pInlineTags = createMapFromString ( 'a, audio, del, ins, map, noscript, video') ;
408
- const rubyTags = createMapFromString ( 'rb,rt, rtc, rp' ) ;
409
- const rtcTag = createMapFromString ( 'rb, rtc, rp' ) ;
410
- const optionTag = createMapFromString ( 'option, optgroup' ) ;
411
- const tableContentTags = createMapFromString ( 'tbody, tfoot' ) ;
412
- const tableSectionTags = createMapFromString ( 'thead, tbody, tfoot' ) ;
413
- const cellTags = createMapFromString ( 'td, th' ) ;
414
- const topLevelTags = createMapFromString ( 'html, head, body' ) ;
415
- const compactTags = createMapFromString ( 'html, body' ) ;
416
- const looseTags = createMapFromString ( 'head, colgroup, caption' ) ;
417
- const trailingTags = createMapFromString ( 'dt, thead' ) ;
418
- const htmlTags = createMapFromString ( 'a,abbr,acronym,address,applet,area,article,aside,audio,b,base,basefont,bdi,bdo,bgsound,big,blink,blockquote,body,br,button,canvas,caption,center,cite,code,col,colgroup,command,content,data,datalist,dd,del,details,dfn,dialog,dir,div,dl,dt,element,em,embed,fieldset,figcaption,figure,font,footer,form,frame,frameset,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,i,iframe,image,img,input,ins,isindex,kbd,keygen,label,legend,li,link,listing,main,map,mark,marquee,menu,menuitem,meta,meter,multicol,nav,nobr,noembed,noframes,noscript,object,ol,optgroup,option,output,p,param,picture,plaintext,pre,progress,q,rb,rp,rt,rtc,ruby,s,samp,script,section,select,shadow,small,source,spacer,span,strike,strong,style,sub,summary,sup,table,tbody,td,template,textarea,tfoot,th,thead,time,title,tr,track,tt,u,ul,var,video,wbr,xmp' ) ;
402
+ const optionalStartTags = new Set ( [ 'html' , ' head' , ' body' , ' colgroup' , ' tbody'] ) ;
403
+ const optionalEndTags = new Set ( [ 'html' , ' head' , ' body' , 'li' , 'dt' , 'dd' , 'p' , 'rb' , 'rt' , ' rtc' , 'rp' , ' optgroup' , ' option' , ' colgroup' , ' caption' , ' thead' , ' tbody' , ' tfoot' , 'tr' , 'td' , ' th'] ) ;
404
+ const headerTags = new Set ( [ 'meta' , ' link' , ' script' , ' style' , ' template' , ' noscript'] ) ;
405
+ const descriptionTags = new Set ( [ 'dt' , ' dd'] ) ;
406
+ const pBlockTags = new Set ( [ 'address' , ' article' , ' aside' , ' blockquote' , ' details' , ' div' , 'dl' , ' fieldset' , ' figcaption' , ' figure' , ' footer' , ' form' , 'h1' , 'h2' , 'h3' , 'h4' , 'h5' , 'h6' , ' header' , ' hgroup' , 'hr' , ' main' , ' menu' , ' nav' , 'ol' , 'p' , ' pre' , ' section' , ' table' , ' ul'] ) ;
407
+ const pInlineTags = new Set ( [ 'a' , ' audio' , ' del' , ' ins' , ' map' , ' noscript' , ' video'] ) ;
408
+ const rubyTags = new Set ( [ 'rb' , 'rt' , ' rtc' , ' rp'] ) ;
409
+ const rtcTag = new Set ( [ 'rb' , ' rtc' , ' rp'] ) ;
410
+ const optionTag = new Set ( [ 'option' , ' optgroup'] ) ;
411
+ const tableContentTags = new Set ( [ 'tbody' , ' tfoot'] ) ;
412
+ const tableSectionTags = new Set ( [ 'thead' , ' tbody' , ' tfoot'] ) ;
413
+ const cellTags = new Set ( [ 'td' , ' th'] ) ;
414
+ const topLevelTags = new Set ( [ 'html' , ' head' , ' body'] ) ;
415
+ const compactTags = new Set ( [ 'html' , ' body'] ) ;
416
+ const looseTags = new Set ( [ 'head' , ' colgroup' , ' caption'] ) ;
417
+ const trailingTags = new Set ( [ 'dt' , ' thead'] ) ;
418
+ const htmlTags = new Set ( [ 'a' , 'abbr' , 'acronym' , 'address' , 'applet' , 'area' , 'article' , 'aside' , 'audio' , 'b' , 'base' , 'basefont' , 'bdi' , 'bdo' , 'bgsound' , 'big' , 'blink' , 'blockquote' , 'body' , 'br' , 'button' , 'canvas' , 'caption' , 'center' , 'cite' , 'code' , 'col' , 'colgroup' , 'command' , 'content' , 'data' , 'datalist' , 'dd' , 'del' , 'details' , 'dfn' , 'dialog' , 'dir' , 'div' , 'dl' , 'dt' , 'element' , 'em' , 'embed' , 'fieldset' , 'figcaption' , 'figure' , 'font' , 'footer' , 'form' , 'frame' , 'frameset' , 'h1' , 'h2' , 'h3' , 'h4' , 'h5' , 'h6' , 'head' , 'header' , 'hgroup' , 'hr' , 'html' , 'i' , 'iframe' , 'image' , 'img' , 'input' , 'ins' , 'isindex' , 'kbd' , 'keygen' , 'label' , 'legend' , 'li' , 'link' , 'listing' , 'main' , 'map' , 'mark' , 'marquee' , 'menu' , 'menuitem' , 'meta' , 'meter' , 'multicol' , 'nav' , 'nobr' , 'noembed' , 'noframes' , 'noscript' , 'object' , 'ol' , 'optgroup' , 'option' , 'output' , 'p' , 'param' , 'picture' , 'plaintext' , 'pre' , 'progress' , 'q' , 'rb' , 'rp' , 'rt' , 'rtc' , 'ruby' , 's' , 'samp' , 'script' , 'section' , 'select' , 'shadow' , 'small' , 'source' , 'spacer' , 'span' , 'strike' , 'strong' , 'style' , 'sub' , 'summary' , 'sup' , 'table' , 'tbody' , 'td' , 'template' , 'textarea' , 'tfoot' , 'th' , 'thead' , 'time' , 'title' , 'tr' , 'track' , 'tt' , 'u' , 'ul' , 'var' , 'video' , 'wbr' , 'xmp' ] ) ;
419
419
420
420
function canRemoveParentTag ( optionalStartTag , tag ) {
421
421
switch ( optionalStartTag ) {
422
422
case 'html' :
423
423
case 'head' :
424
424
return true ;
425
425
case 'body' :
426
- return ! headerTags ( tag ) ;
426
+ return ! headerTags . has ( tag ) ;
427
427
case 'colgroup' :
428
428
return tag === 'col' ;
429
429
case 'tbody' :
@@ -437,7 +437,7 @@ function isStartTagMandatory(optionalEndTag, tag) {
437
437
case 'colgroup' :
438
438
return optionalEndTag === 'colgroup' ;
439
439
case 'tbody' :
440
- return tableSectionTags ( optionalEndTag ) ;
440
+ return tableSectionTags . has ( optionalEndTag ) ;
441
441
}
442
442
return false ;
443
443
}
@@ -456,25 +456,25 @@ function canRemovePrecedingTag(optionalEndTag, tag) {
456
456
return tag === optionalEndTag ;
457
457
case 'dt' :
458
458
case 'dd' :
459
- return descriptionTags ( tag ) ;
459
+ return descriptionTags . has ( tag ) ;
460
460
case 'p' :
461
- return pBlockTags ( tag ) ;
461
+ return pBlockTags . has ( tag ) ;
462
462
case 'rb' :
463
463
case 'rt' :
464
464
case 'rp' :
465
- return rubyTags ( tag ) ;
465
+ return rubyTags . has ( tag ) ;
466
466
case 'rtc' :
467
- return rtcTag ( tag ) ;
467
+ return rtcTag . has ( tag ) ;
468
468
case 'option' :
469
- return optionTag ( tag ) ;
469
+ return optionTag . has ( tag ) ;
470
470
case 'thead' :
471
471
case 'tbody' :
472
- return tableContentTags ( tag ) ;
472
+ return tableContentTags . has ( tag ) ;
473
473
case 'tfoot' :
474
474
return tag === 'tbody' ;
475
475
case 'td' :
476
476
case 'th' :
477
- return cellTags ( tag ) ;
477
+ return cellTags . has ( tag ) ;
478
478
}
479
479
return false ;
480
480
}
@@ -744,7 +744,7 @@ function uniqueId(value) {
744
744
return id ;
745
745
}
746
746
747
- const specialContentTags = createMapFromString ( 'script, style' ) ;
747
+ const specialContentTags = new Set ( [ 'script' , ' style'] ) ;
748
748
749
749
async function createSortFns ( value , options , uidIgnore , uidAttr ) {
750
750
const attrChains = options . sortAttributes && Object . create ( null ) ;
@@ -788,7 +788,7 @@ async function createSortFns(value, options, uidIgnore, uidAttr) {
788
788
currentTag = '' ;
789
789
} ,
790
790
chars : async function ( text ) {
791
- if ( options . processScripts && specialContentTags ( currentTag ) &&
791
+ if ( options . processScripts && specialContentTags . has ( currentTag ) &&
792
792
options . processScripts . indexOf ( currentType ) > - 1 ) {
793
793
await scan ( text ) ;
794
794
}
@@ -996,15 +996,15 @@ async function minifyHTML(value, options, partialMarkup) {
996
996
tag = options . name ( tag ) ;
997
997
currentTag = tag ;
998
998
charsPrevTag = tag ;
999
- if ( ! inlineTextTags ( tag ) ) {
999
+ if ( ! inlineTextTags . has ( tag ) ) {
1000
1000
currentChars = '' ;
1001
1001
}
1002
1002
hasChars = false ;
1003
1003
currentAttrs = attrs ;
1004
1004
1005
1005
let optional = options . removeOptionalTags ;
1006
1006
if ( optional ) {
1007
- const htmlTag = htmlTags ( tag ) ;
1007
+ const htmlTag = htmlTags . has ( tag ) ;
1008
1008
// <html> may be omitted if first thing inside is not comment
1009
1009
// <head> may be omitted if first thing inside is an element
1010
1010
// <body> may be omitted if first thing inside is not space, comment, <meta>, <link>, <script>, <style> or <template>
@@ -1059,7 +1059,7 @@ async function minifyHTML(value, options, partialMarkup) {
1059
1059
if ( parts . length > 0 ) {
1060
1060
buffer . push ( ' ' ) ;
1061
1061
buffer . push . apply ( buffer , parts ) ;
1062
- } else if ( optional && optionalStartTags ( tag ) ) {
1062
+ } else if ( optional && optionalStartTags . has ( tag ) ) {
1063
1063
// start tag must never be omitted if it has any attributes
1064
1064
optionalStartTag = tag ;
1065
1065
}
@@ -1100,18 +1100,18 @@ async function minifyHTML(value, options, partialMarkup) {
1100
1100
1101
1101
if ( options . removeOptionalTags ) {
1102
1102
// <html>, <head> or <body> may be omitted if the element is empty
1103
- if ( isElementEmpty && topLevelTags ( optionalStartTag ) ) {
1103
+ if ( isElementEmpty && topLevelTags . has ( optionalStartTag ) ) {
1104
1104
removeStartTag ( ) ;
1105
1105
}
1106
1106
optionalStartTag = '' ;
1107
1107
// </html> or </body> may be omitted if not followed by comment
1108
1108
// </head> may be omitted if not followed by space or comment
1109
1109
// </p> may be omitted if no more content in non-</a> parent
1110
1110
// except for </dt> or </thead>, end tags may be omitted if no more content in parent element
1111
- if ( htmlTags ( tag ) && optionalEndTag && ! trailingTags ( optionalEndTag ) && ( optionalEndTag !== 'p' || ! pInlineTags ( tag ) ) ) {
1111
+ if ( htmlTags . has ( tag ) && optionalEndTag && ! trailingTags . has ( optionalEndTag ) && ( optionalEndTag !== 'p' || ! pInlineTags . has ( tag ) ) ) {
1112
1112
removeEndTag ( ) ;
1113
1113
}
1114
- optionalEndTag = optionalEndTags ( tag ) ? tag : '' ;
1114
+ optionalEndTag = optionalEndTags . has ( tag ) ? tag : '' ;
1115
1115
}
1116
1116
1117
1117
if ( options . removeEmptyElements && isElementEmpty && canRemoveElement ( tag , attrs ) ) {
@@ -1126,7 +1126,7 @@ async function minifyHTML(value, options, partialMarkup) {
1126
1126
buffer . push ( '</' + tag + '>' ) ;
1127
1127
}
1128
1128
charsPrevTag = '/' + tag ;
1129
- if ( ! inlineTags ( tag ) ) {
1129
+ if ( ! inlineTags . has ( tag ) ) {
1130
1130
currentChars = '' ;
1131
1131
} else if ( isElementEmpty ) {
1132
1132
currentChars += '|' ;
@@ -1136,7 +1136,7 @@ async function minifyHTML(value, options, partialMarkup) {
1136
1136
chars : async function ( text , prevTag , nextTag ) {
1137
1137
prevTag = prevTag === '' ? 'comment' : prevTag ;
1138
1138
nextTag = nextTag === '' ? 'comment' : nextTag ;
1139
- if ( options . decodeEntities && text && ! specialContentTags ( currentTag ) ) {
1139
+ if ( options . decodeEntities && text && ! specialContentTags . has ( currentTag ) ) {
1140
1140
text = decodeHTML ( text ) ;
1141
1141
}
1142
1142
if ( options . collapseWhitespace ) {
@@ -1165,7 +1165,7 @@ async function minifyHTML(value, options, partialMarkup) {
1165
1165
}
1166
1166
trimTrailingWhitespace ( tagIndex - 1 , 'br' ) ;
1167
1167
}
1168
- } else if ( inlineTextTags ( prevTag . charAt ( 0 ) === '/' ? prevTag . slice ( 1 ) : prevTag ) ) {
1168
+ } else if ( inlineTextTags . has ( prevTag . charAt ( 0 ) === '/' ? prevTag . slice ( 1 ) : prevTag ) ) {
1169
1169
text = collapseWhitespace ( text , options , / (?: ^ | \s ) $ / . test ( currentChars ) ) ;
1170
1170
}
1171
1171
}
@@ -1182,7 +1182,7 @@ async function minifyHTML(value, options, partialMarkup) {
1182
1182
text = collapseWhitespace ( text , options , false , false , true ) ;
1183
1183
}
1184
1184
}
1185
- if ( options . processScripts && specialContentTags ( currentTag ) ) {
1185
+ if ( options . processScripts && specialContentTags . has ( currentTag ) ) {
1186
1186
text = await processScript ( text , options , currentAttrs ) ;
1187
1187
}
1188
1188
if ( isExecutableScript ( currentTag , currentAttrs ) ) {
@@ -1200,13 +1200,13 @@ async function minifyHTML(value, options, partialMarkup) {
1200
1200
optionalStartTag = '' ;
1201
1201
// </html> or </body> may be omitted if not followed by comment
1202
1202
// </head>, </colgroup> or </caption> may be omitted if not followed by space or comment
1203
- if ( compactTags ( optionalEndTag ) || ( looseTags ( optionalEndTag ) && ! / ^ \s / . test ( text ) ) ) {
1203
+ if ( compactTags . has ( optionalEndTag ) || ( looseTags . has ( optionalEndTag ) && ! / ^ \s / . test ( text ) ) ) {
1204
1204
removeEndTag ( ) ;
1205
1205
}
1206
1206
optionalEndTag = '' ;
1207
1207
}
1208
1208
charsPrevTag = / ^ \s * $ / . test ( text ) ? prevTag : 'comment' ;
1209
- if ( options . decodeEntities && text && ! specialContentTags ( currentTag ) ) {
1209
+ if ( options . decodeEntities && text && ! specialContentTags . has ( currentTag ) ) {
1210
1210
// Escape any `&` symbols that start either:
1211
1211
// 1) a legacy named character reference (i.e. one that doesn't end with `;`)
1212
1212
// 2) or any other character reference (i.e. one that does end with `;`)
@@ -1259,11 +1259,11 @@ async function minifyHTML(value, options, partialMarkup) {
1259
1259
if ( options . removeOptionalTags ) {
1260
1260
// <html> may be omitted if first thing inside is not comment
1261
1261
// <head> or <body> may be omitted if empty
1262
- if ( topLevelTags ( optionalStartTag ) ) {
1262
+ if ( topLevelTags . has ( optionalStartTag ) ) {
1263
1263
removeStartTag ( ) ;
1264
1264
}
1265
1265
// except for </dt> or </thead>, end tags may be omitted if no more content in parent element
1266
- if ( optionalEndTag && ! trailingTags ( optionalEndTag ) ) {
1266
+ if ( optionalEndTag && ! trailingTags . has ( optionalEndTag ) ) {
1267
1267
removeEndTag ( ) ;
1268
1268
}
1269
1269
}
0 commit comments