Skip to content

Commit 9122152

Browse files
committed
fix: honor the localFonts option in the capture path
localFonts was accepted and documented but only wired into preCache — the capture pipeline never forwarded it to embedCustomFonts, so snapdom(el, { localFonts: [...] }) embedded nothing. The capture now passes it through, so a user-provided font file is embedded as @font-face and the rasterized SVG uses it instead of falling back. Useful when content relies on a font the SVG-as-image path can't resolve (e.g. system-ui): supply a metric-compatible file via localFonts and reference its family in the content.
1 parent 69400a6 commit 9122152

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// localFonts must be honored in the direct capture path (not only via preCache): a user can
2+
// supply a font file so the rasterized SVG uses it instead of falling back (e.g. system-ui is
3+
// unavailable when an SVG renders as an <img>). capture.js previously dropped the option.
4+
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
5+
import { snapdom } from '../src/index'
6+
7+
const svgOf = (raw) => decodeURIComponent(raw.replace(/^data:image\/svg\+xml;charset=utf-8,/, ''))
8+
9+
describe('localFonts in capture', () => {
10+
let el
11+
beforeEach(() => {
12+
el = document.createElement('div')
13+
el.style.fontFamily = "'SnapTestFont', sans-serif"
14+
el.textContent = 'abc 123'
15+
document.body.appendChild(el)
16+
})
17+
afterEach(() => el.remove())
18+
19+
it('embeds a user-provided localFonts @font-face when the family is used', async () => {
20+
const raw = await snapdom.toRaw(el, {
21+
embedFonts: true,
22+
localFonts: [{ family: 'SnapTestFont', src: 'data:font/woff2;base64,AAAA', weight: '400', style: 'normal' }],
23+
})
24+
expect(svgOf(raw)).toMatch(/@font-face\{font-family:'SnapTestFont';src:url\(data:font\/woff2;base64,AAAA\)/)
25+
})
26+
27+
it('skips a localFonts family that the captured content does not use', async () => {
28+
const raw = await snapdom.toRaw(el, {
29+
embedFonts: true,
30+
localFonts: [{ family: 'UnusedFont', src: 'data:font/woff2;base64,AAAA' }],
31+
})
32+
expect(svgOf(raw)).not.toContain("font-family:'UnusedFont'")
33+
})
34+
})

src/core/capture.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ export async function captureDOM(element, options) {
158158
usedCodepoints,
159159
preCached: false,
160160
exclude: state.options.excludeFonts,
161+
localFonts: state.options.localFonts,
161162
useProxy: state.options.useProxy,
162163
fontStylesheetDomains: state.options.fontStylesheetDomains
163164
})

0 commit comments

Comments
 (0)