Stage five. pdf.js draws pages as pictures, so selecting means laying
transparent spans over them exactly where each word was painted. The
layer carries the same scale as the canvas — they drift apart otherwise
and a selection lands on the wrong words. While drawing it stops taking
pointer events entirely, or a stroke would come out as a selection.
The text is also extracted and handed to the index that already holds the
notes, so one search box finds a sentence whether it was typed or
imported. Extraction runs after the document is on screen and yields
between pages: it must never stand between the reader and the first page.
The extracted text is deliberately not sent to the server. It is
derivable from a file the server already holds, so storing it again costs
space and a second thing to encrypt for nothing gained. The price, stated
plainly in the readme, is that a PDF becomes searchable on a device once
that device has opened it — the same shape as the limitation notes have.
Text runs are joined on pdf.js's hasEOL rather than concatenated. Without
it the last word of a line glues to the first of the next and matches
nothing when searched for.
The minimal text-layer CSS is written out rather than importing
pdfjs-dist/web/pdf_viewer.css, which carries the whole reference viewer's
toolbars and dialogs.
Suite now checks the layer sits over the page rather than stacked in a
corner, that the text is transparent, that dragging selects real words,
that a word from inside the file finds the note and one that is not in it
finds nothing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>