Skip to content

Release: unified-editor redesign — palette, stylus signatures, annotate & placement upgrades#127

Merged
sumitsahoo merged 17 commits into
mainfrom
dev
Jun 23, 2026
Merged

Release: unified-editor redesign — palette, stylus signatures, annotate & placement upgrades#127
sumitsahoo merged 17 commits into
mainfrom
dev

Conversation

@sumitsahoo

Copy link
Copy Markdown
Collaborator

Promotes the accumulated dev work to main (covers merged PRs #119 and #126).

Highlights

Unified editor — navigation & keyboard

  • ⌘K command palette to jump to any tool (searches name / family / description), with name-first ranking and a discoverable Search affordance on the rail.
  • Editor-level undo/redo shortcuts (⌘Z / ⌘⇧Z / ⌘Y), guarded against text fields.
  • Tool rail auto-scrolls the selected tool into view.

Signatures

  • Realistic-ink toggle (pen-like weight + ink bleed) and a migration to the Pointer Events API — real stylus pressure (Apple Pencil / Wacom / S-Pen / Surface Pen) with a speed-based fallback, coalesced sampling, pointer capture, and pen-priority palm rejection.

Annotate & placement

  • Form-filling icons (tick / cross / dot / circle) with inline move/resize.
  • Drag-to-resize placement, live stamp previews, focus-ring fix.

Hardening & housekeeping

  • Editor audit refactor (switch consistency, apply spinners, accent dedup, PDF robustness); single centered loader for the editor route.
  • Security: resolve CodeQL alerts; add an origin guard to the crypto worker message handler.
  • Dependency upgrades (incl. pdf-lib 6.1.10) and an Ask-PDF e2e warm-cache race fix.
  • README refreshed.

Testing

  • vp check, vp test (312 passing), vp build — green across the included work.
  • e2e suites for the editor (smoke), command palette, and signature pen/mouse/touch input all pass.

🤖 Generated with Claude Code

…ng fix

Placement & sizing UX upgrade across the canvas editor:

- Shared resize-handles module (resize-handles.ts): 8-handle hit-test, free
  + aspect-locked corner resize, selection chrome. AnnotateTool refactored
  onto it (behaviour-identical).
- Signature: place then drag a corner to resize (aspect-locked, no slider);
  Background switch (ink-only/transparent default vs opaque colour) with a
  WYSIWYG preview (transparency checker, no misleading white); fixed a placed
  signature being invisible on tool return yet still applied.
- QR / barcode: converted to a place-then-drag-resize canvas tool
  (addCodeStampAt burns explicit-rect vector art); "Same spot on all N pages"
  replicates a code to every page, still movable per page.
- Page numbers / Header & footer / Bates: live on-canvas preview (Stage)
  mirroring each writer's geometry; state moved to the tool slice; Apply
  unchanged.
- Auto-fill: fix focus ring clipped on the left inside the scrollable field
  list (overflow-y-auto also clips x) by padding the scroll box; audited the
  other scroll/overflow containers (all already padded).

Tests: resize-handles + addCodeStampAt unit tests; place-resize (desktop +
mobile) and editor-features (every fixture PDF) e2e harnesses. vp check, 306
unit tests, both editor smokes, and vp build all pass.
…, accent dedup, pdf robustness

- Toggle now renders the shared pill Switch everywhere (one binary-toggle look
  across panels); drop ExportModal's duplicate Switch and import the shared one.
- PrimaryAction + OCR 'Make searchable' show a Loader2 + aria-busy while running,
  matching every other busy button (no more spinner-less 'Working…').
- Consolidate the duplicated ACCENT='#2563eb' (signature/QR/annotate) into one
  exported constant in resize-handles.ts — single source for overlay chrome.
- metadata: empty Keywords clears the entry (no blank ['']); read tolerates
  encrypted files (ignoreEncryption) like its siblings.
- addSignature skips stale/out-of-range page indices instead of hard-throwing.
- DigitalSignature 'checking…' status gets role=status. Add metadata unit tests.
…e move/resize

- New 'Icons' tool in Annotate stamps vector glyphs for filling printed forms by
  hand — tick a checkbox, cross a box, fill a radio dot, circle a choice.
- Shared unit-square geometry (annotate.ts) drives BOTH the canvas preview and
  the pdf-lib burn, so what you place is exactly what exports.
- Unified Icon mode mirrors the signature/QR model: tap empty page to stamp
  (sticky, for many ticks in a row); tap a placed glyph to select, drag to move,
  pull a CORNER to resize (aspect-locked — never distorts); recolor/retype a
  selected one from the palette. Delete removes it.
- Add icon unit tests (geometry + burn round-trip).
- The editor route's Suspense fallback is now a full-screen CENTERED spinner
  matching EditorShell's own 'Opening PDF…' spinner, so the chunk-load → parse
  handoff shows ONE loader in ONE place (was a top spinner then a centered one).
- README: reflect the real 22 editor tools / 7 utilities and the new icons;
  drop the stale '18 tools' comment in App.tsx.
CodeQL js/missing-origin-check (medium): the dedicated worker's onmessage
accessed e.data without checking the event origin. A dedicated worker only
receives messages from the same-origin parent that spawned it (origin is the
empty string), so reject any foreign-origin message before touching the
payload — defence in depth that also clears the alert.
- js/insecure-temporary-file (high ×2): the place-resize e2e scripts wrote
  fixtures/screenshots to predictable paths in the shared OS temp dir. Default
  SHOT_DIR to a per-run unique dir via mkdtempSync(tmpdir()/'cloakpdf-e2e-*').
- js/useless-assignment-to-local (warning): drop the dead 'nh = nw / aspect'
  in resizeBBoxAspect — nh is unconditionally recomputed from the clamped width
  two lines later, so the intermediate assignment was never read. Behaviour
  unchanged (11 resize-handles unit tests still green).
Editor: drag-resize placement, signatures, annotate icons + audit pass
The warm-cache return-visit step failed reproducibly as 'composer never
enabled / stuck at Preparing'. Root cause was the TEST, not the product: after
the reload the home grid paints first and the Ask-PDF card-click navigation is
async, so the bare `input[type=file]` selector matched the HOME drop zone
(still in the DOM during the view transition). Uploading there opens the
EDITOR, not Ask PDF, so the composer never appears.

Fix: before grabbing the input, wait for the tool-only 'drop a PDF to start
chatting' hint (not the home card's 'runs entirely on-device' description) to
pin us to the Ask PDF tool with models ready, then take the last file input.

