html-minifier-next 1.3.3 → 1.4.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
@@ -57,7 +57,7 @@ Use `html-minifier-next --help` to check all available options:
57
57
  | --- | --- | --- |
58
58
  | `--input-dir <dir>` | Specify an input directory | `--input-dir=src` |
59
59
  | `--output-dir <dir>` | Specify an output directory | `--output-dir=dist` |
60
- | `--file-ext <extensions>` | Specify file extension(s) to process (overrides config file setting) | `--file-ext=html` or `--file-ext=html,htm,php` |
60
+ | `--file-ext <extensions>` | Specify file extension(s) to process (overrides config file setting) | `--file-ext=html`, `--file-ext=html,htm,php`, `--file-ext="html, htm, php"` |
61
61
  | `-o --output <file>` | Specify output file (single file mode) | `-o minified.html` |
62
62
  | `-c --config-file <file>` | Use a configuration file | `--config-file=html-minifier.json` |
63
63
 
@@ -157,59 +157,59 @@ Most of the options are disabled by default.
157
157
  | `caseSensitive` | Treat attributes in case-sensitive manner (useful for custom HTML elements) | `false` |
158
158
  | `collapseBooleanAttributes` | [Omit attribute values from boolean attributes](http://perfectionkills.com/experimenting-with-html-minifier#collapse_boolean_attributes) | `false` |
159
159
  | `customFragmentQuantifierLimit` | Set maximum quantifier limit for custom fragments to prevent ReDoS attacks | `200` |
160
- | `collapseInlineTagWhitespace` | Don’t leave any spaces between `display:inline;` elements when collapsing. Must be used in conjunction with `collapseWhitespace=true` | `false` |
161
- | `collapseWhitespace` | [Collapse white space that contributes to text nodes in a document tree](http://perfectionkills.com/experimenting-with-html-minifier#collapse_whitespace) | `false` |
162
- | `conservativeCollapse` | Always collapse to 1 space (never remove it entirely). Must be used in conjunction with `collapseWhitespace=true` | `false` |
163
- | `continueOnParseError` | [Handle parse errors](https://html.spec.whatwg.org/multipage/parsing.html#parse-errors) instead of aborting. | `false` |
164
- | `customAttrAssign` | Arrays of regex’es that allow to support custom attribute assign expressions (e.g. `'<div flex?="{{mode != cover}}"></div>'`) | `[]` |
165
- | `customAttrCollapse` | Regex that specifies custom attribute to strip newlines from (e.g. `/ng-class/`) | |
166
- | `customAttrSurround` | Arrays of regexes that allow to support custom attribute surround expressions (e.g. `<input {{#if value}}checked="checked"{{/if}}>`) | `[]` |
167
- | `customEventAttributes` | Arrays of regexes that allow to support custom event attributes for `minifyJS` (e.g. `ng-click`) | `[ /^on[a-z]{3,}$/ ]` |
160
+ | `collapseInlineTagWhitespace` | Don’t leave any spaces between `display: inline;` elements when collapsing—use with `collapseWhitespace=true` | `false` |
161
+ | `collapseWhitespace` | [Collapse whitespace that contributes to text nodes in a document tree](http://perfectionkills.com/experimenting-with-html-minifier#collapse_whitespace) | `false` |
162
+ | `conservativeCollapse` | Always collapse to 1 space (never remove it entirely)—use with `collapseWhitespace=true` | `false` |
163
+ | `continueOnParseError` | [Handle parse errors](https://html.spec.whatwg.org/multipage/parsing.html#parse-errors) instead of aborting | `false` |
164
+ | `customAttrAssign` | Arrays of regexes that allow to support custom attribute assign expressions (e.g., `'<div flex?="{{mode != cover}}"></div>'`) | `[]` |
165
+ | `customAttrCollapse` | Regex that specifies custom attribute to strip newlines from (e.g., `/ng-class/`) | |
166
+ | `customAttrSurround` | Arrays of regexes that allow to support custom attribute surround expressions (e.g., `<input {{#if value}}checked="checked"{{/if}}>`) | `[]` |
167
+ | `customEventAttributes` | Arrays of regexes that allow to support custom event attributes for `minifyJS` (e.g., `ng-click`) | `[ /^on[a-z]{3,}$/ ]` |
168
168
  | `decodeEntities` | Use direct Unicode characters whenever possible | `false` |
169
- | `html5` | Parse input according to HTML5 specifications | `true` |
169
+ | `html5` | Parse input according to the HTML specification | `true` |
170
170
  | `ignoreCustomComments` | Array of regexes that allow to ignore certain comments, when matched | `[ /^!/, /^\s*#/ ]` |
171
- | `ignoreCustomFragments` | Array of regexes that allow to ignore certain fragments, when matched (e.g. `<?php ... ?>`, `{{ ... }}`, etc.) | `[ /<%[\s\S]*?%>/, /<\?[\s\S]*?\?>/ ]` |
171
+ | `ignoreCustomFragments` | Array of regexes that allow to ignore certain fragments, when matched (e.g., `<?php ?>`, `{{ }}`, etc.) | `[ /<%[\s\S]*?%>/, /<\?[\s\S]*?\?>/ ]` |
172
172
  | `includeAutoGeneratedTags` | Insert elements generated by HTML parser | `true` |
173
173
  | `inlineCustomElements` | Array of names of custom elements which are inline | `[]` |
174
- | `keepClosingSlash` | Keep the trailing slash on singleton elements | `false` |
174
+ | `keepClosingSlash` | Keep the trailing slash on void elements | `false` |
175
175
  | `maxInputLength` | Maximum input length to prevent ReDoS attacks (disabled by default) | `undefined` |
176
- | `maxLineLength` | Specify a maximum line length. Compressed output will be split by newlines at valid HTML split-points |
177
- | `minifyCSS` | Minify CSS in style elements and style attributes (uses [clean-css](https://github.com/jakubpawlowicz/clean-css)) | `false` (could be `true`, `Object`, `Function(text, type)`) |
178
- | `minifyJS` | Minify JavaScript in script elements and event attributes (uses [Terser](https://github.com/terser/terser)) | `false` (could be `true`, `Object`, `Function(text, inline)`) |
176
+ | `maxLineLength` | Specify a maximum line length; compressed output will be split by newlines at valid HTML split-points | |
177
+ | `minifyCSS` | Minify CSS in `style` elements and `style` attributes (uses [clean-css](https://github.com/jakubpawlowicz/clean-css)) | `false` (could be `true`, `Object`, `Function(text, type)`) |
178
+ | `minifyJS` | Minify JavaScript in `script` elements and event attributes (uses [Terser](https://github.com/terser/terser)) | `false` (could be `true`, `Object`, `Function(text, inline)`) |
179
179
  | `minifyURLs` | Minify URLs in various attributes (uses [relateurl](https://github.com/stevenvachon/relateurl)) | `false` (could be `String`, `Object`, `Function(text)`) |
180
180
  | `noNewlinesBeforeTagClose` | Never add a newline before a tag that closes an element | `false` |
181
- | `preserveLineBreaks` | Always collapse to 1 line break (never remove it entirely) when whitespace between tags include a line break. Must be used in conjunction with `collapseWhitespace=true` | `false` |
181
+ | `preserveLineBreaks` | Always collapse to 1 line break (never remove it entirely) when whitespace between tags includes a line break—use with `collapseWhitespace=true` | `false` |
182
182
  | `preventAttributesEscaping` | Prevents the escaping of the values of attributes | `false` |
183
183
  | `processConditionalComments` | Process contents of conditional comments through minifier | `false` |
184
- | `processScripts` | Array of strings corresponding to types of script elements to process through minifier (e.g. `text/ng-template`, `text/x-handlebars-template`, etc.) | `[]` |
185
- | `quoteCharacter` | Type of quote to use for attribute values (' or ") | |
184
+ | `processScripts` | Array of strings corresponding to types of `script` elements to process through minifier (e.g., `text/ng-template`, `text/x-handlebars-template`, etc.) | `[]` |
185
+ | `quoteCharacter` | Type of quote to use for attribute values (`'` or `"`) | |
186
186
  | `removeAttributeQuotes` | [Remove quotes around attributes when possible](http://perfectionkills.com/experimenting-with-html-minifier#remove_attribute_quotes) | `false` |
187
187
  | `removeComments` | [Strip HTML comments](http://perfectionkills.com/experimenting-with-html-minifier#remove_comments) | `false` |
188
188
  | `removeEmptyAttributes` | [Remove all attributes with whitespace-only values](http://perfectionkills.com/experimenting-with-html-minifier#remove_empty_or_blank_attributes) | `false` (could be `true`, `Function(attrName, tag)`) |
189
189
  | `removeEmptyElements` | [Remove all elements with empty contents](http://perfectionkills.com/experimenting-with-html-minifier#remove_empty_elements) | `false` |
190
190
  | `removeOptionalTags` | [Remove optional tags](http://perfectionkills.com/experimenting-with-html-minifier#remove_optional_tags) | `false` |
191
191
  | `removeRedundantAttributes` | [Remove attributes when value matches default.](http://perfectionkills.com/experimenting-with-html-minifier#remove_redundant_attributes) | `false` |
192
- | `removeScriptTypeAttributes` | Remove `type="text/javascript"` from `script` elements. Other `type` attribute values are left intact | `false` |
193
- | `removeStyleLinkTypeAttributes`| Remove `type="text/css"` from `style` and `link` elements. Other `type` attribute values are left intact | `false` |
194
- | `removeTagWhitespace` | Remove space between attributes whenever possible. **Note that this will result in invalid HTML!** | `false` |
195
- | `sortAttributes` | [Sort attributes by frequency](#sorting-attributes--style-classes) | `false` |
196
- | `sortClassName` | [Sort style classes by frequency](#sorting-attributes--style-classes) | `false` |
197
- | `trimCustomFragments` | Trim white space around `ignoreCustomFragments`. | `false` |
198
- | `useShortDoctype` | [Replaces the `doctype` with the short (HTML5) doctype](http://perfectionkills.com/experimenting-with-html-minifier#use_short_doctype) | `false` |
192
+ | `removeScriptTypeAttributes` | Remove `type="text/javascript"` from `script` elements; other `type` attribute values are left intact | `false` |
193
+ | `removeStyleLinkTypeAttributes`| Remove `type="text/css"` from `style` and `link` elements; other `type` attribute values are left intact | `false` |
194
+ | `removeTagWhitespace` | Remove space between attributes whenever possible; **note that this will result in invalid HTML** | `false` |
195
+ | `sortAttributes` | [Sort attributes by frequency](#sorting-attributes-and-style-classes) | `false` |
196
+ | `sortClassName` | [Sort style classes by frequency](#sorting-attributes-and-style-classes) | `false` |
197
+ | `trimCustomFragments` | Trim whitespace around `ignoreCustomFragments` | `false` |
198
+ | `useShortDoctype` | [Replaces the doctype with the short (HTML) doctype](http://perfectionkills.com/experimenting-with-html-minifier#use_short_doctype) | `false` |
199
199
 
200
- ### Sorting attributes / style classes
200
+ ### Sorting attributes and style classes
201
201
 
202
- Minifier options like `sortAttributes` and `sortClassName` won’t impact the plain-text size of the output. However, they form long repetitive chains of characters that should improve compression ratio of gzip used in HTTP compression.
202
+ Minifier options like `sortAttributes` and `sortClassName` won’t impact the plaintext size of the output. However, they form long, repetitive character chains that should improve the compression ratio of gzip used for HTTP.
203
203
 
204
204
  ## Special cases
205
205
 
206
206
  ### Ignoring chunks of markup
207
207
 
208
- If you have chunks of markup you would like preserved, you can wrap them `<!-- htmlmin:ignore -->`.
208
+ If you have chunks of markup you would like preserved, you can wrap them with `<!-- htmlmin:ignore -->`.
209
209
 
210
210
  ### Minifying JSON-LD
211
211
 
212
- You can minify script elements with JSON-LD by setting the option `{ processScripts: ['application/ld+json'] }`. Note that this minification is very rudimentary, it is mainly useful for removing newlines and excessive whitespace.
212
+ You can minify `script` elements with JSON-LD by setting `{ processScripts: ['application/ld+json'] }`. Note that this minification is rudimentary; it’s mainly useful for removing newlines and excessive whitespace.
213
213
 
214
214
  ### Preserving SVG elements
215
215
 
@@ -219,9 +219,11 @@ SVG elements are automatically recognized, and when they are minified, both case
219
219
 
220
220
  HTML Minifier **can’t work with invalid or partial chunks of markup**. This is because it parses markup into a tree structure, then modifies it (removing anything that was specified for removal, ignoring anything that was specified to be ignored, etc.), then it creates a markup out of that tree and returns it.
221
221
 
222
- Input markup (e.g. `<p id="">foo`) → Internal representation of markup in a form of tree (e.g. `{ tag: "p", attr: "id", children: ["foo"] }`) → Transformation of internal representation (e.g. removal of `id` attribute) → Output of resulting markup (e.g. `<p>foo</p>`)
222
+ Input markup (e.g., `<p id="">foo`) → Internal representation of markup in a form of tree (e.g., `{ tag: "p", attr: "id", children: ["foo"] }`) → Transformation of internal representation (e.g., removal of `id` attribute) → Output of resulting markup (e.g., `<p>foo</p>`)
223
223
 
224
- HTML Minifier can’t know that original markup was only half of the tree; it does its best to try to parse it as a full tree and it loses information about tree being malformed or partial in the beginning. As a result, it can’t create a partial/malformed tree at the time of the output.
224
+ HTML Minifier can’t know that the original markup represented only part of the tree. It parses a complete tree and, in doing so, loses information about the input being malformed or partial. As a result, it can’t emit a partial or malformed tree.
225
+
226
+ To validate HTML markup, use [the W3C validator](https://validator.w3.org/) or one of [several validator packages](https://meiert.com/blog/html-validator-packages/).
225
227
 
226
228
  ## Security
227
229
 
@@ -237,8 +239,6 @@ This minifier includes protection against regular expression denial of service (
237
239
 
238
240
  **Important:** When using custom `ignoreCustomFragments`, ensure your regular expressions don’t contain unlimited quantifiers (`*`, `+`) without bounds, as these can lead to ReDoS vulnerabilities.
239
241
 
240
- (Further improvements are needed. Contributions welcome.)
241
-
242
242
  #### Custom fragment examples
243
243
 
244
244
  **Safe patterns** (recommended):
package/cli.js CHANGED
@@ -97,48 +97,48 @@ function parseJSONRegExpArray(value) {
97
97
  const parseString = value => value;
98
98
 
99
99
  const mainOptions = {
100
- caseSensitive: 'Treat attributes in case sensitive manner (useful for SVG; e.g. viewBox)',
100
+ caseSensitive: 'Treat attributes in case-sensitive manner (useful for custom HTML elements)',
101
101
  collapseBooleanAttributes: 'Omit attribute values from boolean attributes',
102
102
  customFragmentQuantifierLimit: ['Set maximum quantifier limit for custom fragments to prevent ReDoS attacks (default: 200)', parseInt],
103
- collapseInlineTagWhitespace: 'Collapse white space around inline tag',
104
- collapseWhitespace: 'Collapse white space that contributes to text nodes in a document tree.',
105
- conservativeCollapse: 'Always collapse to 1 space (never remove it entirely)',
103
+ collapseInlineTagWhitespace: 'Don’t leave any spaces between “display: inline;” elements when collapsing—use with “collapseWhitespace=true”',
104
+ collapseWhitespace: 'Collapse whitespace that contributes to text nodes in a document tree',
105
+ conservativeCollapse: 'Always collapse to 1 space (never remove it entirely)—use with “collapseWhitespace=true”',
106
106
  continueOnParseError: 'Handle parse errors instead of aborting',
107
- customAttrAssign: ['Arrays of regex\'es that allow to support custom attribute assign expressions (e.g. \'<div flex?="{{mode != cover}}"></div>\')', parseJSONRegExpArray],
108
- customAttrCollapse: ['Regex that specifies custom attribute to strip newlines from (e.g. /ng-class/)', parseRegExp],
109
- customAttrSurround: ['Arrays of regex\'es that allow to support custom attribute surround expressions (e.g. <input {{#if value}}checked="checked"{{/if}}>)', parseJSONRegExpArray],
110
- customEventAttributes: ['Arrays of regex\'es that allow to support custom event attributes for minifyJS (e.g. ng-click)', parseJSONRegExpArray],
107
+ customAttrAssign: ['Arrays of regexes that allow to support custom attribute assign expressions (e.g., “<div flex?="{{mode != cover}}"></div>”)', parseJSONRegExpArray],
108
+ customAttrCollapse: ['Regex that specifies custom attribute to strip newlines from (e.g., /ng-class/)', parseRegExp],
109
+ customAttrSurround: ['Arrays of regexes that allow to support custom attribute surround expressions (e.g., “<input {{#if value}}checked="checked"{{/if}}>”)', parseJSONRegExpArray],
110
+ customEventAttributes: ['Arrays of regexes that allow to support custom event attributes for minifyJS (e.g., ng-click)', parseJSONRegExpArray],
111
111
  decodeEntities: 'Use direct Unicode characters whenever possible',
112
- html5: 'Parse input according to HTML5 specifications',
113
- ignoreCustomComments: ['Array of regex\'es that allow to ignore certain comments, when matched', parseJSONRegExpArray],
114
- ignoreCustomFragments: ['Array of regex\'es that allow to ignore certain fragments, when matched (e.g. <?php ... ?>, {{ ... }})', parseJSONRegExpArray],
115
- includeAutoGeneratedTags: 'Insert tags generated by HTML parser',
112
+ html5: 'Parse input according to the HTML specification',
113
+ ignoreCustomComments: ['Array of regexes that allow to ignore certain comments, when matched', parseJSONRegExpArray],
114
+ ignoreCustomFragments: ['Array of regexes that allow to ignore certain fragments, when matched (e.g., “<?php ?>”, {{ }})', parseJSONRegExpArray],
115
+ includeAutoGeneratedTags: 'Insert elements generated by HTML parser',
116
116
  inlineCustomElements: ['Array of names of custom elements which are inline', parseJSONArray],
117
- keepClosingSlash: 'Keep the trailing slash on singleton elements',
117
+ keepClosingSlash: 'Keep the trailing slash on void elements',
118
118
  maxInputLength: ['Maximum input length to prevent ReDoS attacks', parseInt],
119
- maxLineLength: ['Max line length', parseInt],
120
- minifyCSS: ['Minify CSS in style elements and style attributes (uses clean-css)', parseJSON],
121
- minifyJS: ['Minify Javascript in script elements and on* attributes', parseJSON],
119
+ maxLineLength: ['Specify a maximum line length; compressed output will be split by newlines at valid HTML split-points', parseInt],
120
+ minifyCSS: ['Minify CSS in style elements and style attributes (uses clean-css)', parseJSON],
121
+ minifyJS: ['Minify JavaScript in script elements and event attributes (uses Terser)', parseJSON],
122
122
  minifyURLs: ['Minify URLs in various attributes (uses relateurl)', parseJSON],
123
123
  noNewlinesBeforeTagClose: 'Never add a newline before a tag that closes an element',
124
- preserveLineBreaks: 'Always collapse to 1 line break (never remove it entirely) when whitespace between tags include a line break.',
125
- preventAttributesEscaping: 'Prevents the escaping of the values of attributes.',
124
+ preserveLineBreaks: 'Always collapse to 1 line break (never remove it entirely) when whitespace between tags includes a line break—use with “collapseWhitespace=true”',
125
+ preventAttributesEscaping: 'Prevents the escaping of the values of attributes',
126
126
  processConditionalComments: 'Process contents of conditional comments through minifier',
127
- processScripts: ['Array of strings corresponding to types of script elements to process through minifier (e.g. "text/ng-template", "text/x-handlebars-template", etc.)', parseJSONArray],
128
- quoteCharacter: ['Type of quote to use for attribute values (\' or ")', parseString],
129
- removeAttributeQuotes: 'Remove quotes around attributes when possible.',
127
+ processScripts: ['Array of strings corresponding to types of script elements to process through minifier (e.g., text/ng-template”, text/x-handlebars-template”, etc.)', parseJSONArray],
128
+ quoteCharacter: ['Type of quote to use for attribute values (“\' or “\")', parseString],
129
+ removeAttributeQuotes: 'Remove quotes around attributes when possible',
130
130
  removeComments: 'Strip HTML comments',
131
131
  removeEmptyAttributes: 'Remove all attributes with whitespace-only values',
132
132
  removeEmptyElements: 'Remove all elements with empty contents',
133
133
  removeOptionalTags: 'Remove unrequired tags',
134
- removeRedundantAttributes: 'Remove attributes when value matches default.',
135
- removeScriptTypeAttributes: 'Removes the following attributes from script tags: text/javascript, text/ecmascript, text/jscript, application/javascript, application/x-javascript, application/ecmascript. Other type attribute values are left intact',
136
- removeStyleLinkTypeAttributes: 'Remove type="text/css" from style and link tags. Other type attribute values are left intact.',
137
- removeTagWhitespace: 'Remove space between attributes whenever possible',
134
+ removeRedundantAttributes: 'Remove attributes when value matches default',
135
+ removeScriptTypeAttributes: 'Remove “type="text/javascript"” from “script” elements; other type attribute values are left intact',
136
+ removeStyleLinkTypeAttributes: 'Remove type="text/css" from style and link elements; other type attribute values are left intact',
137
+ removeTagWhitespace: 'Remove space between attributes whenever possible; note that this will result in invalid HTML',
138
138
  sortAttributes: 'Sort attributes by frequency',
139
139
  sortClassName: 'Sort style classes by frequency',
140
- trimCustomFragments: 'Trim white space around ignoreCustomFragments.',
141
- useShortDoctype: 'Replaces the doctype with the short (HTML5) doctype'
140
+ trimCustomFragments: 'Trim whitespace around ignoreCustomFragments',
141
+ useShortDoctype: 'Replaces the doctype with the short (HTML) doctype'
142
142
  };
143
143
 
144
144
  // Configure command line flags
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "description": "Highly configurable, well-tested, JavaScript-based HTML minifier.",
16
16
  "devDependencies": {
17
17
  "@commitlint/cli": "^19.8.1",
18
- "@jest/globals": "^30.0.5",
18
+ "@jest/globals": "^30.1.2",
19
19
  "@rollup/plugin-commonjs": "^28.0.6",
20
20
  "@rollup/plugin-json": "^6.1.0",
21
21
  "@rollup/plugin-node-resolve": "^16.0.1",
@@ -25,11 +25,11 @@
25
25
  "eslint": "^9.33.0",
26
26
  "husky": "^9.1.7",
27
27
  "is-ci": "^4.1.0",
28
- "jest": "^30.0.5",
28
+ "jest": "^30.1.3",
29
29
  "lint-staged": "^16.1.5",
30
- "rollup": "^4.46.2",
30
+ "rollup": "^4.50.0",
31
31
  "rollup-plugin-polyfill-node": "^0.13.0",
32
- "vite": "^7.1.2"
32
+ "vite": "^7.1.5"
33
33
  },
34
34
  "exports": {
35
35
  ".": {
@@ -88,5 +88,5 @@
88
88
  "test:watch": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest --watch"
89
89
  },
90
90
  "type": "module",
91
- "version": "1.3.3"
91
+ "version": "1.4.1"
92
92
  }
@@ -260,7 +260,7 @@ function isSrcset(attrName, tag) {
260
260
  return attrName === 'srcset' && srcsetTags.has(tag);
261
261
  }
262
262
 
263
- async function cleanAttributeValue(tag, attrName, attrValue, options, attrs) {
263
+ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs, minifyHTMLSelf) {
264
264
  if (isEventAttribute(attrName, options)) {
265
265
  attrValue = trimWhitespace(attrValue).replace(/^javascript:\s*/i, '');
266
266
  return options.minifyJS(attrValue, true);
@@ -318,6 +318,13 @@ async function cleanAttributeValue(tag, attrName, attrValue, options, attrs) {
318
318
  } else if (isMediaQuery(tag, attrs, attrName)) {
319
319
  attrValue = trimWhitespace(attrValue);
320
320
  return options.minifyCSS(attrValue, 'media');
321
+ } else if (tag === 'iframe' && attrName === 'srcdoc') {
322
+ // Recursively minify HTML content within srcdoc attribute
323
+ // Fast-path: skip if nothing would change
324
+ if (!shouldMinifyInnerHTML(options)) {
325
+ return attrValue;
326
+ }
327
+ return minifyHTMLSelf(attrValue, options, true);
321
328
  }
322
329
  return attrValue;
323
330
  }
@@ -557,7 +564,7 @@ async function normalizeAttr(attr, attrs, tag, options) {
557
564
  }
558
565
 
559
566
  if (attrValue) {
560
- attrValue = await cleanAttributeValue(tag, attrName, attrValue, options, attrs);
567
+ attrValue = await cleanAttributeValue(tag, attrName, attrValue, options, attrs, minifyHTML);
561
568
  }
562
569
 
563
570
  if (options.removeEmptyAttributes &&
@@ -632,6 +639,17 @@ function identityAsync(value) {
632
639
  return Promise.resolve(value);
633
640
  }
634
641
 
642
+ function shouldMinifyInnerHTML(options) {
643
+ return Boolean(
644
+ options.collapseWhitespace ||
645
+ options.removeComments ||
646
+ options.removeOptionalTags ||
647
+ options.minifyJS !== identity ||
648
+ options.minifyCSS !== identityAsync ||
649
+ options.minifyURLs !== identity
650
+ );
651
+ }
652
+
635
653
  const processOptions = (inputOptions) => {
636
654
  const options = {
637
655
  name: function (name) {
package/src/htmlparser.js CHANGED
@@ -36,7 +36,7 @@ class CaseInsensitiveSet extends Set {
36
36
  }
37
37
  }
38
38
 
39
- // Regular Expressions for parsing tags and attributes
39
+ // Regular expressions for parsing tags and attributes
40
40
  const singleAttrIdentifier = /([^\s"'<>/=]+)/;
41
41
  const singleAttrAssigns = [/=/];
42
42
  const singleAttrValues = [
@@ -67,10 +67,10 @@ let IS_REGEX_CAPTURING_BROKEN = false;
67
67
  IS_REGEX_CAPTURING_BROKEN = g === '';
68
68
  });
69
69
 
70
- // Empty Elements
70
+ // Empty elements
71
71
  const empty = new CaseInsensitiveSet(['area', 'base', 'basefont', 'br', 'col', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']);
72
72
 
73
- // Inline Elements
73
+ // Inline elements
74
74
  const inline = new CaseInsensitiveSet(['a', 'abbr', 'acronym', 'applet', 'b', 'basefont', 'bdo', 'big', 'br', 'button', 'cite', 'code', 'del', 'dfn', 'em', 'font', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'label', 'map', 'noscript', 'object', 'q', 's', 'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'svg', 'textarea', 'tt', 'u', 'var']);
75
75
 
76
76
  // Elements that you can, intentionally, leave open
@@ -80,10 +80,10 @@ const closeSelf = new CaseInsensitiveSet(['colgroup', 'dd', 'dt', 'li', 'option'
80
80
  // Attributes that have their values filled in disabled='disabled'
81
81
  const fillAttrs = new CaseInsensitiveSet(['checked', 'compact', 'declare', 'defer', 'disabled', 'ismap', 'multiple', 'nohref', 'noresize', 'noshade', 'nowrap', 'readonly', 'selected']);
82
82
 
83
- // Special Elements (can contain anything)
83
+ // Special elements (can contain anything)
84
84
  const special = new CaseInsensitiveSet(['script', 'style']);
85
85
 
86
- // HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
86
+ // HTML5 elements https://html.spec.whatwg.org/multipage/indices.html#elements-3
87
87
  // Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
88
88
  const nonPhrasing = new CaseInsensitiveSet(['address', 'article', 'aside', 'base', 'blockquote', 'body', 'caption', 'col', 'colgroup', 'dd', 'details', 'dialog', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'legend', 'li', 'menuitem', 'meta', 'ol', 'optgroup', 'option', 'param', 'rp', 'rt', 'source', 'style', 'summary', 'tbody', 'td', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul']);
89
89