fontawesome-svg-sprite-generator
Version:
Generate custom SVG sprites for a selected number of Font Awesome 5 icons
121 lines • 4.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const fontawesome_svg_core_1 = require("@fortawesome/fontawesome-svg-core");
/**
* Generates a SVG sprite for the selected icons.
*
* The first parameter may be either an object, mapping each icon to an
* (unique) ID, or an array (in which case an ID will be generated
* automatically for each icon).
*
* Icon selection generally works the same way as in the Font Awesome
* JS API. Check README of module for usage examples.
*
* @param {IconDescriptors} icons The icons to include in the sprite
* @param {Options} options Additional options
* @returns {Sprite} The generated SVG sprite
*
* @see {@link https://fontawesome.com/how-to-use/font-awesome-api#findicondefinition|findIconDefinition()}
* @see {@link https://fontawesome.com/how-to-use/font-awesome-api#icon|icon()}
*/
function generate(icons, options = {}) {
const symbols = prepareSymbols(icons);
return generateSprite(symbols, options);
}
exports.generate = generate;
function prepareSymbols(icons) {
if (Array.isArray(icons)) {
return icons
.map(icon => prepareSymbol(loadSymbol(icon)));
}
else {
return Object.entries(icons)
.map(([id, icon]) => prepareSymbol(loadSymbol(icon, id), id));
}
}
function loadSymbol(icon, id) {
if ('abstract' in icon) {
return icon;
}
const [lookup, params] = Array.isArray(icon) ? icon : [icon, {}];
// Ensure we generate a symbol with the specified id
params.symbol = params.symbol || id || true;
const result = fontawesome_svg_core_1.icon(lookup, params);
if (!result) {
throw new Error(`Failed to generate symbol for ${icon}`);
}
return result;
}
const ALLOWED_ATTRIBUTES = ['viewBox', 'aria-labelledby'];
function findTitle(symbol) {
const title = (symbol.children || []).find(e => e.tag === 'title');
return title && title.children + '';
}
function prepareSymbol(icon, customId) {
const abstract = icon.abstract;
if (abstract.length !== 1) {
throw new Error('Unexpected number of root elements:\n' + abstract.map(fontawesome_svg_core_1.toHtml).join('\n'));
}
const svg = abstract[0];
if (svg.tag !== 'svg') {
throw new Error(`Unexpected root tag: '${svg.tag}' (expected 'svg')`);
}
if (!svg.children) {
throw new Error('SVG has no children');
}
if (svg.children.length !== 1) {
throw new Error('Multiple elements included in SVG:\n' + svg.children.map(fontawesome_svg_core_1.toHtml).join('\n'));
}
const symbol = svg.children[0];
if (symbol.tag !== 'symbol') {
throw new Error(`Unexpected element in SVG: '${symbol.tag}' (expected 'symbol'). Did you set {symbol: true}?`);
}
const title = findTitle(symbol);
const originalAttributes = symbol.attributes;
const attributes = Object.assign({ class: originalAttributes.class + '', viewBox: originalAttributes.viewBox + '' }, (title && { title }));
const id = customId || '' + originalAttributes.id;
// Remove (mostly unneeded) attributes
symbol.attributes = { id };
// Add back allowed attributes
for (const attribute of ALLOWED_ATTRIBUTES) {
if (attribute in originalAttributes) {
symbol.attributes[attribute] = originalAttributes[attribute];
}
}
return { id, icon, symbol, attributes };
}
function generateSprite(symbols, options) {
const children = [];
const attributes = {};
for (const icon of symbols) {
if (icon.id in attributes) {
throw Error(`Duplicate symbol id '${icon.id}'`);
}
children.push(icon.symbol);
attributes[icon.id] = icon.attributes;
}
const abstract = {
tag: 'svg',
attributes: {
xmlns: 'http://www.w3.org/2000/svg'
},
children: children
};
return {
abstract,
svg: toSvg(abstract, options.xmlDeclaration, options.license),
symbols,
attributes
};
}
const XML_DECLARATION = '<?xml version="1.0" encoding="UTF-8"?>\n';
const LICENSE_FREE = `
Font Awesome Free by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
`;
function toSvg(abstract, includeXmlDeclaration = true, licenseText = LICENSE_FREE) {
const xmlDeclaration = includeXmlDeclaration ? XML_DECLARATION : '';
const license = licenseText ? '<!--' + licenseText + '-->\n' : '';
return xmlDeclaration + license + fontawesome_svg_core_1.toHtml(abstract);
}
//# sourceMappingURL=index.js.map