htmlnano 3.0.0 → 3.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.
Files changed (115) hide show
  1. package/README.md +40 -25
  2. package/dist/_modules/collapseAttributeWhitespace.d.mts +41 -5
  3. package/dist/_modules/collapseAttributeWhitespace.d.ts +41 -5
  4. package/dist/_modules/collapseAttributeWhitespace.js +69 -16
  5. package/dist/_modules/collapseAttributeWhitespace.mjs +67 -17
  6. package/dist/_modules/collapseBooleanAttributes.d.mts +36 -3
  7. package/dist/_modules/collapseBooleanAttributes.d.ts +36 -3
  8. package/dist/_modules/collapseBooleanAttributes.js +18 -11
  9. package/dist/_modules/collapseBooleanAttributes.mjs +18 -11
  10. package/dist/_modules/collapseWhitespace.d.mts +36 -3
  11. package/dist/_modules/collapseWhitespace.d.ts +36 -3
  12. package/dist/_modules/collapseWhitespace.js +25 -2
  13. package/dist/_modules/collapseWhitespace.mjs +25 -2
  14. package/dist/_modules/custom.d.mts +36 -3
  15. package/dist/_modules/custom.d.ts +36 -3
  16. package/dist/_modules/deduplicateAttributeValues.d.mts +36 -3
  17. package/dist/_modules/deduplicateAttributeValues.d.ts +36 -3
  18. package/dist/_modules/deduplicateAttributeValues.js +20 -5
  19. package/dist/_modules/deduplicateAttributeValues.mjs +21 -6
  20. package/dist/_modules/example.d.mts +36 -3
  21. package/dist/_modules/example.d.ts +36 -3
  22. package/dist/_modules/mergeScripts.d.mts +36 -3
  23. package/dist/_modules/mergeScripts.d.ts +36 -3
  24. package/dist/_modules/mergeScripts.js +111 -24
  25. package/dist/_modules/mergeScripts.mjs +111 -24
  26. package/dist/_modules/mergeStyles.d.mts +36 -3
  27. package/dist/_modules/mergeStyles.d.ts +36 -3
  28. package/dist/_modules/mergeStyles.js +66 -4
  29. package/dist/_modules/mergeStyles.mjs +66 -4
  30. package/dist/_modules/minifyAttributes.d.mts +95 -0
  31. package/dist/_modules/minifyAttributes.d.ts +95 -0
  32. package/dist/_modules/minifyAttributes.js +159 -0
  33. package/dist/_modules/minifyAttributes.mjs +157 -0
  34. package/dist/_modules/minifyConditionalComments.d.mts +36 -3
  35. package/dist/_modules/minifyConditionalComments.d.ts +36 -3
  36. package/dist/_modules/minifyConditionalComments.js +37 -19
  37. package/dist/_modules/minifyConditionalComments.mjs +37 -19
  38. package/dist/_modules/minifyCss.d.mts +36 -3
  39. package/dist/_modules/minifyCss.d.ts +36 -3
  40. package/dist/_modules/minifyCss.js +13 -27
  41. package/dist/_modules/minifyCss.mjs +14 -28
  42. package/dist/_modules/minifyHtmlTemplate.d.mts +91 -0
  43. package/dist/_modules/minifyHtmlTemplate.d.ts +91 -0
  44. package/dist/_modules/minifyHtmlTemplate.js +231 -0
  45. package/dist/_modules/minifyHtmlTemplate.mjs +228 -0
  46. package/dist/_modules/minifyJs.d.mts +36 -3
  47. package/dist/_modules/minifyJs.d.ts +36 -3
  48. package/dist/_modules/minifyJs.js +106 -5
  49. package/dist/_modules/minifyJs.mjs +107 -6
  50. package/dist/_modules/minifyJson.d.mts +36 -3
  51. package/dist/_modules/minifyJson.d.ts +36 -3
  52. package/dist/_modules/minifyJson.js +8 -11
  53. package/dist/_modules/minifyJson.mjs +8 -11
  54. package/dist/_modules/minifySvg.d.mts +36 -3
  55. package/dist/_modules/minifySvg.d.ts +36 -3
  56. package/dist/_modules/minifySvg.js +35 -4
  57. package/dist/_modules/minifySvg.mjs +35 -4
  58. package/dist/_modules/minifyUrls.d.mts +37 -4
  59. package/dist/_modules/minifyUrls.d.ts +37 -4
  60. package/dist/_modules/minifyUrls.js +52 -27
  61. package/dist/_modules/minifyUrls.mjs +52 -27
  62. package/dist/_modules/normalizeAttributeValues.d.mts +36 -3
  63. package/dist/_modules/normalizeAttributeValues.d.ts +36 -3
  64. package/dist/_modules/normalizeAttributeValues.js +10 -8
  65. package/dist/_modules/normalizeAttributeValues.mjs +10 -8
  66. package/dist/_modules/removeAttributeQuotes.d.mts +40 -4
  67. package/dist/_modules/removeAttributeQuotes.d.ts +40 -4
  68. package/dist/_modules/removeAttributeQuotes.js +9 -4
  69. package/dist/_modules/removeAttributeQuotes.mjs +9 -4
  70. package/dist/_modules/removeComments.d.mts +37 -4
  71. package/dist/_modules/removeComments.d.ts +37 -4
  72. package/dist/_modules/removeComments.js +44 -12
  73. package/dist/_modules/removeComments.mjs +44 -12
  74. package/dist/_modules/removeEmptyAttributes.d.mts +36 -3
  75. package/dist/_modules/removeEmptyAttributes.d.ts +36 -3
  76. package/dist/_modules/removeEmptyAttributes.js +37 -16
  77. package/dist/_modules/removeEmptyAttributes.mjs +37 -16
  78. package/dist/_modules/removeEmptyElements.d.mts +95 -0
  79. package/dist/_modules/removeEmptyElements.d.ts +95 -0
  80. package/dist/_modules/removeEmptyElements.js +90 -0
  81. package/dist/_modules/removeEmptyElements.mjs +88 -0
  82. package/dist/_modules/removeOptionalTags.d.mts +36 -3
  83. package/dist/_modules/removeOptionalTags.d.ts +36 -3
  84. package/dist/_modules/removeOptionalTags.js +39 -28
  85. package/dist/_modules/removeOptionalTags.mjs +39 -28
  86. package/dist/_modules/removeRedundantAttributes.d.mts +36 -3
  87. package/dist/_modules/removeRedundantAttributes.d.ts +36 -3
  88. package/dist/_modules/removeRedundantAttributes.js +43 -28
  89. package/dist/_modules/removeRedundantAttributes.mjs +43 -28
  90. package/dist/_modules/removeUnusedCss.d.mts +37 -3
  91. package/dist/_modules/removeUnusedCss.d.ts +37 -3
  92. package/dist/_modules/removeUnusedCss.js +40 -14
  93. package/dist/_modules/removeUnusedCss.mjs +41 -15
  94. package/dist/_modules/sortAttributes.d.mts +39 -5
  95. package/dist/_modules/sortAttributes.d.ts +39 -5
  96. package/dist/_modules/sortAttributes.js +27 -8
  97. package/dist/_modules/sortAttributes.mjs +27 -8
  98. package/dist/_modules/sortAttributesWithLists.d.mts +39 -4
  99. package/dist/_modules/sortAttributesWithLists.d.ts +39 -4
  100. package/dist/_modules/sortAttributesWithLists.js +61 -52
  101. package/dist/_modules/sortAttributesWithLists.mjs +62 -53
  102. package/dist/helpers.d.ts +8 -1
  103. package/dist/helpers.js +48 -0
  104. package/dist/helpers.mjs +45 -1
  105. package/dist/index.d.ts +37 -4
  106. package/dist/index.js +13 -0
  107. package/dist/index.mjs +13 -0
  108. package/dist/presets/ampSafe.d.ts +36 -3
  109. package/dist/presets/max.d.ts +36 -3
  110. package/dist/presets/max.js +13 -5
  111. package/dist/presets/max.mjs +13 -5
  112. package/dist/presets/safe.d.ts +36 -3
  113. package/dist/presets/safe.js +6 -0
  114. package/dist/presets/safe.mjs +6 -0
  115. package/package.json +27 -15
