Skip to content

Commit dfe0547

Browse files
committed
split up in smaller files
1 parent b790a52 commit dfe0547

File tree

4 files changed

+145
-136
lines changed

4 files changed

+145
-136
lines changed

src/chunkify.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { Coverage } from './parse-coverage'
2+
3+
export type ChunkedCoverage = Coverage & {
4+
chunks: {
5+
start_offset: number
6+
end_offset: number
7+
is_covered: boolean
8+
}[]
9+
}
10+
11+
// TODO: get rid of empty chunks, merge first/last with adjecent covered block
12+
export function chunkify_stylesheet(stylesheet: Coverage): ChunkedCoverage {
13+
let chunks = []
14+
let offset = 0
15+
16+
for (let range of stylesheet.ranges) {
17+
// Create non-covered chunk
18+
if (offset !== range.start) {
19+
chunks.push({
20+
start_offset: offset,
21+
end_offset: range.start,
22+
is_covered: false,
23+
})
24+
offset = range.start
25+
}
26+
27+
chunks.push({
28+
start_offset: range.start,
29+
end_offset: range.end,
30+
is_covered: true,
31+
})
32+
offset = range.end
33+
}
34+
35+
// fill up last chunk if necessary:
36+
if (offset !== stylesheet.text.length) {
37+
chunks.push({
38+
start_offset: offset,
39+
end_offset: stylesheet.text.length,
40+
is_covered: false,
41+
})
42+
}
43+
44+
return {
45+
...stylesheet,
46+
chunks,
47+
}
48+
}

src/extend-ranges.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { Coverage } from './parse-coverage'
2+
3+
/**
4+
* WARNING: mutates the ranges array
5+
*/
6+
export function extend_ranges(coverage: Coverage[]): Coverage[] {
7+
// Adjust ranges to include @-rule name (only preludes included)
8+
// Note: Cannot reliably include closing } because it may not be the end of the range
9+
const LONGEST_ATRULE_NAME = '@-webkit-font-feature-values'.length
10+
11+
for (let stylesheet of coverage) {
12+
for (let range of stylesheet.ranges) {
13+
// Heuristic: atrule names are no longer than LONGEST_ATRULE_NAME
14+
for (let i = 1; i >= -LONGEST_ATRULE_NAME; i--) {
15+
let char_position = range.start + i
16+
if (stylesheet.text.charAt(char_position) === '@') {
17+
range.start = char_position
18+
break
19+
}
20+
}
21+
}
22+
}
23+
24+
return coverage
25+
}

src/index.ts

Lines changed: 7 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { is_valid_coverage, type Coverage, type Range } from './parse-coverage.t
22
import { deduplicate_entries } from './decuplicate.ts'
33
import { filter_coverage } from './filter-entries.ts'
44
import type { Parser } from './types.ts'
5-
import { format } from '@projectwallace/format-css'
5+
import { chunkify_stylesheet } from './chunkify.ts'
6+
import { extend_ranges } from './extend-ranges.ts'
7+
import { prettify, type PrettifiedCoverage, type PrettifiedChunk } from './prettify.ts'
68

