@onedarnleyroad/vite-plugin-svg-sprite 2.0.0-beta.1 → 2.0.0-beta.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/README.md +1 -0
- package/package.json +1 -1
- package/src/index.js +21 -3
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ A Vite plugin that builds SVG sprite sheets from a directory of SVG files — wi
|
|
|
9
9
|
- **Vite manifest integration** — works out of the box with [nystudio107's Craft Vite plugin](https://nystudio107.com/docs/vite/) and any other manifest consumer
|
|
10
10
|
- **Multiple sprites from subfolders** — organise icons into `light/`, `dark/`, etc. and get one sprite per folder
|
|
11
11
|
- Namespaces internal IDs to prevent conflicts across icons
|
|
12
|
+
- **Preserves outer `<svg>` attributes** on the generated `<symbol>` — `fill="currentColor"`, `stroke`, `class`, `role`, `aria-*`, `data-*`, `style` (including CSS custom properties), etc. Only the truly wrapper-specific attributes are stripped: `xmlns`, `version`, `width`, `height`, and `id` (we set our own).
|
|
12
13
|
- Preserves existing `<title>` elements, or falls back to the filename
|
|
13
14
|
- Strips comments and empty `<defs>` blocks
|
|
14
15
|
- Dev server serves sprites from memory with full-reload on change
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -3,7 +3,21 @@ import { resolve, basename, extname, join } from 'path'
|
|
|
3
3
|
import { createHash } from 'crypto'
|
|
4
4
|
|
|
5
5
|
function hashContent(content) {
|
|
6
|
-
return createHash('sha256').update(content).digest('
|
|
6
|
+
return createHash('sha256').update(content).digest('hex').slice(0, 8)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const STRIP_ATTRS = new Set(['xmlns', 'version', 'width', 'height', 'id'])
|
|
10
|
+
|
|
11
|
+
function extractOuterAttrs(openTag) {
|
|
12
|
+
const attrRe = /\s+([a-zA-Z_][a-zA-Z0-9_:-]*)="([^"]*)"/g
|
|
13
|
+
const kept = []
|
|
14
|
+
let m
|
|
15
|
+
while ((m = attrRe.exec(openTag)) !== null) {
|
|
16
|
+
const [, attr, value] = m
|
|
17
|
+
if (STRIP_ATTRS.has(attr) || attr.startsWith('xmlns:')) continue
|
|
18
|
+
kept.push(`${attr}="${value}"`)
|
|
19
|
+
}
|
|
20
|
+
return kept.join(' ')
|
|
7
21
|
}
|
|
8
22
|
|
|
9
23
|
function buildSymbol(svg, name) {
|
|
@@ -21,7 +35,8 @@ function buildSymbol(svg, name) {
|
|
|
21
35
|
.replace(/\bhref="#([^"]+)"/g, `href="#${name}-$1"`)
|
|
22
36
|
.replace(/\bxlink:href="#([^"]+)"/g, `xlink:href="#${name}-$1"`)
|
|
23
37
|
|
|
24
|
-
const
|
|
38
|
+
const openTag = namespaced.match(/<svg\b[^>]*>/i)?.[0] ?? ''
|
|
39
|
+
const outerAttrs = extractOuterAttrs(openTag)
|
|
25
40
|
|
|
26
41
|
const inner = namespaced
|
|
27
42
|
.replace(/<svg[^>]*>/i, '')
|
|
@@ -30,7 +45,8 @@ function buildSymbol(svg, name) {
|
|
|
30
45
|
.replace(/>\s+</g, '><')
|
|
31
46
|
.trim()
|
|
32
47
|
|
|
33
|
-
|
|
48
|
+
const attrs = `id="svg-${name}"${outerAttrs ? ' ' + outerAttrs : ''}`
|
|
49
|
+
return `<symbol ${attrs}><title>${title}</title>${inner}</symbol>`
|
|
34
50
|
}
|
|
35
51
|
|
|
36
52
|
function buildSpriteSvg(dir, files) {
|
|
@@ -145,6 +161,8 @@ export default function svgSpritePlugin(options = {}) {
|
|
|
145
161
|
if (!match) return next()
|
|
146
162
|
res.setHeader('Content-Type', 'image/svg+xml')
|
|
147
163
|
res.setHeader('Cache-Control', 'no-cache')
|
|
164
|
+
res.setHeader('Access-Control-Allow-Origin', '*')
|
|
165
|
+
res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin')
|
|
148
166
|
res.end(match)
|
|
149
167
|
})
|
|
150
168
|
|