htmlnano 2.1.2 → 2.1.4

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 (191) hide show
  1. package/README.md +54 -12
  2. package/dist/_modules/collapseAttributeWhitespace.d.mts +57 -0
  3. package/dist/_modules/collapseAttributeWhitespace.d.ts +57 -0
  4. package/dist/_modules/collapseAttributeWhitespace.js +296 -0
  5. package/dist/_modules/collapseAttributeWhitespace.mjs +293 -0
  6. package/dist/_modules/collapseBooleanAttributes.d.mts +60 -0
  7. package/dist/_modules/collapseBooleanAttributes.d.ts +60 -0
  8. package/dist/_modules/collapseBooleanAttributes.js +159 -0
  9. package/{lib/modules → dist/_modules}/collapseBooleanAttributes.mjs +39 -57
  10. package/dist/_modules/collapseWhitespace.d.mts +57 -0
  11. package/dist/_modules/collapseWhitespace.d.ts +57 -0
  12. package/dist/_modules/collapseWhitespace.js +172 -0
  13. package/dist/_modules/collapseWhitespace.mjs +170 -0
  14. package/dist/_modules/custom.d.mts +57 -0
  15. package/dist/_modules/custom.d.ts +57 -0
  16. package/dist/_modules/custom.js +22 -0
  17. package/dist/_modules/custom.mjs +20 -0
  18. package/dist/_modules/deduplicateAttributeValues.d.mts +56 -0
  19. package/dist/_modules/deduplicateAttributeValues.d.ts +56 -0
  20. package/dist/_modules/deduplicateAttributeValues.js +38 -0
  21. package/dist/_modules/deduplicateAttributeValues.mjs +36 -0
  22. package/dist/_modules/example.d.mts +59 -0
  23. package/dist/_modules/example.d.ts +59 -0
  24. package/dist/_modules/example.js +67 -0
  25. package/dist/_modules/example.mjs +65 -0
  26. package/dist/_modules/mergeScripts.d.mts +56 -0
  27. package/dist/_modules/mergeScripts.d.ts +56 -0
  28. package/dist/_modules/mergeScripts.js +53 -0
  29. package/dist/_modules/mergeScripts.mjs +51 -0
  30. package/dist/_modules/mergeStyles.d.mts +56 -0
  31. package/dist/_modules/mergeStyles.d.ts +56 -0
  32. package/dist/_modules/mergeStyles.js +42 -0
  33. package/dist/_modules/mergeStyles.mjs +40 -0
  34. package/dist/_modules/minifyConditionalComments.d.mts +56 -0
  35. package/dist/_modules/minifyConditionalComments.d.ts +56 -0
  36. package/dist/_modules/minifyConditionalComments.js +54 -0
  37. package/{lib/modules → dist/_modules}/minifyConditionalComments.mjs +21 -22
  38. package/dist/_modules/minifyCss.d.mts +56 -0
  39. package/dist/_modules/minifyCss.d.ts +56 -0
  40. package/dist/_modules/minifyCss.js +84 -0
  41. package/dist/_modules/minifyCss.mjs +82 -0
  42. package/dist/_modules/minifyJs.d.mts +56 -0
  43. package/dist/_modules/minifyJs.d.ts +56 -0
  44. package/dist/_modules/minifyJs.js +108 -0
  45. package/dist/_modules/minifyJs.mjs +106 -0
  46. package/dist/_modules/minifyJson.d.mts +56 -0
  47. package/dist/_modules/minifyJson.d.ts +56 -0
  48. package/dist/_modules/minifyJson.js +35 -0
  49. package/dist/_modules/minifyJson.mjs +33 -0
  50. package/dist/_modules/minifySvg.d.mts +56 -0
  51. package/dist/_modules/minifySvg.d.ts +56 -0
  52. package/dist/_modules/minifySvg.js +40 -0
  53. package/dist/_modules/minifySvg.mjs +38 -0
  54. package/dist/_modules/minifyUrls.d.mts +56 -0
  55. package/dist/_modules/minifyUrls.d.ts +56 -0
  56. package/dist/_modules/minifyUrls.js +180 -0
  57. package/dist/_modules/minifyUrls.mjs +178 -0
  58. package/dist/_modules/normalizeAttributeValues.d.mts +56 -0
  59. package/dist/_modules/normalizeAttributeValues.d.ts +56 -0
  60. package/dist/_modules/normalizeAttributeValues.js +234 -0
  61. package/dist/_modules/normalizeAttributeValues.mjs +232 -0
  62. package/dist/_modules/removeAttributeQuotes.d.mts +56 -0
  63. package/dist/_modules/removeAttributeQuotes.d.ts +56 -0
  64. package/dist/_modules/removeAttributeQuotes.js +15 -0
  65. package/dist/_modules/removeAttributeQuotes.mjs +13 -0
  66. package/dist/_modules/removeComments.d.mts +58 -0
  67. package/dist/_modules/removeComments.d.ts +58 -0
  68. package/dist/_modules/removeComments.js +83 -0
  69. package/{lib/modules → dist/_modules}/removeComments.mjs +24 -35
  70. package/dist/_modules/removeEmptyAttributes.d.mts +56 -0
  71. package/dist/_modules/removeEmptyAttributes.d.ts +56 -0
  72. package/dist/_modules/removeEmptyAttributes.js +197 -0
  73. package/dist/_modules/removeEmptyAttributes.mjs +195 -0
  74. package/dist/_modules/removeOptionalTags.d.mts +56 -0
  75. package/dist/_modules/removeOptionalTags.d.ts +56 -0
  76. package/dist/_modules/removeOptionalTags.js +190 -0
  77. package/{lib/modules → dist/_modules}/removeOptionalTags.mjs +54 -91
  78. package/dist/_modules/removeRedundantAttributes.d.mts +57 -0
  79. package/dist/_modules/removeRedundantAttributes.d.ts +57 -0
  80. package/dist/_modules/removeRedundantAttributes.js +128 -0
  81. package/{lib/modules → dist/_modules}/removeRedundantAttributes.mjs +43 -59
  82. package/dist/_modules/removeUnusedCss.d.mts +60 -0
  83. package/dist/_modules/removeUnusedCss.d.ts +60 -0
  84. package/dist/_modules/removeUnusedCss.js +134 -0
  85. package/dist/_modules/removeUnusedCss.mjs +132 -0
  86. package/dist/_modules/sortAttributes.d.mts +57 -0
  87. package/dist/_modules/sortAttributes.d.ts +57 -0
  88. package/dist/_modules/sortAttributes.js +102 -0
  89. package/{lib/modules → dist/_modules}/sortAttributes.mjs +39 -58
  90. package/dist/_modules/sortAttributesWithLists.d.mts +56 -0
  91. package/dist/_modules/sortAttributesWithLists.d.ts +56 -0
  92. package/dist/_modules/sortAttributesWithLists.js +118 -0
  93. package/{lib/modules → dist/_modules}/sortAttributesWithLists.mjs +41 -59
  94. package/dist/helpers.d.ts +16 -0
  95. package/dist/helpers.js +72 -0
  96. package/dist/helpers.mjs +63 -0
  97. package/dist/index.d.ts +79 -0
  98. package/dist/index.js +223 -0
  99. package/dist/index.mjs +209 -0
  100. package/dist/presets/ampSafe.d.ts +47 -0
  101. package/dist/presets/ampSafe.js +19 -0
  102. package/{lib → dist}/presets/ampSafe.mjs +6 -4
  103. package/dist/presets/max.d.ts +47 -0
  104. package/dist/presets/max.js +28 -0
  105. package/{lib → dist}/presets/max.mjs +6 -4
  106. package/dist/presets/safe.d.ts +47 -0
  107. package/dist/presets/safe.js +60 -0
  108. package/{lib → dist}/presets/safe.mjs +13 -20
  109. package/package.json +53 -56
  110. package/.eslintignore +0 -3
  111. package/CHANGELOG.md +0 -409
  112. package/docs/README.md +0 -33
  113. package/docs/babel.config.js +0 -3
  114. package/docs/docs/010-introduction.md +0 -22
  115. package/docs/docs/020-usage.md +0 -117
  116. package/docs/docs/030-config.md +0 -21
  117. package/docs/docs/040-presets.md +0 -75
  118. package/docs/docs/050-modules.md +0 -855
  119. package/docs/docs/060-contribute.md +0 -16
  120. package/docs/docusaurus.config.js +0 -65
  121. package/docs/netlify.toml +0 -4
  122. package/docs/package-lock.json +0 -21630
  123. package/docs/package.json +0 -40
  124. package/docs/sidebars.js +0 -26
  125. package/docs/versioned_docs/version-1.1.1/010-introduction.md +0 -22
  126. package/docs/versioned_docs/version-1.1.1/020-usage.md +0 -77
  127. package/docs/versioned_docs/version-1.1.1/030-config.md +0 -21
  128. package/docs/versioned_docs/version-1.1.1/040-presets.md +0 -75
  129. package/docs/versioned_docs/version-1.1.1/050-modules.md +0 -785
  130. package/docs/versioned_docs/version-1.1.1/060-contribute.md +0 -16
  131. package/docs/versioned_docs/version-2.0.0/010-introduction.md +0 -22
  132. package/docs/versioned_docs/version-2.0.0/020-usage.md +0 -77
  133. package/docs/versioned_docs/version-2.0.0/030-config.md +0 -21
  134. package/docs/versioned_docs/version-2.0.0/040-presets.md +0 -75
  135. package/docs/versioned_docs/version-2.0.0/050-modules.md +0 -838
  136. package/docs/versioned_docs/version-2.0.0/060-contribute.md +0 -16
  137. package/docs/versioned_sidebars/version-1.1.1-sidebars.json +0 -8
  138. package/docs/versioned_sidebars/version-2.0.0-sidebars.json +0 -8
  139. package/docs/versions.json +0 -4
  140. package/index.cjs +0 -11
  141. package/index.d.cts +0 -3
  142. package/index.d.mts +0 -3
  143. package/index.d.ts +0 -94
  144. package/index.mjs +0 -2
  145. package/lib/helpers.cjs +0 -79
  146. package/lib/helpers.mjs +0 -53
  147. package/lib/htmlnano.cjs +0 -202
  148. package/lib/htmlnano.mjs +0 -198
  149. package/lib/modules/collapseAttributeWhitespace.cjs +0 -86
  150. package/lib/modules/collapseAttributeWhitespace.mjs +0 -104
  151. package/lib/modules/collapseBooleanAttributes.cjs +0 -62
  152. package/lib/modules/collapseWhitespace.cjs +0 -100
  153. package/lib/modules/collapseWhitespace.mjs +0 -132
  154. package/lib/modules/custom.cjs +0 -19
  155. package/lib/modules/custom.mjs +0 -16
  156. package/lib/modules/deduplicateAttributeValues.cjs +0 -38
  157. package/lib/modules/deduplicateAttributeValues.mjs +0 -40
  158. package/lib/modules/example.cjs +0 -85
  159. package/lib/modules/example.mjs +0 -75
  160. package/lib/modules/mergeScripts.cjs +0 -54
  161. package/lib/modules/mergeScripts.mjs +0 -56
  162. package/lib/modules/mergeStyles.cjs +0 -38
  163. package/lib/modules/mergeStyles.mjs +0 -36
  164. package/lib/modules/minifyConditionalComments.cjs +0 -47
  165. package/lib/modules/minifyCss.cjs +0 -73
  166. package/lib/modules/minifyCss.mjs +0 -88
  167. package/lib/modules/minifyJs.cjs +0 -103
  168. package/lib/modules/minifyJs.mjs +0 -121
  169. package/lib/modules/minifyJson.cjs +0 -24
  170. package/lib/modules/minifyJson.mjs +0 -21
  171. package/lib/modules/minifySvg.cjs +0 -37
  172. package/lib/modules/minifySvg.mjs +0 -30
  173. package/lib/modules/minifyUrls.cjs +0 -141
  174. package/lib/modules/minifyUrls.mjs +0 -229
  175. package/lib/modules/normalizeAttributeValues.cjs +0 -120
  176. package/lib/modules/normalizeAttributeValues.mjs +0 -140
  177. package/lib/modules/removeAttributeQuotes.cjs +0 -17
  178. package/lib/modules/removeAttributeQuotes.mjs +0 -12
  179. package/lib/modules/removeComments.cjs +0 -86
  180. package/lib/modules/removeEmptyAttributes.cjs +0 -72
  181. package/lib/modules/removeEmptyAttributes.mjs +0 -121
  182. package/lib/modules/removeOptionalTags.cjs +0 -183
  183. package/lib/modules/removeRedundantAttributes.cjs +0 -112
  184. package/lib/modules/removeUnusedCss.cjs +0 -113
  185. package/lib/modules/removeUnusedCss.mjs +0 -122
  186. package/lib/modules/sortAttributes.cjs +0 -98
  187. package/lib/modules/sortAttributesWithLists.cjs +0 -114
  188. package/lib/presets/ampSafe.cjs +0 -18
  189. package/lib/presets/max.cjs +0 -27
  190. package/lib/presets/safe.cjs +0 -65
  191. package/test.js +0 -23
