html-minifier-next 8.1.1 → 8.2.0

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
@@ -149,7 +149,7 @@ Options can be used in config files (camelCase) or via CLI flags (kebab-case wit
149
149
  | `ignoreCustomFragments`<br>`--ignore-custom-fragments` | Array of regexes that allow to ignore certain fragments, when matched (e.g., `<?php … ?>`, `{{ … }}`, etc.) | `[ /<%[\s\S]*?%>/, /<\?[\s\S]*?\?>/ ]` |
150
150
  | `includeAutoGeneratedTags`<br>`--include-auto-generated-tags` | Insert elements generated by HTML parser | `false` |
151
151
  | `inlineCustomElements`<br>`--inline-custom-elements` | Array of names of custom elements which are inline, for whitespace handling | `[]` |
152
- | `keepClosingSlash`<br>`--keep-closing-slash` | Keep the trailing slash on void elements | `false` |
152
+ | `keepClosingSlash`<br>`--keep-closing-slash` | Keep the trailing slash on void elements and other start tags that carry one, and read it as closing the element | `false` |
153
153
  | `maxInputLength`<br>`--max-input-length` | Maximum input length to prevent ReDoS attacks (disabled by default) | `undefined` |
154
154
  | `maxLineLength`<br>`--max-line-length` | Specify a maximum line length; compressed output will be split by newlines at valid HTML split-points | `undefined` |
155
155
  | `mergeScripts`<br>`--merge-scripts` | Merge consecutive inline `script` elements into one (only merges compatible scripts with same `type`, matching `async`/`defer`/`nomodule`/`nonce`) | `false` |
@@ -191,7 +191,9 @@ export type MinifierOptions = {
191
191
  */
192
192
  inlineCustomElements?: ArrayLike<string>;
193
193
  /**
194
- * Preserve the trailing slash in self-closing tags when present.
194
+ * Keep the trailing slash on void elements and other start tags that carry one, and read it
195
+ * as closing the element. The default drops the slash and ignores it, as HTML does; in SVG
196
+ * and MathML a slash closes the element either way.
195
197
  *
196
198
  * Default: `false`
197
199
  */
@@ -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":"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"}
@@ -7,6 +7,7 @@ export type HTMLParserHandler = {
7
7
  continueOnParseError?: boolean | undefined;
8
8
  partialMarkup?: boolean | undefined;
9
9
  wantsNextTag?: boolean | undefined;
10
+ selfClosingSlash?: boolean | undefined;
10
11
  customAttrSurround?: RegExp[][] | undefined;
11
12
  customAttrAssign?: RegExp[] | undefined;
12
13
  };
@@ -1 +1 @@
1
- {"version":3,"file":"htmlparser.d.ts","sourceRoot":"","sources":["../../src/htmlparser.js"],"names":[],"mappings":"AAcG,YAWG,iBAAiB,GAXV;IACR,KAAK,CAAC,WAAW;IACjB,GAAG,CAAC,WAAW;IACf,KAAK,CAAC,WAAW;IACjB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,WAAW;IACnB,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,SAAS,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;CACxC,CAAmB;AAyCvB,eAAO,MAAM,MAAM,QAA8C,CAAC;AA2HlE,qBAAa,UAAU;IAMd,IAAI;IACJ,OAAO;IANd;;;OAGG;IACH,YAAY,IAAI,EAHL,MAGK,EAAE,OAAO,EAFd,iBAEc,EAGxB;IAEK,KAAK,kBAmqBV;CACF"}
1
+ {"version":3,"file":"htmlparser.d.ts","sourceRoot":"","sources":["../../src/htmlparser.js"],"names":[],"mappings":"AAeG,YAYG,iBAAiB,GAZV;IACR,KAAK,CAAC,WAAW;IACjB,GAAG,CAAC,WAAW;IACf,KAAK,CAAC,WAAW;IACjB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,WAAW;IACnB,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,SAAS,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;CACxC,CAAmB;AA0CvB,eAAO,MAAM,MAAM,QAA8C,CAAC;AAoJlE,qBAAa,UAAU;IAMd,IAAI;IACJ,OAAO;IANd;;;OAGG;IACH,YAAY,IAAI,EAHL,MAGK,EAAE,OAAO,EAFd,iBAEc,EAGxB;IAEK,KAAK,kBA4uBV;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/attributes.js"],"names":[],"mappings":"AAuBI,OAAQ,KAAA,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAKjD,YAA0I,aAAa,GAA7I;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAE1I;AAyBD;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,IAAI,EAHnB,MAGmB,EAAE,OAAO,EAF5B,gBAE4B,WAOtC;AAED;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,QAAQ,EAHvB,MAGuB,EAAE,OAAO,EAFhC;IAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;CAED,WAW1C;AAED,4BAA4B;AAC5B,iBAAS,wBAAwB,CAAC,KAAK,EAD3B,MAC2B,WAGtC;AAED;;;GAGG;AACH,iBAAS,iBAAiB,CAAC,UAAU,EAH1B,aAAa,EAGa,EAAE,SAAS,EAFrC,MAEqC,WAO/C;AAED;;;;;;;GAOG;AACH,iBAAS,qBAAqB,CAAC,KAAK,EAJzB,aAAa,EAIY,EAAE,aAAa,EAHxC,OAGwC,GAFtC,aAAa,EAAE,CAqB3B;AAED;;;;;GAKG;AACH,iBAAS,oBAAoB,CAAC,GAAG,EALtB,MAKsB,EAAE,QAAQ,EAJhC,MAIgC,EAAE,SAAS,EAH3C,MAG2C,EAAE,KAAK,EAFlD,aAAa,EAEqC,WAuC5D;AAED,iBAAS,qBAAqB,CAAC,SAAS,SAAK,WAG5C;AAED,iBAAS,uBAAuB,CAAC,SAAS,SAAK,WAG9C;AAED;;;GAGG;AACH,iBAAS,kBAAkB,CAAC,GAAG,EAHpB,MAGoB,EAAE,KAAK,EAF3B,aAAa,EAEc,WAUrC;AAED,iBAAS,wBAAwB,CAAC,SAAS,SAAK,WAG/C;AAED;;;GAGG;AACH,iBAAS,cAAc,CAAC,GAAG,EAHhB,MAGgB,EAAE,KAAK,EAFvB,aAAa,EAEU,WAUjC;AAED;;;GAGG;AACH,iBAAS,kBAAkB,CAAC,QAAQ,EAHzB,MAGyB,EAAE,SAAS,EAFpC,MAEoC,uBAI9C;AAmBD;;;GAGG;AACH,iBAAS,kBAAkB,CAAC,QAAQ,EAHzB,MAGyB,EAAE,GAAG,EAF9B,MAE8B,WAGxC;AAgBD;;;GAGG;AACH,iBAAS,qBAAqB,CAAC,QAAQ,EAH5B,MAG4B,EAAE,GAAG,EAFjC,MAEiC,WAG3C;AAED;;;;GAIG;AACH,iBAAS,UAAU,CAAC,GAAG,EAJZ,MAIY,EAAE,KAAK,EAHnB,aAAa,EAGM,EAAE,KAAK,EAF1B,MAE0B,WAUpC;AAED;;;;GAIG;AACH,iBAAS,YAAY,CAAC,GAAG,EAJd,MAIc,EAAE,KAAK,EAHrB,aAAa,EAGQ,EAAE,QAAQ,EAF/B,MAE+B,WAEzC;AAED;;;GAGG;AACH,iBAAS,QAAQ,CAAC,QAAQ,EAHf,MAGe,EAAE,GAAG,EAFpB,MAEoB,WAG9B;AAED;;;GAGG;AACH,iBAAS,cAAc,CAAC,GAAG,EAHhB,MAGgB,EAAE,KAAK,EAFvB,aAAa,EAEU,WAUjC;AAED;;;GAGG;AACH,iBAAS,uBAAuB,CAAC,GAAG,EAHzB,MAGyB,EAAE,KAAK,EAFhC,aAAa,EAEmB,WAU1C;AAED;;;;;GAKG;AACH,iBAAS,uBAAuB,CAAC,GAAG,EALzB,MAKyB,EAAE,QAAQ,EAJnC,MAImC,EAAE,SAAS,EAH9C,MAAM,GAAG,SAGqC,EAAE,OAAO,EAFvD;IAAC,qBAAqB,CAAC,EAAE,OAAO,WAAW,CAAA;CAEY,OASjE;AAED;;;GAGG;AACH,iBAAS,WAAW,CAAC,IAAI,EAHd,MAGc,EAAE,KAAK,EAFrB,aAAa,EAEQ,WAO/B;AAUD;;;;;;;GAOG;AACH,iBAAS,mBAAmB,CAAC,GAAG,EAPrB,MAOqB,EAAE,QAAQ,EAN/B,MAM+B,EAAE,SAAS,EAL1C,MAK0C,EAAE,OAAO,EAJnD,gBAImD,EAAE,KAAK,EAH1D,aAAa,EAG6C,EAAE,cAAc,UAAA,4BAwNpF;AAsED;;;;;;GAMG;AACH,iBAAS,aAAa,CAAC,IAAI,EANhB,aAMgB,EAAE,KAAK,EALvB,aAAa,EAKU,EAAE,GAAG,EAJ5B,MAI4B,EAAE,OAAO,EAHrC,gBAGqC,EAAE,UAAU,UAAA;;;;;;;;cAY3D;AA0DD;;;;;;GAMG;AACH,iBAAS,SAAS,CAAC,UAAU,EANlB;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAM3C,EAAE,aAAa,EALjC,MAAM,GAAG,OAAO,GAAG,SAKc,EAAE,OAAO,EAJ1C,gBAI0C,EAAE,MAAM,EAHlD,OAGkD,EAAE,OAAO,EAF3D,MAAM,GAAG,SAEkD,UAwHrE;AAID,OAAO,EAEL,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,wBAAwB,EACxB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,uBAAuB,EACvB,uBAAuB,EACvB,WAAW,EAGX,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,qBAAqB,EACtB,CAAC"}
1
+ {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../../src/lib/attributes.js"],"names":[],"mappings":"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"}
@@ -13,6 +13,8 @@ declare const RE_TRAILING_SEMICOLON: RegExp;
13
13
  declare const RE_AMP_ENTITY: RegExp;
14
14
  declare const RE_LEGACY_ENTITIES: RegExp;
15
15
  declare const RE_ESCAPE_LT: RegExp;
16
+ declare const RE_ESCAPE_LT_RAW_TEXT: Record<string, RegExp>;
17
+ declare const RE_HTML_ENCODING: RegExp;
16
18
  declare const RE_ATTR_WS_CHECK: RegExp;
17
19
  declare const RE_ATTR_WS_COLLAPSE: RegExp;
18
20
  declare const RE_ATTR_WS_TRIM: RegExp;
@@ -97,5 +99,8 @@ declare const looseElements: Set<string>;
97
99
  declare const trailingElements: Set<string>;
98
100
  declare const htmlElements: Set<string>;
99
101
  declare const specialContentElements: Set<string>;
100
- export { RE_WS_START, RE_WS_END, RE_WS_ONLY, RE_WS_NBSP_END, RE_ALL_WS_NBSP, RE_NBSP_LEADING_GROUP, RE_NBSP_LEAD_GROUP, RE_NBSP_TRAILING_GROUP, RE_NBSP_TRAILING_STRIP, RE_EVENT_ATTR_DEFAULT, RE_CAN_REMOVE_ATTR_QUOTES, RE_TRAILING_SEMICOLON, RE_AMP_ENTITY, RE_LEGACY_ENTITIES, RE_ESCAPE_LT, RE_ATTR_WS_CHECK, RE_ATTR_WS_COLLAPSE, RE_ATTR_WS_TRIM, RE_STYLE_ELEMENT, RE_EMPTY_ATTRIBUTE, inlineElementsToKeepWhitespaceAround, inlineElementsToKeepWhitespaceWithin, inlineElementsToKeepWhitespace, formControlElements, generalDefaults, tagDefaults, executableScriptsMimetypes, keepScriptsMimetypes, jsonScriptTypes, isSimpleBoolean, isBooleanValue, collapsibleValues, srcsetElements, optionalStartTags, optionalEndTags, headerElements, descriptionElements, pBlockElements, pInlineElements, rubyEndTagOmission, rubyRtcEndTagOmission, optionElements, tableContentElements, tableSectionElements, cellElements, topLevelElements, compactElements, looseElements, trailingElements, htmlElements, specialContentElements };
102
+ declare const genericRawTextElements: Set<string>;
103
+ declare const escapableRawTextElements: Set<string>;
104
+ declare const rawTextElements: Set<string>;
105
+ export { RE_WS_START, RE_WS_END, RE_WS_ONLY, RE_WS_NBSP_END, RE_ALL_WS_NBSP, RE_NBSP_LEADING_GROUP, RE_NBSP_LEAD_GROUP, RE_NBSP_TRAILING_GROUP, RE_NBSP_TRAILING_STRIP, RE_EVENT_ATTR_DEFAULT, RE_CAN_REMOVE_ATTR_QUOTES, RE_TRAILING_SEMICOLON, RE_AMP_ENTITY, RE_LEGACY_ENTITIES, RE_ESCAPE_LT, RE_ESCAPE_LT_RAW_TEXT, RE_HTML_ENCODING, RE_ATTR_WS_CHECK, RE_ATTR_WS_COLLAPSE, RE_ATTR_WS_TRIM, RE_STYLE_ELEMENT, RE_EMPTY_ATTRIBUTE, inlineElementsToKeepWhitespaceAround, inlineElementsToKeepWhitespaceWithin, inlineElementsToKeepWhitespace, formControlElements, generalDefaults, tagDefaults, executableScriptsMimetypes, keepScriptsMimetypes, jsonScriptTypes, isSimpleBoolean, isBooleanValue, collapsibleValues, srcsetElements, optionalStartTags, optionalEndTags, headerElements, descriptionElements, pBlockElements, pInlineElements, rubyEndTagOmission, rubyRtcEndTagOmission, optionElements, tableContentElements, tableSectionElements, cellElements, topLevelElements, compactElements, looseElements, trailingElements, htmlElements, specialContentElements, genericRawTextElements, escapableRawTextElements, rawTextElements };
101
106
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/lib/constants.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/lib/constants.js"],"names":[],"mappings":"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"}
@@ -25,6 +25,7 @@ export type ProcessedOptions = Omit<MinifierOptions, 'preset' | 'canCollapseWhit
25
25
  cssContext?: CSSContext;
26
26
  nameParent?: (name: string) => string;
27
27
  nameHTML?: (name: string) => string;
28
+ keepClosingSlashHTML?: boolean;
28
29
  insideSVG?: boolean;
29
30
  insideForeignContent?: boolean;
30
31
  };
@@ -63,6 +64,7 @@ export type ProcessedOptions = Omit<MinifierOptions, 'preset' | 'canCollapseWhit
63
64
  * cssContext?: CSSContext,
64
65
  * nameParent?: (name: string) => string,
65
66
  * nameHTML?: (name: string) => string,
67
+ * keepClosingSlashHTML?: boolean,
66
68
  * insideSVG?: boolean,
67
69
  * insideForeignContent?: boolean
68
70
  * }} ProcessedOptions
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/lib/options.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/lib/options.js"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAwI,MAAM,YAAY,CAAC;AAQnK,OAAQ,KAAA,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AASrE,YAA4D,UAAU,GAA5D;IAAC,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAC,CAAY;AAOtE,YAA6C,SAAS,GAA5C;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAC,CAAW;AAUtD,YAiBG,gBAAgB,GAjBT,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,uBAAuB,GAAG,mBAAmB,GAAG,sBAAsB,GAAG,KAAK,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,iBAAiB,CAAC,GAAG;IACvM,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/B,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC;IAC/B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,qBAAqB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,KAAK,OAAO,CAAC;IAC7G,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,KAAK,OAAO,CAAC;IACzG,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3F,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3F,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,SAAS,EAAE,CAAC,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IACrE,eAAe,EAAE;QAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAC,GAAG,IAAI,CAAC;IAC7E,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,CAAkB;AA3CtB,2EAA2E;AAI3E;;;;;;GAMG;AAEH;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,wCAAwC;AACxC,iBAAS,qBAAqB,CAAC,OAAO,EAD1B,gBAC0B,WAUrC;AAwCD;;;;GAIG;AACH,QAAA,MAAM,cAAc,iBAJT,eAAe,mGACf;IAAC,eAAe,CAAC,EAAE,WAAW,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,WAAW,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,WAAW,SAAS,CAAC;IAAC,cAAc,CAAC,EAAE,GAAG,GAAG,SAAS,CAAC;IAAC,aAAa,CAAC,EAAE,GAAG,GAAG,SAAS,CAAC;IAAC,cAAc,CAAC,EAAE,GAAG,GAAG,SAAS,CAAA;CAAC,KAC5O,gBAsiBZ,CAAC;AAIF,OAAO,EACL,qBAAqB,EACrB,cAAc,EACf,CAAC"}
@@ -89,8 +89,9 @@ declare function describeQuantifierRisk(pattern: RegExp | string): string | null
89
89
  * over quoted attribute values (which may contain `>`).
