Skip to content

Commit

Permalink
Flatten nested defs blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
yuanchuan committed Nov 19, 2023
1 parent 7fbfe74 commit 4f7d633
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 11 deletions.
27 changes: 20 additions & 7 deletions src/generator/svg.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class Tag {
if (!name) {
throw new Error("Tag name is required");
}
this.id = Symbol();
this.name = name;
this.body = [];
this.attrs = {};
Expand All @@ -26,9 +27,17 @@ class Tag {
return this.body.find(tag => tag.attrs.id === id && tag.name === name);
}
}
append(tag) {
if (!this.isTextNode()) {
this.body.push(tag);
findSpareDefs() {
return this.body.find(n => n.name === 'defs' && !n.attrs.id);
}
append(tags) {
if (!Array.isArray(tags)) {
tags = [tags];
}
for (let tag of tags) {
if (!this.isTextNode()) {
this.body.push(tag);
}
}
}
merge(tag) {
Expand Down Expand Up @@ -124,9 +133,8 @@ function generate(token, element, parent, root) {
root = el;
root.attr('xmlns', NS);
}
let defsElement = null;
if (token.name === 'defs') {
defsElement = root.body.find(n => n.name === 'defs');
let defsElement = root.findSpareDefs();
// replace with existing defs
if (defsElement) {
el = defsElement;
Expand Down Expand Up @@ -156,8 +164,13 @@ function generate(token, element, parent, root) {
existedTag.merge(el);
} else {
if (token.name === 'defs') {
// append only when there's no defs
if (!defsElement) {
// append only when there's no defs and spare defs
let defsElement = root.findSpareDefs();
if (defsElement && !el.attrs.id) {
if (el.id !== defsElement.id) {
defsElement.append(el.body);
}
} else {
root.append(el);
}
} else {
Expand Down
27 changes: 23 additions & 4 deletions test/generate-svg.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,25 @@ test('combile defs elements into one', t => {
);
});

test('handle nested defs', t => {
compare(t,
`path {
fill: defs g {
mask: defs g {}
}
}`,
trim(`
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<g id="g-3"/>
<g mask="url(#g-3)" id="g-4"/>
</defs>
<path fill="url(#g-4)"/>
</svg>
`)
);
});

test('generate single defs id', t => {
compare(t,
`defs g#1 {}
Expand Down Expand Up @@ -432,11 +451,11 @@ test('put id at right element', t => {
trim(`
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<g id="g-3">
<g id="g-5">
<circle/>
</g>
</defs>
<circle filter="url(#g-3)"/>
<circle filter="url(#g-5)"/>
</svg>
`)
);
Expand All @@ -450,15 +469,15 @@ test('put id at right element', t => {
trim(`
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<g id="g-4">
<g id="g-6">
<g>
<g>
<circle/>
</g>
</g>
</g>
</defs>
<circle filter="url(#g-4)"/>
<circle filter="url(#g-6)"/>
</svg>
`)
);
Expand Down

0 comments on commit 4f7d633

Please sign in to comment.