@@ -0,0 +1,72 @@
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+
3
+ const ampBoilerplateAttributes = [
4
+ 'amp-boilerplate',
5
+ 'amp4ads-boilerplate',
6
+ 'amp4email-boilerplate'
7
+ ];
8
+ function isAmpBoilerplate(node) {
9
+ if (!node.attrs) {
10
+ return false;
11
+ }
12
+ for (const attr of ampBoilerplateAttributes){
13
+ if (attr in node.attrs) {
14
+ return true;
15
+ }
16
+ }
17
+ return false;
18
+ }
19
+ function isComment(content) {
20
+ if (typeof content === 'string') {
21
+ return content.trim().startsWith('<!--');
22
+ }
23
+ return false;
24
+ }
25
+ function isConditionalComment(content) {
26
+ const clean = (content || '').trim();
27
+ return clean.startsWith('<!--[if') || clean === '<!--<![endif]-->';
28
+ }
29
+ function isStyleNode(node) {
30
+ return node.tag === 'style' && !isAmpBoilerplate(node) && 'content' in node && node.content && node.content.length > 0;
31
+ }
32
+ function extractCssFromStyleNode(node) {
33
+ return Array.isArray(node.content) ? node.content.join(' ') : node.content;
34
+ }
35
+ function isEventHandler(attributeName) {
36
+ return attributeName && attributeName.slice(0, 2).toLowerCase() === 'on' && attributeName.length >= 5;
37
+ }
38
+ function extractTextContentFromNode(node) {
39
+ if (!node.content) {
40
+ return '';
41
+ }
42
+ if (!Array.isArray(node.content)) {
43
+ return '';
44
+ }
45
+ let content = '';
46
+ for (const child of node.content){
47
+ if (typeof child === 'string') {
48
+ content += child;
49
+ }
50
+ }
51
+ return content;
52
+ }
53
+ async function optionalImport(moduleName) {
54
+ try {
55
+ const module = await import(moduleName);
56
+ return module.default || module;
57
+ } catch (e) {
58
+ if (typeof e === 'object' && e && 'code' in e && (e.code === 'MODULE_NOT_FOUND' || e.code === 'ERR_MODULE_NOT_FOUND')) {
59
+ return null;
60
+ }
61
+ throw e;
62
+ }
63
+ }
64
+
65
+ exports.extractCssFromStyleNode = extractCssFromStyleNode;
66
+ exports.extractTextContentFromNode = extractTextContentFromNode;
67
+ exports.isAmpBoilerplate = isAmpBoilerplate;
68
+ exports.isComment = isComment;
69
+ exports.isConditionalComment = isConditionalComment;
70
+ exports.isEventHandler = isEventHandler;
71
+ exports.isStyleNode = isStyleNode;
72
+ exports.optionalImport = optionalImport;
@@ -0,0 +1,63 @@
1
+ const ampBoilerplateAttributes = [
2
+ 'amp-boilerplate',
3
+ 'amp4ads-boilerplate',
4
+ 'amp4email-boilerplate'
5
+ ];
6
+ function isAmpBoilerplate(node) {
7
+ if (!node.attrs) {
8
+ return false;
9
+ }
10
+ for (const attr of ampBoilerplateAttributes){
11
+ if (attr in node.attrs) {
12
+ return true;
13
+ }
14
+ }
15
+ return false;
16
+ }
17
+ function isComment(content) {
18
+ if (typeof content === 'string') {
19
+ return content.trim().startsWith('<!--');
20
+ }
21
+ return false;
22
+ }
23
+ function isConditionalComment(content) {
24
+ const clean = (content || '').trim();
25
+ return clean.startsWith('<!--[if') || clean === '<!--<![endif]-->';
26
+ }
27
+ function isStyleNode(node) {
28
+ return node.tag === 'style' && !isAmpBoilerplate(node) && 'content' in node && node.content && node.content.length > 0;
29
+ }
30
+ function extractCssFromStyleNode(node) {
31
+ return Array.isArray(node.content) ? node.content.join(' ') : node.content;
32
+ }
33
+ function isEventHandler(attributeName) {
34
+ return attributeName && attributeName.slice(0, 2).toLowerCase() === 'on' && attributeName.length >= 5;
35
+ }
36
+ function extractTextContentFromNode(node) {
37
+ if (!node.content) {
38
+ return '';
39
+ }
40
+ if (!Array.isArray(node.content)) {
41
+ return '';
42
+ }
43
+ let content = '';
44
+ for (const child of node.content){
45
+ if (typeof child === 'string') {
46
+ content += child;
47
+ }
48
+ }
49
+ return content;
50
+ }
51
+ async function optionalImport(moduleName) {
52
+ try {
53
+ const module = await import(moduleName);
54
+ return module.default || module;
55
+ } catch (e) {
56
+ if (typeof e === 'object' && e && 'code' in e && (e.code === 'MODULE_NOT_FOUND' || e.code === 'ERR_MODULE_NOT_FOUND')) {
57
+ return null;
58
+ }
59
+ throw e;
60
+ }
61
+ }
62
+
63
+ export { extractCssFromStyleNode, extractTextContentFromNode, isAmpBoilerplate, isComment, isConditionalComment, isEventHandler, isStyleNode, optionalImport };
@@ -0,0 +1,79 @@
1
+ import PostHTML from 'posthtml';
2
+ import { MinifyOptions } from 'terser';
3
+ import { Options } from 'cssnano';
4
+ import { Config } from 'svgo';
5
+
6
+ type PostHTMLTreeLike = [PostHTML.Node] & PostHTML.NodeAPI & {
7
+ options?: {
8
+ quoteAllAttributes?: boolean | undefined;
9
+ } | undefined;
10
+ render(): string;
11
+ render(node: PostHTML.Node | PostHTMLTreeLike, renderOptions?: any): string;
12
+ };
13
+ type MaybeArray<T> = T | Array<T>;
14
+ type PostHTMLNodeLike = PostHTML.Node | string;
15
+ interface HtmlnanoOptions {
16
+ skipConfigLoading?: boolean;
17
+ skipInternalWarnings?: boolean;
18
+ collapseAttributeWhitespace?: boolean;
19
+ collapseBooleanAttributes?: {
20
+ amphtml?: boolean;
21
+ };
22
+ collapseWhitespace?: 'conservative' | 'all' | 'aggressive';
23
+ custom?: MaybeArray<(tree: PostHTMLTreeLike, options?: any) => (PostHTML.Node | PostHTMLTreeLike)>;
24
+ deduplicateAttributeValues?: boolean;
25
+ minifyUrls?: URL | string | false;
26
+ mergeStyles?: boolean;
27
+ mergeScripts?: boolean;
28
+ minifyCss?: Options | boolean;
29
+ minifyConditionalComments?: boolean;
30
+ minifyJs?: MinifyOptions | boolean;
31
+ minifyJson?: boolean;
32
+ minifySvg?: Config | boolean;
33
+ normalizeAttributeValues?: boolean;
34
+ removeAttributeQuotes?: boolean;
35
+ removeComments?: boolean | 'safe' | 'all' | RegExp | ((comment: string) => boolean);
36
+ removeEmptyAttributes?: boolean;
37
+ removeRedundantAttributes?: boolean;
38
+ removeOptionalTags?: boolean;
39
+ removeUnusedCss?: boolean;
40
+ sortAttributes?: boolean | 'alphabetical' | 'frequency';
41
+ sortAttributesWithLists?: boolean | 'alphabetical' | 'frequency';
42
+ }
43
+ interface HtmlnanoPreset extends Omit<HtmlnanoOptions, 'skipConfigLoading'> {
44
+ }
45
+ type HtmlnanoPredefinedPreset = 'safe' | 'ampSafe' | 'max';
46
+ type HtmlnanoPredefinedPresets = Record<HtmlnanoPredefinedPreset, HtmlnanoPreset>;
47
+ type HtmlnanoOptionsConfigFile = Omit<HtmlnanoOptions, 'skipConfigLoading'> & {
48
+ preset?: HtmlnanoPredefinedPreset;
49
+ };
50
+ type HtmlnanoModuleAttrsHandler = (attrs: Record<string, string | boolean | void>, node: PostHTML.Node) => Record<string, string | boolean | void>;
51
+ type HtmlnanoModuleContentHandler = (content: Array<PostHTMLNodeLike>, node: PostHTML.Node) => MaybeArray<PostHTMLNodeLike>;
52
+ type HtmlnanoModuleNodeHandler = (node: PostHTMLNodeLike) => PostHTML.Node | string;
53
+ type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends object ? Partial<T> : T;
54
+ type HtmlnanoModule<Options = any> = {
55
+ onAttrs?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleAttrsHandler;
56
+ onContent?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleContentHandler;
57
+ onNode?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleNodeHandler;
58
+ default?: (tree: PostHTMLTreeLike, options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => PostHTMLTreeLike | Promise<PostHTMLTreeLike>;
59
+ };
60
+
61
+ declare function loadConfig(options?: HtmlnanoOptions, preset?: HtmlnanoPreset, configPath?: string): [Partial<HtmlnanoOptions>, HtmlnanoPreset];
62
+ declare function htmlnano(optionsRun?: HtmlnanoOptions, presetRun?: HtmlnanoPreset): PostHTML.Plugin<never>;
63
+ declare namespace htmlnano {
64
+ var presets: HtmlnanoPredefinedPresets;
65
+ var getRequiredOptionalDependencies: typeof getRequiredOptionalDependencies;
66
+ var process: typeof process;
67
+ var htmlMinimizerWebpackPluginMinify: typeof htmlMinimizerWebpackPluginMinify;
68
+ var loadConfig: typeof loadConfig;
69
+ }
70
+ declare function getRequiredOptionalDependencies(optionsRun: HtmlnanoOptions, presetRun: HtmlnanoPreset): string[];
71
+ declare function process(html: string, options?: HtmlnanoOptions, preset?: HtmlnanoPreset, postHtmlOptions?: PostHTML.Options): Promise<PostHTML.Result<unknown>>;
72
+ declare function htmlMinimizerWebpackPluginMinify(input: {
73
+ [file: string]: string;
74
+ }, minimizerOptions?: HtmlnanoOptions): Promise<{
75
+ code: string;
76
+ }>;
77
+
78
+ export { htmlnano as default, getRequiredOptionalDependencies, htmlMinimizerWebpackPluginMinify, htmlnano, loadConfig, process };
79
+ export type { HtmlnanoModule, HtmlnanoModuleAttrsHandler, HtmlnanoModuleContentHandler, HtmlnanoModuleNodeHandler, HtmlnanoOptions, HtmlnanoOptionsConfigFile, HtmlnanoPredefinedPreset, HtmlnanoPredefinedPresets, HtmlnanoPreset, PostHTMLNodeLike, PostHTMLTreeLike };
package/dist/index.js ADDED
@@ -0,0 +1,223 @@
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+
3
+ var posthtml = require('posthtml');
4
+ var cosmiconfig = require('cosmiconfig');
5
+ var safePreset = require('./presets/safe.js');
6
+ var ampSafePreset = require('./presets/ampSafe.js');
7
+ var maxPreset = require('./presets/max.js');
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+
11
+ var posthtml__default = /*#__PURE__*/_interopDefault(posthtml);
12
+ var safePreset__default = /*#__PURE__*/_interopDefault(safePreset);
13
+ var ampSafePreset__default = /*#__PURE__*/_interopDefault(ampSafePreset);
14
+ var maxPreset__default = /*#__PURE__*/_interopDefault(maxPreset);
15
+
16
+ const presets = {
17
+ safe: safePreset__default.default,
18
+ ampSafe: ampSafePreset__default.default,
19
+ max: maxPreset__default.default
20
+ };
21
+ function loadConfig(options, preset, configPath) {
22
+ const { skipConfigLoading = false, ...rest } = options || {};
23
+ let restConfig = rest;
24
+ if (!skipConfigLoading) {
25
+ const explorer = cosmiconfig.cosmiconfigSync('htmlnano');
26
+ const rc = configPath ? explorer.load(configPath) : explorer.search();
27
+ if (rc) {
28
+ const { preset: presetName } = rc.config;
29
+ if (presetName) {
30
+ if (!preset && presetName in presets) {
31
+ preset = presets[presetName];
32
+ }
33
+ delete rc.config.preset;
34
+ }
35
+ if (!options) {
36
+ restConfig = rc.config;
37
+ }
38
+ }
39
+ }
40
+ return [
41
+ restConfig || {},
42
+ preset || safePreset__default.default
43
+ ];
44
+ }
45
+ const optionalDependencies = {
46
+ minifyCss: [
47
+ 'cssnano',
48
+ 'postcss'
49
+ ],
50
+ minifyJs: [
51
+ 'terser'
52
+ ],
53
+ minifyUrls: [
54
+ 'relateurl',
55
+ 'srcset',
56
+ 'terser'
57
+ ],
58
+ minifySvg: [
59
+ 'svgo'
60
+ ]
61
+ };
62
+ const interop = (imported)=>imported.then((mod)=>mod.default);
63
+ const modules = {
64
+ collapseAttributeWhitespace: ()=>interop(import('./_modules/collapseAttributeWhitespace.js')),
65
+ collapseBooleanAttributes: ()=>interop(import('./_modules/collapseBooleanAttributes.js')),
66
+ collapseWhitespace: ()=>interop(import('./_modules/collapseWhitespace.js')),
67
+ custom: ()=>interop(import('./_modules/custom.js')),
68
+ deduplicateAttributeValues: ()=>interop(import('./_modules/deduplicateAttributeValues.js')),
69
+ // example: () => import('./_modules/example.mjs'),
70
+ mergeScripts: ()=>interop(import('./_modules/mergeScripts.js')),
71
+ mergeStyles: ()=>interop(import('./_modules/mergeStyles.js')),
72
+ minifyConditionalComments: ()=>interop(import('./_modules/minifyConditionalComments.js')),
73
+ minifyCss: ()=>interop(import('./_modules/minifyCss.js')),
74
+ minifyJs: ()=>interop(import('./_modules/minifyJs.js')),
75
+ minifyJson: ()=>interop(import('./_modules/minifyJson.js')),
76
+ minifySvg: ()=>interop(import('./_modules/minifySvg.js')),
77
+ minifyUrls: ()=>interop(import('./_modules/minifyUrls.js')),
78
+ normalizeAttributeValues: ()=>interop(import('./_modules/normalizeAttributeValues.js')),
79
+ removeAttributeQuotes: ()=>interop(import('./_modules/removeAttributeQuotes.js')),
80
+ removeComments: ()=>interop(import('./_modules/removeComments.js')),
81
+ removeEmptyAttributes: ()=>interop(import('./_modules/removeEmptyAttributes.js')),
82
+ removeOptionalTags: ()=>interop(import('./_modules/removeOptionalTags.js')),
83
+ removeRedundantAttributes: ()=>interop(import('./_modules/removeRedundantAttributes.js')),
84
+ removeUnusedCss: ()=>interop(import('./_modules/removeUnusedCss.js')),
85
+ sortAttributes: ()=>interop(import('./_modules/sortAttributes.js')),
86
+ sortAttributesWithLists: ()=>interop(import('./_modules/sortAttributesWithLists.js'))
87
+ };
88
+ function htmlnano(optionsRun = {}, presetRun) {
89
+ // eslint-disable-next-line prefer-const -- re-assign options
90
+ let [options, preset] = loadConfig(optionsRun, presetRun);
91
+ const minifier = async (_tree)=>{
92
+ const tree = _tree;
93
+ const nodeHandlers = [];
94
+ const attrsHandlers = [];
95
+ const contentsHandlers = [];
96
+ options = {
97
+ ...preset,
98
+ ...options
99
+ };
100
+ let promise = Promise.resolve(tree);
101
+ for (const [moduleName, moduleOptions] of Object.entries(options)){
102
+ if (!moduleOptions) {
103
+ continue;
104
+ }
105
+ if (!(moduleName in safePreset__default.default)) {
106
+ throw new Error('Module "' + moduleName + '" is not defined');
107
+ }
108
+ if (moduleName in optionalDependencies) {
109
+ const modules = optionalDependencies[moduleName];
110
+ await Promise.all(modules.map(async (dependency)=>{
111
+ try {
112
+ await import(dependency);
113
+ } catch (e) {
114
+ if (typeof e === 'object' && e !== null && 'code' in e && typeof e.code === 'string') {
115
+ if (e.code === 'MODULE_NOT_FOUND' || e.code === 'ERR_MODULE_NOT_FOUND') {
116
+ if (!options.skipInternalWarnings) {
117
+ console.warn(`You have to install "${dependency}" in order to use htmlnano's "${moduleName}" module`);
118
+ return;
119
+ }
120
+ }
121
+ throw e;
122
+ }
123
+ }
124
+ }));
125
+ }
126
+ const mod = moduleName in modules ? await modules[moduleName]() : await import(`./_modules/${moduleName}.mjs`);
127
+ if (typeof mod.onAttrs === 'function') {
128
+ attrsHandlers.push(mod.onAttrs(options, moduleOptions));
129
+ }
130
+ if (typeof mod.onContent === 'function') {
131
+ contentsHandlers.push(mod.onContent(options, moduleOptions));
132
+ }
133
+ if (typeof mod.onNode === 'function') {
134
+ nodeHandlers.push(mod.onNode(options, moduleOptions));
135
+ }
136
+ if (typeof mod.default === 'function') {
137
+ promise = promise.then(async (tree)=>await mod.default(tree, options, moduleOptions));
138
+ }
139
+ }
140
+ if (attrsHandlers.length + contentsHandlers.length + nodeHandlers.length === 0) {
141
+ return promise;
142
+ }
143
+ return promise.then((tree)=>{
144
+ tree.walk((node)=>{
145
+ if (node) {
146
+ if (node.attrs && typeof node.attrs === 'object') {
147
+ // Convert all attrs' key to lower case
148
+ let newAttrsObj = {};
149
+ Object.entries(node.attrs).forEach(([attrName, attrValue])=>{
150
+ newAttrsObj[attrName.toLowerCase()] = attrValue;
151
+ });
152
+ for (const handler of attrsHandlers){
153
+ newAttrsObj = handler(newAttrsObj, node);
154
+ }
155
+ node.attrs = newAttrsObj;
156
+ }
157
+ if (node.content) {
158
+ node.content = typeof node.content === 'string' ? [
159
+ node.content
160
+ ] : node.content;
161
+ if (Array.isArray(node.content) && node.content.length > 0) {
162
+ for (const handler of contentsHandlers){
163
+ var _node_content;
164
+ const result = handler((_node_content = node.content) != null ? _node_content : [], node);
165
+ node.content = Array.isArray(result) ? result : [
166
+ result
167
+ ];
168
+ }
169
+ }
170
+ }
171
+ for (const handler of nodeHandlers){
172
+ if (handler) {
173
+ node = handler(node);
174
+ }
175
+ }
176
+ }
177
+ return node;
178
+ });
179
+ return tree;
180
+ });
181
+ };
182
+ return minifier;
183
+ }
184
+ function getRequiredOptionalDependencies(optionsRun, presetRun) {
185
+ const [options] = loadConfig(optionsRun, presetRun);
186
+ return Array.from(Object.keys(options).reduce((acc, moduleName)=>{
187
+ if (moduleName in optionalDependencies) {
188
+ const dependencies = optionalDependencies[moduleName];
189
+ // eslint-disable-next-line @typescript-eslint/unbound-method -- thisArg provided by forEach
190
+ dependencies.forEach(acc.add, acc);
191
+ }
192
+ return acc;
193
+ }, new Set()));
194
+ }
195
+ function process(html, options, preset, postHtmlOptions) {
196
+ return posthtml__default.default([
197
+ htmlnano(options, preset)
198
+ ]).process(html, postHtmlOptions);
199
+ }
200
+ // https://github.com/webpack-contrib/html-minimizer-webpack-plugin/blob/faca00f2219514bc671c5942685721f0b5dbaa70/src/utils.js#L74
201
+ function htmlMinimizerWebpackPluginMinify(input, minimizerOptions) {
202
+ const [[, code]] = Object.entries(input);
203
+ return htmlnano.process(code, minimizerOptions, presets.safe).then((result)=>{
204
+ return {
205
+ code: result.html
206
+ };
207
+ });
208
+ }
209
+ htmlnano.presets = presets;
210
+ htmlnano.getRequiredOptionalDependencies = getRequiredOptionalDependencies;
211
+ htmlnano.process = process;
212
+ htmlnano.htmlMinimizerWebpackPluginMinify = htmlMinimizerWebpackPluginMinify;
213
+ htmlnano.loadConfig = loadConfig;
214
+ if (typeof module !== 'undefined') {
215
+ module.exports = htmlnano;
216
+ }
217
+
218
+ exports.default = htmlnano;
219
+ exports.getRequiredOptionalDependencies = getRequiredOptionalDependencies;
220
+ exports.htmlMinimizerWebpackPluginMinify = htmlMinimizerWebpackPluginMinify;
221
+ exports.htmlnano = htmlnano;
222
+ exports.loadConfig = loadConfig;
223
+ exports.process = process;
package/dist/index.mjs ADDED
@@ -0,0 +1,209 @@
1
+ import posthtml from 'posthtml';
2
+ import { cosmiconfigSync } from 'cosmiconfig';
3
+ import safePreset from './presets/safe.mjs';
4
+ import ampSafePreset from './presets/ampSafe.mjs';
5
+ import maxPreset from './presets/max.mjs';
6
+
7
+ const presets = {
8
+ safe: safePreset,
9
+ ampSafe: ampSafePreset,
10
+ max: maxPreset
11
+ };
12
+ function loadConfig(options, preset, configPath) {
13
+ const { skipConfigLoading = false, ...rest } = options || {};
14
+ let restConfig = rest;
15
+ if (!skipConfigLoading) {
16
+ const explorer = cosmiconfigSync('htmlnano');
17
+ const rc = configPath ? explorer.load(configPath) : explorer.search();
18
+ if (rc) {
19
+ const { preset: presetName } = rc.config;
20
+ if (presetName) {
21
+ if (!preset && presetName in presets) {
22
+ preset = presets[presetName];
23
+ }
24
+ delete rc.config.preset;
25
+ }
26
+ if (!options) {
27
+ restConfig = rc.config;
28
+ }
29
+ }
30
+ }
31
+ return [
32
+ restConfig || {},
33
+ preset || safePreset
34
+ ];
35
+ }
36
+ const optionalDependencies = {
37
+ minifyCss: [
38
+ 'cssnano',
39
+ 'postcss'
40
+ ],
41
+ minifyJs: [
42
+ 'terser'
43
+ ],
44
+ minifyUrls: [
45
+ 'relateurl',
46
+ 'srcset',
47
+ 'terser'
48
+ ],
49
+ minifySvg: [
50
+ 'svgo'
51
+ ]
52
+ };
53
+ const interop = (imported)=>imported.then((mod)=>mod.default);
54
+ const modules = {
55
+ collapseAttributeWhitespace: ()=>interop(import('./_modules/collapseAttributeWhitespace.mjs')),
56
+ collapseBooleanAttributes: ()=>interop(import('./_modules/collapseBooleanAttributes.mjs')),
57
+ collapseWhitespace: ()=>interop(import('./_modules/collapseWhitespace.mjs')),
58
+ custom: ()=>interop(import('./_modules/custom.mjs')),
59
+ deduplicateAttributeValues: ()=>interop(import('./_modules/deduplicateAttributeValues.mjs')),
60
+ // example: () => import('./_modules/example.mjs'),
61
+ mergeScripts: ()=>interop(import('./_modules/mergeScripts.mjs')),
62
+ mergeStyles: ()=>interop(import('./_modules/mergeStyles.mjs')),
63
+ minifyConditionalComments: ()=>interop(import('./_modules/minifyConditionalComments.mjs')),
64
+ minifyCss: ()=>interop(import('./_modules/minifyCss.mjs')),
65
+ minifyJs: ()=>interop(import('./_modules/minifyJs.mjs')),
66
+ minifyJson: ()=>interop(import('./_modules/minifyJson.mjs')),
67
+ minifySvg: ()=>interop(import('./_modules/minifySvg.mjs')),
68
+ minifyUrls: ()=>interop(import('./_modules/minifyUrls.mjs')),
69
+ normalizeAttributeValues: ()=>interop(import('./_modules/normalizeAttributeValues.mjs')),
70
+ removeAttributeQuotes: ()=>interop(import('./_modules/removeAttributeQuotes.mjs')),
71
+ removeComments: ()=>interop(import('./_modules/removeComments.mjs')),
72
+ removeEmptyAttributes: ()=>interop(import('./_modules/removeEmptyAttributes.mjs')),
73
+ removeOptionalTags: ()=>interop(import('./_modules/removeOptionalTags.mjs')),
74
+ removeRedundantAttributes: ()=>interop(import('./_modules/removeRedundantAttributes.mjs')),
75
+ removeUnusedCss: ()=>interop(import('./_modules/removeUnusedCss.mjs')),
76
+ sortAttributes: ()=>interop(import('./_modules/sortAttributes.mjs')),
77
+ sortAttributesWithLists: ()=>interop(import('./_modules/sortAttributesWithLists.mjs'))
78
+ };
79
+ function htmlnano(optionsRun = {}, presetRun) {
80
+ // eslint-disable-next-line prefer-const -- re-assign options
81
+ let [options, preset] = loadConfig(optionsRun, presetRun);
82
+ const minifier = async (_tree)=>{
83
+ const tree = _tree;
84
+ const nodeHandlers = [];
85
+ const attrsHandlers = [];
86
+ const contentsHandlers = [];
87
+ options = {
88
+ ...preset,
89
+ ...options
90
+ };
91
+ let promise = Promise.resolve(tree);
92
+ for (const [moduleName, moduleOptions] of Object.entries(options)){
93
+ if (!moduleOptions) {
94
+ continue;
95
+ }
96
+ if (!(moduleName in safePreset)) {
97
+ throw new Error('Module "' + moduleName + '" is not defined');
98
+ }
99
+ if (moduleName in optionalDependencies) {
100
+ const modules = optionalDependencies[moduleName];
101
+ await Promise.all(modules.map(async (dependency)=>{
102
+ try {
103
+ await import(dependency);
104
+ } catch (e) {
105
+ if (typeof e === 'object' && e !== null && 'code' in e && typeof e.code === 'string') {
106
+ if (e.code === 'MODULE_NOT_FOUND' || e.code === 'ERR_MODULE_NOT_FOUND') {
107
+ if (!options.skipInternalWarnings) {
108
+ console.warn(`You have to install "${dependency}" in order to use htmlnano's "${moduleName}" module`);
109
+ return;
110
+ }
111
+ }
112
+ throw e;
113
+ }
114
+ }
115
+ }));
116
+ }
117
+ const mod = moduleName in modules ? await modules[moduleName]() : await import(`./_modules/${moduleName}.mjs`);
118
+ if (typeof mod.onAttrs === 'function') {
119
+ attrsHandlers.push(mod.onAttrs(options, moduleOptions));
120
+ }
121
+ if (typeof mod.onContent === 'function') {
122
+ contentsHandlers.push(mod.onContent(options, moduleOptions));
123
+ }
124
+ if (typeof mod.onNode === 'function') {
125
+ nodeHandlers.push(mod.onNode(options, moduleOptions));
126
+ }
127
+ if (typeof mod.default === 'function') {
128
+ promise = promise.then(async (tree)=>await mod.default(tree, options, moduleOptions));
129
+ }
130
+ }
131
+ if (attrsHandlers.length + contentsHandlers.length + nodeHandlers.length === 0) {
132
+ return promise;
133
+ }
134
+ return promise.then((tree)=>{
135
+ tree.walk((node)=>{
136
+ if (node) {
137
+ if (node.attrs && typeof node.attrs === 'object') {
138
+ // Convert all attrs' key to lower case
139
+ let newAttrsObj = {};
140
+ Object.entries(node.attrs).forEach(([attrName, attrValue])=>{
141
+ newAttrsObj[attrName.toLowerCase()] = attrValue;
142
+ });
143
+ for (const handler of attrsHandlers){
144
+ newAttrsObj = handler(newAttrsObj, node);
145
+ }
146
+ node.attrs = newAttrsObj;
147
+ }
148
+ if (node.content) {
149
+ node.content = typeof node.content === 'string' ? [
150
+ node.content
151
+ ] : node.content;
152
+ if (Array.isArray(node.content) && node.content.length > 0) {
153
+ for (const handler of contentsHandlers){
154
+ var _node_content;
155
+ const result = handler((_node_content = node.content) != null ? _node_content : [], node);
156
+ node.content = Array.isArray(result) ? result : [
157
+ result
158
+ ];
159
+ }
160
+ }
161
+ }
162
+ for (const handler of nodeHandlers){
163
+ if (handler) {
164
+ node = handler(node);
165
+ }
166
+ }
167
+ }
168
+ return node;
169
+ });
170
+ return tree;
171
+ });
172
+ };
173
+ return minifier;
174
+ }
175
+ function getRequiredOptionalDependencies(optionsRun, presetRun) {
176
+ const [options] = loadConfig(optionsRun, presetRun);
177
+ return Array.from(Object.keys(options).reduce((acc, moduleName)=>{
178
+ if (moduleName in optionalDependencies) {
179
+ const dependencies = optionalDependencies[moduleName];
180
+ // eslint-disable-next-line @typescript-eslint/unbound-method -- thisArg provided by forEach
181
+ dependencies.forEach(acc.add, acc);
182
+ }
183
+ return acc;
184
+ }, new Set()));
185
+ }
186
+ function process(html, options, preset, postHtmlOptions) {
187
+ return posthtml([
188
+ htmlnano(options, preset)
189
+ ]).process(html, postHtmlOptions);
190
+ }
191
+ // https://github.com/webpack-contrib/html-minimizer-webpack-plugin/blob/faca00f2219514bc671c5942685721f0b5dbaa70/src/utils.js#L74
192
+ function htmlMinimizerWebpackPluginMinify(input, minimizerOptions) {
193
+ const [[, code]] = Object.entries(input);
194
+ return htmlnano.process(code, minimizerOptions, presets.safe).then((result)=>{
195
+ return {
196
+ code: result.html
197
+ };
198
+ });
199
+ }
200
+ htmlnano.presets = presets;
201
+ htmlnano.getRequiredOptionalDependencies = getRequiredOptionalDependencies;
202
+ htmlnano.process = process;
203
+ htmlnano.htmlMinimizerWebpackPluginMinify = htmlMinimizerWebpackPluginMinify;
204
+ htmlnano.loadConfig = loadConfig;
205
+ if (typeof module !== 'undefined') {
206
+ module.exports = htmlnano;
207
+ }
208
+
209
+ export { htmlnano as default, getRequiredOptionalDependencies, htmlMinimizerWebpackPluginMinify, htmlnano, loadConfig, process };