htmlnano 3.1.0 → 3.2.1
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 +37 -23
- package/dist/_modules/collapseAttributeWhitespace.d.mts +58 -14
- package/dist/_modules/collapseAttributeWhitespace.d.ts +58 -14
- package/dist/_modules/collapseBooleanAttributes.d.mts +58 -14
- package/dist/_modules/collapseBooleanAttributes.d.ts +58 -14
- package/dist/_modules/collapseWhitespace.d.mts +58 -14
- package/dist/_modules/collapseWhitespace.d.ts +58 -14
- package/dist/_modules/custom.d.mts +58 -14
- package/dist/_modules/custom.d.ts +58 -14
- package/dist/_modules/deduplicateAttributeValues.d.mts +58 -14
- package/dist/_modules/deduplicateAttributeValues.d.ts +58 -14
- package/dist/_modules/example.d.mts +58 -14
- package/dist/_modules/example.d.ts +58 -14
- package/dist/_modules/mergeScripts.d.mts +58 -14
- package/dist/_modules/mergeScripts.d.ts +58 -14
- package/dist/_modules/mergeScripts.js +30 -23
- package/dist/_modules/mergeScripts.mjs +30 -23
- package/dist/_modules/mergeStyles.d.mts +58 -14
- package/dist/_modules/mergeStyles.d.ts +58 -14
- package/dist/_modules/mergeStyles.js +26 -21
- package/dist/_modules/mergeStyles.mjs +26 -21
- package/dist/_modules/minifyAttributes.d.mts +58 -14
- package/dist/_modules/minifyAttributes.d.ts +58 -14
- package/dist/_modules/minifyAttributes.js +2 -2
- package/dist/_modules/minifyAttributes.mjs +2 -2
- package/dist/_modules/minifyConditionalComments.d.mts +58 -14
- package/dist/_modules/minifyConditionalComments.d.ts +58 -14
- package/dist/_modules/minifyCss.d.mts +61 -14
- package/dist/_modules/minifyCss.d.ts +61 -14
- package/dist/_modules/minifyCss.js +79 -12
- package/dist/_modules/minifyCss.mjs +79 -13
- package/dist/_modules/minifyHtmlTemplate.d.mts +58 -14
- package/dist/_modules/minifyHtmlTemplate.d.ts +58 -14
- package/dist/_modules/minifyJs.d.mts +58 -13
- package/dist/_modules/minifyJs.d.ts +58 -13
- package/dist/_modules/minifyJs.js +12 -0
- package/dist/_modules/minifyJs.mjs +12 -0
- package/dist/_modules/minifyJson.d.mts +58 -14
- package/dist/_modules/minifyJson.d.ts +58 -14
- package/dist/_modules/minifyJson.js +1 -1
- package/dist/_modules/minifyJson.mjs +1 -1
- package/dist/_modules/minifySvg.d.mts +58 -13
- package/dist/_modules/minifySvg.d.ts +58 -13
- package/dist/_modules/minifySvg.js +2 -2
- package/dist/_modules/minifySvg.mjs +2 -2
- package/dist/_modules/minifyUrls.d.mts +58 -14
- package/dist/_modules/minifyUrls.d.ts +58 -14
- package/dist/_modules/minifyUrls.js +2 -2
- package/dist/_modules/minifyUrls.mjs +2 -2
- package/dist/_modules/normalizeAttributeValues.d.mts +58 -14
- package/dist/_modules/normalizeAttributeValues.d.ts +58 -14
- package/dist/_modules/removeAttributeQuotes.d.mts +58 -14
- package/dist/_modules/removeAttributeQuotes.d.ts +58 -14
- package/dist/_modules/removeComments.d.mts +58 -14
- package/dist/_modules/removeComments.d.ts +58 -14
- package/dist/_modules/removeComments.js +1 -1
- package/dist/_modules/removeComments.mjs +1 -1
- package/dist/_modules/removeEmptyAttributes.d.mts +58 -14
- package/dist/_modules/removeEmptyAttributes.d.ts +58 -14
- package/dist/_modules/removeEmptyElements.d.mts +58 -14
- package/dist/_modules/removeEmptyElements.d.ts +58 -14
- package/dist/_modules/removeOptionalTags.d.mts +58 -14
- package/dist/_modules/removeOptionalTags.d.ts +58 -14
- package/dist/_modules/removeRedundantAttributes.d.mts +58 -14
- package/dist/_modules/removeRedundantAttributes.d.ts +58 -14
- package/dist/_modules/removeUnusedCss.d.mts +58 -14
- package/dist/_modules/removeUnusedCss.d.ts +58 -14
- package/dist/_modules/removeUnusedCss.js +3 -2
- package/dist/_modules/removeUnusedCss.mjs +3 -2
- package/dist/_modules/sortAttributes.d.mts +61 -16
- package/dist/_modules/sortAttributes.d.ts +61 -16
- package/dist/_modules/sortAttributes.js +5 -9
- package/dist/_modules/sortAttributes.mjs +5 -9
- package/dist/_modules/sortAttributesWithLists.d.mts +61 -15
- package/dist/_modules/sortAttributesWithLists.d.ts +61 -15
- package/dist/_modules/sortAttributesWithLists.js +43 -56
- package/dist/_modules/sortAttributesWithLists.mjs +43 -56
- package/dist/index.d.ts +59 -15
- package/dist/index.js +7 -6
- package/dist/index.mjs +7 -6
- package/dist/presets/ampSafe.d.ts +57 -12
- package/dist/presets/max.d.ts +57 -12
- package/dist/presets/max.js +9 -5
- package/dist/presets/max.mjs +9 -5
- package/dist/presets/safe.d.ts +57 -12
- package/dist/presets/safe.js +1 -1
- package/dist/presets/safe.mjs +1 -1
- package/package.json +20 -14
|
@@ -1,25 +1,70 @@
|
|
|
1
1
|
import PostHTML from 'posthtml';
|
|
2
|
-
import { MinifyOptions } from 'terser';
|
|
3
|
-
import { Options } from 'cssnano';
|
|
4
|
-
import { Config } from 'svgo';
|
|
5
|
-
import { UserDefinedOptions } from 'purgecss';
|
|
6
2
|
|
|
7
|
-
type
|
|
3
|
+
type PostHTMLNodeLike = PostHTML.Node | string;
|
|
4
|
+
type PostHTMLTreeLike = [PostHTMLNodeLike] & PostHTML.NodeAPI & {
|
|
8
5
|
options?: {
|
|
9
6
|
quoteAllAttributes?: boolean | undefined;
|
|
10
7
|
quoteStyle?: 0 | 1 | 2 | undefined;
|
|
11
8
|
replaceQuote?: boolean | undefined;
|
|
12
9
|
} | undefined;
|
|
13
10
|
render(): string;
|
|
14
|
-
render(node:
|
|
11
|
+
render(node: PostHTMLNodeLike | PostHTMLTreeLike, renderOptions?: any): string;
|
|
15
12
|
};
|
|
16
13
|
type MaybeArray<T> = T | Array<T>;
|
|
17
|
-
type PostHTMLNodeLike = PostHTML.Node | string;
|
|
18
14
|
type HtmlnanoTemplateRule = {
|
|
19
15
|
tag: string;
|
|
20
16
|
attrs?: Record<string, string | boolean | void>;
|
|
21
17
|
};
|
|
22
18
|
type MinifyHtmlTemplateOptions = boolean | HtmlnanoTemplateRule[];
|
|
19
|
+
type HtmlnanoMinifyCssOptions = object;
|
|
20
|
+
type HtmlnanoMinifyJsOptions = object;
|
|
21
|
+
type HtmlnanoMinifySvgOptions = object;
|
|
22
|
+
type HtmlnanoPurgeCssPattern = string | RegExp;
|
|
23
|
+
type HtmlnanoPurgeCssExtractorResultDetailed = {
|
|
24
|
+
attributes: {
|
|
25
|
+
names: string[];
|
|
26
|
+
values: string[];
|
|
27
|
+
};
|
|
28
|
+
classes: string[];
|
|
29
|
+
ids: string[];
|
|
30
|
+
tags: string[];
|
|
31
|
+
undetermined: string[];
|
|
32
|
+
};
|
|
33
|
+
type HtmlnanoPurgeCssExtractorResult = HtmlnanoPurgeCssExtractorResultDetailed | string[];
|
|
34
|
+
type HtmlnanoPurgeCssDefaultExtractor = (content: string) => HtmlnanoPurgeCssExtractorResult;
|
|
35
|
+
type HtmlnanoPurgeCssSourceMapOptions = {
|
|
36
|
+
absolute?: boolean;
|
|
37
|
+
annotation?: boolean | string;
|
|
38
|
+
from?: string;
|
|
39
|
+
inline?: boolean;
|
|
40
|
+
prev?: boolean | object | string;
|
|
41
|
+
sourcesContent?: boolean;
|
|
42
|
+
to?: string;
|
|
43
|
+
};
|
|
44
|
+
type HtmlnanoPurgeCssSafelist = HtmlnanoPurgeCssPattern[] | {
|
|
45
|
+
standard?: HtmlnanoPurgeCssPattern[];
|
|
46
|
+
deep?: RegExp[];
|
|
47
|
+
greedy?: RegExp[];
|
|
48
|
+
variables?: HtmlnanoPurgeCssPattern[];
|
|
49
|
+
keyframes?: HtmlnanoPurgeCssPattern[];
|
|
50
|
+
};
|
|
51
|
+
interface HtmlnanoPurgeCssOptions {
|
|
52
|
+
tool: 'purgeCSS';
|
|
53
|
+
defaultExtractor?: HtmlnanoPurgeCssDefaultExtractor;
|
|
54
|
+
fontFace?: boolean;
|
|
55
|
+
keyframes?: boolean;
|
|
56
|
+
output?: string;
|
|
57
|
+
rejected?: boolean;
|
|
58
|
+
rejectedCss?: boolean;
|
|
59
|
+
sourceMap?: boolean | HtmlnanoPurgeCssSourceMapOptions;
|
|
60
|
+
stdin?: boolean;
|
|
61
|
+
stdout?: boolean;
|
|
62
|
+
variables?: boolean;
|
|
63
|
+
safelist?: HtmlnanoPurgeCssSafelist;
|
|
64
|
+
blocklist?: HtmlnanoPurgeCssPattern[];
|
|
65
|
+
skippedContentGlobs?: string[];
|
|
66
|
+
dynamicAttributes?: string[];
|
|
67
|
+
}
|
|
23
68
|
interface HtmlnanoOptions {
|
|
24
69
|
skipConfigLoading?: boolean;
|
|
25
70
|
configPath?: string;
|
|
@@ -34,16 +79,16 @@ interface HtmlnanoOptions {
|
|
|
34
79
|
minifyUrls?: URL | string | false;
|
|
35
80
|
mergeStyles?: boolean;
|
|
36
81
|
mergeScripts?: boolean;
|
|
37
|
-
minifyCss?:
|
|
82
|
+
minifyCss?: HtmlnanoMinifyCssOptions | boolean;
|
|
38
83
|
minifyHtmlTemplate?: MinifyHtmlTemplateOptions;
|
|
39
84
|
minifyConditionalComments?: boolean;
|
|
40
|
-
minifyJs?:
|
|
85
|
+
minifyJs?: HtmlnanoMinifyJsOptions | boolean;
|
|
41
86
|
minifyJson?: boolean;
|
|
42
87
|
minifyAttributes?: boolean | {
|
|
43
88
|
metaContent?: boolean;
|
|
44
89
|
redundantWhitespaces?: 'safe' | 'agressive' | false;
|
|
45
90
|
};
|
|
46
|
-
minifySvg?:
|
|
91
|
+
minifySvg?: HtmlnanoMinifySvgOptions | boolean;
|
|
47
92
|
normalizeAttributeValues?: boolean;
|
|
48
93
|
removeAttributeQuotes?: boolean | {
|
|
49
94
|
force?: boolean;
|
|
@@ -55,9 +100,8 @@ interface HtmlnanoOptions {
|
|
|
55
100
|
};
|
|
56
101
|
removeRedundantAttributes?: boolean;
|
|
57
102
|
removeOptionalTags?: boolean;
|
|
58
|
-
removeUnusedCss?: boolean |
|
|
59
|
-
tool
|
|
60
|
-
} & Omit<UserDefinedOptions, 'content' | 'css' | 'extractors'>) | {
|
|
103
|
+
removeUnusedCss?: boolean | HtmlnanoPurgeCssOptions | {
|
|
104
|
+
tool?: 'uncss';
|
|
61
105
|
banner?: boolean;
|
|
62
106
|
csspath?: string;
|
|
63
107
|
htmlroot?: string;
|
|
@@ -77,7 +121,7 @@ interface HtmlnanoOptions {
|
|
|
77
121
|
type HtmlnanoModuleAttrsHandler = (attrs: Record<string, string | boolean | void>, node: PostHTML.Node) => Record<string, string | boolean | void>;
|
|
78
122
|
type HtmlnanoModuleContentHandler = (content: Array<PostHTMLNodeLike>, node: PostHTML.Node) => MaybeArray<PostHTMLNodeLike>;
|
|
79
123
|
type HtmlnanoModuleNodeHandler = (node: PostHTMLNodeLike) => PostHTML.Node | string;
|
|
80
|
-
type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends object ? Partial<T> : T;
|
|
124
|
+
type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends Array<infer Item> ? Array<Item> : T extends object ? Partial<T> : T;
|
|
81
125
|
type HtmlnanoModule<Options = any> = {
|
|
82
126
|
onAttrs?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleAttrsHandler;
|
|
83
127
|
onContent?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleContentHandler;
|
|
@@ -1,25 +1,70 @@
|
|
|
1
1
|
import PostHTML from 'posthtml';
|
|
2
|
-
import { MinifyOptions } from 'terser';
|
|
3
|
-
import { Options } from 'cssnano';
|
|
4
|
-
import { Config } from 'svgo';
|
|
5
|
-
import { UserDefinedOptions } from 'purgecss';
|
|
6
2
|
|
|
7
|
-
type
|
|
3
|
+
type PostHTMLNodeLike = PostHTML.Node | string;
|
|
4
|
+
type PostHTMLTreeLike = [PostHTMLNodeLike] & PostHTML.NodeAPI & {
|
|
8
5
|
options?: {
|
|
9
6
|
quoteAllAttributes?: boolean | undefined;
|
|
10
7
|
quoteStyle?: 0 | 1 | 2 | undefined;
|
|
11
8
|
replaceQuote?: boolean | undefined;
|
|
12
9
|
} | undefined;
|
|
13
10
|
render(): string;
|
|
14
|
-
render(node:
|
|
11
|
+
render(node: PostHTMLNodeLike | PostHTMLTreeLike, renderOptions?: any): string;
|
|
15
12
|
};
|
|
16
13
|
type MaybeArray<T> = T | Array<T>;
|
|
17
|
-
type PostHTMLNodeLike = PostHTML.Node | string;
|
|
18
14
|
type HtmlnanoTemplateRule = {
|
|
19
15
|
tag: string;
|
|
20
16
|
attrs?: Record<string, string | boolean | void>;
|
|
21
17
|
};
|
|
22
18
|
type MinifyHtmlTemplateOptions = boolean | HtmlnanoTemplateRule[];
|
|
19
|
+
type HtmlnanoMinifyCssOptions = object;
|
|
20
|
+
type HtmlnanoMinifyJsOptions = object;
|
|
21
|
+
type HtmlnanoMinifySvgOptions = object;
|
|
22
|
+
type HtmlnanoPurgeCssPattern = string | RegExp;
|
|
23
|
+
type HtmlnanoPurgeCssExtractorResultDetailed = {
|
|
24
|
+
attributes: {
|
|
25
|
+
names: string[];
|
|
26
|
+
values: string[];
|
|
27
|
+
};
|
|
28
|
+
classes: string[];
|
|
29
|
+
ids: string[];
|
|
30
|
+
tags: string[];
|
|
31
|
+
undetermined: string[];
|
|
32
|
+
};
|
|
33
|
+
type HtmlnanoPurgeCssExtractorResult = HtmlnanoPurgeCssExtractorResultDetailed | string[];
|
|
34
|
+
type HtmlnanoPurgeCssDefaultExtractor = (content: string) => HtmlnanoPurgeCssExtractorResult;
|
|
35
|
+
type HtmlnanoPurgeCssSourceMapOptions = {
|
|
36
|
+
absolute?: boolean;
|
|
37
|
+
annotation?: boolean | string;
|
|
38
|
+
from?: string;
|
|
39
|
+
inline?: boolean;
|
|
40
|
+
prev?: boolean | object | string;
|
|
41
|
+
sourcesContent?: boolean;
|
|
42
|
+
to?: string;
|
|
43
|
+
};
|
|
44
|
+
type HtmlnanoPurgeCssSafelist = HtmlnanoPurgeCssPattern[] | {
|
|
45
|
+
standard?: HtmlnanoPurgeCssPattern[];
|
|
46
|
+
deep?: RegExp[];
|
|
47
|
+
greedy?: RegExp[];
|
|
48
|
+
variables?: HtmlnanoPurgeCssPattern[];
|
|
49
|
+
keyframes?: HtmlnanoPurgeCssPattern[];
|
|
50
|
+
};
|
|
51
|
+
interface HtmlnanoPurgeCssOptions {
|
|
52
|
+
tool: 'purgeCSS';
|
|
53
|
+
defaultExtractor?: HtmlnanoPurgeCssDefaultExtractor;
|
|
54
|
+
fontFace?: boolean;
|
|
55
|
+
keyframes?: boolean;
|
|
56
|
+
output?: string;
|
|
57
|
+
rejected?: boolean;
|
|
58
|
+
rejectedCss?: boolean;
|
|
59
|
+
sourceMap?: boolean | HtmlnanoPurgeCssSourceMapOptions;
|
|
60
|
+
stdin?: boolean;
|
|
61
|
+
stdout?: boolean;
|
|
62
|
+
variables?: boolean;
|
|
63
|
+
safelist?: HtmlnanoPurgeCssSafelist;
|
|
64
|
+
blocklist?: HtmlnanoPurgeCssPattern[];
|
|
65
|
+
skippedContentGlobs?: string[];
|
|
66
|
+
dynamicAttributes?: string[];
|
|
67
|
+
}
|
|
23
68
|
interface HtmlnanoOptions {
|
|
24
69
|
skipConfigLoading?: boolean;
|
|
25
70
|
configPath?: string;
|
|
@@ -34,16 +79,16 @@ interface HtmlnanoOptions {
|
|
|
34
79
|
minifyUrls?: URL | string | false;
|
|
35
80
|
mergeStyles?: boolean;
|
|
36
81
|
mergeScripts?: boolean;
|
|
37
|
-
minifyCss?:
|
|
82
|
+
minifyCss?: HtmlnanoMinifyCssOptions | boolean;
|
|
38
83
|
minifyHtmlTemplate?: MinifyHtmlTemplateOptions;
|
|
39
84
|
minifyConditionalComments?: boolean;
|
|
40
|
-
minifyJs?:
|
|
85
|
+
minifyJs?: HtmlnanoMinifyJsOptions | boolean;
|
|
41
86
|
minifyJson?: boolean;
|
|
42
87
|
minifyAttributes?: boolean | {
|
|
43
88
|
metaContent?: boolean;
|
|
44
89
|
redundantWhitespaces?: 'safe' | 'agressive' | false;
|
|
45
90
|
};
|
|
46
|
-
minifySvg?:
|
|
91
|
+
minifySvg?: HtmlnanoMinifySvgOptions | boolean;
|
|
47
92
|
normalizeAttributeValues?: boolean;
|
|
48
93
|
removeAttributeQuotes?: boolean | {
|
|
49
94
|
force?: boolean;
|
|
@@ -55,9 +100,8 @@ interface HtmlnanoOptions {
|
|
|
55
100
|
};
|
|
56
101
|
removeRedundantAttributes?: boolean;
|
|
57
102
|
removeOptionalTags?: boolean;
|
|
58
|
-
removeUnusedCss?: boolean |
|
|
59
|
-
tool
|
|
60
|
-
} & Omit<UserDefinedOptions, 'content' | 'css' | 'extractors'>) | {
|
|
103
|
+
removeUnusedCss?: boolean | HtmlnanoPurgeCssOptions | {
|
|
104
|
+
tool?: 'uncss';
|
|
61
105
|
banner?: boolean;
|
|
62
106
|
csspath?: string;
|
|
63
107
|
htmlroot?: string;
|
|
@@ -77,7 +121,7 @@ interface HtmlnanoOptions {
|
|
|
77
121
|
type HtmlnanoModuleAttrsHandler = (attrs: Record<string, string | boolean | void>, node: PostHTML.Node) => Record<string, string | boolean | void>;
|
|
78
122
|
type HtmlnanoModuleContentHandler = (content: Array<PostHTMLNodeLike>, node: PostHTML.Node) => MaybeArray<PostHTMLNodeLike>;
|
|
79
123
|
type HtmlnanoModuleNodeHandler = (node: PostHTMLNodeLike) => PostHTML.Node | string;
|
|
80
|
-
type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends object ? Partial<T> : T;
|
|
124
|
+
type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends Array<infer Item> ? Array<Item> : T extends object ? Partial<T> : T;
|
|
81
125
|
type HtmlnanoModule<Options = any> = {
|
|
82
126
|
onAttrs?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleAttrsHandler;
|
|
83
127
|
onContent?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleContentHandler;
|
|
@@ -112,13 +112,14 @@ function runPurgecss(tree, css, userOptions, purgecss, extractor) {
|
|
|
112
112
|
}
|
|
113
113
|
/** Remove unused CSS */ const mod = {
|
|
114
114
|
async default (tree, options, userOptions) {
|
|
115
|
+
var _resolvedOptions_tool;
|
|
115
116
|
const promises = [];
|
|
116
117
|
let html;
|
|
117
118
|
let extractor;
|
|
118
119
|
const purgecss = await helpers_js.optionalImport('purgecss');
|
|
119
120
|
const uncss = await helpers_js.optionalImport('uncss');
|
|
120
121
|
const resolvedOptions = resolveUserOptions(userOptions);
|
|
121
|
-
const tool = resolvedOptions.tool;
|
|
122
|
+
const tool = (_resolvedOptions_tool = resolvedOptions.tool) != null ? _resolvedOptions_tool : 'purgeCSS';
|
|
122
123
|
const toolOptions = stripToolOption(resolvedOptions);
|
|
123
124
|
tree.walk((node)=>{
|
|
124
125
|
if (helpers_js.isStyleNode(node) && helpers_js.isCssStyleType(node)) {
|
|
@@ -127,7 +128,7 @@ function runPurgecss(tree, css, userOptions, purgecss, extractor) {
|
|
|
127
128
|
extractor != null ? extractor : extractor = purgeFromHtml(tree);
|
|
128
129
|
promises.push(processStyleNodePurgeCSS(tree, node, toolOptions, purgecss, extractor));
|
|
129
130
|
}
|
|
130
|
-
} else {
|
|
131
|
+
} else if (tool === 'uncss') {
|
|
131
132
|
if (uncss) {
|
|
132
133
|
html != null ? html : html = tree.render(tree);
|
|
133
134
|
promises.push(processStyleNodeUnCSS(html, node, toolOptions, uncss));
|
|
@@ -110,13 +110,14 @@ function runPurgecss(tree, css, userOptions, purgecss, extractor) {
|
|
|
110
110
|
}
|
|
111
111
|
/** Remove unused CSS */ const mod = {
|
|
112
112
|
async default (tree, options, userOptions) {
|
|
113
|
+
var _resolvedOptions_tool;
|
|
113
114
|
const promises = [];
|
|
114
115
|
let html;
|
|
115
116
|
let extractor;
|
|
116
117
|
const purgecss = await optionalImport('purgecss');
|
|
117
118
|
const uncss = await optionalImport('uncss');
|
|
118
119
|
const resolvedOptions = resolveUserOptions(userOptions);
|
|
119
|
-
const tool = resolvedOptions.tool;
|
|
120
|
+
const tool = (_resolvedOptions_tool = resolvedOptions.tool) != null ? _resolvedOptions_tool : 'purgeCSS';
|
|
120
121
|
const toolOptions = stripToolOption(resolvedOptions);
|
|
121
122
|
tree.walk((node)=>{
|
|
122
123
|
if (isStyleNode(node) && isCssStyleType(node)) {
|
|
@@ -125,7 +126,7 @@ function runPurgecss(tree, css, userOptions, purgecss, extractor) {
|
|
|
125
126
|
extractor != null ? extractor : extractor = purgeFromHtml(tree);
|
|
126
127
|
promises.push(processStyleNodePurgeCSS(tree, node, toolOptions, purgecss, extractor));
|
|
127
128
|
}
|
|
128
|
-
} else {
|
|
129
|
+
} else if (tool === 'uncss') {
|
|
129
130
|
if (uncss) {
|
|
130
131
|
html != null ? html : html = tree.render(tree);
|
|
131
132
|
promises.push(processStyleNodeUnCSS(html, node, toolOptions, uncss));
|
|
@@ -1,25 +1,70 @@
|
|
|
1
1
|
import PostHTML from 'posthtml';
|
|
2
|
-
import { MinifyOptions } from 'terser';
|
|
3
|
-
import { Options } from 'cssnano';
|
|
4
|
-
import { Config } from 'svgo';
|
|
5
|
-
import { UserDefinedOptions } from 'purgecss';
|
|
6
2
|
|
|
7
|
-
type
|
|
3
|
+
type PostHTMLNodeLike = PostHTML.Node | string;
|
|
4
|
+
type PostHTMLTreeLike = [PostHTMLNodeLike] & PostHTML.NodeAPI & {
|
|
8
5
|
options?: {
|
|
9
6
|
quoteAllAttributes?: boolean | undefined;
|
|
10
7
|
quoteStyle?: 0 | 1 | 2 | undefined;
|
|
11
8
|
replaceQuote?: boolean | undefined;
|
|
12
9
|
} | undefined;
|
|
13
10
|
render(): string;
|
|
14
|
-
render(node:
|
|
11
|
+
render(node: PostHTMLNodeLike | PostHTMLTreeLike, renderOptions?: any): string;
|
|
15
12
|
};
|
|
16
13
|
type MaybeArray<T> = T | Array<T>;
|
|
17
|
-
type PostHTMLNodeLike = PostHTML.Node | string;
|
|
18
14
|
type HtmlnanoTemplateRule = {
|
|
19
15
|
tag: string;
|
|
20
16
|
attrs?: Record<string, string | boolean | void>;
|
|
21
17
|
};
|
|
22
18
|
type MinifyHtmlTemplateOptions = boolean | HtmlnanoTemplateRule[];
|
|
19
|
+
type HtmlnanoMinifyCssOptions = object;
|
|
20
|
+
type HtmlnanoMinifyJsOptions = object;
|
|
21
|
+
type HtmlnanoMinifySvgOptions = object;
|
|
22
|
+
type HtmlnanoPurgeCssPattern = string | RegExp;
|
|
23
|
+
type HtmlnanoPurgeCssExtractorResultDetailed = {
|
|
24
|
+
attributes: {
|
|
25
|
+
names: string[];
|
|
26
|
+
values: string[];
|
|
27
|
+
};
|
|
28
|
+
classes: string[];
|
|
29
|
+
ids: string[];
|
|
30
|
+
tags: string[];
|
|
31
|
+
undetermined: string[];
|
|
32
|
+
};
|
|
33
|
+
type HtmlnanoPurgeCssExtractorResult = HtmlnanoPurgeCssExtractorResultDetailed | string[];
|
|
34
|
+
type HtmlnanoPurgeCssDefaultExtractor = (content: string) => HtmlnanoPurgeCssExtractorResult;
|
|
35
|
+
type HtmlnanoPurgeCssSourceMapOptions = {
|
|
36
|
+
absolute?: boolean;
|
|
37
|
+
annotation?: boolean | string;
|
|
38
|
+
from?: string;
|
|
39
|
+
inline?: boolean;
|
|
40
|
+
prev?: boolean | object | string;
|
|
41
|
+
sourcesContent?: boolean;
|
|
42
|
+
to?: string;
|
|
43
|
+
};
|
|
44
|
+
type HtmlnanoPurgeCssSafelist = HtmlnanoPurgeCssPattern[] | {
|
|
45
|
+
standard?: HtmlnanoPurgeCssPattern[];
|
|
46
|
+
deep?: RegExp[];
|
|
47
|
+
greedy?: RegExp[];
|
|
48
|
+
variables?: HtmlnanoPurgeCssPattern[];
|
|
49
|
+
keyframes?: HtmlnanoPurgeCssPattern[];
|
|
50
|
+
};
|
|
51
|
+
interface HtmlnanoPurgeCssOptions {
|
|
52
|
+
tool: 'purgeCSS';
|
|
53
|
+
defaultExtractor?: HtmlnanoPurgeCssDefaultExtractor;
|
|
54
|
+
fontFace?: boolean;
|
|
55
|
+
keyframes?: boolean;
|
|
56
|
+
output?: string;
|
|
57
|
+
rejected?: boolean;
|
|
58
|
+
rejectedCss?: boolean;
|
|
59
|
+
sourceMap?: boolean | HtmlnanoPurgeCssSourceMapOptions;
|
|
60
|
+
stdin?: boolean;
|
|
61
|
+
stdout?: boolean;
|
|
62
|
+
variables?: boolean;
|
|
63
|
+
safelist?: HtmlnanoPurgeCssSafelist;
|
|
64
|
+
blocklist?: HtmlnanoPurgeCssPattern[];
|
|
65
|
+
skippedContentGlobs?: string[];
|
|
66
|
+
dynamicAttributes?: string[];
|
|
67
|
+
}
|
|
23
68
|
interface HtmlnanoOptions {
|
|
24
69
|
skipConfigLoading?: boolean;
|
|
25
70
|
configPath?: string;
|
|
@@ -34,16 +79,16 @@ interface HtmlnanoOptions {
|
|
|
34
79
|
minifyUrls?: URL | string | false;
|
|
35
80
|
mergeStyles?: boolean;
|
|
36
81
|
mergeScripts?: boolean;
|
|
37
|
-
minifyCss?:
|
|
82
|
+
minifyCss?: HtmlnanoMinifyCssOptions | boolean;
|
|
38
83
|
minifyHtmlTemplate?: MinifyHtmlTemplateOptions;
|
|
39
84
|
minifyConditionalComments?: boolean;
|
|
40
|
-
minifyJs?:
|
|
85
|
+
minifyJs?: HtmlnanoMinifyJsOptions | boolean;
|
|
41
86
|
minifyJson?: boolean;
|
|
42
87
|
minifyAttributes?: boolean | {
|
|
43
88
|
metaContent?: boolean;
|
|
44
89
|
redundantWhitespaces?: 'safe' | 'agressive' | false;
|
|
45
90
|
};
|
|
46
|
-
minifySvg?:
|
|
91
|
+
minifySvg?: HtmlnanoMinifySvgOptions | boolean;
|
|
47
92
|
normalizeAttributeValues?: boolean;
|
|
48
93
|
removeAttributeQuotes?: boolean | {
|
|
49
94
|
force?: boolean;
|
|
@@ -55,9 +100,8 @@ interface HtmlnanoOptions {
|
|
|
55
100
|
};
|
|
56
101
|
removeRedundantAttributes?: boolean;
|
|
57
102
|
removeOptionalTags?: boolean;
|
|
58
|
-
removeUnusedCss?: boolean |
|
|
59
|
-
tool
|
|
60
|
-
} & Omit<UserDefinedOptions, 'content' | 'css' | 'extractors'>) | {
|
|
103
|
+
removeUnusedCss?: boolean | HtmlnanoPurgeCssOptions | {
|
|
104
|
+
tool?: 'uncss';
|
|
61
105
|
banner?: boolean;
|
|
62
106
|
csspath?: string;
|
|
63
107
|
htmlroot?: string;
|
|
@@ -77,7 +121,7 @@ interface HtmlnanoOptions {
|
|
|
77
121
|
type HtmlnanoModuleAttrsHandler = (attrs: Record<string, string | boolean | void>, node: PostHTML.Node) => Record<string, string | boolean | void>;
|
|
78
122
|
type HtmlnanoModuleContentHandler = (content: Array<PostHTMLNodeLike>, node: PostHTML.Node) => MaybeArray<PostHTMLNodeLike>;
|
|
79
123
|
type HtmlnanoModuleNodeHandler = (node: PostHTMLNodeLike) => PostHTML.Node | string;
|
|
80
|
-
type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends object ? Partial<T> : T;
|
|
124
|
+
type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends Array<infer Item> ? Array<Item> : T extends object ? Partial<T> : T;
|
|
81
125
|
type HtmlnanoModule<Options = any> = {
|
|
82
126
|
onAttrs?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleAttrsHandler;
|
|
83
127
|
onContent?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleContentHandler;
|
|
@@ -85,7 +129,8 @@ type HtmlnanoModule<Options = any> = {
|
|
|
85
129
|
default?: (tree: PostHTMLTreeLike, options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => PostHTMLTreeLike | Promise<PostHTMLTreeLike>;
|
|
86
130
|
};
|
|
87
131
|
|
|
88
|
-
type
|
|
89
|
-
|
|
132
|
+
type SortAttributesOption = 'alphabetical' | 'frequency';
|
|
133
|
+
|
|
134
|
+
declare const mod: HtmlnanoModule<boolean | SortAttributesOption>;
|
|
90
135
|
|
|
91
136
|
export { mod as default };
|
|
@@ -1,25 +1,70 @@
|
|
|
1
1
|
import PostHTML from 'posthtml';
|
|
2
|
-
import { MinifyOptions } from 'terser';
|
|
3
|
-
import { Options } from 'cssnano';
|
|
4
|
-
import { Config } from 'svgo';
|
|
5
|
-
import { UserDefinedOptions } from 'purgecss';
|
|
6
2
|
|
|
7
|
-
type
|
|
3
|
+
type PostHTMLNodeLike = PostHTML.Node | string;
|
|
4
|
+
type PostHTMLTreeLike = [PostHTMLNodeLike] & PostHTML.NodeAPI & {
|
|
8
5
|
options?: {
|
|
9
6
|
quoteAllAttributes?: boolean | undefined;
|
|
10
7
|
quoteStyle?: 0 | 1 | 2 | undefined;
|
|
11
8
|
replaceQuote?: boolean | undefined;
|
|
12
9
|
} | undefined;
|
|
13
10
|
render(): string;
|
|
14
|
-
render(node:
|
|
11
|
+
render(node: PostHTMLNodeLike | PostHTMLTreeLike, renderOptions?: any): string;
|
|
15
12
|
};
|
|
16
13
|
type MaybeArray<T> = T | Array<T>;
|
|
17
|
-
type PostHTMLNodeLike = PostHTML.Node | string;
|
|
18
14
|
type HtmlnanoTemplateRule = {
|
|
19
15
|
tag: string;
|
|
20
16
|
attrs?: Record<string, string | boolean | void>;
|
|
21
17
|
};
|
|
22
18
|
type MinifyHtmlTemplateOptions = boolean | HtmlnanoTemplateRule[];
|
|
19
|
+
type HtmlnanoMinifyCssOptions = object;
|
|
20
|
+
type HtmlnanoMinifyJsOptions = object;
|
|
21
|
+
type HtmlnanoMinifySvgOptions = object;
|
|
22
|
+
type HtmlnanoPurgeCssPattern = string | RegExp;
|
|
23
|
+
type HtmlnanoPurgeCssExtractorResultDetailed = {
|
|
24
|
+
attributes: {
|
|
25
|
+
names: string[];
|
|
26
|
+
values: string[];
|
|
27
|
+
};
|
|
28
|
+
classes: string[];
|
|
29
|
+
ids: string[];
|
|
30
|
+
tags: string[];
|
|
31
|
+
undetermined: string[];
|
|
32
|
+
};
|
|
33
|
+
type HtmlnanoPurgeCssExtractorResult = HtmlnanoPurgeCssExtractorResultDetailed | string[];
|
|
34
|
+
type HtmlnanoPurgeCssDefaultExtractor = (content: string) => HtmlnanoPurgeCssExtractorResult;
|
|
35
|
+
type HtmlnanoPurgeCssSourceMapOptions = {
|
|
36
|
+
absolute?: boolean;
|
|
37
|
+
annotation?: boolean | string;
|
|
38
|
+
from?: string;
|
|
39
|
+
inline?: boolean;
|
|
40
|
+
prev?: boolean | object | string;
|
|
41
|
+
sourcesContent?: boolean;
|
|
42
|
+
to?: string;
|
|
43
|
+
};
|
|
44
|
+
type HtmlnanoPurgeCssSafelist = HtmlnanoPurgeCssPattern[] | {
|
|
45
|
+
standard?: HtmlnanoPurgeCssPattern[];
|
|
46
|
+
deep?: RegExp[];
|
|
47
|
+
greedy?: RegExp[];
|
|
48
|
+
variables?: HtmlnanoPurgeCssPattern[];
|
|
49
|
+
keyframes?: HtmlnanoPurgeCssPattern[];
|
|
50
|
+
};
|
|
51
|
+
interface HtmlnanoPurgeCssOptions {
|
|
52
|
+
tool: 'purgeCSS';
|
|
53
|
+
defaultExtractor?: HtmlnanoPurgeCssDefaultExtractor;
|
|
54
|
+
fontFace?: boolean;
|
|
55
|
+
keyframes?: boolean;
|
|
56
|
+
output?: string;
|
|
57
|
+
rejected?: boolean;
|
|
58
|
+
rejectedCss?: boolean;
|
|
59
|
+
sourceMap?: boolean | HtmlnanoPurgeCssSourceMapOptions;
|
|
60
|
+
stdin?: boolean;
|
|
61
|
+
stdout?: boolean;
|
|
62
|
+
variables?: boolean;
|
|
63
|
+
safelist?: HtmlnanoPurgeCssSafelist;
|
|
64
|
+
blocklist?: HtmlnanoPurgeCssPattern[];
|
|
65
|
+
skippedContentGlobs?: string[];
|
|
66
|
+
dynamicAttributes?: string[];
|
|
67
|
+
}
|
|
23
68
|
interface HtmlnanoOptions {
|
|
24
69
|
skipConfigLoading?: boolean;
|
|
25
70
|
configPath?: string;
|
|
@@ -34,16 +79,16 @@ interface HtmlnanoOptions {
|
|
|
34
79
|
minifyUrls?: URL | string | false;
|
|
35
80
|
mergeStyles?: boolean;
|
|
36
81
|
mergeScripts?: boolean;
|
|
37
|
-
minifyCss?:
|
|
82
|
+
minifyCss?: HtmlnanoMinifyCssOptions | boolean;
|
|
38
83
|
minifyHtmlTemplate?: MinifyHtmlTemplateOptions;
|
|
39
84
|
minifyConditionalComments?: boolean;
|
|
40
|
-
minifyJs?:
|
|
85
|
+
minifyJs?: HtmlnanoMinifyJsOptions | boolean;
|
|
41
86
|
minifyJson?: boolean;
|
|
42
87
|
minifyAttributes?: boolean | {
|
|
43
88
|
metaContent?: boolean;
|
|
44
89
|
redundantWhitespaces?: 'safe' | 'agressive' | false;
|
|
45
90
|
};
|
|
46
|
-
minifySvg?:
|
|
91
|
+
minifySvg?: HtmlnanoMinifySvgOptions | boolean;
|
|
47
92
|
normalizeAttributeValues?: boolean;
|
|
48
93
|
removeAttributeQuotes?: boolean | {
|
|
49
94
|
force?: boolean;
|
|
@@ -55,9 +100,8 @@ interface HtmlnanoOptions {
|
|
|
55
100
|
};
|
|
56
101
|
removeRedundantAttributes?: boolean;
|
|
57
102
|
removeOptionalTags?: boolean;
|
|
58
|
-
removeUnusedCss?: boolean |
|
|
59
|
-
tool
|
|
60
|
-
} & Omit<UserDefinedOptions, 'content' | 'css' | 'extractors'>) | {
|
|
103
|
+
removeUnusedCss?: boolean | HtmlnanoPurgeCssOptions | {
|
|
104
|
+
tool?: 'uncss';
|
|
61
105
|
banner?: boolean;
|
|
62
106
|
csspath?: string;
|
|
63
107
|
htmlroot?: string;
|
|
@@ -77,7 +121,7 @@ interface HtmlnanoOptions {
|
|
|
77
121
|
type HtmlnanoModuleAttrsHandler = (attrs: Record<string, string | boolean | void>, node: PostHTML.Node) => Record<string, string | boolean | void>;
|
|
78
122
|
type HtmlnanoModuleContentHandler = (content: Array<PostHTMLNodeLike>, node: PostHTML.Node) => MaybeArray<PostHTMLNodeLike>;
|
|
79
123
|
type HtmlnanoModuleNodeHandler = (node: PostHTMLNodeLike) => PostHTML.Node | string;
|
|
80
|
-
type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends object ? Partial<T> : T;
|
|
124
|
+
type OptionalOptions<T> = T extends boolean | string | Function | number | null | undefined ? T : T extends Array<infer Item> ? Array<Item> : T extends object ? Partial<T> : T;
|
|
81
125
|
type HtmlnanoModule<Options = any> = {
|
|
82
126
|
onAttrs?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleAttrsHandler;
|
|
83
127
|
onContent?: (options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => HtmlnanoModuleContentHandler;
|
|
@@ -85,7 +129,8 @@ type HtmlnanoModule<Options = any> = {
|
|
|
85
129
|
default?: (tree: PostHTMLTreeLike, options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => PostHTMLTreeLike | Promise<PostHTMLTreeLike>;
|
|
86
130
|
};
|
|
87
131
|
|
|
88
|
-
type
|
|
89
|
-
|
|
132
|
+
type SortAttributesOption = 'alphabetical' | 'frequency';
|
|
133
|
+
|
|
134
|
+
declare const mod: HtmlnanoModule<boolean | SortAttributesOption>;
|
|
90
135
|
|
|
91
136
|
export { mod as default };
|
|
@@ -4,11 +4,12 @@ const validOptions = new Set([
|
|
|
4
4
|
'frequency',
|
|
5
5
|
'alphabetical'
|
|
6
6
|
]);
|
|
7
|
-
|
|
7
|
+
function resolveSortType(options) {
|
|
8
8
|
if (options === true) return 'alphabetical';
|
|
9
9
|
if (options === false) return false;
|
|
10
10
|
return validOptions.has(options) ? options : false;
|
|
11
|
-
}
|
|
11
|
+
}
|
|
12
|
+
|
|
12
13
|
class AttributeTokenChain {
|
|
13
14
|
addFromNodeAttrs(nodeAttrs) {
|
|
14
15
|
Object.keys(nodeAttrs).forEach((attrName)=>{
|
|
@@ -70,7 +71,7 @@ class AttributeTokenChain {
|
|
|
70
71
|
}
|
|
71
72
|
/** Sort attibutes */ const mod = {
|
|
72
73
|
default (tree, options, moduleOptions) {
|
|
73
|
-
const sortType =
|
|
74
|
+
const sortType = resolveSortType(moduleOptions);
|
|
74
75
|
if (sortType === 'alphabetical') {
|
|
75
76
|
return sortAttributesInAlphabeticalOrder(tree);
|
|
76
77
|
}
|
|
@@ -86,12 +87,7 @@ function sortAttributesInAlphabeticalOrder(tree) {
|
|
|
86
87
|
if (!node.attrs) {
|
|
87
88
|
return node;
|
|
88
89
|
}
|
|
89
|
-
|
|
90
|
-
Object.keys(node.attrs)// @ts-expect-error -- deliberately use minus operator to sort things
|
|
91
|
-
.sort((a, b)=>typeof a.localeCompare === 'function' ? a.localeCompare(b) : a - b).forEach((attr)=>{
|
|
92
|
-
newAttrs[attr] = node.attrs[attr];
|
|
93
|
-
});
|
|
94
|
-
node.attrs = newAttrs;
|
|
90
|
+
node.attrs = Object.fromEntries(Object.entries(node.attrs).sort(([attrA], [attrB])=>attrA.localeCompare(attrB)));
|
|
95
91
|
return node;
|
|
96
92
|
});
|
|
97
93
|
return tree;
|
|
@@ -2,11 +2,12 @@ const validOptions = new Set([
|
|
|
2
2
|
'frequency',
|
|
3
3
|
'alphabetical'
|
|
4
4
|
]);
|
|
5
|
-
|
|
5
|
+
function resolveSortType(options) {
|
|
6
6
|
if (options === true) return 'alphabetical';
|
|
7
7
|
if (options === false) return false;
|
|
8
8
|
return validOptions.has(options) ? options : false;
|
|
9
|
-
}
|
|
9
|
+
}
|
|
10
|
+
|
|
10
11
|
class AttributeTokenChain {
|
|
11
12
|
addFromNodeAttrs(nodeAttrs) {
|
|
12
13
|
Object.keys(nodeAttrs).forEach((attrName)=>{
|
|
@@ -68,7 +69,7 @@ class AttributeTokenChain {
|
|
|
68
69
|
}
|
|
69
70
|
/** Sort attibutes */ const mod = {
|
|
70
71
|
default (tree, options, moduleOptions) {
|
|
71
|
-
const sortType =
|
|
72
|
+
const sortType = resolveSortType(moduleOptions);
|
|
72
73
|
if (sortType === 'alphabetical') {
|
|
73
74
|
return sortAttributesInAlphabeticalOrder(tree);
|
|
74
75
|
}
|
|
@@ -84,12 +85,7 @@ function sortAttributesInAlphabeticalOrder(tree) {
|
|
|
84
85
|
if (!node.attrs) {
|
|
85
86
|
return node;
|
|
86
87
|
}
|
|
87
|
-
|
|
88
|
-
Object.keys(node.attrs)// @ts-expect-error -- deliberately use minus operator to sort things
|
|
89
|
-
.sort((a, b)=>typeof a.localeCompare === 'function' ? a.localeCompare(b) : a - b).forEach((attr)=>{
|
|
90
|
-
newAttrs[attr] = node.attrs[attr];
|
|
91
|
-
});
|
|
92
|
-
node.attrs = newAttrs;
|
|
88
|
+
node.attrs = Object.fromEntries(Object.entries(node.attrs).sort(([attrA], [attrB])=>attrA.localeCompare(attrB)));
|
|
93
89
|
return node;
|
|
94
90
|
});
|
|
95
91
|
return tree;
|