@tomasvn/svgstore 3.1.3 → 3.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/pages.yml +33 -0
- package/.github/workflows/publish.yml +21 -0
- package/CHANGELOG.md +14 -1
- package/docs/index.html +76 -0
- package/package.json +1 -1
- package/readme.md +8 -3
- package/src/svgstore.js +23 -22
- package/src/utils/safe-clean-defs.js +1 -2
- package/test/svgstore.js +65 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Deploy documentation to GitHub Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: pages
|
|
14
|
+
cancel-in-progress: false
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
deploy:
|
|
18
|
+
environment:
|
|
19
|
+
name: github-pages
|
|
20
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
permissions:
|
|
23
|
+
pages: write
|
|
24
|
+
id-token: write
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- uses: actions/configure-pages@v5
|
|
28
|
+
- uses: actions/upload-pages-artifact@v3
|
|
29
|
+
with:
|
|
30
|
+
path: docs
|
|
31
|
+
- name: Deploy to GitHub Pages
|
|
32
|
+
id: deployment
|
|
33
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Publish Package to npmjs
|
|
2
|
+
on:
|
|
3
|
+
release:
|
|
4
|
+
types: [published]
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
# Setup .npmrc file to publish to npm
|
|
14
|
+
- uses: actions/setup-node@v4
|
|
15
|
+
with:
|
|
16
|
+
node-version: '20.x'
|
|
17
|
+
registry-url: 'https://registry.npmjs.org'
|
|
18
|
+
- run: npm ci
|
|
19
|
+
- run: npm publish --provenance --access public
|
|
20
|
+
env:
|
|
21
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
# 3.1.5
|
|
4
|
+
|
|
5
|
+
- Deployed docs site
|
|
6
|
+
|
|
7
|
+
# 3.1.4
|
|
8
|
+
|
|
9
|
+
- Closes [#36][https://github.com/svgstore/svgstore/issues/36]
|
|
10
|
+
- Fix failing test
|
|
11
|
+
|
|
3
12
|
# 3.1.0
|
|
13
|
+
|
|
4
14
|
- implements [PR #33](https://github.com/svgstore/svgstore/pull/33) from original work
|
|
5
15
|
|
|
6
16
|
# 3.1.1
|
|
17
|
+
|
|
7
18
|
- parsing of `linearGradient` elements
|
|
8
19
|
|
|
9
20
|
# 3.1.2
|
|
21
|
+
|
|
10
22
|
- update readme file
|
|
11
23
|
|
|
12
24
|
# 3.1.3
|
|
25
|
+
|
|
13
26
|
- add safe clean `def` util
|
|
14
|
-
- passing `opts`, `cleanDefs: true` would break `linearGradient`
|
|
27
|
+
- passing `opts`, `cleanDefs: true` would break `linearGradient`
|
package/docs/index.html
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<meta name="description" content="Documentation and examples for svgstore, a tool for combining SVG files into a sprite.">
|
|
7
|
+
<title>svgstore documentation</title>
|
|
8
|
+
<style>
|
|
9
|
+
:root {
|
|
10
|
+
color-scheme: light;
|
|
11
|
+
font-family: system-ui, sans-serif;
|
|
12
|
+
color: #20232a;
|
|
13
|
+
background: #f7f8fa;
|
|
14
|
+
}
|
|
15
|
+
body {
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
max-width: 760px;
|
|
18
|
+
margin: 0 auto;
|
|
19
|
+
padding: 4rem 1.5rem;
|
|
20
|
+
line-height: 1.6;
|
|
21
|
+
}
|
|
22
|
+
h1, h2 {
|
|
23
|
+
line-height: 1.2;
|
|
24
|
+
}
|
|
25
|
+
a {
|
|
26
|
+
color: #0969da;
|
|
27
|
+
}
|
|
28
|
+
code {
|
|
29
|
+
padding: 0.15rem 0.35rem;
|
|
30
|
+
border-radius: 4px;
|
|
31
|
+
background: #e9edf2;
|
|
32
|
+
}
|
|
33
|
+
pre {
|
|
34
|
+
overflow-x: auto;
|
|
35
|
+
padding: 1rem;
|
|
36
|
+
border-radius: 6px;
|
|
37
|
+
background: #20232a;
|
|
38
|
+
color: #f7f8fa;
|
|
39
|
+
}
|
|
40
|
+
pre code {
|
|
41
|
+
padding: 0;
|
|
42
|
+
background: none;
|
|
43
|
+
color: inherit;
|
|
44
|
+
}
|
|
45
|
+
nav {
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-wrap: wrap;
|
|
48
|
+
gap: 1rem;
|
|
49
|
+
margin-top: 2rem;
|
|
50
|
+
}
|
|
51
|
+
</style>
|
|
52
|
+
</head>
|
|
53
|
+
<body>
|
|
54
|
+
<main>
|
|
55
|
+
<h1>svgstore</h1>
|
|
56
|
+
<p>Combine multiple SVG files into one sprite using <code><symbol></code> elements.</p>
|
|
57
|
+
|
|
58
|
+
<h2>Quick start</h2>
|
|
59
|
+
<p>Install the package and add SVG files to a sprite:</p>
|
|
60
|
+
<pre><code>npm install @tomasvn/svgstore</code></pre>
|
|
61
|
+
<pre><code>const svgstore = require('@tomasvn/svgstore');
|
|
62
|
+
const fs = require('fs');
|
|
63
|
+
|
|
64
|
+
const sprite = svgstore()
|
|
65
|
+
.add('icon', fs.readFileSync('./icon.svg', 'utf8'));
|
|
66
|
+
|
|
67
|
+
fs.writeFileSync('./sprite.svg', sprite);</code></pre>
|
|
68
|
+
|
|
69
|
+
<nav aria-label="Documentation links">
|
|
70
|
+
<a href="examples/">View the examples</a>
|
|
71
|
+
<a href="https://github.com/tomasvn/svgstore#api">API reference</a>
|
|
72
|
+
<a href="https://github.com/tomasvn/svgstore">GitHub repository</a>
|
|
73
|
+
</nav>
|
|
74
|
+
</main>
|
|
75
|
+
</body>
|
|
76
|
+
</html>
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -6,9 +6,14 @@ Combines multiple SVG files into one using `<symbol>` elements which you may [`<
|
|
|
6
6
|
|
|
7
7
|
## NOTE
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
<blockquote>
|
|
10
|
+
<strong>NOTE:</strong> This is a fork of original work, released with patched fixes <br />
|
|
11
|
+
SEE: <a href="./CHANGELOG.md">Changelog</a>
|
|
12
|
+
</blockquote>
|
|
13
|
+
|
|
14
|
+
## Documentation
|
|
15
|
+
|
|
16
|
+
Visit the [svgstore documentation site](https://tomasvn.github.io/svgstore/) for a quick start and examples.
|
|
12
17
|
|
|
13
18
|
## Install
|
|
14
19
|
|
package/src/svgstore.js
CHANGED
|
@@ -134,32 +134,33 @@ function svgstore(options) {
|
|
|
134
134
|
var elem = child(_elem);
|
|
135
135
|
var oldDefId = elem.attr('id');
|
|
136
136
|
var newDefId = id + '_' + oldDefId;
|
|
137
|
+
var oldHref = '#' + oldDefId;
|
|
138
|
+
var newHref = '#' + newDefId;
|
|
139
|
+
var oldUrl = 'url(' + oldHref + ')';
|
|
140
|
+
var newUrl = 'url(' + newHref + ')';
|
|
137
141
|
elem.attr('id', newDefId);
|
|
138
142
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
var
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
143
|
+
child('*').each(function (i, refElem) {
|
|
144
|
+
var ref = child(refElem);
|
|
145
|
+
var attrs = refElem.attribs || {};
|
|
146
|
+
Object.keys(attrs).forEach(function (attr) {
|
|
147
|
+
var originalValue = attrs[attr];
|
|
148
|
+
var value = originalValue;
|
|
149
|
+
if (typeof value !== 'string') return;
|
|
150
|
+
|
|
151
|
+
if (
|
|
152
|
+
(attr === 'href' || attr === 'xlink:href') &&
|
|
153
|
+
value === oldHref
|
|
154
|
+
) {
|
|
155
|
+
value = newHref;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (value.indexOf(oldUrl) !== -1) {
|
|
159
|
+
value = value.split(oldUrl).join(newUrl);
|
|
149
160
|
}
|
|
150
|
-
}
|
|
151
|
-
if (!foundProperty) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
child(use).attr(foundProperty, '#' + newDefId);
|
|
155
|
-
});
|
|
156
161
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
i,
|
|
160
|
-
use
|
|
161
|
-
) {
|
|
162
|
-
child(use).attr('fill', 'url(#' + newDefId + ')');
|
|
162
|
+
if (value !== originalValue) ref.attr(attr, value);
|
|
163
|
+
});
|
|
163
164
|
});
|
|
164
165
|
});
|
|
165
166
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
function safeCleanDefsAttrs(attrs) {
|
|
2
2
|
if (attrs === true) {
|
|
3
|
-
|
|
4
|
-
return [];
|
|
3
|
+
return ['style'];
|
|
5
4
|
}
|
|
6
5
|
if (!Array.isArray(attrs)) return [];
|
|
7
6
|
// Exclude 'style' to preserve gradient stops and fills
|
package/test/svgstore.js
CHANGED
|
@@ -231,6 +231,71 @@ test('should rename defs id', async (t) => {
|
|
|
231
231
|
t.strictEqual(store.toString(), expected);
|
|
232
232
|
});
|
|
233
233
|
|
|
234
|
+
test('should update all references to renamed defs ids', async (t) => {
|
|
235
|
+
const svg =
|
|
236
|
+
'<svg><defs>' +
|
|
237
|
+
'<linearGradient id="paint0"/>' +
|
|
238
|
+
'<linearGradient id="paint1" href="#paint0"/>' +
|
|
239
|
+
'<clipPath id="clip0"/>' +
|
|
240
|
+
'<mask id="mask0"/>' +
|
|
241
|
+
'<filter id="filter0"/>' +
|
|
242
|
+
'<marker id="marker0"/>' +
|
|
243
|
+
'</defs>' +
|
|
244
|
+
'<g clip-path="url(#clip0)" mask="url(#mask0)" filter="url(#filter0)" ' +
|
|
245
|
+
'marker-start="url(#marker0)" marker-mid="url(#marker0)" ' +
|
|
246
|
+
'marker-end="url(#marker0)">' +
|
|
247
|
+
'<path fill="url(#paint0)" stroke="url(#paint0)" ' +
|
|
248
|
+
'style="fill:url(#paint0);stroke:url(#paint0)"/>' +
|
|
249
|
+
'</g></svg>';
|
|
250
|
+
const output = svgstore({ inline: true, renameDefs: true })
|
|
251
|
+
.add('icon', svg)
|
|
252
|
+
.toString();
|
|
253
|
+
|
|
254
|
+
[
|
|
255
|
+
'href="#icon_paint0"',
|
|
256
|
+
'clip-path="url(#icon_clip0)"',
|
|
257
|
+
'mask="url(#icon_mask0)"',
|
|
258
|
+
'filter="url(#icon_filter0)"',
|
|
259
|
+
'marker-start="url(#icon_marker0)"',
|
|
260
|
+
'marker-mid="url(#icon_marker0)"',
|
|
261
|
+
'marker-end="url(#icon_marker0)"',
|
|
262
|
+
'fill="url(#icon_paint0)"',
|
|
263
|
+
'stroke="url(#icon_paint0)"',
|
|
264
|
+
'style="fill:url(#icon_paint0);stroke:url(#icon_paint0)"',
|
|
265
|
+
].forEach((reference) => {
|
|
266
|
+
t.ok(output.includes(reference), `expected output to include ${reference}`);
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
test('should match the renameDefs issue reproduction', async (t) => {
|
|
271
|
+
const icon =
|
|
272
|
+
'<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">' +
|
|
273
|
+
'<g clip-path="url(#clip0)"><path d="M0 12h24" stroke="url(#paint0)" stroke-width="4"/></g>' +
|
|
274
|
+
'<defs>' +
|
|
275
|
+
'<linearGradient id="paint0" x2="24" gradientUnits="userSpaceOnUse">' +
|
|
276
|
+
'<stop stop-color="red"/><stop offset="1" stop-color="blue"/>' +
|
|
277
|
+
'</linearGradient>' +
|
|
278
|
+
'<clipPath id="clip0"><rect width="12" height="24"/></clipPath>' +
|
|
279
|
+
'</defs></svg>';
|
|
280
|
+
|
|
281
|
+
const output = svgstore({ renameDefs: true })
|
|
282
|
+
.add('icon', icon)
|
|
283
|
+
.toString({ inline: true });
|
|
284
|
+
|
|
285
|
+
const expected =
|
|
286
|
+
'<svg><defs>' +
|
|
287
|
+
'<linearGradient id="icon_paint0" x2="24" gradientUnits="userSpaceOnUse">' +
|
|
288
|
+
'<stop stop-color="red"/><stop offset="1" stop-color="blue"/>' +
|
|
289
|
+
'</linearGradient>' +
|
|
290
|
+
'<clipPath id="icon_clip0"><rect width="12" height="24"/></clipPath>' +
|
|
291
|
+
'</defs>' +
|
|
292
|
+
'<symbol id="icon" viewBox="0 0 24 24">' +
|
|
293
|
+
'<g clip-path="url(#icon_clip0)"><path d="M0 12h24" stroke="url(#icon_paint0)" stroke-width="4"/></g>' +
|
|
294
|
+
'</symbol></svg>';
|
|
295
|
+
|
|
296
|
+
t.strictEqual(output, expected);
|
|
297
|
+
});
|
|
298
|
+
|
|
234
299
|
test('should add <view/> and <use/> to enable SVG Fragment Identifiers', async (t) => {
|
|
235
300
|
const store = svgstore({ fragmentIdentifier: (id) => `view-${id}` })
|
|
236
301
|
.add('foo', doctype + FIXTURE_SVGS.foo.replace('<svg', svgNs.slice(0, -1)))
|