@laminapdf/viewer 0.2.0-alpha.3 → 0.2.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/README.md +102 -8
  2. package/dist/client.d.ts +75 -2
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +192 -32
  5. package/dist/client.js.map +1 -1
  6. package/dist/find/controller.d.ts +73 -0
  7. package/dist/find/controller.d.ts.map +1 -0
  8. package/dist/find/controller.js +227 -0
  9. package/dist/find/controller.js.map +1 -0
  10. package/dist/find/fold.d.ts +23 -0
  11. package/dist/find/fold.d.ts.map +1 -0
  12. package/dist/find/fold.js +99 -0
  13. package/dist/find/fold.js.map +1 -0
  14. package/dist/find/page.d.ts +44 -0
  15. package/dist/find/page.d.ts.map +1 -0
  16. package/dist/find/page.js +173 -0
  17. package/dist/find/page.js.map +1 -0
  18. package/dist/first-draw.d.ts +10 -0
  19. package/dist/first-draw.d.ts.map +1 -0
  20. package/dist/first-draw.js +33 -0
  21. package/dist/first-draw.js.map +1 -0
  22. package/dist/history/history.d.ts +65 -0
  23. package/dist/history/history.d.ts.map +1 -0
  24. package/dist/history/history.js +135 -0
  25. package/dist/history/history.js.map +1 -0
  26. package/dist/index.d.ts +13 -2
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +4 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/layers/box.d.ts +10 -0
  31. package/dist/layers/box.d.ts.map +1 -0
  32. package/dist/layers/box.js +19 -0
  33. package/dist/layers/box.js.map +1 -0
  34. package/dist/layers/copy.d.ts +26 -0
  35. package/dist/layers/copy.d.ts.map +1 -0
  36. package/dist/layers/copy.js +150 -0
  37. package/dist/layers/copy.js.map +1 -0
  38. package/dist/layers/highlight-layer.d.ts +31 -0
  39. package/dist/layers/highlight-layer.d.ts.map +1 -0
  40. package/dist/layers/highlight-layer.js +95 -0
  41. package/dist/layers/highlight-layer.js.map +1 -0
  42. package/dist/layers/link-layer.d.ts +68 -0
  43. package/dist/layers/link-layer.d.ts.map +1 -0
  44. package/dist/layers/link-layer.js +279 -0
  45. package/dist/layers/link-layer.js.map +1 -0
  46. package/dist/layers/link-url.d.ts +19 -0
  47. package/dist/layers/link-url.d.ts.map +1 -0
  48. package/dist/layers/link-url.js +47 -0
  49. package/dist/layers/link-url.js.map +1 -0
  50. package/dist/layers/spans.d.ts +36 -0
  51. package/dist/layers/spans.d.ts.map +1 -0
  52. package/dist/layers/spans.js +103 -0
  53. package/dist/layers/spans.js.map +1 -0
  54. package/dist/layers/structure-layer.d.ts +15 -0
  55. package/dist/layers/structure-layer.d.ts.map +1 -0
  56. package/dist/layers/structure-layer.js +155 -0
  57. package/dist/layers/structure-layer.js.map +1 -0
  58. package/dist/layers/text-layer.d.ts +70 -0
  59. package/dist/layers/text-layer.d.ts.map +1 -0
  60. package/dist/layers/text-layer.js +576 -0
  61. package/dist/layers/text-layer.js.map +1 -0
  62. package/dist/layout/range.d.ts +3 -0
  63. package/dist/layout/range.d.ts.map +1 -0
  64. package/dist/layout/range.js +5 -0
  65. package/dist/layout/range.js.map +1 -0
  66. package/dist/network/watch.d.ts +30 -0
  67. package/dist/network/watch.d.ts.map +1 -0
  68. package/dist/network/watch.js +181 -0
  69. package/dist/network/watch.js.map +1 -0
  70. package/dist/protocol.d.ts +193 -6
  71. package/dist/protocol.d.ts.map +1 -1
  72. package/dist/protocol.js +16 -4
  73. package/dist/protocol.js.map +1 -1
  74. package/dist/render/tiles.d.ts +43 -3
  75. package/dist/render/tiles.d.ts.map +1 -1
  76. package/dist/render/tiles.js +62 -10
  77. package/dist/render/tiles.js.map +1 -1
  78. package/dist/source/http-range.d.ts +59 -0
  79. package/dist/source/http-range.d.ts.map +1 -0
  80. package/dist/source/http-range.js +284 -0
  81. package/dist/source/http-range.js.map +1 -0
  82. package/dist/source/opfs.d.ts +35 -0
  83. package/dist/source/opfs.d.ts.map +1 -0
  84. package/dist/source/opfs.js +178 -0
  85. package/dist/source/opfs.js.map +1 -0
  86. package/dist/thumbnails/strip.d.ts +37 -0
  87. package/dist/thumbnails/strip.d.ts.map +1 -0
  88. package/dist/thumbnails/strip.js +324 -0
  89. package/dist/thumbnails/strip.js.map +1 -0
  90. package/dist/view/budgets.d.ts +29 -0
  91. package/dist/view/budgets.d.ts.map +1 -0
  92. package/dist/view/budgets.js +63 -0
  93. package/dist/view/budgets.js.map +1 -0
  94. package/dist/view/touch.d.ts +71 -0
  95. package/dist/view/touch.d.ts.map +1 -0
  96. package/dist/view/touch.js +220 -0
  97. package/dist/view/touch.js.map +1 -0
  98. package/dist/view/user-select.d.ts +3 -0
  99. package/dist/view/user-select.d.ts.map +1 -0
  100. package/dist/view/user-select.js +10 -0
  101. package/dist/view/user-select.js.map +1 -0
  102. package/dist/view/viewer.d.ts +102 -1
  103. package/dist/view/viewer.d.ts.map +1 -1
  104. package/dist/view/viewer.js +660 -95
  105. package/dist/view/viewer.js.map +1 -1
  106. package/dist/worker/document.d.ts +53 -1
  107. package/dist/worker/document.d.ts.map +1 -1
  108. package/dist/worker/document.js +222 -24
  109. package/dist/worker/document.js.map +1 -1
  110. package/dist/worker/entry.d.ts +1 -1
  111. package/dist/worker/entry.d.ts.map +1 -1
  112. package/dist/worker/entry.js +2 -0
  113. package/dist/worker/entry.js.map +1 -1
  114. package/dist/worker/find.d.ts +7 -0
  115. package/dist/worker/find.d.ts.map +1 -0
  116. package/dist/worker/find.js +46 -0
  117. package/dist/worker/find.js.map +1 -0
  118. package/dist/worker/methods.d.ts.map +1 -1
  119. package/dist/worker/methods.js +49 -4
  120. package/dist/worker/methods.js.map +1 -1
  121. package/dist/worker/navigation.d.ts +10 -0
  122. package/dist/worker/navigation.d.ts.map +1 -0
  123. package/dist/worker/navigation.js +34 -0
  124. package/dist/worker/navigation.js.map +1 -0
  125. package/dist/worker/network.d.ts +4 -0
  126. package/dist/worker/network.d.ts.map +1 -0
  127. package/dist/worker/network.js +24 -0
  128. package/dist/worker/network.js.map +1 -0
  129. package/dist/worker/print.d.ts +14 -0
  130. package/dist/worker/print.d.ts.map +1 -0
  131. package/dist/worker/print.js +49 -0
  132. package/dist/worker/print.js.map +1 -0
  133. package/dist/worker/recent-pages.d.ts +14 -0
  134. package/dist/worker/recent-pages.d.ts.map +1 -0
  135. package/dist/worker/recent-pages.js +53 -0
  136. package/dist/worker/recent-pages.js.map +1 -0
  137. package/dist/worker/render.d.ts +5 -2
  138. package/dist/worker/render.d.ts.map +1 -1
  139. package/dist/worker/render.js +16 -6
  140. package/dist/worker/render.js.map +1 -1
  141. package/dist/worker/text.d.ts +25 -0
  142. package/dist/worker/text.d.ts.map +1 -0
  143. package/dist/worker/text.js +82 -0
  144. package/dist/worker/text.js.map +1 -0
  145. package/dist/zoom/destination.d.ts +18 -0
  146. package/dist/zoom/destination.d.ts.map +1 -0
  147. package/dist/zoom/destination.js +56 -0
  148. package/dist/zoom/destination.js.map +1 -0
  149. package/package.json +6 -5