90
90
  * @param {string} html
91
91
  * @param {number} pos - Start position (just after the tag name)
92
+ * @param {number} [limit] - Position to stop the search at (exclusive)
92
93
  * @returns {number} Index of the closing `>`, or -1 if not found
93
94
  */
94
- declare function findTagEnd(html: string, pos: number): number;
95
+ declare function findTagEnd(html: string, pos: number, limit?: number): number;
95
96
  export { stableStringify, findTagEnd, LRU, MAX_CACHE_ENTRY_SIZE, hashContent, uniqueId, identity, isThenable, lowercase, replaceAsync, parseRegExp, embedSource, lostFlag, describeQuantifierRisk };
96
97
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,iBAAS,eAAe,CAAC,GAAG,EAHjB,OAGiB,GAFf,MAAM,CAYlB;AAID,cAAM,GAAG;IAEA,KAAK;IACL,IAAI;IACJ,IAAI;IACT,mCAAmC;IAC9B,GAAG,EADG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAJjC,YAAY,KAAK,SAAM,EAMtB;IACD,0BAA0B;IAC1B,GAAG,CAAC,GAAG,EADK,MACL,WAUN;IACD;;;OAGG;IACH,GAAG,CAAC,GAAG,EAHI,MAGJ,EAAE,KAAK,EAFH,OAEG,QAOb;IACD,0BAA0B;IAC1B,MAAM,CAAC,GAAG,EADE,MACF,QAA2B;IACrC,6EAA6E;IAC7E,KAAK,IADS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAGxE;CACF;AAKD,QAAA,MAAM,oBAAoB,QAAc,CAAC;AAIzC,0BAA0B;AAC1B,iBAAS,WAAW,CAAC,GAAG,EADZ,MACY,UAOvB;AAID,4BAA4B;AAC5B,iBAAS,QAAQ,CAAC,KAAK,EADX,MACW,UAMtB;AAID,4BAA4B;AAC5B,iBAAS,QAAQ,CAAC,KAAK,EADX,MACW,UAEtB;AAED;;;GAGG;AACH,iBAAS,UAAU,CAAC,KAAK,EAHd,OAGc,GAFZ,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,CAIrC;AAED,4BAA4B;AAC5B,iBAAS,SAAS,CAAC,KAAK,EADZ,MACY,UAEvB;AAID;;;;;;GAMG;AACH,iBAAe,YAAY,CAAC,GAAG,EALpB,MAKoB,EAAE,KAAK,EAJ3B,MAI2B,EAAE,OAAO,UAAA,GAFlC,OAAO,CAAC,MAAM,CAAC,CAe3B;AAID,qCAAqC;AACrC,iBAAS,WAAW,CAAC,KAAK,EADd,MAAM,GAAG,MACK,sBAUzB;AAyYD;;;;;;;;;GASG;AACH,iBAAS,QAAQ,CAAC,OAAO,EAJd,MAIc,GAHZ,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAqDlC;AAED;;;;;;;;;GASG;AACH,iBAAS,WAAW,CAAC,OAAO,EAHjB,MAGiB,GAFf,MAAM,CAOlB;AAGE,YAA6D,MAAM,GAAzD;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,CAAA;CAAC,CAE7D;AAqKD;;;;;GAKG;AACH,iBAAS,sBAAsB,CAAC,OAAO,EAL5B,MAAM,GAAG,MAKmB,GAH1B,MAAM,GAAG,IAAI,CAqBzB;AAED;;;;;;GAMG;AACH,iBAAS,UAAU,CAAC,IAAI,EAJb,MAIa,EAAE,GAAG,EAHlB,MAGkB,GAFhB,MAAM,CAelB;AAID,OAAO,EACL,eAAe,EACf,UAAU,EACV,GAAG,EACH,oBAAoB,EACpB,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,WAAW,EACX,QAAQ,EACR,sBAAsB,EACvB,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/utils.js"],"names":[],"mappings":"AAEA;;;GAGG;AACH,iBAAS,eAAe,CAAC,GAAG,EAHjB,OAGiB,GAFf,MAAM,CAYlB;AAID,cAAM,GAAG;IAEA,KAAK;IACL,IAAI;IACJ,IAAI;IACT,mCAAmC;IAC9B,GAAG,EADG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAJjC,YAAY,KAAK,SAAM,EAMtB;IACD,0BAA0B;IAC1B,GAAG,CAAC,GAAG,EADK,MACL,WAUN;IACD;;;OAGG;IACH,GAAG,CAAC,GAAG,EAHI,MAGJ,EAAE,KAAK,EAFH,OAEG,QAOb;IACD,0BAA0B;IAC1B,MAAM,CAAC,GAAG,EADE,MACF,QAA2B;IACrC,6EAA6E;IAC7E,KAAK,IADS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAGxE;CACF;AAKD,QAAA,MAAM,oBAAoB,QAAc,CAAC;AAIzC,0BAA0B;AAC1B,iBAAS,WAAW,CAAC,GAAG,EADZ,MACY,UAOvB;AAID,4BAA4B;AAC5B,iBAAS,QAAQ,CAAC,KAAK,EADX,MACW,UAMtB;AAID,4BAA4B;AAC5B,iBAAS,QAAQ,CAAC,KAAK,EADX,MACW,UAEtB;AAED;;;GAGG;AACH,iBAAS,UAAU,CAAC,KAAK,EAHd,OAGc,GAFZ,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,CAIrC;AAED,4BAA4B;AAC5B,iBAAS,SAAS,CAAC,KAAK,EADZ,MACY,UAEvB;AAID;;;;;;GAMG;AACH,iBAAe,YAAY,CAAC,GAAG,EALpB,MAKoB,EAAE,KAAK,EAJ3B,MAI2B,EAAE,OAAO,UAAA,GAFlC,OAAO,CAAC,MAAM,CAAC,CAe3B;AAID,qCAAqC;AACrC,iBAAS,WAAW,CAAC,KAAK,EADd,MAAM,GAAG,MACK,sBAUzB;AAyYD;;;;;;;;;GASG;AACH,iBAAS,QAAQ,CAAC,OAAO,EAJd,MAIc,GAHZ,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAqDlC;AAED;;;;;;;;;GASG;AACH,iBAAS,WAAW,CAAC,OAAO,EAHjB,MAGiB,GAFf,MAAM,CAOlB;AAGE,YAA6D,MAAM,GAAzD;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,CAAA;CAAC,CAE7D;AAqKD;;;;;GAKG;AACH,iBAAS,sBAAsB,CAAC,OAAO,EAL5B,MAAM,GAAG,MAKmB,GAH1B,MAAM,GAAG,IAAI,CAqBzB;AAED;;;;;;;GAOG;AACH,iBAAS,UAAU,CAAC,IAAI,EALb,MAKa,EAAE,GAAG,EAJlB,MAIkB,EAAE,KAAK,AAHjC,CACA,EADQ,MAGuC,GAFrC,MAAM,CAelB;AAID,OAAO,EACL,eAAe,EACf,UAAU,EACV,GAAG,EACH,oBAAoB,EACpB,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,WAAW,EACX,QAAQ,EACR,sBAAsB,EACvB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"whitespace.d.ts","sourceRoot":"","sources":["../../../src/lib/whitespace.js"],"names":[],"mappings":"AAeA,0BAA0B;AAC1B,QAAA,MAAM,cAAc,QADR,MAAM,WAQjB,CAAC;AAIF,0BAA0B;AAC1B,iBAAS,qBAAqB,CAAC,GAAG,EADtB,MACsB,UAgBjC;AAID;;;;;;GAMG;AACH,iBAAS,kBAAkB,CAAC,GAAG,EANpB,MAMoB,EAAE,OAAO,EAL7B;IAAC,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAKxD,EAAE,QAAQ,EAJvC,OAIuC,EAAE,SAAS,EAHlD,OAGkD,EAAE,WAAW,AAFvE,CAA8B,EAAtB,OAEuE,UAqFjF;AAoBD;;;;;;;;;GASG;AACH,iBAAS,uBAAuB,CAAC,GAAG,EATzB,MASyB,EAAE,OAAO,EARlC,MAQkC,EAAE,OAAO,EAP3C,MAO2C,EAAE,SAAS,EANtD,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAMkB,EAAE,SAAS,EALjE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAK6B,EAAE,OAAO,EAJ1E;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAAC,2BAA2B,CAAC,EAAE,OAAO,CAAA;CAI1B,EAAE,cAAc,EAH1F,GAAG,CAAC,MAAM,CAGgF,EAAE,aAAa,EAFzG,GAAG,CAAC,MAAM,CAE+F,UAiEnH;AAOD,0BAA0B;AAC1B,iBAAS,qBAAqB,CAAC,GAAG,EADtB,MACsB,WAEjC;AAED,0BAA0B;AAC1B,iBAAS,iBAAiB,CAAC,GAAG,EADlB,MACkB,WAE7B;AAID,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EAClB,CAAC"}
1
+ {"version":3,"file":"whitespace.d.ts","sourceRoot":"","sources":["../../../src/lib/whitespace.js"],"names":[],"mappings":"AAeA,0BAA0B;AAC1B,QAAA,MAAM,cAAc,QADR,MAAM,WAQjB,CAAC;AAIF,0BAA0B;AAC1B,iBAAS,qBAAqB,CAAC,GAAG,EADtB,MACsB,UAgBjC;AAID;;;;;;GAMG;AACH,iBAAS,kBAAkB,CAAC,GAAG,EANpB,MAMoB,EAAE,OAAO,EAL7B;IAAC,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAKxD,EAAE,QAAQ,EAJvC,OAIuC,EAAE,SAAS,EAHlD,OAGkD,EAAE,WAAW,AAFvE,CAA8B,EAAtB,OAEuE,UAqFjF;AAoBD;;;;;;;;;GASG;AACH,iBAAS,uBAAuB,CAAC,GAAG,EATzB,MASyB,EAAE,OAAO,EARlC,MAQkC,EAAE,OAAO,EAP3C,MAO2C,EAAE,SAAS,EANtD,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAMkB,EAAE,SAAS,EALjE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAK6B,EAAE,OAAO,EAJ1E;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAAC,2BAA2B,CAAC,EAAE,OAAO,CAAA;CAI1B,EAAE,cAAc,EAH1F,GAAG,CAAC,MAAM,CAGgF,EAAE,aAAa,EAFzG,GAAG,CAAC,MAAM,CAE+F,UAiEnH;AASD,0BAA0B;AAC1B,iBAAS,qBAAqB,CAAC,GAAG,EADtB,MACsB,WAEjC;AAED,0BAA0B;AAC1B,iBAAS,iBAAiB,CAAC,GAAG,EADlB,MACkB,WAE7B;AAID,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EAClB,CAAC"}
@@ -156,7 +156,7 @@
156
156
  }
