html-minifier-next 5.1.5 → 5.1.7

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
@@ -38,7 +38,7 @@ Use `html-minifier-next --help` to check all available options:
38
38
  | `--ignore-dir <patterns>`, `-X <patterns>` | Exclude directories—relative to input directory—from processing (comma-separated, overrides config file setting) | `--ignore-dir=libs`, `--ignore-dir=libs,vendor,node_modules` |
39
39
  | `--output-dir <dir>`, `-O <dir>` | Specify an output directory | `--output-dir=dist` |
40
40
  | `--output <file>`, `-o <file>` | Specify output file (reads from file arguments or STDIN) | File to file: `html-minifier-next input.html -o output.html`<br>Pipe to file: `cat input.html \| html-minifier-next -o output.html`<br>File to STDOUT: `html-minifier-next input.html` |
41
- | `--file-ext <extensions>`, `-f <extensions>` | Specify file extension(s) to process (comma-separated, overrides config file setting); defaults to `html,htm,xhtml,shtml`; use `*` for all files | `--file-ext=html,php`, `--file-ext='*'` |
41
+ | `--file-ext <extensions>`, `-f <extensions>` | Specify file extension(s) to process (comma-separated, overrides config file setting); defaults to `html,htm,shtml,shtm`; use `*` for all files | `--file-ext=html,php`, `--file-ext='*'` |
42
42
  | `--preset <name>`, `-p <name>` | Use a preset configuration (conservative or comprehensive) | `--preset=conservative` |
43
43
  | `--config-file <file>`, `-c <file>` | Use a configuration file | `--config-file=html-minifier.json` |
44
44
  | `--verbose`, `-v` | Show detailed processing information (active options, file statistics) | `html-minifier-next --input-dir=src --output-dir=dist --verbose --collapse-whitespace` |
@@ -400,7 +400,7 @@ npx html-minifier-next --input-dir=test --preset comprehensive --output-dir exam
400
400
  **Process specific files and directories:**
401
401
 
