Skip to content

Commit d0b8657

Browse files
committed
Support post-hoc addition of a prefix to avoid SVG collision
1 parent b7e8c96 commit d0b8657

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

src/index.ts

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,49 @@ export interface IRenderOptions extends IRendererOptionsIn {
6161
*
6262
*/
6363
svgid?: string;
64+
/**
65+
* A string that will be prepended to all ids to prevent collisions.
66+
* Gets added to the final rendered SVG via search/replace.
67+
* Only works with static rendering.
68+
*/
69+
prefix?: string;
70+
}
71+
72+
export const addPrefix = (svg: string, opts = {} as IRenderOptions): string => {
73+
if (opts.prefix !== undefined) {
74+
const prefix = opts.prefix;
75+
// Regex to find all id="something"
76+
const idRegex = /id="([^"]+)"/g;
77+
78+
// Collect all IDs
79+
const ids: string[] = [];
80+
let match: RegExpExecArray | null;
81+
while ((match = idRegex.exec(svg)) !== null) {
82+
ids.push(match[1]);
83+
}
84+
85+
// For each ID, replace both the definition and references
86+
ids.forEach((id) => {
87+
const newId = `${prefix}${id}`;
88+
89+
// Replace the id definition
90+
const idDefRegex = new RegExp(`id="${id}"`, "g");
91+
svg = svg.replace(idDefRegex, `id="${newId}"`);
92+
93+
// Replace references: url(#id), href="#id", xlink:href="#id"
94+
const refPatterns = [
95+
new RegExp(`url\\(#${id}\\)`, "g"),
96+
new RegExp(`href="#${id}"`, "g"),
97+
new RegExp(`xlink:href="#${id}"`, "g"),
98+
new RegExp(`"#${id}"`, "g"), // handles cases like begin="0s;id.end"
99+
];
100+
101+
refPatterns.forEach((regex) => {
102+
svg = svg.replace(regex, (match) => match.replace(`#${id}`, `#${newId}`));
103+
});
104+
});
105+
}
106+
return svg;
64107
}
65108

66109
/**
@@ -93,7 +136,7 @@ export const renderStatic = (json: APRenderRep, opts = {} as IRenderOptions): st
93136
node.setAttribute("id", uid);
94137
opts.divelem = node;
95138
const canvas = render(json, opts);
96-
return canvas.svg();
139+
return addPrefix(canvas.svg(), opts);
97140
}
98141

99142
/**
@@ -121,7 +164,7 @@ export const renderglyph = (glyphid: string, colour: number | string, opts = {}
121164
node.setAttribute("id", uid);
122165
opts.divelem = node;
123166
const canvas = render(obj, opts);
124-
return canvas.svg();
167+
return addPrefix(canvas.svg(), opts);
125168
}
126169

127170
/**

0 commit comments

Comments
 (0)