157
157
  },
158
158
  "keepClosingSlash": {
159
- "description": "Keep the trailing slash on void elements",
159
+ "description": "Keep the trailing slash on void elements and other start tags that carry one, and read it as closing the element",
160
160
  "type": "boolean"
161
161
  },
162
162
  "maxInputLength": {
package/package.json CHANGED
@@ -16,9 +16,9 @@
16
16
  "devDependencies": {
17
17
  "@commitlint/cli": "^21.2.2",
18
18
  "@eslint/js": "^10.0.1",
19
- "@swc/core": "^1.16.0",
19
+ "@swc/core": "^1.16.1",
20
20
  "@types/node": "^26.2.0",
21
- "eslint": "^10.8.1",
21
+ "eslint": "^10.9.1",
22
22
  "globals": "^17.11.0",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.1"
@@ -95,5 +95,5 @@
95
95
  },
96
96
  "type": "module",
97
97
  "types": "dist/types/htmlminifier.d.ts",
98
- "version": "8.1.1"
98
+ "version": "8.2.0"
99
99
  }
@@ -8,6 +8,8 @@ import { collectUsedSymbols } from './lib/unused-css.js';
8
8
  import {
9
9
  RE_LEGACY_ENTITIES,
10
10
  RE_ESCAPE_LT,
11
+ RE_ESCAPE_LT_RAW_TEXT,
12
+ RE_HTML_ENCODING,
11
13
  RE_WS_START,
12
14
  RE_WS_END,
13
15
  RE_WS_ONLY,
@@ -16,6 +18,7 @@ import {
16
18
  inlineElementsToKeepWhitespaceAround,
17
19
  inlineElementsToKeepWhitespaceWithin,
18
20
  specialContentElements,
21
+ rawTextElements,
19
22
  htmlElements,
20
23
  optionalStartTags,
21
24
  optionalEndTags,
@@ -244,7 +247,9 @@ import { toFragment, replaceCustomFragments } from './lib/fragments.js';
244
247
  * Default: `[]`
245
248
  *
246
249
  * @prop {boolean} [keepClosingSlash]
247
- * Preserve the trailing slash in self-closing tags when present.
250
+ * Keep the trailing slash on void elements and other start tags that carry one, and read it
251
+ * as closing the element. The default drops the slash and ignores it, as HTML does; in SVG
252
+ * and MathML a slash closes the element either way.
248
253
  *
249
254
  * Default: `false`
250
255
  *
@@ -586,8 +591,6 @@ const RE_HTML_COMMENT_START = /^\s*<!--/;
586
591
  const RE_CLOSING_TAG_START = /^\s*<\/([a-zA-Z][\w:-]*)/;
587
592
  const RE_LAST_HTML_TAG = /[\s\S]*<(\/?[a-zA-Z][\w:-]*)/;
588
593
 
589
- // HTML encoding types for annotation-xml (MathML)
590
- const RE_HTML_ENCODING = /^(text\/html|application\/xhtml\+xml)$/i;
591
594
 
592
595
  // Probe for SVG/MathML elements—when the input has none (the common case),
593
596
  // the per-tag foreign-content machinery can be skipped entirely
@@ -764,7 +767,7 @@ async function createSortFns(value, options, uidIgnore, uidAttr, ignoredMarkupCh
764
767
  /** @type {string | undefined} */
765
768
  let currentType;
766
769
  const parser = new HTMLParser(input, {
767
- start: function (/** @type {string} */ tag, /** @type {HTMLAttribute[]} */ attrs) {
770
+ start: function (/** @type {string} */ tag, /** @type {HTMLAttribute[]} */ attrs, /** @type {boolean} */ unary) {
768
771
  if (attrChains) {
769
772
  if (!attrChains[tag]) {
770
773
  attrChains[tag] = new TokenChain();
@@ -781,6 +784,11 @@ async function createSortFns(value, options, uidIgnore, uidAttr, ignoredMarkupCh
781
784
  currentType = attr.value;
782
785
  }
783
786
  }
787
+ // As on the main path: What a unary tag holds ends with the tag, so no text can belong to it
788
+ if (unary) {
789
+ currentTag = '';
790
+ currentType = undefined;
791
+ }
784
792
  },
785
793
  end: function () {
786
794
  currentTag = '';
@@ -797,7 +805,8 @@ async function createSortFns(value, options, uidIgnore, uidAttr, ignoredMarkupCh
797
805
  // No need for `nextTag` information in this scan
798
806
  wantsNextTag: false,
799
807
  // Continue on parse errors during analysis pass
800
- continueOnParseError: options.continueOnParseError
808
+ continueOnParseError: options.continueOnParseError,
809
+ selfClosingSlash: options.keepClosingSlash
801
810
  });
802
811
 
803
812
  try {
@@ -1123,6 +1132,14 @@ async function minifyHTML(value, options, partialMarkup) {
1123
1132
  buffer.length = Math.max(0, index);
1124
1133
  }
1125
1134
 
1135
+ // Whether the element being parsed holds text rather than markup. The namespace decides
1136
+ // this, not the name alone: `script` and `style` hold text wherever they stand, the rest
1137
+ // only as HTML elements—an SVG or MathML `title` holds markup like any foreign element
1138
+ function holdsRawText() {
1139
+ return specialContentElements.has(currentTag) ||
1140
+ (rawTextElements.has(currentTag) && !options.insideForeignContent);
1141
+ }
1142
+
1126
1143
  // Whether whitespace-only text between tags survives minification
1127
1144
  function keepsWhitespace() {
1128
1145
  return !options.collapseWhitespace || Boolean(options.conservativeCollapse) || Boolean(options.preserveLineBreaks);
@@ -1348,7 +1365,7 @@ async function minifyHTML(value, options, partialMarkup) {
1348
1365
  }
1349
1366
  }
1350
1367
  charsPrevTag = /^\s*$/.test(text) ? textPrevTag : 'comment';
1351
- if (options.decodeEntities && text && !specialContentElements.has(currentTag)) {
1368
+ if (options.decodeEntities && text && !holdsRawText()) {
1352
1369
  // Escape any `&` symbols that start either:
1353
1370
  // 1. a legacy-named character reference (i.e., one that doesn’t end with `;`)
1354
1371
  // 2. or any other character reference (i.e., one that does end with `;`)
@@ -1358,7 +1375,10 @@ async function minifyHTML(value, options, partialMarkup) {
1358
1375
  text = text.replace(RE_LEGACY_ENTITIES, '&amp$1');
1359
1376
  }
1360
1377
  if (text.indexOf('<') !== -1) {
1361
- text = text.replace(RE_ESCAPE_LT, '&lt;');
1378
+ // Escapable raw text ends at its own end tag alone, so only that one needs escaping;
1379
+ // in foreign content the same element holds markup, where every `<` does
1380
+ const escapeLt = (options.insideForeignContent ? undefined : RE_ESCAPE_LT_RAW_TEXT[currentTag]) ?? RE_ESCAPE_LT;
1381
+ text = text.replace(escapeLt, '&lt;');
1362
1382
  }
1363
1383
  }
1364
1384
  if (uidPattern && options.collapseWhitespace && stackNoTrimWhitespace.length) {
@@ -1502,43 +1522,61 @@ async function minifyHTML(value, options, partialMarkup) {
1502
1522
  customAttrSurround: options.customAttrSurround,
1503
1523
  // Compute `nextTag` only when whitespace collapse features require it
1504
1524
  wantsNextTag: !!(options.collapseWhitespace || options.collapseInlineTagWhitespace || options.conservativeCollapse),
1525
+ // `keepClosingSlash` calls the slash meaningful, which decides how the input is read as well
1526
+ selfClosingSlash: options.keepClosingSlash,
1505
1527
 
1506
1528
  start: async function (/** @type {string} */ tag, /** @type {HTMLAttribute[]} */ attrs, /** @type {boolean} */ unary, /** @type {string} */ unarySlash, /** @type {boolean} */ autoGenerated) {
1507
1529
  // `lowerTag` stays '' when no foreign content is around—the SVG/MathML
1508
1530
  // checks below can then never match, and no per-tag lowercasing is needed
1509
1531
  let lowerTag = '';
1510
1532
  let useNameParentForTag = false;
1533
+ // The context the start tag sits in, which the branches below leave behind
1534
+ const optionsParent = options;
1535
+ let pushedContext = false;
1511
1536
  if (hasForeignContext) {
1512
1537
  lowerTag = tag.toLowerCase();
1513
1538
  if (lowerTag === 'svg' || lowerTag === 'math') {
1514
1539
  // Preserve the surrounding HTML context’s name function (e.g., `identity`
1515
- // under `caseSensitive`) so `foreignObject`/`annotation-xml` can restore it
1540
+ // under `caseSensitive`) and slash handling so `foreignObject`/`annotation-xml`
1541
+ // can restore them
1516
1542
  const nameHTML = options.name;
1543
+ const keepClosingSlashHTML = Boolean(options.keepClosingSlash);
1517
1544
  options = Object.create(options);
1518
1545
  options.caseSensitive = true;
1519
1546
  options.keepClosingSlash = true;
1520
1547
  options.name = identity;
1521
1548
  options.nameHTML = nameHTML;
1522
- options.insideSVG = lowerTag === 'svg';
1549
+ options.keepClosingSlashHTML = keepClosingSlashHTML;
1550
+ // SVGO reads an SVG block whole, nested MathML included, so what the block is stays true inside it
1551
+ options.insideSVG = lowerTag === 'svg' || Boolean(options.insideSVG);
1523
1552
  options.insideForeignContent = true;
1524
1553
  // Disable HTML-specific options that produce invalid XML:
1525
1554
  // SVG with `minifySVG` enabled is passed to SVGO, which requires valid XML input;
1526
1555
  // MathML is never processed by SVGO, so these restrictions never apply to it
1527
1556
  if (lowerTag === 'svg' && options.minifySVG) {
1528
1557
  options.removeAttributeQuotes = false;
1558
+ // @@ Encode a bare `&` for SVGO as well—it costs the block its optimization
1559
+ // (though not its validity; early fix could encode `&` where it’s unambiguous)
1529
1560
  options.decodeEntities = false;
1561
+ // Omitting a start and end tag both would keep the block well-formed, which this misses
1562
+ options.removeOptionalTags = false;
1563
+ options.collapseBooleanAttributes = false;
1564
+ options.includeAutoGeneratedTags = true;
1530
1565
  }
1531
1566
  options.removeTagWhitespace = false;
1567
+ pushedContext = true;
1532
1568
  }
1533
1569
  // `foreignObject` in SVG and `annotation-xml` in MathML contain HTML content
1534
- // Note: The element itself is in SVG/MathML namespace, only its children are HTML
1570
+ // (the element itself is in SVG/MathML namespace, only its children are HTML);
1571
+ // a repeated attribute is dropped after the first, so the first `encoding` decides
1535
1572
  if (options.insideForeignContent && (lowerTag === 'foreignobject' ||
1536
- (lowerTag === 'annotation-xml' && attrs.some((/** @type {HTMLAttribute} */ a) => a.name.toLowerCase() === 'encoding' &&
1537
- RE_HTML_ENCODING.test(a.value ?? ''))))) {
1573
+ (lowerTag === 'annotation-xml' && RE_HTML_ENCODING.test(
1574
+ attrs.find((/** @type {HTMLAttribute} */ a) => a.name.toLowerCase() === 'encoding')?.value ?? '')))) {
1538
1575
  const nameParent = options.name;
1539
1576
  options = Object.create(options);
1540
1577
  options.caseSensitive = false;
1541
- options.keepClosingSlash = false;
1578
+ // What the parser read the slash as, so that the two agree here as they do in HTML
1579
+ options.keepClosingSlash = options.keepClosingSlashHTML ?? false;
1542
1580
  options.nameParent = nameParent; // Preserve for the element tag itself
1543
1581
  options.name = options.nameHTML ?? lowercase;
1544
1582
  options.insideForeignContent = false;
@@ -1546,6 +1584,7 @@ async function minifyHTML(value, options, partialMarkup) {
1546
1584
  // stay disabled (inherited from SVG context) because the entire SVG block
1547
1585
  // must be valid XML for SVGO processing
1548
1586
  useNameParentForTag = true;
1587
+ pushedContext = true;
1549
1588
  }
1550
1589
  }
1551
1590
  // `nameParent` is always set when `useNameParentForTag` is true; the extra check only narrows the type
@@ -1600,7 +1639,7 @@ async function minifyHTML(value, options, partialMarkup) {
1600
1639
  }
1601
1640
 
1602
1641
  // Track SVG subtree for SVGO block processing
1603
- if (lowerTag === 'svg' && options.minifySVG) {
1642
+ if (lowerTag === 'svg' && options.minifySVG && !unary) {
1604
1643
  if (svgDepth === 0) {
1605
1644
  svgBufferStartIndex = buffer.length; // Record position before <svg> is pushed
1606
1645
  }
@@ -1608,7 +1647,10 @@ async function minifyHTML(value, options, partialMarkup) {
1608
1647
  }
1609
1648
 
1610
1649
  const openTag = '<' + tag;
1611
- const hasUnarySlash = unarySlash && options.keepClosingSlash;
1650
+ // SVGO reads the whole SVG block as XML, where an element closes itself or not, so
1651
+ // every unary element in there is written with a slash
1652
+ const needsXMLSlash = unary && Boolean(options.insideSVG) && Boolean(options.minifySVG);
1653
+ const hasUnarySlash = needsXMLSlash || (unarySlash && (useNameParentForTag ? optionsParent : options).keepClosingSlash);
1612
1654
 
1613
1655
  buffer.push(openTag);
1614
1656
 
@@ -1662,6 +1704,16 @@ async function minifyHTML(value, options, partialMarkup) {
1662
1704
  optionalStartTag = '';
1663
1705
  currentTag = '';
1664
1706
  }
1707
+
1708
+ // `end` restores what a start tag pushed, and a unary tag never reaches it
1709
+ if (unary && pushedContext) {
1710
+ options = optionsParent;
1711
+ }
1712
+
1713
+ // What a unary tag holds ends with the tag, so no text can belong to it
1714
+ if (unary) {
1715
+ currentTag = '';
1716
+ }
1665
1717
  },
1666
1718
  end: function (/** @type {string} */ tag, /** @type {HTMLAttribute[]} */ attrs, /** @type {boolean} */ autoGenerated) {
1667
1719
  // As in `start`: `lowerTag` stays '' when no foreign content is around
@@ -1778,7 +1830,7 @@ async function minifyHTML(value, options, partialMarkup) {
1778
1830
  textNextAttrs = nextAttrs || [];
1779
1831
 
1780
1832
  // Detect whether any async work is actually needed for this text node
1781
- const needsDecode = options.decodeEntities && text && !specialContentElements.has(currentTag) && text.indexOf('&') !== -1;
1833
+ const needsDecode = options.decodeEntities && text && !holdsRawText() && text.indexOf('&') !== -1;
1782
1834
  const needsProcessScript = specialContentElements.has(currentTag) && (options.processScripts || hasJsonScriptType(currentAttrs));
1783
1835
  const needsMinifyJS = options.minifyJS !== identity && isExecutableScript(currentTag, currentAttrs);
1784
1836
  const isModuleScript = needsMinifyJS && currentAttrs.some(
package/src/htmlparser.js CHANGED
@@ -5,7 +5,8 @@
5
5
  * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
6
6
  */
7
7
 
8
- import { isThenable, embedSource } from './lib/utils.js';
8
+ import { isThenable, embedSource, findTagEnd } from './lib/utils.js';
9
+ import { escapableRawTextElements, genericRawTextElements, RE_HTML_ENCODING } from './lib/constants.js';
9
10
 
10
11
  /** @import { HTMLAttribute } from './lib/attributes.js' */
11
12
 
@@ -21,6 +22,7 @@ import { isThenable, embedSource } from './lib/utils.js';
21
22
  * continueOnParseError?: boolean | undefined,
22
23
  * partialMarkup?: boolean | undefined,
23
24
  * wantsNextTag?: boolean | undefined,
25
+ * selfClosingSlash?: boolean | undefined,
24
26
  * customAttrSurround?: RegExp[][] | undefined,
25
27
  * customAttrAssign?: RegExp[] | undefined
26
28
  * }} HTMLParserHandler
@@ -64,6 +66,7 @@ const qnameCapture = (function () {
64
66
  return '((?:' + ncname + '\\:)?' + ncname + ')';
65
67
  })();
66
68
  const startTagOpen = new RegExp('^<' + qnameCapture);
69
+ const endTagOpen = new RegExp('^</' + qnameCapture);
67
70
  export const endTag = new RegExp('^</' + qnameCapture + '[^>]*>');
68
71
 
69
72
  let IS_REGEX_CAPTURING_BROKEN = false;
@@ -84,45 +87,70 @@ const fillAttrs = new Set(['checked', 'compact', 'declare', 'defer', 'disabled',
84
87
  // Special elements (can contain anything)
85
88
  const special = new Set(['script', 'style']);
86
89
 
90
+ // Elements whose children are HTML rather than foreign content, each only in
91
+ // the namespace it belongs to (`annotation-xml` is one, too, but only for some
92
+ // `encoding` values, so it is checked separately)
93
+ // https://html.spec.whatwg.org/multipage/parsing.html#html-integration-point
94
+ const svgIntegrationPoints = new Set(['foreignobject', 'desc', 'title']);
95
+ const mathIntegrationPoints = new Set(['mi', 'mo', 'mn', 'ms', 'mtext']);
96
+
87
97
  // HTML elements, https://html.spec.whatwg.org/multipage/indices.html#elements-3
88
98
  // Phrasing content, https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
89
- const nonPhrasing = new Set(['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']);
90
-
91
- const reCache = {};
99
+ const nonPhrasing = new Set(['address', 'article', 'aside', 'base', 'blockquote', 'body', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dialog', 'dir', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'legend', 'li', 'listing', 'main', 'menu', 'menuitem', 'meta', 'nav', 'ol', 'optgroup', 'option', 'param', 'plaintext', 'pre', 'rp', 'rt', 'search', 'section', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'xmp']);
92
100
 
93
- // Pre-compiled regexes for common special elements (`script`, `style`, `noscript`)
94
- // These are used frequently, and pre-compiling them avoids regex creation overhead
95
- const preCompiledStackedTags = {
96
- 'script': /([\s\S]*?)<\/script[^>]*>/i,
97
- 'style': /([\s\S]*?)<\/style[^>]*>/i,
98
- 'noscript': /([\s\S]*?)<\/noscript[^>]*>/i
99
- };
101
+ // A tag name ends at whitespace, a slash, or the closing bracket, so `</scriptx>` names a
102
+ // different element and does not end this one
103
+ const endsTagName = (/** @type {string} */ character) =>
104
+ character === '' || character === '/' || character === '>' || /\s/.test(character);
100
105
 
101
- // Cache for compiled attribute regexes per handler configuration
102
- const attrRegexCache = new WeakMap();
106
+ /**
107
+ * @param {string} text - The input the tag stands in
108
+ * @param {number} nameEnd - Position right after the tag name
109
+ * @returns {number} Position of the `>` that ends the tag, or -1 where none follows
110
+ */
111
+ function findEndTagClose(text, nameEnd) {
112
+ const close = text.indexOf('>', nameEnd);
113
+ if (close === -1) {
114
+ return -1;
115
+ }
116
+ // A quoted attribute value can hold a `>` that does not end the tag it stands in, so a
117
+ // quote ahead of that bracket calls for a scan that knows about quoting. It stops at the
118
+ // next `<`, which no tag reaches past: The scans of consecutive tags then never overlap,
119
+ // and an unquoted value that spans one leaves the first bracket as the end, as before.
120
+ for (let index = nameEnd; index < close; index++) {
121
+ const character = text[index];
122
+ if (character === '"' || character === "'") {
123
+ const nextOpen = text.indexOf('<', nameEnd);
124
+ const quoted = findTagEnd(text, nameEnd, nextOpen === -1 ? text.length : nextOpen);
125
+ return quoted === -1 ? close : quoted;
126
+ }
127
+ }
128
+ return close;
129
+ }
103
130
 
104
- // O(n) helper: Strip all occurrences of `open…close` delimiters, keeping inner content
105
- // Used instead of a regex replace to avoid O(n²) behavior on adversarial inputs
106
131
  /**
107
- * @param {string} str
108
- * @param {string} open
109
- * @param {string} close
132
+ * @param {string} text - The input from the start of the content on
133
+ * @param {string} tag - Lowercase element name
134
+ * @returns {{content: string, length: number} | null} What the element holds and how far it
135
+ * reaches, or `null` where no end tag of its own follows
110
136
  */
111
- function stripDelimited(str, open, close) {
112
- let result = '';
113
- let i = 0;
114
- while (i < str.length) {
115
- const start = str.indexOf(open, i);
116
- if (start === -1) { result += str.slice(i); break; }
117
- result += str.slice(i, start);
118
- const end = str.indexOf(close, start + open.length);
119
- if (end === -1) { result += str.slice(start); break; }
120
- result += str.slice(start + open.length, end);
121
- i = end + close.length;
137
+ function findRawTextEnd(text, tag) {
138
+ const nameEnd = tag.length + 2;
139
+ for (let candidate = text.indexOf('</'); candidate !== -1; candidate = text.indexOf('</', candidate + 2)) {
140
+ if (text.slice(candidate + 2, candidate + nameEnd).toLowerCase() !== tag || !endsTagName(text.charAt(candidate + nameEnd))) {
141
+ continue;
142
+ }
143
+ // What follows the name is not part of it, and the tag ends at the next bracket outside
144
+ // its attribute values—where none follows, no later end tag can be complete, either
145
+ const end = findEndTagClose(text, candidate + nameEnd);
146
+ return end === -1 ? null : { content: text.slice(0, candidate), length: end + 1 };
122
147
  }
123
- return result;
148
+ return null;
124
149
  }
125
150
 
151
+ // Cache for compiled attribute regexes per handler configuration
152
+ const attrRegexCache = new WeakMap();
153
+
126
154
  /** @param {HTMLParserHandler} handler */
127
155
  function buildAttrRegex(handler) {
128
156
  const unquotedValue = handler.continueOnParseError ? singleAttrValueLenientUnquoted : singleAttrValues[2];
@@ -202,7 +230,7 @@ export class HTMLParser {
202
230
  const fullHtml = this.html;
203
231
  const fullLength = fullHtml.length;
204
232
 
205
- /** @type {Array<{tag: string, lowerTag: string, attrs: HTMLAttribute[]}>} */
233
+ /** @type {Array<{tag: string, lowerTag: string, attrs: HTMLAttribute[], namespace: string}>} */
206
234
  const stack = [];
207
235
  /** @type {string} */
208
236
  let lastTag = '';
@@ -225,7 +253,7 @@ export class HTMLParser {
225
253
  const startTagOpenY = new RegExp(startTagOpen.source.slice(1), 'y');
226
254
  // `\s*` with sticky flag is O(n) at worst—no retry from different positions possible
227
255
  const startTagCloseY = /\s*(\/?)>/y;
228
- const endTagY = new RegExp(endTag.source.slice(1), 'y');
256
+ const endTagOpenY = new RegExp(endTagOpen.source.slice(1), 'y');
229
257
  const doctypeY = /<!DOCTYPE[^<>]+>/iy;
230
258
  const commentTestY = /<!--/y;
231
259
  const conditionalTestY = /<!\[/y;
@@ -238,11 +266,11 @@ export class HTMLParser {
238
266
  let pos = 0;
239
267
  let lastPos;
240
268
 
241
- // An end tag always ends at a `>`; without one, the `endTag` regex’s name run
242
- // and its `[^>]*` tail overlap and backtrack O(n²) on a long unclosed name
243
- // (e.g., `</aaaa…` with no `>`). Track the next `>` monotonically—`pos` only
244
- // advances, so the aggregate scan work stays O(n)—and skip the regex when none
245
- // lies ahead, where it could not match anyway.
269
+ // An end tag always ends at a `>`; without one ahead, matching the name only to find
270
+ // no bracket behind it repeats the name run at every position, which costs O(n²) on a
271
+ // long unclosed name (e.g., `</aaaa…` with no `>`). Track the next `>` monotonically—
272
+ // `pos` only advances, so the aggregate scan work stays O(n)—and skip the match when
273
+ // none lies ahead, where the tag could not be complete anyway.
246
274
  let nextGtPos = fullHtml.indexOf('>');
247
275
  const hasCloseAtOrAfter = (/** @type {number} */ p) => {
248
276
  if (nextGtPos !== -1 && nextGtPos < p) {
@@ -251,6 +279,13 @@ export class HTMLParser {
251
279
  return nextGtPos !== -1;
252
280
  };
253
281
 
282
+ // A `-->` that the opener at `pos` does not find is not there for any later one, either,
283
+ // and the same holds for the `]>` of a downlevel-revealed conditional comment. `pos`
284
+ // only advances, so remembering the search that came up empty keeps the aggregate work
285
+ // O(n), where searching again at every opener rescans the rest of the input each time.
286
+ let commentEndAhead = true;
287
+ let conditionalEndAhead = true;
288
+
254
289
  // Helper to advance position
255
290
  const advance = (/** @type {number} */ n) => { pos += n; };
256
291
 
@@ -274,11 +309,55 @@ export class HTMLParser {
274
309
  return fullHtml.slice(startPos);
275
310
  };
276
311
 
312
+ // `annotation-xml` holds HTML only where its `encoding` says so; with any other value,
313
+ // and with none, its content stays MathML
314
+ const annotationHoldsHTML = (/** @type {{attrs?: HTMLAttribute[]}} */ entry) => {
315
+ for (const attr of entry.attrs ?? []) {
316
+ if (attr.name.toLowerCase() === 'encoding') {
317
+ return RE_HTML_ENCODING.test(attr.value ?? '');
318
+ }
319
+ }
320
+ return false;
321
+ };
322
+
323
+ // Escapable raw text is an HTML rule, so what decides it is the namespace the element sits
324
+ // in. Walking down from the root resolves that: `<svg>`/`<math>` lead out of HTML, an
325
+ // integration point leads back in, and a name counts only in the namespace it belongs to
326
+ // (`title` is one in SVG but not in MathML, `annotation-xml` one in MathML but not in SVG)
327
+ /** @param {{lowerTag: string, namespace: string, attrs?: HTMLAttribute[]} | undefined} entry */
328
+ const namespaceInside = (entry) => {
329
+ if (!entry) {
330
+ return '';
331
+ }
332
+ const { namespace, lowerTag } = entry;
333
+ if (!namespace) {
334
+ return lowerTag === 'svg' || lowerTag === 'math' ? lowerTag : '';
335
+ }
336
+ if (namespace === 'svg') {
337
+ return svgIntegrationPoints.has(lowerTag) ? '' : namespace;
338
+ }
339
+ return mathIntegrationPoints.has(lowerTag) || (lowerTag === 'annotation-xml' && annotationHoldsHTML(entry)) ? '' : namespace;
340
+ };
341
+
342
+ // The element itself never decides this: `<svg><title>` is SVG, what it holds is HTML
343
+ const inForeignContent = () => Boolean(stack[stack.length - 1]?.namespace);
344
+
345
+ // The same question for a start tag, which is not on the stack yet: The element enters the
346
+ // namespace its parent holds, except that `svg` and `math` lead out of HTML themselves
347
+ const startsForeignContent = (/** @type {string} */ lowerTag) =>
348
+ Boolean(namespaceInside(stack[stack.length - 1])) || lowerTag === 'svg' || lowerTag === 'math';
349
+
350
+ // Whether the content of the element being parsed is read as text rather than markup
351
+ // (`script` and `style` hold text in every namespace; the rest do so as HTML elements only)
352
+ const holdsRawText = (/** @type {string} */ tag) =>
353
+ special.has(tag) ||
354
+ ((genericRawTextElements.has(tag) || escapableRawTextElements.has(tag)) && !inForeignContent());
355
+
277
356
  while (pos < fullLength) {
278
357
  lastPos = pos;
279
358
 
280
- // Make sure not to be in a `script` or `style` element
281
- if (!lastTagLower || !special.has(lastTagLower)) {
359
+ // Make sure not to be in an element whose content is text, not markup
360
+ if (!lastTagLower || !holdsRawText(lastTagLower)) {
282
361
  const textEnd = fullHtml.indexOf('<', pos);
283
362
 
284
363
  if (textEnd === pos) {
@@ -298,9 +377,9 @@ export class HTMLParser {
298
377
  const endTagMatch = cachedNextEndTag.match;
299
378
  cachedNextStartTag = null;
300
379
  cachedNextEndTag = null;
301
- advance((endTagMatch[0] ?? '').length);
302
- await parseEndTag(endTagMatch[0] ?? '', endTagMatch[1] ?? '');
303
- prevTag = '/' + (endTagMatch[1] ?? '').toLowerCase();
380
+ advance(endTagMatch.text.length);
381
+ await parseEndTag(endTagMatch.text, endTagMatch.name);
382
+ prevTag = '/' + endTagMatch.name.toLowerCase();
304
383
  prevAttrs = [];
305
384
  continue;
306
385
  }
@@ -310,7 +389,8 @@ export class HTMLParser {
310
389
  // Comment
311
390
  commentTestY.lastIndex = pos;
312
391
  if (commentTestY.test(fullHtml)) {
313
- const commentEnd = fullHtml.indexOf('-->', pos + 4);
392
+ const commentEnd = commentEndAhead ? fullHtml.indexOf('-->', pos + 4) : -1;
393
+ if (commentEnd === -1) commentEndAhead = false;
314
394
 
315
395
  if (commentEnd >= 0) {
316
396
  if (handler.comment) {
@@ -327,7 +407,8 @@ export class HTMLParser {
327
407
  // https://web.archive.org/web/20241201212701/https://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
328
408
  conditionalTestY.lastIndex = pos;
329
409
  if (conditionalTestY.test(fullHtml)) {
330
- const conditionalEnd = fullHtml.indexOf(']>', pos + 3);
410
+ const conditionalEnd = conditionalEndAhead ? fullHtml.indexOf(']>', pos + 3) : -1;
411
+ if (conditionalEnd === -1) conditionalEndAhead = false;
331
412
 
332
413
  if (conditionalEnd >= 0) {
333
414
  if (handler.comment) {
@@ -354,15 +435,14 @@ export class HTMLParser {
354
435
  continue;
355
436
  }
356
437
 
357
- // End tag—skip when no `>` lies ahead: The regex cannot match, and would
358
- // otherwise backtrack quadratically on a long unclosed name
438
+ // End tag—skip when no `>` lies ahead: The tag cannot be complete, and matching
439
+ // its name at every position would cost O(n²) on a long unclosed name
359
440
  if (hasCloseAtOrAfter(pos)) {
360
- endTagY.lastIndex = pos;
361
- const endTagMatch = endTagY.exec(fullHtml);
441
+ const endTagMatch = matchEndTag(pos);
362
442
  if (endTagMatch) {
363
- advance((endTagMatch[0] ?? '').length);
364
- await parseEndTag(endTagMatch[0] ?? '', endTagMatch[1] ?? '');
365
- prevTag = '/' + (endTagMatch[1] ?? '').toLowerCase();
443
+ advance(endTagMatch.text.length);
444
+ await parseEndTag(endTagMatch.text, endTagMatch.name);
445
+ prevTag = '/' + endTagMatch.name.toLowerCase();
366
446
  prevAttrs = [];
367
447
  continue;
368
448
  }
@@ -401,10 +481,9 @@ export class HTMLParser {
401
481
  nextAttrs = extractAttrInfo(nextStartTagMatch.attrs);
402
482
  cachedNextStartTag = { match: nextStartTagMatch, pos };
403
483
  } else if (hasCloseAtOrAfter(pos)) {
404
- endTagY.lastIndex = pos;
405
- const nextEndTagMatch = endTagY.exec(fullHtml);
484
+ const nextEndTagMatch = matchEndTag(pos);
406
485
  if (nextEndTagMatch) {
407
- nextTag = '/' + nextEndTagMatch[1];
486
+ nextTag = '/' + nextEndTagMatch.name;
408
487
  nextAttrs = [];
409
488
  cachedNextEndTag = { match: nextEndTagMatch, pos };
410
489
  } else {
@@ -425,32 +504,36 @@ export class HTMLParser {
425
504
  prevAttrs = [];
426
505
  } else {
427
506
  const stackedTag = lastTagLower;
428
- // Use pre-compiled regex for common tags (`script`, `style`, `noscript`) to avoid regex creation overhead
429
- const reStackedTag = /** @type {Record<string, RegExp>} */ (preCompiledStackedTags)[stackedTag] || /** @type {Record<string, RegExp>} */ (reCache)[stackedTag] || (/** @type {Record<string, RegExp>} */ (reCache)[stackedTag] = new RegExp('([\\s\\S]*?)\\x3c/' + stackedTag + '[^>]*>', 'i'));
507
+ const isEscapableRawText = escapableRawTextElements.has(stackedTag);
430
508
 
431
509
  const remaining = sliceFromPos(pos);
432
- const m = reStackedTag.exec(remaining);
433
- if (m && m.index === 0) {
434
- let text = m[1] ?? '';
435
- if (stackedTag !== 'script' && stackedTag !== 'style' && stackedTag !== 'noscript') {
436
- text = stripDelimited(stripDelimited(text, '<!--', '-->'), '<![CDATA[', ']]>');
437
- }
510
+ const rawText = findRawTextEnd(remaining, stackedTag);
511
+ if (rawText) {
512
+ const text = rawText.content;
438
513
  if (handler.chars) {
439
- const result = handler.chars(text);
514
+ // Escapable raw text is a text node like any other, so the handler gets the tags
515
+ // around it—it collapses and trims whitespace by what stands next to the text
516
+ const result = isEscapableRawText
517
+ ? handler.chars(text, stackedTag, '/' + stackedTag, prevAttrs, [])
518
+ : handler.chars(text);
440
519
  if (isThenable(result)) await result;
441
520
  }
442
521
  // Advance HTML past the matched special tag content and its closing tag
443
- advance(m[0].length);
522
+ advance(rawText.length);
444
523
  await parseEndTag('</' + stackedTag + '>', stackedTag);
524
+ // What follows stands after that end tag, not after the start tag still named here—
525
+ // whitespace next to `textarea` stays verbatim only while the element is open
526
+ prevTag = '/' + stackedTag;
527
+ prevAttrs = [];
445
528
  } else {
446
- // No closing tag found; break to avoid an infinite loop
447
- if (handler.continueOnParseError && handler.chars && pos < fullLength) {
448
- const result = handler.chars(fullHtml[pos], prevTag, '', prevAttrs, []);
529
+ // Without an end tag of its own, the element holds the rest of the input as text
530
+ if (handler.chars && remaining) {
531
+ const result = isEscapableRawText
532
+ ? handler.chars(remaining, stackedTag, '', prevAttrs, [])
533
+ : handler.chars(remaining);
449
534
  if (isThenable(result)) await result;
450
- advance(1);
451
- } else {
452
- break;
453
535
  }
536
+ advance(remaining.length);
454
537
  }
455
538
  }
456
539
 
@@ -497,6 +580,21 @@ export class HTMLParser {
497
580
  }).filter(attr => attr.name)); // Filter out invalid entries
498
581
  }
499
582
 
583
+ /**
584
+ * @param {number} startPos
585
+ * @returns {{text: string, name: string} | null} The end tag standing there, or `null`
586
+ * where none is complete
587
+ */
588
+ function matchEndTag(startPos) {
589
+ endTagOpenY.lastIndex = startPos;
590
+ const open = endTagOpenY.exec(fullHtml);
591
+ if (!open) {
592
+ return null;
593
+ }
594
+ const close = findEndTagClose(fullHtml, startPos + open[0].length);
595
+ return close === -1 ? null : { text: fullHtml.slice(startPos, close + 1), name: open[1] ?? '' };
596
+ }
597
+
500
598
  function parseStartTag(/** @type {number} */ startPos) {
501
599
  startTagOpenY.lastIndex = startPos;
502
600
  const start = startTagOpenY.exec(fullHtml);
@@ -730,7 +828,7 @@ export class HTMLParser {
730
828
  if (lowerTagName === 'col' && findTagInCurrentTable('colgroup') < 0) {
731
829
  lastTag = 'colgroup';
732
830
  lastTagLower = 'colgroup';
733
- stack.push({ tag: lastTag, lowerTag: 'colgroup', attrs: [] });
831
+ stack.push({ tag: lastTag, lowerTag: 'colgroup', attrs: [], namespace: namespaceInside(stack[stack.length - 1]) });
734
832
  if (handler.start) {
735
833
  await handler.start(lastTag, [], false, '', true);
736
834
  }
@@ -748,7 +846,10 @@ export class HTMLParser {
748
846
  await parseEndTag('', lastTag);
749
847
  }
750
848
 
751
- const unary = empty.has(lowerTagName) || (lowerTagName === 'html' && lastTagLower === 'head') || !!unarySlash;
849
+ // HTML ignores the slash on a start tag—only in SVG and MathML does it close the
850
+ // element, which `selfClosingSlash` extends back to every element
851
+ const selfClosed = !!unarySlash && (handler.selfClosingSlash || startsForeignContent(lowerTagName));
852
+ const unary = empty.has(lowerTagName) || (lowerTagName === 'html' && lastTagLower === 'head') || selfClosed;
752
853
 
753
854
  const attrs = /** @type {HTMLAttribute[]} */ (match.attrs.map(function (/** @type {Array<string | undefined>} */ args) {
754
855
  /** @type {string | undefined} */
@@ -806,7 +907,7 @@ export class HTMLParser {
806
907
  }));
807
908
 
808
909
  if (!unary) {
809
- stack.push({ tag: tagName, lowerTag: lowerTagName, attrs });
910
+ stack.push({ tag: tagName, lowerTag: lowerTagName, attrs, namespace: namespaceInside(stack[stack.length - 1]) });
810
911
  lastTag = tagName;
811
912
  lastTagLower = lowerTagName;
812
913
  unarySlash = '';
@@ -781,6 +781,8 @@ function buildAttr(normalized, hasUnarySlash, options, isLast, uidAttr) {
781
781
  (options.removeAttributeQuotes && ((uidAttr ? attrValue.indexOf(uidAttr) !== -1 : false) || !canRemoveAttributeQuotes(attrValue))) ||
782
782
  // If `removeAttributeQuotes` is not enabled, preserve original quote style or add quotes if value requires them
783
783
  (!options.removeAttributeQuotes && (attrQuote !== '' || !canRemoveAttributeQuotes(attrValue) ||
784
+ // SVGO reads the whole SVG block as XML, where every attribute value carries quotes
785
+ (Boolean(options.insideSVG) && Boolean(options.minifySVG)) ||
784
786
  // Special case: With `removeTagWhitespace`, unquoted values that aren’t last will have space added,
785
787
  // which can create ambiguous/invalid HTML—add quotes to be safe
786
788
  (options.removeTagWhitespace && attrQuote === '' && !isLast)))
@@ -15,6 +15,17 @@ const RE_TRAILING_SEMICOLON = /;$/;
15
15
  const RE_AMP_ENTITY = /&(#?[0-9a-zA-Z]+;)/g;
16
16
  const RE_LEGACY_ENTITIES = /&((?:Iacute|aacute|uacute|plusmn|Otilde|otilde|agrave|Agrave|Yacute|yacute|Oslash|oslash|atilde|Atilde|brvbar|ccedil|Ccedil|Ograve|curren|divide|eacute|Eacute|ograve|Oacute|egrave|Egrave|Ugrave|frac12|frac14|frac34|ugrave|oacute|iacute|Ntilde|ntilde|Uacute|middot|igrave|Igrave|iquest|Aacute|cedil|laquo|micro|iexcl|Icirc|icirc|acirc|Ucirc|Ecirc|ocirc|Ocirc|ecirc|ucirc|Aring|aring|AElig|aelig|acute|pound|raquo|Acirc|times|THORN|szlig|thorn|COPY|auml|ordf|ordm|Uuml|macr|uuml|Auml|ouml|Ouml|para|nbsp|euml|quot|QUOT|Euml|yuml|cent|sect|copy|sup1|sup2|sup3|iuml|Iuml|ETH|shy|reg|not|yen|amp|AMP|REG|uml|eth|deg|gt|GT|LT|lt)(?!;)|(?:#?[0-9a-zA-Z]+;))/g;
17
17
  const RE_ESCAPE_LT = /</g;
18
+ // In escapable raw text only the element’s own end tag ends the element, so nothing else
19
+ // that `decodeEntities` decoded to a `<` needs escaping there
20
+ // (the record has no prototype, so a tag named after an inherited property—`constructor`,
21
+ // `__proto__`—finds nothing here and falls back to escaping every `<`)
22
+ const RE_ESCAPE_LT_RAW_TEXT = /** @type {Record<string, RegExp>} */ (Object.assign(Object.create(null), {
23
+ textarea: /<(?=\/textarea[\s/>])/gi,
24
+ title: /<(?=\/title[\s/>])/gi
25
+ }));
26
+ // Encodings that make an `annotation-xml` element hold HTML rather than MathML
27
+ // https://html.spec.whatwg.org/multipage/parsing.html#html-integration-point
28
+ const RE_HTML_ENCODING = /^(text\/html|application\/xhtml\+xml)$/i;
18
29
  const RE_ATTR_WS_CHECK = /[ \n\r\t\f]/;
19
30
  const RE_ATTR_WS_COLLAPSE = /[ \n\r\t\f]+/g;
20
31
  const RE_ATTR_WS_TRIM = /^[ \n\r\t\f]+|[ \n\r\t\f]+$/g;
@@ -172,6 +183,23 @@ const htmlElements = new Set(['a', 'abbr', 'acronym', 'address', 'applet', 'area
172
183
 
173
184
  const specialContentElements = new Set(['script', 'style']);
174
185
 
186
+ // Elements the parser reads as raw text as well, though only `script` and `style` are raw text
187
+ // elements by name—these are HTML’s alone, where `script` and `style` hold text in SVG, too
188
+ // https://html.spec.whatwg.org/multipage/parsing.html#generic-raw-text-element-parsing-algorithm
189
+ //
190
+ // (`noscript`, `noframes`, and `noembed` are raw text, too, but stay markup here: What they
191
+ // hold is markup to the UA that displays it—one without scripting or frames—so minifying it
192
+ // as markup keeps what that UA sees)
193
+ const genericRawTextElements = new Set(['iframe', 'xmp']);
194
+
195
+ // Escapable raw text elements, whose content is text rather than markup
196
+ // https://html.spec.whatwg.org/multipage/syntax.html#elements-2
197
+ const escapableRawTextElements = new Set(['textarea', 'title']);
198
+
199
+ // Raw text is read without resolving character references, so its text keeps them—unlike that
200
+ // of `textarea` and `title`, where they are resolved as they are anywhere else
201
+ const rawTextElements = new Set([...specialContentElements, ...genericRawTextElements]);
202
+
175
203
  // Exports
176
204
 
177
205
  export {
@@ -191,6 +219,8 @@ export {
191
219
  RE_AMP_ENTITY,
192
220
  RE_LEGACY_ENTITIES,
193
221
  RE_ESCAPE_LT,
222
+ RE_ESCAPE_LT_RAW_TEXT,
223
+ RE_HTML_ENCODING,
194
224
  RE_ATTR_WS_CHECK,
195
225
  RE_ATTR_WS_COLLAPSE,
196
226
  RE_ATTR_WS_TRIM,
@@ -240,5 +270,8 @@ export {
240
270
  htmlElements,
241
271
 
242
272
  // Special content elements
243
- specialContentElements
273
+ specialContentElements,
274
+ genericRawTextElements,
275
+ escapableRawTextElements,
276
+ rawTextElements
244
277
  };
@@ -91,7 +91,7 @@ const optionDefinitions = {
91
91
  type: 'jsonArray'
92
92
  },
93
93
  keepClosingSlash: {
94
- description: 'Keep the trailing slash on void elements',
94
+ description: 'Keep the trailing slash on void elements and other start tags that carry one, and read it as closing the element',
95
95
  type: 'boolean'
96
96
  },
97
97
  maxInputLength: {
@@ -47,6 +47,7 @@ import { optionDefinitions, optionDefaults } from './option-definitions.js';
47
47
  * cssContext?: CSSContext,
48
48
  * nameParent?: (name: string) => string,
49
49
  * nameHTML?: (name: string) => string,
50
+ * keepClosingSlashHTML?: boolean,
50
51
  * insideSVG?: boolean,
51
52
  * insideForeignContent?: boolean
52
53
  * }} ProcessedOptions
package/src/lib/utils.js CHANGED
@@ -814,17 +814,18 @@ function describeQuantifierRisk(pattern) {
814
814
  * over quoted attribute values (which may contain `>`).
815
815
  * @param {string} html
816
816
  * @param {number} pos - Start position (just after the tag name)
817
+ * @param {number} [limit] - Position to stop the search at (exclusive)
817
818
  * @returns {number} Index of the closing `>`, or -1 if not found
818
819
  */
819
- function findTagEnd(html, pos) {
820
+ function findTagEnd(html, pos, limit = html.length) {
820
821
  let i = pos;
821
- while (i < html.length) {
822
+ while (i < limit) {
822
823
  const ch = html[i];
823
824
  if (ch === '>') return i;
824
825
  if (ch === '"' || ch === "'") {
825
826
  const q = ch;
826
827
  i++;
827
- while (i < html.length && html[i] !== q) i++;
828
+ while (i < limit && html[i] !== q) i++;
828
829
  }
829
830
  i++;
830
831
  }
@@ -237,8 +237,10 @@ function collapseWhitespaceSmart(str, prevTag, nextTag, prevAttrs, nextAttrs, op
237
237
 
238
238
  // Collapse/trim whitespace for given tag
239
239
 
240
- const noCollapseWhitespaceTags = new Set(['script', 'style', 'pre', 'textarea']);
241
- const noTrimWhitespaceTags = new Set(['pre', 'textarea']);
240
+ // `xmp`, `listing`, and `plaintext` render preformatted, as `pre` does
241
+ // https://html.spec.whatwg.org/multipage/rendering.html#the-page
242
+ const noCollapseWhitespaceTags = new Set(['script', 'style', 'pre', 'textarea', 'xmp', 'listing', 'plaintext']);
243
+ const noTrimWhitespaceTags = new Set(['pre', 'textarea', 'xmp', 'listing', 'plaintext']);
242
244
 
243
245
  /** @param {string} tag */
244
246
  function canCollapseWhitespace(tag) {