@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,103 @@
1
+ // The text layer's geometry, pure: one span per text run, placed from its glyphs' quads (Lamina
2
+ // PDF's, never the renderer's: ADR 0004's two-parsers rule) in page space, points from the
3
+ // displayed page's top-left, y down. The span's own frame follows the run's baseline, so a rotated
4
+ // or vertical run gets a rotated span, and a right-to-left run reads right to left. Also where one
5
+ // piece of a selection's text ends a line or a word (copy.ts joins them).
6
+ const dot = (a, b) => a.x * b.x + a.y * b.y;
7
+ /** A unit vector along `v`, or `fallback` for a zero vector. */
8
+ function unit(v, fallback) {
9
+ const length = Math.hypot(v.x, v.y);
10
+ return length < 1e-6 ? fallback : { x: v.x / length, y: v.y / length };
11
+ }
12
+ /** Glyph `g`'s corners: bottom-left, bottom-right, top-right, top-left. */
13
+ function corners(quads, g) {
14
+ const at = (k) => ({ x: quads[g * 8 + k * 2] ?? 0, y: quads[g * 8 + k * 2 + 1] ?? 0 });
15
+ return [at(0), at(1), at(2), at(3)];
16
+ }
17
+ function centre(c) {
18
+ return { x: c.reduce((s, p) => s + p.x, 0) / c.length, y: c.reduce((s, p) => s + p.y, 0) / c.length };
19
+ }
20
+ /** Letters of right-to-left scripts (Hebrew, Arabic, Syriac, Thaana, N'Ko and their presentation forms). */
21
+ const RTL = /[\u0590-\u08ff\ufb1d-\ufdff\ufe70-\ufefc]/;
22
+ /**
23
+ * Whether `text` reads right to left: its first letter is of a right-to-left script (UAX #9's
24
+ * rule P2 for a paragraph's direction). A run's glyphs come in drawing order and its text in
25
+ * logical order, so only the text can say.
26
+ */
27
+ function readsRightToLeft(text) {
28
+ const first = /\p{L}/u.exec(text)?.[0];
29
+ return first !== undefined && RTL.test(first);
30
+ }
31
+ /**
32
+ * Each run's span, in run order (the page's reading order). Runs without glyphs or text have none.
33
+ * The baseline's direction comes from the first glyph's quad (its bottom edge), or for vertical
34
+ * writing from the first glyph's centre to the last's; the span's box covers every glyph's quad
35
+ * in that frame.
36
+ */
37
+ export function layoutSpans(runs, quads) {
38
+ return runs.flatMap((run, index) => {
39
+ const span = spanOf(run, index, quads);
40
+ return span === undefined ? [] : [span];
41
+ });
42
+ }
43
+ /** Run `run`'s span, or undefined for a run without glyphs or text. */
44
+ function spanOf(run, index, quads) {
45
+ const [start, end] = run.glyphRange;
46
+ if (end <= start || run.text === "")
47
+ return undefined;
48
+ const first = corners(quads, start);
49
+ const last = corners(quads, end - 1);
50
+ const along = run.vertical
51
+ ? unit({ x: centre(last).x - centre(first).x, y: centre(last).y - centre(first).y }, { x: 0, y: 1 })
52
+ : unit({ x: first[1].x - first[0].x, y: first[1].y - first[0].y }, { x: 1, y: 0 });
53
+ // Across the baseline, upwards: the baseline turned a quarter anticlockwise (y points down).
54
+ const up = { x: along.y, y: -along.x };
55
+ const { minA, maxA, minB, maxB } = extent(quads, start, end, along, up);
56
+ return {
57
+ run: index,
58
+ text: run.text,
59
+ left: along.x * minA + up.x * maxB,
60
+ top: along.y * minA + up.y * maxB,
61
+ width: maxA - minA,
62
+ height: maxB - minB,
63
+ angle: Math.atan2(along.y, along.x),
64
+ rtl: !run.vertical && readsRightToLeft(run.text),
65
+ ...(run.mcid === undefined ? {} : { mcid: run.mcid }),
66
+ };
67
+ }
68
+ /** How far glyphs `start..end` reach along the baseline (`A`) and across it (`B`). */
69
+ function extent(quads, start, end, along, up) {
70
+ let [minA, maxA, minB, maxB] = [Infinity, -Infinity, Infinity, -Infinity];
71
+ for (let g = start; g < end; g++) {
72
+ for (const p of corners(quads, g)) {
73
+ const a = dot(p, along);
74
+ const b = dot(p, up);
75
+ minA = Math.min(minA, a);
76
+ maxA = Math.max(maxA, a);
77
+ minB = Math.min(minB, b);
78
+ maxB = Math.max(maxB, b);
79
+ }
80
+ }
81
+ return { minA, maxA, minB, maxB };
82
+ }
83
+ /** What goes between two pieces as copy writes them: a new line, a space or nothing. */
84
+ export function separator(a, b) {
85
+ if (a.page !== b.page)
86
+ return "\n";
87
+ const along = { x: Math.cos(a.span.angle), y: Math.sin(a.span.angle) };
88
+ const up = { x: along.y, y: -along.x };
89
+ // Bottoms, not tops: a drop cap or a superscript on the same line has another top, while its
90
+ // bottom stays within half a line of the line's.
91
+ const lineA = dot({ x: a.span.left, y: a.span.top }, up) - a.span.height;
92
+ const lineB = dot({ x: b.span.left, y: b.span.top }, up) - b.span.height;
93
+ if (Math.abs(lineA - lineB) > Math.max(a.span.height, b.span.height) / 2)
94
+ return "\n";
95
+ const startA = dot({ x: a.span.left, y: a.span.top }, along);
96
+ const startB = dot({ x: b.span.left, y: b.span.top }, along);
97
+ // The space between the two boxes along the baseline, whichever comes first: right to left, or a
98
+ // comma between two words of another direction, the next run sits before the last.
99
+ const gap = Math.max(startB - (startA + a.span.width), startA - (startB + b.span.width));
100
+ const joined = /\s$/.test(a.text) || /^\s/.test(b.text);
101
+ return !joined && gap > a.span.height * 0.15 ? " " : "";
102
+ }
103
+ //# sourceMappingURL=spans.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spans.js","sourceRoot":"","sources":["../../src/layers/spans.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { StructureData } from "../protocol.js";
2
+ /** One viewer's structure tree. */
3
+ export declare class StructureLayer {
4
+ #private;
5
+ constructor(root: HTMLElement, untaggedLabel: string, idPrefix: string);
6
+ /** Builds the tree from the worker's answer, or the one-time note for an untagged document. */
7
+ show(structure: StructureData): void;
8
+ /** Span `id` drew marked content `mcid` of `page`: its element owns it. */
9
+ link(page: number, mcid: number, id: string): void;
10
+ /** Page `page` unmounted: its spans leave the elements that owned them. */
11
+ unlink(page: number): void;
12
+ /** Forgets the tree (a new document). */
13
+ reset(): void;
14
+ }
15
+ //# sourceMappingURL=structure-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure-layer.d.ts","sourceRoot":"","sources":["../../src/layers/structure-layer.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAkCpD,mCAAmC;AACnC,qBAAa,cAAc;;IASzB,YAAY,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAIrE;IAED,+FAA+F;IAC/F,IAAI,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAkBnC;IAED,2EAA2E;IAC3E,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAMjD;IAUD,2EAA2E;IAC3E,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAYzB;IAED,yCAAyC;IACzC,KAAK,IAAI,IAAI,CAIZ;CA2BF"}
@@ -0,0 +1,155 @@
1
+ // The structure layer (web-app §6 C5): a tagged document's structure tree as a hidden but
2
+ // accessible tree of elements with ARIA roles (headings, paragraphs, lists, tables, figures with
3
+ // their alternate text) whose leaves own the text layer's spans through `aria-owns`, matched by
4
+ // page and MCID. Assistive technology then reads the document in structure order with its
5
+ // semantics, whichever backend renders it (the pdf.js pattern). The spans join their elements as
6
+ // their pages mount and leave as they unmount. A document without structure says so once.
7
+ import { setUserSelect } from "../view/user-select.js";
8
+ /** An ARIA role (and level) per standard structure type; types not here are plain groups. */
9
+ const ROLES = {
10
+ P: "paragraph",
11
+ H: "heading",
12
+ Title: "heading",
13
+ L: "list",
14
+ LI: "listitem",
15
+ Table: "table",
16
+ THead: "rowgroup",
17
+ TBody: "rowgroup",
18
+ TFoot: "rowgroup",
19
+ TR: "row",
20
+ TH: "columnheader",
21
+ TD: "cell",
22
+ Formula: "math",
23
+ BlockQuote: "blockquote",
24
+ TOC: "list",
25
+ TOCI: "listitem",
26
+ Note: "note",
27
+ };
28
+ /** Hidden from sight, present for assistive technology (as sr-only CSS does). */
29
+ const HIDDEN = {
30
+ position: "absolute",
31
+ width: "1px",
32
+ height: "1px",
33
+ overflow: "hidden",
34
+ clipPath: "inset(50%)",
35
+ whiteSpace: "nowrap",
36
+ };
37
+ /** One viewer's structure tree. */
38
+ export class StructureLayer {
39
+ #root;
40
+ #untagged;
41
+ #tree;
42
+ /** The elements that own each page's marked content, by `page:mcid`. */
43
+ #owners = new Map();
44
+ #idPrefix;
45
+ constructor(root, untaggedLabel, idPrefix) {
46
+ this.#root = root;
47
+ this.#untagged = untaggedLabel;
48
+ this.#idPrefix = idPrefix;
49
+ }
50
+ /** Builds the tree from the worker's answer, or the one-time note for an untagged document. */
51
+ show(structure) {
52
+ this.reset();
53
+ const tree = document.createElement("div");
54
+ tree.className = "lamina-structure";
55
+ Object.assign(tree.style, HIDDEN);
56
+ // Hidden from sight, never from a drag: it takes no part in a selection.
57
+ setUserSelect(tree, "none");
58
+ const untagged = structure.tree === undefined || structure.tree.length === 0;
59
+ if (untagged)
60
+ tree.setAttribute("role", "status");
61
+ else
62
+ for (const node of structure.tree)
63
+ tree.append(this.#element(node, undefined));
64
+ this.#root.prepend(tree);
65
+ this.#tree = tree;
66
+ // A live region speaks what changes in it after it is in the page, not what it was made with.
67
+ if (untagged) {
68
+ requestAnimationFrame(() => {
69
+ if (this.#tree === tree)
70
+ tree.textContent = this.#untagged;
71
+ });
72
+ }
73
+ }
74
+ /** Span `id` drew marked content `mcid` of `page`: its element owns it. */
75
+ link(page, mcid, id) {
76
+ for (const owner of this.#owners.get(`${page}:${mcid}`) ?? []) {
77
+ const owned = (owner.getAttribute("aria-owns") ?? "").split(" ").filter(Boolean);
78
+ // In page and reading order, whatever order the pages mounted in.
79
+ if (!owned.includes(id))
80
+ owner.setAttribute("aria-owns", [...owned, id].sort(this.#byPlace).join(" "));
81
+ }
82
+ }
83
+ /** Orders span ids (`<prefix><page>-<index>`) by page, then by index. */
84
+ #byPlace = (a, b) => {
85
+ const place = (id) => id.slice(this.#idPrefix.length).split("-").map(Number);
86
+ const [pa = 0, ia = 0] = place(a);
87
+ const [pb = 0, ib = 0] = place(b);
88
+ return pa - pb || ia - ib;
89
+ };
90
+ /** Page `page` unmounted: its spans leave the elements that owned them. */
91
+ unlink(page) {
92
+ const prefix = `${this.#idPrefix}${page}-`;
93
+ for (const [key, owners] of this.#owners) {
94
+ if (!key.startsWith(`${page}:`))
95
+ continue;
96
+ for (const owner of owners) {
97
+ const kept = (owner.getAttribute("aria-owns") ?? "")
98
+ .split(" ")
99
+ .filter((id) => id !== "" && !id.startsWith(prefix));
100
+ if (kept.length === 0)
101
+ owner.removeAttribute("aria-owns");
102
+ else
103
+ owner.setAttribute("aria-owns", kept.join(" "));
104
+ }
105
+ }
106
+ }
107
+ /** Forgets the tree (a new document). */
108
+ reset() {
109
+ this.#tree?.remove();
110
+ this.#tree = undefined;
111
+ this.#owners = new Map();
112
+ }
113
+ /** `node` as an element; `parent` is its parent's structure type (a caption needs a table or figure). */
114
+ #element(node, parent) {
115
+ const el = document.createElement("div");
116
+ const heading = /^H([1-6])$/.exec(node.kind);
117
+ const alt = node.alt !== undefined && node.alt !== "" ? node.alt : undefined;
118
+ const role = heading !== null ? "heading" : roleOf(node.kind, parent, alt);
119
+ if (role !== undefined)
120
+ el.setAttribute("role", role);
121
+ if (heading !== null)
122
+ el.setAttribute("aria-level", heading[1]);
123
+ if (node.kind === "Title")
124
+ el.setAttribute("aria-level", "1");
125
+ if (alt !== undefined)
126
+ el.setAttribute("aria-label", alt);
127
+ if (node.lang !== undefined && node.lang !== "")
128
+ el.lang = node.lang;
129
+ for (const kid of node.kids)
130
+ this.#kid(el, kid, node.kind);
131
+ return el;
132
+ }
133
+ #kid(parent, kid, kind) {
134
+ if (kid.type === "node") {
135
+ parent.append(this.#element(kid, kind));
136
+ return;
137
+ }
138
+ const key = `${kid.page}:${kid.mcid}`;
139
+ const owners = this.#owners.get(key) ?? [];
140
+ owners.push(parent);
141
+ this.#owners.set(key, owners);
142
+ }
143
+ }
144
+ /**
145
+ * The role of a structure type that ROLES doesn't settle alone: a figure is an image only with
146
+ * alternate text to name it (else a group), and a caption only inside a table or a figure.
147
+ */
148
+ function roleOf(kind, parent, alt) {
149
+ if (kind === "Figure")
150
+ return alt === undefined ? "group" : "img";
151
+ if (kind === "Caption")
152
+ return parent === "Table" || parent === "Figure" ? "caption" : undefined;
153
+ return ROLES[kind];
154
+ }
155
+ //# sourceMappingURL=structure-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure-layer.js","sourceRoot":"","sources":["../../src/layers/structure-layer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import type { ViewerClient } from "../client.js";
2
+ import type { Rotation } from "../layout/page-layout.js";
3
+ import type { OpenedDocument } from "../protocol.js";
4
+ import type { PageLayer } from "../view/viewer.js";
5
+ import { type CopyMode } from "./copy.js";
6
+ /** What the text layer needs of its viewer. */
7
+ export interface TextLayerHost {
8
+ /** The viewer's root: where selections start, and where the structure tree lives. */
9
+ readonly root: HTMLElement;
10
+ readonly client: Pick<ViewerClient, "pageText" | "structure" | "readingOrder">;
11
+ /** The view's rotation now. */
12
+ rotation(): Rotation;
13
+ /** Keeps these pages mounted (the ones the selection touches). */
14
+ keepMounted(pages: Iterable<number>): void;
15
+ }
16
+ /** A selection in the text layer, for the app's selection surfaces (UI/UX plan §5.3). */
17
+ export interface TextSelection {
18
+ /** The selected text, as copy writes it (by paragraph). */
19
+ readonly text: string;
20
+ /** Its client rects, to place a toolbar or a menu near. */
21
+ readonly rects: readonly DOMRect[];
22
+ /** The pages it touches, in order. */
23
+ readonly pages: readonly number[];
24
+ /** The pointer that made it: `mouse`, `pen`, `touch`, or `""` for the keyboard. */
25
+ readonly pointerType: string;
26
+ /**
27
+ * The selection is done: the pointer that makes it is up (false during a drag, when a toolbar
28
+ * would get in the way). A keyboard selection is always settled.
29
+ */
30
+ readonly settled: boolean;
31
+ /** A rectangle's runs (column selection), rather than the browser's selection. */
32
+ readonly column: boolean;
33
+ }
34
+ /** The text layer's options (`createViewer`'s `text`). */
35
+ export interface TextLayerOptions {
36
+ /** Outlines each span, to check its fit over the rendered glyphs (a debug view). */
37
+ readonly outline?: boolean;
38
+ /** What a screen reader hears once for a document without structure (default "Untagged document"). */
39
+ readonly untaggedLabel?: string;
40
+ /** Called as the selection changes; `undefined` when it leaves the text layer. */
41
+ readonly onSelection?: (selection: TextSelection | undefined) => void;
42
+ }
43
+ /** The text layer of one viewer. */
44
+ export declare class TextLayer implements PageLayer {
45
+ #private;
46
+ readonly name = "text";
47
+ constructor(host: TextLayerHost, options?: TextLayerOptions);
48
+ /** Whether a plain drag selects a rectangle (column mode). */
49
+ get columnMode(): boolean;
50
+ set columnMode(on: boolean);
51
+ /**
52
+ * Copies the selection in `mode` to the clipboard, as the copy event would (for a command or a
53
+ * toolbar button; it must run in a user gesture). Resolves false when nothing is selected or
54
+ * the clipboard refused.
55
+ */
56
+ copy(mode?: CopyMode): Promise<boolean>;
57
+ /** A new document: its page sizes, and its structure tree, read once. */
58
+ open(document: OpenedDocument): void;
59
+ onMount(page: number, slot: HTMLElement): void;
60
+ onUnmount(page: number): void;
61
+ onZoom(page: number, _slot: HTMLElement, size: {
62
+ readonly width: number;
63
+ readonly height: number;
64
+ }): void;
65
+ /** Places every page's box again: the view turned. */
66
+ refresh(): void;
67
+ /** Stops listening; the viewer calls it on destroy. */
68
+ destroy(): void;
69
+ }
70
+ //# sourceMappingURL=text-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-layer.d.ts","sourceRoot":"","sources":["../../src/layers/text-layer.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,gBAAgB,CAAC;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EAAE,KAAK,QAAQ,EAAiB,MAAM,WAAW,CAAC;AAIzD,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,WAAW,GAAG,cAAc,CAAC,CAAC;IAC/E,+BAA+B;IAC/B,QAAQ,IAAI,QAAQ,CAAC;IACrB,kEAAkE;IAClE,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CAC5C;AAED,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;IACnC,sCAAsC;IACtC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,mFAAmF;IACnF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,oFAAoF;IACpF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,sGAAsG;IACtG,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,kFAAkF;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,GAAG,SAAS,KAAK,IAAI,CAAC;CACvE;AAYD,oCAAoC;AACpC,qBAAa,SAAU,YAAW,SAAS;;IACzC,QAAQ,CAAC,IAAI,UAAU;IA8BvB,YAAY,IAAI,EAAE,aAAa,EAAE,OAAO,GAAE,gBAAqB,EAiB9D;IAED,8DAA8D;IAC9D,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,IAAI,UAAU,CAAC,EAAE,EAAE,OAAO,EAEzB;IAED;;;;OAIG;IACG,IAAI,CAAC,IAAI,GAAE,QAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0BzD;IAED,yEAAyE;IACzE,IAAI,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAiBnC;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAyB7C;IAED,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAU5B;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAGxG;IAED,sDAAsD;IACtD,OAAO,IAAI,IAAI,CAEd;IAUD,uDAAuD;IACvD,OAAO,IAAI,IAAI,CAId;CAgVF"}