htmlnano 2.0.4 → 2.1.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/.eslintignore +3 -2
- package/CHANGELOG.md +19 -0
- package/docs/docs/040-presets.md +4 -4
- package/docs/docs/050-modules.md +1 -1
- package/docs/docs/060-contribute.md +1 -1
- package/docs/docusaurus.config.js +5 -0
- package/docs/package-lock.json +563 -326
- package/docs/package.json +1 -0
- package/docs/versioned_docs/version-1.1.1/040-presets.md +4 -4
- package/docs/versioned_docs/version-1.1.1/050-modules.md +1 -2
- package/docs/versioned_docs/version-1.1.1/060-contribute.md +1 -1
- package/docs/versioned_docs/version-2.0.0/040-presets.md +4 -4
- package/docs/versioned_docs/version-2.0.0/050-modules.md +1 -1
- package/docs/versioned_docs/version-2.0.0/060-contribute.md +1 -1
- package/index.cjs +11 -0
- package/index.d.cts +3 -0
- package/index.d.mts +3 -0
- package/index.d.ts +3 -3
- package/index.mjs +2 -0
- package/lib/helpers.cjs +79 -0
- package/lib/helpers.mjs +53 -0
- package/lib/htmlnano.cjs +200 -0
- package/lib/htmlnano.mjs +196 -0
- package/lib/modules/{collapseAttributeWhitespace.js → collapseAttributeWhitespace.cjs} +2 -3
- package/lib/modules/collapseAttributeWhitespace.mjs +104 -0
- package/lib/modules/collapseBooleanAttributes.mjs +175 -0
- package/lib/modules/{collapseWhitespace.js → collapseWhitespace.cjs} +3 -2
- package/lib/modules/collapseWhitespace.mjs +132 -0
- package/lib/modules/custom.mjs +16 -0
- package/lib/modules/{deduplicateAttributeValues.js → deduplicateAttributeValues.cjs} +1 -1
- package/lib/modules/deduplicateAttributeValues.mjs +40 -0
- package/lib/modules/example.cjs +85 -0
- package/lib/modules/example.mjs +75 -0
- package/lib/modules/mergeScripts.mjs +56 -0
- package/lib/modules/{mergeStyles.js → mergeStyles.cjs} +1 -1
- package/lib/modules/mergeStyles.mjs +36 -0
- package/lib/modules/{minifyConditionalComments.js → minifyConditionalComments.cjs} +2 -2
- package/lib/modules/minifyConditionalComments.mjs +49 -0
- package/lib/modules/{minifyCss.js → minifyCss.cjs} +8 -8
- package/lib/modules/minifyCss.mjs +88 -0
- package/lib/modules/{minifyJs.js → minifyJs.cjs} +8 -9
- package/lib/modules/minifyJs.mjs +121 -0
- package/lib/modules/minifyJson.mjs +21 -0
- package/lib/modules/{minifySvg.js → minifySvg.cjs} +3 -4
- package/lib/modules/minifySvg.mjs +30 -0
- package/lib/modules/{minifyUrls.js → minifyUrls.cjs} +11 -12
- package/lib/modules/minifyUrls.mjs +229 -0
- package/lib/modules/normalizeAttributeValues.mjs +140 -0
- package/lib/modules/removeAttributeQuotes.mjs +12 -0
- package/lib/modules/{removeComments.js → removeComments.cjs} +1 -1
- package/lib/modules/removeComments.mjs +92 -0
- package/lib/modules/{removeEmptyAttributes.js → removeEmptyAttributes.cjs} +1 -1
- package/lib/modules/removeEmptyAttributes.mjs +121 -0
- package/lib/modules/{removeOptionalTags.js → removeOptionalTags.cjs} +1 -1
- package/lib/modules/removeOptionalTags.mjs +225 -0
- package/lib/modules/{removeRedundantAttributes.js → removeRedundantAttributes.cjs} +1 -2
- package/lib/modules/removeRedundantAttributes.mjs +141 -0
- package/lib/modules/{removeUnusedCss.js → removeUnusedCss.cjs} +12 -13
- package/lib/modules/removeUnusedCss.mjs +122 -0
- package/lib/modules/{sortAttributes.js → sortAttributes.cjs} +0 -1
- package/lib/modules/sortAttributes.mjs +121 -0
- package/lib/modules/{sortAttributesWithLists.js → sortAttributesWithLists.cjs} +1 -2
- package/lib/modules/sortAttributesWithLists.mjs +135 -0
- package/lib/presets/{ampSafe.js → ampSafe.cjs} +4 -9
- package/lib/presets/ampSafe.mjs +11 -0
- package/lib/presets/{max.js → max.cjs} +4 -9
- package/lib/presets/max.mjs +20 -0
- package/lib/presets/{safe.js → safe.cjs} +2 -3
- package/lib/presets/safe.mjs +65 -0
- package/package.json +40 -12
- package/index.js +0 -1
- package/lib/helpers.js +0 -53
- package/lib/htmlnano.js +0 -150
- /package/lib/modules/{collapseBooleanAttributes.js → collapseBooleanAttributes.cjs} +0 -0
- /package/lib/modules/{custom.js → custom.cjs} +0 -0
- /package/lib/modules/{mergeScripts.js → mergeScripts.cjs} +0 -0
- /package/lib/modules/{minifyJson.js → minifyJson.cjs} +0 -0
- /package/lib/modules/{normalizeAttributeValues.js → normalizeAttributeValues.cjs} +0 -0
- /package/lib/modules/{removeAttributeQuotes.js → removeAttributeQuotes.cjs} +0 -0
package/lib/helpers.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.extractCssFromStyleNode = extractCssFromStyleNode;
|
|
7
|
-
exports.isAmpBoilerplate = isAmpBoilerplate;
|
|
8
|
-
exports.isComment = isComment;
|
|
9
|
-
exports.isConditionalComment = isConditionalComment;
|
|
10
|
-
exports.isEventHandler = isEventHandler;
|
|
11
|
-
exports.isStyleNode = isStyleNode;
|
|
12
|
-
exports.optionalRequire = optionalRequire;
|
|
13
|
-
const ampBoilerplateAttributes = ['amp-boilerplate', 'amp4ads-boilerplate', 'amp4email-boilerplate'];
|
|
14
|
-
function isAmpBoilerplate(node) {
|
|
15
|
-
if (!node.attrs) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
for (const attr of ampBoilerplateAttributes) {
|
|
19
|
-
if (attr in node.attrs) {
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
function isComment(content) {
|
|
26
|
-
if (typeof content === 'string') {
|
|
27
|
-
return content.trim().startsWith('<!--');
|
|
28
|
-
}
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
function isConditionalComment(content) {
|
|
32
|
-
return (content || '').trim().startsWith('<!--[if');
|
|
33
|
-
}
|
|
34
|
-
function isStyleNode(node) {
|
|
35
|
-
return node.tag === 'style' && !isAmpBoilerplate(node) && 'content' in node && node.content.length > 0;
|
|
36
|
-
}
|
|
37
|
-
function extractCssFromStyleNode(node) {
|
|
38
|
-
return Array.isArray(node.content) ? node.content.join(' ') : node.content;
|
|
39
|
-
}
|
|
40
|
-
function isEventHandler(attributeName) {
|
|
41
|
-
return attributeName && attributeName.slice && attributeName.slice(0, 2).toLowerCase() === 'on' && attributeName.length >= 5;
|
|
42
|
-
}
|
|
43
|
-
function optionalRequire(moduleName) {
|
|
44
|
-
try {
|
|
45
|
-
const module = require(moduleName);
|
|
46
|
-
return module.default || module;
|
|
47
|
-
} catch (e) {
|
|
48
|
-
if (e.code === 'MODULE_NOT_FOUND') {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
throw e;
|
|
52
|
-
}
|
|
53
|
-
}
|
package/lib/htmlnano.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
exports.loadConfig = loadConfig;
|
|
8
|
-
var _posthtml = _interopRequireDefault(require("posthtml"));
|
|
9
|
-
var _cosmiconfig = require("cosmiconfig");
|
|
10
|
-
var _safe = _interopRequireDefault(require("./presets/safe"));
|
|
11
|
-
var _ampSafe = _interopRequireDefault(require("./presets/ampSafe"));
|
|
12
|
-
var _max = _interopRequireDefault(require("./presets/max"));
|
|
13
|
-
var _package = _interopRequireDefault(require("../package.json"));
|
|
14
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
const presets = {
|
|
16
|
-
safe: _safe.default,
|
|
17
|
-
ampSafe: _ampSafe.default,
|
|
18
|
-
max: _max.default
|
|
19
|
-
};
|
|
20
|
-
function loadConfig(options, preset, configPath) {
|
|
21
|
-
let {
|
|
22
|
-
skipConfigLoading = false,
|
|
23
|
-
...rest
|
|
24
|
-
} = options || {};
|
|
25
|
-
if (!skipConfigLoading) {
|
|
26
|
-
const explorer = (0, _cosmiconfig.cosmiconfigSync)(_package.default.name);
|
|
27
|
-
const rc = configPath ? explorer.load(configPath) : explorer.search();
|
|
28
|
-
if (rc) {
|
|
29
|
-
const {
|
|
30
|
-
preset: presetName
|
|
31
|
-
} = rc.config;
|
|
32
|
-
if (presetName) {
|
|
33
|
-
if (!preset && presets[presetName]) {
|
|
34
|
-
preset = presets[presetName];
|
|
35
|
-
}
|
|
36
|
-
delete rc.config.preset;
|
|
37
|
-
}
|
|
38
|
-
if (!options) {
|
|
39
|
-
rest = rc.config;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return [rest || {}, preset || _safe.default];
|
|
44
|
-
}
|
|
45
|
-
const optionalDependencies = {
|
|
46
|
-
minifyCss: ['cssnano', 'postcss'],
|
|
47
|
-
minifyJs: ['terser'],
|
|
48
|
-
minifyUrl: ['relateurl', 'srcset', 'terser'],
|
|
49
|
-
minifySvg: ['svgo']
|
|
50
|
-
};
|
|
51
|
-
function htmlnano(optionsRun, presetRun) {
|
|
52
|
-
let [options, preset] = loadConfig(optionsRun, presetRun);
|
|
53
|
-
return function minifier(tree) {
|
|
54
|
-
const nodeHandlers = [];
|
|
55
|
-
const attrsHandlers = [];
|
|
56
|
-
const contentsHandlers = [];
|
|
57
|
-
options = {
|
|
58
|
-
...preset,
|
|
59
|
-
...options
|
|
60
|
-
};
|
|
61
|
-
let promise = Promise.resolve(tree);
|
|
62
|
-
for (const [moduleName, moduleOptions] of Object.entries(options)) {
|
|
63
|
-
if (!moduleOptions) {
|
|
64
|
-
// The module is disabled
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
if (_safe.default[moduleName] === undefined) {
|
|
68
|
-
throw new Error('Module "' + moduleName + '" is not defined');
|
|
69
|
-
}
|
|
70
|
-
(optionalDependencies[moduleName] || []).forEach(dependency => {
|
|
71
|
-
try {
|
|
72
|
-
require(dependency);
|
|
73
|
-
} catch (e) {
|
|
74
|
-
if (e.code === 'MODULE_NOT_FOUND') {
|
|
75
|
-
console.warn(`You have to install "${dependency}" in order to use htmlnano's "${moduleName}" module`);
|
|
76
|
-
} else {
|
|
77
|
-
throw e;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
const module = require('./modules/' + moduleName);
|
|
82
|
-
if (typeof module.onAttrs === 'function') {
|
|
83
|
-
attrsHandlers.push(module.onAttrs(options, moduleOptions));
|
|
84
|
-
}
|
|
85
|
-
if (typeof module.onContent === 'function') {
|
|
86
|
-
contentsHandlers.push(module.onContent(options, moduleOptions));
|
|
87
|
-
}
|
|
88
|
-
if (typeof module.onNode === 'function') {
|
|
89
|
-
nodeHandlers.push(module.onNode(options, moduleOptions));
|
|
90
|
-
}
|
|
91
|
-
if (typeof module.default === 'function') {
|
|
92
|
-
promise = promise.then(tree => module.default(tree, options, moduleOptions));
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (attrsHandlers.length + contentsHandlers.length + nodeHandlers.length === 0) {
|
|
96
|
-
return promise;
|
|
97
|
-
}
|
|
98
|
-
return promise.then(tree => {
|
|
99
|
-
tree.walk(node => {
|
|
100
|
-
if (node) {
|
|
101
|
-
if (node.attrs && typeof node.attrs === 'object') {
|
|
102
|
-
// Convert all attrs' key to lower case
|
|
103
|
-
let newAttrsObj = {};
|
|
104
|
-
Object.entries(node.attrs).forEach(([attrName, attrValue]) => {
|
|
105
|
-
newAttrsObj[attrName.toLowerCase()] = attrValue;
|
|
106
|
-
});
|
|
107
|
-
for (const handler of attrsHandlers) {
|
|
108
|
-
newAttrsObj = handler(newAttrsObj, node);
|
|
109
|
-
}
|
|
110
|
-
node.attrs = newAttrsObj;
|
|
111
|
-
}
|
|
112
|
-
if (node.content) {
|
|
113
|
-
node.content = typeof node.content === 'string' ? [node.content] : node.content;
|
|
114
|
-
if (Array.isArray(node.content) && node.content.length > 0) {
|
|
115
|
-
for (const handler of contentsHandlers) {
|
|
116
|
-
const result = handler(node.content, node);
|
|
117
|
-
node.content = typeof result === 'string' ? [result] : result;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
for (const handler of nodeHandlers) {
|
|
122
|
-
node = handler(node);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return node;
|
|
126
|
-
});
|
|
127
|
-
return tree;
|
|
128
|
-
});
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
htmlnano.getRequiredOptionalDependencies = function (optionsRun, presetRun) {
|
|
132
|
-
const [options] = loadConfig(optionsRun, presetRun);
|
|
133
|
-
return [...new Set(Object.keys(options).filter(moduleName => options[moduleName]).map(moduleName => optionalDependencies[moduleName]).flat())];
|
|
134
|
-
};
|
|
135
|
-
htmlnano.process = function (html, options, preset, postHtmlOptions) {
|
|
136
|
-
return (0, _posthtml.default)([htmlnano(options, preset)]).process(html, postHtmlOptions);
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
// https://github.com/webpack-contrib/html-minimizer-webpack-plugin/blob/faca00f2219514bc671c5942685721f0b5dbaa70/src/utils.js#L74
|
|
140
|
-
htmlnano.htmlMinimizerWebpackPluginMinify = function htmlNano(input, minimizerOptions = {}) {
|
|
141
|
-
const [[, code]] = Object.entries(input);
|
|
142
|
-
return htmlnano.process(code, minimizerOptions, presets.safe).then(result => {
|
|
143
|
-
return {
|
|
144
|
-
code: result.html
|
|
145
|
-
};
|
|
146
|
-
});
|
|
147
|
-
};
|
|
148
|
-
htmlnano.presets = presets;
|
|
149
|
-
var _default = htmlnano;
|
|
150
|
-
exports.default = _default;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|