You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
2.6 KiB

const SVGO = require('svgo');
const { compile } = require('vue-template-compiler');
const transformChildren = (value) => {
const chilldren = value.reduce((acc, child) => {
if (child.text) {
acc.push(`_v('${child.text}')`);
} else {
const args = [`'${child.tag}'`];
if (Object.keys(child.attrsMap).length) {
const data = [];
if (child.staticClass) {
data.push(`staticClass:${child.staticClass}`);
}
if (child.staticStyle) {
data.push(`staticStyle:${child.staticStyle}`);
}
if (child.attrsList.length) {
const attrs = child.attrsList.reduce((v, attr) => ({
...v,
[attr.name]: attr.value,
}), {});
data.push(`attrs:${JSON.stringify(attrs)}`);
}
if (data.length) {
args.push(`{${data.join()}}`);
}
}
if (child.children.length) {
args.push(transformChildren(child.children));
}
acc.push(`_c(${args.join()})`);
}
return acc;
}, []);
return `[${chilldren.join()}]`;
};
const stringify = (value) => value.filter((item) => item).join();
module.exports = (content, options = {}) => {
const {
svgoConfig = {},
svgoPath = null,
} = options;
let svg = Promise.resolve(content);
if (svgoConfig !== false) {
svg = new SVGO(svgoConfig)
.optimize(content, { path: svgoPath })
.then((result) => result.data);
}
return svg.then((result) => {
const { ast } = compile(result, {
preserveWhitespace: false,
});
const children = ast.children.length
? `children.concat(${transformChildren(ast.children)})`
: 'children';
delete ast.attrsMap.class;
const attrs = Object.keys(ast.attrsMap).length
? `attrs: Object.assign(${JSON.stringify(ast.attrsMap)}, attrs)`
: 'attrs';
const classNames = stringify([ast.staticClass, 'classNames', 'staticClass']);
const styles = stringify([ast.staticStyle, 'style', 'staticStyle']);
return `
module.exports = {
functional: true,
render(_h, _vm) {
const { _c, _v, data, children = [] } = _vm;
const {
class: classNames,
staticClass,
style,
staticStyle,
attrs = {},
...rest
} = data;
return _c(
'svg',
{
class: [${classNames}],
style: [${styles}],
${attrs},
...rest,
},
${children}
)
}
}
`;
});
};