Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
bd74b39
feat: lay out stamps with Blank's engine, on a page that is the stamp…
FPurchess Oct 12, 2026
a8b38de
feat: find where a PDF without a form asks for a signature, a date or…
FPurchess Oct 12, 2026
2162bd5
feat: put a PDF's fields and found places in reading order, with Next…
FPurchess Oct 12, 2026
e512a46
feat: stamp and sign received PDFs natively: stamps as Form XObjects …
FPurchess Oct 12, 2026
610ef88
feat: find signature places by the signer's role, with a stamp, and t…
FPurchess Oct 12, 2026
b35f533
feat: read a PDF page's words and lines, fill its form in and save th…
FPurchess Oct 12, 2026
eb30265
feat: ask a PDF tab's helper for page text, fields and fills, and giv…
FPurchess Oct 12, 2026
abd6af4
feat: sign a PDF tab with its form filled in, as MuPDF's revision und…
FPurchess Oct 12, 2026
cd2b5b7
feat: one Sign dialog for exports and PDF tabs, with Sign as, initial…
FPurchess Oct 12, 2026
15295f7
feat: a model of the stamps placed on a PDF, with their history, and …
FPurchess Oct 12, 2026
cb58208
feat: place stamps on a PDF's pages from the signing toolbar, move an…
FPurchess Oct 12, 2026
6541d30
docs: placing stamps on a PDF by mouse and keys, the PDF tab's keys a…
FPurchess Oct 12, 2026
0d4d84d
fix: show only the stamps on pages the PDF shown has
FPurchess Oct 12, 2026
6b3bf7d
feat: fill in a received PDF's fields and found places on its pages, …
FPurchess Oct 12, 2026
72a38a6
test: sign form.pdf in E2E: Next to its name field, a typed signature…
FPurchess Oct 12, 2026
5b1e068
fix: let a PDF form field's text be selected in the pages, which can'…
FPurchess Oct 12, 2026
16dbcb0
docs: fill in and sign a PDF you received, its places, Next, fields, …
FPurchess Oct 12, 2026
b44a604
fix: fill a PDF field in with what Blank suggests only on Enter or ty…
FPurchess Oct 12, 2026
cc0fe04
fix: hold each helper answer to its own request's limit, name the fie…
FPurchess Oct 12, 2026
fe33512
fix: refuse fills of locked fields, read received PDFs within a decom…
FPurchess Oct 12, 2026
f68ec66
fix: centre a stamp's image over lines at the left too, as the rules say
FPurchess Oct 12, 2026
ca233bc
docs: the helper's answer limits, timeouts and fill refusals, choices…
FPurchess Oct 12, 2026
38aab0c
fix: send the PDF's fingerprint with its rules, name the field a refu…
FPurchess Oct 12, 2026
cc1dd2f
fix: queue fills, hold a PDF tab still while it's signed, fit its sta…
FPurchess Oct 12, 2026
95b1e29
test: cover signing, fills, places and stamp focus of PDF tabs with s…
FPurchess Oct 12, 2026
49ee3a2
fix: paint a PDF tab's stamps once they mount, not only when they change
FPurchess Oct 12, 2026
c401536
fix: give a stamp placed from the keyboard the focus, also after maki…
FPurchess Oct 12, 2026
d51f5a0
fix: move stamps onto the smaller pages of a file that changed, and m…
FPurchess Oct 12, 2026
5ee620e
fix: keep a signature valid when later revisions only add signatures,…
FPurchess Oct 12, 2026
e4fd4a6
fix: stand a signature on a found line at least 36 pt tall, and write…
FPurchess Oct 12, 2026
8a64ec9
fix: say what undo and redo changed in a PDF tab, and give a place th…
FPurchess Oct 12, 2026
39e1ad4
fix: say a PDF signed without a digital signature was saved with the …
FPurchess Oct 12, 2026
8f980f3
fix: show no places to fill and no Next on a PDF nothing can be added to
FPurchess Oct 12, 2026
712c9b1
fix: start a select's menu opened from the keyboard on the chosen item
FPurchess Oct 12, 2026
c54120d
fix: draw no SIGN arrow of MuPDF's over unsigned signature fields, wh…
FPurchess Oct 12, 2026
dff1454
fix: name a PDF's fields and places in their tooltips
FPurchess Oct 12, 2026
77c6ec1
fix: say Place added, tell how to check a checkbox or choose from Nex…
FPurchess Oct 12, 2026
7a21f41
fix: name the first character a PDF field's font can't show, above th…
FPurchess Oct 12, 2026
f999660
docs: note that a signed PDF's found places come back under the pictu…
FPurchess Oct 12, 2026
cd1b604
ci: check signed PDFs with poppler and qpdf in the Linux build, and s…
FPurchess Oct 12, 2026
6112285
fix: wait for initials turned on or off in the Sign dialog before sig…
FPurchess Oct 12, 2026
804ea28
fix: unmark a stamp's marked content also when its properties are nam…
FPurchess Oct 12, 2026
101cab0
test: call a page rewritten or freed before a later signature a chang…
FPurchess Oct 12, 2026
b49b7a3
fix: leave the signer's name of a received PDF's signature to its cer…
FPurchess Oct 12, 2026
52bdfd0
fix: draw stamps in the page's own space when its content leaves a q …
FPurchess Oct 12, 2026
07afd9f
fix: log initials the Sign dialog couldn't place instead of dropping …
FPurchess Oct 12, 2026
754a4f5
test: sign the PDF whose DSS lists its /Info as the other tests sign
FPurchess Oct 12, 2026
8a3f18a
merge: take signing and PDF tabs on the block standards of #119
FPurchess Oct 13, 2026
bbc7a9e
test: check signed PDFs with the pdfsig of CI's poppler 22.02, and gi…
FPurchess Oct 13, 2026
971b2f8
merge: take signing and PDF tabs on #119 and Tauri 2.12
FPurchess Oct 13, 2026
bd0fbfc
refactor: know the user's signature by one name in the stamps' engine…
FPurchess Oct 13, 2026
7808c0a
merge: take the PDF fixtures kept byte for byte on Windows
FPurchess Oct 13, 2026
d6af7d7
test: check a signed PDF's words only with poppler's pdftotext, not t…
FPurchess Oct 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/rules/layout-engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ The wasm API between Rust (`model.rs`, `wasm.rs`) and TypeScript (`flatten.ts`,
- A `toc` item (one position) is a table of contents: `title`, `depth` and its `entries` (`{level, text}`, the listed headings up to `depth`, which `flatten.ts` gives it). Its n-th entry is the n-th listed heading up to `depth`, so it holds no positions that could go stale. `items/toc.rs` lays out the title and the entries, as extras (not text of the document), leaving a column for the page numbers as wide as the widest number a page shows (`format_number` of the settings' style and start, up to page 999), so the numbers never change its lines. After paginating, `engine/toc.rs` (`set_toc_numbers`, next to the chapters) works out each entry's page label, as the footer's `{page}` writes it, and gives a new body version only to the pages showing an entry whose number changed. `display.rs` sets in the numbers, the leader dots up to them, and a link `#toc:<entry>` per entry (`TOC_LINK`), which the PDF makes a link to the heading (`toc_target`) and the editor follows on Ctrl+Click. The PDF tags it `TOC` > `TOCI` > `Link`.
- A table of contents depends on other blocks than itself, which `flattenBlocks` otherwise never assumes: `pageSync` (`tocBlocks` in `src/editor/plugins/pageView.ts`) flattens the tables of contents again whenever `headingsSignature` (the listed headings' levels and texts, not their positions) changes.
- An `image` item's `share` (0 to 1) makes it that share of the room's width, larger too; without it, it keeps its own size, at most the room's. Its `caption` is laid out below it in the caption style, aligned as the picture is (`caption_box` in `items/mod.rs`, which a table's caption above it uses too) as a unit of extras kept with the picture's, which ↑/↓ step over, tagged `Caption` in the PDF's `Figure`. A cell's image has `share` of the cell. The picture and its caption fit one page together.
- A `stamp` item is a stamp placed on a PDF's page (`items/stamp.rs`): an image (`src`, with `width` and `height` for its shape) contained in the box, centred, and `lines` under it in the body font at `size` pt, `align`ed left or `center`. It's drawn as an artifact, not text of the document. Only stamp engines (`src/pdf/stampEngine.ts`, one per stamp that looks different, `sharing()` the page view's fonts, with the user's marks as `blank:signature` (`SIGNATURE_IMAGE`, as in a signed export)/`blank:initials`) lay it out, on settings with `stamp: true`: the page is the stamp's box, from `MIN_STAMP` (2 pt), without margins or bands. `boxes(0, 1)` gives what it shows (`Laid::extent`): its natural size, laid out on a 600 × 200 pt page.
- A table cell has `paragraphs`, or `blocks` when it holds more: `text` blocks with their own `indent`, `marker` and `bars` (lists, quotes, code) and `image` blocks, fitted to the cell's width.
- The engine clamps what it gets (sizes, margins, start numbers, columns) and never panics on odd input; a panic that is left is written to `console.error` before the instance traps.
- **Pages:** `pageCount()`, `versions()`, and `bodyVersions()`/`bandVersions()`, one per page, which change only when a page's body or its header and footer change, so only those are painted again. `pageBody(page)` and `pageBands(page)` are the display lists (JSON strings of drawing ops), `page(page)` both; `bands(page)`, `bottoms()`, `glyphPath(font, glyph)` and `unitsPerEm(font)`. A glyph run's `font` is a font index: below the number of faces a face of a file, from `INSTANCE_BASE` (2^20) on an instance of a variable face at other coordinates (e.g. the bold of Noto Emoji). An index never changes its meaning, so a cache keyed by it stays right; the `fontFile*` calls count files, never instances.
Expand Down
40 changes: 34 additions & 6 deletions .claude/rules/pdf.md

Large diffs are not rendered by default.

32 changes: 26 additions & 6 deletions .claude/rules/signing.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion .claude/rules/state.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ Blank's modules share state through Vue refs in `src/state/`, instead of importi
| `appearance.ts` | `themes`, `theme`, `isTheme`, and `colorMode` (accent or mono, see `design.md`) |
| `language.ts` | `language`, `languagePicker` |
| `spellcheck.ts` | `spellcheck`, `spellcheckStatus`, `spellchecker` |
| `dialogs.ts` | the requests of open dialogs (`linkDialog`, `imageDialog`, `pageSetup`, `unsavedDialog`, `settingsDialog`, `printDialog`, `signatureDialog`, `signDialog`, `certificateDialog`, `confirmDialog`, `signatureDetails`) and popovers (`tocPopover`, `diagramPopover`, `signaturePopover`, `signaturesPopover`) and of the open header or footer strip (`bandEditor`, with `bandEditorDone`, which closes it), `focusTakingDialogs`, those of them that take the focus, and `closeDialog` |
| `dialogs.ts` | the requests of open dialogs (`linkDialog`, `imageDialog`, `pageSetup`, `unsavedDialog`, `settingsDialog`, `printDialog`, `signatureDialog`, `signDialog`, `placeDialog`, `certificateDialog`, `confirmDialog`, `signatureDetails`) and popovers (`tocPopover`, `diagramPopover`, `signaturePopover`, `signaturesPopover`) and of the open header or footer strip (`bandEditor`, with `bandEditorDone`, which closes it), `focusTakingDialogs`, those of them that take the focus, and `closeDialog` |
| `drawings.ts` | counters of what modules drew for the pages: `vectorPictures` (a diagram's picture is ready to paint) and `drawnVectors` (the diagram module drew one), which the pages and the page view follow |
| `blocksPane.ts` | the blocks pane: `blocksPaneOpen` (persisted), `blocksPaneFocused` (part of `uiTakesFocus`), `blockChoices` (the blocks it offers) and `focusBlocksSearch()`, which asks it for the focus in its search |
| `popups.ts` | `tablePicker`, `tableToolbar`, `tableHandles` (with `Point`, `Span`), `blockToolbar`, `ToolbarItem` (with the `command` whose shortcut its tooltip shows), `BoxAnchor` (an `Anchor` with its right end), `contextMenu` (its `owner`, the button that opened it, if a button did), `MenuItem` (with an optional `icon`, `detail` and `look`, a class that draws it like what it makes), `Anchor`, `tooltipsSuppressed` (keeps the controls' tooltips hidden), and `wordCountCard` (whether the word count's card shows) |
| `messages.ts` | `announcement` and `spellcheckMessage`, written through `announce()` (`quiet` for what only screen readers hear) and `flashSpellcheckMessage()`; `bootMessages()` clears each after a moment |
| `page.ts` | `frontmatter` (of the document, notifying only when it changes), `pageLayout` (its `resolveLayout` over `config`'s defaults, resolved again only when either changes) and `pageFields` (what the placeholders of headers and footers show, the same object while they stay the same) |
| `stamps.ts` | the stamps placed on PDF tabs: `stampBooks` (each tab's stamps, their history and the SHA-256 they were placed on, written through `src/pdf/stampBooks.ts`), `selectedStamp`, `placingStamp` (the tool waiting for a press on a page) and `shownPdfRules` (what the PDF shown allows); the places: `pdfPlaces` (each tab's fields and found places), `pageRevisions` (pages filled in anew), `fieldProblem` (why a field refused what was typed) and `lastPlace` (where Next goes on from); see `pdf.md`, "Stamps" and "Places and fills" |
| `pdf.ts` | the PDF tab shown: `shownPdf` (its `PdfTabDocument`, null in a markdown tab; the page view of PDFs writes what it learns into it), `pdfPageInView` (for "Page N of M"), `pdfViewAnchor` (the spot it shows, which `currentViewAnchor` gives storage and a switch in a PDF tab), `pdfViewFocused` (part of `uiTakesFocus`) and `pdfViewport` (its size and scroll, which `pdfDeskLayout` in `pageView.ts` places the pages by); see `pdf.md` |
| `pageView.ts` | the page view: `pageView` (the view chosen), `pageLayoutState` (the pages as laid out), `pageCaret`, `pageSelection`, `pageHeadBox` (where the selection's head is painted, with its affinity, e.g. for the IME), `pageDropCaret` (where dragged text would drop), `pageDropGap` (where a dragged block would drop), `pageHoverBlock` (the content block under the pointer), `engineMissing` (true once the editor shows the text itself), `pageScrollRequest`, and `pageViewport` (where the view is and how far it scrolled, down and across, for `src/engine/geometry.ts`; written at most once per frame, and only when it changed); the zoom: `pageZoom` (persisted), `zoomAnchor`, `zoomFactor`, `zoomLabel`, and `viewFrames`/`deskLayout`, the one source of where the pages are shown (see `layout-engine.md`, "Zoom"), and `pdfDeskLayout`, a PDF tab's |
| `print.ts` | `printSettings`, what the print dialog remembers (persisted, see `print.md`) |
Expand Down
2 changes: 1 addition & 1 deletion .claude/rules/tabs.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Blank keeps several documents open, one tab each, in the one ProseMirror view: e

## Storage (`src/storage.ts`)

- `session` holds the order, the active tab and each tab without its document; `tab:<id>` holds each tab's `doc.toJSON()`, a markdown tab's only: a PDF tab's PDF is its file. The session is `version: 2` while a PDF tab is open (`SESSION_VERSION`, `sessionVersion`) and 1 otherwise, so an older Blank, which reads only 1, still reads a session without PDF tabs; it keeps a session of 2 as `session-backup` and starts afresh. This Blank reads 1 and 2. Only changed documents are written, at most a second after a change; the documents first, then the session, then the closed tabs' keys are removed, so the session never lists a document that isn't stored.
- `session` holds the order, the active tab and each tab without its document; `tab:<id>` holds each tab's `doc.toJSON()`, a markdown tab's only: a PDF tab's PDF is its file, and what was placed and filled in on it is `stamps:<id>` (`{ sha256, stamps, fills, dismissed }`, see `pdf.md`, "Stamps"); stamps and fills make it unsaved, and closing it then asks whether to sign it first. The session is `version: 2` while a PDF tab is open (`SESSION_VERSION`, `sessionVersion`) and 1 otherwise, so an older Blank, which reads only 1, still reads a session without PDF tabs; it keeps a session of 2 as `session-backup` and starts afresh. This Blank reads 1 and 2. Only changed documents are written, at most a second after a change; the documents first, then the session, then the closed tabs' keys are removed, so the session never lists a document that isn't stored.
- Every tab has its document stored, a saved file's too: it is what shows when the file has gone. A tab without unsaved changes reads its file again when it's first shown; one with changes keeps them and reads the file in the background as its baseline.
- Restored tabs load when first shown, except the active one.
- An earlier Blank's `doc`, `path` and `importedFrom` become the first tab (`migrate`), marked unsaved until its file says otherwise. A stored document that can't be read is kept as `tab-backup:<id>`, a session that can't be read (e.g. a newer Blank's) as `session-backup`.
Expand Down
8 changes: 6 additions & 2 deletions .claude/rules/ui-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ All of the UI around the editor is Vue 3.5. `bootUI` (`src/ui.ts`) runs after `b
- **What the keys move between** is found with `shownIn(root, selectors)` (`src/dom.ts`), which leaves out what's inside `[hidden]`: the dialog's Tab trap, the page setup's ↑↓ and the band strip's Tab use it.
- **Everything renders through `App.vue`**, into `#ui-app` inside `#ui`, never into `document.body` directly: `#ui` comes after the editor, which is what lets the UI paint above it and take its clicks. A popup of a bar item, whose bar is a stacking context of its own, goes there with `<Teleport to="#ui-app">` (the word count's card). Classes on the body come from `useBodyClass`.
- **Keep every id, class, role, `data-*` and aria attribute** that E2E, the docs shots and the tests use.
- **Stacking:** `#ui` comes after `.ProseMirror`. The z-index layers are set in `src/scss/main.scss` (e.g. the page view 1, the top area (both rows), the bottom bar and the outline 2, table handles 4, toolbar 5, the floating blocks pane 6 (above the toolbars it may cover; docked, it covers nothing), the header or footer being edited 8 (its strip and slots), dialog backdrop 10, picker and menus 20, the tooltip 30); keep a new part in line with them, below the backdrop unless it is a modal or a menu. `#page-view` (`PageView.vue`), or in a PDF tab `#pdf-view` (`PdfView.vue`) in its place, is fixed between the top area and the status bar at 1, above the hidden editor and below everything else; its page canvases (`PageFrame.vue`), marks and overlay (`PageOverlay.vue`: caret, selection, composition) are positioned inside it and have no z-index of their own. `BlockMarks.vue` (the drop line and the hover hairline of content blocks) is fixed at 1 too, after it in `App.vue`, so it paints over the pages and under the bars.
- **Stacking:** `#ui` comes after `.ProseMirror`. The z-index layers are set in `src/scss/main.scss` (e.g. the page view 1, the top area (both rows), the bottom bar and the outline 2, table handles 4, toolbar 5, the floating blocks pane 6 (above the toolbars it may cover; docked, it covers nothing), the header or footer being edited 8 (its strip and slots), dialog backdrop 10, picker and menus 20, the tooltip 30); keep a new part in line with them, below the backdrop unless it is a modal or a menu. `#page-view` (`PageView.vue`), or in a PDF tab `#pdf-view` (`PdfView.vue`) in its place, is fixed between the top area and the status bar at 1, above the hidden editor and below everything else; its page canvases (`PageFrame.vue`), marks and overlay (`PageOverlay.vue`: caret, selection, composition) are positioned inside it and have no z-index of their own, nor have a PDF's stamps, its places' targets and fields and the selected stamp's toolbar, which come after the pages in `.page-desk`, in reading order. `BlockMarks.vue` (the drop line and the hover hairline of content blocks) is fixed at 1 too, after it in `App.vue`, so it paints over the pages and under the bars.

## Components

Expand Down Expand Up @@ -68,7 +68,8 @@ All of the UI around the editor is Vue 3.5. `bootUI` (`src/ui.ts`) runs after `b
| `BlockMarks.vue` | over the pages: the line where a dragged block drops, the hairline around the content block under the pointer (`blockMarksModel.ts`) |
| `TocPopover.vue`, `DiagramPopover.vue`, `SignaturePopover.vue`, `components/BlockPopover.vue` | the settings of a table of contents (`tocPopoverModel.ts`), a diagram (widths from `widthOptions.ts`) and a signature block (`signaturePopoverModel.ts`) below the block toolbar, applied at once; `BlockPopover` places them, focuses the first control, and closes on Esc, Enter in a text field, a press elsewhere or a resize |
| `SignatureDialog.vue`, `SignaturePad.vue` | the user's signature or initials: drawn on the pad, typed in a signature font, or from a picture (`signatureDialogModel.ts`, see `signing.md`) |
| `SignDialog.vue` | Export signed PDF's dialog: the block, the place, digital or a picture only (`signDialogModel.ts`) |
| `SignDialog.vue` | the Sign dialog of both flows, Export signed PDF and a PDF tab's Sign… (`mode`): Sign as, the block, the initials, the place, the reason, the passphrase (`signDialogModel.ts`; see `signing.md`) |
| `PlaceDialog.vue` | asks where the user signs, before a place stamp when Blank doesn't know it (`placeDialog`, remembered in `signingPlace`) |
| `CertificateDialog.vue` | makes or imports the user's certificate (`certificateDialogModel.ts`), busy while the key is made |
| `ConfirmDialog.vue` | the question before something that can't be undone (request `confirmDialog`), with Cancel focused and an optional secondary action that leaves it open |
| `components/SidePaneHead.vue` | the head of a side pane (the `side-pane` mixin): its title and the button that hides it |
Expand All @@ -87,6 +88,9 @@ All of the UI around the editor is Vue 3.5. `bootUI` (`src/ui.ts`) runs after `b
| `components/IconButton.vue` | a button that shows only an icon: its label for screen readers and the tooltip, a command's shortcut, `pressed`, `disabled` (aria-disabled), `focusable` |
| `settings/SettingsDialog.vue` and the rest of `settings/` | the settings (`Mod-,`): the sections, an inner page in place of its section (`InnerPage.vue`), `SwitchRow.vue` (a setting row with a switch), `EditRow.vue` and `PagedSection.vue` (a setting edited on an inner page), `EntryList.vue` and `AddRow.vue` (a list with Remove and a filter, and its fields), `ThemeCards.vue`, `SigningSection.vue` and `CertificateRows.vue` (Signing); see `settings.md` |
| `PdfView.vue`, `PdfPage.vue` | a PDF tab's pages in place of the page view, or why it can't show them (Open again, Find it…, Close tab); one page's canvas; the logic in `pdfViewModel.ts` (see `pdf.md`) |
| `SigningToolbar.vue` | a PDF tab's signing tools in the formatting toolbar's row: Signature, Initials, Date, Place, Sign…, Next (hidden while the PDF has no places) and a note when no tool works (`signingToolbarModel.ts`, on `src/pdf/toolRules.ts`; see `pdf.md`, "Stamps") |
| `PdfTarget.vue`, `PdfField.vue` | a PDF's places on its pages: a target to sign or date (a dashed box), and a field of its form to type into, tick or choose from (`pdfFieldModel.ts`), each disabled with its reason while it can't be filled in (`placeRefusal`); see `pdf.md`, "Places and fills" |
| `StampOverlay.vue`, `StampToolbar.vue` | a stamp on a PDF's page (a group with its canvas, the ring and corners while selected, its keys and drags in `stampOverlayModel.ts` and `stampDrag.ts`), or a repeated stamp's ghost; the selected stamp's toolbar after it (Remove, Repeat on every page) |
| `SignaturesStatus.vue`, `SignaturesPopover.vue`, `SignatureDetailsDialog.vue`, `settings/TrustedRows.vue` | a PDF's signatures: the status bar's item, the list above it, one's details with Trust this certificate…, and Settings ▸ Signing ▸ Trusted certificates; the words in `signaturesModel.ts` (see `pdf.md`) |
| `FocusModeButton.vue` | focus mode's button at the end of the status bar; see `focus-mode.md` |
| `UiTooltip.vue` | the shared tooltip of controls, mounted once; what it shows and when in `tooltipModel.ts` (`tipAttrs`, `watchTips`), its timer in `hoverIntent.ts` |
Expand Down
6 changes: 4 additions & 2 deletions .github/actions/webkit-deps/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ runs:
using: composite
steps:
# `webkit2gtk-driver` (`webkitgtk-webdriver` from Ubuntu 26.04 on) provides
# WebKitWebDriver, `xvfb` a virtual display, and `xclip` the X selection the
# middle-click paste spec sets
# WebKitWebDriver, `xvfb` a virtual display, `xclip` the X selection the
# middle-click paste spec sets, and `poppler-utils` the pdftotext the PDF
# spec reads a signed PDF's text with
- name: install system dependencies
shell: bash
run: |
Expand All @@ -32,6 +33,7 @@ runs:
"$driver" \
xclip \
xvfb \
poppler-utils \
${{ inputs.ffmpeg == 'true' && 'ffmpeg' || '' }}
# the desktop portal is registered with D-Bus but never comes up on the runner, so WebKitGTK
# and tao wait for its timeouts (~30s) on every app start. Without the service file, the
Expand Down
11 changes: 7 additions & 4 deletions .github/workflows/test-on-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ jobs:
libxdo-dev \
libssl-dev \
libayatana-appindicator3-dev \
librsvg2-dev
librsvg2-dev \
poppler-utils \
qpdf

# tauri-action builds the frontend and the PDF helper through
# beforeBuildCommand
Expand All @@ -64,9 +66,10 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# the app crate (the spell check engine and the system fonts) on every
# platform; the layout engine is tested by the engine job of test.yml,
# with poppler. tauri-action has built the frontend (dist/), which the
# the app crate (the spell check engine, the system fonts and the
# signer) on every platform, the signer's PDFs checked with poppler and
# qpdf on Linux; the layout engine is tested by the engine job of
# test.yml, with poppler. tauri-action has built the frontend (dist/), which the
# Rust side needs to compile
- name: run rust tests
run: cargo test --manifest-path src-tauri/Cargo.toml -p blank
Expand Down
Loading
Loading