Skip to content

Fix blank PDF editor and simplify editing controls - #19

Merged
KibouAkari merged 16 commits into
mainfrom
fix/editor-visible-canvas-and-simplified-ui-20261026
Oct 26, 2026
Merged

KibouAkari merged 16 commits into
mainfrom
fix/editor-visible-canvas-and-simplified-ui-20261026

Conversation

@KibouAkari

Copy link
Copy Markdown
Owner

Scope

One focused PR, no direct production changes until validation.

  • Keep the PDF.js-rendered page in its own immutable visible image layer under Fabric. This prevents Fabric backgrounds or reconstructed image objects from blanking a page.
  • Native text, image and shape selection remain transparent until actually changed. Image movement previews show only after edits.
  • Replace the cluttered two-row editing tools with a compact Select/Text/Highlight/Draw/Shapes/Image toolbar and separate small Undo/Delete/Zoom controls. Existing font/color inspector stays contextual.
  • Improve preview loading and page status.
  • Add real pixel-level Chromium regressions. Tests sample pixels of the PDF page, verify that readable text is present, and check the editor overlay stays transparent. This detects the user's white-page screenshot, which prior DOM-only tests missed.
  • Continue testing text replacement, export, multi-page editing and keyboard interactions.

Release criteria

GitHub CI + Chromium E2E green. Do not merge until the sample PDFs display readable content and exported edits remain valid. Complex PDFs and OCR have explicit limitations.

@vercel

vercel Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
s-pdf-api Ready Ready Preview Oct 26, 2026 9:48pm UTC

Request Review

@KibouAkari
KibouAkari marked this pull request as ready for review October 26, 2026 21:51
Copilot AI balanced review requested due to automatic review settings October 26, 2026 21:51
@KibouAkari
KibouAkari merged commit 413606d into main Oct 26, 2026
5 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Native-image restoration still creates opaque overlays, and viewport clipping and zoom behavior need correction.

3 open issues
What changed in this PR

This PR addresses blank PDF editor pages by separating the rendered PDF from Fabric’s editing layer, while simplifying controls and strengthening browser regression checks.

Changes:

  • Add a dedicated PDF image layer, transparent selection targets, and clearer loading status.
  • Compact the editing toolbar and increase typesetting space for native text replacements.
  • Add pixel-based Chromium checks and update editor documentation.
File Description
tests/​e2e/​editor-viewport.mjs Check page-image pixels and update toolbar interactions.
tests/​e2e/​editor-smoke.mjs Add rendering checks, screenshots, and export diagnostics.
services/​converter/​tests/​test_native_editor.py Cover replacement text in tight selection boxes.
services/​converter/​editor_native.py Allow additional height for replacement text.
README.md Describe the revised editor layers and controls.
docs/​TESTING.md Document visual regressions and manual validation.
docs/​EDITOR.md Explain rendering layers, controls, and backend responsibilities.
apps/​web/​src/​pages/​tools/​Editor.tsx Separate page rendering from editing and simplify controls.
.github/​workflows/​editor-e2e.yml Validate screenshot pixels and retain screenshot diagnostics.

Review effort: Balanced

Comment on lines +402 to +405
object.spdfSrc = src;
// Never duplicate entire raster images as opaque editable overlays.
// The underlying PDF layer owns its visuals until an object changes.
canvas.add(object);
<Button size="sm" variant="secondary" onClick={() => void stepHistory(1)} title="Redo (Ctrl+Y)" aria-label="Redo"><Redo2 className="h-4 w-4" /></Button>
<Button size="sm" variant="secondary" onClick={deleteSelected} disabled={!selected} title="Delete selected (Del)" aria-label="Delete selected"><Trash2 className="h-4 w-4" /></Button>
<span className="mx-2 h-5 w-px bg-ink-600" aria-hidden="true" />
<Button size="sm" variant="secondary" onClick={() => setZoom((v) => Math.max(0.2, +(v - 0.15).toFixed(2)))} title="Zoom out" aria-label="Zoom out"><ZoomOut className="h-4 w-4" /></Button>
<div className="relative shrink-0 overflow-hidden" style={{ width: pagePixels.width * zoom, height: pagePixels.height * zoom }}>
<div style={{ width: pagePixels.width, height: pagePixels.height, transform: `scale(${zoom})`, transformOrigin: "top left", pointerEvents: panMode ? "none" : "auto" }}>
<canvas ref={attachCanvas} className="rounded-sm shadow-lg" />
<div className="relative shrink-0 rounded-sm bg-white shadow-lg" style={{ width: pagePixels.width * zoom, height: pagePixels.height * zoom }}>

This branch was successfully deployed

1 active deployment
Preview – s-pdf-api — f3f48f66 Deployed Oct 26, 2026 by vercel[bot]
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.

2 participants