Repository navigation
feat(print): add paged-media-safe document output #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
8745297
f70f522
bc32643
ae12d0f
f598190
db6644d
c82f2ac
73e2a3e
01ee9e8
a813ff9
841d19b
f3f24db
94e9a10
bc87941
660c55a
6833896
ce1259d
5d615c5
3a35ba0
a3f3626
ab5f924
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import { readFileSync } from 'node:fs'; | ||
| import { resolve } from 'node:path'; | ||
|
|
||
| import { describe, expect, it } from 'vitest'; | ||
|
|
||
| const styles = readFileSync(resolve(process.cwd(), 'src/styles.css'), 'utf8'); | ||
|
|
||
| /** Match one CSS rule body for an exact selector within the shipped stylesheet. */ | ||
| function ruleBody(selector: string): string { | ||
| const escaped = selector.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&'); | ||
| const match = styles.match(new RegExp(`${escaped}\\s*\\{([^}]*)\\}`, 'u')); | ||
| if (!match?.[1]) throw new Error(`Missing CSS rule for ${selector}`); | ||
| return match[1]; | ||
| } | ||
|
|
||
| describe('print stylesheet contract', () => { | ||
| it('defines an explicit paged-document print media boundary', () => { | ||
| expect(styles).toMatch(/@media\s+print\s*\{/u); | ||
|
Check failure on line 18 in src/printStyles.test.ts
|
||
| }); | ||
|
|
||
| it('removes screen-only clipping and interactive chrome from printed output', () => { | ||
| const printIndex = styles.indexOf('@media print'); | ||
| expect(printIndex).toBeGreaterThan(-1); | ||
|
Check failure on line 23 in src/printStyles.test.ts
|
||
| const printStyles = styles.slice(printIndex); | ||
|
|
||
| expect(printStyles).toMatch( | ||
| /\.cwl-toolbar[\s\S]*\.cwl-collaboration-status[\s\S]*\.collaboration-cursor__caret[\s\S]*\.collaboration-cursor__label[\s\S]*\{[^}]*display:\s*none\s*!important\s*;/u, | ||
| ); | ||
| expect(printStyles).toMatch( | ||
| /\.cwl-editor__surface\s*\{[^}]*overflow(?:-y)?:\s*visible\s*;[^}]*max-height:\s*none\s*;/u, | ||
| ); | ||
| expect(printStyles).toMatch( | ||
| /\.cwl-editor\s*\{[^}]*overflow:\s*visible\s*;[^}]*border:\s*0\s*;/u, | ||
| ); | ||
| }); | ||
|
|
||
| it('does not print placeholder UI and keeps document blocks page-safe', () => { | ||
| const printIndex = styles.indexOf('@media print'); | ||
| expect(printIndex).toBeGreaterThan(-1); | ||
|
Check failure on line 39 in src/printStyles.test.ts
|
||
| const printStyles = styles.slice(printIndex); | ||
|
|
||
| expect(printStyles).toMatch( | ||
| /\.cwl-editor__content \.is-editor-empty:first-child::before\s*\{[^}]*content:\s*none\s*;/u, | ||
| ); | ||
| expect(printStyles).toMatch(/break-inside:\s*avoid\s*;/u); | ||
| expect(printStyles).toMatch(/break-after:\s*avoid\s*;/u); | ||
| expect(printStyles).toMatch(/orphans:\s*3\s*;/u); | ||
| expect(printStyles).toMatch(/widows:\s*3\s*;/u); | ||
| }); | ||
|
|
||
| it('keeps authored links distinguishable independently of color', () => { | ||
| expect(ruleBody('.cwl-editor__content a')).toMatch( | ||
| /text-decoration:\s*underline\s*;/u, | ||
| ); | ||
| }); | ||
| }); | ||
Uh oh!
There was an error while loading. Please reload this page.