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,293 @@
1
+ import { isEventHandler } from '../helpers.mjs';
2
+
3
+ const attributesWithLists = new Set([
4
+ 'class',
5
+ 'dropzone',
6
+ 'rel',
7
+ 'ping',
8
+ 'sandbox',
9
+ /**
10
+ * https://github.com/posthtml/htmlnano/issues/180
11
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-sizes
12
+ *
13
+ * "sizes" of <img> should not be modified, while "sizes" of <link> will only have one entry in most cases.
14
+ */ // 'sizes', // link
15
+ 'headers' // td, th
16
+ ]);
17
+ /** empty set means the attribute is alwasy trimmable */ const attributesWithSingleValue = new Map([
18
+ [
19
+ 'accept',
20
+ new Set([
21
+ 'input'
22
+ ])
23
+ ],
24
+ [
25
+ 'action',
26
+ new Set([
27
+ 'form'
28
+ ])
29
+ ],
30
+ [
31
+ 'accesskey',
32
+ new Set()
33
+ ],
34
+ [
35
+ 'accept-charset',
36
+ new Set([
37
+ 'form'
38
+ ])
39
+ ],
40
+ [
41
+ 'cite',
42
+ new Set([
43
+ 'blockquote',
44
+ 'del',
45
+ 'ins',
46
+ 'q'
47
+ ])
48
+ ],
49
+ [
50
+ 'cols',
51
+ new Set([
52
+ 'textarea'
53
+ ])
54
+ ],
55
+ [
56
+ 'colspan',
57
+ new Set([
58
+ 'td',
59
+ 'th'
60
+ ])
61
+ ],
62
+ [
63
+ 'data',
64
+ new Set([
65
+ 'object'
66
+ ])
67
+ ],
68
+ [
69
+ 'dropzone',
70
+ new Set()
71
+ ],
72
+ [
73
+ 'formaction',
74
+ new Set([
75
+ 'button',
76
+ 'input'
77
+ ])
78
+ ],
79
+ [
80
+ 'height',
81
+ new Set([
82
+ 'canvas',
83
+ 'embed',
84
+ 'iframe',
85
+ 'img',
86
+ 'input',
87
+ 'object',
88
+ 'video'
89
+ ])
90
+ ],
91
+ [
92
+ 'high',
93
+ new Set([
94
+ 'meter'
95
+ ])
96
+ ],
97
+ [
98
+ 'href',
99
+ new Set([
100
+ 'a',
101
+ 'area',
102
+ 'base',
103
+ 'link'
104
+ ])
105
+ ],
106
+ [
107
+ 'itemid',
108
+ new Set()
109
+ ],
110
+ [
111
+ 'low',
112
+ new Set([
113
+ 'meter'
114
+ ])
115
+ ],
116
+ [
117
+ 'manifest',
118
+ new Set([
119
+ 'html'
120
+ ])
121
+ ],
122
+ [
123
+ 'max',
124
+ new Set([
125
+ 'meter',
126
+ 'progress'
127
+ ])
128
+ ],
129
+ [
130
+ 'maxlength',
131
+ new Set([
132
+ 'input',
133
+ 'textarea'
134
+ ])
135
+ ],
136
+ [
137
+ 'media',
138
+ new Set([
139
+ 'source'
140
+ ])
141
+ ],
142
+ [
143
+ 'min',
144
+ new Set([
145
+ 'meter'
146
+ ])
147
+ ],
148
+ [
149
+ 'minlength',
150
+ new Set([
151
+ 'input',
152
+ 'textarea'
153
+ ])
154
+ ],
155
+ [
156
+ 'optimum',
157
+ new Set([
158
+ 'meter'
159
+ ])
160
+ ],
161
+ [
162
+ 'ping',
163
+ new Set([
164
+ 'a',
165
+ 'area'
166
+ ])
167
+ ],
168
+ [
169
+ 'poster',
170
+ new Set([
171
+ 'video'
172
+ ])
173
+ ],
174
+ [
175
+ 'profile',
176
+ new Set([
177
+ 'head'
178
+ ])
179
+ ],
180
+ [
181
+ 'rows',
182
+ new Set([
183
+ 'textarea'
184
+ ])
185
+ ],
186
+ [
187
+ 'rowspan',
188
+ new Set([
189
+ 'td',
190
+ 'th'
191
+ ])
192
+ ],
193
+ [
194
+ 'size',
195
+ new Set([
196
+ 'input',
197
+ 'select'
198
+ ])
199
+ ],
200
+ [
201
+ 'span',
202
+ new Set([
203
+ 'col',
204
+ 'colgroup'
205
+ ])
206
+ ],
207
+ [
208
+ 'src',
209
+ new Set([
210
+ 'audio',
211
+ 'embed',
212
+ 'iframe',
213
+ 'img',
214
+ 'input',
215
+ 'script',
216
+ 'source',
217
+ 'track',
218
+ 'video'
219
+ ])
220
+ ],
221
+ [
222
+ 'start',
223
+ new Set([
224
+ 'ol'
225
+ ])
226
+ ],
227
+ [
228
+ 'step',
229
+ new Set([
230
+ 'input'
231
+ ])
232
+ ],
233
+ [
234
+ 'style',
235
+ new Set()
236
+ ],
237
+ [
238
+ 'tabindex',
239
+ new Set()
240
+ ],
241
+ [
242
+ 'usemap',
243
+ new Set([
244
+ 'img',
245
+ 'object'
246
+ ])
247
+ ],
248
+ [
249
+ 'value',
250
+ new Set([
251
+ 'li',
252
+ 'meter',
253
+ 'progress'
254
+ ])
255
+ ],
256
+ [
257
+ 'width',
258
+ new Set([
259
+ 'canvas',
260
+ 'embed',
261
+ 'iframe',
262
+ 'img',
263
+ 'input',
264
+ 'object',
265
+ 'video'
266
+ ])
267
+ ]
268
+ ]);
269
+ /** Collapse whitespaces inside list-like attributes (e.g. class, rel) */ const mod = {
270
+ onAttrs () {
271
+ return (attrs, node)=>{
272
+ const newAttrs = attrs;
273
+ Object.entries(attrs).forEach(([attrName, attrValue])=>{
274
+ if (typeof attrValue !== 'string') return;
275
+ if (attributesWithLists.has(attrName)) {
276
+ newAttrs[attrName] = attrValue.replace(/\s+/g, ' ').trim();
277
+ return;
278
+ }
279
+ if (isEventHandler(attrName)) {
280
+ newAttrs[attrName] = attrValue.trim();
281
+ } else if (node.tag && attributesWithSingleValue.has(attrName)) {
282
+ const tagSet = attributesWithSingleValue.get(attrName);
283
+ if (tagSet.size === 0 || tagSet.has(node.tag)) {
284
+ newAttrs[attrName] = attrValue.trim();
285
+ }
286
+ }
287
+ });
288
+ return newAttrs;
289
+ };
290
+ }
291
+ };
292
+
293
+ export { attributesWithLists, mod as default };
@@ -0,0 +1,60 @@
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
+ type HtmlnanoModuleAttrsHandler = (attrs: Record<string, string | boolean | void>, node: PostHTML.Node) => Record<string, string | boolean | void>;
44
+ type HtmlnanoModuleContentHandler = (content: Array<PostHTMLNodeLike>, node: PostHTML.Node) => MaybeArray<PostHTMLNodeLike>;
45
+ type HtmlnanoModuleNodeHandler = (node: PostHTMLNodeLike) => PostHTML.Node | string;
46
+ type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends object ? Partial<T> : T;
47
+ type HtmlnanoModule<Options = any> = {
48
+ onAttrs?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleAttrsHandler;
49
+ onContent?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleContentHandler;
50
+ onNode?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleNodeHandler;
51
+ default?: (tree: PostHTMLTreeLike, options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => PostHTMLTreeLike | Promise<PostHTMLTreeLike>;
52
+ };
53
+
54
+ interface CollapseBooleanAttributesOptions {
55
+ amphtml: boolean;
56
+ }
57
+ declare const mod: HtmlnanoModule<CollapseBooleanAttributesOptions>;
58
+
59
+ export { mod as default };
60
+ export type { CollapseBooleanAttributesOptions };
@@ -0,0 +1,60 @@
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
+ type HtmlnanoModuleAttrsHandler = (attrs: Record<string, string | boolean | void>, node: PostHTML.Node) => Record<string, string | boolean | void>;
44
+ type HtmlnanoModuleContentHandler = (content: Array<PostHTMLNodeLike>, node: PostHTML.Node) => MaybeArray<PostHTMLNodeLike>;
45
+ type HtmlnanoModuleNodeHandler = (node: PostHTMLNodeLike) => PostHTML.Node | string;
46
+ type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends object ? Partial<T> : T;
47
+ type HtmlnanoModule<Options = any> = {
48
+ onAttrs?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleAttrsHandler;
49
+ onContent?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleContentHandler;
50
+ onNode?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleNodeHandler;
51
+ default?: (tree: PostHTMLTreeLike, options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => PostHTMLTreeLike | Promise<PostHTMLTreeLike>;
52
+ };
53
+
54
+ interface CollapseBooleanAttributesOptions {
55
+ amphtml: boolean;
56
+ }
57
+ declare const mod: HtmlnanoModule<CollapseBooleanAttributesOptions>;
58
+
59
+ export { mod as default };
60
+ export type { CollapseBooleanAttributesOptions };
@@ -0,0 +1,159 @@
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+
3
+ // Source: https://github.com/kangax/html-minifier/issues/63
4
+ // https://html.spec.whatwg.org/#boolean-attribute
5
+ // https://html.spec.whatwg.org/#attributes-1
6
+ const htmlBooleanAttributes = new Set([
7
+ 'allowfullscreen',
8
+ 'allowpaymentrequest',
9
+ 'allowtransparency',
10
+ 'async',
11
+ 'autofocus',
12
+ 'autoplay',
13
+ 'checked',
14
+ 'compact',
15
+ 'controls',
16
+ 'declare',
17
+ 'default',
18
+ 'defaultchecked',
19
+ 'defaultmuted',
20
+ 'defaultselected',
21
+ 'defer',
22
+ 'disabled',
23
+ 'enabled',
24
+ 'formnovalidate',
25
+ 'hidden',
26
+ 'indeterminate',
27
+ 'inert',
28
+ 'ismap',
29
+ 'itemscope',
30
+ 'loop',
31
+ 'multiple',
32
+ 'muted',
33
+ 'nohref',
34
+ 'nomodule',
35
+ 'noresize',
36
+ 'noshade',
37
+ 'novalidate',
38
+ 'nowrap',
39
+ 'open',
40
+ 'pauseonexit',
41
+ 'playsinline',
42
+ 'readonly',
43
+ 'required',
44
+ 'reversed',
45
+ 'scoped',
46
+ 'seamless',
47
+ 'selected',
48
+ 'sortable',
49
+ 'truespeed',
50
+ 'typemustmatch',
51
+ 'visible'
52
+ ]);
53
+ const amphtmlBooleanAttributes = new Set([
54
+ '⚡',
55
+ 'amp',
56
+ '⚡4ads',
57
+ 'amp4ads',
58
+ '⚡4email',
59
+ 'amp4email',
60
+ 'amp-custom',
61
+ 'amp-boilerplate',
62
+ 'amp4ads-boilerplate',
63
+ 'amp4email-boilerplate',
64
+ 'allow-blocked-ranges',
65
+ 'amp-access-hide',
66
+ 'amp-access-template',
67
+ 'amp-keyframes',
68
+ 'animate',
69
+ 'arrows',
70
+ 'data-block-on-consent',
71
+ 'data-enable-refresh',
72
+ 'data-multi-size',
73
+ 'date-template',
74
+ 'disable-double-tap',
75
+ 'disable-session-states',
76
+ 'disableremoteplayback',
77
+ 'dots',
78
+ 'expand-single-section',
79
+ 'expanded',
80
+ 'fallback',
81
+ 'first',
82
+ 'fullscreen',
83
+ 'inline',
84
+ 'lightbox',
85
+ 'noaudio',
86
+ 'noautoplay',
87
+ 'noloading',
88
+ 'once',
89
+ 'open-after-clear',
90
+ 'open-after-select',
91
+ 'open-button',
92
+ 'placeholder',
93
+ 'preload',
94
+ 'reset-on-refresh',
95
+ 'reset-on-resize',
96
+ 'resizable',
97
+ 'rotate-to-fullscreen',
98
+ 'second',
99
+ 'standalone',
100
+ 'stereo',
101
+ 'submit-error',
102
+ 'submit-success',
103
+ 'submitting',
104
+ 'subscriptions-actions',
105
+ 'subscriptions-dialog'
106
+ ]);
107
+ const missingValueDefaultEmptyStringAttributes = {
108
+ // https://html.spec.whatwg.org/#attr-media-preload
109
+ audio: {
110
+ preload: 'auto'
111
+ },
112
+ video: {
113
+ preload: 'auto'
114
+ }
115
+ };
116
+ const tagsHasMissingValueDefaultEmptyStringAttributes = new Set(Object.keys(missingValueDefaultEmptyStringAttributes));
117
+ const mod = {
118
+ onAttrs (options, moduleOptions) {
119
+ return (attrs, node)=>{
120
+ if (!node.tag) return attrs;
121
+ const newAttrs = attrs;
122
+ if (tagsHasMissingValueDefaultEmptyStringAttributes.has(node.tag)) {
123
+ const tagAttributesCanBeReplacedWithEmptyString = missingValueDefaultEmptyStringAttributes[node.tag];
124
+ for (const attributesCanBeReplacedWithEmptyString of Object.keys(tagAttributesCanBeReplacedWithEmptyString)){
125
+ if (attributesCanBeReplacedWithEmptyString in attrs && attributesCanBeReplacedWithEmptyString in tagAttributesCanBeReplacedWithEmptyString && attrs[attributesCanBeReplacedWithEmptyString] === tagAttributesCanBeReplacedWithEmptyString[attributesCanBeReplacedWithEmptyString]) {
126
+ attrs[attributesCanBeReplacedWithEmptyString] = true;
127
+ }
128
+ }
129
+ }
130
+ for (const attrName of Object.keys(attrs)){
131
+ if (attrName === 'visible' && node.tag.startsWith('a-')) {
132
+ continue;
133
+ }
134
+ if (htmlBooleanAttributes.has(attrName)) {
135
+ newAttrs[attrName] = true;
136
+ }
137
+ // Fast path optimization.
138
+ // The rest of tranformations are only for string type attrValue.
139
+ if (typeof newAttrs[attrName] !== 'string') continue;
140
+ if (moduleOptions.amphtml && amphtmlBooleanAttributes.has(attrName) && attrs[attrName] === '') {
141
+ newAttrs[attrName] = true;
142
+ }
143
+ // https://html.spec.whatwg.org/#a-quick-introduction-to-html
144
+ // The value, along with the "=" character, can be omitted altogether if the value is the empty string.
145
+ if (attrs[attrName] === '') {
146
+ newAttrs[attrName] = true;
147
+ }
148
+ // collapse crossorigin attributes
149
+ // Specification: https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes
150
+ if (attrName.toLowerCase() === 'crossorigin' && attrs[attrName] === 'anonymous') {
151
+ newAttrs[attrName] = true;
152
+ }
153
+ }
154
+ return newAttrs;
155
+ };
156
+ }
157
+ };
158
+
159
+ exports.default = mod;