html-minifier-next 5.2.2 → 6.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -166,7 +166,6 @@ Options can be used in config files (camelCase) or via CLI flags (kebab-case wit
166
166
  | `partialMarkup`<br>`--partial-markup` | Treat input as a partial HTML fragment, preserving stray end tags (closing tags without opening tags) and preventing auto-closing of unclosed tags at end of input | `false` |
167
167
  | `preserveLineBreaks`<br>`--preserve-line-breaks` | Always collapse to one line break (never remove it entirely) when whitespace between tags includes a line break—use with `collapseWhitespace: true` | `false` |
168
168
  | `preventAttributesEscaping`<br>`--prevent-attributes-escaping` | Prevents the escaping of the values of attributes | `false` |
169
- | `processConditionalComments`<br>`--process-conditional-comments` | Process contents of conditional comments through minifier | `false` |
170
169
  | `processScripts`<br>`--process-scripts` | Array of strings corresponding to types of `script` elements to process through minifier (e.g., `text/ng-template`, `text/x-handlebars-template`, etc.) | `[]` |
171
170
  | `quoteCharacter`<br>`--quote-character` | Type of quote to use for attribute values (`'` or `"`) | Auto-detected (uses the quote requiring less escaping; defaults to `"` when equal) |
172
171
  | `removeAttributeQuotes`<br>`--remove-attribute-quotes` | [Remove quotes around attributes when possible](https://perfectionkills.com/experimenting-with-html-minifier/#remove_attribute_quotes) | `false` |
@@ -988,7 +988,6 @@ const presets = {
988
988
  collapseWhitespace: true,
989
989
  conservativeCollapse: true,
990
990
  preserveLineBreaks: true,
991
- processConditionalComments: true,
992
991
  removeComments: true,
993
992
  removeScriptTypeAttributes: true,
994
993
  removeStyleLinkTypeAttributes: true,
@@ -1005,7 +1004,6 @@ const presets = {
1005
1004
  minifyJS: true,
1006
1005
  minifySVG: true,
1007
1006
  minifyURLs: true,
1008
- processConditionalComments: true,
1009
1007
  removeAttributeQuotes: true,
1010
1008
  removeComments: true,
1011
1009
  removeEmptyAttributes: true,
@@ -1045,7 +1043,6 @@ const RE_NBSP_LEADING_GROUP = /(^|\xA0+)[^\xA0]+/g;
1045
1043
  const RE_NBSP_LEAD_GROUP = /(\xA0+)[^\xA0]+/g;
1046
1044
  const RE_NBSP_TRAILING_GROUP = /[^\xA0]+(\xA0+)/g;
1047
1045
  const RE_NBSP_TRAILING_STRIP = /[^\xA0]+$/;
1048
- const RE_CONDITIONAL_COMMENT = /^\[if\s[^\]]+]|\[endif]$/;
1049
1046
  const RE_EVENT_ATTR_DEFAULT = /^on[a-z]{3,}$/;
1050
1047
  const RE_CAN_REMOVE_ATTR_QUOTES = /^[^ \t\n\f\r"'`=<>]+$/;
1051
1048
  const RE_TRAILING_SEMICOLON = /;$/;
@@ -1610,14 +1607,6 @@ function unwrapCSS(text, type) {
1610
1607
  return matches ? matches[1] : text;
1611
1608
  }
1612
1609
 
1613
- async function cleanConditionalComment(comment, options, minifyHTML) {
1614
- return options.processConditionalComments
1615
- ? await replaceAsync(comment, /^(\[if\s[^\]]+]>)([\s\S]*?)(<!\[endif])$/, async function (match, prefix, text, suffix) {
1616
- return prefix + await minifyHTML(text, options, true) + suffix;
1617
- })
1618
- : comment;
1619
- }
1620
-
1621
1610
  // Script processing
1622
1611
 
1623
1612
  function minifyJson(text, options) {
@@ -1904,7 +1893,7 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, getS
1904
1893
  cont: !!options.continueOnMinifyError
1905
1894
  });
1906
1895
 
1907
- options.minifyJS = async function (text, inline) {
1896
+ options.minifyJS = async function (text, inline, isModule) {
1908
1897
  const start = text.match(/^\s*<!--.*/);
1909
1898
  const code = start ? text.slice(start[0].length).replace(/\n\s*-->\s*$/, '') : text;
1910
1899
 
@@ -1924,7 +1913,7 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, getS
1924
1913
 
1925
1914
  // For large inputs, use length and content fingerprint to prevent collisions
1926
1915
  jsKey = (code.length > 2048 ? (code.length + '|' + code.slice(0, 50) + code.slice(-50) + '|') : (code + '|'))
1927
- + (inline ? '1' : '0') + '|' + useEngine + '|' + optsSig;
1916
+ + (inline ? '1' : '0') + '|' + (isModule ? 'm' : '') + '|' + useEngine + '|' + optsSig;
1928
1917
 
1929
1918
  const cached = jsMinifyCache.get(jsKey);
1930
1919
  if (cached) {
@@ -1940,7 +1929,8 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, getS
1940
1929
  parse: {
1941
1930
  ...terserOptions.parse,
1942
1931
  bare_returns: inline
1943
- }
1932
+ },
1933
+ ...(isModule ? { module: true } : {}) // Overrides user options: module detection takes precedence for `<script type=module>`
1944
1934
  };
1945
1935
  const terser = await getTerser();
1946
1936
  const result = await terser(code, terserCallOptions);
@@ -1951,7 +1941,8 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, getS
1951
1941
  const result = await swc.minify(code, {
1952
1942
  compress: true,
1953
1943
  mangle: true,
1954
- ...swcOptions, // User options override defaults
1944
+ ...swcOptions,
1945
+ ...(isModule ? { module: true } : {}) // Overrides user options: module detection takes precedence for `<script type=module>`
1955
1946
  });
1956
1947
  return result.code.replace(RE_TRAILING_SEMICOLON, '');
1957
1948
  }
@@ -2094,10 +2085,6 @@ async function getDecodeHTMLStrict() {
2094
2085
 
2095
2086
  // Validators
2096
2087
 
2097
- function isConditionalComment(text) {
2098
- return RE_CONDITIONAL_COMMENT.test(text);
2099
- }
2100
-
2101
2088
  function isIgnoredComment(text, options) {
2102
2089
  for (let i = 0, len = options.ignoreCustomComments.length; i < len; i++) {
2103
2090
  if (options.ignoreCustomComments[i].test(text)) {
@@ -3083,12 +3070,14 @@ function mergeConsecutiveScripts(html) {
3083
3070
  return match;
3084
3071
  }
3085
3072
 
3086
- // Check `type` compatibility (both must be same, or both default JS)
3087
- const type1 = a1.type || '';
3088
- const type2 = a2.type || '';
3073
+ // Check `type` compatibility (both must be default JS)
3074
+ const type1 = (a1.type || '').toLowerCase();
3075
+ const type2 = (a2.type || '').toLowerCase();
3089
3076
 
3090
- if (DEFAULT_JS_TYPES.has(type1) && DEFAULT_JS_TYPES.has(type2)) ; else if (type1 === type2) ; else {
3091
- // Incompatible types
3077
+ if (DEFAULT_JS_TYPES.has(type1) && DEFAULT_JS_TYPES.has(type2)) ; else {
3078
+ // Non-JS types (modules, JSON, etc.) must not be merged:
3079
+ // Module scripts have per-script lexical scope, and non-JS content (e.g., JSON)
3080
+ // is not concatenable. Even identical non-JS types are incompatible.
3092
3081
  return match;
3093
3082
  }
3094
3083
 
@@ -3415,13 +3404,6 @@ function mergeConsecutiveScripts(html) {
3415
3404
  *
3416
3405
  * Default: `false`
3417
3406
  *
3418
- * @prop {boolean} [processConditionalComments]
3419
- * When true, conditional comments (for example `<!--[if IE]> … <![endif]-->`)
3420
- * will have their inner content processed by the minifier.
3421
- * Useful to minify HTML that appears inside conditional comments.
3422
- *
3423
- * Default: `false`
3424
- *
3425
3407
  * @prop {string[]} [processScripts]
3426
3408
  * Array of `type` attribute values for `<script>` elements whose contents
3427
3409
  * should be processed as HTML
@@ -3909,11 +3891,11 @@ async function minifyHTML(value, options, partialMarkup) {
3909
3891
 
3910
3892
  if (options.minifyJS) {
3911
3893
  options.minifyJS = (function (fn) {
3912
- return function (text, type) {
3894
+ return function (text, inline, isModule) {
3913
3895
  return fn(text.replace(uidPattern, function (match, prefix, index) {
3914
3896
  const chunks = ignoredCustomMarkupChunks[+index];
3915
3897
  return chunks[1] + uidAttr + index + uidAttr + chunks[2];
3916
- }), type);
3898
+ }), inline, isModule);
3917
3899
  };
3918
3900
  })(options.minifyJS);
3919
3901
  }
@@ -4236,6 +4218,9 @@ async function minifyHTML(value, options, partialMarkup) {
4236
4218
  const needsDecode = options.decodeEntities && text && !specialContentElements.has(currentTag) && text.indexOf('&') !== -1;
4237
4219
  const needsProcessScript = specialContentElements.has(currentTag) && (options.processScripts || hasJsonScriptType(currentAttrs));
4238
4220
  const needsMinifyJS = options.minifyJS !== identity && isExecutableScript(currentTag, currentAttrs);
4221
+ const isModuleScript = needsMinifyJS && currentAttrs.some(
4222
+ a => a.name.toLowerCase() === 'type' && (a.value ?? '').trim().toLowerCase() === 'module'
4223
+ );
4239
4224
  const needsMinifyCSS = options.minifyCSS !== identity && isStyleElement(currentTag, currentAttrs);
4240
4225
 
4241
4226
  // Whitespace collapsing phase (sync); captures `prevTag`/`nextTag`/`prevAttrs`/`nextAttrs` from outer scope
@@ -4362,7 +4347,7 @@ async function minifyHTML(value, options, partialMarkup) {
4362
4347
  text = await processScript(text, options, currentAttrs, minifyHTML);
4363
4348
  }
4364
4349
  if (needsMinifyJS) {
4365
- text = await options.minifyJS(text);
4350
+ text = await options.minifyJS(text, false, isModuleScript);
4366
4351
  }
4367
4352
  if (needsMinifyCSS) {
4368
4353
  text = await options.minifyCSS(text);
@@ -4457,16 +4442,9 @@ async function minifyHTML(value, options, partialMarkup) {
4457
4442
  buffer.push(comment);
4458
4443
  }
4459
4444
 
4460
- // Only conditional comments require async work (recursive minification)
4461
- if (isConditionalComment(text)) {
4462
- return cleanConditionalComment(text, options, minifyHTML).then(cleaned => {
4463
- commentFinalize(prefix + cleaned + suffix);
4464
- });
4465
- }
4466
-
4467
4445
  if (options.removeComments) {
4468
4446
  if (isIgnoredComment(text, options)) {
4469
- text = '<!--' + text + '-->';
4447
+ text = prefix + text + suffix;
4470
4448
  } else {
4471
4449
  text = '';
4472
4450
  }
@@ -11,11 +11,11 @@ export default _default;
11
11
  */
12
12
  export type HTMLAttribute = {
13
13
  name: string;
14
- value?: string;
15
- quote?: string;
16
- customAssign?: string;
17
- customOpen?: string;
18
- customClose?: string;
14
+ value?: string | undefined;
15
+ quote?: string | undefined;
16
+ customAssign?: string | undefined;
17
+ customOpen?: string | undefined;
18
+ customClose?: string | undefined;
19
19
  };
20
20
  /**
21
21
  * Options that control how HTML is minified. All of these are optional
@@ -28,14 +28,14 @@ export type MinifierOptions = {
28
28
  *
29
29
  * Default: Built-in `canCollapseWhitespace` function
30
30
  */
31
- canCollapseWhitespace?: (tag: string, attrs: HTMLAttribute[], canCollapseWhitespace: (tag: string) => boolean) => boolean;
31
+ canCollapseWhitespace?: ((tag: string, attrs: HTMLAttribute[], canCollapseWhitespace: (tag: string) => boolean) => boolean) | undefined;
32
32
  /**
33
33
  * Predicate that determines whether leading/trailing whitespace around
34
34
  * the element may be trimmed.
35
35
  *
36
36
  * Default: Built-in `canTrimWhitespace` function
37
37
  */
38
- canTrimWhitespace?: (tag: string | null, attrs: HTMLAttribute[] | undefined, canTrimWhitespace: (tag: string) => boolean) => boolean;
38
+ canTrimWhitespace?: ((tag: string | null, attrs: HTMLAttribute[] | undefined, canTrimWhitespace: (tag: string) => boolean) => boolean) | undefined;
39
39
  /**
40
40
  * The maximum number of entries for the CSS minification cache. Higher values
41
41
  * improve performance for inputs with repeated CSS (e.g., batch processing).
@@ -45,7 +45,7 @@ export type MinifierOptions = {
45
45
  *
46
46
  * Default: `500`
47
47
  */
48
- cacheCSS?: number;
48
+ cacheCSS?: number | undefined;
49
49
  /**
50
50
  * The maximum number of entries for the JavaScript minification cache. Higher
51
51
  * values improve performance for inputs with repeated JavaScript.
@@ -55,7 +55,7 @@ export type MinifierOptions = {
55
55
  *
56
56
  * Default: `500`
57
57
  */
58
- cacheJS?: number;
58
+ cacheJS?: number | undefined;
59
59
  /**
60
60
  * The maximum number of entries for the SVG minification cache. Higher
61
61
  * values improve performance for inputs with repeated SVG content.
@@ -65,7 +65,7 @@ export type MinifierOptions = {
65
65
  *
66
66
  * Default: `500`
67
67
  */
68
- cacheSVG?: number;
68
+ cacheSVG?: number | undefined;
69
69
  /**
70
70
  * When true, tag and attribute names are treated as case-sensitive.
71
71
  * Useful for custom HTML tags.
@@ -73,7 +73,7 @@ export type MinifierOptions = {
73
73
  *
74
74
  * Default: `false`
75
75
  */
76
- caseSensitive?: boolean;
76
+ caseSensitive?: boolean | undefined;
77
77
  /**
78
78
  * Collapse multiple whitespace characters within attribute values into a
79
79
  * single space. Also trims leading and trailing whitespace from attribute
@@ -82,7 +82,7 @@ export type MinifierOptions = {
82
82
  *
83
83
  * Default: `false`
84
84
  */
85
- collapseAttributeWhitespace?: boolean;
85
+ collapseAttributeWhitespace?: boolean | undefined;
86
86
  /**
87
87
  * Collapse boolean attributes to their name only (for example
88
88
  * `disabled="disabled"` → `disabled`).
@@ -90,7 +90,7 @@ export type MinifierOptions = {
90
90
  *
91
91
  * Default: `false`
92
92
  */
93
- collapseBooleanAttributes?: boolean;
93
+ collapseBooleanAttributes?: boolean | undefined;
94
94
  /**
95
95
  * When false (default) whitespace around `inline` tags is preserved in
96
96
  * more cases. When true, whitespace around inline tags may be collapsed.
@@ -98,7 +98,7 @@ export type MinifierOptions = {
98
98
  *
99
99
  * Default: `false`
100
100
  */
101
- collapseInlineTagWhitespace?: boolean;
101
+ collapseInlineTagWhitespace?: boolean | undefined;
102
102
  /**
103
103
  * Collapse multiple whitespace characters into one where allowed. Also
104
104
  * controls trimming behaviour in several code paths.
@@ -106,7 +106,7 @@ export type MinifierOptions = {
106
106
  *
107
107
  * Default: `false`
108
108
  */
109
- collapseWhitespace?: boolean;
109
+ collapseWhitespace?: boolean | undefined;
110
110
  /**
111
111
  * If true, be conservative when collapsing whitespace (preserve more
112
112
  * whitespace in edge cases). Affects collapse algorithms.
@@ -114,7 +114,7 @@ export type MinifierOptions = {
114
114
  *
115
115
  * Default: `false`
116
116
  */
117
- conservativeCollapse?: boolean;
117
+ conservativeCollapse?: boolean | undefined;
118
118
  /**
119
119
  * When set to `false`, minification errors may throw.
120
120
  * By default, the minifier will attempt to recover from minification
@@ -122,14 +122,14 @@ export type MinifierOptions = {
122
122
  *
123
123
  * Default: `true`
124
124
  */
125
- continueOnMinifyError?: boolean;
125
+ continueOnMinifyError?: boolean | undefined;
126
126
  /**
127
127
  * When true, the parser will attempt to continue on recoverable parse
128
128
  * errors. Otherwise, parsing errors may throw.
129
129
  *
130
130
  * Default: `false`
131
131
  */
132
- continueOnParseError?: boolean;
132
+ continueOnParseError?: boolean | undefined;
133
133
  /**
134
134
  * Array of regexes used to recognise custom attribute assignment
135
135
  * operators (e.g. `'<div flex?="{{mode != cover}}"></div>'`).
@@ -137,40 +137,40 @@ export type MinifierOptions = {
137
137
  *
138
138
  * Default: `[]`
139
139
  */
140
- customAttrAssign?: RegExp[];
140
+ customAttrAssign?: RegExp[] | undefined;
141
141
  /**
142
142
  * Regex matching attribute names whose values should be collapsed.
143
143
  * Basically used to remove newlines and excess spaces inside attribute values,
144
144
  * e.g. `/ng-class/`.
145
145
  */
146
- customAttrCollapse?: RegExp;
146
+ customAttrCollapse?: RegExp | undefined;
147
147
  /**
148
148
  * Array of `[openRegExp, closeRegExp]` pairs used by the parser to
149
149
  * detect custom attribute surround patterns (for non-standard syntaxes,
150
150
  * e.g. `<input {{#if value}}checked="checked"{{/if}}>`).
151
151
  */
152
- customAttrSurround?: [RegExp, RegExp][];
152
+ customAttrSurround?: [RegExp, RegExp][] | undefined;
153
153
  /**
154
154
  * Array of regexes used to detect event handler attributes for `minifyJS`
155
155
  * (e.g. `ng-click`). The default matches standard `on…` event attributes.
156
156
  *
157
157
  * Default: `[/^on[a-z]{3,}$/]`
158
158
  */
159
- customEventAttributes?: RegExp[];
159
+ customEventAttributes?: RegExp[] | undefined;
160
160
  /**
161
161
  * Limits the quantifier used when building a safe regex for custom
162
162
  * fragments to avoid ReDoS. See source use for details.
163
163
  *
164
164
  * Default: `200`
165
165
  */
166
- customFragmentQuantifierLimit?: number;
166
+ customFragmentQuantifierLimit?: number | undefined;
167
167
  /**
168
168
  * When true, decodes HTML entities in text and attributes before
169
169
  * processing, and re-encodes ambiguous ampersands when outputting.
170
170
  *
171
171
  * Default: `false`
172
172
  */
173
- decodeEntities?: boolean;
173
+ decodeEntities?: boolean | undefined;
174
174
  /**
175
175
  * Comments matching any pattern in this array of regexes will be
176
176
  * preserved when `removeComments` is enabled. The default preserves
@@ -178,7 +178,7 @@ export type MinifierOptions = {
178
178
  *
179
179
  * Default: `[/^!/, /^\s*#/]`
180
180
  */
181
- ignoreCustomComments?: RegExp[];
181
+ ignoreCustomComments?: RegExp[] | undefined;
182
182
  /**
183
183
  * Array of regexes used to identify fragments that should be
184
184
  * preserved (for example server templates). These fragments are temporarily
@@ -187,27 +187,27 @@ export type MinifierOptions = {
187
187
  *
188
188
  * Default: `[/<%[\s\S]*?%>/, /<\?[\s\S]*?\?>/]`
189
189
  */
190
- ignoreCustomFragments?: RegExp[];
190
+ ignoreCustomFragments?: RegExp[] | undefined;
191
191
  /**
192
192
  * If false, tags marked as auto-generated by the parser will be omitted
193
193
  * from output. Useful to skip injected tags.
194
194
  *
195
195
  * Default: `false`
196
196
  */
197
- includeAutoGeneratedTags?: boolean;
197
+ includeAutoGeneratedTags?: boolean | undefined;
198
198
  /**
199
199
  * Collection of custom element tag names that should be treated as inline
200
200
  * elements for white-space handling, alongside the built-in inline elements.
201
201
  *
202
202
  * Default: `[]`
203
203
  */
204
- inlineCustomElements?: ArrayLike<string>;
204
+ inlineCustomElements?: ArrayLike<string> | undefined;
205
205
  /**
206
206
  * Preserve the trailing slash in self-closing tags when present.
207
207
  *
208
208
  * Default: `false`
209
209
  */
210
- keepClosingSlash?: boolean;
210
+ keepClosingSlash?: boolean | undefined;
211
211
  /**
212
212
  * Logging function used by the minifier for warnings/errors/info.
213
213
  * You can directly provide `console.log`, but `message` may also be an `Error`
@@ -215,7 +215,7 @@ export type MinifierOptions = {
215
215
  *
216
216
  * Default: `() => {}` (no-op function)
217
217
  */
218
- log?: (message: unknown) => void;
218
+ log?: ((message: unknown) => void) | undefined;
219
219
  /**
220
220
  * The maximum allowed input length. Used as a guard against ReDoS via
221
221
  * pathological inputs. If the input exceeds this length an error is
@@ -223,14 +223,14 @@ export type MinifierOptions = {
223
223
  *
224
224
  * Default: No limit
225
225
  */
226
- maxInputLength?: number;
226
+ maxInputLength?: number | undefined;
227
227
  /**
228
228
  * Maximum line length for the output. When set the minifier will wrap
229
229
  * output to the given number of characters where possible.
230
230
  *
231
231
  * Default: No limit
232
232
  */
233
- maxLineLength?: number;
233
+ maxLineLength?: number | undefined;
234
234
  /**
235
235
  * When true, consecutive inline `<script>` elements are merged into one.
236
236
  * Only merges compatible scripts (same `type`, matching `async`/`defer`/
@@ -238,7 +238,7 @@ export type MinifierOptions = {
238
238
  *
239
239
  * Default: `false`
240
240
  */
241
- mergeScripts?: boolean;
241
+ mergeScripts?: boolean | undefined;
242
242
  /**
243
243
  * When true, enables CSS minification for inline `<style>` tags or
244
244
  * `style` attributes. If an object is provided, it is passed to
@@ -248,7 +248,7 @@ export type MinifierOptions = {
248
248
  *
249
249
  * Default: `false`
250
250
  */
251
- minifyCSS?: boolean | Partial<import("lightningcss").TransformOptions<import("lightningcss").CustomAtRules>> | ((text: string, type?: string) => Promise<string> | string);
251
+ minifyCSS?: boolean | Partial<import("lightningcss").TransformOptions<import("lightningcss").CustomAtRules>> | ((text: string, type?: string) => Promise<string> | string) | undefined;
252
252
  /**
253
253
  * When true, enables JS minification for `<script>` contents and
254
254
  * event handler attributes. If an object is provided, it can include:
@@ -263,9 +263,9 @@ export type MinifierOptions = {
263
263
  * Default: `false`
264
264
  */
265
265
  minifyJS?: boolean | import("terser").MinifyOptions | {
266
- engine?: "terser" | "swc";
267
266
  [key: string]: any;
268
- } | ((text: string, inline?: boolean) => Promise<string> | string);
267
+ engine?: "terser" | "swc";
268
+ } | ((text: string, inline?: boolean) => Promise<string> | string) | undefined;
269
269
  /**
270
270
  * When true, enables URL rewriting/minification. If an object is provided,
271
271
  * the `site` property sets the base URL for computing relative paths.
@@ -275,9 +275,9 @@ export type MinifierOptions = {
275
275
  *
276
276
  * Default: `false`
277
277
  */
278
- minifyURLs?: boolean | string | {
278
+ minifyURLs?: string | boolean | {
279
279
  site?: string;
280
- } | ((text: string) => Promise<string> | string);
280
+ } | ((text: string) => Promise<string> | string) | undefined;
281
281
  /**
282
282
  * When true, enables SVG minification using [SVGO](https://github.com/svg/svgo).
283
283
  * Complete SVG subtrees are extracted and optimized as a block.
@@ -286,7 +286,7 @@ export type MinifierOptions = {
286
286
  *
287
287
  * Default: `false`
288
288
  */
289
- minifySVG?: boolean | any;
289
+ minifySVG?: boolean | Object | undefined;
290
290
  /**
291
291
  * Function used to normalise tag/attribute names. By default, this lowercases
292
292
  * names, unless `caseSensitive` is enabled.
@@ -294,14 +294,14 @@ export type MinifierOptions = {
294
294
  * Default: `(name) => name.toLowerCase()`,
295
295
  * or `(name) => name` (no-op function) if `caseSensitive` is enabled.
296
296
  */
297
- name?: (name: string) => string;
297
+ name?: ((name: string) => string) | undefined;
298
298
  /**
299
299
  * When wrapping lines, prevent inserting a newline directly before a
300
300
  * closing tag (useful to keep tags like `</a>` on the same line).
301
301
  *
302
302
  * Default: `false`
303
303
  */
304
- noNewlinesBeforeTagClose?: boolean;
304
+ noNewlinesBeforeTagClose?: boolean | undefined;
305
305
  /**
306
306
  * When true, treat input as a partial HTML fragment rather than a complete
307
307
  * document. This preserves stray end tags (closing tags without corresponding
@@ -311,7 +311,7 @@ export type MinifierOptions = {
311
311
  *
312
312
  * Default: `false`
313
313
  */
314
- partialMarkup?: boolean;
314
+ partialMarkup?: boolean | undefined;
315
315
  /**
316
316
  * Preserve a single line break at the start/end of text nodes when
317
317
  * collapsing/trimming whitespace.
@@ -319,22 +319,14 @@ export type MinifierOptions = {
319
319
  *
320
320
  * Default: `false`
321
321
  */
322
- preserveLineBreaks?: boolean;
322
+ preserveLineBreaks?: boolean | undefined;
323
323
  /**
324
324
  * When true, attribute values will not be HTML-escaped (dangerous for
325
325
  * untrusted input). By default, attributes are escaped.
326
326
  *
327
327
  * Default: `false`
328
328
  */
329
- preventAttributesEscaping?: boolean;
330
- /**
331
- * When true, conditional comments (for example `<!--[if IE]> … <![endif]-->`)
332
- * will have their inner content processed by the minifier.
333
- * Useful to minify HTML that appears inside conditional comments.
334
- *
335
- * Default: `false`
336
- */
337
- processConditionalComments?: boolean;
329
+ preventAttributesEscaping?: boolean | undefined;
338
330
  /**
339
331
  * Array of `type` attribute values for `<script>` elements whose contents
340
332
  * should be processed as HTML
@@ -344,21 +336,21 @@ export type MinifierOptions = {
344
336
  *
345
337
  * Default: `[]`
346
338
  */
347
- processScripts?: string[];
339
+ processScripts?: string[] | undefined;
348
340
  /**
349
341
  * Preferred quote character for attribute values. If unspecified the
350
342
  * minifier picks the safest quote based on the attribute value.
351
343
  *
352
344
  * Default: Auto-detected
353
345
  */
354
- quoteCharacter?: "\"" | "'";
346
+ quoteCharacter?: "\"" | "'" | undefined;
355
347
  /**
356
348
  * Remove quotes around attribute values where it is safe to do so.
357
349
  * See also: https://perfectionkills.com/experimenting-with-html-minifier/#remove_attribute_quotes
358
350
  *
359
351
  * Default: `false`
360
352
  */
361
- removeAttributeQuotes?: boolean;
353
+ removeAttributeQuotes?: boolean | undefined;
362
354
  /**
363
355
  * Remove HTML comments. Comments that match `ignoreCustomComments` will
364
356
  * still be preserved.
@@ -366,7 +358,7 @@ export type MinifierOptions = {
366
358
  *
367
359
  * Default: `false`
368
360
  */
369
- removeComments?: boolean;
361
+ removeComments?: boolean | undefined;
370
362
  /**
371
363
  * If true, removes attributes whose values are empty (some attributes
372
364
  * are excluded by name). Can also be a function to customise which empty
@@ -375,7 +367,7 @@ export type MinifierOptions = {
375
367
  *
376
368
  * Default: `false`
377
369
  */
378
- removeEmptyAttributes?: boolean | ((attrName: string, tag: string) => boolean);
370
+ removeEmptyAttributes?: boolean | ((attrName: string, tag: string) => boolean) | undefined;
379
371
  /**
380
372
  * Remove elements that are empty and safe to remove (for example
381
373
  * `<script />` without `src`).
@@ -383,7 +375,7 @@ export type MinifierOptions = {
383
375
  *
384
376
  * Default: `false`
385
377
  */
386
- removeEmptyElements?: boolean;
378
+ removeEmptyElements?: boolean | undefined;
387
379
  /**
388
380
  * Specifies empty elements to preserve when `removeEmptyElements` is enabled.
389
381
  * Has no effect unless `removeEmptyElements: true`.
@@ -409,7 +401,7 @@ export type MinifierOptions = {
409
401
  *
410
402
  * Default: `[]`
411
403
  */
412
- removeEmptyElementsExcept?: string[];
404
+ removeEmptyElementsExcept?: string[] | undefined;
413
405
  /**
414
406
  * Drop optional start/end tags where the HTML specification permits it
415
407
  * (for example `</li>`, optional `<html>` etc.).
@@ -417,7 +409,7 @@ export type MinifierOptions = {
417
409
  *
418
410
  * Default: `false`
419
411
  */
420
- removeOptionalTags?: boolean;
412
+ removeOptionalTags?: boolean | undefined;
421
413
  /**
422
414
  * Remove attributes that are redundant because they match the element’s
423
415
  * default values (for example `<button type="submit">`).
@@ -425,21 +417,21 @@ export type MinifierOptions = {
425
417
  *
426
418
  * Default: `false`
427
419
  */
428
- removeRedundantAttributes?: boolean;
420
+ removeRedundantAttributes?: boolean | undefined;
429
421
  /**
430
422
  * Remove `type` attributes from `<script>` when they are unnecessary
431
423
  * (e.g. `type="text/javascript"`).
432
424
  *
433
425
  * Default: `false`
434
426
  */
435
- removeScriptTypeAttributes?: boolean;
427
+ removeScriptTypeAttributes?: boolean | undefined;
436
428
  /**
437
429
  * Remove `type` attributes from `<style>` and `<link>` elements when
438
430
  * they are unnecessary (e.g. `type="text/css"`).
439
431
  *
440
432
  * Default: `false`
441
433
  */
442
- removeStyleLinkTypeAttributes?: boolean;
434
+ removeStyleLinkTypeAttributes?: boolean | undefined;
443
435
  /**
444
436
  * **Note that this will result in invalid HTML!**
445
437
  *
@@ -449,7 +441,7 @@ export type MinifierOptions = {
449
441
  *
450
442
  * Default: `false`
451
443
  */
452
- removeTagWhitespace?: boolean;
444
+ removeTagWhitespace?: boolean | undefined;
453
445
  /**
454
446
  * When true, enables sorting of attributes. If a function is provided it
455
447
  * will be used as a custom attribute sorter, which should mutate `attrs`
@@ -458,7 +450,7 @@ export type MinifierOptions = {
458
450
  *
459
451
  * Default: `false`
460
452
  */
461
- sortAttributes?: boolean | ((tag: string, attrs: HTMLAttribute[]) => void);
453
+ sortAttributes?: boolean | ((tag: string, attrs: HTMLAttribute[]) => void) | undefined;
462
454
  /**
463
455
  * When true, enables sorting of class names inside `class` attributes.
464
456
  * If a function is provided, it will be used to transform/sort the class
@@ -467,7 +459,7 @@ export type MinifierOptions = {
467
459
  *
468
460
  * Default: `false`
469
461
  */
470
- sortClassNames?: boolean | ((value: string) => string);
462
+ sortClassNames?: boolean | ((value: string) => string) | undefined;
471
463
  /**
472
464
  * When true, whitespace around ignored custom fragments may be trimmed
473
465
  * more aggressively. This affects how preserved fragments interact with
@@ -475,14 +467,14 @@ export type MinifierOptions = {
475
467
  *
476
468
  * Default: `false`
477
469
  */
478
- trimCustomFragments?: boolean;
470
+ trimCustomFragments?: boolean | undefined;
479
471
  /**
480
472
  * Replace the HTML doctype with the short `<!doctype html>` form.
481
473
  * See also: https://perfectionkills.com/experimenting-with-html-minifier/#use_short_doctype
482
474
  *
483
475
  * Default: `false`
484
476
  */
485
- useShortDoctype?: boolean;
477
+ useShortDoctype?: boolean | undefined;
486
478
  };
487
479
  import { presets } from './presets.js';
488
480
  import { getPreset } from './presets.js';
@@ -1 +1 @@
1
- {"version":3,"file":"htmlminifier.d.ts","sourceRoot":"","sources":["../../src/htmlminifier.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"htmlminifier.d.ts","sourceRoot":"","sources":["../../src/htmlminifier.js"],"names":[],"mappings":"AAyrDO,8BAJI,MAAM,YACN,eAAe,GACb,OAAO,CAAC,MAAM,CAAC,CAwB3B;;;;;;;;;;;;UA99CS,MAAM;;;;;;;;;;;;;;;;;;mCAaA,MAAM,SAAS,aAAa,EAAE,yBAAyB,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,KAAK,OAAO;;;;;;;+BAM3F,MAAM,GAAG,IAAI,SAAS,aAAa,EAAE,GAAG,SAAS,qBAAqB,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,KAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA6JtG,OAAO,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2HA2BiF,MAAM,SAAS,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;;;;;;;;;;;;;;;;iBASxG,QAAQ,GAAG,KAAK;gBAAgC,MAAM,WAAW,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;;;;;;;;;;;eAa/H,MAAM;gBAAY,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM;;;;;;;;;;;;;;;;;mBAiBzE,MAAM,KAAK,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDA+DF,MAAM,OAAO,MAAM,KAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCA2EpC,MAAM,SAAS,aAAa,EAAE,KAAK,IAAI;;;;;;;;;wCAQrC,MAAM,KAAK,MAAM;;;;;;;;;;;;;;;;;wBAjnBK,cAAc;0BAAd,cAAc;+BAAd,cAAc"}
@@ -1,4 +1,3 @@
1
- export function isConditionalComment(text: any): boolean;
2
1
  export function isIgnoredComment(text: any, options: any): boolean;
3
2
  export function isEventAttribute(attrName: any, options: any): boolean;
4
3
  export function canRemoveAttributeQuotes(value: any): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/attributes.js"],"names":[],"mappings":"AAoCA,yDAEC;AAED,mEAOC;AAED,uEAWC;AAED,8DAGC;AAED,4EAOC;AAgCD,mGAuCC;AAED,mEAGC;AAED,qEAGC;AAED,kEAWC;AAED,sEAGC;AAED,8DAWC;AAED,2EAIC;AAmBD,qEAGC;AAgBD,wEAGC;AAED,sEAUC;AAED,2EAEC;AAED,2DAEC;AAED,8DAUC;AAED,uEAUC;AAED,oGASC;AAED,4DAOC;AAMD,iIA0KC;AAwBD,mGAYC;AA0CD,6GAuHC;AAllBD;;;;;;;GAOG;AACH,mEAHW,OAAO,SAuBjB"}
1
+ {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/attributes.js"],"names":[],"mappings":"AAmCA,mEAOC;AAED,uEAWC;AAED,8DAGC;AAED,4EAOC;AAgCD,mGAuCC;AAED,mEAGC;AAED,qEAGC;AAED,kEAWC;AAED,sEAGC;AAED,8DAWC;AAED,2EAIC;AAmBD,qEAGC;AAgBD,wEAGC;AAED,sEAUC;AAED,2EAEC;AAED,2DAEC;AAED,8DAUC;AAED,uEAUC;AAED,oGASC;AAED,4DAOC;AAMD,iIA0KC;AAwBD,mGAYC;AA0CD,6GAuHC;AAllBD;;;;;;;GAOG;AACH,mEAHW,OAAO,SAuBjB"}
@@ -5,7 +5,6 @@ export const RE_NBSP_LEADING_GROUP: RegExp;
5
5
  export const RE_NBSP_LEAD_GROUP: RegExp;
6
6
  export const RE_NBSP_TRAILING_GROUP: RegExp;
7
7
  export const RE_NBSP_TRAILING_STRIP: RegExp;
8
- export const RE_CONDITIONAL_COMMENT: RegExp;
9
8
  export const RE_EVENT_ATTR_DEFAULT: RegExp;
10
9
  export const RE_CAN_REMOVE_ATTR_QUOTES: RegExp;
11
10
  export const RE_TRAILING_SEMICOLON: RegExp;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/lib/constants.js"],"names":[],"mappings":"AAEA,iCAAoC;AACpC,+BAAkC;AAClC,oCAA2C;AAC3C,2CAAmD;AACnD,wCAA8C;AAC9C,4CAAkD;AAClD,4CAA2C;AAC3C,4CAA0D;AAC1D,2CAA8C;AAC9C,+CAA0D;AAC1D,2CAAmC;AACnC,mCAA4C;AAC5C,wCAAwqB;AACxqB,kCAA0B;AAC1B,sCAAuC;AACvC,yCAA4C;AAC5C,qCAAuD;AAKvD,+DAAgb;AAGhb,+DAA6O;AAG7O,yDAAmF;AAGnF,8CAA8G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0C9G,qDAWG;AAEH,+CAEG;AAuBH,0CAUG;AA7BH,0CAAwhB;AAExhB,yCAAkD;AAMlD,yDAGG;AAIH,yCAAkD;AAuBlD,4CAAiF;AAEjF,0CAAoM;AAEpM,yCAA4F;AAE5F,8CAAkD;AAElD,yCAAiT;AAEjT,0CAA0F;AAE1F,6CAA8D;AAE9D,gDAAqD;AAErD,yCAAuD;AAEvD,+CAAyD;AAEzD,+CAAkE;AAElE,uCAA2C;AAE3C,2CAA2D;AAE3D,0CAAkD;AAElD,wCAA+D;AAE/D,2CAAkD;AAElD,uCAAmxC;AAInxC,sCAEsD;AAItD,iDAA4D"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/lib/constants.js"],"names":[],"mappings":"AAEA,iCAAoC;AACpC,+BAAkC;AAClC,oCAA2C;AAC3C,2CAAmD;AACnD,wCAA8C;AAC9C,4CAAkD;AAClD,4CAA2C;AAC3C,2CAA8C;AAC9C,+CAA0D;AAC1D,2CAAmC;AACnC,mCAA4C;AAC5C,wCAAwqB;AACxqB,kCAA0B;AAC1B,sCAAuC;AACvC,yCAA4C;AAC5C,qCAAuD;AAKvD,+DAAgb;AAGhb,+DAA6O;AAG7O,yDAAmF;AAGnF,8CAA8G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0C9G,qDAWG;AAEH,+CAEG;AAuBH,0CAUG;AA7BH,0CAAwhB;AAExhB,yCAAkD;AAMlD,yDAGG;AAIH,yCAAkD;AAuBlD,4CAAiF;AAEjF,0CAAoM;AAEpM,yCAA4F;AAE5F,8CAAkD;AAElD,yCAAiT;AAEjT,0CAA0F;AAE1F,6CAA8D;AAE9D,gDAAqD;AAErD,yCAAuD;AAEvD,+CAAyD;AAEzD,+CAAkE;AAElE,uCAA2C;AAE3C,2CAA2D;AAE3D,0CAAkD;AAElD,wCAA+D;AAE/D,2CAAkD;AAElD,uCAAmxC;AAInxC,sCAEsD;AAItD,iDAA4D"}
@@ -1,6 +1,5 @@
1
1
  export function wrapCSS(text: any, type: any): any;
2
2
  export function unwrapCSS(text: any, type: any): any;
3
- export function cleanConditionalComment(comment: any, options: any, minifyHTML: any): Promise<any>;
4
3
  export function minifyJson(text: any, options: any): any;
5
4
  export function hasJsonScriptType(attrs: any): boolean;
6
5
  export function processScript(text: any, options: any, currentAttrs: any, minifyHTML: any): Promise<any>;
@@ -1 +1 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../src/lib/content.js"],"names":[],"mappings":"AAYA,mDASC;AAED,qDAWC;AAED,mGAMC;AAID,yDAWC;AAED,uDAWC;AAED,yGAiBC"}
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../src/lib/content.js"],"names":[],"mappings":"AAWA,mDASC;AAED,qDAWC;AAID,yDAWC;AAED,uDAWC;AAED,yGAiBC"}
@@ -177,108 +177,102 @@ export namespace optionDefinitions {
177
177
  let type_29: string;
178
178
  export { type_29 as type };
179
179
  }
180
- namespace processConditionalComments {
180
+ namespace processScripts {
181
181
  let description_30: string;
182
182
  export { description_30 as description };
183
183
  let type_30: string;
184
184
  export { type_30 as type };
185
185
  }
186
- namespace processScripts {
186
+ namespace quoteCharacter {
187
187
  let description_31: string;
188
188
  export { description_31 as description };
189
189
  let type_31: string;
190
190
  export { type_31 as type };
191
191
  }
192
- namespace quoteCharacter {
192
+ namespace removeAttributeQuotes {
193
193
  let description_32: string;
194
194
  export { description_32 as description };
195
195
  let type_32: string;
196
196
  export { type_32 as type };
197
197
  }
198
- namespace removeAttributeQuotes {
198
+ namespace removeComments {
199
199
  let description_33: string;
200
200
  export { description_33 as description };
201
201
  let type_33: string;
202
202
  export { type_33 as type };
203
203
  }
204
- namespace removeComments {
204
+ namespace removeEmptyAttributes {
205
205
  let description_34: string;
206
206
  export { description_34 as description };
207
207
  let type_34: string;
208
208
  export { type_34 as type };
209
209
  }
210
- namespace removeEmptyAttributes {
210
+ namespace removeEmptyElements {
211
211
  let description_35: string;
212
212
  export { description_35 as description };
213
213
  let type_35: string;
214
214
  export { type_35 as type };
215
215
  }
216
- namespace removeEmptyElements {
216
+ namespace removeEmptyElementsExcept {
217
217
  let description_36: string;
218
218
  export { description_36 as description };
219
219
  let type_36: string;
220
220
  export { type_36 as type };
221
221
  }
222
- namespace removeEmptyElementsExcept {
222
+ namespace removeOptionalTags {
223
223
  let description_37: string;
224
224
  export { description_37 as description };
225
225
  let type_37: string;
226
226
  export { type_37 as type };
227
227
  }
228
- namespace removeOptionalTags {
228
+ namespace removeRedundantAttributes {
229
229
  let description_38: string;
230
230
  export { description_38 as description };
231
231
  let type_38: string;
232
232
  export { type_38 as type };
233
233
  }
234
- namespace removeRedundantAttributes {
234
+ namespace removeScriptTypeAttributes {
235
235
  let description_39: string;
236
236
  export { description_39 as description };
237
237
  let type_39: string;
238
238
  export { type_39 as type };
239
239
  }
240
- namespace removeScriptTypeAttributes {
240
+ namespace removeStyleLinkTypeAttributes {
241
241
  let description_40: string;
242
242
  export { description_40 as description };
243
243
  let type_40: string;
244
244
  export { type_40 as type };
245
245
  }
246
- namespace removeStyleLinkTypeAttributes {
246
+ namespace removeTagWhitespace {
247
247
  let description_41: string;
248
248
  export { description_41 as description };
249
249
  let type_41: string;
250
250
  export { type_41 as type };
251
251
  }
252
- namespace removeTagWhitespace {
252
+ namespace sortAttributes {
253
253
  let description_42: string;
254
254
  export { description_42 as description };
255
255
  let type_42: string;
256
256
  export { type_42 as type };
257
257
  }
258
- namespace sortAttributes {
258
+ namespace sortClassNames {
259
259
  let description_43: string;
260
260
  export { description_43 as description };
261
261
  let type_43: string;
262
262
  export { type_43 as type };
263
263
  }
264
- namespace sortClassNames {
264
+ namespace trimCustomFragments {
265
265
  let description_44: string;
266
266
  export { description_44 as description };
267
267
  let type_44: string;
268
268
  export { type_44 as type };
269
269
  }
270
- namespace trimCustomFragments {
270
+ namespace useShortDoctype {
271
271
  let description_45: string;
272
272
  export { description_45 as description };
273
273
  let type_45: string;
274
274
  export { type_45 as type };
275
275
  }
276
- namespace useShortDoctype {
277
- let description_46: string;
278
- export { description_46 as description };
279
- let type_46: string;
280
- export { type_46 as type };
281
- }
282
276
  }
283
277
  export namespace optionDefaults {
284
278
  let continueOnMinifyError_1: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/lib/options.js"],"names":[],"mappings":"AAYA,6DAUC;AAID;;;;;;;;;;;GAWG;AACH,6CAXW,OAAO,CAAC,eAAe,CAAC,mGAEhC;IAAuB,eAAe;IACf,SAAS;IACT,MAAM;CAA2B,GAK9C,eAAe,CA+W3B"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/lib/options.js"],"names":[],"mappings":"AAYA,6DAUC;AAID;;;;;;;;;;;GAWG;AACH,6CAXW,OAAO,CAAC,eAAe,CAAC,mGAEhC;IAAuB,eAAe;IACf,SAAS;IACT,MAAM;CAA2B,GAK9C,eAAe,CAiX3B"}
@@ -16,7 +16,6 @@ export namespace presets {
16
16
  let collapseWhitespace: boolean;
17
17
  let conservativeCollapse: boolean;
18
18
  let preserveLineBreaks: boolean;
19
- let processConditionalComments: boolean;
20
19
  let removeComments: boolean;
21
20
  let removeScriptTypeAttributes: boolean;
22
21
  let removeStyleLinkTypeAttributes: boolean;
@@ -35,8 +34,6 @@ export namespace presets {
35
34
  export let minifyJS: boolean;
36
35
  export let minifySVG: boolean;
37
36
  export let minifyURLs: boolean;
38
- let processConditionalComments_1: boolean;
39
- export { processConditionalComments_1 as processConditionalComments };
40
37
  export let removeAttributeQuotes: boolean;
41
38
  let removeComments_1: boolean;
42
39
  export { removeComments_1 as removeComments };
@@ -1 +1 @@
1
- {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/presets.js"],"names":[],"mappings":"AA4CA;;;;GAIG;AACH,gCAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CAMvB;AAED;;;GAGG;AACH,kCAFa,MAAM,EAAE,CAIpB"}
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/presets.js"],"names":[],"mappings":"AA0CA;;;;GAIG;AACH,gCAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CAMvB;AAED;;;GAGG;AACH,kCAFa,MAAM,EAAE,CAIpB"}
package/package.json CHANGED
@@ -6,24 +6,24 @@
6
6
  "bugs": "https://github.com/j9t/html-minifier-next/issues",
7
7
  "dependencies": {
8
8
  "commander": "^14.0.2",
9
- "entities": "^7.0.1",
9
+ "entities": "^8.0.0",
10
10
  "lightningcss": "^1.32.0",
11
11
  "svgo": "^4.0.1",
12
- "terser": "^5.46.0"
12
+ "terser": "^5.46.1"
13
13
  },
14
14
  "description": "Super-configurable and well-tested web page minifier (enhanced successor of HTML Minifier)",
15
15
  "devDependencies": {
16
- "@commitlint/cli": "^20.3.1",
16
+ "@commitlint/cli": "^20.5.0",
17
17
  "@eslint/js": "^10.0.1",
18
18
  "@rollup/plugin-commonjs": "^29.0.2",
19
19
  "@rollup/plugin-json": "^6.1.0",
20
20
  "@rollup/plugin-node-resolve": "^16.0.3",
21
- "@swc/core": "^1.15.11",
22
- "eslint": "^10.0.0",
23
- "rollup": "^4.59.0",
21
+ "@swc/core": "^1.15.21",
22
+ "eslint": "^10.1.0",
23
+ "rollup": "^4.60.0",
24
24
  "rollup-plugin-polyfill-node": "^0.13.0",
25
- "typescript": "^5.9.3",
26
- "vite": "^8.0.1"
25
+ "typescript": "^6.0.2",
26
+ "vite": "^8.0.5"
27
27
  },
28
28
  "exports": {
29
29
  ".": {
@@ -96,5 +96,5 @@
96
96
  },
97
97
  "type": "module",
98
98
  "types": "./dist/types/htmlminifier.d.ts",
99
- "version": "5.2.2"
99
+ "version": "6.1.1"
100
100
  }
@@ -32,7 +32,6 @@ import {
32
32
  } from './lib/whitespace.js';
33
33
 
34
34
  import {
35
- isConditionalComment,
36
35
  isIgnoredComment,
37
36
  isExecutableScript,
38
37
  isStyleElement,
@@ -51,7 +50,6 @@ import {
51
50
  } from './lib/elements.js';
52
51
 
53
52
  import {
54
- cleanConditionalComment,
55
53
  hasJsonScriptType,
56
54
  processScript
57
55
  } from './lib/content.js';
@@ -182,16 +180,16 @@ function mergeConsecutiveScripts(html) {
182
180
  return match;
183
181
  }
184
182
 
185
- // Check `type` compatibility (both must be same, or both default JS)
186
- const type1 = a1.type || '';
187
- const type2 = a2.type || '';
183
+ // Check `type` compatibility (both must be default JS)
184
+ const type1 = (a1.type || '').toLowerCase();
185
+ const type2 = (a2.type || '').toLowerCase();
188
186
 
189
187
  if (DEFAULT_JS_TYPES.has(type1) && DEFAULT_JS_TYPES.has(type2)) {
190
188
  // Both are default JavaScript—compatible
191
- } else if (type1 === type2) {
192
- // Same explicit type—compatible
193
189
  } else {
194
- // Incompatible types
190
+ // Non-JS types (modules, JSON, etc.) must not be merged:
191
+ // Module scripts have per-script lexical scope, and non-JS content (e.g., JSON)
192
+ // is not concatenable. Even identical non-JS types are incompatible.
195
193
  return match;
196
194
  }
197
195
 
@@ -518,13 +516,6 @@ function mergeConsecutiveScripts(html) {
518
516
  *
519
517
  * Default: `false`
520
518
  *
521
- * @prop {boolean} [processConditionalComments]
522
- * When true, conditional comments (for example `<!--[if IE]> … <![endif]-->`)
523
- * will have their inner content processed by the minifier.
524
- * Useful to minify HTML that appears inside conditional comments.
525
- *
526
- * Default: `false`
527
- *
528
519
  * @prop {string[]} [processScripts]
529
520
  * Array of `type` attribute values for `<script>` elements whose contents
530
521
  * should be processed as HTML
@@ -1012,11 +1003,11 @@ async function minifyHTML(value, options, partialMarkup) {
1012
1003
 
1013
1004
  if (options.minifyJS) {
1014
1005
  options.minifyJS = (function (fn) {
1015
- return function (text, type) {
1006
+ return function (text, inline, isModule) {
1016
1007
  return fn(text.replace(uidPattern, function (match, prefix, index) {
1017
1008
  const chunks = ignoredCustomMarkupChunks[+index];
1018
1009
  return chunks[1] + uidAttr + index + uidAttr + chunks[2];
1019
- }), type);
1010
+ }), inline, isModule);
1020
1011
  };
1021
1012
  })(options.minifyJS);
1022
1013
  }
@@ -1339,6 +1330,9 @@ async function minifyHTML(value, options, partialMarkup) {
1339
1330
  const needsDecode = options.decodeEntities && text && !specialContentElements.has(currentTag) && text.indexOf('&') !== -1;
1340
1331
  const needsProcessScript = specialContentElements.has(currentTag) && (options.processScripts || hasJsonScriptType(currentAttrs));
1341
1332
  const needsMinifyJS = options.minifyJS !== identity && isExecutableScript(currentTag, currentAttrs);
1333
+ const isModuleScript = needsMinifyJS && currentAttrs.some(
1334
+ a => a.name.toLowerCase() === 'type' && (a.value ?? '').trim().toLowerCase() === 'module'
1335
+ );
1342
1336
  const needsMinifyCSS = options.minifyCSS !== identity && isStyleElement(currentTag, currentAttrs);
1343
1337
 
1344
1338
  // Whitespace collapsing phase (sync); captures `prevTag`/`nextTag`/`prevAttrs`/`nextAttrs` from outer scope
@@ -1465,7 +1459,7 @@ async function minifyHTML(value, options, partialMarkup) {
1465
1459
  text = await processScript(text, options, currentAttrs, minifyHTML);
1466
1460
  }
1467
1461
  if (needsMinifyJS) {
1468
- text = await options.minifyJS(text);
1462
+ text = await options.minifyJS(text, false, isModuleScript);
1469
1463
  }
1470
1464
  if (needsMinifyCSS) {
1471
1465
  text = await options.minifyCSS(text);
@@ -1560,16 +1554,9 @@ async function minifyHTML(value, options, partialMarkup) {
1560
1554
  buffer.push(comment);
1561
1555
  }
1562
1556
 
1563
- // Only conditional comments require async work (recursive minification)
1564
- if (isConditionalComment(text)) {
1565
- return cleanConditionalComment(text, options, minifyHTML).then(cleaned => {
1566
- commentFinalize(prefix + cleaned + suffix);
1567
- });
1568
- }
1569
-
1570
1557
  if (options.removeComments) {
1571
1558
  if (isIgnoredComment(text, options)) {
1572
- text = '<!--' + text + '-->';
1559
+ text = prefix + text + suffix;
1573
1560
  } else {
1574
1561
  text = '';
1575
1562
  }
@@ -1,7 +1,6 @@
1
1
  // Imports
2
2
 
3
3
  import {
4
- RE_CONDITIONAL_COMMENT,
5
4
  RE_EVENT_ATTR_DEFAULT,
6
5
  RE_CAN_REMOVE_ATTR_QUOTES,
7
6
  RE_AMP_ENTITY,
@@ -34,10 +33,6 @@ async function getDecodeHTMLStrict() {
34
33
 
35
34
  // Validators
36
35
 
37
- function isConditionalComment(text) {
38
- return RE_CONDITIONAL_COMMENT.test(text);
39
- }
40
-
41
36
  function isIgnoredComment(text, options) {
42
37
  for (let i = 0, len = options.ignoreCustomComments.length; i < len; i++) {
43
38
  if (options.ignoreCustomComments[i].test(text)) {
@@ -674,7 +669,6 @@ function buildAttr(normalized, hasUnarySlash, options, isLast, uidAttr) {
674
669
 
675
670
  export {
676
671
  // Validators
677
- isConditionalComment,
678
672
  isIgnoredComment,
679
673
  isEventAttribute,
680
674
  canRemoveAttributeQuotes,
@@ -7,7 +7,6 @@ const RE_NBSP_LEADING_GROUP = /(^|\xA0+)[^\xA0]+/g;
7
7
  const RE_NBSP_LEAD_GROUP = /(\xA0+)[^\xA0]+/g;
8
8
  const RE_NBSP_TRAILING_GROUP = /[^\xA0]+(\xA0+)/g;
9
9
  const RE_NBSP_TRAILING_STRIP = /[^\xA0]+$/;
10
- const RE_CONDITIONAL_COMMENT = /^\[if\s[^\]]+]|\[endif]$/;
11
10
  const RE_EVENT_ATTR_DEFAULT = /^on[a-z]{3,}$/;
12
11
  const RE_CAN_REMOVE_ATTR_QUOTES = /^[^ \t\n\f\r"'`=<>]+$/;
13
12
  const RE_TRAILING_SEMICOLON = /;$/;
@@ -184,7 +183,6 @@ export {
184
183
  RE_NBSP_LEAD_GROUP,
185
184
  RE_NBSP_TRAILING_GROUP,
186
185
  RE_NBSP_TRAILING_STRIP,
187
- RE_CONDITIONAL_COMMENT,
188
186
  RE_EVENT_ATTR_DEFAULT,
189
187
  RE_CAN_REMOVE_ATTR_QUOTES,
190
188
  RE_TRAILING_SEMICOLON,
@@ -3,7 +3,6 @@
3
3
  import {
4
4
  jsonScriptTypes
5
5
  } from './constants.js';
6
- import { replaceAsync } from './utils.js';
7
6
  import { trimWhitespace } from './whitespace.js';
8
7
 
9
8
  // CSS processing
@@ -34,14 +33,6 @@ function unwrapCSS(text, type) {
34
33
  return matches ? matches[1] : text;
35
34
  }
36
35
 
37
- async function cleanConditionalComment(comment, options, minifyHTML) {
38
- return options.processConditionalComments
39
- ? await replaceAsync(comment, /^(\[if\s[^\]]+]>)([\s\S]*?)(<!\[endif])$/, async function (match, prefix, text, suffix) {
40
- return prefix + await minifyHTML(text, options, true) + suffix;
41
- })
42
- : comment;
43
- }
44
-
45
36
  // Script processing
46
37
 
47
38
  function minifyJson(text, options) {
@@ -95,7 +86,6 @@ export {
95
86
  // CSS
96
87
  wrapCSS,
97
88
  unwrapCSS,
98
- cleanConditionalComment,
99
89
 
100
90
  // Scripts
101
91
  minifyJson,
@@ -121,10 +121,6 @@ const optionDefinitions = {
121
121
  description: 'Prevents the escaping of the values of attributes',
122
122
  type: 'boolean'
123
123
  },
124
- processConditionalComments: {
125
- description: 'Process contents of conditional comments through minifier',
126
- type: 'boolean'
127
- },
128
124
  processScripts: {
129
125
  description: 'Array of strings corresponding to types of `script` elements to process through minifier (e.g., `text/ng-template`, `text/x-handlebars-template`, etc.)',
130
126
  type: 'jsonArray'
@@ -228,7 +228,7 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, getS
228
228
  cont: !!options.continueOnMinifyError
229
229
  });
230
230
 
231
- options.minifyJS = async function (text, inline) {
231
+ options.minifyJS = async function (text, inline, isModule) {
232
232
  const start = text.match(/^\s*<!--.*/);
233
233
  const code = start ? text.slice(start[0].length).replace(/\n\s*-->\s*$/, '') : text;
234
234
 
@@ -248,7 +248,7 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, getS
248
248
 
249
249
  // For large inputs, use length and content fingerprint to prevent collisions
250
250
  jsKey = (code.length > 2048 ? (code.length + '|' + code.slice(0, 50) + code.slice(-50) + '|') : (code + '|'))
251
- + (inline ? '1' : '0') + '|' + useEngine + '|' + optsSig;
251
+ + (inline ? '1' : '0') + '|' + (isModule ? 'm' : '') + '|' + useEngine + '|' + optsSig;
252
252
 
253
253
  const cached = jsMinifyCache.get(jsKey);
254
254
  if (cached) {
@@ -264,7 +264,8 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, getS
264
264
  parse: {
265
265
  ...terserOptions.parse,
266
266
  bare_returns: inline
267
- }
267
+ },
268
+ ...(isModule ? { module: true } : {}) // Overrides user options: module detection takes precedence for `<script type=module>`
268
269
  };
269
270
  const terser = await getTerser();
270
271
  const result = await terser(code, terserCallOptions);
@@ -275,7 +276,8 @@ const processOptions = (inputOptions, { getLightningCSS, getTerser, getSwc, getS
275
276
  const result = await swc.minify(code, {
276
277
  compress: true,
277
278
  mangle: true,
278
- ...swcOptions, // User options override defaults
279
+ ...swcOptions,
280
+ ...(isModule ? { module: true } : {}) // Overrides user options: module detection takes precedence for `<script type=module>`
279
281
  });
280
282
  return result.code.replace(RE_TRAILING_SEMICOLON, '');
281
283
  }
package/src/presets.js CHANGED
@@ -13,7 +13,6 @@ export const presets = {
13
13
  collapseWhitespace: true,
14
14
  conservativeCollapse: true,
15
15
  preserveLineBreaks: true,
16
- processConditionalComments: true,
17
16
  removeComments: true,
18
17
  removeScriptTypeAttributes: true,
19
18
  removeStyleLinkTypeAttributes: true,
@@ -30,7 +29,6 @@ export const presets = {
30
29
  minifyJS: true,
31
30
  minifySVG: true,
32
31
  minifyURLs: true,
33
- processConditionalComments: true,
34
32
  removeAttributeQuotes: true,
35
33
  removeComments: true,
36
34
  removeEmptyAttributes: true,