402
402
  ```shell
403
- # Process default extensions (html, htm, xhtml, shtml)
403
+ # Process default extensions (html, htm, shtml, shtm)
404
404
  html-minifier-next --collapse-whitespace --input-dir=src --output-dir=dist
405
405
 
406
406
  # Process only specific extensions
package/cli.js CHANGED
@@ -47,7 +47,7 @@ import { optionDefinitions } from './src/lib/option-definitions.js';
47
47
  const require = createRequire(import.meta.url);
48
48
  const pkg = require('./package.json');
49
49
 
50
- const DEFAULT_FILE_EXTENSIONS = ['html', 'htm', 'xhtml', 'shtml'];
50
+ const DEFAULT_FILE_EXTENSIONS = ['html', 'htm', 'shtml', 'shtm'];
51
51
 
52
52
  const program = new Command();
53
53
  program.name(pkg.name);
@@ -240,7 +240,7 @@ let config = {};
240
240
  program.option('-I --input-dir <dir>', 'Specify an input directory');
241
241
  program.option('-X --ignore-dir <patterns>', 'Exclude directories—relative to input directory—from processing (comma-separated), e.g., “libs” or “libs,vendor,node_modules”');
242
242
  program.option('-O --output-dir <dir>', 'Specify an output directory');
243
- program.option('-f --file-ext <extensions>', 'Specify file extension(s) to process (comma-separated); defaults to “html,htm,xhtml,shtml”; use “*” for all files');
243
+ program.option('-f --file-ext <extensions>', 'Specify file extension(s) to process (comma-separated); defaults to “html,htm,shtml,shtm”; use “*” for all files');
244
244
  program.option('-p --preset <name>', `Use a preset configuration (${getPresetNames().join(', ')})`);
245
245
  program.option('-c --config-file <file>', 'Use config file');
246
246
  program.option('--cache-css <size>', 'Set CSS minification cache size (number of entries, default: 500)', parseValidInt('cacheCSS'));
@@ -266,7 +266,7 @@ program.helpOption('-h, --help', 'Display help for command');
266
266
  const jsonOptionKeys = ['minifyCss', 'minifyJs', 'minifyUrls'];
267
267
  for (const key of jsonOptionKeys) {
268
268
  const value = programOptions[key];
269
- if (typeof value === 'string' && /\.(html?|php|xml|svg|xhtml|jsx|tsx|vue|ejs|hbs|mustache|twig)$/i.test(value)) {
269
+ if (typeof value === 'string' && /\.(html?|shtml?|xhtml?|php|xml|svg|jsx|tsx|vue|ejs|hbs|mustache|twig)$/i.test(value)) {
270
270
  // The option consumed a filename - inject it back
271
271
  programOptions[key] = true;
272
272
  capturedFiles.push(value);
@@ -1133,10 +1133,14 @@ const isSimpleBoolean = new Set(['allowfullscreen', 'async', 'autofocus', 'autop
1133
1133
 
1134
1134
  const isBooleanValue = new Set(['true', 'false']);
1135
1135
 
1136
- // Attributes where empty value can be collapsed to just the attribute name
1137
- // `crossorigin=""` `crossorigin` (empty string equals anonymous mode)
1138
- // `contenteditable=""` → `contenteditable` (empty string equals `true`)
1139
- const emptyCollapsible = new Set(['crossorigin', 'contenteditable']);
1136
+ // Attributes where certain values can be collapsed to just the attribute name;
1137
+ // maps each attribute name to the set of values that collapse to the bare attribute:
1138
+ // - `crossorigin=""` and `crossorigin="anonymous"` → `crossorigin` (anonymous is the default)
1139
+ // - `contenteditable=""` `contenteditable` (empty string means inherit/true)
1140
+ const collapsibleValues = new Map([
1141
+ ['crossorigin', new Set(['', 'anonymous'])],
1142
+ ['contenteditable', new Set([''])]
1143
+ ]);
1140
1144
 
1141
1145
  // `srcset` elements
1142
1146
 
@@ -2245,7 +2249,7 @@ function isStyleElement(tag, attrs) {
2245
2249
  function isBooleanAttribute(attrName, attrValue) {
2246
2250
  return isSimpleBoolean.has(attrName) ||
2247
2251
  (attrName === 'draggable' && !isBooleanValue.has(attrValue)) ||
2248
- (attrValue === '' && emptyCollapsible.has(attrName));
2252
+ (collapsibleValues.has(attrName) && collapsibleValues.get(attrName).has(attrValue));
2249
2253
  }
2250
2254
 
2251
2255
  const uriTypeAttributes = new Map([
@@ -78,7 +78,7 @@ export const keepScriptsMimetypes: Set<string>;
78
78
  export const jsonScriptTypes: Set<string>;
79
79
  export const isSimpleBoolean: Set<string>;
80
80
  export const isBooleanValue: Set<string>;
81
- export const emptyCollapsible: Set<string>;
81
+ export const collapsibleValues: Map<string, Set<string>>;
82
82
  export const srcsetElements: Set<string>;
83
83
  export const optionalStartTags: Set<string>;
84
84
  export const optionalEndTags: Set<string>;
@@ -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;AAmBH,0CAUG;AAzBH,0CAAwhB;AAExhB,yCAAkD;AAKlD,2CAAqE;AAIrE,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,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"}
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "commander": "^14.0.2",
9
9
  "entities": "^7.0.1",
10
10
  "lightningcss": "^1.31.1",
11
- "svgo": "^4.0.0",
11
+ "svgo": "^4.0.1",
12
12
  "terser": "^5.46.0"
13
13
  },
14
14
  "description": "Super-configurable and well-tested web page minifier (enhanced successor of HTML Minifier)",
@@ -95,5 +95,5 @@
95
95
  },
96
96
  "type": "module",
97
97
  "types": "./dist/types/htmlminifier.d.ts",
98
- "version": "5.1.5"
98
+ "version": "5.1.7"
99
99
  }
@@ -14,7 +14,7 @@ import {
14
14
  keepScriptsMimetypes,
15
15
  isSimpleBoolean,
16
16
  isBooleanValue,
17
- emptyCollapsible,
17
+ collapsibleValues,
18
18
  srcsetElements,
19
19
  reEmptyAttribute
20
20
  } from './constants.js';
@@ -189,7 +189,7 @@ function isStyleElement(tag, attrs) {
189
189
  function isBooleanAttribute(attrName, attrValue) {
190
190
  return isSimpleBoolean.has(attrName) ||
191
191
  (attrName === 'draggable' && !isBooleanValue.has(attrValue)) ||
192
- (attrValue === '' && emptyCollapsible.has(attrName));
192
+ (collapsibleValues.has(attrName) && collapsibleValues.get(attrName).has(attrValue));
193
193
  }
194
194
 
195
195
  const uriTypeAttributes = new Map([
@@ -95,10 +95,14 @@ const isSimpleBoolean = new Set(['allowfullscreen', 'async', 'autofocus', 'autop
95
95
 
96
96
  const isBooleanValue = new Set(['true', 'false']);
97
97
 
98
- // Attributes where empty value can be collapsed to just the attribute name
99
- // `crossorigin=""` `crossorigin` (empty string equals anonymous mode)
100
- // `contenteditable=""` → `contenteditable` (empty string equals `true`)
101
- const emptyCollapsible = new Set(['crossorigin', 'contenteditable']);
98
+ // Attributes where certain values can be collapsed to just the attribute name;
99
+ // maps each attribute name to the set of values that collapse to the bare attribute:
100
+ // - `crossorigin=""` and `crossorigin="anonymous"` → `crossorigin` (anonymous is the default)
101
+ // - `contenteditable=""` `contenteditable` (empty string means inherit/true)
102
+ const collapsibleValues = new Map([
103
+ ['crossorigin', new Set(['', 'anonymous'])],
104
+ ['contenteditable', new Set([''])]
105
+ ]);
102
106
 
103
107
  // `srcset` elements
104
108
 
@@ -208,7 +212,7 @@ export {
208
212
  // Boolean sets
209
213
  isSimpleBoolean,
210
214
  isBooleanValue,
211
- emptyCollapsible,
215
+ collapsibleValues,
212
216
 
213
217
  // Misc
214
218
  srcsetElements,
File without changes