@@ -2,16 +2,24 @@ import PostHTML from 'posthtml';
2
2
  import { MinifyOptions } from 'terser';
3
3
  import { Options } from 'cssnano';
4
4
  import { Config } from 'svgo';
5
+ import { UserDefinedOptions } from 'purgecss';
5
6
 
6
7
  type PostHTMLTreeLike = [PostHTML.Node] & PostHTML.NodeAPI & {
7
8
  options?: {
8
9
  quoteAllAttributes?: boolean | undefined;
10
+ quoteStyle?: 0 | 1 | 2 | undefined;
11
+ replaceQuote?: boolean | undefined;
9
12
  } | undefined;
10
13
  render(): string;
11
14
  render(node: PostHTML.Node | PostHTMLTreeLike, renderOptions?: any): string;
12
15
  };
13
16
  type MaybeArray<T> = T | Array<T>;
14
17
  type PostHTMLNodeLike = PostHTML.Node | string;
18
+ type HtmlnanoTemplateRule = {
19
+ tag: string;
20
+ attrs?: Record<string, string | boolean | void>;
21
+ };
22
+ type MinifyHtmlTemplateOptions = boolean | HtmlnanoTemplateRule[];
15
23
  interface HtmlnanoOptions {
16
24
  skipConfigLoading?: boolean;
17
25
  configPath?: string;
@@ -27,17 +35,42 @@ interface HtmlnanoOptions {
27
35
  mergeStyles?: boolean;
28
36
  mergeScripts?: boolean;
29
37
  minifyCss?: Options | boolean;
38
+ minifyHtmlTemplate?: MinifyHtmlTemplateOptions;
30
39
  minifyConditionalComments?: boolean;
31
40
  minifyJs?: MinifyOptions | boolean;
32
41
  minifyJson?: boolean;
42
+ minifyAttributes?: boolean | {
43
+ metaContent?: boolean;
44
+ redundantWhitespaces?: 'safe' | 'agressive' | false;
45
+ };
33
46
  minifySvg?: Config | boolean;
34
47
  normalizeAttributeValues?: boolean;
35
- removeAttributeQuotes?: boolean;
36
- removeComments?: boolean | 'safe' | 'all' | RegExp | ((comment: string) => boolean);
48
+ removeAttributeQuotes?: boolean | {
49
+ force?: boolean;
50
+ };
51
+ removeComments?: boolean | RegExp | ((comment: string) => boolean) | string;
37
52
  removeEmptyAttributes?: boolean;
53
+ removeEmptyElements?: boolean | {
54
+ removeWithAttributes?: boolean;
55
+ };
38
56
  removeRedundantAttributes?: boolean;
39
57
  removeOptionalTags?: boolean;
40
- removeUnusedCss?: boolean;
58
+ removeUnusedCss?: boolean | ({
59
+ tool: 'purgeCSS';
60
+ } & Omit<UserDefinedOptions, 'content' | 'css' | 'extractors'>) | {
61
+ banner?: boolean;
62
+ csspath?: string;
63
+ htmlroot?: string;
64
+ ignore?: (string | RegExp)[];
65
+ inject?: string;
66
+ jsdom?: object;
67
+ media?: string[];
68
+ report?: boolean;
69
+ strictSSL?: boolean;
70
+ timeout?: number;
71
+ uncssrc?: string;
72
+ userAgent?: string;
73
+ };
41
74
  sortAttributes?: boolean | 'alphabetical' | 'frequency';
42
75
  sortAttributesWithLists?: boolean | 'alphabetical' | 'frequency';
43
76
  }
@@ -2,16 +2,24 @@ import PostHTML from 'posthtml';
2
2
  import { MinifyOptions } from 'terser';
3
3
  import { Options } from 'cssnano';
4
4
  import { Config } from 'svgo';
5
+ import { UserDefinedOptions } from 'purgecss';
5
6
 
6
7
  type PostHTMLTreeLike = [PostHTML.Node] & PostHTML.NodeAPI & {
7
8
  options?: {
8
9
  quoteAllAttributes?: boolean | undefined;
10
+ quoteStyle?: 0 | 1 | 2 | undefined;
11
+ replaceQuote?: boolean | undefined;
9
12
  } | undefined;
10
13
  render(): string;
11
14
  render(node: PostHTML.Node | PostHTMLTreeLike, renderOptions?: any): string;
12
15
  };
13
16
  type MaybeArray<T> = T | Array<T>;
14
17
  type PostHTMLNodeLike = PostHTML.Node | string;
18
+ type HtmlnanoTemplateRule = {
19
+ tag: string;
20
+ attrs?: Record<string, string | boolean | void>;
21
+ };
22
+ type MinifyHtmlTemplateOptions = boolean | HtmlnanoTemplateRule[];
15
23
  interface HtmlnanoOptions {
16
24
  skipConfigLoading?: boolean;
17
25
  configPath?: string;
@@ -27,17 +35,42 @@ interface HtmlnanoOptions {
27
35
  mergeStyles?: boolean;
28
36
  mergeScripts?: boolean;
29
37
  minifyCss?: Options | boolean;
38
+ minifyHtmlTemplate?: MinifyHtmlTemplateOptions;
30
39
  minifyConditionalComments?: boolean;
31
40
  minifyJs?: MinifyOptions | boolean;
32
41
  minifyJson?: boolean;
42
+ minifyAttributes?: boolean | {
43
+ metaContent?: boolean;
44
+ redundantWhitespaces?: 'safe' | 'agressive' | false;
45
+ };
33
46
  minifySvg?: Config | boolean;
34
47
  normalizeAttributeValues?: boolean;
35
- removeAttributeQuotes?: boolean;
36
- removeComments?: boolean | 'safe' | 'all' | RegExp | ((comment: string) => boolean);
48
+ removeAttributeQuotes?: boolean | {
49
+ force?: boolean;
50
+ };
51
+ removeComments?: boolean | RegExp | ((comment: string) => boolean) | string;
37
52
  removeEmptyAttributes?: boolean;
53
+ removeEmptyElements?: boolean | {
54
+ removeWithAttributes?: boolean;
55
+ };
38
56
  removeRedundantAttributes?: boolean;
39
57
  removeOptionalTags?: boolean;
40
- removeUnusedCss?: boolean;
58
+ removeUnusedCss?: boolean | ({
59
+ tool: 'purgeCSS';
60
+ } & Omit<UserDefinedOptions, 'content' | 'css' | 'extractors'>) | {
61
+ banner?: boolean;
62
+ csspath?: string;
63
+ htmlroot?: string;
64
+ ignore?: (string | RegExp)[];
65
+ inject?: string;
66
+ jsdom?: object;
67
+ media?: string[];
68
+ report?: boolean;
69
+ strictSSL?: boolean;
70
+ timeout?: number;
71
+ uncssrc?: string;
72
+ userAgent?: string;
73
+ };
41
74
  sortAttributes?: boolean | 'alphabetical' | 'frequency';
42
75
  sortAttributesWithLists?: boolean | 'alphabetical' | 'frequency';
43
76
  }
@@ -22,7 +22,7 @@ const postcssOptions = {
22
22
  if (node.attrs && 'integrity' in node.attrs) {
23
23
  return node;
24
24
  }
25
- if (helpers_js.isStyleNode(node)) {
25
+ if (helpers_js.isStyleNode(node) && helpers_js.isCssStyleType(node)) {
26
26
  p = processStyleNode(node, cssnanoOptions, cssnano, postcss);
27
27
  if (p) {
28
28
  promises.push(p);
@@ -40,26 +40,17 @@ const postcssOptions = {
40
40
  };
41
41
  function processStyleNode(styleNode, cssnanoOptions, cssnano, postcss) {
42
42
  let css = helpers_js.extractCssFromStyleNode(styleNode);
43
- if (!css) return;
44
- // Improve performance by avoiding calling stripCdata again and again
45
- let isCdataWrapped = false;
46
- if (css.includes('CDATA')) {
47
- const strippedCss = stripCdata(css);
48
- isCdataWrapped = css !== strippedCss;
49
- css = strippedCss;
50
- }
43
+ if (!css || css.trim() === '') return;
44
+ // Improve performance by avoiding calling stripCssCdata again and again
45
+ const { strippedCss, isCdataWrapped } = helpers_js.stripCssCdata(css);
46
+ css = strippedCss;
51
47
  return postcss([
52
48
  cssnano(cssnanoOptions)
53
49
  ]).process(css, postcssOptions).then((result)=>{
54
- if (isCdataWrapped) {
55
- styleNode.content = [
56
- '<![CDATA[' + result.toString() + ']]>'
57
- ];
58
- } else {
59
- styleNode.content = [
60
- result.css
61
- ];
62
- }
50
+ const minifiedCss = isCdataWrapped ? result.toString() : result.css;
51
+ styleNode.content = [
52
+ helpers_js.wrapCssCdata(minifiedCss, isCdataWrapped)
53
+ ];
63
54
  });
64
55
  }
65
56
  function processStyleAttr(node, cssnanoOptions, cssnano, postcss) {
@@ -67,7 +58,10 @@ function processStyleAttr(node, cssnanoOptions, cssnano, postcss) {
67
58
  // a{color: red;}
68
59
  const wrapperStart = 'a{';
69
60
  const wrapperEnd = '}';
70
- if (!node.attrs || !node.attrs.style) {
61
+ if (!node.attrs || !node.attrs.style || typeof node.attrs.style !== 'string') {
62
+ return;
63
+ }
64
+ if (node.attrs.style.trim() === '') {
71
65
  return;
72
66
  }
73
67
  const wrappedStyle = wrapperStart + (node.attrs.style || '') + wrapperEnd;
@@ -79,13 +73,5 @@ function processStyleAttr(node, cssnanoOptions, cssnano, postcss) {
79
73
  node.attrs.style = minifiedCss.substring(wrapperStart.length, minifiedCss.length - wrapperEnd.length);
80
74
  });
81
75
  }
82
- function stripCdata(css) {
83
- const leftStrippedCss = css.replace('<![CDATA[', '');
84
- if (leftStrippedCss === css) {
85
- return css;
86
- }
87
- const strippedCss = leftStrippedCss.replace(']]>', '');
88
- return leftStrippedCss === strippedCss ? css : strippedCss;
89
- }
90
76
 
91
77
  exports.default = mod;
@@ -1,4 +1,4 @@
1
- import { optionalImport, isStyleNode, extractCssFromStyleNode } from '../helpers.mjs';
1
+ import { optionalImport, isStyleNode, isCssStyleType, extractCssFromStyleNode, stripCssCdata, wrapCssCdata } from '../helpers.mjs';
2
2
 
3
3
  const postcssOptions = {
4
4
  // Prevent the following warning from being shown:
@@ -20,7 +20,7 @@ const postcssOptions = {
20
20
  if (node.attrs && 'integrity' in node.attrs) {
21
21
  return node;
22
22
  }
23
- if (isStyleNode(node)) {
23
+ if (isStyleNode(node) && isCssStyleType(node)) {
24
24
  p = processStyleNode(node, cssnanoOptions, cssnano, postcss);
25
25
  if (p) {
26
26
  promises.push(p);
@@ -38,26 +38,17 @@ const postcssOptions = {
38
38
  };
39
39
  function processStyleNode(styleNode, cssnanoOptions, cssnano, postcss) {
40
40
  let css = extractCssFromStyleNode(styleNode);
41
- if (!css) return;
42
- // Improve performance by avoiding calling stripCdata again and again
43
- let isCdataWrapped = false;
44
- if (css.includes('CDATA')) {
45
- const strippedCss = stripCdata(css);
46
- isCdataWrapped = css !== strippedCss;
47
- css = strippedCss;
48
- }
41
+ if (!css || css.trim() === '') return;
42
+ // Improve performance by avoiding calling stripCssCdata again and again
43
+ const { strippedCss, isCdataWrapped } = stripCssCdata(css);
44
+ css = strippedCss;
49
45
  return postcss([
50
46
  cssnano(cssnanoOptions)
51
47
  ]).process(css, postcssOptions).then((result)=>{
52
- if (isCdataWrapped) {
53
- styleNode.content = [
54
- '<![CDATA[' + result.toString() + ']]>'
55
- ];
56
- } else {
57
- styleNode.content = [
58
- result.css
59
- ];
60
- }
48
+ const minifiedCss = isCdataWrapped ? result.toString() : result.css;
49
+ styleNode.content = [
50
+ wrapCssCdata(minifiedCss, isCdataWrapped)
51
+ ];
61
52
  });
62
53
  }
63
54
  function processStyleAttr(node, cssnanoOptions, cssnano, postcss) {
@@ -65,7 +56,10 @@ function processStyleAttr(node, cssnanoOptions, cssnano, postcss) {
65
56
  // a{color: red;}
66
57
  const wrapperStart = 'a{';
67
58
  const wrapperEnd = '}';
68
- if (!node.attrs || !node.attrs.style) {
59
+ if (!node.attrs || !node.attrs.style || typeof node.attrs.style !== 'string') {
60
+ return;
61
+ }
62
+ if (node.attrs.style.trim() === '') {
69
63
  return;
70
64
  }
71
65
  const wrappedStyle = wrapperStart + (node.attrs.style || '') + wrapperEnd;
@@ -77,13 +71,5 @@ function processStyleAttr(node, cssnanoOptions, cssnano, postcss) {
77
71
  node.attrs.style = minifiedCss.substring(wrapperStart.length, minifiedCss.length - wrapperEnd.length);
78
72
  });
79
73
  }
80
- function stripCdata(css) {
81
- const leftStrippedCss = css.replace('<![CDATA[', '');
82
- if (leftStrippedCss === css) {
83
- return css;
84
- }
85
- const strippedCss = leftStrippedCss.replace(']]>', '');
86
- return leftStrippedCss === strippedCss ? css : strippedCss;
87
- }
88
74
 
89
75
  export { mod as default };
@@ -0,0 +1,91 @@
1
+ import PostHTML from 'posthtml';
2
+ import { MinifyOptions } from 'terser';
3
+ import { Options } from 'cssnano';
4
+ import { Config } from 'svgo';
5
+ import { UserDefinedOptions } from 'purgecss';
6
+
7
+ type PostHTMLTreeLike = [PostHTML.Node] & PostHTML.NodeAPI & {
8
+ options?: {
9
+ quoteAllAttributes?: boolean | undefined;
10
+ quoteStyle?: 0 | 1 | 2 | undefined;
11
+ replaceQuote?: boolean | undefined;
12
+ } | undefined;
13
+ render(): string;
14
+ render(node: PostHTML.Node | PostHTMLTreeLike, renderOptions?: any): string;
15
+ };
16
+ type MaybeArray<T> = T | Array<T>;
17
+ type PostHTMLNodeLike = PostHTML.Node | string;
18
+ type HtmlnanoTemplateRule = {
19
+ tag: string;
20
+ attrs?: Record<string, string | boolean | void>;
21
+ };
22
+ type MinifyHtmlTemplateOptions = boolean | HtmlnanoTemplateRule[];
23
+ interface HtmlnanoOptions {
24
+ skipConfigLoading?: boolean;
25
+ configPath?: string;
26
+ skipInternalWarnings?: boolean;
27
+ collapseAttributeWhitespace?: boolean;
28
+ collapseBooleanAttributes?: {
29
+ amphtml?: boolean;
30
+ };
31
+ collapseWhitespace?: 'conservative' | 'all' | 'aggressive';
32
+ custom?: MaybeArray<(tree: PostHTMLTreeLike, options?: any) => (PostHTML.Node | PostHTMLTreeLike)>;
33
+ deduplicateAttributeValues?: boolean;
34
+ minifyUrls?: URL | string | false;
35
+ mergeStyles?: boolean;
36
+ mergeScripts?: boolean;
37
+ minifyCss?: Options | boolean;
38
+ minifyHtmlTemplate?: MinifyHtmlTemplateOptions;
39
+ minifyConditionalComments?: boolean;
40
+ minifyJs?: MinifyOptions | boolean;
41
+ minifyJson?: boolean;
42
+ minifyAttributes?: boolean | {
43
+ metaContent?: boolean;
44
+ redundantWhitespaces?: 'safe' | 'agressive' | false;
45
+ };
46
+ minifySvg?: Config | boolean;
47
+ normalizeAttributeValues?: boolean;
48
+ removeAttributeQuotes?: boolean | {
49
+ force?: boolean;
50
+ };
51
+ removeComments?: boolean | RegExp | ((comment: string) => boolean) | string;
52
+ removeEmptyAttributes?: boolean;
53
+ removeEmptyElements?: boolean | {
54
+ removeWithAttributes?: boolean;
55
+ };
56
+ removeRedundantAttributes?: boolean;
57
+ removeOptionalTags?: boolean;
58
+ removeUnusedCss?: boolean | ({
59
+ tool: 'purgeCSS';
60
+ } & Omit<UserDefinedOptions, 'content' | 'css' | 'extractors'>) | {
61
+ banner?: boolean;
62
+ csspath?: string;
63
+ htmlroot?: string;
64
+ ignore?: (string | RegExp)[];
65
+ inject?: string;
66
+ jsdom?: object;
67
+ media?: string[];
68
+ report?: boolean;
69
+ strictSSL?: boolean;
70
+ timeout?: number;
71
+ uncssrc?: string;
72
+ userAgent?: string;
73
+ };
74
+ sortAttributes?: boolean | 'alphabetical' | 'frequency';
75
+ sortAttributesWithLists?: boolean | 'alphabetical' | 'frequency';
76
+ }
77
+ type HtmlnanoModuleAttrsHandler = (attrs: Record<string, string | boolean | void>, node: PostHTML.Node) => Record<string, string | boolean | void>;
78
+ type HtmlnanoModuleContentHandler = (content: Array<PostHTMLNodeLike>, node: PostHTML.Node) => MaybeArray<PostHTMLNodeLike>;
79
+ type HtmlnanoModuleNodeHandler = (node: PostHTMLNodeLike) => PostHTML.Node | string;
80
+ type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends object ? Partial<T> : T;
81
+ type HtmlnanoModule<Options = any> = {
82
+ onAttrs?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleAttrsHandler;
83
+ onContent?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleContentHandler;
84
+ onNode?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleNodeHandler;
85
+ default?: (tree: PostHTMLTreeLike, options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => PostHTMLTreeLike | Promise<PostHTMLTreeLike>;
86
+ };
87
+
88
+ declare const defaultRules: HtmlnanoTemplateRule[];
89
+ declare const mod: HtmlnanoModule<MinifyHtmlTemplateOptions>;
90
+
91
+ export { mod as default, defaultRules };
@@ -0,0 +1,91 @@
1
+ import PostHTML from 'posthtml';
2
+ import { MinifyOptions } from 'terser';
3
+ import { Options } from 'cssnano';
4
+ import { Config } from 'svgo';
5
+ import { UserDefinedOptions } from 'purgecss';
6
+
7
+ type PostHTMLTreeLike = [PostHTML.Node] & PostHTML.NodeAPI & {
8
+ options?: {
9
+ quoteAllAttributes?: boolean | undefined;
10
+ quoteStyle?: 0 | 1 | 2 | undefined;
11
+ replaceQuote?: boolean | undefined;
12
+ } | undefined;
13
+ render(): string;
14
+ render(node: PostHTML.Node | PostHTMLTreeLike, renderOptions?: any): string;
15
+ };
16
+ type MaybeArray<T> = T | Array<T>;
17
+ type PostHTMLNodeLike = PostHTML.Node | string;
18
+ type HtmlnanoTemplateRule = {
19
+ tag: string;
20
+ attrs?: Record<string, string | boolean | void>;
21
+ };
22
+ type MinifyHtmlTemplateOptions = boolean | HtmlnanoTemplateRule[];
23
+ interface HtmlnanoOptions {
24
+ skipConfigLoading?: boolean;
25
+ configPath?: string;
26
+ skipInternalWarnings?: boolean;
27
+ collapseAttributeWhitespace?: boolean;
28
+ collapseBooleanAttributes?: {
29
+ amphtml?: boolean;
30
+ };
31
+ collapseWhitespace?: 'conservative' | 'all' | 'aggressive';
32
+ custom?: MaybeArray<(tree: PostHTMLTreeLike, options?: any) => (PostHTML.Node | PostHTMLTreeLike)>;
33
+ deduplicateAttributeValues?: boolean;
34
+ minifyUrls?: URL | string | false;
35
+ mergeStyles?: boolean;
36
+ mergeScripts?: boolean;
37
+ minifyCss?: Options | boolean;
38
+ minifyHtmlTemplate?: MinifyHtmlTemplateOptions;
39
+ minifyConditionalComments?: boolean;
40
+ minifyJs?: MinifyOptions | boolean;
41
+ minifyJson?: boolean;
42
+ minifyAttributes?: boolean | {
43
+ metaContent?: boolean;
44
+ redundantWhitespaces?: 'safe' | 'agressive' | false;
45
+ };
46
+ minifySvg?: Config | boolean;
47
+ normalizeAttributeValues?: boolean;
48
+ removeAttributeQuotes?: boolean | {
49
+ force?: boolean;
50
+ };
51
+ removeComments?: boolean | RegExp | ((comment: string) => boolean) | string;
52
+ removeEmptyAttributes?: boolean;
53
+ removeEmptyElements?: boolean | {
54
+ removeWithAttributes?: boolean;
55
+ };
56
+ removeRedundantAttributes?: boolean;
57
+ removeOptionalTags?: boolean;
58
+ removeUnusedCss?: boolean | ({
59
+ tool: 'purgeCSS';
60
+ } & Omit<UserDefinedOptions, 'content' | 'css' | 'extractors'>) | {
61
+ banner?: boolean;
62
+ csspath?: string;
63
+ htmlroot?: string;
64
+ ignore?: (string | RegExp)[];
65
+ inject?: string;
66
+ jsdom?: object;
67
+ media?: string[];
68
+ report?: boolean;
69
+ strictSSL?: boolean;
70
+ timeout?: number;
71
+ uncssrc?: string;
72
+ userAgent?: string;
73
+ };
74
+ sortAttributes?: boolean | 'alphabetical' | 'frequency';
75
+ sortAttributesWithLists?: boolean | 'alphabetical' | 'frequency';
76
+ }
77
+ type HtmlnanoModuleAttrsHandler = (attrs: Record<string, string | boolean | void>, node: PostHTML.Node) => Record<string, string | boolean | void>;
78
+ type HtmlnanoModuleContentHandler = (content: Array<PostHTMLNodeLike>, node: PostHTML.Node) => MaybeArray<PostHTMLNodeLike>;
79
+ type HtmlnanoModuleNodeHandler = (node: PostHTMLNodeLike) => PostHTML.Node | string;
80
+ type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends object ? Partial<T> : T;
81
+ type HtmlnanoModule<Options = any> = {
82
+ onAttrs?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleAttrsHandler;
83
+ onContent?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleContentHandler;
84
+ onNode?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleNodeHandler;
85
+ default?: (tree: PostHTMLTreeLike, options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => PostHTMLTreeLike | Promise<PostHTMLTreeLike>;
86
+ };
87
+
88
+ declare const defaultRules: HtmlnanoTemplateRule[];
89
+ declare const mod: HtmlnanoModule<MinifyHtmlTemplateOptions>;
90
+
91
+ export { mod as default, defaultRules };