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.
- package/README.md +54 -12
- package/dist/_modules/collapseAttributeWhitespace.d.mts +57 -0
- package/dist/_modules/collapseAttributeWhitespace.d.ts +57 -0
- package/dist/_modules/collapseAttributeWhitespace.js +296 -0
- package/dist/_modules/collapseAttributeWhitespace.mjs +293 -0
- package/dist/_modules/collapseBooleanAttributes.d.mts +60 -0
- package/dist/_modules/collapseBooleanAttributes.d.ts +60 -0
- package/dist/_modules/collapseBooleanAttributes.js +159 -0
- package/{lib/modules → dist/_modules}/collapseBooleanAttributes.mjs +39 -57
- package/dist/_modules/collapseWhitespace.d.mts +57 -0
- package/dist/_modules/collapseWhitespace.d.ts +57 -0
- package/dist/_modules/collapseWhitespace.js +172 -0
- package/dist/_modules/collapseWhitespace.mjs +170 -0
- package/dist/_modules/custom.d.mts +57 -0
- package/dist/_modules/custom.d.ts +57 -0
- package/dist/_modules/custom.js +22 -0
- package/dist/_modules/custom.mjs +20 -0
- package/dist/_modules/deduplicateAttributeValues.d.mts +56 -0
- package/dist/_modules/deduplicateAttributeValues.d.ts +56 -0
- package/dist/_modules/deduplicateAttributeValues.js +38 -0
- package/dist/_modules/deduplicateAttributeValues.mjs +36 -0
- package/dist/_modules/example.d.mts +59 -0
- package/dist/_modules/example.d.ts +59 -0
- package/dist/_modules/example.js +67 -0
- package/dist/_modules/example.mjs +65 -0
- package/dist/_modules/mergeScripts.d.mts +56 -0
- package/dist/_modules/mergeScripts.d.ts +56 -0
- package/dist/_modules/mergeScripts.js +53 -0
- package/dist/_modules/mergeScripts.mjs +51 -0
- package/dist/_modules/mergeStyles.d.mts +56 -0
- package/dist/_modules/mergeStyles.d.ts +56 -0
- package/dist/_modules/mergeStyles.js +42 -0
- package/dist/_modules/mergeStyles.mjs +40 -0
- package/dist/_modules/minifyConditionalComments.d.mts +56 -0
- package/dist/_modules/minifyConditionalComments.d.ts +56 -0
- package/dist/_modules/minifyConditionalComments.js +54 -0
- package/{lib/modules → dist/_modules}/minifyConditionalComments.mjs +21 -22
- package/dist/_modules/minifyCss.d.mts +56 -0
- package/dist/_modules/minifyCss.d.ts +56 -0
- package/dist/_modules/minifyCss.js +84 -0
- package/dist/_modules/minifyCss.mjs +82 -0
- package/dist/_modules/minifyJs.d.mts +56 -0
- package/dist/_modules/minifyJs.d.ts +56 -0
- package/dist/_modules/minifyJs.js +108 -0
- package/dist/_modules/minifyJs.mjs +106 -0
- package/dist/_modules/minifyJson.d.mts +56 -0
- package/dist/_modules/minifyJson.d.ts +56 -0
- package/dist/_modules/minifyJson.js +35 -0
- package/dist/_modules/minifyJson.mjs +33 -0
- package/dist/_modules/minifySvg.d.mts +56 -0
- package/dist/_modules/minifySvg.d.ts +56 -0
- package/dist/_modules/minifySvg.js +40 -0
- package/dist/_modules/minifySvg.mjs +38 -0
- package/dist/_modules/minifyUrls.d.mts +56 -0
- package/dist/_modules/minifyUrls.d.ts +56 -0
- package/dist/_modules/minifyUrls.js +180 -0
- package/dist/_modules/minifyUrls.mjs +178 -0
- package/dist/_modules/normalizeAttributeValues.d.mts +56 -0
- package/dist/_modules/normalizeAttributeValues.d.ts +56 -0
- package/dist/_modules/normalizeAttributeValues.js +234 -0
- package/dist/_modules/normalizeAttributeValues.mjs +232 -0
- package/dist/_modules/removeAttributeQuotes.d.mts +56 -0
- package/dist/_modules/removeAttributeQuotes.d.ts +56 -0
- package/dist/_modules/removeAttributeQuotes.js +15 -0
- package/dist/_modules/removeAttributeQuotes.mjs +13 -0
- package/dist/_modules/removeComments.d.mts +58 -0
- package/dist/_modules/removeComments.d.ts +58 -0
- package/dist/_modules/removeComments.js +83 -0
- package/{lib/modules → dist/_modules}/removeComments.mjs +24 -35
- package/dist/_modules/removeEmptyAttributes.d.mts +56 -0
- package/dist/_modules/removeEmptyAttributes.d.ts +56 -0
- package/dist/_modules/removeEmptyAttributes.js +197 -0
- package/dist/_modules/removeEmptyAttributes.mjs +195 -0
- package/dist/_modules/removeOptionalTags.d.mts +56 -0
- package/dist/_modules/removeOptionalTags.d.ts +56 -0
- package/dist/_modules/removeOptionalTags.js +190 -0
- package/{lib/modules → dist/_modules}/removeOptionalTags.mjs +54 -91
- package/dist/_modules/removeRedundantAttributes.d.mts +57 -0
- package/dist/_modules/removeRedundantAttributes.d.ts +57 -0
- package/dist/_modules/removeRedundantAttributes.js +128 -0
- package/{lib/modules → dist/_modules}/removeRedundantAttributes.mjs +43 -59
- package/dist/_modules/removeUnusedCss.d.mts +60 -0
- package/dist/_modules/removeUnusedCss.d.ts +60 -0
- package/dist/_modules/removeUnusedCss.js +134 -0
- package/dist/_modules/removeUnusedCss.mjs +132 -0
- package/dist/_modules/sortAttributes.d.mts +57 -0
- package/dist/_modules/sortAttributes.d.ts +57 -0
- package/dist/_modules/sortAttributes.js +102 -0
- package/{lib/modules → dist/_modules}/sortAttributes.mjs +39 -58
- package/dist/_modules/sortAttributesWithLists.d.mts +56 -0
- package/dist/_modules/sortAttributesWithLists.d.ts +56 -0
- package/dist/_modules/sortAttributesWithLists.js +118 -0
- package/{lib/modules → dist/_modules}/sortAttributesWithLists.mjs +41 -59
- package/dist/helpers.d.ts +16 -0
- package/dist/helpers.js +72 -0
- package/dist/helpers.mjs +63 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.js +223 -0
- package/dist/index.mjs +209 -0
- package/dist/presets/ampSafe.d.ts +47 -0
- package/dist/presets/ampSafe.js +19 -0
- package/{lib → dist}/presets/ampSafe.mjs +6 -4
- package/dist/presets/max.d.ts +47 -0
- package/dist/presets/max.js +28 -0
- package/{lib → dist}/presets/max.mjs +6 -4
- package/dist/presets/safe.d.ts +47 -0
- package/dist/presets/safe.js +60 -0
- package/{lib → dist}/presets/safe.mjs +13 -20
- package/package.json +53 -56
- package/.eslintignore +0 -3
- package/CHANGELOG.md +0 -409
- package/docs/README.md +0 -33
- package/docs/babel.config.js +0 -3
- package/docs/docs/010-introduction.md +0 -22
- package/docs/docs/020-usage.md +0 -117
- package/docs/docs/030-config.md +0 -21
- package/docs/docs/040-presets.md +0 -75
- package/docs/docs/050-modules.md +0 -855
- package/docs/docs/060-contribute.md +0 -16
- package/docs/docusaurus.config.js +0 -65
- package/docs/netlify.toml +0 -4
- package/docs/package-lock.json +0 -21630
- package/docs/package.json +0 -40
- package/docs/sidebars.js +0 -26
- package/docs/versioned_docs/version-1.1.1/010-introduction.md +0 -22
- package/docs/versioned_docs/version-1.1.1/020-usage.md +0 -77
- package/docs/versioned_docs/version-1.1.1/030-config.md +0 -21
- package/docs/versioned_docs/version-1.1.1/040-presets.md +0 -75
- package/docs/versioned_docs/version-1.1.1/050-modules.md +0 -785
- package/docs/versioned_docs/version-1.1.1/060-contribute.md +0 -16
- package/docs/versioned_docs/version-2.0.0/010-introduction.md +0 -22
- package/docs/versioned_docs/version-2.0.0/020-usage.md +0 -77
- package/docs/versioned_docs/version-2.0.0/030-config.md +0 -21
- package/docs/versioned_docs/version-2.0.0/040-presets.md +0 -75
- package/docs/versioned_docs/version-2.0.0/050-modules.md +0 -838
- package/docs/versioned_docs/version-2.0.0/060-contribute.md +0 -16
- package/docs/versioned_sidebars/version-1.1.1-sidebars.json +0 -8
- package/docs/versioned_sidebars/version-2.0.0-sidebars.json +0 -8
- package/docs/versions.json +0 -4
- package/index.cjs +0 -11
- package/index.d.cts +0 -3
- package/index.d.mts +0 -3
- package/index.d.ts +0 -94
- package/index.mjs +0 -2
- package/lib/helpers.cjs +0 -79
- package/lib/helpers.mjs +0 -53
- package/lib/htmlnano.cjs +0 -202
- package/lib/htmlnano.mjs +0 -198
- package/lib/modules/collapseAttributeWhitespace.cjs +0 -86
- package/lib/modules/collapseAttributeWhitespace.mjs +0 -104
- package/lib/modules/collapseBooleanAttributes.cjs +0 -62
- package/lib/modules/collapseWhitespace.cjs +0 -100
- package/lib/modules/collapseWhitespace.mjs +0 -132
- package/lib/modules/custom.cjs +0 -19
- package/lib/modules/custom.mjs +0 -16
- package/lib/modules/deduplicateAttributeValues.cjs +0 -38
- package/lib/modules/deduplicateAttributeValues.mjs +0 -40
- package/lib/modules/example.cjs +0 -85
- package/lib/modules/example.mjs +0 -75
- package/lib/modules/mergeScripts.cjs +0 -54
- package/lib/modules/mergeScripts.mjs +0 -56
- package/lib/modules/mergeStyles.cjs +0 -38
- package/lib/modules/mergeStyles.mjs +0 -36
- package/lib/modules/minifyConditionalComments.cjs +0 -47
- package/lib/modules/minifyCss.cjs +0 -73
- package/lib/modules/minifyCss.mjs +0 -88
- package/lib/modules/minifyJs.cjs +0 -103
- package/lib/modules/minifyJs.mjs +0 -121
- package/lib/modules/minifyJson.cjs +0 -24
- package/lib/modules/minifyJson.mjs +0 -21
- package/lib/modules/minifySvg.cjs +0 -37
- package/lib/modules/minifySvg.mjs +0 -30
- package/lib/modules/minifyUrls.cjs +0 -141
- package/lib/modules/minifyUrls.mjs +0 -229
- package/lib/modules/normalizeAttributeValues.cjs +0 -120
- package/lib/modules/normalizeAttributeValues.mjs +0 -140
- package/lib/modules/removeAttributeQuotes.cjs +0 -17
- package/lib/modules/removeAttributeQuotes.mjs +0 -12
- package/lib/modules/removeComments.cjs +0 -86
- package/lib/modules/removeEmptyAttributes.cjs +0 -72
- package/lib/modules/removeEmptyAttributes.mjs +0 -121
- package/lib/modules/removeOptionalTags.cjs +0 -183
- package/lib/modules/removeRedundantAttributes.cjs +0 -112
- package/lib/modules/removeUnusedCss.cjs +0 -113
- package/lib/modules/removeUnusedCss.mjs +0 -122
- package/lib/modules/sortAttributes.cjs +0 -98
- package/lib/modules/sortAttributesWithLists.cjs +0 -114
- package/lib/presets/ampSafe.cjs +0 -18
- package/lib/presets/max.cjs +0 -27
- package/lib/presets/safe.cjs +0 -65
- package/test.js +0 -23
|
@@ -48,7 +48,6 @@ const htmlBooleanAttributes = new Set([
|
|
|
48
48
|
'typemustmatch',
|
|
49
49
|
'visible'
|
|
50
50
|
]);
|
|
51
|
-
|
|
52
51
|
const amphtmlBooleanAttributes = new Set([
|
|
53
52
|
'⚡',
|
|
54
53
|
'amp',
|
|
@@ -56,12 +55,10 @@ const amphtmlBooleanAttributes = new Set([
|
|
|
56
55
|
'amp4ads',
|
|
57
56
|
'⚡4email',
|
|
58
57
|
'amp4email',
|
|
59
|
-
|
|
60
58
|
'amp-custom',
|
|
61
59
|
'amp-boilerplate',
|
|
62
60
|
'amp4ads-boilerplate',
|
|
63
61
|
'amp4email-boilerplate',
|
|
64
|
-
|
|
65
62
|
'allow-blocked-ranges',
|
|
66
63
|
'amp-access-hide',
|
|
67
64
|
'amp-access-template',
|
|
@@ -105,7 +102,6 @@ const amphtmlBooleanAttributes = new Set([
|
|
|
105
102
|
'subscriptions-actions',
|
|
106
103
|
'subscriptions-dialog'
|
|
107
104
|
]);
|
|
108
|
-
|
|
109
105
|
const missingValueDefaultEmptyStringAttributes = {
|
|
110
106
|
// https://html.spec.whatwg.org/#attr-media-preload
|
|
111
107
|
audio: {
|
|
@@ -115,61 +111,47 @@ const missingValueDefaultEmptyStringAttributes = {
|
|
|
115
111
|
preload: 'auto'
|
|
116
112
|
}
|
|
117
113
|
};
|
|
118
|
-
|
|
119
114
|
const tagsHasMissingValueDefaultEmptyStringAttributes = new Set(Object.keys(missingValueDefaultEmptyStringAttributes));
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (
|
|
132
|
-
Object.prototype.hasOwnProperty.call(attrs, attributesCanBeReplacedWithEmptyString)
|
|
133
|
-
&& attrs[attributesCanBeReplacedWithEmptyString] === tagAttributesCanBeReplacedWithEmptyString[attributesCanBeReplacedWithEmptyString]
|
|
134
|
-
) {
|
|
135
|
-
attrs[attributesCanBeReplacedWithEmptyString] = true;
|
|
115
|
+
const mod = {
|
|
116
|
+
onAttrs (options, moduleOptions) {
|
|
117
|
+
return (attrs, node)=>{
|
|
118
|
+
if (!node.tag) return attrs;
|
|
119
|
+
const newAttrs = attrs;
|
|
120
|
+
if (tagsHasMissingValueDefaultEmptyStringAttributes.has(node.tag)) {
|
|
121
|
+
const tagAttributesCanBeReplacedWithEmptyString = missingValueDefaultEmptyStringAttributes[node.tag];
|
|
122
|
+
for (const attributesCanBeReplacedWithEmptyString of Object.keys(tagAttributesCanBeReplacedWithEmptyString)){
|
|
123
|
+
if (attributesCanBeReplacedWithEmptyString in attrs && attributesCanBeReplacedWithEmptyString in tagAttributesCanBeReplacedWithEmptyString && attrs[attributesCanBeReplacedWithEmptyString] === tagAttributesCanBeReplacedWithEmptyString[attributesCanBeReplacedWithEmptyString]) {
|
|
124
|
+
attrs[attributesCanBeReplacedWithEmptyString] = true;
|
|
125
|
+
}
|
|
136
126
|
}
|
|
137
127
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
// collapse crossorigin attributes
|
|
163
|
-
// Specification: https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes
|
|
164
|
-
if (
|
|
165
|
-
attrName.toLowerCase() === 'crossorigin' && (
|
|
166
|
-
attrs[attrName] === 'anonymous'
|
|
167
|
-
)
|
|
168
|
-
) {
|
|
169
|
-
newAttrs[attrName] = true;
|
|
128
|
+
for (const attrName of Object.keys(attrs)){
|
|
129
|
+
if (attrName === 'visible' && node.tag.startsWith('a-')) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (htmlBooleanAttributes.has(attrName)) {
|
|
133
|
+
newAttrs[attrName] = true;
|
|
134
|
+
}
|
|
135
|
+
// Fast path optimization.
|
|
136
|
+
// The rest of tranformations are only for string type attrValue.
|
|
137
|
+
if (typeof newAttrs[attrName] !== 'string') continue;
|
|
138
|
+
if (moduleOptions.amphtml && amphtmlBooleanAttributes.has(attrName) && attrs[attrName] === '') {
|
|
139
|
+
newAttrs[attrName] = true;
|
|
140
|
+
}
|
|
141
|
+
// https://html.spec.whatwg.org/#a-quick-introduction-to-html
|
|
142
|
+
// The value, along with the "=" character, can be omitted altogether if the value is the empty string.
|
|
143
|
+
if (attrs[attrName] === '') {
|
|
144
|
+
newAttrs[attrName] = true;
|
|
145
|
+
}
|
|
146
|
+
// collapse crossorigin attributes
|
|
147
|
+
// Specification: https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes
|
|
148
|
+
if (attrName.toLowerCase() === 'crossorigin' && attrs[attrName] === 'anonymous') {
|
|
149
|
+
newAttrs[attrName] = true;
|
|
150
|
+
}
|
|
170
151
|
}
|
|
171
|
-
|
|
152
|
+
return newAttrs;
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
};
|
|
172
156
|
|
|
173
|
-
|
|
174
|
-
};
|
|
175
|
-
}
|
|
157
|
+
export { mod as default };
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
type CollapseType = 'all' | 'aggressive' | 'conservative';
|
|
55
|
+
declare const mod: HtmlnanoModule<CollapseType>;
|
|
56
|
+
|
|
57
|
+
export { mod as default };
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
type CollapseType = 'all' | 'aggressive' | 'conservative';
|
|
55
|
+
declare const mod: HtmlnanoModule<CollapseType>;
|
|
56
|
+
|
|
57
|
+
export { mod as default };
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
|
|
3
|
+
var helpers_js = require('../helpers.js');
|
|
4
|
+
|
|
5
|
+
const noWhitespaceCollapseElements = new Set([
|
|
6
|
+
'script',
|
|
7
|
+
'style',
|
|
8
|
+
'pre',
|
|
9
|
+
'textarea'
|
|
10
|
+
]);
|
|
11
|
+
const noTrimWhitespacesArroundElements = new Set([
|
|
12
|
+
// non-empty tags that will maintain whitespace around them
|
|
13
|
+
'a',
|
|
14
|
+
'abbr',
|
|
15
|
+
'acronym',
|
|
16
|
+
'b',
|
|
17
|
+
'bdi',
|
|
18
|
+
'bdo',
|
|
19
|
+
'big',
|
|
20
|
+
'button',
|
|
21
|
+
'cite',
|
|
22
|
+
'code',
|
|
23
|
+
'del',
|
|
24
|
+
'dfn',
|
|
25
|
+
'em',
|
|
26
|
+
'font',
|
|
27
|
+
'i',
|
|
28
|
+
'ins',
|
|
29
|
+
'kbd',
|
|
30
|
+
'label',
|
|
31
|
+
'mark',
|
|
32
|
+
'math',
|
|
33
|
+
'nobr',
|
|
34
|
+
'object',
|
|
35
|
+
'q',
|
|
36
|
+
'rp',
|
|
37
|
+
'rt',
|
|
38
|
+
'rtc',
|
|
39
|
+
'ruby',
|
|
40
|
+
's',
|
|
41
|
+
'samp',
|
|
42
|
+
'select',
|
|
43
|
+
'small',
|
|
44
|
+
'span',
|
|
45
|
+
'strike',
|
|
46
|
+
'strong',
|
|
47
|
+
'sub',
|
|
48
|
+
'sup',
|
|
49
|
+
'svg',
|
|
50
|
+
'textarea',
|
|
51
|
+
'time',
|
|
52
|
+
'tt',
|
|
53
|
+
'u',
|
|
54
|
+
'var',
|
|
55
|
+
// self-closing tags that will maintain whitespace around them
|
|
56
|
+
'comment',
|
|
57
|
+
'img',
|
|
58
|
+
'input',
|
|
59
|
+
'wbr'
|
|
60
|
+
]);
|
|
61
|
+
const noTrimWhitespacesInsideElements = new Set([
|
|
62
|
+
// non-empty tags that will maintain whitespace within them
|
|
63
|
+
'a',
|
|
64
|
+
'abbr',
|
|
65
|
+
'acronym',
|
|
66
|
+
'b',
|
|
67
|
+
'big',
|
|
68
|
+
'del',
|
|
69
|
+
'em',
|
|
70
|
+
'font',
|
|
71
|
+
'i',
|
|
72
|
+
'ins',
|
|
73
|
+
'kbd',
|
|
74
|
+
'mark',
|
|
75
|
+
'nobr',
|
|
76
|
+
'rp',
|
|
77
|
+
's',
|
|
78
|
+
'samp',
|
|
79
|
+
'small',
|
|
80
|
+
'span',
|
|
81
|
+
'strike',
|
|
82
|
+
'strong',
|
|
83
|
+
'sub',
|
|
84
|
+
'sup',
|
|
85
|
+
'time',
|
|
86
|
+
'tt',
|
|
87
|
+
'u',
|
|
88
|
+
'var'
|
|
89
|
+
]);
|
|
90
|
+
const startsWithWhitespacePattern = /^\s/;
|
|
91
|
+
const endsWithWhitespacePattern = /\s$/;
|
|
92
|
+
// See https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace and https://infra.spec.whatwg.org/#ascii-whitespace
|
|
93
|
+
const multipleWhitespacePattern = /[\t\n\f\r ]+/g;
|
|
94
|
+
const NONE = '';
|
|
95
|
+
const SINGLE_SPACE = ' ';
|
|
96
|
+
const validOptions = [
|
|
97
|
+
'all',
|
|
98
|
+
'aggressive',
|
|
99
|
+
'conservative'
|
|
100
|
+
];
|
|
101
|
+
function collapseWhitespace(tree, options, collapseType, parent) {
|
|
102
|
+
collapseType = validOptions.includes(collapseType) ? collapseType : 'conservative';
|
|
103
|
+
tree.forEach((node, index)=>{
|
|
104
|
+
const prevNode = tree[index - 1];
|
|
105
|
+
const nextNode = tree[index + 1];
|
|
106
|
+
if (typeof node === 'string') {
|
|
107
|
+
const parentNodeTag = parent == null ? void 0 : parent.node.tag;
|
|
108
|
+
const isTopLevel = parentNodeTag == null || parentNodeTag === 'html' || parentNodeTag === 'head';
|
|
109
|
+
const shouldTrim = isTopLevel || collapseType === 'all' || collapseType === 'aggressive';
|
|
110
|
+
node = collapseRedundantWhitespaces(node, collapseType, shouldTrim, parent, prevNode, nextNode);
|
|
111
|
+
} else if (node.tag) {
|
|
112
|
+
var _node_content;
|
|
113
|
+
const isAllowCollapseWhitespace = !noWhitespaceCollapseElements.has(node.tag);
|
|
114
|
+
if (isAllowCollapseWhitespace && ((_node_content = node.content) == null ? void 0 : _node_content.length)) {
|
|
115
|
+
node.content = collapseWhitespace(node.content, options, collapseType, {
|
|
116
|
+
node,
|
|
117
|
+
prevNode});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
tree[index] = node;
|
|
121
|
+
});
|
|
122
|
+
return tree;
|
|
123
|
+
}
|
|
124
|
+
function collapseRedundantWhitespaces(text, collapseType, shouldTrim = false, parent, prevNode, nextNode) {
|
|
125
|
+
if (!text || text.length === 0) {
|
|
126
|
+
return NONE;
|
|
127
|
+
}
|
|
128
|
+
if (!helpers_js.isComment(text)) {
|
|
129
|
+
text = text.replace(multipleWhitespacePattern, SINGLE_SPACE);
|
|
130
|
+
}
|
|
131
|
+
if (shouldTrim) {
|
|
132
|
+
// either all or top level, trim all
|
|
133
|
+
if (collapseType === 'all' || collapseType === 'conservative') {
|
|
134
|
+
return text.trim();
|
|
135
|
+
}
|
|
136
|
+
if (typeof parent !== 'object' || !(parent == null ? void 0 : parent.node.tag) || !noTrimWhitespacesInsideElements.has(parent.node.tag)) {
|
|
137
|
+
if (// It is the first child node of the parent
|
|
138
|
+
!prevNode || typeof prevNode === 'object' && prevNode.tag && !noTrimWhitespacesArroundElements.has(prevNode.tag)) {
|
|
139
|
+
text = text.trimStart();
|
|
140
|
+
} else {
|
|
141
|
+
// previous node is a "no trim whitespaces arround element"
|
|
142
|
+
if (// but previous node ends with a whitespace
|
|
143
|
+
typeof prevNode === 'object' && prevNode.content) {
|
|
144
|
+
const prevNodeLastContent = prevNode.content[prevNode.content.length - 1];
|
|
145
|
+
if (typeof prevNodeLastContent === 'string' && endsWithWhitespacePattern.test(prevNodeLastContent) && (!nextNode // either the current node is the last child of the parent
|
|
146
|
+
|| // or the next node starts with a white space
|
|
147
|
+
typeof nextNode === 'object' && nextNode.content && typeof nextNode.content[0] === 'string' && !startsWithWhitespacePattern.test(nextNode.content[0]))) {
|
|
148
|
+
text = text.trimStart();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (!nextNode || typeof nextNode === 'object' && nextNode.tag && !noTrimWhitespacesArroundElements.has(nextNode.tag)) {
|
|
153
|
+
text = text.trimEnd();
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
// now it is a textNode inside a "no trim whitespaces inside elements" node
|
|
157
|
+
if (!prevNode // it the textnode is the first child of the node
|
|
158
|
+
&& startsWithWhitespacePattern.test(text[0]) // it starts with white space
|
|
159
|
+
&& typeof (parent == null ? void 0 : parent.prevNode) === 'string' // the prev of the node is a textNode as well
|
|
160
|
+
&& endsWithWhitespacePattern.test(parent.prevNode[parent.prevNode.length - 1]) // that prev is ends with a white
|
|
161
|
+
) {
|
|
162
|
+
text = text.trimStart();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return text;
|
|
167
|
+
}
|
|
168
|
+
const mod = {
|
|
169
|
+
default: collapseWhitespace
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
exports.default = mod;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { isComment } from '../helpers.mjs';
|
|
2
|
+
|
|
3
|
+
const noWhitespaceCollapseElements = new Set([
|
|
4
|
+
'script',
|
|
5
|
+
'style',
|
|
6
|
+
'pre',
|
|
7
|
+
'textarea'
|
|
8
|
+
]);
|
|
9
|
+
const noTrimWhitespacesArroundElements = new Set([
|
|
10
|
+
// non-empty tags that will maintain whitespace around them
|
|
11
|
+
'a',
|
|
12
|
+
'abbr',
|
|
13
|
+
'acronym',
|
|
14
|
+
'b',
|
|
15
|
+
'bdi',
|
|
16
|
+
'bdo',
|
|
17
|
+
'big',
|
|
18
|
+
'button',
|
|
19
|
+
'cite',
|
|
20
|
+
'code',
|
|
21
|
+
'del',
|
|
22
|
+
'dfn',
|
|
23
|
+
'em',
|
|
24
|
+
'font',
|
|
25
|
+
'i',
|
|
26
|
+
'ins',
|
|
27
|
+
'kbd',
|
|
28
|
+
'label',
|
|
29
|
+
'mark',
|
|
30
|
+
'math',
|
|
31
|
+
'nobr',
|
|
32
|
+
'object',
|
|
33
|
+
'q',
|
|
34
|
+
'rp',
|
|
35
|
+
'rt',
|
|
36
|
+
'rtc',
|
|
37
|
+
'ruby',
|
|
38
|
+
's',
|
|
39
|
+
'samp',
|
|
40
|
+
'select',
|
|
41
|
+
'small',
|
|
42
|
+
'span',
|
|
43
|
+
'strike',
|
|
44
|
+
'strong',
|
|
45
|
+
'sub',
|
|
46
|
+
'sup',
|
|
47
|
+
'svg',
|
|
48
|
+
'textarea',
|
|
49
|
+
'time',
|
|
50
|
+
'tt',
|
|
51
|
+
'u',
|
|
52
|
+
'var',
|
|
53
|
+
// self-closing tags that will maintain whitespace around them
|
|
54
|
+
'comment',
|
|
55
|
+
'img',
|
|
56
|
+
'input',
|
|
57
|
+
'wbr'
|
|
58
|
+
]);
|
|
59
|
+
const noTrimWhitespacesInsideElements = new Set([
|
|
60
|
+
// non-empty tags that will maintain whitespace within them
|
|
61
|
+
'a',
|
|
62
|
+
'abbr',
|
|
63
|
+
'acronym',
|
|
64
|
+
'b',
|
|
65
|
+
'big',
|
|
66
|
+
'del',
|
|
67
|
+
'em',
|
|
68
|
+
'font',
|
|
69
|
+
'i',
|
|
70
|
+
'ins',
|
|
71
|
+
'kbd',
|
|
72
|
+
'mark',
|
|
73
|
+
'nobr',
|
|
74
|
+
'rp',
|
|
75
|
+
's',
|
|
76
|
+
'samp',
|
|
77
|
+
'small',
|
|
78
|
+
'span',
|
|
79
|
+
'strike',
|
|
80
|
+
'strong',
|
|
81
|
+
'sub',
|
|
82
|
+
'sup',
|
|
83
|
+
'time',
|
|
84
|
+
'tt',
|
|
85
|
+
'u',
|
|
86
|
+
'var'
|
|
87
|
+
]);
|
|
88
|
+
const startsWithWhitespacePattern = /^\s/;
|
|
89
|
+
const endsWithWhitespacePattern = /\s$/;
|
|
90
|
+
// See https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace and https://infra.spec.whatwg.org/#ascii-whitespace
|
|
91
|
+
const multipleWhitespacePattern = /[\t\n\f\r ]+/g;
|
|
92
|
+
const NONE = '';
|
|
93
|
+
const SINGLE_SPACE = ' ';
|
|
94
|
+
const validOptions = [
|
|
95
|
+
'all',
|
|
96
|
+
'aggressive',
|
|
97
|
+
'conservative'
|
|
98
|
+
];
|
|
99
|
+
function collapseWhitespace(tree, options, collapseType, parent) {
|
|
100
|
+
collapseType = validOptions.includes(collapseType) ? collapseType : 'conservative';
|
|
101
|
+
tree.forEach((node, index)=>{
|
|
102
|
+
const prevNode = tree[index - 1];
|
|
103
|
+
const nextNode = tree[index + 1];
|
|
104
|
+
if (typeof node === 'string') {
|
|
105
|
+
const parentNodeTag = parent == null ? void 0 : parent.node.tag;
|
|
106
|
+
const isTopLevel = parentNodeTag == null || parentNodeTag === 'html' || parentNodeTag === 'head';
|
|
107
|
+
const shouldTrim = isTopLevel || collapseType === 'all' || collapseType === 'aggressive';
|
|
108
|
+
node = collapseRedundantWhitespaces(node, collapseType, shouldTrim, parent, prevNode, nextNode);
|
|
109
|
+
} else if (node.tag) {
|
|
110
|
+
var _node_content;
|
|
111
|
+
const isAllowCollapseWhitespace = !noWhitespaceCollapseElements.has(node.tag);
|
|
112
|
+
if (isAllowCollapseWhitespace && ((_node_content = node.content) == null ? void 0 : _node_content.length)) {
|
|
113
|
+
node.content = collapseWhitespace(node.content, options, collapseType, {
|
|
114
|
+
node,
|
|
115
|
+
prevNode});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
tree[index] = node;
|
|
119
|
+
});
|
|
120
|
+
return tree;
|
|
121
|
+
}
|
|
122
|
+
function collapseRedundantWhitespaces(text, collapseType, shouldTrim = false, parent, prevNode, nextNode) {
|
|
123
|
+
if (!text || text.length === 0) {
|
|
124
|
+
return NONE;
|
|
125
|
+
}
|
|
126
|
+
if (!isComment(text)) {
|
|
127
|
+
text = text.replace(multipleWhitespacePattern, SINGLE_SPACE);
|
|
128
|
+
}
|
|
129
|
+
if (shouldTrim) {
|
|
130
|
+
// either all or top level, trim all
|
|
131
|
+
if (collapseType === 'all' || collapseType === 'conservative') {
|
|
132
|
+
return text.trim();
|
|
133
|
+
}
|
|
134
|
+
if (typeof parent !== 'object' || !(parent == null ? void 0 : parent.node.tag) || !noTrimWhitespacesInsideElements.has(parent.node.tag)) {
|
|
135
|
+
if (// It is the first child node of the parent
|
|
136
|
+
!prevNode || typeof prevNode === 'object' && prevNode.tag && !noTrimWhitespacesArroundElements.has(prevNode.tag)) {
|
|
137
|
+
text = text.trimStart();
|
|
138
|
+
} else {
|
|
139
|
+
// previous node is a "no trim whitespaces arround element"
|
|
140
|
+
if (// but previous node ends with a whitespace
|
|
141
|
+
typeof prevNode === 'object' && prevNode.content) {
|
|
142
|
+
const prevNodeLastContent = prevNode.content[prevNode.content.length - 1];
|
|
143
|
+
if (typeof prevNodeLastContent === 'string' && endsWithWhitespacePattern.test(prevNodeLastContent) && (!nextNode // either the current node is the last child of the parent
|
|
144
|
+
|| // or the next node starts with a white space
|
|
145
|
+
typeof nextNode === 'object' && nextNode.content && typeof nextNode.content[0] === 'string' && !startsWithWhitespacePattern.test(nextNode.content[0]))) {
|
|
146
|
+
text = text.trimStart();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (!nextNode || typeof nextNode === 'object' && nextNode.tag && !noTrimWhitespacesArroundElements.has(nextNode.tag)) {
|
|
151
|
+
text = text.trimEnd();
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
// now it is a textNode inside a "no trim whitespaces inside elements" node
|
|
155
|
+
if (!prevNode // it the textnode is the first child of the node
|
|
156
|
+
&& startsWithWhitespacePattern.test(text[0]) // it starts with white space
|
|
157
|
+
&& typeof (parent == null ? void 0 : parent.prevNode) === 'string' // the prev of the node is a textNode as well
|
|
158
|
+
&& endsWithWhitespacePattern.test(parent.prevNode[parent.prevNode.length - 1]) // that prev is ends with a white
|
|
159
|
+
) {
|
|
160
|
+
text = text.trimStart();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return text;
|
|
165
|
+
}
|
|
166
|
+
const mod = {
|
|
167
|
+
default: collapseWhitespace
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export { mod as default };
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
type CustomModule = (tree: PostHTMLTreeLike, options: Partial<HtmlnanoOptions>) => PostHTMLTreeLike;
|
|
55
|
+
declare const mod: HtmlnanoModule<CustomModule[]>;
|
|
56
|
+
|
|
57
|
+
export { mod as default };
|