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