fix(reader): PDF highlights never appeared — isPDF read too early + overlay shrunk by pdf.js transform
Two bugs broke the Phase 3b PDF highlight flow end to end: 1. Selection capture never attached: reader.ts read renderer.isPDF before view.init() rendered the first spread, but the renderer only sets that flag once frames exist (PDF frames carry pdf.js onZoom). The stale undefined copy gated the pointerup selection listener off, so selecting PDF text did nothing. The listener now gates structurally on the loaded document having a .textLayer (true for every PDF page, false for comics), and isPDF is re-read after init — which also finally makes the Smart|Pan|Text control and the saved pointer mode apply on PDFs. 2. Highlights rendered invisibly: the overlay SVG lived inside the page iframe, whose <html> pdf.js scales by 1/devicePixelRatio — shrinking the overlay into the top-left corner on any dpr != 1 display. The fork (1c0ebf3) now renders annotation rects host-side, inside the frame wrapper element, positioned in percentages of the visible page box — immune to the html transform, zoom re-renders, comic iframe scaling, and pan/zoom.
This commit is contained in:
+1
-1
@@ -12,7 +12,7 @@
|
||||
"dev": "npm run build:ts:dev && npm run build:css"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bookhoard/foliate-js": "git+https://github.com/john-okeefe/foliate-js.git#aba68d8",
|
||||
"@bookhoard/foliate-js": "git+https://github.com/john-okeefe/foliate-js.git#1c0ebf3",
|
||||
"alpinejs": "^3.15.8",
|
||||
"chart.js": "^4.5.1",
|
||||
"highlight.js": "^11.11.1",
|
||||
|
||||
@@ -576,9 +576,6 @@ document.addEventListener("alpine:init", () => {
|
||||
this.book.dir = "rtl";
|
||||
}
|
||||
this.isPDF = (this.renderer as any).isPDF;
|
||||
if (this.isPDF) {
|
||||
this.renderer.setAttribute("interaction-mode", this.interactionMode);
|
||||
}
|
||||
// Click on a PDF/fixed-layout highlight rect → edit popover.
|
||||
this.renderer.addEventListener(
|
||||
"show-rect-annotation",
|
||||
@@ -671,7 +668,10 @@ document.addEventListener("alpine:init", () => {
|
||||
);
|
||||
}
|
||||
// PDF textLayer selection → rect-fraction highlight popover.
|
||||
if (this.isPDF) {
|
||||
// Detected structurally: renderer.isPDF isn't set until the first
|
||||
// spread renders (during view.init), which is after this listener
|
||||
// attaches — the stale copy here would always be falsy.
|
||||
if (this.isFixedLayout && doc.querySelector(".textLayer")) {
|
||||
const checkPDFSelection = () => {
|
||||
const sel = doc.getSelection();
|
||||
if (!sel || sel.isCollapsed || !sel.rangeCount) return;
|
||||
@@ -816,6 +816,14 @@ document.addEventListener("alpine:init", () => {
|
||||
} else {
|
||||
await this.view.init({})
|
||||
}
|
||||
// The renderer only knows it's a PDF once frames exist (they carry
|
||||
// pdf.js onZoom), i.e. after init has rendered the first spread.
|
||||
// Read it now and apply the saved pointer mode — this also makes the
|
||||
// Smart|Pan|Text control appear for PDFs.
|
||||
this.isPDF = !!this.renderer?.isPDF;
|
||||
if (this.isPDF) {
|
||||
this.renderer.setAttribute("interaction-mode", this.interactionMode);
|
||||
}
|
||||
this.initTime = Date.now();
|
||||
this.fetchReadingSpeed();
|
||||
this.refreshAnnotations();
|
||||
|
||||
Reference in New Issue
Block a user