163 lines
4.9 KiB
JavaScript
163 lines
4.9 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
function _htmlnano() {
|
|
const data = _interopRequireDefault(require("htmlnano"));
|
|
_htmlnano = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _plugin() {
|
|
const data = require("@parcel/plugin");
|
|
_plugin = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _posthtml() {
|
|
const data = _interopRequireDefault(require("posthtml"));
|
|
_posthtml = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _path() {
|
|
const data = _interopRequireDefault(require("path"));
|
|
_path = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
var _svgMappings = require("./svgMappings");
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
var _default = exports.default = new (_plugin().Optimizer)({
|
|
async loadConfig({
|
|
config,
|
|
options
|
|
}) {
|
|
let userConfig = await config.getConfigFrom(_path().default.join(options.projectRoot, 'index.html'), ['.htmlnanorc', '.htmlnanorc.json', '.htmlnanorc.js', '.htmlnanorc.cjs', '.htmlnanorc.mjs', 'htmlnano.config.js', 'htmlnano.config.cjs', 'htmlnano.config.mjs'], {
|
|
packageKey: 'htmlnano'
|
|
});
|
|
return userConfig === null || userConfig === void 0 ? void 0 : userConfig.contents;
|
|
},
|
|
async optimize({
|
|
bundle,
|
|
contents,
|
|
map,
|
|
config
|
|
}) {
|
|
if (!bundle.env.shouldOptimize) {
|
|
return {
|
|
contents,
|
|
map
|
|
};
|
|
}
|
|
if (typeof contents !== 'string') {
|
|
throw new Error('HTMLNanoOptimizer: Only string contents are currently supported');
|
|
}
|
|
const clonedConfig = config || {};
|
|
|
|
// $FlowFixMe
|
|
const presets = _htmlnano().default.presets;
|
|
const preset = typeof clonedConfig.preset === 'string' ? presets[clonedConfig.preset] : {};
|
|
delete clonedConfig.preset;
|
|
const htmlNanoConfig = {
|
|
// Inline <script> and <style> elements, and style attributes are already
|
|
// minified before they are re-inserted by the packager.
|
|
minifyJs: false,
|
|
minifyCss: false,
|
|
minifySvg: {
|
|
plugins: [{
|
|
name: 'preset-default',
|
|
params: {
|
|
overrides: {
|
|
// Copied from htmlnano defaults.
|
|
collapseGroups: false,
|
|
convertShapeToPath: false,
|
|
// Additional defaults to preserve accessibility information.
|
|
removeTitle: false,
|
|
removeDesc: false,
|
|
removeUnknownsAndDefaults: {
|
|
keepAriaAttrs: true,
|
|
keepRoleAttr: true
|
|
},
|
|
// Do not minify ids or remove unreferenced elements in
|
|
// inline SVGs because they could actually be referenced
|
|
// by a separate inline SVG.
|
|
cleanupIDs: false
|
|
}
|
|
}
|
|
},
|
|
// XML namespaces are not required in HTML.
|
|
'removeXMLNS']
|
|
},
|
|
...(preset || {}),
|
|
...clonedConfig
|
|
// TODO: Uncomment this line once we update htmlnano, new version isn't out yet
|
|
// skipConfigLoading: true,
|
|
};
|
|
|
|
let plugins = [(0, _htmlnano().default)(htmlNanoConfig)];
|
|
|
|
// $FlowFixMe
|
|
if (htmlNanoConfig.minifySvg !== false) {
|
|
plugins.unshift(mapSVG);
|
|
}
|
|
return {
|
|
contents: (await (0, _posthtml().default)(plugins).process(contents, {
|
|
xmlMode: bundle.type === 'xhtml',
|
|
closingSingleTag: bundle.type === 'xhtml' ? 'slash' : undefined
|
|
})).html
|
|
};
|
|
}
|
|
}); // HTML tags and attributes are case insensitive. The HTML transformer normalizes them so it can
|
|
// more easily process any case. But SVGO requires case sensitive tags and attributes to work correctly.
|
|
// So map lowercased tag and attribute names back to their case-sensitive equivalents.
|
|
function mapSVG(node, inSVG = false) {
|
|
if (Array.isArray(node)) {
|
|
for (let i = 0; i < node.length; i++) {
|
|
// $FlowFixMe
|
|
node[i] = mapSVG(node[i], inSVG);
|
|
}
|
|
} else if (node && typeof node === 'object') {
|
|
let {
|
|
tag,
|
|
attrs
|
|
} = node;
|
|
|
|
// SVG in HTML does not require xml namespaces to be declared, but standalone SVG files do.
|
|
// If unset, add them here so that SVGO doesn't have parse errors.
|
|
if (tag === 'svg') {
|
|
if (!attrs) {
|
|
node.attrs = attrs = {};
|
|
}
|
|
if (!attrs.xmlns) {
|
|
attrs.xmlns = 'http://www.w3.org/2000/svg';
|
|
}
|
|
if (!attrs['xmlns:xlink']) {
|
|
attrs['xmlns:xlink'] = 'http://www.w3.org/1999/xlink';
|
|
}
|
|
}
|
|
if (inSVG || tag === 'svg') {
|
|
if (_svgMappings.SVG_TAG_NAMES[tag]) {
|
|
node.tag = _svgMappings.SVG_TAG_NAMES[tag];
|
|
}
|
|
if (attrs) {
|
|
for (let key in attrs) {
|
|
if (_svgMappings.SVG_ATTRS[key]) {
|
|
attrs[_svgMappings.SVG_ATTRS[key]] = attrs[key];
|
|
delete attrs[key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (node.content != null) {
|
|
mapSVG(node.content, inSVG || tag === 'svg');
|
|
}
|
|
}
|
|
return node;
|
|
} |