@@ -0,0 +1,576 @@
1
+ // The text layer (web-app §6 C5): on every mounted page, one transparent span per text run of
2
+ // Lamina PDF's extraction, laid over the rendered glyphs, so the browser's own selection, copy
3
+ // and screen readers work on the page's text. Spans are placed in page points inside a box that
4
+ // one CSS transform scales and rotates to the page's current size, so a zoom or a rotation moves
5
+ // no span. Only the spans are selectable, never canvases or gaps, so a selection runs from one
6
+ // page into the next; the pages it touches stay mounted while it lasts. Copy writes the extracted
7
+ // text of the part of a selection inside the viewer: by paragraph in the extraction's reading
8
+ // order, or exact, as laid out (layers/copy.ts). Alt/Option-drag, or a drag in column mode,
9
+ // selects the runs inside a rectangle instead (a column of a multi-column page), which the layer
10
+ // marks itself, since a browser selection can't hold a rectangle.
11
+ import { range as range_ } from "../layout/range.js";
12
+ import { setUserSelect } from "../view/user-select.js";
13
+ import { placeBox } from "./box.js";
14
+ import { copySelection } from "./copy.js";
15
+ import { layoutSpans } from "./spans.js";
16
+ import { StructureLayer } from "./structure-layer.js";
17
+ /** Numbers each text layer, for its span ids. */
18
+ let nextViewer = 0;
19
+ /** The text layer of one viewer. */
20
+ export class TextLayer {
21
+ name = "text";
22
+ #host;
23
+ #options;
24
+ #pages = new Map();
25
+ #specs = new WeakMap();
26
+ #structure;
27
+ #cleanup = [];
28
+ #points = [];
29
+ /** Each mounted page's size in CSS px, as the last resize gave it. */
30
+ #sizes = new Map();
31
+ #pointerType = "";
32
+ /** A pointer is down in the viewer: a selection it makes isn't settled until it comes up. */
33
+ #pointerDown = false;
34
+ /** The mode the next copy event writes in (a command may ask for exact). */
35
+ #copyMode = "paragraph";
36
+ /** Each page's reading-order blocks, once read; a page being read has a pending entry. */
37
+ #blocks = new Map();
38
+ /** Whether a plain drag selects a rectangle (column mode), as an Alt-drag always does. */
39
+ #columnMode = false;
40
+ /** The column selection: its pieces and spans, while it lasts. */
41
+ #column;
42
+ /** The rectangle being dragged out for a column selection. */
43
+ #drag;
44
+ /** Span ids' prefix, unique to this viewer, so two viewers on a page never share an id. */
45
+ #idPrefix = `lamina-text-${nextViewer++}-`;
46
+ /** Counts opens: a structure tree answered for an earlier document is dropped. */
47
+ #generation = 0;
48
+ /** Whether the last selection change was in this viewer, so a selection elsewhere is told only once. */
49
+ #selecting = false;
50
+ constructor(host, options = {}) {
51
+ this.#host = host;
52
+ this.#options = options;
53
+ this.#structure = new StructureLayer(host.root, options.untaggedLabel ?? "Untagged document", this.#idPrefix);
54
+ // Only the spans are selectable (set on each); what holds nothing to select sets `none` on
55
+ // itself (view/user-select.ts says why no ancestor of the spans may).
56
+ this.#listen(document, "selectionchange", () => this.#selectionChanged());
57
+ this.#listen(document, "copy", (e) => this.#copy(e));
58
+ this.#listen(host.root, "keydown", (e) => this.#selectAll(e));
59
+ this.#listen(host.root, "pointerdown", (e) => this.#pointerDownIn(e));
60
+ this.#listen(document, "pointermove", (e) => this.#dragTo(e));
61
+ this.#listen(document, "pointerup", (e) => this.#pointerUp(e));
62
+ this.#listen(document, "pointercancel", (e) => this.#pointerUp(e));
63
+ // On the document: the drag that made a column selection kept the focus where it was.
64
+ this.#listen(document, "keydown", (e) => {
65
+ if (e.key === "Escape" && this.#column !== undefined)
66
+ this.#clearColumn(true);
67
+ });
68
+ }
69
+ /** Whether a plain drag selects a rectangle (column mode). */
70
+ get columnMode() {
71
+ return this.#columnMode;
72
+ }
73
+ set columnMode(on) {
74
+ this.#columnMode = on;
75
+ }
76
+ /**
77
+ * Copies the selection in `mode` to the clipboard, as the copy event would (for a command or a
78
+ * toolbar button; it must run in a user gesture). Resolves false when nothing is selected or
79
+ * the clipboard refused.
80
+ */
81
+ async copy(mode = "paragraph") {
82
+ const pieces = this.#selectedPieces();
83
+ if (pieces === undefined || pieces.length === 0)
84
+ return false;
85
+ // The browser's own copy, in this gesture: the copy event writes both formats.
86
+ this.#copyMode = mode;
87
+ try {
88
+ if (document.execCommand("copy"))
89
+ return true;
90
+ }
91
+ catch {
92
+ // No synchronous copy here: the async clipboard below.
93
+ }
94
+ finally {
95
+ this.#copyMode = "paragraph";
96
+ }
97
+ const copied = copySelection(pieces, mode, (page) => this.#blocksOf(page));
98
+ try {
99
+ if (typeof ClipboardItem !== "undefined" && navigator.clipboard?.write !== undefined) {
100
+ await navigator.clipboard.write([
101
+ new ClipboardItem({
102
+ "text/plain": new Blob([copied.text], { type: "text/plain" }),
103
+ "text/html": new Blob([copied.html], { type: "text/html" }),
104
+ }),
105
+ ]);
106
+ }
107
+ else
108
+ await navigator.clipboard.writeText(copied.text);
109
+ return true;
110
+ }
111
+ catch {
112
+ return false;
113
+ }
114
+ }
115
+ /** A new document: its page sizes, and its structure tree, read once. */
116
+ open(document) {
117
+ this.#points = document.pages.map((p) => ({ width: p.width, height: p.height }));
118
+ this.#structure.reset();
119
+ this.#blocks.clear();
120
+ const opening = ++this.#generation;
121
+ this.#host.client
122
+ .structure()
123
+ .then((structure) => {
124
+ // Another document opened while this one's tree was read: it isn't this document's.
125
+ if (opening !== this.#generation)
126
+ return;
127
+ this.#structure.show(structure);
128
+ // Pages whose text came first: link them now that their elements exist.
129
+ for (const page of this.#pages.keys())
130
+ this.#linkPage(page);
131
+ })
132
+ .catch(() => {
133
+ // No structure (a worker restart, a closed document): the spans still read in order.
134
+ });
135
+ }
136
+ onMount(page, slot) {
137
+ const box = document.createElement("div");
138
+ box.className = "lamina-text-layer";
139
+ // The spans lie over the canvas, so an app's ::selection fill would paint over the glyphs it
140
+ // selects. With the box multiplied over the canvas, the fill shows where the page is paper and
141
+ // the ink stays as dark as drawn: the tint sits under the text, as the find highlights do.
142
+ Object.assign(box.style, {
143
+ position: "absolute",
144
+ left: "0",
145
+ top: "0",
146
+ transformOrigin: "0 0",
147
+ mixBlendMode: "multiply",
148
+ });
149
+ slot.append(box);
150
+ const text = { box, abort: new AbortController(), spans: [] };
151
+ this.#pages.set(page, text);
152
+ this.#host.client
153
+ .pageText(page, { signal: text.abort.signal })
154
+ .then((data) => {
155
+ if (this.#pages.get(page) !== text)
156
+ return;
157
+ this.#fill(page, text, layoutSpans(data.runs, data.quads));
158
+ })
159
+ .catch(() => {
160
+ // Aborted (the page left), or a page whose text can't be read: it stays without text.
161
+ });
162
+ }
163
+ onUnmount(page) {
164
+ const text = this.#pages.get(page);
165
+ if (text === undefined)
166
+ return;
167
+ text.abort.abort();
168
+ text.box.remove();
169
+ this.#structure.unlink(page);
170
+ this.#pages.delete(page);
171
+ this.#sizes.delete(page);
172
+ this.#blocks.delete(page);
173
+ if (this.#column?.pieces.some((p) => p.page === page))
174
+ this.#clearColumn(true);
175
+ }
176
+ onZoom(page, _slot, size) {
177
+ this.#sizes.set(page, size);
178
+ this.#place(page, size);
179
+ }
180
+ /** Places every page's box again: the view turned. */
181
+ refresh() {
182
+ for (const [page, size] of this.#sizes)
183
+ this.#place(page, size);
184
+ }
185
+ /** Scales and turns page `page`'s box to `size` at the view's rotation. */
186
+ #place(page, size) {
187
+ const text = this.#pages.get(page);
188
+ const points = this.#points[page];
189
+ if (text === undefined || points === undefined)
190
+ return;
191
+ placeBox(text.box, points, size, this.#host.rotation());
192
+ }
193
+ /** Stops listening; the viewer calls it on destroy. */
194
+ destroy() {
195
+ for (const f of this.#cleanup.splice(0))
196
+ f();
197
+ for (const page of [...this.#pages.keys()])
198
+ this.onUnmount(page);
199
+ this.#structure.reset();
200
+ }
201
+ #listen(target, type, f) {
202
+ target.addEventListener(type, f);
203
+ this.#cleanup.push(() => target.removeEventListener(type, f));
204
+ }
205
+ /**
206
+ * The page's spans, built once: written, then every natural width read in one pass, then each
207
+ * stretched to its run's width in another, so the page costs one layout, not one per span.
208
+ */
209
+ #fill(page, text, specs) {
210
+ const fragment = document.createDocumentFragment();
211
+ text.spans = specs.map((spec, k) => {
212
+ const span = document.createElement("span");
213
+ span.id = `${this.#idPrefix}${page}-${k}`;
214
+ span.textContent = spec.text;
215
+ if (spec.rtl)
216
+ span.dir = "rtl";
217
+ Object.assign(span.style, {
218
+ position: "absolute",
219
+ left: `${spec.left}px`,
220
+ top: `${spec.top}px`,
221
+ fontSize: `${spec.height}px`,
222
+ lineHeight: "1",
223
+ fontFamily: "sans-serif",
224
+ whiteSpace: "pre",
225
+ color: "transparent",
226
+ cursor: "text",
227
+ transformOrigin: "0 0",
228
+ ...(this.#options.outline === true ? { outline: "1px solid rgb(220 0 0 / 0.7)" } : {}),
229
+ });
230
+ setUserSelect(span, "text");
231
+ this.#specs.set(span, { page, spec });
232
+ fragment.append(span);
233
+ return span;
234
+ });
235
+ text.box.append(fragment);
236
+ // Reads, then writes: each natural width in points, fractional, with the box briefly
237
+ // untransformed (its zoom and turn would scale and rotate the rects).
238
+ const placed = text.box.style.transform;
239
+ text.box.style.transform = "none";
240
+ // The box is its points wide: what the page around the viewer scales it by (a zoomed host)
241
+ // comes out of every width.
242
+ const outside = text.box.getBoundingClientRect().width / Math.max(1, text.box.offsetWidth);
243
+ const natural = text.spans.map((span) => span.getBoundingClientRect().width / (outside || 1));
244
+ text.box.style.transform = placed;
245
+ specs.forEach((spec, k) => {
246
+ const span = text.spans[k];
247
+ const fit = (natural[k] ?? 0) > 0 ? spec.width / natural[k] : 1;
248
+ span.style.transform = `rotate(${spec.angle}rad) scaleX(${fit})`;
249
+ });
250
+ this.#linkPage(page);
251
+ }
252
+ /** Gives the structure tree's elements the page's spans that their marked content drew. */
253
+ #linkPage(page) {
254
+ const text = this.#pages.get(page);
255
+ if (text === undefined)
256
+ return;
257
+ for (const span of text.spans) {
258
+ const mcid = this.#specs.get(span)?.spec.mcid;
259
+ if (mcid !== undefined)
260
+ this.#structure.link(page, mcid, span.id);
261
+ }
262
+ }
263
+ /** The mounted pages' spans, in page and reading order. */
264
+ #spansInOrder() {
265
+ return [...this.#pages.entries()].sort(([a], [b]) => a - b).flatMap(([, text]) => text.spans);
266
+ }
267
+ /**
268
+ * The selection's range in this viewer. A selection that runs on past the viewer into the app
269
+ * around it is cut at the first or last mounted span, so copy, the pinned pages and
270
+ * `onSelection` keep to the page text. `undefined` when it doesn't reach the viewer, or when its
271
+ * other end is in another viewer: neither could tell the whole of it, so both leave it to the
272
+ * browser.
273
+ */
274
+ #range() {
275
+ const selection = document.getSelection();
276
+ if (selection === null || selection.rangeCount === 0 || selection.isCollapsed)
277
+ return undefined;
278
+ const range = selection.getRangeAt(0);
279
+ const root = this.#host.root;
280
+ if (root.contains(range.commonAncestorContainer))
281
+ return range;
282
+ if (!range.intersectsNode(root))
283
+ return undefined;
284
+ const outside = (node) => !root.contains(node);
285
+ const inOtherViewer = (node) => outside(node) && (node instanceof Element ? node : node.parentElement)?.closest(".lamina-viewer") != null;
286
+ if (inOtherViewer(range.startContainer) || inOtherViewer(range.endContainer))
287
+ return undefined;
288
+ const spans = this.#spansInOrder();
289
+ const first = spans[0];
290
+ const last = spans.at(-1);
291
+ if (first === undefined || last === undefined)
292
+ return undefined;
293
+ const inside = range.cloneRange();
294
+ if (outside(range.startContainer))
295
+ inside.setStart(first, 0);
296
+ if (outside(range.endContainer))
297
+ inside.setEnd(last, last.childNodes.length);
298
+ return inside.collapsed ? undefined : inside;
299
+ }
300
+ /** The selected part of each span the selection touches, in order. */
301
+ #pieces(range) {
302
+ const pieces = [];
303
+ for (const span of this.#spansInOrder()) {
304
+ const info = this.#specs.get(span);
305
+ if (info === undefined || !range.intersectsNode(span))
306
+ continue;
307
+ const full = span.textContent ?? "";
308
+ const start = span.contains(range.startContainer) ? offsetIn(span, range.startContainer, range.startOffset) : 0;
309
+ const end = span.contains(range.endContainer) ? offsetIn(span, range.endContainer, range.endOffset) : full.length;
310
+ const text = full.slice(start, end);
311
+ if (text !== "")
312
+ pieces.push({ page: info.page, text, span: info.spec });
313
+ }
314
+ return pieces;
315
+ }
316
+ /** The selection's pieces: the browser selection's in this viewer, else the column's. */
317
+ #selectedPieces() {
318
+ const range = this.#range();
319
+ if (range !== undefined)
320
+ return this.#pieces(range);
321
+ // The column, unless something else is selected or a field has the focus: that copy is theirs.
322
+ const selection = document.getSelection();
323
+ const elsewhere = selection !== null && selection.rangeCount > 0 && !selection.isCollapsed;
324
+ const field = document.activeElement?.closest("input, textarea, [contenteditable]") ?? null;
325
+ return elsewhere || field !== null ? undefined : this.#column?.pieces;
326
+ }
327
+ /**
328
+ * Page `page`'s reading-order blocks if read; else starts reading them, and tells the app the
329
+ * selection again once they come, its text then in reading order. A page whose blocks can't be
330
+ * read gets none, once: its text is joined in run order.
331
+ */
332
+ #blocksOf(page) {
333
+ const known = this.#blocks.get(page);
334
+ if (known === "reading")
335
+ return undefined;
336
+ if (known !== undefined)
337
+ return known;
338
+ this.#blocks.set(page, "reading");
339
+ const asked = this.#generation;
340
+ const store = (blocks) => {
341
+ // Another document opened since: these blocks are the old one's.
342
+ if (asked !== this.#generation || this.#blocks.get(page) !== "reading")
343
+ return;
344
+ this.#blocks.set(page, blocks);
345
+ this.#retell();
346
+ };
347
+ this.#host.client
348
+ .readingOrder(page)
349
+ .then(store)
350
+ .catch(() => store([]));
351
+ return undefined;
352
+ }
353
+ /** Tells the app about the selection as it is now (its text may read better with new blocks). */
354
+ #retell() {
355
+ if (!this.#selecting)
356
+ return;
357
+ if (this.#column !== undefined) {
358
+ this.#tell(this.#column.pieces, this.#column.spans.map((s) => s.getBoundingClientRect()), true);
359
+ return;
360
+ }
361
+ const range = this.#range();
362
+ if (range !== undefined)
363
+ this.#tell(this.#pieces(range), [...range.getClientRects()], false);
364
+ }
365
+ #copy(event) {
366
+ const pieces = this.#selectedPieces();
367
+ if (pieces === undefined || event.clipboardData === null)
368
+ return;
369
+ const copied = copySelection(pieces, this.#copyMode, (page) => this.#blocksOf(page));
370
+ event.clipboardData.setData("text/plain", copied.text);
371
+ event.clipboardData.setData("text/html", copied.html);
372
+ event.preventDefault();
373
+ }
374
+ /** Ctrl/Cmd+A in the viewer selects the mounted pages' text (find reaches the rest). */
375
+ #selectAll(event) {
376
+ if (event.key.toLowerCase() !== "a" || !(event.ctrlKey || event.metaKey) || event.altKey)
377
+ return;
378
+ const spans = this.#spansInOrder();
379
+ const first = spans[0];
380
+ const last = spans.at(-1);
381
+ if (first === undefined || last === undefined)
382
+ return;
383
+ event.preventDefault();
384
+ const range = document.createRange();
385
+ range.setStart(first, 0);
386
+ range.setEnd(last, last.childNodes.length);
387
+ const selection = document.getSelection();
388
+ selection?.removeAllRanges();
389
+ selection?.addRange(range);
390
+ }
391
+ #selectionChanged() {
392
+ const range = this.#range();
393
+ // A browser selection replaces a column selection.
394
+ if (range !== undefined && this.#column !== undefined)
395
+ this.#clearColumn(false);
396
+ if (range === undefined && this.#column !== undefined) {
397
+ // A selection made elsewhere (a field, the outline) ends the column's; a collapsed one doesn't.
398
+ const selection = document.getSelection();
399
+ if (selection !== null && selection.rangeCount > 0 && !selection.isCollapsed)
400
+ this.#clearColumn(true);
401
+ return;
402
+ }
403
+ if (range === undefined) {
404
+ // A selection elsewhere on the page (an input, another viewer): told once, when it leaves.
405
+ if (!this.#selecting)
406
+ return;
407
+ this.#selecting = false;
408
+ this.#host.keepMounted([]);
409
+ this.#options.onSelection?.(undefined);
410
+ return;
411
+ }
412
+ this.#selecting = true;
413
+ // Every page from the one the selection starts on to the one it ends on, those between too:
414
+ // read from its two ends, not by walking every span while a drag goes on.
415
+ // An end in a gap between pages counts as the other end's page.
416
+ const start = pageOf(range.startContainer);
417
+ const end = pageOf(range.endContainer);
418
+ const [low, high] = [start ?? end, end ?? start];
419
+ if (low !== undefined && high !== undefined)
420
+ this.#host.keepMounted(range_(Math.min(low, high), Math.max(low, high)));
421
+ this.#tell(this.#pieces(range), [...range.getClientRects()], false);
422
+ }
423
+ /** Tells the app about a selection of `pieces` (and reads their pages' blocks for copy). */
424
+ #tell(pieces, rects, column) {
425
+ const pages = [...new Set(pieces.map((p) => p.page))];
426
+ for (const page of pages)
427
+ this.#blocksOf(page);
428
+ if (this.#options.onSelection === undefined)
429
+ return;
430
+ // The text only when asked for (Search for, Share): joining it on every change of a drag costs.
431
+ let text;
432
+ const blocksOf = (page) => this.#blocksOf(page);
433
+ this.#options.onSelection({
434
+ get text() {
435
+ text ??= copySelection(pieces, "paragraph", blocksOf).text;
436
+ return text;
437
+ },
438
+ rects,
439
+ pages,
440
+ pointerType: this.#pointerType,
441
+ settled: !this.#pointerDown,
442
+ column,
443
+ });
444
+ }
445
+ #pointerDownIn(event) {
446
+ this.#pointerType = event.pointerType;
447
+ this.#pointerDown = true;
448
+ // The page the press is on: its blocks are read while the drag goes on, for the copy after it.
449
+ const page = event.target instanceof Node ? pageOf(event.target) : undefined;
450
+ if (page !== undefined && this.#pages.has(page))
451
+ this.#blocksOf(page);
452
+ if (this.#column !== undefined)
453
+ this.#clearColumn(true);
454
+ const rectangle = (event.altKey || this.#columnMode) && event.pointerType !== "touch" && event.button === 0;
455
+ if (!rectangle)
456
+ return;
457
+ // A rectangle, not a run of text: the browser's selection stays out of it.
458
+ event.preventDefault();
459
+ document.getSelection()?.removeAllRanges();
460
+ const box = document.createElement("div");
461
+ box.className = "lamina-column-selection";
462
+ Object.assign(box.style, {
463
+ position: "fixed",
464
+ left: `${event.clientX}px`,
465
+ top: `${event.clientY}px`,
466
+ width: "0",
467
+ height: "0",
468
+ border: "1px dashed currentColor",
469
+ background: "rgb(45 93 168 / 0.08)",
470
+ pointerEvents: "none",
471
+ zIndex: "1",
472
+ });
473
+ this.#host.root.append(box);
474
+ this.#drag = { x: event.clientX, y: event.clientY, box, pointer: event.pointerId };
475
+ }
476
+ #dragTo(event) {
477
+ const drag = this.#drag;
478
+ if (drag === undefined || event.pointerId !== drag.pointer)
479
+ return;
480
+ const r = rectBetween(drag, event);
481
+ Object.assign(drag.box.style, {
482
+ left: `${r.left}px`,
483
+ top: `${r.top}px`,
484
+ width: `${r.width}px`,
485
+ height: `${r.height}px`,
486
+ });
487
+ }
488
+ #pointerUp(event) {
489
+ const wasDown = this.#pointerDown;
490
+ this.#pointerDown = false;
491
+ const drag = this.#drag;
492
+ if (drag !== undefined && event.pointerId === drag.pointer) {
493
+ this.#drag = undefined;
494
+ drag.box.remove();
495
+ this.#selectColumn(rectBetween(drag, event));
496
+ return;
497
+ }
498
+ if (!wasDown)
499
+ return;
500
+ // The drag ended: the selection is settled, and the app may show its toolbar now.
501
+ const range = this.#range();
502
+ if (range !== undefined)
503
+ this.#tell(this.#pieces(range), [...range.getClientRects()], false);
504
+ }
505
+ /** Selects the runs whose centre is inside `area` (client coordinates), in page and run order. */
506
+ #selectColumn(area) {
507
+ if (area.width < 2 || area.height < 2)
508
+ return;
509
+ const spans = [];
510
+ const pieces = [];
511
+ const rects = [];
512
+ for (const span of this.#spansInOrder()) {
513
+ const info = this.#specs.get(span);
514
+ if (info === undefined)
515
+ continue;
516
+ const r = span.getBoundingClientRect();
517
+ const [x, y] = [r.left + r.width / 2, r.top + r.height / 2];
518
+ if (x < area.left || x > area.left + area.width || y < area.top || y > area.top + area.height)
519
+ continue;
520
+ spans.push(span);
521
+ rects.push(r);
522
+ pieces.push({ page: info.page, text: span.textContent ?? "", span: info.spec });
523
+ }
524
+ if (pieces.length === 0)
525
+ return;
526
+ for (const span of spans)
527
+ span.classList.add("lamina-column-selected");
528
+ // The browser draws no selection for these: a tint marks them, under the ink as the
529
+ // selection's own would be.
530
+ for (const span of spans)
531
+ span.style.backgroundColor = "rgb(45 93 168 / 0.25)";
532
+ this.#column = { pieces, spans };
533
+ this.#selecting = true;
534
+ this.#host.keepMounted(new Set(pieces.map((p) => p.page)));
535
+ this.#tell(pieces, rects, true);
536
+ }
537
+ /** Ends the column selection; `tell` says so to the app (not when a browser selection replaces it). */
538
+ #clearColumn(tell) {
539
+ const column = this.#column;
540
+ if (column === undefined)
541
+ return;
542
+ this.#column = undefined;
543
+ for (const span of column.spans) {
544
+ span.classList.remove("lamina-column-selected");
545
+ span.style.backgroundColor = "";
546
+ }
547
+ if (!tell)
548
+ return;
549
+ this.#selecting = false;
550
+ this.#host.keepMounted([]);
551
+ this.#options.onSelection?.(undefined);
552
+ }
553
+ }
554
+ /** The rectangle between a drag's start and the pointer now, in client coordinates. */
555
+ function rectBetween(start, now) {
556
+ return {
557
+ left: Math.min(start.x, now.clientX),
558
+ top: Math.min(start.y, now.clientY),
559
+ width: Math.abs(now.clientX - start.x),
560
+ height: Math.abs(now.clientY - start.y),
561
+ };
562
+ }
563
+ /** The index of the page `node` is on, from its shell. */
564
+ function pageOf(node) {
565
+ const element = node instanceof Element ? node : node.parentElement;
566
+ const index = element?.closest(".lamina-page")?.dataset.pageIndex;
567
+ return index === undefined ? undefined : Number(index);
568
+ }
569
+ /** The character offset in `span`'s text of the boundary point (`node`, `offset`). */
570
+ function offsetIn(span, node, offset) {
571
+ if (node.nodeType === Node.TEXT_NODE)
572
+ return offset;
573
+ // A boundary between the span's children: before the first or after its text.
574
+ return offset === 0 ? 0 : (span.textContent ?? "").length;
575
+ }
576
+ //# sourceMappingURL=text-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-layer.js","sourceRoot":"","sources":["../../src/layers/text-layer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** `first..last`, both included (empty when `last` is before `first`). */
2
+ export declare function range(first: number, last: number): number[];
3
+ //# sourceMappingURL=range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.d.ts","sourceRoot":"","sources":["../../src/layout/range.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAE3D"}
@@ -0,0 +1,5 @@
1
+ /** `first..last`, both included (empty when `last` is before `first`). */
2
+ export function range(first, last) {
3
+ return Array.from({ length: Math.max(0, last - first + 1) }, (_, k) => first + k);
4
+ }
5
+ //# sourceMappingURL=range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.js","sourceRoot":"","sources":["../../src/layout/range.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,MAAM,UAAU,KAAK,CAAC,KAAa,EAAE,IAAY;IAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AACpF,CAAC"}