Skip to content

Commit 9efb59b

Browse files
committed
Add support for import rules
1 parent d9ee199 commit 9efb59b

File tree

4 files changed

+50
-1
lines changed

4 files changed

+50
-1
lines changed

src/Generator.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@ export async function cssToHtml(css: CSSRuleList | string, options: Options = {}
5757

5858
// Filter and format the supplied style rules.
5959
for (const [index, rule] of Object.entries(styleRules) as [string, (CSSStyleRule | CSSMediaRule)][]) {
60+
// Fetch the content of import rules.
61+
if (rule instanceof CSSImportRule && new URL(rule.href).pathname.endsWith('.css')) {
62+
try {
63+
const resource = await fetch(rule.href);
64+
if (resource.status !== 200) {
65+
throw new Error(`Response status was ${resource.status}.`);
66+
}
67+
// Recursively convert all imported stylesheets to HTML.
68+
const resourceCss = await resource.text();
69+
const resourceHtml = await cssToHtml(resourceCss, options);
70+
output.innerHTML += resourceHtml.innerHTML;
71+
} catch (error) {
72+
console.warn('Failed to fetch remote stylesheet:', rule.href, '-', error);
73+
}
74+
}
75+
6076
// Skip:
6177
// - Non-style rules.
6278
// - Rules including `*`.

tests/ignored.spec.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { test, expect } from '@playwright/test';
66
import { cssToHtml } from '../src/index';
77

88
const css = `
9-
@import url('https://example.com/example.css');
109
:root {
1110
background: #000;
1211
}

tests/import.spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Verify that remote style sheets can be imported.
3+
*/
4+
5+
import { test, expect } from '@playwright/test';
6+
import { cssToHtml } from '../src/index';
7+
8+
const css = `
9+
@import url('https://cascades.app/project/wBcGlZUV.css');
10+
div.last {
11+
content: 'a';
12+
}
13+
`;
14+
15+
test('Import', async ({ page }) => {
16+
await page.addScriptTag({ path: './dist/Generator.script.js' });
17+
18+
page.on('console', msg => console.log(msg.text()));
19+
20+
const result = await page.evaluate(async (css) => {
21+
document.body = await cssToHtml(css);
22+
23+
const element = document.body.querySelector('div.last');
24+
return element
25+
&& element.innerHTML === 'a'
26+
&& element.previousElementSibling !== null
27+
&& element.previousElementSibling.innerHTML === 'Test'
28+
&& element.nextSibling === null;
29+
}, css);
30+
31+
expect(result).toBeDefined();
32+
expect(result).toBe(true);
33+
});

tests/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { cssToHtml } from '../dist/index.js';
22

33
const input = `
4+
@import url('https://cascades.app/project/wBcGlZUV.css');
45
:root {
56
background: #000;
67
}

0 commit comments

Comments
 (0)