Verified: the warm path re-hydrates models from CacheStorage and the cached
index from IndexedDB and answers correctly — full `pnpm test:e2e` now passes
end to end (cold + warm overview, phone/email/address extraction, tier swap).
Adds editor-level keyboard control, the connective tissue for navigating a
23-tool editor that previously had button-only undo/redo and no quick switcher.

- ⌘/Ctrl-K opens a command palette that searches every tool by name, family,
  and description (token-based, order-independent) and leads with the global
  actions (undo/redo/reset) when available; full keyboard nav + click select.
- ⌘/Ctrl-Z undo, ⌘/Ctrl-(Shift-)Z / ⌘/Ctrl-Y redo at the editor level, guarded
  so native text undo wins inside input/textarea/contenteditable fields.
- A Search affordance pinned atop the tool rail makes the palette discoverable.
- Mirrors the home ⌘K idiom; HomeScreen unmounts in-editor so no conflict.

Verified: vp check, vp test (312), vp build, plus a new headless e2e
(command-palette.e2e.ts) and a no-regression run of editor-smoke.
Makes the signature pad feel like real pen on paper, and lets digital styluses
drive it natively.

- "Realistic ink" toggle (Draw mode, off by default): stroke weight modulates
  and a soft low-alpha blurred copy under the crisp ink simulates bleed into
  paper, via an offscreen buffer so overlapping segments don't darken the halo.
- Pad input migrated from Mouse+Touch to the Pointer Events API — one path for
  mouse, touchpad, finger, and styluses (Apple Pencil, Wacom, Android/S-Pen,
  Surface Pen). Real `pressure` drives the realistic weight when present, with a
  speed-based fallback for pressure-less devices (mouse/touch). High-rate
  coalesced samples for pens, pointer capture so a stroke survives leaving the
  canvas, and pen-priority palm rejection (a stray finger is ignored mid-pen).
- Per-point pressure stored with the stroke paths, so colour/ink-mode replays
  keep the pen look. Canvas `filter` feature-detected (weight-only fallback).

Verified: vp check, vp test (312), vp build, a new e2e (signature-pen.e2e.ts)
exercising pen-with-pressure / mouse / touch / palm rejection over CDP, and a
no-regression run of editor-smoke (which drives the pad via mouse).
Selecting a tool from the command palette (⌘K) could target one below the fold
of the scrollable rail, leaving the active tool selected but off-screen. On
active-tool change, scroll its rail button into view with `block: "nearest"`
(minimal scroll, no-op when already visible, e.g. a normal rail click) and
honour prefers-reduced-motion.

Also hardens the command-palette e2e: wait for the filtered "Page numbers" row
to render before clicking (was racing React's re-render), and add a step that
asserts a bottom tool (Attach) scrolls into view on selection.
Palette search reached descriptions, so "attach" surfaced Scrub (its blurb says
"…attachments…") above the Attach tool. Add a relevance score that ranks a
match in the tool NAME above one only in the hint/description — exact name
> name prefix > name substring, then per-token name > hint > description — and
sort the filtered results by it (roster order on ties). Description matches
still appear, just below name matches.

e2e updated to assert the ordering: "page numbers" tops Strip furniture and
"attach" tops Scrub, each selectable with a plain Enter.
Reflect the recent editor work in "What it does": signatures now support a
real-pen ink feel and pressure-sensitive styluses (Apple Pencil / Wacom /
S-Pen), and the editor has a ⌘K command palette plus undo/redo shortcuts.
Editor: ⌘K command palette, keyboard shortcuts & realistic-ink/stylus signatures
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 23, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
cloakpdf 5722186 Commit Preview URL

Branch Preview URL
Jun 23 2026, 06:43 AM

@sumitsahoo sumitsahoo merged commit a355488 into main Jun 23, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant