diff --git a/.oxlintrc.json b/.oxlintrc.json
index 8368fe5..f92b8c3 100644
--- a/.oxlintrc.json
+++ b/.oxlintrc.json
@@ -52,23 +52,5 @@
"default-case": "off",
"no-rest-spread-properties": "off",
"require-await": "warn"
- },
- "overrides": [
- {
- "files": [
- "*.svelte"
- ],
- "rules": {
- "no-unassigned-vars": "off"
- }
- },
- {
- "files": [
- ".stylelintrc.mjs"
- ],
- "rules": {
- "unicorn/no-null": "off"
- }
- }
- ]
+ }
}
\ No newline at end of file
diff --git a/src/cli/cli.ts b/src/cli/cli.ts
index 227379a..2f9bbdd 100644
--- a/src/cli/cli.ts
+++ b/src/cli/cli.ts
@@ -10,7 +10,7 @@ async function cli(cli_args: string[]) {
const args = parse_arguments(cli_args)
let params = validate_arguments(args)
let coverage_data = await read(params['coverage-dir'])
- let report = program(
+ let report = await program(
{
min_file_coverage: params['min-line-coverage'],
min_file_line_coverage: params['min-file-line-coverage'],
diff --git a/src/cli/program.ts b/src/cli/program.ts
index 93e0727..95f1db4 100644
--- a/src/cli/program.ts
+++ b/src/cli/program.ts
@@ -1,9 +1,4 @@
import { calculate_coverage, type Coverage, type CoverageResult } from '../lib/index.js'
-import { DOMParser } from 'linkedom'
-
-function parse_html(html: string) {
- return new DOMParser().parseFromString(html, 'text/html')
-}
export class MissingDataError extends Error {
constructor() {
@@ -54,7 +49,7 @@ function validate_min_file_line_coverage(actual: number, expected: number | unde
}
}
-export function program(
+export async function program(
{
min_file_coverage,
min_file_line_coverage,
@@ -67,7 +62,7 @@ export function program(
if (coverage_data.length === 0) {
throw new MissingDataError()
}
- let coverage = calculate_coverage(coverage_data, parse_html)
+ let coverage = await calculate_coverage(coverage_data)
let min_line_coverage_result = validate_min_line_coverage(coverage.line_coverage_ratio, min_file_coverage)
let min_file_line_coverage_result = validate_min_file_line_coverage(
Math.min(...coverage.coverage_per_stylesheet.map((sheet) => sheet.line_coverage_ratio)),
diff --git a/src/lib/filter-entries.test.ts b/src/lib/filter-entries.test.ts
index a71850b..5bb6ed4 100644
--- a/src/lib/filter-entries.test.ts
+++ b/src/lib/filter-entries.test.ts
@@ -1,12 +1,7 @@
import { test, expect } from '@playwright/test'
import { filter_coverage } from './filter-entries.js'
-import { DOMParser } from 'linkedom'
-function html_parser(html: string) {
- return new DOMParser().parseFromString(html, 'text/html')
-}
-
-test('filters out JS files', () => {
+test('filters out JS files', async () => {
let entries = [
{
url: 'http://example.com/script.js',
@@ -14,10 +9,10 @@ test('filters out JS files', () => {
ranges: [{ start: 0, end: 25 }],
},
]
- expect(filter_coverage(entries, html_parser)).toEqual([])
+ expect(await filter_coverage(entries)).toEqual([])
})
-test('keeps files with CSS extension', () => {
+test('keeps files with CSS extension', async () => {
let entries = [
{
url: 'http://example.com/styles.css',
@@ -25,10 +20,10 @@ test('keeps files with CSS extension', () => {
ranges: [{ start: 0, end: 13 }],
},
]
- expect(filter_coverage(entries, html_parser)).toEqual(entries)
+ expect(await filter_coverage(entries)).toEqual(entries)
})
-test('keeps extension-less URL with HTML text', () => {
+test('keeps extension-less URL with HTML text', async () => {
let entries = [
{
url: 'http://example.com',
@@ -43,10 +38,10 @@ test('keeps extension-less URL with HTML text', () => {
ranges: [{ start: 0, end: 13 }], // ranges are remapped
},
]
- expect(filter_coverage(entries, html_parser)).toEqual(expected)
+ expect(await filter_coverage(entries)).toEqual(expected)
})
-test('keeps extension-less URL with CSS text (running coverage in vite dev mode)', () => {
+test('keeps extension-less URL with CSS text (running coverage in vite dev mode)', async () => {
let entries = [
{
url: 'http://example.com',
@@ -54,16 +49,5 @@ test('keeps extension-less URL with CSS text (running coverage in vite dev mode)
ranges: [{ start: 0, end: 13 }],
},
]
- expect(filter_coverage(entries, html_parser)).toEqual(entries)
-})
-
-test('skips extension-less URL with HTML text when no parser is provided', () => {
- let entries = [
- {
- url: 'http://example.com',
- text: ``,
- ranges: [{ start: 13, end: 26 }],
- },
- ]
- expect(filter_coverage(entries)).toEqual([])
+ expect(await filter_coverage(entries)).toEqual(entries)
})
diff --git a/src/lib/filter-entries.ts b/src/lib/filter-entries.ts
index a355b69..eb80726 100644
--- a/src/lib/filter-entries.ts
+++ b/src/lib/filter-entries.ts
@@ -1,13 +1,12 @@
import type { Coverage } from './parse-coverage.js'
import { ext } from './ext.js'
-import type { Parser } from './types.js'
import { remap_html } from './remap-html.js'
function is_html(text: string): boolean {
return /<\/?(html|body|head|div|span|script|style)/i.test(text)
}
-export function filter_coverage(coverage: Coverage[], parse_html?: Parser): Coverage[] {
+export async function filter_coverage(coverage: Coverage[]): Promise {
let result = []
for (let entry of coverage) {
@@ -21,12 +20,7 @@ export function filter_coverage(coverage: Coverage[], parse_html?: Parser): Cove
}
if (is_html(entry.text)) {
- if (!parse_html) {
- // No parser provided, cannot extract CSS from HTML, silently skip this entry
- continue
- }
-
- let { css, ranges } = remap_html(parse_html, entry.text, entry.ranges)
+ let { css, ranges } = await remap_html(entry.text, entry.ranges)
result.push({
url: entry.url,
text: css,
diff --git a/src/lib/index.test.ts b/src/lib/index.test.ts
index da62b6a..83e634d 100644
--- a/src/lib/index.test.ts
+++ b/src/lib/index.test.ts
@@ -3,11 +3,6 @@ import { generate_coverage } from './test/generate-coverage.js'
import { calculate_coverage } from './index.js'
import type { Coverage } from './parse-coverage.js'
import { format } from '@projectwallace/format-css'
-import { DOMParser } from 'linkedom'
-
-function html_parser(html: string) {
- return new DOMParser().parseFromString(html, 'text/html')
-}
test.describe('from ')
- let result = remap_html(html_parser, html, [{ start: 1, end: 2 }])
+ let result = await remap_html(html, [{ start: 1, end: 2 }])
expect(result).toEqual({
css: '',
ranges: [],
})
})
-test('skips white-space-only style block', () => {
+test('skips white-space-only style block', async () => {
let html = create_html(``)
- let result = remap_html(html_parser, html, [{ start: 1, end: 2 }])
+ let result = await remap_html(html, [{ start: 1, end: 2 }])
expect(result).toEqual({
css: '',
ranges: [],
})
})
-test('remaps a single style block', () => {
+test('remaps a single style block', async () => {
let css = `h1 { color: red; }`
let html = create_html(``, `Hello world
`)
let range = { start: html.indexOf(css), end: html.indexOf(css) + css.length }
- let result = remap_html(html_parser, html, [range])
+ let result = await remap_html(html, [range])
expect(result).toEqual({
css,
ranges: [{ start: 0, end: css.length }],
})
})
-test('remaps multiple style blocks', () => {
+test('remaps multiple style blocks', async () => {
let css_head = `h1 { color: red; }`
let css_body = `h2 { font-size: 24px; }`
let html = create_html(``, ``)
let range_head = { start: html.indexOf(css_head), end: html.indexOf(css_head) + css_head.length }
let range_body = { start: html.indexOf(css_body), end: html.indexOf(css_body) + css_body.length }
- let result = remap_html(html_parser, html, [range_head, range_body])
+ let result = await remap_html(html, [range_head, range_body])
expect(result).toEqual({
css: css_head + css_body,
ranges: [
diff --git a/src/lib/remap-html.ts b/src/lib/remap-html.ts
index d59d309..10bbb39 100644
--- a/src/lib/remap-html.ts
+++ b/src/lib/remap-html.ts
@@ -1,12 +1,23 @@
-import type { Parser } from './types.js'
import type { Range } from './parse-coverage.js'
+import type { DOMParser as LinkedomParser } from 'linkedom'
-export function remap_html(parse_html: Parser, html: string, old_ranges: Range[]) {
- let doc = parse_html(html)
+async function get_dom_parser(): Promise {
+ if (typeof window !== 'undefined' && 'DOMParser' in window) {
+ /* v8 ignore */
+ return new window.DOMParser()
+ }
+
+ let { DOMParser } = await import('linkedom')
+ return new DOMParser() as LinkedomParser
+}
+
+export async function remap_html(html: string, old_ranges: Range[]) {
+ let dom_parser = await get_dom_parser()
+ let doc = dom_parser.parseFromString(html, 'text/html')
let combined_css = ''
let new_ranges = []
let current_offset = 0
- let style_elements = doc.querySelectorAll('style')
+ let style_elements = doc.querySelectorAll('style') as NodeListOf
for (let style_element of Array.from(style_elements)) {
let style_content = style_element.textContent
diff --git a/src/lib/test/kitchen-sink.test.ts b/src/lib/test/kitchen-sink.test.ts
index 3f7a91c..fde52da 100644
--- a/src/lib/test/kitchen-sink.test.ts
+++ b/src/lib/test/kitchen-sink.test.ts
@@ -1,12 +1,7 @@
import { test, expect } from '@playwright/test'
import { calculate_coverage } from '../index.js'
-import { DOMParser } from 'linkedom'
-function parse_html(html: string) {
- return new DOMParser().parseFromString(html, 'text/html')
-}
-
-test('project wallace Container component', () => {
+test('project wallace Container component', async () => {
const coverage = [
{
url: 'http://localhost:4173/_app/immutable/assets/Container.n-2BXq6O.css',
@@ -20,7 +15,7 @@ test('project wallace Container component', () => {
],
},
]
- let result = calculate_coverage(coverage, parse_html)
+ let result = await calculate_coverage(coverage)
let sheet = result.coverage_per_stylesheet.at(0)!
expect.soft(sheet.total_lines).toBe(44)
diff --git a/src/lib/types.ts b/src/lib/types.ts
deleted file mode 100644
index 433468d..0000000
--- a/src/lib/types.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-type NodeList = Iterable<{ textContent: string }> | NodeListOf
-
-export interface Parser {
- (html: string): {
- querySelectorAll: (selector: string) => NodeList
- }
-}