79
export type CoverageData = {
810
uncovered_bytes: number
@@ -19,7 +21,7 @@ export type StylesheetCoverage = CoverageData & {
1921
url: string
2022
text: string
2123
ranges: Range[]
22-
chunks: CoverageChunk[]
24+
chunks: PrettifiedChunk[]
2325
}
2426

2527
export type CoverageResult = CoverageData & {
@@ -33,7 +35,8 @@ function ratio(fraction: number, total: number) {
3335
return fraction / total
3436
}
3537

36-
function calculate_stylesheet_coverage({ text, ranges, url, chunks }: LineCoverage): StylesheetCoverage {
38+
function calculate_stylesheet_coverage(stylesheet: PrettifiedCoverage): StylesheetCoverage {
39+
let { text, ranges, url, chunks } = stylesheet
3740
let uncovered_bytes = 0
3841
let covered_bytes = 0
3942
let total_bytes = 0
@@ -73,136 +76,6 @@ function calculate_stylesheet_coverage({ text, ranges, url, chunks }: LineCovera
7376
}
7477
}
7578

76-
/**
77-
* WARNING: mutates the ranges array
78-
*/
79-
function include_atrule_name_in_ranges(coverage: Coverage[]): Coverage[] {
80-
// Adjust ranges to include @-rule name (only preludes included)
81-
// Note: Cannot reliably include closing } because it may not be the end of the range
82-
const LONGEST_ATRULE_NAME = '@-webkit-font-feature-values'.length
83-
84-
for (let stylesheet of coverage) {
85-
for (let range of stylesheet.ranges) {
86-
// Heuristic: atrule names are no longer than LONGEST_ATRULE_NAME
87-
for (let i = 1; i >= -LONGEST_ATRULE_NAME; i--) {
88-
let char_position = range.start + i
89-
if (stylesheet.text.charAt(char_position) === '@') {
90-
range.start = char_position
91-
break
92-
}
93-
}
94-
}
95-
}
96-
97-
return coverage
98-
}
99-
100-
type OffsetChunk = {
101-
start_offset: number
102-
end_offset: number
103-
is_covered: boolean
104-
}
105-
106-
type CoverageChunk = OffsetChunk & {
107-
start_line: number
108-
end_line: number
109-
total_lines: number
110-
css: string
111-
}
112-
113-
type ChunkifiedCoverage = Coverage & { chunks: OffsetChunk[] }
114-
type LineCoverage = Coverage & { chunks: CoverageChunk[] }
115-
116-
// TODO: get rid of empty chunks, merge first/last with adjecent covered block
117-
function chunkify_stylesheet(stylesheet: Coverage): ChunkifiedCoverage {
118-
let chunks = []
119-
let offset = 0
120-
121-
for (let range of stylesheet.ranges) {
122-
// Create non-covered chunk
123-
if (offset !== range.start) {
124-
chunks.push({
125-
start_offset: offset,
126-
end_offset: range.start,
127-
is_covered: false,
128-
})
129-
offset = range.start
130-
}
131-
132-
chunks.push({
133-
start_offset: range.start,
134-
end_offset: range.end,
135-
is_covered: true,
136-
})
137-
offset = range.end
138-
}
139-
140-
// fill up last chunk if necessary:
141-
if (offset !== stylesheet.text.length) {
142-
chunks.push({
143-
start_offset: offset,
144-
end_offset: stylesheet.text.length,
145-
is_covered: false,
146-
})
147-
}
148-
149-
return {
150-
...stylesheet,
151-
chunks,
152-
}
153-
}
154-
155-
function prettify(stylesheet: ChunkifiedCoverage): LineCoverage {
156-
let line = 1
157-
let offset = 0
158-
159-
let pretty_chunks = stylesheet.chunks.map((offset_chunk, index) => {
160-
let css = format(stylesheet.text.slice(offset_chunk.start_offset, offset_chunk.end_offset))
161-
162-
if (offset_chunk.is_covered) {
163-
if (index === 0) {
164-
// mark the line between this chunk and the next on as covered
165-
css = css + '\n'
166-
} else if (index === stylesheet.chunks.length - 1) {
167-
// mark the newline after the previous uncovered block as covered
168-
css = '\n' + css
169-
} else {
170-
// mark the newline after the previous uncovered block as covered
171-
// and mark the line between this chunk and the next on as covered
172-
css = '\n' + css + '\n'
173-
}
174-
}
175-
176-
let line_count = css.split('\n').length
177-
let start_offset = offset
178-
let end_offset = Math.max(offset + css.length - 1, 0)
179-
let start_line = line
180-
let end_line = line + line_count
181-
182-
line = end_line
183-
offset = end_offset
184-
185-
return {
186-
...offset_chunk,
187-
start_offset,
188-
start_line,
189-
end_line: end_line - 1,
190-
end_offset,
191-
css,
192-
total_lines: end_line - start_line,
193-
}
194-
})
195-
196-
let updated_stylesheet = {
197-
...stylesheet,
198-
// TODO: update ranges as well?? Or remove them because we have chunks now
199-
chunks: pretty_chunks,
200-
text: pretty_chunks.map(({ css }) => css).join(''),
201-
}
202-
203-
return updated_stylesheet
204-
}
205-
20679
/**
20780
* @description
20881
* CSS Code Coverage calculation
@@ -223,11 +96,9 @@ export function calculate_coverage(coverage: Coverage[], parse_html?: Parser): C
22396

22497
let filtered_coverage = filter_coverage(coverage, parse_html)
22598
let deduplicated = deduplicate_entries(filtered_coverage)
226-
let range_extended = include_atrule_name_in_ranges(deduplicated)
99+
let range_extended = extend_ranges(deduplicated)
227100
let chunkified = range_extended.map((stylesheet) => chunkify_stylesheet(stylesheet))
228101
let prettified = chunkified.map((stylesheet) => prettify(stylesheet))
229-
230-
// Calculate coverage for each individual stylesheet we found
231102
let coverage_per_stylesheet = prettified.map((stylesheet) => calculate_stylesheet_coverage(stylesheet))
232103

233104
// Calculate total coverage for all stylesheets combined

src/prettify.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import type { Coverage } from './parse-coverage'
2+
import { type ChunkedCoverage } from './chunkify'
3+
import { format } from '@projectwallace/format-css'
4+
5+
export type PrettifiedChunk = ChunkedCoverage['chunks'][0] & {
6+
start_line: number
7+
end_line: number
8+
total_lines: number
9+
css: string
10+
}
11+
12+
export type PrettifiedCoverage = Coverage & {
13+
chunks: PrettifiedChunk[]
14+
}
15+
16+
export function prettify(stylesheet: ChunkedCoverage): PrettifiedCoverage {
17+
let line = 1
18+
let offset = 0
19+
20+
let pretty_chunks = stylesheet.chunks.map((offset_chunk, index) => {
21+
let css = format(stylesheet.text.slice(offset_chunk.start_offset, offset_chunk.end_offset))
22+
23+
if (offset_chunk.is_covered) {
24+
if (index === 0) {
25+
// mark the line between this chunk and the next on as covered
26+
css = css + '\n'
27+
} else if (index === stylesheet.chunks.length - 1) {
28+
// mark the newline after the previous uncovered block as covered
29+
css = '\n' + css
30+
} else {
31+
// mark the newline after the previous uncovered block as covered
32+
// and mark the line between this chunk and the next on as covered
33+
css = '\n' + css + '\n'
34+
}
35+
}
36+
37+
let line_count = css.split('\n').length
38+
let start_offset = offset
39+
let end_offset = Math.max(offset + css.length - 1, 0)
40+
let start_line = line
41+
let end_line = line + line_count
42+
43+
line = end_line
44+
offset = end_offset
45+
46+
return {
47+
...offset_chunk,
48+
start_offset,
49+
start_line,
50+
end_line: end_line - 1,
51+
end_offset,
52+
css,
53+
total_lines: end_line - start_line,
54+
}
55+
})
56+
57+
let updated_stylesheet = {
58+
...stylesheet,
59+
// TODO: update ranges as well?? Or remove them because we have chunks now
60+
chunks: pretty_chunks,
61+
text: pretty_chunks.map(({ css }) => css).join(''),
62+
}
63+
64+
return updated_stylesheet
65+
}

0 commit comments

Comments
 (0)