htmlnano 2.1.5 → 3.1.0
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 +24 -17
- package/dist/_modules/collapseAttributeWhitespace.d.mts +42 -5
- package/dist/_modules/collapseAttributeWhitespace.d.ts +42 -5
- package/dist/_modules/collapseAttributeWhitespace.js +69 -16
- package/dist/_modules/collapseAttributeWhitespace.mjs +67 -17
- package/dist/_modules/collapseBooleanAttributes.d.mts +37 -3
- package/dist/_modules/collapseBooleanAttributes.d.ts +37 -3
- package/dist/_modules/collapseBooleanAttributes.js +18 -11
- package/dist/_modules/collapseBooleanAttributes.mjs +18 -11
- package/dist/_modules/collapseWhitespace.d.mts +37 -3
- package/dist/_modules/collapseWhitespace.d.ts +37 -3
- package/dist/_modules/collapseWhitespace.js +25 -2
- package/dist/_modules/collapseWhitespace.mjs +25 -2
- package/dist/_modules/custom.d.mts +37 -3
- package/dist/_modules/custom.d.ts +37 -3
- package/dist/_modules/deduplicateAttributeValues.d.mts +37 -3
- package/dist/_modules/deduplicateAttributeValues.d.ts +37 -3
- package/dist/_modules/deduplicateAttributeValues.js +20 -5
- package/dist/_modules/deduplicateAttributeValues.mjs +21 -6
- package/dist/_modules/example.d.mts +37 -3
- package/dist/_modules/example.d.ts +37 -3
- package/dist/_modules/mergeScripts.d.mts +37 -3
- package/dist/_modules/mergeScripts.d.ts +37 -3
- package/dist/_modules/mergeScripts.js +99 -24
- package/dist/_modules/mergeScripts.mjs +99 -24
- package/dist/_modules/mergeStyles.d.mts +37 -3
- package/dist/_modules/mergeStyles.d.ts +37 -3
- package/dist/_modules/mergeStyles.js +57 -6
- package/dist/_modules/mergeStyles.mjs +57 -6
- package/dist/_modules/minifyAttributes.d.mts +95 -0
- package/dist/_modules/minifyAttributes.d.ts +95 -0
- package/dist/_modules/minifyAttributes.js +159 -0
- package/dist/_modules/minifyAttributes.mjs +157 -0
- package/dist/_modules/minifyConditionalComments.d.mts +37 -3
- package/dist/_modules/minifyConditionalComments.d.ts +37 -3
- package/dist/_modules/minifyConditionalComments.js +37 -19
- package/dist/_modules/minifyConditionalComments.mjs +37 -19
- package/dist/_modules/minifyCss.d.mts +37 -3
- package/dist/_modules/minifyCss.d.ts +37 -3
- package/dist/_modules/minifyCss.js +13 -27
- package/dist/_modules/minifyCss.mjs +14 -28
- package/dist/_modules/minifyHtmlTemplate.d.mts +91 -0
- package/dist/_modules/minifyHtmlTemplate.d.ts +91 -0
- package/dist/_modules/minifyHtmlTemplate.js +231 -0
- package/dist/_modules/minifyHtmlTemplate.mjs +228 -0
- package/dist/_modules/minifyJs.d.mts +37 -3
- package/dist/_modules/minifyJs.d.ts +37 -3
- package/dist/_modules/minifyJs.js +94 -5
- package/dist/_modules/minifyJs.mjs +95 -6
- package/dist/_modules/minifyJson.d.mts +37 -3
- package/dist/_modules/minifyJson.d.ts +37 -3
- package/dist/_modules/minifyJson.js +9 -12
- package/dist/_modules/minifyJson.mjs +9 -12
- package/dist/_modules/minifySvg.d.mts +37 -3
- package/dist/_modules/minifySvg.d.ts +37 -3
- package/dist/_modules/minifySvg.js +36 -5
- package/dist/_modules/minifySvg.mjs +36 -5
- package/dist/_modules/minifyUrls.d.mts +38 -4
- package/dist/_modules/minifyUrls.d.ts +38 -4
- package/dist/_modules/minifyUrls.js +53 -28
- package/dist/_modules/minifyUrls.mjs +53 -28
- package/dist/_modules/normalizeAttributeValues.d.mts +37 -3
- package/dist/_modules/normalizeAttributeValues.d.ts +37 -3
- package/dist/_modules/normalizeAttributeValues.js +10 -8
- package/dist/_modules/normalizeAttributeValues.mjs +10 -8
- package/dist/_modules/removeAttributeQuotes.d.mts +41 -4
- package/dist/_modules/removeAttributeQuotes.d.ts +41 -4
- package/dist/_modules/removeAttributeQuotes.js +9 -5
- package/dist/_modules/removeAttributeQuotes.mjs +9 -5
- package/dist/_modules/removeComments.d.mts +38 -4
- package/dist/_modules/removeComments.d.ts +38 -4
- package/dist/_modules/removeComments.js +44 -12
- package/dist/_modules/removeComments.mjs +44 -12
- package/dist/_modules/removeEmptyAttributes.d.mts +37 -3
- package/dist/_modules/removeEmptyAttributes.d.ts +37 -3
- package/dist/_modules/removeEmptyAttributes.js +37 -16
- package/dist/_modules/removeEmptyAttributes.mjs +37 -16
- package/dist/_modules/removeEmptyElements.d.mts +95 -0
- package/dist/_modules/removeEmptyElements.d.ts +95 -0
- package/dist/_modules/removeEmptyElements.js +90 -0
- package/dist/_modules/removeEmptyElements.mjs +88 -0
- package/dist/_modules/removeOptionalTags.d.mts +37 -3
- package/dist/_modules/removeOptionalTags.d.ts +37 -3
- package/dist/_modules/removeOptionalTags.js +39 -28
- package/dist/_modules/removeOptionalTags.mjs +39 -28
- package/dist/_modules/removeRedundantAttributes.d.mts +37 -3
- package/dist/_modules/removeRedundantAttributes.d.ts +37 -3
- package/dist/_modules/removeRedundantAttributes.js +43 -28
- package/dist/_modules/removeRedundantAttributes.mjs +43 -28
- package/dist/_modules/removeUnusedCss.d.mts +38 -3
- package/dist/_modules/removeUnusedCss.d.ts +38 -3
- package/dist/_modules/removeUnusedCss.js +38 -13
- package/dist/_modules/removeUnusedCss.mjs +39 -14
- package/dist/_modules/sortAttributes.d.mts +37 -3
- package/dist/_modules/sortAttributes.d.ts +37 -3
- package/dist/_modules/sortAttributes.js +23 -5
- package/dist/_modules/sortAttributes.mjs +23 -5
- package/dist/_modules/sortAttributesWithLists.d.mts +37 -3
- package/dist/_modules/sortAttributesWithLists.d.ts +37 -3
- package/dist/_modules/sortAttributesWithLists.js +30 -8
- package/dist/_modules/sortAttributesWithLists.mjs +31 -9
- package/dist/bin.js +34 -0
- package/dist/helpers.d.ts +8 -1
- package/dist/helpers.js +48 -0
- package/dist/helpers.mjs +45 -1
- package/dist/index.d.ts +43 -8
- package/dist/index.js +20 -5
- package/dist/index.mjs +20 -6
- package/dist/presets/ampSafe.d.ts +38 -4
- package/dist/presets/max.d.ts +38 -4
- package/dist/presets/max.js +4 -0
- package/dist/presets/max.mjs +4 -0
- package/dist/presets/safe.d.ts +38 -4
- package/dist/presets/safe.js +6 -0
- package/dist/presets/safe.mjs +6 -0
- package/package.json +27 -16
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isListAttribute } from './collapseAttributeWhitespace.mjs';
|
|
2
2
|
|
|
3
3
|
// class, rel, ping
|
|
4
4
|
const validOptions = new Set([
|
|
@@ -13,6 +13,9 @@ const processModuleOptions = (options)=>{
|
|
|
13
13
|
class AttributeTokenChain {
|
|
14
14
|
addFromNodeAttrsArray(attrValuesArray) {
|
|
15
15
|
attrValuesArray.forEach((attrValue)=>{
|
|
16
|
+
if (!attrValue) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
16
19
|
if (this.freqData.has(attrValue)) {
|
|
17
20
|
this.freqData.set(attrValue, this.freqData.get(attrValue) + 1);
|
|
18
21
|
} else {
|
|
@@ -24,16 +27,28 @@ class AttributeTokenChain {
|
|
|
24
27
|
const _sortOrder = [
|
|
25
28
|
...this.freqData.entries()
|
|
26
29
|
];
|
|
27
|
-
_sortOrder.sort((a, b)=>b[1] - a[1]);
|
|
30
|
+
_sortOrder.sort((a, b)=>b[1] - a[1] || a[0].localeCompare(b[0]));
|
|
28
31
|
this.sortOrder = _sortOrder.map((i)=>i[0]);
|
|
29
32
|
}
|
|
30
33
|
sortFromNodeAttrsArray(attrValuesArray) {
|
|
31
34
|
const resultArray = [];
|
|
35
|
+
const tokenCounts = new Map();
|
|
36
|
+
attrValuesArray.forEach((attrValue)=>{
|
|
37
|
+
var _tokenCounts_get;
|
|
38
|
+
if (!attrValue) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
tokenCounts.set(attrValue, ((_tokenCounts_get = tokenCounts.get(attrValue)) != null ? _tokenCounts_get : 0) + 1);
|
|
42
|
+
});
|
|
32
43
|
if (!this.sortOrder) {
|
|
33
44
|
this.createSortOrder();
|
|
34
45
|
}
|
|
35
46
|
this.sortOrder.forEach((k)=>{
|
|
36
|
-
|
|
47
|
+
const count = tokenCounts.get(k);
|
|
48
|
+
if (!count) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
for(let i = 0; i < count; i += 1){
|
|
37
52
|
resultArray.push(k);
|
|
38
53
|
}
|
|
39
54
|
});
|
|
@@ -57,17 +72,22 @@ class AttributeTokenChain {
|
|
|
57
72
|
return tree;
|
|
58
73
|
}
|
|
59
74
|
};
|
|
75
|
+
const splitListAttributeValues = (attrValue)=>attrValue.split(/\s+/).filter(Boolean);
|
|
60
76
|
function sortAttributesWithListsInAlphabeticalOrder(tree) {
|
|
61
77
|
tree.walk((node)=>{
|
|
62
78
|
if (!node.attrs) {
|
|
63
79
|
return node;
|
|
64
80
|
}
|
|
81
|
+
const tagName = node.tag ? node.tag.toLowerCase() : undefined;
|
|
65
82
|
Object.keys(node.attrs).forEach((attrName)=>{
|
|
66
83
|
const attrNameLower = attrName.toLowerCase();
|
|
67
|
-
if (!
|
|
84
|
+
if (!isListAttribute(attrNameLower, tagName)) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const attrValues = splitListAttributeValues(node.attrs[attrName]);
|
|
88
|
+
if (attrValues.length < 2) {
|
|
68
89
|
return;
|
|
69
90
|
}
|
|
70
|
-
const attrValues = node.attrs[attrName].split(/\s/);
|
|
71
91
|
node.attrs[attrName] = attrValues.sort((a, b)=>{
|
|
72
92
|
// @ts-expect-error -- deliberately use minus operator to sort things
|
|
73
93
|
return typeof a.localeCompare === 'function' ? a.localeCompare(b) : a - b;
|
|
@@ -84,13 +104,14 @@ function sortAttributesWithListsByFrequency(tree) {
|
|
|
84
104
|
if (!node.attrs) {
|
|
85
105
|
return node;
|
|
86
106
|
}
|
|
107
|
+
const tagName = node.tag ? node.tag.toLowerCase() : undefined;
|
|
87
108
|
Object.entries(node.attrs).forEach(([attrName, attrValues])=>{
|
|
88
109
|
const attrNameLower = attrName.toLowerCase();
|
|
89
|
-
if (!
|
|
110
|
+
if (!isListAttribute(attrNameLower, tagName)) {
|
|
90
111
|
return;
|
|
91
112
|
}
|
|
92
113
|
tokenChainObj[attrNameLower] = tokenChainObj[attrNameLower] || new AttributeTokenChain();
|
|
93
|
-
tokenChainObj[attrNameLower].addFromNodeAttrsArray(attrValues
|
|
114
|
+
tokenChainObj[attrNameLower].addFromNodeAttrsArray(splitListAttributeValues(attrValues));
|
|
94
115
|
});
|
|
95
116
|
return node;
|
|
96
117
|
});
|
|
@@ -99,13 +120,14 @@ function sortAttributesWithListsByFrequency(tree) {
|
|
|
99
120
|
if (!node.attrs) {
|
|
100
121
|
return node;
|
|
101
122
|
}
|
|
123
|
+
const tagName = node.tag ? node.tag.toLowerCase() : undefined;
|
|
102
124
|
Object.entries(node.attrs).forEach(([attrName, attrValues])=>{
|
|
103
125
|
const attrNameLower = attrName.toLowerCase();
|
|
104
|
-
if (!
|
|
126
|
+
if (!isListAttribute(attrNameLower, tagName)) {
|
|
105
127
|
return;
|
|
106
128
|
}
|
|
107
129
|
if (tokenChainObj[attrNameLower]) {
|
|
108
|
-
node.attrs[attrName] = tokenChainObj[attrNameLower].sortFromNodeAttrsArray(attrValues
|
|
130
|
+
node.attrs[attrName] = tokenChainObj[attrNameLower].sortFromNodeAttrsArray(splitListAttributeValues(attrValues)).join(' ');
|
|
109
131
|
}
|
|
110
132
|
});
|
|
111
133
|
return node;
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var commander = require('commander');
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var process = require('process');
|
|
5
|
+
var index_js = require('./index.js');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
10
|
+
var process__default = /*#__PURE__*/_interopDefault(process);
|
|
11
|
+
|
|
12
|
+
commander.program.name('htmlnano').description('Minify HTML with htmlnano').argument('[input]', 'input file', '-').option('-o, --output <file>', 'output file', '-').option('-p, --preset <preset>', 'preset to use', 'safe').option('-c, --config <file>', 'path to config file').action(async (input, options)=>{
|
|
13
|
+
const { preset, output } = options;
|
|
14
|
+
if (!preset || !(preset in index_js.presets)) {
|
|
15
|
+
const available = Object.keys(index_js.presets).join(', ');
|
|
16
|
+
process__default.default.stderr.write(`Unknown preset: ${preset}. Available presets: ${available}\n`);
|
|
17
|
+
process__default.default.exitCode = 1;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const html = fs__default.default.readFileSync(input && input !== '-' ? input : 0, 'utf8');
|
|
21
|
+
const key = preset;
|
|
22
|
+
const chosenPreset = index_js.presets[key];
|
|
23
|
+
const htmlnanoOptions = {};
|
|
24
|
+
if (options.config) {
|
|
25
|
+
htmlnanoOptions.configPath = options.config;
|
|
26
|
+
}
|
|
27
|
+
const result = await index_js.process(html, htmlnanoOptions, chosenPreset);
|
|
28
|
+
if (output && output !== '-') {
|
|
29
|
+
fs__default.default.writeFileSync(output, result.html);
|
|
30
|
+
} else {
|
|
31
|
+
process__default.default.stdout.write(result.html);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
commander.program.parse();
|
package/dist/helpers.d.ts
CHANGED
|
@@ -7,10 +7,17 @@ declare function isComment(content: PostHTMLNodeLike | null): boolean;
|
|
|
7
7
|
declare function isConditionalComment(content: string): boolean;
|
|
8
8
|
declare function isStyleNode(node: PostHTML.Node): boolean | undefined;
|
|
9
9
|
declare function extractCssFromStyleNode(node: PostHTML.Node): string | undefined;
|
|
10
|
+
declare function stripCssCdata(css: string): {
|
|
11
|
+
strippedCss: string;
|
|
12
|
+
isCdataWrapped: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare function wrapCssCdata(css: string, isCdataWrapped: boolean): string;
|
|
15
|
+
declare function isCssStyleType(node: PostHTML.Node): boolean;
|
|
16
|
+
declare function normalizeMimeType(value: string): string;
|
|
10
17
|
declare function isEventHandler(attributeName: string): boolean | "";
|
|
11
18
|
declare function extractTextContentFromNode(node: PostHTML.Node): string;
|
|
12
19
|
declare function optionalImport<Module = unknown, Default = Module>(moduleName: string): Promise<(Module & {
|
|
13
20
|
default?: Default;
|
|
14
21
|
}) | NonNullable<Default> | null>;
|
|
15
22
|
|
|
16
|
-
export { extractCssFromStyleNode, extractTextContentFromNode, isAmpBoilerplate, isComment, isConditionalComment, isEventHandler, isStyleNode, optionalImport };
|
|
23
|
+
export { extractCssFromStyleNode, extractTextContentFromNode, isAmpBoilerplate, isComment, isConditionalComment, isCssStyleType, isEventHandler, isStyleNode, normalizeMimeType, optionalImport, stripCssCdata, wrapCssCdata };
|
package/dist/helpers.js
CHANGED
|
@@ -5,6 +5,8 @@ const ampBoilerplateAttributes = [
|
|
|
5
5
|
'amp4ads-boilerplate',
|
|
6
6
|
'amp4email-boilerplate'
|
|
7
7
|
];
|
|
8
|
+
const cssCdataStart = '<![CDATA[';
|
|
9
|
+
const cssCdataEnd = ']]>';
|
|
8
10
|
function isAmpBoilerplate(node) {
|
|
9
11
|
if (!node.attrs) {
|
|
10
12
|
return false;
|
|
@@ -32,6 +34,48 @@ function isStyleNode(node) {
|
|
|
32
34
|
function extractCssFromStyleNode(node) {
|
|
33
35
|
return Array.isArray(node.content) ? node.content.join(' ') : node.content;
|
|
34
36
|
}
|
|
37
|
+
function stripCssCdata(css) {
|
|
38
|
+
const trimmed = css.trim();
|
|
39
|
+
if (!trimmed.startsWith(cssCdataStart) || !trimmed.endsWith(cssCdataEnd)) {
|
|
40
|
+
return {
|
|
41
|
+
strippedCss: css,
|
|
42
|
+
isCdataWrapped: false
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const strippedCss = trimmed.slice(cssCdataStart.length, trimmed.length - cssCdataEnd.length);
|
|
46
|
+
return {
|
|
47
|
+
strippedCss,
|
|
48
|
+
isCdataWrapped: true
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function wrapCssCdata(css, isCdataWrapped) {
|
|
52
|
+
if (!isCdataWrapped) {
|
|
53
|
+
return css;
|
|
54
|
+
}
|
|
55
|
+
return `${cssCdataStart}${css}${cssCdataEnd}`;
|
|
56
|
+
}
|
|
57
|
+
function isCssStyleType(node) {
|
|
58
|
+
if (!node.attrs || !('type' in node.attrs)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
const rawType = node.attrs.type;
|
|
62
|
+
if (rawType === '') {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (typeof rawType !== 'string') {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const normalizedType = rawType.trim().toLowerCase();
|
|
69
|
+
return /^text\/css(?:$|\s*;)/.test(normalizedType);
|
|
70
|
+
}
|
|
71
|
+
function normalizeMimeType(value) {
|
|
72
|
+
const trimmed = value.trim();
|
|
73
|
+
if (!trimmed) {
|
|
74
|
+
return '';
|
|
75
|
+
}
|
|
76
|
+
const [mimeType] = trimmed.split(';');
|
|
77
|
+
return mimeType.trim().toLowerCase();
|
|
78
|
+
}
|
|
35
79
|
function isEventHandler(attributeName) {
|
|
36
80
|
return attributeName && attributeName.slice(0, 2).toLowerCase() === 'on' && attributeName.length >= 5;
|
|
37
81
|
}
|
|
@@ -67,6 +111,10 @@ exports.extractTextContentFromNode = extractTextContentFromNode;
|
|
|
67
111
|
exports.isAmpBoilerplate = isAmpBoilerplate;
|
|
68
112
|
exports.isComment = isComment;
|
|
69
113
|
exports.isConditionalComment = isConditionalComment;
|
|
114
|
+
exports.isCssStyleType = isCssStyleType;
|
|
70
115
|
exports.isEventHandler = isEventHandler;
|
|
71
116
|
exports.isStyleNode = isStyleNode;
|
|
117
|
+
exports.normalizeMimeType = normalizeMimeType;
|
|
72
118
|
exports.optionalImport = optionalImport;
|
|
119
|
+
exports.stripCssCdata = stripCssCdata;
|
|
120
|
+
exports.wrapCssCdata = wrapCssCdata;
|
package/dist/helpers.mjs
CHANGED
|
@@ -3,6 +3,8 @@ const ampBoilerplateAttributes = [
|
|
|
3
3
|
'amp4ads-boilerplate',
|
|
4
4
|
'amp4email-boilerplate'
|
|
5
5
|
];
|
|
6
|
+
const cssCdataStart = '<![CDATA[';
|
|
7
|
+
const cssCdataEnd = ']]>';
|
|
6
8
|
function isAmpBoilerplate(node) {
|
|
7
9
|
if (!node.attrs) {
|
|
8
10
|
return false;
|
|
@@ -30,6 +32,48 @@ function isStyleNode(node) {
|
|
|
30
32
|
function extractCssFromStyleNode(node) {
|
|
31
33
|
return Array.isArray(node.content) ? node.content.join(' ') : node.content;
|
|
32
34
|
}
|
|
35
|
+
function stripCssCdata(css) {
|
|
36
|
+
const trimmed = css.trim();
|
|
37
|
+
if (!trimmed.startsWith(cssCdataStart) || !trimmed.endsWith(cssCdataEnd)) {
|
|
38
|
+
return {
|
|
39
|
+
strippedCss: css,
|
|
40
|
+
isCdataWrapped: false
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const strippedCss = trimmed.slice(cssCdataStart.length, trimmed.length - cssCdataEnd.length);
|
|
44
|
+
return {
|
|
45
|
+
strippedCss,
|
|
46
|
+
isCdataWrapped: true
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function wrapCssCdata(css, isCdataWrapped) {
|
|
50
|
+
if (!isCdataWrapped) {
|
|
51
|
+
return css;
|
|
52
|
+
}
|
|
53
|
+
return `${cssCdataStart}${css}${cssCdataEnd}`;
|
|
54
|
+
}
|
|
55
|
+
function isCssStyleType(node) {
|
|
56
|
+
if (!node.attrs || !('type' in node.attrs)) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
const rawType = node.attrs.type;
|
|
60
|
+
if (rawType === '') {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
if (typeof rawType !== 'string') {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const normalizedType = rawType.trim().toLowerCase();
|
|
67
|
+
return /^text\/css(?:$|\s*;)/.test(normalizedType);
|
|
68
|
+
}
|
|
69
|
+
function normalizeMimeType(value) {
|
|
70
|
+
const trimmed = value.trim();
|
|
71
|
+
if (!trimmed) {
|
|
72
|
+
return '';
|
|
73
|
+
}
|
|
74
|
+
const [mimeType] = trimmed.split(';');
|
|
75
|
+
return mimeType.trim().toLowerCase();
|
|
76
|
+
}
|
|
33
77
|
function isEventHandler(attributeName) {
|
|
34
78
|
return attributeName && attributeName.slice(0, 2).toLowerCase() === 'on' && attributeName.length >= 5;
|
|
35
79
|
}
|
|
@@ -60,4 +104,4 @@ async function optionalImport(moduleName) {
|
|
|
60
104
|
}
|
|
61
105
|
}
|
|
62
106
|
|
|
63
|
-
export { extractCssFromStyleNode, extractTextContentFromNode, isAmpBoilerplate, isComment, isConditionalComment, isEventHandler, isStyleNode, optionalImport };
|
|
107
|
+
export { extractCssFromStyleNode, extractTextContentFromNode, isAmpBoilerplate, isComment, isConditionalComment, isCssStyleType, isEventHandler, isStyleNode, normalizeMimeType, optionalImport, stripCssCdata, wrapCssCdata };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,18 +2,27 @@ import PostHTML from 'posthtml';
|
|
|
2
2
|
import { MinifyOptions } from 'terser';
|
|
3
3
|
import { Options } from 'cssnano';
|
|
4
4
|
import { Config } from 'svgo';
|
|
5
|
+
import { UserDefinedOptions } from 'purgecss';
|
|
5
6
|
|
|
6
7
|
type PostHTMLTreeLike = [PostHTML.Node] & PostHTML.NodeAPI & {
|
|
7
8
|
options?: {
|
|
8
9
|
quoteAllAttributes?: boolean | undefined;
|
|
10
|
+
quoteStyle?: 0 | 1 | 2 | undefined;
|
|
11
|
+
replaceQuote?: boolean | undefined;
|
|
9
12
|
} | undefined;
|
|
10
13
|
render(): string;
|
|
11
14
|
render(node: PostHTML.Node | PostHTMLTreeLike, renderOptions?: any): string;
|
|
12
15
|
};
|
|
13
16
|
type MaybeArray<T> = T | Array<T>;
|
|
14
17
|
type PostHTMLNodeLike = PostHTML.Node | string;
|
|
18
|
+
type HtmlnanoTemplateRule = {
|
|
19
|
+
tag: string;
|
|
20
|
+
attrs?: Record<string, string | boolean | void>;
|
|
21
|
+
};
|
|
22
|
+
type MinifyHtmlTemplateOptions = boolean | HtmlnanoTemplateRule[];
|
|
15
23
|
interface HtmlnanoOptions {
|
|
16
24
|
skipConfigLoading?: boolean;
|
|
25
|
+
configPath?: string;
|
|
17
26
|
skipInternalWarnings?: boolean;
|
|
18
27
|
collapseAttributeWhitespace?: boolean;
|
|
19
28
|
collapseBooleanAttributes?: {
|
|
@@ -26,25 +35,50 @@ interface HtmlnanoOptions {
|
|
|
26
35
|
mergeStyles?: boolean;
|
|
27
36
|
mergeScripts?: boolean;
|
|
28
37
|
minifyCss?: Options | boolean;
|
|
38
|
+
minifyHtmlTemplate?: MinifyHtmlTemplateOptions;
|
|
29
39
|
minifyConditionalComments?: boolean;
|
|
30
40
|
minifyJs?: MinifyOptions | boolean;
|
|
31
41
|
minifyJson?: boolean;
|
|
42
|
+
minifyAttributes?: boolean | {
|
|
43
|
+
metaContent?: boolean;
|
|
44
|
+
redundantWhitespaces?: 'safe' | 'agressive' | false;
|
|
45
|
+
};
|
|
32
46
|
minifySvg?: Config | boolean;
|
|
33
47
|
normalizeAttributeValues?: boolean;
|
|
34
|
-
removeAttributeQuotes?: boolean
|
|
35
|
-
|
|
48
|
+
removeAttributeQuotes?: boolean | {
|
|
49
|
+
force?: boolean;
|
|
50
|
+
};
|
|
51
|
+
removeComments?: boolean | RegExp | ((comment: string) => boolean) | string;
|
|
36
52
|
removeEmptyAttributes?: boolean;
|
|
53
|
+
removeEmptyElements?: boolean | {
|
|
54
|
+
removeWithAttributes?: boolean;
|
|
55
|
+
};
|
|
37
56
|
removeRedundantAttributes?: boolean;
|
|
38
57
|
removeOptionalTags?: boolean;
|
|
39
|
-
removeUnusedCss?: boolean
|
|
58
|
+
removeUnusedCss?: boolean | ({
|
|
59
|
+
tool: 'purgeCSS';
|
|
60
|
+
} & Omit<UserDefinedOptions, 'content' | 'css' | 'extractors'>) | {
|
|
61
|
+
banner?: boolean;
|
|
62
|
+
csspath?: string;
|
|
63
|
+
htmlroot?: string;
|
|
64
|
+
ignore?: (string | RegExp)[];
|
|
65
|
+
inject?: string;
|
|
66
|
+
jsdom?: object;
|
|
67
|
+
media?: string[];
|
|
68
|
+
report?: boolean;
|
|
69
|
+
strictSSL?: boolean;
|
|
70
|
+
timeout?: number;
|
|
71
|
+
uncssrc?: string;
|
|
72
|
+
userAgent?: string;
|
|
73
|
+
};
|
|
40
74
|
sortAttributes?: boolean | 'alphabetical' | 'frequency';
|
|
41
75
|
sortAttributesWithLists?: boolean | 'alphabetical' | 'frequency';
|
|
42
76
|
}
|
|
43
|
-
interface HtmlnanoPreset extends Omit<HtmlnanoOptions, 'skipConfigLoading'> {
|
|
77
|
+
interface HtmlnanoPreset extends Omit<HtmlnanoOptions, 'skipConfigLoading' | 'configPath'> {
|
|
44
78
|
}
|
|
45
79
|
type HtmlnanoPredefinedPreset = 'safe' | 'ampSafe' | 'max';
|
|
46
80
|
type HtmlnanoPredefinedPresets = Record<HtmlnanoPredefinedPreset, HtmlnanoPreset>;
|
|
47
|
-
type HtmlnanoOptionsConfigFile = Omit<HtmlnanoOptions, 'skipConfigLoading'> & {
|
|
81
|
+
type HtmlnanoOptionsConfigFile = Omit<HtmlnanoOptions, 'skipConfigLoading' | 'configPath'> & {
|
|
48
82
|
preset?: HtmlnanoPredefinedPreset;
|
|
49
83
|
};
|
|
50
84
|
type HtmlnanoModuleAttrsHandler = (attrs: Record<string, string | boolean | void>, node: PostHTML.Node) => Record<string, string | boolean | void>;
|
|
@@ -58,7 +92,8 @@ type HtmlnanoModule<Options = any> = {
|
|
|
58
92
|
default?: (tree: PostHTMLTreeLike, options: Partial<HtmlnanoOptions>, moduleOptions: OptionalOptions<Options>) => PostHTMLTreeLike | Promise<PostHTMLTreeLike>;
|
|
59
93
|
};
|
|
60
94
|
|
|
61
|
-
declare
|
|
95
|
+
declare const presets: HtmlnanoPredefinedPresets;
|
|
96
|
+
declare function loadConfig(options?: HtmlnanoOptions, preset?: HtmlnanoPreset): [Partial<HtmlnanoOptions>, HtmlnanoPreset];
|
|
62
97
|
declare const htmlnano: ((optionsRun?: HtmlnanoOptions, presetRun?: HtmlnanoPreset) => PostHTML.Plugin<never>) & {
|
|
63
98
|
presets: HtmlnanoPredefinedPresets;
|
|
64
99
|
getRequiredOptionalDependencies: typeof getRequiredOptionalDependencies;
|
|
@@ -74,5 +109,5 @@ declare function htmlMinimizerWebpackPluginMinify(input: {
|
|
|
74
109
|
code: string;
|
|
75
110
|
}>;
|
|
76
111
|
|
|
77
|
-
export { htmlnano as default, getRequiredOptionalDependencies, htmlMinimizerWebpackPluginMinify, loadConfig, process };
|
|
78
|
-
export type { HtmlnanoModule, HtmlnanoModuleAttrsHandler, HtmlnanoModuleContentHandler, HtmlnanoModuleNodeHandler, HtmlnanoOptions, HtmlnanoOptionsConfigFile, HtmlnanoPredefinedPreset, HtmlnanoPredefinedPresets, HtmlnanoPreset, PostHTMLNodeLike, PostHTMLTreeLike };
|
|
112
|
+
export { htmlnano as default, getRequiredOptionalDependencies, htmlMinimizerWebpackPluginMinify, loadConfig, presets, process };
|
|
113
|
+
export type { HtmlnanoModule, HtmlnanoModuleAttrsHandler, HtmlnanoModuleContentHandler, HtmlnanoModuleNodeHandler, HtmlnanoOptions, HtmlnanoOptionsConfigFile, HtmlnanoPredefinedPreset, HtmlnanoPredefinedPresets, HtmlnanoPreset, HtmlnanoTemplateRule, MinifyHtmlTemplateOptions, PostHTMLNodeLike, PostHTMLTreeLike };
|
package/dist/index.js
CHANGED
|
@@ -18,8 +18,8 @@ const presets = {
|
|
|
18
18
|
ampSafe: ampSafePreset__default.default,
|
|
19
19
|
max: maxPreset__default.default
|
|
20
20
|
};
|
|
21
|
-
function loadConfig(options, preset
|
|
22
|
-
const { skipConfigLoading = false, ...rest } = options || {};
|
|
21
|
+
function loadConfig(options, preset) {
|
|
22
|
+
const { skipConfigLoading = false, configPath, ...rest } = options || {};
|
|
23
23
|
let restConfig = rest;
|
|
24
24
|
if (!skipConfigLoading) {
|
|
25
25
|
const explorer = cosmiconfig.cosmiconfigSync('htmlnano');
|
|
@@ -32,9 +32,10 @@ function loadConfig(options, preset, configPath) {
|
|
|
32
32
|
}
|
|
33
33
|
delete rc.config.preset;
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
restConfig = {
|
|
36
|
+
...rc.config,
|
|
37
|
+
...restConfig
|
|
38
|
+
};
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
return [
|
|
@@ -124,14 +125,17 @@ const modules = {
|
|
|
124
125
|
mergeStyles: ()=>interop(import('./_modules/mergeStyles.js')),
|
|
125
126
|
minifyConditionalComments: ()=>interop(import('./_modules/minifyConditionalComments.js')),
|
|
126
127
|
minifyCss: ()=>interop(import('./_modules/minifyCss.js')),
|
|
128
|
+
minifyHtmlTemplate: ()=>interop(import('./_modules/minifyHtmlTemplate.js')),
|
|
127
129
|
minifyJs: ()=>interop(import('./_modules/minifyJs.js')),
|
|
128
130
|
minifyJson: ()=>interop(import('./_modules/minifyJson.js')),
|
|
131
|
+
minifyAttributes: ()=>interop(import('./_modules/minifyAttributes.js')),
|
|
129
132
|
minifySvg: ()=>interop(import('./_modules/minifySvg.js')),
|
|
130
133
|
minifyUrls: ()=>interop(import('./_modules/minifyUrls.js')),
|
|
131
134
|
normalizeAttributeValues: ()=>interop(import('./_modules/normalizeAttributeValues.js')),
|
|
132
135
|
removeAttributeQuotes: ()=>interop(import('./_modules/removeAttributeQuotes.js')),
|
|
133
136
|
removeComments: ()=>interop(import('./_modules/removeComments.js')),
|
|
134
137
|
removeEmptyAttributes: ()=>interop(import('./_modules/removeEmptyAttributes.js')),
|
|
138
|
+
removeEmptyElements: ()=>interop(import('./_modules/removeEmptyElements.js')),
|
|
135
139
|
removeOptionalTags: ()=>interop(import('./_modules/removeOptionalTags.js')),
|
|
136
140
|
removeRedundantAttributes: ()=>interop(import('./_modules/removeRedundantAttributes.js')),
|
|
137
141
|
removeUnusedCss: ()=>interop(import('./_modules/removeUnusedCss.js')),
|
|
@@ -151,7 +155,13 @@ const htmlnano = Object.assign(function htmlnano(optionsRun = {}, presetRun) {
|
|
|
151
155
|
...options
|
|
152
156
|
};
|
|
153
157
|
let promise = Promise.resolve(tree);
|
|
158
|
+
const nonModuleOptions = new Set([
|
|
159
|
+
'skipInternalWarnings'
|
|
160
|
+
]);
|
|
154
161
|
for (const [moduleName, moduleOptions] of Object.entries(options)){
|
|
162
|
+
if (nonModuleOptions.has(moduleName)) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
155
165
|
if (!moduleOptions) {
|
|
156
166
|
continue;
|
|
157
167
|
}
|
|
@@ -178,15 +188,19 @@ const htmlnano = Object.assign(function htmlnano(optionsRun = {}, presetRun) {
|
|
|
178
188
|
}
|
|
179
189
|
const mod = moduleName in modules ? await modules[moduleName]() : await import(`./_modules/${moduleName}.mjs`);
|
|
180
190
|
if (typeof mod.onAttrs === 'function') {
|
|
191
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- module options are generic
|
|
181
192
|
attrsHandlers.push(mod.onAttrs(options, moduleOptions));
|
|
182
193
|
}
|
|
183
194
|
if (typeof mod.onContent === 'function') {
|
|
195
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- module options are generic
|
|
184
196
|
contentsHandlers.push(mod.onContent(options, moduleOptions));
|
|
185
197
|
}
|
|
186
198
|
if (typeof mod.onNode === 'function') {
|
|
199
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- module options are generic
|
|
187
200
|
nodeHandlers.push(mod.onNode(options, moduleOptions));
|
|
188
201
|
}
|
|
189
202
|
if (typeof mod.default === 'function') {
|
|
203
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- module options are generic
|
|
190
204
|
promise = promise.then(async (tree)=>await mod.default(tree, options, moduleOptions));
|
|
191
205
|
}
|
|
192
206
|
}
|
|
@@ -273,4 +287,5 @@ exports.default = htmlnano;
|
|
|
273
287
|
exports.getRequiredOptionalDependencies = getRequiredOptionalDependencies;
|
|
274
288
|
exports.htmlMinimizerWebpackPluginMinify = htmlMinimizerWebpackPluginMinify;
|
|
275
289
|
exports.loadConfig = loadConfig;
|
|
290
|
+
exports.presets = presets;
|
|
276
291
|
exports.process = process;
|
package/dist/index.mjs
CHANGED
|
@@ -9,8 +9,8 @@ const presets = {
|
|
|
9
9
|
ampSafe: ampSafePreset,
|
|
10
10
|
max: maxPreset
|
|
11
11
|
};
|
|
12
|
-
function loadConfig(options, preset
|
|
13
|
-
const { skipConfigLoading = false, ...rest } = options || {};
|
|
12
|
+
function loadConfig(options, preset) {
|
|
13
|
+
const { skipConfigLoading = false, configPath, ...rest } = options || {};
|
|
14
14
|
let restConfig = rest;
|
|
15
15
|
if (!skipConfigLoading) {
|
|
16
16
|
const explorer = cosmiconfigSync('htmlnano');
|
|
@@ -23,9 +23,10 @@ function loadConfig(options, preset, configPath) {
|
|
|
23
23
|
}
|
|
24
24
|
delete rc.config.preset;
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
restConfig = {
|
|
27
|
+
...rc.config,
|
|
28
|
+
...restConfig
|
|
29
|
+
};
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
return [
|
|
@@ -115,14 +116,17 @@ const modules = {
|
|
|
115
116
|
mergeStyles: ()=>interop(import('./_modules/mergeStyles.mjs')),
|
|
116
117
|
minifyConditionalComments: ()=>interop(import('./_modules/minifyConditionalComments.mjs')),
|
|
117
118
|
minifyCss: ()=>interop(import('./_modules/minifyCss.mjs')),
|
|
119
|
+
minifyHtmlTemplate: ()=>interop(import('./_modules/minifyHtmlTemplate.mjs')),
|
|
118
120
|
minifyJs: ()=>interop(import('./_modules/minifyJs.mjs')),
|
|
119
121
|
minifyJson: ()=>interop(import('./_modules/minifyJson.mjs')),
|
|
122
|
+
minifyAttributes: ()=>interop(import('./_modules/minifyAttributes.mjs')),
|
|
120
123
|
minifySvg: ()=>interop(import('./_modules/minifySvg.mjs')),
|
|
121
124
|
minifyUrls: ()=>interop(import('./_modules/minifyUrls.mjs')),
|
|
122
125
|
normalizeAttributeValues: ()=>interop(import('./_modules/normalizeAttributeValues.mjs')),
|
|
123
126
|
removeAttributeQuotes: ()=>interop(import('./_modules/removeAttributeQuotes.mjs')),
|
|
124
127
|
removeComments: ()=>interop(import('./_modules/removeComments.mjs')),
|
|
125
128
|
removeEmptyAttributes: ()=>interop(import('./_modules/removeEmptyAttributes.mjs')),
|
|
129
|
+
removeEmptyElements: ()=>interop(import('./_modules/removeEmptyElements.mjs')),
|
|
126
130
|
removeOptionalTags: ()=>interop(import('./_modules/removeOptionalTags.mjs')),
|
|
127
131
|
removeRedundantAttributes: ()=>interop(import('./_modules/removeRedundantAttributes.mjs')),
|
|
128
132
|
removeUnusedCss: ()=>interop(import('./_modules/removeUnusedCss.mjs')),
|
|
@@ -142,7 +146,13 @@ const htmlnano = Object.assign(function htmlnano(optionsRun = {}, presetRun) {
|
|
|
142
146
|
...options
|
|
143
147
|
};
|
|
144
148
|
let promise = Promise.resolve(tree);
|
|
149
|
+
const nonModuleOptions = new Set([
|
|
150
|
+
'skipInternalWarnings'
|
|
151
|
+
]);
|
|
145
152
|
for (const [moduleName, moduleOptions] of Object.entries(options)){
|
|
153
|
+
if (nonModuleOptions.has(moduleName)) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
146
156
|
if (!moduleOptions) {
|
|
147
157
|
continue;
|
|
148
158
|
}
|
|
@@ -169,15 +179,19 @@ const htmlnano = Object.assign(function htmlnano(optionsRun = {}, presetRun) {
|
|
|
169
179
|
}
|
|
170
180
|
const mod = moduleName in modules ? await modules[moduleName]() : await import(`./_modules/${moduleName}.mjs`);
|
|
171
181
|
if (typeof mod.onAttrs === 'function') {
|
|
182
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- module options are generic
|
|
172
183
|
attrsHandlers.push(mod.onAttrs(options, moduleOptions));
|
|
173
184
|
}
|
|
174
185
|
if (typeof mod.onContent === 'function') {
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- module options are generic
|
|
175
187
|
contentsHandlers.push(mod.onContent(options, moduleOptions));
|
|
176
188
|
}
|
|
177
189
|
if (typeof mod.onNode === 'function') {
|
|
190
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- module options are generic
|
|
178
191
|
nodeHandlers.push(mod.onNode(options, moduleOptions));
|
|
179
192
|
}
|
|
180
193
|
if (typeof mod.default === 'function') {
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- module options are generic
|
|
181
195
|
promise = promise.then(async (tree)=>await mod.default(tree, options, moduleOptions));
|
|
182
196
|
}
|
|
183
197
|
}
|
|
@@ -260,4 +274,4 @@ if (typeof module !== 'undefined') {
|
|
|
260
274
|
module.exports = htmlnano;
|
|
261
275
|
}
|
|
262
276
|
|
|
263
|
-
export { htmlnano as default, getRequiredOptionalDependencies, htmlMinimizerWebpackPluginMinify, loadConfig, process };
|
|
277
|
+
export { htmlnano as default, getRequiredOptionalDependencies, htmlMinimizerWebpackPluginMinify, loadConfig, presets, process };
|
|
@@ -2,17 +2,26 @@ import PostHTML from 'posthtml';
|
|
|
2
2
|
import { MinifyOptions } from 'terser';
|
|
3
3
|
import { Options } from 'cssnano';
|
|
4
4
|
import { Config } from 'svgo';
|
|
5
|
+
import { UserDefinedOptions } from 'purgecss';
|
|
5
6
|
|
|
6
7
|
type PostHTMLTreeLike = [PostHTML.Node] & PostHTML.NodeAPI & {
|
|
7
8
|
options?: {
|
|
8
9
|
quoteAllAttributes?: boolean | undefined;
|
|
10
|
+
quoteStyle?: 0 | 1 | 2 | undefined;
|
|
11
|
+
replaceQuote?: boolean | undefined;
|
|
9
12
|
} | undefined;
|
|
10
13
|
render(): string;
|
|
11
14
|
render(node: PostHTML.Node | PostHTMLTreeLike, renderOptions?: any): string;
|
|
12
15
|
};
|
|
13
16
|
type MaybeArray<T> = T | Array<T>;
|
|
17
|
+
type HtmlnanoTemplateRule = {
|
|
18
|
+
tag: string;
|
|
19
|
+
attrs?: Record<string, string | boolean | void>;
|
|
20
|
+
};
|
|
21
|
+
type MinifyHtmlTemplateOptions = boolean | HtmlnanoTemplateRule[];
|
|
14
22
|
interface HtmlnanoOptions {
|
|
15
23
|
skipConfigLoading?: boolean;
|
|
24
|
+
configPath?: string;
|
|
16
25
|
skipInternalWarnings?: boolean;
|
|
17
26
|
collapseAttributeWhitespace?: boolean;
|
|
18
27
|
collapseBooleanAttributes?: {
|
|
@@ -25,21 +34,46 @@ interface HtmlnanoOptions {
|
|
|
25
34
|
mergeStyles?: boolean;
|
|
26
35
|
mergeScripts?: boolean;
|
|
27
36
|
minifyCss?: Options | boolean;
|
|
37
|
+
minifyHtmlTemplate?: MinifyHtmlTemplateOptions;
|
|
28
38
|
minifyConditionalComments?: boolean;
|
|
29
39
|
minifyJs?: MinifyOptions | boolean;
|
|
30
40
|
minifyJson?: boolean;
|
|
41
|
+
minifyAttributes?: boolean | {
|
|
42
|
+
metaContent?: boolean;
|
|
43
|
+
redundantWhitespaces?: 'safe' | 'agressive' | false;
|
|
44
|
+
};
|
|
31
45
|
minifySvg?: Config | boolean;
|
|
32
46
|
normalizeAttributeValues?: boolean;
|
|
33
|
-
removeAttributeQuotes?: boolean
|
|
34
|
-
|
|
47
|
+
removeAttributeQuotes?: boolean | {
|
|
48
|
+
force?: boolean;
|
|
49
|
+
};
|
|
50
|
+
removeComments?: boolean | RegExp | ((comment: string) => boolean) | string;
|
|
35
51
|
removeEmptyAttributes?: boolean;
|
|
52
|
+
removeEmptyElements?: boolean | {
|
|
53
|
+
removeWithAttributes?: boolean;
|
|
54
|
+
};
|
|
36
55
|
removeRedundantAttributes?: boolean;
|
|
37
56
|
removeOptionalTags?: boolean;
|
|
38
|
-
removeUnusedCss?: boolean
|
|
57
|
+
removeUnusedCss?: boolean | ({
|
|
58
|
+
tool: 'purgeCSS';
|
|
59
|
+
} & Omit<UserDefinedOptions, 'content' | 'css' | 'extractors'>) | {
|
|
60
|
+
banner?: boolean;
|
|
61
|
+
csspath?: string;
|
|
62
|
+
htmlroot?: string;
|
|
63
|
+
ignore?: (string | RegExp)[];
|
|
64
|
+
inject?: string;
|
|
65
|
+
jsdom?: object;
|
|
66
|
+
media?: string[];
|
|
67
|
+
report?: boolean;
|
|
68
|
+
strictSSL?: boolean;
|
|
69
|
+
timeout?: number;
|
|
70
|
+
uncssrc?: string;
|
|
71
|
+
userAgent?: string;
|
|
72
|
+
};
|
|
39
73
|
sortAttributes?: boolean | 'alphabetical' | 'frequency';
|
|
40
74
|
sortAttributesWithLists?: boolean | 'alphabetical' | 'frequency';
|
|
41
75
|
}
|
|
42
|
-
interface HtmlnanoPreset extends Omit<HtmlnanoOptions, 'skipConfigLoading'> {
|
|
76
|
+
interface HtmlnanoPreset extends Omit<HtmlnanoOptions, 'skipConfigLoading' | 'configPath'> {
|
|
43
77
|
}
|
|
44
78
|
|
|
45
79
|
declare const _default: HtmlnanoPreset;
|