"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; exports.loadConfig = loadConfig; var _posthtml = _interopRequireDefault(require("posthtml")); var _cosmiconfig = require("cosmiconfig"); var _safe = _interopRequireDefault(require("./presets/safe.cjs")); var _ampSafe = _interopRequireDefault(require("./presets/ampSafe.cjs")); var _max = _interopRequireDefault(require("./presets/max.cjs")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function __transformExtension(filepath, extMapping) { if (!filepath.startsWith('./') && !filepath.startsWith('../')) { // Package import return filepath; } const idx = filepath.lastIndexOf('.'); if (idx === -1 || filepath.includes('/', idx)) { // No extension const newExt = extMapping['']; if (newExt) { return filepath + newExt; } return filepath; } for (let [origExt, newExt] of Object.entries(extMapping).sort((a, b) => b[0].length - a[0].length)) { if (filepath.endsWith(origExt)) { return filepath.slice(0, -origExt.length) + newExt; } } return filepath; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } const presets = { safe: _safe.default, ampSafe: _ampSafe.default, max: _max.default }; function loadConfig(options, preset, configPath) { let { skipConfigLoading = false, ...rest } = options || {}; if (!skipConfigLoading) { const explorer = (0, _cosmiconfig.cosmiconfigSync)('htmlnano'); const rc = configPath ? explorer.load(configPath) : explorer.search(); if (rc) { const { preset: presetName } = rc.config; if (presetName) { if (!preset && presets[presetName]) { preset = presets[presetName]; } delete rc.config.preset; } if (!options) { rest = rc.config; } } } return [rest || {}, preset || _safe.default]; } const optionalDependencies = { minifyCss: ['cssnano', 'postcss'], minifyJs: ['terser'], minifyUrl: ['relateurl', 'srcset', 'terser'], minifySvg: ['svgo'] }; const modules = { collapseAttributeWhitespace: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/collapseAttributeWhitespace.cjs"))), collapseBooleanAttributes: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/collapseBooleanAttributes.cjs"))), collapseWhitespace: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/collapseWhitespace.cjs"))), custom: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/custom.cjs"))), deduplicateAttributeValues: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/deduplicateAttributeValues.cjs"))), example: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/example.cjs"))), mergeScripts: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/mergeScripts.cjs"))), mergeStyles: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/mergeStyles.cjs"))), minifyConditionalComments: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/minifyConditionalComments.cjs"))), minifyCss: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/minifyCss.cjs"))), minifyJs: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/minifyJs.cjs"))), minifyJson: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/minifyJson.cjs"))), minifySvg: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/minifySvg.cjs"))), minifyUrls: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/minifyUrls.cjs"))), normalizeAttributeValues: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/normalizeAttributeValues.cjs"))), removeAttributeQuotes: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/removeAttributeQuotes.cjs"))), removeComments: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/removeComments.cjs"))), removeEmptyAttributes: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/removeEmptyAttributes.cjs"))), removeOptionalTags: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/removeOptionalTags.cjs"))), removeRedundantAttributes: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/removeRedundantAttributes.cjs"))), removeUnusedCss: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/removeUnusedCss.cjs"))), sortAttributes: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/sortAttributes.cjs"))), sortAttributesWithLists: () => Promise.resolve().then(() => _interopRequireWildcard(require("./modules/sortAttributesWithLists.cjs"))) }; function htmlnano(optionsRun, presetRun) { let [options, preset] = loadConfig(optionsRun, presetRun); return async function minifier(tree) { const nodeHandlers = []; const attrsHandlers = []; const contentsHandlers = []; options = { ...preset, ...options }; let promise = Promise.resolve(tree); for (const [moduleName, moduleOptions] of Object.entries(options)) { if (!moduleOptions) { // The module is disabled continue; } if (_safe.default[moduleName] === undefined) { throw new Error('Module "' + moduleName + '" is not defined'); } (optionalDependencies[moduleName] || []).forEach(async dependency => { try { await (specifier => new Promise(r => r(`${specifier}`)).then(s => _interopRequireWildcard(require(s))))(__transformExtension(dependency, { ".mjs": ".cjs" })); } catch (e) { if (e.code === 'MODULE_NOT_FOUND' || e.code === 'ERR_MODULE_NOT_FOUND') { console.warn(`You have to install "${dependency}" in order to use htmlnano's "${moduleName}" module`); } else { throw e; } } }); const module = moduleName in modules ? await modules[moduleName]() : await (specifier => new Promise(r => r(`${specifier}`)).then(s => _interopRequireWildcard(require(s))))(__transformExtension(`./modules/${moduleName}.mjs`, { ".mjs": ".cjs" })); if (typeof module.onAttrs === 'function') { attrsHandlers.push(module.onAttrs(options, moduleOptions)); } if (typeof module.onContent === 'function') { contentsHandlers.push(module.onContent(options, moduleOptions)); } if (typeof module.onNode === 'function') { nodeHandlers.push(module.onNode(options, moduleOptions)); } if (typeof module.default === 'function') { promise = promise.then(async tree => await module.default(tree, options, moduleOptions)); } } if (attrsHandlers.length + contentsHandlers.length + nodeHandlers.length === 0) { return promise; } return promise.then(tree => { tree.walk(node => { if (node) { if (node.attrs && typeof node.attrs === 'object') { // Convert all attrs' key to lower case let newAttrsObj = {}; Object.entries(node.attrs).forEach(([attrName, attrValue]) => { newAttrsObj[attrName.toLowerCase()] = attrValue; }); for (const handler of attrsHandlers) { newAttrsObj = handler(newAttrsObj, node); } node.attrs = newAttrsObj; } if (node.content) { node.content = typeof node.content === 'string' ? [node.content] : node.content; if (Array.isArray(node.content) && node.content.length > 0) { for (const handler of contentsHandlers) { const result = handler(node.content, node); node.content = typeof result === 'string' ? [result] : result; } } } for (const handler of nodeHandlers) { node = handler(node); } } return node; }); return tree; }); }; } htmlnano.getRequiredOptionalDependencies = function (optionsRun, presetRun) { const [options] = loadConfig(optionsRun, presetRun); return [...new Set(Object.keys(options).filter(moduleName => options[moduleName]).map(moduleName => optionalDependencies[moduleName]).flat())]; }; htmlnano.process = function (html, options, preset, postHtmlOptions) { return (0, _posthtml.default)([htmlnano(options, preset)]).process(html, postHtmlOptions); }; // https://github.com/webpack-contrib/html-minimizer-webpack-plugin/blob/faca00f2219514bc671c5942685721f0b5dbaa70/src/utils.js#L74 htmlnano.htmlMinimizerWebpackPluginMinify = function htmlNano(input, minimizerOptions = {}) { const [[, code]] = Object.entries(input); return htmlnano.process(code, minimizerOptions, presets.safe).then(result => { return { code: result.html }; }); }; htmlnano.presets = presets; var _default = exports.default = htmlnano;