Programmatic text selection in the Reader from plugins

31 views
Skip to first unread message

Han Jiarui

unread,
Sep 22, 2026, 4:01:08 PMSep 22
to zoter...@googlegroups.com
Hi everyone,

I'm developing Zotero-Neo, a keyboard-first Zotero plugin, and I've
run into a Reader integration point for programmatic text selection.

The workflow is:

1. The user locates visible PDF text from the keyboard.
2. The plugin resolves the match to text-layer DOM endpoints.
3. The plugin creates and adjusts a selection without using the mouse.
4. The user can then copy it, create an annotation, translate it, or
run another action on the selected text.

At the moment we can create a valid DOM `Range` / `Selection` in the
PDF text layer. The selected text is available through
`window.getSelection()` and the endpoints can be manipulated
correctly.

However, this does not appear to synchronize with the Reader's own
text-selection state.

From what I can tell, the desktop PDF Reader also maintains semantic
selection ranges internally (`PDFView._selectionRanges`). Native
Reader behavior such as selection rendering and copying uses those
ranges rather than just the DOM selection.

This caused two concrete problems for us:

- a keyboard-created DOM selection does not get the same native Reader
selection behavior as a mouse-created selection;
- trying to reuse the Reader's native copy path while only the DOM
selection existed reached `_handleCopy()` with an empty
selection-ranges array.

For now, Zotero-Neo works around this by displaying its DOM selection
separately and copying normalized DOM text. I would prefer not to
access or modify `_selectionRanges` directly.

A few questions:

1. Is there already a supported way for a plugin to programmatically
create or update a Reader text selection so that it behaves like a
mouse-created selection?
2. If not, would exposing such a capability through the Reader plugin
API be reasonable?
3. Is there a preferred representation plugins should use for text
ranges that could potentially work across PDF, EPUB, and snapshot
readers, rather than relying on PDF.js DOM nodes?

The capability I'm looking for is essentially a supported way to hand
a programmatically created text range back to the Reader, so normal
Reader behavior — rendering, copy, annotation creation, selection
popup, etc. — can operate on it.

I'm happy to test an API or submit a PR if there is a direction you'd prefer.

References:

- Zotero-Neo: https://github.com/zhongyangchuwu/Zotero-Neo
- Current Select/Flash work:
https://github.com/zhongyangchuwu/Zotero-Neo/pull/19

Thanks!
Reply all
Reply to author
Forward
0 new messages