UNPKG

fabric

Version:

Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.

71 lines (65 loc) 2.28 kB
import type { CSSRules } from './typedefs'; /** * Returns CSS rules for a given SVG document * @param {HTMLElement} doc SVG document to parse * @return {Object} CSS rules of this document */ export function getCSSRules(doc: Document) { const styles = doc.getElementsByTagName('style'); let i; let len; const allRules: CSSRules = {}; // very crude parsing of style contents for (i = 0, len = styles.length; i < len; i++) { const styleContents = (styles[i].textContent || '').replace( // remove comments /\/\*[\s\S]*?\*\//g, '', ); if (styleContents.trim() === '') { continue; } // recovers all the rule in this form `body { style code... }` // rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g); styleContents .split('}') // remove empty rules and remove everything if we didn't split in at least 2 pieces .filter((rule, index, array) => array.length > 1 && rule.trim()) // at this point we have hopefully an array of rules `body { style code... ` .forEach((rule) => { // if there is more than one opening bracket and the rule starts with '@', it is likely // a nested at-rule like @media, @supports, @scope, etc. Ignore these as the code below // can not handle it. if ( (rule.match(/{/g) || []).length > 1 && rule.trim().startsWith('@') ) { return; } const match = rule.split('{'), ruleObj: Record<string, string> = {}, declaration = match[1].trim(), propertyValuePairs = declaration.split(';').filter(function (pair) { return pair.trim(); }); for (i = 0, len = propertyValuePairs.length; i < len; i++) { const pair = propertyValuePairs[i].split(':'), property = pair[0].trim(), value = pair[1].trim(); ruleObj[property] = value; } rule = match[0].trim(); rule.split(',').forEach((_rule) => { _rule = _rule.replace(/^svg/i, '').trim(); if (_rule === '') { return; } allRules[_rule] = { ...(allRules[_rule] || {}), ...ruleObj, }; }); }); } return allRules; }