diff --git a/src/embed-webfonts.ts b/src/embed-webfonts.ts index a84a699d..d3c81214 100644 --- a/src/embed-webfonts.ts +++ b/src/embed-webfonts.ts @@ -104,11 +104,11 @@ function parseCSS(source: string) { async function getCSSRules( styleSheets: CSSStyleSheet[], options: Options, -): Promise { - const ret: CSSStyleRule[] = [] +): Promise { + const ret: CSSRule[] = [] const deferreds: Promise[] = [] - // First loop inlines imports + // replace @import rules with target stylesheet styleSheets.forEach((sheet) => { if ('cssRules' in sheet) { try { @@ -164,34 +164,45 @@ async function getCSSRules( } }) - return Promise.all(deferreds).then(() => { - // Second loop parses rules - styleSheets.forEach((sheet) => { - if ('cssRules' in sheet) { - try { - toArray(sheet.cssRules || []).forEach((item) => { - ret.push(item) - }) - } catch (e) { - console.error(`Error while reading CSS rules from ${sheet.href}`, e) + await Promise.all(deferreds) + + const rulesCollections = toArray<{ cssRules: CSSRuleList }>(styleSheets) + + while (rulesCollections.length) { + const rulesCollection = rulesCollections.pop() + + if (!rulesCollection) { + continue + } + + try { + toArray(rulesCollection.cssRules || []).forEach((rule) => { + ret.push(rule) + + if ('cssRules' in rule) { + rulesCollections.unshift(rule as { cssRules: CSSRuleList }) } - } - }) + }) + } catch (e) { + console.error(`Error while reading CSS rules`, e) + } + } - return ret - }) + return ret } -function getWebFontRules(cssRules: CSSStyleRule[]): CSSStyleRule[] { +function getWebFontRules(cssRules: CSSRule[]): CSSFontFaceRule[] { return cssRules - .filter((rule) => rule.type === CSSRule.FONT_FACE_RULE) + .filter( + (rule): rule is CSSFontFaceRule => rule.type === CSSRule.FONT_FACE_RULE, + ) .filter((rule) => shouldEmbed(rule.style.getPropertyValue('src'))) } async function parseWebFontRules( node: T, options: Options, -) { +): Promise { if (node.ownerDocument == null) { throw new Error('Provided element is not within a Document') } diff --git a/test/spec/webfont.spec.ts b/test/spec/webfont.spec.ts index 5be025d2..23bda45a 100644 --- a/test/spec/webfont.spec.ts +++ b/test/spec/webfont.spec.ts @@ -9,15 +9,15 @@ describe('font embedding', () => { try { root.innerHTML = ` +

Hello world

+

Hello world

+ ` + const svg = await htmlToImage.toSvg(root) + const doc = await getSvgDocument(svg) + const [style] = Array.from(doc.getElementsByTagName('style')) + + expect(style.textContent).toContain( + 'font-family: "Font 0"; src: url("data:application/font-woff;base64,', + ) + expect(style.textContent).toContain( + 'font-family: "Font 1"; src: url("data:application/font-woff;base64,', + ) + expect(style.textContent).not.toContain( + 'font-family: "Font 2"; src: url("data:application/font-woff;base64,', + ) + } finally { + root.remove() + } + }) }) })