Skip to content

Add the eraser editor from mozilla/pdf.js#20227 - #14

Open
legraina wants to merge 4 commits into
stephanrauh:bleeding-edgefrom
legraina:eraser-bleeding-edge
Open

Add the eraser editor from mozilla/pdf.js#20227#14
legraina wants to merge 4 commits into
stephanrauh:bleeding-edgefrom
legraina:eraser-bleeding-edge

Conversation

@legraina

Copy link
Copy Markdown

What

Ports the eraser editor from the (still open) upstream PR mozilla/pdf.js#20227 onto the 6.2-based bleeding-edge branch: a new toolbar tool that erases ink annotations by dragging a circular cursor over them, with adjustable thickness and full undo/redo support.

Changes

  • src/display/editor/eraser.js (new): the EraserEditor, a full-page editor that tracks pointer sessions, shows a circular cursor, hit-tests erasable editors, and commits erase operations as undoable commands.
  • src/display/editor/ink.js: InkEditor becomes erasable — points within the eraser radius are removed, paths are split/rebuilt, and the editor is removed when nothing is left.
  • src/display/editor/editor.js / draw.js: the erasable/erase()/endErase() API and a _drawOutlines getter.
  • src/shared/util.js: AnnotationEditorType.ERASER and the ERASER_THICKNESS/ERASER_STEP param types.
  • web/: toolbar button + thickness slider (viewer.html, viewer.js, toolbar.js, annotation_editor_params.js), CSS (icon, eraserEditing cursor, .eraserCursor), new SVG icon, and an enableEraser viewer option (app.js, app_options.js).

Adaptations to this fork (not a blind copy of the PR)

  • CurrentPointers calls go through the AnnotationEditorUIManager instance (the Pdf.js not working in safari browser on MAC OSX 10.8.2, safari version 6.0.1  mozilla/pdf.js#3260 redesign) instead of the upstream static class.
  • setDims() takes no arguments in 6.2.
  • The PR's isFromEvent changes in tools.js/pdf_viewer.js are omitted: the pickOwner/claimFor ownership design already resets the pointer type on every mode change.
  • InkEditor.#pagePointToLayer uses viewport.convertToViewportPoint() instead of the PR's hand-rolled conversion, so erasing follows the current view rotation rather than the rotation captured at creation time.
  • The eraser toolbar click-binding follows this fork's pattern of Angular-handled editor buttons (Font is not rendered mozilla/pdf.js#2900); the active toggleExpandedBtn/disabled handling is null-guarded for custom-toolbar mode.

Notes

  • Like the upstream PR, no l10n strings are added yet — pdfjs-editor-eraser-button(-label) will render untranslated.
  • The ngx-extended-pdf-viewer Angular side still needs its own eraser button component to expose the tool, since editor-button clicks are delegated to Angular.

🤖 Generated with Claude Code

Port the EraserEditor (eraser tool to erase ink annotations) onto the
6.2-based bleeding-edge branch, adapted to this fork:

- CurrentPointers calls go through the AnnotationEditorUIManager
  instance instead of the upstream static class.
- setDims() takes no arguments in 6.2.
- The PR's isFromEvent changes in tools.js/pdf_viewer.js are not needed
  here: the pickOwner/claimFor ownership design already resets the
  pointer type on every mode change.
- InkEditor.#pagePointToLayer uses viewport.convertToViewportPoint()
  instead of a hand-rolled conversion, so it follows the current view
  rotation instead of the rotation captured at creation time.
- The eraser toolbar button binding follows the fork's pattern of
  Angular-handled editor buttons; the enableEraser option gates it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 31, 2026 16:08

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

legraina and others added 3 commits August 31, 2026 15:25
Unlike the other editor buttons, which ngx-extended-pdf-viewer replaces
with Angular components, the eraser button lives in this viewer's own
toolbar: move its click binding out of the mozilla#2900 commented-out block so
toolbar.js dispatches switchannotationeditormode directly, and drop the
primaryEditorEraser lookup in viewer.js since no Angular counterpart
exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The FreeText/Highlight/Ink/Stamp/Comment/Signature button bindings were
deactivated in toolbar.js (mozilla#2900/mozilla#3069) because ngx-extended-pdf-viewer
handles those clicks in Angular, and having both handlers made the mode
toggle back to NONE immediately. In the standalone viewer there is no
Angular, so those buttons dispatched nothing and only the eraser worked.

Re-bind them - eraser included, so an Angular-side eraser handler will
not double-dispatch either - guarded by globalThis.STANDALONE_VIEWER,
which is only set when the viewer bootstraps itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four fixes to match the behavior of the upstream eraser
(mozilla#20227):

- Port the missing #toogleEditorPointerEvents to the annotation editor
  layer: in eraser mode it disables pointer events on the editor divs
  (upstream behavior) so hovering a drawing erases it instead of
  selecting it. The port had substituted
  toggleAnnotationLayerPointerEvents, which targets the annotation
  layer, leaving the editors interactive.
- Restore upstream's InkEditor.#pagePointToLayer conversion. The
  convertToViewportPoint-based rewrite produced coordinates that never
  fell within the eraser radius, so nothing was ever erased.
- Never select or drag the EraserEditor (override pointerdown): once
  selected, its edit toolbar covered the page-spanning eraser div and
  swallowed the next pointerdown, blocking any further erase session.
  Also fix the CSS selector meant to hide edit toolbars in eraser mode
  (.eraserEditing.editToolbar never matched anything).
- Make undo work after a drawing is fully erased: the editor is removed
  at that point, so the generic undo crashed on this.parent being null;
  re-attach the editor through the captured parent.addOrRebuild()
  instead, and reset #points so a later erase session re-serializes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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