Skip to content

Commit 7d9f93b

Browse files
authored
Preserve existing viewBox (#15)
1 parent a8b3050 commit 7d9f93b

File tree

8 files changed

+451
-407
lines changed

8 files changed

+451
-407
lines changed

README.md

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,26 @@ plugins: [
6060
];
6161
```
6262

63-
6. Execute your SVG transformation NPM script.
63+
6. Arguments
64+
65+
- `overwrite` - boolean - defaults to `true` - If set to `false` will preserve any existing `viewBox` attribute on your input SVG files.
66+
67+
Usage:
68+
69+
```javascript
70+
plugins: [
71+
// ... more plugins
72+
{
73+
...addViewBox,
74+
params: {
75+
overwrite: false
76+
}
77+
}
78+
// ... more plugins
79+
];
80+
```
81+
82+
7. Execute your SVG transformation NPM script.
6483

6584
## LICENSE
6685

@@ -131,30 +150,30 @@ Support and sponsor my work:
131150
<br />
132151
<br />
133152
<a href="https://twitter.com/intent/tweet?text=Checkout%20this%20awesome%20developer%20profile%3A&url=https%3A%2F%2Fgithub.com%2Fscriptex&via=scriptexbg&hashtags=software%2Cgithub%2Ccode%2Cawesome" title="Tweet">
134-
<img src="https://img.shields.io/badge/Tweet-Share_my_profile-blue.svg?logo=twitter&color=38A1F3" />
153+
<img src="https://img.shields.io/badge/Tweet-Share_my_profile-blue.svg?logo=twitter&color=38A1F3" />
135154
</a>
136155
<a href="https://paypal.me/scriptex" title="Donate on Paypal">
137-
<img src="https://img.shields.io/badge/Donate-Support_me_on_PayPal-blue.svg?logo=paypal&color=222d65" />
156+
<img src="https://img.shields.io/badge/Donate-Support_me_on_PayPal-blue.svg?logo=paypal&color=222d65" />
138157
</a>
139158
<a href="https://revolut.me/scriptex" title="Donate on Revolut">
140-
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/revolut.json" />
159+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/revolut.json" />
141160
</a>
142161
<a href="https://patreon.com/atanas" title="Become a Patron">
143-
<img src="https://img.shields.io/badge/Become_Patron-Support_me_on_Patreon-blue.svg?logo=patreon&color=e64413" />
162+
<img src="https://img.shields.io/badge/Become_Patron-Support_me_on_Patreon-blue.svg?logo=patreon&color=e64413" />
144163
</a>
145164
<a href="https://ko-fi.com/scriptex" title="Buy Me A Coffee">
146-
<img src="https://img.shields.io/badge/Donate-Buy%20me%20a%20coffee-yellow.svg?logo=ko-fi" />
165+
<img src="https://img.shields.io/badge/Donate-Buy%20me%20a%20coffee-yellow.svg?logo=ko-fi" />
147166
</a>
148167
<a href="https://liberapay.com/scriptex/donate" title="Donate on Liberapay">
149-
<img src="https://img.shields.io/liberapay/receives/scriptex?label=Donate%20on%20Liberapay&logo=liberapay" />
168+
<img src="https://img.shields.io/liberapay/receives/scriptex?label=Donate%20on%20Liberapay&logo=liberapay" />
150169
</a>
151170
<a href="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/bitcoin.json" title="Donate Bitcoin">
152-
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/bitcoin.json" />
171+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/bitcoin.json" />
153172
</a>
154173
<a href="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/etherium.json" title="Donate Etherium">
155-
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/etherium.json" />
174+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/etherium.json" />
156175
</a>
157176
<a href="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/shiba-inu.json" title="Donate Shiba Inu">
158-
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/shiba-inu.json" />
177+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/scriptex/scriptex/master/badges/shiba-inu.json" />
159178
</a>
160179
</div>

index.mjs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,33 @@ const name = 'SVGOAddViewBox';
1313
/**
1414
* @type {SVGOPluginFunction}
1515
*/
16-
const fn = () => ({
17-
root: {
18-
enter: node => {
19-
const element = /** @type {SVGOElement} */ (node?.children?.[0]);
16+
const fn = (_, params) => {
17+
const { overwrite = true } = params;
2018

21-
if (!element) {
22-
return;
23-
}
19+
return {
20+
root: {
21+
enter: node => {
22+
const element = /** @type {SVGOElement} */ (node?.children?.[0]);
2423

25-
const { width, height } = element.attributes;
24+
if (!element) {
25+
return;
26+
}
2627

27-
if (typeof width === 'undefined' || typeof height === 'undefined') {
28-
return;
29-
}
28+
const { width, height, viewBox } = element.attributes;
29+
30+
if (viewBox && !overwrite) {
31+
return;
32+
}
3033

31-
element.attributes.viewBox = `0 0 ${Number(width)} ${Number(height)}`;
34+
if (typeof width === 'undefined' || typeof height === 'undefined') {
35+
return;
36+
}
37+
38+
element.attributes.viewBox = `0 0 ${Number(width)} ${Number(height)}`;
39+
}
3240
}
33-
}
34-
});
41+
};
42+
};
3543

3644
/**
3745
* @type {SVGOPlugin}

test/index.mjs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,27 @@ tape('Has viewBox attribute', async t => {
2323

2424
t.end();
2525
});
26+
27+
tape('Preserves existing viewBox attribute', async t => {
28+
const input = resolve('test', 'input', 'test-preserve.svg');
29+
const output = resolve('test', 'output', 'test-preserve.svg');
30+
const inputSVG = readFileSync(input, 'utf-8');
31+
const outputSVG = readFileSync(output, 'utf-8');
32+
33+
const config = await loadConfig(resolve('test', 'svgo.config.mjs'));
34+
const optimized = optimize(inputSVG, config).data;
35+
const parsedInput = parse(inputSVG);
36+
const parsedOutput = parse(optimized);
37+
const rootNodeInput = /** @type {svgParser.ElementNode} */ (parsedInput.children[0]);
38+
const rootNodeOutput = /** @type {svgParser.ElementNode} */ (parsedOutput.children[0]);
39+
40+
t.ok(existsSync(input), 'Input file exists.');
41+
t.ok(existsSync(output), 'Output file exists.');
42+
t.equals(optimized, outputSVG, 'The parsed input file and saved output files match.');
43+
t.equals(
44+
rootNodeInput?.properties?.viewBox,
45+
rootNodeOutput?.properties?.viewBox,
46+
'The viewBox attribute was not changed.'
47+
);
48+
t.ok(!!rootNodeInput?.properties?.viewBox, 'Has viewBox attribute.');
49+
});

test/input/test-preserve.svg

Lines changed: 45 additions & 0 deletions
Loading

test/output/test-preserve.svg

Lines changed: 1 addition & 0 deletions
Loading

test/output/test.svg

Lines changed: 1 addition & 1 deletion
Loading

test/svgo.config.mjs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ export default {
1717
}
1818
}
1919
},
20-
addViewBox
20+
{
21+
...addViewBox,
22+
params: {
23+
overwrite: false
24+
}
25+
}
2126
]
2227
};

0 commit comments

Comments
 (0)