parsley/config/webpack/loaders/iconic_svg_loader.js

84 lines
2.0 KiB
JavaScript
Raw Normal View History

2018-09-10 17:25:36 -05:00
const cheerio = require('cheerio');
const iriElementsAndProperties = {
'clipPath': ['clip-path'],
'color-profile': ['color-profile'],
'cursor': ['cursor'],
'filter': ['filter'],
'linearGradient': ['fill', 'stroke'],
'marker': ['marker', 'marker-start', 'marker-mid', 'marker-end'],
'mask': ['mask'],
'pattern': ['fill', 'stroke'],
'radialGradient': ['fill', 'stroke']
};
module.exports = function(content) {
2018-09-10 17:25:36 -05:00
this.cacheable && this.cacheable();
const $ = cheerio.load(content, {
xmlMode: true,
2018-09-10 17:25:36 -05:00
lowerCaseTags: false
});
let idReplacements = [];
for(let element in iriElementsAndProperties) {
let properties = iriElementsAndProperties[element];
$(`svg defs ${element}[id]`).each(function() {
const $elem = $(this);
const id = $elem.attr("id");
const newId = `__ICONIC_SVG_REPLACEMENT_${idReplacements.length}`;
idReplacements.push(newId);
$elem.attr("id", newId);
for (let property of properties) {
$(`svg *[${property}="url(#${id})"]`).each(function() {
const $elem = $(this);
$elem.attr(property, `url(#${newId})`);
})
}
})
}
const $svg = $("svg");
let iconName = $svg.attr("data-icon");
if (!iconName) {
const match = $svg.attr("class").match(/iconic-([a-z\-]+)/);
if (match) {
$svg.attr("data-icon", match[1]);
} else {
throw "Can't parse class into data-icon";
}
}
const scriptBlocks = [];
// Find then prune the scripts
$("svg script").each(function() {
const $script = $(this);
const scriptType = $script.attr("type");
if (!scriptType || scriptType === 'application/ecmascript' || scriptType === 'application/javascript') {
scriptBlocks.push($script.html());
}
});
$("svg script").remove();
const attributes = $svg.get(0).attribs;
const svgMarkup = $("svg").html();
2018-09-10 17:25:36 -05:00
return `module.exports = ${JSON.stringify({
attributes: attributes,
content: svgMarkup,
idReplacements: idReplacements,
scriptBlocks: scriptBlocks
})}`;
};