UNPKG

fabric

Version:

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

1 lines 5.16 kB
{"version":3,"file":"parseUseDirectives.mjs","names":[],"sources":["../../../src/parser/parseUseDirectives.ts"],"sourcesContent":["import { svgNS } from './constants';\nimport { getMultipleNodes } from './getMultipleNodes';\nimport { applyViewboxTransform } from './applyViewboxTransform';\nimport { parseStyleString } from './parseStyleString';\n\nexport function parseUseDirectives(doc: Document) {\n const nodelist = getMultipleNodes(doc, ['use', 'svg:use']);\n const skipAttributes = ['x', 'y', 'xlink:href', 'href', 'transform'];\n\n for (const useElement of nodelist) {\n const useAttributes: NamedNodeMap = useElement.attributes;\n\n const useAttrMap: Record<string, string> = {};\n for (const attr of useAttributes) {\n attr.value && (useAttrMap[attr.name] = attr.value);\n }\n\n const xlink = (useAttrMap['xlink:href'] || useAttrMap.href || '').slice(1);\n\n if (xlink === '') {\n return;\n }\n const referencedElement = doc.getElementById(xlink);\n if (referencedElement === null) {\n // if we can't find the target of the xlink, consider this use tag bad, similar to no xlink\n return;\n }\n let clonedOriginal = referencedElement.cloneNode(true) as Element;\n\n const originalAttributes: NamedNodeMap = clonedOriginal.attributes;\n\n const originalAttrMap: Record<string, string> = {};\n for (const attr of originalAttributes) {\n attr.value && (originalAttrMap[attr.name] = attr.value);\n }\n\n // Transform attribute needs to be merged in a particular way\n const { x = 0, y = 0, transform = '' } = useAttrMap;\n const currentTrans = `${transform} ${\n originalAttrMap.transform || ''\n } translate(${x}, ${y})`;\n\n applyViewboxTransform(clonedOriginal);\n\n if (/^svg$/i.test(clonedOriginal.nodeName)) {\n // if is an SVG, create a group and apply all the attributes on top of it\n const el3 = clonedOriginal.ownerDocument.createElementNS(svgNS, 'g');\n Object.entries(originalAttrMap).forEach(([name, value]) =>\n el3.setAttributeNS(svgNS, name, value),\n );\n el3.append(...clonedOriginal.childNodes);\n clonedOriginal = el3;\n }\n\n for (const attr of useAttributes) {\n if (!attr) {\n continue;\n }\n const { name, value } = attr;\n if (skipAttributes.includes(name)) {\n continue;\n }\n\n if (name === 'style') {\n // when use has a style, merge the two styles, with the ref being priority (not use)\n // priority is by feature. an attribute for fill on the original element\n // will overwrite the fill in style or attribute for tha use\n const styleRecord: Record<string, any> = {};\n parseStyleString(value, styleRecord);\n // cleanup styleRecord from attributes of original\n Object.entries(originalAttrMap).forEach(([name, value]) => {\n styleRecord[name] = value;\n });\n // now we can put in the style of the original that will overwrite the original attributes\n parseStyleString(originalAttrMap.style || '', styleRecord);\n const mergedStyles = Object.entries(styleRecord)\n .map((entry) => entry.join(':'))\n .join(';');\n clonedOriginal.setAttribute(name, mergedStyles);\n } else {\n // set the attribute from use element only if the original does not have it already\n !originalAttrMap[name] && clonedOriginal.setAttribute(name, value);\n }\n }\n\n clonedOriginal.setAttribute('transform', currentTrans);\n clonedOriginal.setAttribute('instantiated_by_use', '1');\n clonedOriginal.removeAttribute('id');\n useElement.parentNode!.replaceChild(clonedOriginal, useElement);\n }\n}\n"],"mappings":";;;;;AAKA,SAAgB,mBAAmB,KAAe;CAChD,MAAM,WAAW,iBAAiB,KAAK,CAAC,OAAO,UAAU,CAAC;CAC1D,MAAM,iBAAiB;EAAC;EAAK;EAAK;EAAc;EAAQ;EAAY;AAEpE,MAAK,MAAM,cAAc,UAAU;EACjC,MAAM,gBAA8B,WAAW;EAE/C,MAAM,aAAqC,EAAE;AAC7C,OAAK,MAAM,QAAQ,cACjB,MAAK,UAAU,WAAW,KAAK,QAAQ,KAAK;EAG9C,MAAM,SAAS,WAAW,iBAAiB,WAAW,QAAQ,IAAI,MAAM,EAAE;AAE1E,MAAI,UAAU,GACZ;EAEF,MAAM,oBAAoB,IAAI,eAAe,MAAM;AACnD,MAAI,sBAAsB,KAExB;EAEF,IAAI,iBAAiB,kBAAkB,UAAU,KAAK;EAEtD,MAAM,qBAAmC,eAAe;EAExD,MAAM,kBAA0C,EAAE;AAClD,OAAK,MAAM,QAAQ,mBACjB,MAAK,UAAU,gBAAgB,KAAK,QAAQ,KAAK;EAInD,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,YAAY,OAAO;EACzC,MAAM,eAAe,GAAG,UAAU,GAChC,gBAAgB,aAAa,GAC9B,aAAa,EAAE,IAAI,EAAE;AAEtB,wBAAsB,eAAe;AAErC,MAAI,SAAS,KAAK,eAAe,SAAS,EAAE;GAE1C,MAAM,MAAM,eAAe,cAAc,gBAAgB,OAAO,IAAI;AACpE,UAAO,QAAQ,gBAAgB,CAAC,SAAS,CAAC,MAAM,WAC9C,IAAI,eAAe,OAAO,MAAM,MAAM,CACvC;AACD,OAAI,OAAO,GAAG,eAAe,WAAW;AACxC,oBAAiB;;AAGnB,OAAK,MAAM,QAAQ,eAAe;AAChC,OAAI,CAAC,KACH;GAEF,MAAM,EAAE,MAAM,UAAU;AACxB,OAAI,eAAe,SAAS,KAAK,CAC/B;AAGF,OAAI,SAAS,SAAS;IAIpB,MAAM,cAAmC,EAAE;AAC3C,qBAAiB,OAAO,YAAY;AAEpC,WAAO,QAAQ,gBAAgB,CAAC,SAAS,CAAC,MAAM,WAAW;AACzD,iBAAY,QAAQ;MACpB;AAEF,qBAAiB,gBAAgB,SAAS,IAAI,YAAY;IAC1D,MAAM,eAAe,OAAO,QAAQ,YAAY,CAC7C,KAAK,UAAU,MAAM,KAAK,IAAI,CAAC,CAC/B,KAAK,IAAI;AACZ,mBAAe,aAAa,MAAM,aAAa;SAG/C,EAAC,gBAAgB,SAAS,eAAe,aAAa,MAAM,MAAM;;AAItE,iBAAe,aAAa,aAAa,aAAa;AACtD,iBAAe,aAAa,uBAAuB,IAAI;AACvD,iBAAe,gBAAgB,KAAK;AACpC,aAAW,WAAY,aAAa,gBAAgB,WAAW"}