@prose-reader/enhancer-pdf 1.303.0 → 1.305.0

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.
@@ -5,10 +5,5 @@ type PdfJsArchive = Archive & {
5
5
  proxyDocument: pdfjsLib.PDFDocumentProxy;
6
6
  };
7
7
  export declare const isPdfJsArchive: (archive: Archive) => archive is PdfJsArchive;
8
- /**
9
- * @important
10
- * Make sure the urls are on the same origin or the cors header is set otherwise
11
- * the resource cannot be consumed as it is on the web.
12
- */
13
8
  export declare const createArchiveFromPdf: (file: Blob, filename: string) => Promise<Archive>;
14
9
  export {};
package/dist/index.js CHANGED
@@ -1,370 +1,165 @@
1
- import * as pdfjsLib from 'pdfjs-dist';
2
- import { TextLayer, RenderingCancelledException } from 'pdfjs-dist';
3
- import { of, from, switchMap, EMPTY, tap, catchError, map, mergeMap } from 'rxjs';
4
- import { setStylePropertyIfChanged, setPropertyIfChanged, DocumentRenderer, waitForSwitch, waitForFrameLoad, injectCSSToFrame, upsertCSSToFrame, setAttributeIfChanged, waitForFrameReady } from '@prose-reader/core';
5
-
6
- const PDF_SYMBOL = /* @__PURE__ */ Symbol(`pdfjs`);
7
- const isPdfJsArchive = (archive) => "_symbol" in archive && archive._symbol === PDF_SYMBOL;
8
- const createArchiveFromPdf = async (file, filename) => {
9
- const loadingTask = pdfjsLib.getDocument(await file.arrayBuffer());
10
- const pdf = await loadingTask.promise;
11
- const pages = Array.from({ length: pdf.numPages });
12
- const pageEntries = pages.map((_, index) => ({
13
- id: `page-${index}`,
14
- resourcePath: `${index}.pdf`
15
- }));
16
- const opfFileData = `
1
+ import * as e from "pdfjs-dist";
2
+ import { RenderingCancelledException as t, TextLayer as n } from "pdfjs-dist";
3
+ import { EMPTY as r, catchError as i, from as a, map as o, mergeMap as s, of as c, switchMap as l, tap as u } from "rxjs";
4
+ import { DocumentRenderer as d, injectCSSToFrame as f, setAttributeIfChanged as p, setPropertyIfChanged as m, setStylePropertyIfChanged as h, upsertCSSToFrame as g, waitForFrameLoad as _, waitForFrameReady as v, waitForSwitch as y } from "@prose-reader/core";
5
+ //#region src/createArchiveFromPdf.ts
6
+ var b = Symbol("pdfjs"), x = (e) => "_symbol" in e && e._symbol === b, S = async (t, n) => {
7
+ let r = await e.getDocument(await t.arrayBuffer()).promise, i = Array.from({ length: r.numPages }), a = i.map((e, t) => ({
8
+ id: `page-${t}`,
9
+ resourcePath: `${t}.pdf`
10
+ })), o = `
17
11
  <?xml version="1.0" encoding="UTF-8"?><package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
18
12
  <metadata>
19
13
  <meta property="rendition:layout">pre-paginated</meta>
20
14
  </metadata>
21
15
  <manifest>
22
- ${pageEntries.map(({ id, resourcePath }) => `<item id="${id}" href="${resourcePath}" />`).join(`
23
- `)}
16
+ ${a.map(({ id: e, resourcePath: t }) => `<item id="${e}" href="${t}" />`).join("\n")}
24
17
  </manifest>
25
18
  <spine>
26
- ${pageEntries.map(({ id }) => `<itemref idref="${id}" />`).join(`
27
- `)}
19
+ ${a.map(({ id: e }) => `<itemref idref="${e}" />`).join("\n")}
28
20
  </spine>
29
21
  </package>
30
22
  `;
31
- const opfFile = {
32
- dir: false,
33
- basename: `content.opf`,
34
- uri: `content.opf`,
35
- size: 0,
36
- blob: async () => new Blob(),
37
- string: async () => opfFileData
38
- };
39
- const archive = {
40
- filename,
41
- encodingFormat: "application/pdf",
42
- proxyDocument: pdf,
43
- _symbol: PDF_SYMBOL,
44
- records: [
45
- opfFile,
46
- ...pages.map((_, index) => ({
47
- dir: false,
48
- blob: async () => {
49
- throw new Error("Unable to get blob from pdf");
50
- },
51
- basename: `${index}.pdf`,
52
- size: 0,
53
- string: () => {
54
- throw new Error("Unable to get blob from pdf");
55
- },
56
- uri: `${index}.pdf`
57
- }))
58
- ],
59
- close: () => {
60
- return pdf.cleanup();
61
- }
62
- };
63
- return archive;
64
- };
65
-
66
- const pdfFrameStyle = "html {\n /* Pdf are always pre-paginated so its safe to disable touch action */\n touch-action: none;\n}\n\nbody {\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n /* This will prevent scrollbar and wrong offset of annotation layer */\n overflow: hidden;\n}\n";
67
-
68
- const layoutContainer = (container, spreadPosition, viewport) => {
69
- if (!container) return;
70
- const { height: pageHeight, width: pageWidth } = viewport.pageSize;
71
- setStylePropertyIfChanged(container.style, `width`, `${pageWidth}px`);
72
- setStylePropertyIfChanged(container.style, `height`, `${pageHeight}px`);
73
- if (spreadPosition === `right`) {
74
- setStylePropertyIfChanged(container.style, `justify-content`, `flex-start`);
75
- } else if (spreadPosition === `left`) {
76
- setStylePropertyIfChanged(container.style, `justify-content`, `flex-end`);
77
- } else {
78
- setStylePropertyIfChanged(container.style, `justify-content`, `center`);
79
- }
80
- };
81
- const layoutCanvas = (pageProxy, canvas, readerViewport) => {
82
- const pixelRatioScale = window.devicePixelRatio || 1;
83
- const { height: pageHeight, width: pageWidth } = readerViewport.pageSize;
84
- const { width: viewportWidth, height: viewportHeight } = pageProxy.getViewport({ scale: 1 });
85
- const pageScale = Math.max(
86
- pageWidth / viewportWidth,
87
- pageHeight / viewportHeight
88
- );
89
- const viewport = pageProxy.getViewport({ scale: pageScale });
90
- const viewportRatio = viewport.width / viewport.height;
91
- const pageRatio = pageWidth / pageHeight;
92
- const isWiderThanPage = viewportRatio > pageRatio;
93
- const canvasWidth = isWiderThanPage ? pageWidth : pageHeight * viewportRatio;
94
- const canvasHeight = viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight;
95
- setPropertyIfChanged(
96
- canvas,
97
- `width`,
98
- Math.floor(viewport.width * pixelRatioScale)
99
- );
100
- setPropertyIfChanged(
101
- canvas,
102
- `height`,
103
- Math.floor(viewport.height * pixelRatioScale)
104
- );
105
- setStylePropertyIfChanged(
106
- canvas.style,
107
- `width`,
108
- `${Math.floor(canvasWidth)}px`
109
- );
110
- setStylePropertyIfChanged(
111
- canvas.style,
112
- `height`,
113
- `${Math.floor(canvasHeight)}px`
114
- );
115
- };
116
-
117
- const pdfScaleStyle = `:root {
118
- --scale-factor: 1;
119
- --user-unit: 1;
120
- --total-scale-factor: calc(var(--scale-factor) * var(--user-unit));
121
- --scale-round-x: 1px;
122
- --scale-round-y: 1px;
123
- }`;
124
- class PdfRenderer extends DocumentRenderer {
125
- constructor(pdfViewerStyle, params) {
126
- super(params);
127
- this.pdfViewerStyle = pdfViewerStyle;
128
- }
129
- pdfViewerStyle;
130
- pageProxy;
131
- renderTask;
132
- textLayer;
133
- getCanvas() {
134
- const element = this.documentContainer?.children[0];
135
- if (!(element instanceof HTMLCanvasElement)) return;
136
- return element;
137
- }
138
- getFrameElement() {
139
- const frame = this.documentContainer?.children[1].children[0];
140
- if (!(frame instanceof HTMLIFrameElement)) return;
141
- return frame;
142
- }
143
- getPageProxy() {
144
- if (this.pageProxy) return of(this.pageProxy);
145
- return from(this.resourcesHandler.fetchResource()).pipe(
146
- switchMap((resource) => {
147
- if (!("custom" in resource)) return EMPTY;
148
- this.pageProxy = resource.data;
149
- return of(this.pageProxy);
150
- })
151
- );
152
- }
153
- onUnload() {
154
- this.detach();
155
- if (this.renderTask) {
156
- this.renderTask.cancel();
157
- }
158
- this.textLayer?.cancel();
159
- this.pageProxy?.cleanup();
160
- return EMPTY;
161
- }
162
- onCreateDocument() {
163
- const frameElement = document.createElement(`iframe`);
164
- frameElement.style.cssText = `
165
- overflow: hidden;
166
- height: 100%;
167
- width: 100%;
168
- `;
169
- frameElement.setAttribute("tabIndex", "0");
170
- frameElement.setAttribute("frameBorder", "0");
171
- frameElement.setAttribute(`src`, "about:blank");
172
- const frameContainer = this.containerElement.ownerDocument.createElement("div");
173
- frameContainer.style.cssText = `
174
- mix-blend-mode: multiply;
175
- -webkit-transform: translateZ(0);
176
- transform: translateZ(0);
177
- position: absolute;
178
- height: 100%;
179
- width: 100%;
180
- top: 0;
181
- `;
182
- const canvas = this.containerElement.ownerDocument.createElement("canvas");
183
- frameContainer.appendChild(frameElement);
184
- const rootElement = this.containerElement.ownerDocument.createElement(`div`);
185
- rootElement.style.cssText = `
186
- display: flex;
187
- align-items: center;
188
- justify-content: center;
189
- `;
190
- rootElement.appendChild(canvas);
191
- rootElement.appendChild(frameContainer);
192
- this.setDocumentContainer(rootElement);
193
- return of(rootElement);
194
- }
195
- onLoadDocument() {
196
- return this.getPageProxy().pipe(
197
- switchMap(() => {
198
- const frameElement = this.getFrameElement();
199
- const pageProxy = this.pageProxy;
200
- if (!frameElement || !pageProxy) return EMPTY;
201
- return of(frameElement).pipe(
202
- waitForSwitch(this.context.bridgeEvent.viewportFree$),
203
- tap(() => {
204
- this.attach();
205
- }),
206
- waitForFrameLoad,
207
- switchMap(() => {
208
- injectCSSToFrame(
209
- frameElement,
210
- "pdfjs-viewer-style",
211
- this.pdfViewerStyle
212
- );
213
- injectCSSToFrame(frameElement, "enhancer-pdf-style", pdfFrameStyle);
214
- upsertCSSToFrame(frameElement, "pdf-scale-scale", pdfScaleStyle);
215
- const frameBody = frameElement.contentDocument?.body;
216
- if (!frameBody || !this.pageProxy) return EMPTY;
217
- setAttributeIfChanged(frameBody, "class", "textLayer");
218
- this.textLayer = new TextLayer({
219
- container: frameBody,
220
- textContentSource: this.pageProxy.streamTextContent(),
221
- viewport: this.pageProxy.getViewport({ scale: 1 })
222
- });
223
- return from(this.textLayer.render());
224
- }),
225
- waitForFrameReady
226
- );
227
- })
228
- );
229
- }
230
- onLayout({
231
- spreadPosition
232
- }) {
233
- const frameElement = this.getFrameElement();
234
- const canvas = this.getCanvas();
235
- if (!frameElement || !canvas) return of(void 0);
236
- const { height: pageHeight, width: pageWidth } = this.viewport.pageSize;
237
- layoutContainer(this.documentContainer, spreadPosition, this.viewport);
238
- const context = canvas.getContext("2d");
239
- const pixelRatioScale = window.devicePixelRatio || 1;
240
- if (!this.pageProxy || !context) return of(void 0);
241
- if (this.renderTask) {
242
- this.renderTask.cancel();
243
- this.renderTask = void 0;
244
- }
245
- layoutCanvas(this.pageProxy, canvas, this.viewport);
246
- const { width: viewportWidth, height: viewportHeight } = this.pageProxy.getViewport({ scale: 1 });
247
- const pageScale = Math.max(
248
- pageWidth / viewportWidth,
249
- pageHeight / viewportHeight
250
- );
251
- const viewport = this.pageProxy.getViewport({ scale: pageScale });
252
- const transform = pixelRatioScale !== 1 ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0] : null;
253
- this.renderTask = this.pageProxy.render({
254
- ...transform && { transform },
255
- canvasContext: context,
256
- viewport,
257
- canvas
258
- });
259
- return from(this.renderTask.promise).pipe(
260
- switchMap(() => {
261
- this.renderTask = void 0;
262
- const frameDoc = frameElement?.contentDocument;
263
- const pdfPage = this.pageProxy;
264
- if (!frameDoc || !frameElement || !pdfPage || !this.textLayer) {
265
- throw new Error("Unable to update text layer due to missing elements");
266
- }
267
- const textLayerElement = frameDoc.body;
268
- const canvasScale = canvas.clientWidth / viewportWidth;
269
- setStylePropertyIfChanged(
270
- textLayerElement.style,
271
- `top`,
272
- `${canvas.offsetTop}px`
273
- );
274
- setStylePropertyIfChanged(
275
- textLayerElement.style,
276
- `left`,
277
- `${canvas.offsetLeft}px`
278
- );
279
- setStylePropertyIfChanged(
280
- textLayerElement.style,
281
- `height`,
282
- canvas.style.height
283
- );
284
- setStylePropertyIfChanged(
285
- textLayerElement.style,
286
- `width`,
287
- canvas.style.width
288
- );
289
- setStylePropertyIfChanged(
290
- frameDoc.documentElement.style,
291
- `--scale-factor`,
292
- `${canvasScale}`
293
- );
294
- this.textLayer.update({
295
- viewport
296
- });
297
- return of(void 0);
298
- }),
299
- catchError((e) => {
300
- if (!(e instanceof RenderingCancelledException)) console.error(e);
301
- return of(void 0);
302
- })
303
- );
304
- }
305
- /**
306
- * @important
307
- * We should keep the same node structure to preserve CFI integrity.
308
- */
309
- onRenderHeadless() {
310
- return this.getPageProxy().pipe(
311
- switchMap((pageProxy) => {
312
- const headlessDocument = document.implementation.createHTMLDocument();
313
- const textLayerElement = headlessDocument.body;
314
- const textLayer = new TextLayer({
315
- container: textLayerElement,
316
- textContentSource: pageProxy.streamTextContent(),
317
- viewport: pageProxy.getViewport({ scale: 1 })
318
- });
319
- return from(textLayer.render()).pipe(map(() => headlessDocument));
320
- })
321
- );
322
- }
323
- getDocumentFrame() {
324
- return this.getFrameElement();
325
- }
326
- }
327
-
328
- const pdfEnhancer = (next) => (options) => {
329
- const reader = next({
330
- ...options,
331
- /**
332
- * We have a special renderer for pdf so we need to inject it
333
- * for the relevant items. The enhancer could be configurable but for
334
- * the sake of simplicity we will assume that an item ending with .pdf should
335
- * be treated as a pdf document.
336
- *
337
- * The `getRenderer` hook should be non destructive, if we detect a renderer already
338
- * setup we should return it.
339
- */
340
- getRenderer(item) {
341
- const maybeFactory = options.getRenderer?.(item);
342
- if (!maybeFactory && item.href.endsWith(`.pdf`)) {
343
- return (params) => new PdfRenderer(options.pdf.pdfjsViewerInlineCss, params);
344
- }
345
- return maybeFactory;
346
- },
347
- getResource: (item) => options.pdf.getArchiveForItem(item).pipe(
348
- mergeMap((archive) => {
349
- if (!archive) return of(void 0);
350
- if (!isPdfJsArchive(archive)) {
351
- console.warn(`You provided an invalid pdf archive`);
352
- return of(void 0);
353
- }
354
- const fileIndex = archive.records.findIndex(
355
- (file) => item.href.endsWith(file.uri)
356
- ) - 1;
357
- return from(archive.proxyDocument.getPage(fileIndex + 1)).pipe(
358
- map((pageProxy) => ({
359
- custom: true,
360
- data: pageProxy
361
- }))
362
- );
363
- })
364
- )
365
- });
366
- return reader;
367
- };
23
+ return {
24
+ filename: n,
25
+ encodingFormat: "application/pdf",
26
+ proxyDocument: r,
27
+ _symbol: b,
28
+ records: [{
29
+ dir: !1,
30
+ basename: "content.opf",
31
+ uri: "content.opf",
32
+ size: 0,
33
+ blob: async () => new Blob(),
34
+ string: async () => o
35
+ }, ...i.map((e, t) => ({
36
+ dir: !1,
37
+ blob: async () => {
38
+ throw Error("Unable to get blob from pdf");
39
+ },
40
+ basename: `${t}.pdf`,
41
+ size: 0,
42
+ string: () => {
43
+ throw Error("Unable to get blob from pdf");
44
+ },
45
+ uri: `${t}.pdf`
46
+ }))],
47
+ close: () => r.cleanup()
48
+ };
49
+ }, C = "html{touch-action:none}body{width:100%;height:100%;margin:0;padding:0;overflow:hidden}", w = (e, t, n) => {
50
+ if (!e) return;
51
+ let { height: r, width: i } = n.pageSize;
52
+ h(e.style, "width", `${i}px`), h(e.style, "height", `${r}px`), t === "right" ? h(e.style, "justify-content", "flex-start") : t === "left" ? h(e.style, "justify-content", "flex-end") : h(e.style, "justify-content", "center");
53
+ }, T = (e, t, n) => {
54
+ let r = window.devicePixelRatio || 1, { height: i, width: a } = n.pageSize, { width: o, height: s } = e.getViewport({ scale: 1 }), c = Math.max(a / o, i / s), l = e.getViewport({ scale: c }), u = l.width / l.height, d = a / i, f = u > d ? a : i * u, p = u > d ? a / u : i;
55
+ m(t, "width", Math.floor(l.width * r)), m(t, "height", Math.floor(l.height * r)), h(t.style, "width", `${Math.floor(f)}px`), h(t.style, "height", `${Math.floor(p)}px`);
56
+ }, E = ":root {\n --scale-factor: 1;\n --user-unit: 1;\n --total-scale-factor: calc(var(--scale-factor) * var(--user-unit));\n --scale-round-x: 1px;\n --scale-round-y: 1px;\n}", D = class extends d {
57
+ pdfViewerStyle;
58
+ pageProxy;
59
+ renderTask;
60
+ textLayer;
61
+ constructor(e, t) {
62
+ super(t), this.pdfViewerStyle = e;
63
+ }
64
+ getCanvas() {
65
+ let e = this.documentContainer?.children[0];
66
+ if (e instanceof HTMLCanvasElement) return e;
67
+ }
68
+ getFrameElement() {
69
+ let e = this.documentContainer?.children[1]?.children[0];
70
+ if (e instanceof HTMLIFrameElement) return e;
71
+ }
72
+ getPageProxy() {
73
+ return this.pageProxy ? c(this.pageProxy) : a(this.resourcesHandler.fetchResource()).pipe(l((e) => "custom" in e ? (this.pageProxy = e.data, c(this.pageProxy)) : r));
74
+ }
75
+ onUnload() {
76
+ return this.detach(), this.renderTask && this.renderTask.cancel(), this.textLayer?.cancel(), this.pageProxy?.cleanup(), r;
77
+ }
78
+ onCreateDocument() {
79
+ let e = document.createElement("iframe");
80
+ e.style.cssText = "\n overflow: hidden;\n height: 100%;\n width: 100%;\n ", e.setAttribute("tabIndex", "0"), e.setAttribute("frameBorder", "0"), e.setAttribute("src", "about:blank");
81
+ let t = this.containerElement.ownerDocument.createElement("div");
82
+ t.style.cssText = "\n mix-blend-mode: multiply;\n -webkit-transform: translateZ(0);\n transform: translateZ(0);\n position: absolute;\n height: 100%;\n width: 100%;\n top: 0;\n ";
83
+ let n = this.containerElement.ownerDocument.createElement("canvas");
84
+ t.appendChild(e);
85
+ let r = this.containerElement.ownerDocument.createElement("div");
86
+ return r.style.cssText = "\n display: flex;\n align-items: center;\n justify-content: center;\n ", r.appendChild(n), r.appendChild(t), this.setDocumentContainer(r), c(r);
87
+ }
88
+ onLoadDocument() {
89
+ return this.getPageProxy().pipe(l(() => {
90
+ let e = this.getFrameElement(), t = this.pageProxy;
91
+ return !e || !t ? r : c(e).pipe(y(this.context.bridgeEvent.viewportFree$), u(() => {
92
+ this.attach();
93
+ }), _, l(() => {
94
+ f(e, "pdfjs-viewer-style", this.pdfViewerStyle), f(e, "enhancer-pdf-style", C), g(e, "pdf-scale-scale", E);
95
+ let t = e.contentDocument?.body;
96
+ return !t || !this.pageProxy ? r : (p(t, "class", "textLayer"), this.textLayer = new n({
97
+ container: t,
98
+ textContentSource: this.pageProxy.streamTextContent(),
99
+ viewport: this.pageProxy.getViewport({ scale: 1 })
100
+ }), a(this.textLayer.render()));
101
+ }), v);
102
+ }));
103
+ }
104
+ onLayout({ spreadPosition: e }) {
105
+ let n = this.getFrameElement(), r = this.getCanvas();
106
+ if (!n || !r) return c(void 0);
107
+ let { height: o, width: s } = this.viewport.pageSize;
108
+ w(this.documentContainer, e, this.viewport);
109
+ let u = r.getContext("2d"), d = window.devicePixelRatio || 1;
110
+ if (!this.pageProxy || !u) return c(void 0);
111
+ this.renderTask &&= (this.renderTask.cancel(), void 0), T(this.pageProxy, r, this.viewport);
112
+ let { width: f, height: p } = this.pageProxy.getViewport({ scale: 1 }), m = Math.max(s / f, o / p), g = this.pageProxy.getViewport({ scale: m }), _ = d === 1 ? null : [
113
+ d,
114
+ 0,
115
+ 0,
116
+ d,
117
+ 0,
118
+ 0
119
+ ];
120
+ return this.renderTask = this.pageProxy.render({
121
+ ..._ && { transform: _ },
122
+ canvasContext: u,
123
+ viewport: g,
124
+ canvas: r
125
+ }), a(this.renderTask.promise).pipe(l(() => {
126
+ this.renderTask = void 0;
127
+ let e = n?.contentDocument, t = this.pageProxy;
128
+ if (!e || !n || !t || !this.textLayer) throw Error("Unable to update text layer due to missing elements");
129
+ let i = e.body, a = r.clientWidth / f;
130
+ return h(i.style, "top", `${r.offsetTop}px`), h(i.style, "left", `${r.offsetLeft}px`), h(i.style, "height", r.style.height), h(i.style, "width", r.style.width), h(e.documentElement.style, "--scale-factor", `${a}`), this.textLayer.update({ viewport: g }), c(void 0);
131
+ }), i((e) => (e instanceof t || console.error(e), c(void 0))));
132
+ }
133
+ onRenderHeadless() {
134
+ return this.getPageProxy().pipe(l((e) => {
135
+ let t = document.implementation.createHTMLDocument(), r = t.body;
136
+ return a(new n({
137
+ container: r,
138
+ textContentSource: e.streamTextContent(),
139
+ viewport: e.getViewport({ scale: 1 })
140
+ }).render()).pipe(o(() => t));
141
+ }));
142
+ }
143
+ getDocumentFrame() {
144
+ return this.getFrameElement();
145
+ }
146
+ }, O = (e) => (t) => e({
147
+ ...t,
148
+ getRenderer(e) {
149
+ let n = t.getRenderer?.(e);
150
+ return !n && e.href.endsWith(".pdf") ? (e) => new D(t.pdf.pdfjsViewerInlineCss, e) : n;
151
+ },
152
+ getResource: (e) => t.pdf.getArchiveForItem(e).pipe(s((t) => {
153
+ if (!t) return c(void 0);
154
+ if (!x(t)) return console.warn("You provided an invalid pdf archive"), c(void 0);
155
+ let n = t.records.findIndex((t) => e.href.endsWith(t.uri)) - 1;
156
+ return a(t.proxyDocument.getPage(n + 1)).pipe(o((e) => ({
157
+ custom: !0,
158
+ data: e
159
+ })));
160
+ }))
161
+ });
162
+ //#endregion
163
+ export { S as createArchiveFromPdf, x as isPdfJsArchive, O as pdfEnhancer };
368
164
 
369
- export { createArchiveFromPdf, isPdfJsArchive, pdfEnhancer };
370
- //# sourceMappingURL=index.js.map
165
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/createArchiveFromPdf.ts","../src/renderer/layout.ts","../src/renderer/PdfRenderer.ts","../src/pdfEnhancer.ts"],"sourcesContent":["import type { Archive } from \"@prose-reader/streamer\"\nimport * as pdfjsLib from \"pdfjs-dist\"\n\ntype PdfJsArchive = Archive & {\n _symbol: symbol\n proxyDocument: pdfjsLib.PDFDocumentProxy\n}\n\nconst PDF_SYMBOL = Symbol(`pdfjs`)\n\nexport const isPdfJsArchive = (archive: Archive): archive is PdfJsArchive =>\n \"_symbol\" in archive && archive._symbol === PDF_SYMBOL\n\n/**\n * @important\n * Make sure the urls are on the same origin or the cors header is set otherwise\n * the resource cannot be consumed as it is on the web.\n */\nexport const createArchiveFromPdf = async (\n file: Blob,\n filename: string,\n): Promise<Archive> => {\n const loadingTask = pdfjsLib.getDocument(await file.arrayBuffer())\n\n const pdf = await loadingTask.promise\n\n const pages = Array.from({ length: pdf.numPages })\n const pageEntries = pages.map((_, index) => ({\n id: `page-${index}`,\n resourcePath: `${index}.pdf`,\n }))\n\n const opfFileData = `\n <?xml version=\"1.0\" encoding=\"UTF-8\"?><package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"bookid\">\n <metadata>\n <meta property=\"rendition:layout\">pre-paginated</meta>\n </metadata>\n <manifest>\n ${pageEntries.map(({ id, resourcePath }) => `<item id=\"${id}\" href=\"${resourcePath}\" />`).join(`\\n`)}\n </manifest>\n <spine>\n ${pageEntries.map(({ id }) => `<itemref idref=\"${id}\" />`).join(`\\n`)}\n </spine>\n </package>\n `\n\n const opfFile: Archive[`records`][number] = {\n dir: false,\n basename: `content.opf`,\n uri: `content.opf`,\n size: 0,\n blob: async () => new Blob(),\n string: async () => opfFileData,\n }\n\n const archive = {\n filename,\n encodingFormat: \"application/pdf\",\n proxyDocument: pdf,\n _symbol: PDF_SYMBOL,\n records: [\n opfFile,\n ...pages.map((_, index) => ({\n dir: false,\n blob: async () => {\n throw new Error(\"Unable to get blob from pdf\")\n },\n basename: `${index}.pdf`,\n size: 0,\n string: () => {\n throw new Error(\"Unable to get blob from pdf\")\n },\n uri: `${index}.pdf`,\n })),\n ],\n close: () => {\n return pdf.cleanup()\n },\n } satisfies PdfJsArchive\n\n return archive as Archive\n}\n","import {\n setPropertyIfChanged,\n setStylePropertyIfChanged,\n type Viewport,\n} from \"@prose-reader/core\"\nimport type { PDFPageProxy } from \"pdfjs-dist\"\n\nexport const layoutContainer = (\n container: HTMLElement | undefined,\n spreadPosition: `none` | `left` | `right`,\n viewport: Viewport,\n) => {\n if (!container) return\n\n // first we try to get the desired viewport for a comfortable reading based on theh current page size\n const { height: pageHeight, width: pageWidth } = viewport.pageSize\n\n setStylePropertyIfChanged(container.style, `width`, `${pageWidth}px`)\n setStylePropertyIfChanged(container.style, `height`, `${pageHeight}px`)\n\n if (spreadPosition === `right`) {\n setStylePropertyIfChanged(container.style, `justify-content`, `flex-start`)\n } else if (spreadPosition === `left`) {\n setStylePropertyIfChanged(container.style, `justify-content`, `flex-end`)\n } else {\n setStylePropertyIfChanged(container.style, `justify-content`, `center`)\n }\n}\n\nexport const layoutCanvas = (\n pageProxy: PDFPageProxy,\n canvas: HTMLCanvasElement,\n readerViewport: Viewport,\n) => {\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n const { height: pageHeight, width: pageWidth } = readerViewport.pageSize\n const { width: viewportWidth, height: viewportHeight } =\n pageProxy.getViewport({ scale: 1 })\n const pageScale = Math.max(\n pageWidth / viewportWidth,\n pageHeight / viewportHeight,\n )\n\n // then we generate the viewport for the canvas based on the page scale\n const viewport = pageProxy.getViewport({ scale: pageScale })\n\n // Then we define which axis should stretch or shrink to ratio\n const viewportRatio = viewport.width / viewport.height\n const pageRatio = pageWidth / pageHeight\n const isWiderThanPage = viewportRatio > pageRatio\n const canvasWidth = isWiderThanPage ? pageWidth : pageHeight * viewportRatio\n const canvasHeight =\n viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight\n\n setPropertyIfChanged(\n canvas,\n `width`,\n Math.floor(viewport.width * pixelRatioScale),\n )\n setPropertyIfChanged(\n canvas,\n `height`,\n Math.floor(viewport.height * pixelRatioScale),\n )\n setStylePropertyIfChanged(\n canvas.style,\n `width`,\n `${Math.floor(canvasWidth)}px`,\n )\n setStylePropertyIfChanged(\n canvas.style,\n `height`,\n `${Math.floor(canvasHeight)}px`,\n )\n}\n","import {\n DocumentRenderer,\n injectCSSToFrame,\n setAttributeIfChanged,\n setStylePropertyIfChanged,\n upsertCSSToFrame,\n waitForFrameLoad,\n waitForFrameReady,\n waitForSwitch,\n} from \"@prose-reader/core\"\nimport {\n type PDFPageProxy,\n RenderingCancelledException,\n type RenderTask,\n TextLayer,\n} from \"pdfjs-dist\"\nimport {\n catchError,\n EMPTY,\n from,\n map,\n type Observable,\n of,\n switchMap,\n tap,\n} from \"rxjs\"\nimport pdfFrameStyle from \"./frame.css?inline\"\nimport { layoutCanvas, layoutContainer } from \"./layout\"\n\nconst pdfScaleStyle = `:root {\n --scale-factor: 1;\n --user-unit: 1;\n --total-scale-factor: calc(var(--scale-factor) * var(--user-unit));\n --scale-round-x: 1px;\n --scale-round-y: 1px;\n}`\n\nexport class PdfRenderer extends DocumentRenderer {\n private pageProxy: PDFPageProxy | undefined\n private renderTask: RenderTask | undefined\n private textLayer: TextLayer | undefined\n\n constructor(\n private pdfViewerStyle: string,\n params: ConstructorParameters<typeof DocumentRenderer>[0],\n ) {\n super(params)\n }\n\n private getCanvas() {\n const element = this.documentContainer?.children[0]\n\n if (!(element instanceof HTMLCanvasElement)) return\n\n return element\n }\n\n private getFrameElement() {\n const frame = this.documentContainer?.children[1].children[0]\n\n if (!(frame instanceof HTMLIFrameElement)) return\n\n return frame\n }\n\n private getPageProxy() {\n if (this.pageProxy) return of(this.pageProxy)\n\n return from(this.resourcesHandler.fetchResource()).pipe(\n switchMap((resource) => {\n if (!(\"custom\" in resource)) return EMPTY\n\n this.pageProxy = resource.data as PDFPageProxy\n\n return of(this.pageProxy)\n }),\n )\n }\n\n onUnload(): Observable<unknown> {\n this.detach()\n\n if (this.renderTask) {\n this.renderTask.cancel()\n }\n\n this.textLayer?.cancel()\n this.pageProxy?.cleanup()\n\n return EMPTY\n }\n\n onCreateDocument(): Observable<HTMLElement> {\n const frameElement = document.createElement(`iframe`)\n frameElement.style.cssText = `\n overflow: hidden;\n height: 100%;\n width: 100%;\n `\n\n frameElement.setAttribute(\"tabIndex\", \"0\")\n frameElement.setAttribute(\"frameBorder\", \"0\")\n frameElement.setAttribute(`src`, \"about:blank\")\n\n const frameContainer =\n this.containerElement.ownerDocument.createElement(\"div\")\n frameContainer.style.cssText = `\n mix-blend-mode: multiply;\n -webkit-transform: translateZ(0);\n transform: translateZ(0);\n position: absolute;\n height: 100%;\n width: 100%;\n top: 0;\n `\n\n /**\n * The canvas is never attached to the DOM and will be used for offscreen rendering\n * then copied into the frame.\n */\n const canvas = this.containerElement.ownerDocument.createElement(\"canvas\")\n\n frameContainer.appendChild(frameElement)\n\n const rootElement = this.containerElement.ownerDocument.createElement(`div`)\n rootElement.style.cssText = `\n display: flex;\n align-items: center;\n justify-content: center;\n `\n\n rootElement.appendChild(canvas)\n rootElement.appendChild(frameContainer)\n\n this.setDocumentContainer(rootElement)\n\n return of(rootElement)\n }\n\n onLoadDocument(): Observable<unknown> {\n return this.getPageProxy().pipe(\n switchMap(() => {\n const frameElement = this.getFrameElement()\n const pageProxy = this.pageProxy\n\n if (!frameElement || !pageProxy) return EMPTY\n\n return of(frameElement).pipe(\n waitForSwitch(this.context.bridgeEvent.viewportFree$),\n tap(() => {\n this.attach()\n }),\n waitForFrameLoad,\n switchMap(() => {\n injectCSSToFrame(\n frameElement,\n \"pdfjs-viewer-style\",\n this.pdfViewerStyle,\n )\n injectCSSToFrame(frameElement, \"enhancer-pdf-style\", pdfFrameStyle)\n upsertCSSToFrame(frameElement, \"pdf-scale-scale\", pdfScaleStyle)\n\n /**\n * We make sure to render the text layer to simulate the document being loaded.\n * It will be correctly re-layout later. Consumers looking for document load have at least\n * the actual text document ready. (cfi lookup, etc.)\n */\n const frameBody = frameElement.contentDocument?.body\n\n if (!frameBody || !this.pageProxy) return EMPTY\n\n setAttributeIfChanged(frameBody, \"class\", \"textLayer\")\n\n this.textLayer = new TextLayer({\n container: frameBody,\n textContentSource: this.pageProxy.streamTextContent(),\n viewport: this.pageProxy.getViewport({ scale: 1 }),\n })\n\n return from(this.textLayer.render())\n }),\n waitForFrameReady,\n )\n }),\n )\n }\n\n onLayout({\n spreadPosition,\n }: {\n minPageSpread: number\n blankPagePosition: `before` | `after` | `none`\n spreadPosition: `none` | `left` | `right`\n }) {\n const frameElement = this.getFrameElement()\n const canvas = this.getCanvas()\n\n if (!frameElement || !canvas) return of(undefined)\n\n // first we try to get the desired viewport for a comfortable reading based on the current page size\n const { height: pageHeight, width: pageWidth } = this.viewport.pageSize\n\n layoutContainer(this.documentContainer, spreadPosition, this.viewport)\n\n const context = canvas.getContext(\"2d\")\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n\n if (!this.pageProxy || !context) return of(undefined)\n\n if (this.renderTask) {\n this.renderTask.cancel()\n this.renderTask = undefined\n }\n\n layoutCanvas(this.pageProxy, canvas, this.viewport)\n\n const { width: viewportWidth, height: viewportHeight } =\n this.pageProxy.getViewport({ scale: 1 })\n\n const pageScale = Math.max(\n pageWidth / viewportWidth,\n pageHeight / viewportHeight,\n )\n\n // then we generate the viewport for the canvas based on the page scale\n const viewport = this.pageProxy.getViewport({ scale: pageScale })\n\n const transform =\n pixelRatioScale !== 1\n ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0]\n : null\n\n this.renderTask = this.pageProxy.render({\n ...(transform && { transform }),\n canvasContext: context,\n viewport,\n canvas,\n })\n\n return from(this.renderTask.promise).pipe(\n switchMap(() => {\n this.renderTask = undefined\n\n const frameDoc = frameElement?.contentDocument\n const pdfPage = this.pageProxy\n\n if (!frameDoc || !frameElement || !pdfPage || !this.textLayer) {\n throw new Error(\"Unable to update text layer due to missing elements\")\n }\n\n const textLayerElement = frameDoc.body\n const canvasScale = canvas.clientWidth / viewportWidth\n\n setStylePropertyIfChanged(\n textLayerElement.style,\n `top`,\n `${canvas.offsetTop}px`,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `left`,\n `${canvas.offsetLeft}px`,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `height`,\n canvas.style.height,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `width`,\n canvas.style.width,\n )\n\n /**\n * Taking inspiration from https://github.com/mozilla/pdf.js/blob/master/web/pdf_viewer.css.\n * Not sure why pdfjs DOES rely on css from the viewer to works. Or in another words, why is it\n * not more obvious that TextLayer requires a set of variables to work correctly.\n */\n setStylePropertyIfChanged(\n frameDoc.documentElement.style,\n `--scale-factor`,\n `${canvasScale}`,\n )\n\n this.textLayer.update({\n viewport,\n })\n\n return of(undefined)\n }),\n catchError((e) => {\n if (!(e instanceof RenderingCancelledException)) console.error(e)\n\n return of(undefined)\n }),\n )\n }\n\n /**\n * @important\n * We should keep the same node structure to preserve CFI integrity.\n */\n onRenderHeadless() {\n return this.getPageProxy().pipe(\n switchMap((pageProxy) => {\n const headlessDocument = document.implementation.createHTMLDocument()\n const textLayerElement = headlessDocument.body\n\n const textLayer = new TextLayer({\n container: textLayerElement,\n textContentSource: pageProxy.streamTextContent(),\n viewport: pageProxy.getViewport({ scale: 1 }),\n })\n\n return from(textLayer.render()).pipe(map(() => headlessDocument))\n }),\n )\n }\n\n getDocumentFrame() {\n return this.getFrameElement()\n }\n}\n","import type { createReader, Reader } from \"@prose-reader/core\"\nimport { from, map, mergeMap, of } from \"rxjs\"\nimport { isPdfJsArchive } from \"./createArchiveFromPdf\"\nimport { PdfRenderer } from \"./renderer/PdfRenderer\"\nimport type { EnhancerOptions } from \"./types\"\n\ntype CreateReader = typeof createReader\ntype CreateReaderOptions = Parameters<CreateReader>[0]\n\nexport const pdfEnhancer =\n <InheritOptions extends CreateReaderOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (options: InheritOptions & EnhancerOptions): InheritOutput => {\n const reader = next({\n ...options,\n /**\n * We have a special renderer for pdf so we need to inject it\n * for the relevant items. The enhancer could be configurable but for\n * the sake of simplicity we will assume that an item ending with .pdf should\n * be treated as a pdf document.\n *\n * The `getRenderer` hook should be non destructive, if we detect a renderer already\n * setup we should return it.\n */\n getRenderer(item) {\n const maybeFactory = options.getRenderer?.(item)\n\n if (!maybeFactory && item.href.endsWith(`.pdf`)) {\n return (params) =>\n new PdfRenderer(options.pdf.pdfjsViewerInlineCss, params)\n }\n\n return maybeFactory\n },\n getResource: (item) =>\n options.pdf.getArchiveForItem(item).pipe(\n mergeMap((archive) => {\n if (!archive) return of(undefined)\n\n if (!isPdfJsArchive(archive)) {\n console.warn(`You provided an invalid pdf archive`)\n\n return of(undefined)\n }\n\n // we account for opf file\n const fileIndex =\n archive.records.findIndex((file) =>\n item.href.endsWith(file.uri),\n ) - 1\n\n return from(archive.proxyDocument.getPage(fileIndex + 1)).pipe(\n map((pageProxy) => ({\n custom: true as const,\n data: pageProxy,\n })),\n )\n }),\n ),\n })\n\n return reader\n }\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/createArchiveFromPdf.ts","../src/renderer/frame.css?inline","../src/renderer/layout.ts","../src/renderer/PdfRenderer.ts","../src/pdfEnhancer.ts"],"sourcesContent":["import type { Archive } from \"@prose-reader/streamer\"\nimport * as pdfjsLib from \"pdfjs-dist\"\n\ntype PdfJsArchive = Archive & {\n _symbol: symbol\n proxyDocument: pdfjsLib.PDFDocumentProxy\n}\n\nconst PDF_SYMBOL = Symbol(`pdfjs`)\n\nexport const isPdfJsArchive = (archive: Archive): archive is PdfJsArchive =>\n \"_symbol\" in archive && archive._symbol === PDF_SYMBOL\n\n/**\n * @important\n * Make sure the urls are on the same origin or the cors header is set otherwise\n * the resource cannot be consumed as it is on the web.\n */\nexport const createArchiveFromPdf = async (\n file: Blob,\n filename: string,\n): Promise<Archive> => {\n const loadingTask = pdfjsLib.getDocument(await file.arrayBuffer())\n\n const pdf = await loadingTask.promise\n\n const pages = Array.from({ length: pdf.numPages })\n const pageEntries = pages.map((_, index) => ({\n id: `page-${index}`,\n resourcePath: `${index}.pdf`,\n }))\n\n const opfFileData = `\n <?xml version=\"1.0\" encoding=\"UTF-8\"?><package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"bookid\">\n <metadata>\n <meta property=\"rendition:layout\">pre-paginated</meta>\n </metadata>\n <manifest>\n ${pageEntries.map(({ id, resourcePath }) => `<item id=\"${id}\" href=\"${resourcePath}\" />`).join(`\\n`)}\n </manifest>\n <spine>\n ${pageEntries.map(({ id }) => `<itemref idref=\"${id}\" />`).join(`\\n`)}\n </spine>\n </package>\n `\n\n const opfFile: Archive[`records`][number] = {\n dir: false,\n basename: `content.opf`,\n uri: `content.opf`,\n size: 0,\n blob: async () => new Blob(),\n string: async () => opfFileData,\n }\n\n const archive = {\n filename,\n encodingFormat: \"application/pdf\",\n proxyDocument: pdf,\n _symbol: PDF_SYMBOL,\n records: [\n opfFile,\n ...pages.map((_, index) => ({\n dir: false,\n blob: async () => {\n throw new Error(\"Unable to get blob from pdf\")\n },\n basename: `${index}.pdf`,\n size: 0,\n string: () => {\n throw new Error(\"Unable to get blob from pdf\")\n },\n uri: `${index}.pdf`,\n })),\n ],\n close: () => {\n return pdf.cleanup()\n },\n } satisfies PdfJsArchive\n\n return archive as Archive\n}\n","html {\n /* Pdf are always pre-paginated so its safe to disable touch action */\n touch-action: none;\n}\n\nbody {\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n /* This will prevent scrollbar and wrong offset of annotation layer */\n overflow: hidden;\n}\n","import {\n setPropertyIfChanged,\n setStylePropertyIfChanged,\n type Viewport,\n} from \"@prose-reader/core\"\nimport type { PDFPageProxy } from \"pdfjs-dist\"\n\nexport const layoutContainer = (\n container: HTMLElement | undefined,\n spreadPosition: `none` | `left` | `right`,\n viewport: Viewport,\n) => {\n if (!container) return\n\n // first we try to get the desired viewport for a comfortable reading based on theh current page size\n const { height: pageHeight, width: pageWidth } = viewport.pageSize\n\n setStylePropertyIfChanged(container.style, `width`, `${pageWidth}px`)\n setStylePropertyIfChanged(container.style, `height`, `${pageHeight}px`)\n\n if (spreadPosition === `right`) {\n setStylePropertyIfChanged(container.style, `justify-content`, `flex-start`)\n } else if (spreadPosition === `left`) {\n setStylePropertyIfChanged(container.style, `justify-content`, `flex-end`)\n } else {\n setStylePropertyIfChanged(container.style, `justify-content`, `center`)\n }\n}\n\nexport const layoutCanvas = (\n pageProxy: PDFPageProxy,\n canvas: HTMLCanvasElement,\n readerViewport: Viewport,\n) => {\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n const { height: pageHeight, width: pageWidth } = readerViewport.pageSize\n const { width: viewportWidth, height: viewportHeight } =\n pageProxy.getViewport({ scale: 1 })\n const pageScale = Math.max(\n pageWidth / viewportWidth,\n pageHeight / viewportHeight,\n )\n\n // then we generate the viewport for the canvas based on the page scale\n const viewport = pageProxy.getViewport({ scale: pageScale })\n\n // Then we define which axis should stretch or shrink to ratio\n const viewportRatio = viewport.width / viewport.height\n const pageRatio = pageWidth / pageHeight\n const isWiderThanPage = viewportRatio > pageRatio\n const canvasWidth = isWiderThanPage ? pageWidth : pageHeight * viewportRatio\n const canvasHeight =\n viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight\n\n setPropertyIfChanged(\n canvas,\n `width`,\n Math.floor(viewport.width * pixelRatioScale),\n )\n setPropertyIfChanged(\n canvas,\n `height`,\n Math.floor(viewport.height * pixelRatioScale),\n )\n setStylePropertyIfChanged(\n canvas.style,\n `width`,\n `${Math.floor(canvasWidth)}px`,\n )\n setStylePropertyIfChanged(\n canvas.style,\n `height`,\n `${Math.floor(canvasHeight)}px`,\n )\n}\n","import {\n DocumentRenderer,\n injectCSSToFrame,\n setAttributeIfChanged,\n setStylePropertyIfChanged,\n upsertCSSToFrame,\n waitForFrameLoad,\n waitForFrameReady,\n waitForSwitch,\n} from \"@prose-reader/core\"\nimport {\n type PDFPageProxy,\n RenderingCancelledException,\n type RenderTask,\n TextLayer,\n} from \"pdfjs-dist\"\nimport {\n catchError,\n EMPTY,\n from,\n map,\n type Observable,\n of,\n switchMap,\n tap,\n} from \"rxjs\"\nimport pdfFrameStyle from \"./frame.css?inline\"\nimport { layoutCanvas, layoutContainer } from \"./layout\"\n\nconst pdfScaleStyle = `:root {\n --scale-factor: 1;\n --user-unit: 1;\n --total-scale-factor: calc(var(--scale-factor) * var(--user-unit));\n --scale-round-x: 1px;\n --scale-round-y: 1px;\n}`\n\nexport class PdfRenderer extends DocumentRenderer {\n private pageProxy: PDFPageProxy | undefined\n private renderTask: RenderTask | undefined\n private textLayer: TextLayer | undefined\n\n constructor(\n private pdfViewerStyle: string,\n params: ConstructorParameters<typeof DocumentRenderer>[0],\n ) {\n super(params)\n }\n\n private getCanvas() {\n const element = this.documentContainer?.children[0]\n\n if (!(element instanceof HTMLCanvasElement)) return\n\n return element\n }\n\n private getFrameElement() {\n const frame = this.documentContainer?.children[1]?.children[0]\n\n if (!(frame instanceof HTMLIFrameElement)) return\n\n return frame\n }\n\n private getPageProxy() {\n if (this.pageProxy) return of(this.pageProxy)\n\n return from(this.resourcesHandler.fetchResource()).pipe(\n switchMap((resource) => {\n if (!(\"custom\" in resource)) return EMPTY\n\n this.pageProxy = resource.data as PDFPageProxy\n\n return of(this.pageProxy)\n }),\n )\n }\n\n onUnload(): Observable<unknown> {\n this.detach()\n\n if (this.renderTask) {\n this.renderTask.cancel()\n }\n\n this.textLayer?.cancel()\n this.pageProxy?.cleanup()\n\n return EMPTY\n }\n\n onCreateDocument(): Observable<HTMLElement> {\n const frameElement = document.createElement(`iframe`)\n frameElement.style.cssText = `\n overflow: hidden;\n height: 100%;\n width: 100%;\n `\n\n frameElement.setAttribute(\"tabIndex\", \"0\")\n frameElement.setAttribute(\"frameBorder\", \"0\")\n frameElement.setAttribute(`src`, \"about:blank\")\n\n const frameContainer =\n this.containerElement.ownerDocument.createElement(\"div\")\n frameContainer.style.cssText = `\n mix-blend-mode: multiply;\n -webkit-transform: translateZ(0);\n transform: translateZ(0);\n position: absolute;\n height: 100%;\n width: 100%;\n top: 0;\n `\n\n /**\n * The canvas is never attached to the DOM and will be used for offscreen rendering\n * then copied into the frame.\n */\n const canvas = this.containerElement.ownerDocument.createElement(\"canvas\")\n\n frameContainer.appendChild(frameElement)\n\n const rootElement = this.containerElement.ownerDocument.createElement(`div`)\n rootElement.style.cssText = `\n display: flex;\n align-items: center;\n justify-content: center;\n `\n\n rootElement.appendChild(canvas)\n rootElement.appendChild(frameContainer)\n\n this.setDocumentContainer(rootElement)\n\n return of(rootElement)\n }\n\n onLoadDocument(): Observable<unknown> {\n return this.getPageProxy().pipe(\n switchMap(() => {\n const frameElement = this.getFrameElement()\n const pageProxy = this.pageProxy\n\n if (!frameElement || !pageProxy) return EMPTY\n\n return of(frameElement).pipe(\n waitForSwitch(this.context.bridgeEvent.viewportFree$),\n tap(() => {\n this.attach()\n }),\n waitForFrameLoad,\n switchMap(() => {\n injectCSSToFrame(\n frameElement,\n \"pdfjs-viewer-style\",\n this.pdfViewerStyle,\n )\n injectCSSToFrame(frameElement, \"enhancer-pdf-style\", pdfFrameStyle)\n upsertCSSToFrame(frameElement, \"pdf-scale-scale\", pdfScaleStyle)\n\n /**\n * We make sure to render the text layer to simulate the document being loaded.\n * It will be correctly re-layout later. Consumers looking for document load have at least\n * the actual text document ready. (cfi lookup, etc.)\n */\n const frameBody = frameElement.contentDocument?.body\n\n if (!frameBody || !this.pageProxy) return EMPTY\n\n setAttributeIfChanged(frameBody, \"class\", \"textLayer\")\n\n this.textLayer = new TextLayer({\n container: frameBody,\n textContentSource: this.pageProxy.streamTextContent(),\n viewport: this.pageProxy.getViewport({ scale: 1 }),\n })\n\n return from(this.textLayer.render())\n }),\n waitForFrameReady,\n )\n }),\n )\n }\n\n onLayout({\n spreadPosition,\n }: {\n minPageSpread: number\n blankPagePosition: `before` | `after` | `none`\n spreadPosition: `none` | `left` | `right`\n }) {\n const frameElement = this.getFrameElement()\n const canvas = this.getCanvas()\n\n if (!frameElement || !canvas) return of(undefined)\n\n // first we try to get the desired viewport for a comfortable reading based on the current page size\n const { height: pageHeight, width: pageWidth } = this.viewport.pageSize\n\n layoutContainer(this.documentContainer, spreadPosition, this.viewport)\n\n const context = canvas.getContext(\"2d\")\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n\n if (!this.pageProxy || !context) return of(undefined)\n\n if (this.renderTask) {\n this.renderTask.cancel()\n this.renderTask = undefined\n }\n\n layoutCanvas(this.pageProxy, canvas, this.viewport)\n\n const { width: viewportWidth, height: viewportHeight } =\n this.pageProxy.getViewport({ scale: 1 })\n\n const pageScale = Math.max(\n pageWidth / viewportWidth,\n pageHeight / viewportHeight,\n )\n\n // then we generate the viewport for the canvas based on the page scale\n const viewport = this.pageProxy.getViewport({ scale: pageScale })\n\n const transform =\n pixelRatioScale !== 1\n ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0]\n : null\n\n this.renderTask = this.pageProxy.render({\n ...(transform && { transform }),\n canvasContext: context,\n viewport,\n canvas,\n })\n\n return from(this.renderTask.promise).pipe(\n switchMap(() => {\n this.renderTask = undefined\n\n const frameDoc = frameElement?.contentDocument\n const pdfPage = this.pageProxy\n\n if (!frameDoc || !frameElement || !pdfPage || !this.textLayer) {\n throw new Error(\"Unable to update text layer due to missing elements\")\n }\n\n const textLayerElement = frameDoc.body\n const canvasScale = canvas.clientWidth / viewportWidth\n\n setStylePropertyIfChanged(\n textLayerElement.style,\n `top`,\n `${canvas.offsetTop}px`,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `left`,\n `${canvas.offsetLeft}px`,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `height`,\n canvas.style.height,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `width`,\n canvas.style.width,\n )\n\n /**\n * Taking inspiration from https://github.com/mozilla/pdf.js/blob/master/web/pdf_viewer.css.\n * Not sure why pdfjs DOES rely on css from the viewer to works. Or in another words, why is it\n * not more obvious that TextLayer requires a set of variables to work correctly.\n */\n setStylePropertyIfChanged(\n frameDoc.documentElement.style,\n `--scale-factor`,\n `${canvasScale}`,\n )\n\n this.textLayer.update({\n viewport,\n })\n\n return of(undefined)\n }),\n catchError((e) => {\n if (!(e instanceof RenderingCancelledException)) console.error(e)\n\n return of(undefined)\n }),\n )\n }\n\n /**\n * @important\n * We should keep the same node structure to preserve CFI integrity.\n */\n onRenderHeadless() {\n return this.getPageProxy().pipe(\n switchMap((pageProxy) => {\n const headlessDocument = document.implementation.createHTMLDocument()\n const textLayerElement = headlessDocument.body\n\n const textLayer = new TextLayer({\n container: textLayerElement,\n textContentSource: pageProxy.streamTextContent(),\n viewport: pageProxy.getViewport({ scale: 1 }),\n })\n\n return from(textLayer.render()).pipe(map(() => headlessDocument))\n }),\n )\n }\n\n getDocumentFrame() {\n return this.getFrameElement()\n }\n}\n","import type { createReader, Reader } from \"@prose-reader/core\"\nimport { from, map, mergeMap, of } from \"rxjs\"\nimport { isPdfJsArchive } from \"./createArchiveFromPdf\"\nimport { PdfRenderer } from \"./renderer/PdfRenderer\"\nimport type { EnhancerOptions } from \"./types\"\n\ntype CreateReader = typeof createReader\ntype CreateReaderOptions = Parameters<CreateReader>[0]\n\nexport const pdfEnhancer =\n <InheritOptions extends CreateReaderOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (options: InheritOptions & EnhancerOptions): InheritOutput => {\n const reader = next({\n ...options,\n /**\n * We have a special renderer for pdf so we need to inject it\n * for the relevant items. The enhancer could be configurable but for\n * the sake of simplicity we will assume that an item ending with .pdf should\n * be treated as a pdf document.\n *\n * The `getRenderer` hook should be non destructive, if we detect a renderer already\n * setup we should return it.\n */\n getRenderer(item) {\n const maybeFactory = options.getRenderer?.(item)\n\n if (!maybeFactory && item.href.endsWith(`.pdf`)) {\n return (params) =>\n new PdfRenderer(options.pdf.pdfjsViewerInlineCss, params)\n }\n\n return maybeFactory\n },\n getResource: (item) =>\n options.pdf.getArchiveForItem(item).pipe(\n mergeMap((archive) => {\n if (!archive) return of(undefined)\n\n if (!isPdfJsArchive(archive)) {\n console.warn(`You provided an invalid pdf archive`)\n\n return of(undefined)\n }\n\n // we account for opf file\n const fileIndex =\n archive.records.findIndex((file) =>\n item.href.endsWith(file.uri),\n ) - 1\n\n return from(archive.proxyDocument.getPage(fileIndex + 1)).pipe(\n map((pageProxy) => ({\n custom: true as const,\n data: pageProxy,\n })),\n )\n }),\n ),\n })\n\n return reader\n }\n"],"mappings":"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"}
@@ -1,196 +1,28 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('pdfjs-dist'), require('rxjs'), require('@prose-reader/core')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'pdfjs-dist', 'rxjs', '@prose-reader/core'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["prose-reader-enhancer-pdf"] = {}, global.pdfjsLib, global.rxjs, global.core));
5
- })(this, (function (exports, pdfjsLib, rxjs, core) { 'use strict';
6
-
7
- function _interopNamespaceDefault(e) {
8
- const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
9
- if (e) {
10
- for (const k in e) {
11
- if (k !== 'default') {
12
- const d = Object.getOwnPropertyDescriptor(e, k);
13
- Object.defineProperty(n, k, d.get ? d : {
14
- enumerable: true,
15
- get: () => e[k]
16
- });
17
- }
18
- }
19
- }
20
- n.default = e;
21
- return Object.freeze(n);
22
- }
23
-
24
- const pdfjsLib__namespace = /*#__PURE__*/_interopNamespaceDefault(pdfjsLib);
25
-
26
- const PDF_SYMBOL = /* @__PURE__ */ Symbol(`pdfjs`);
27
- const isPdfJsArchive = (archive) => "_symbol" in archive && archive._symbol === PDF_SYMBOL;
28
- const createArchiveFromPdf = async (file, filename) => {
29
- const loadingTask = pdfjsLib__namespace.getDocument(await file.arrayBuffer());
30
- const pdf = await loadingTask.promise;
31
- const pages = Array.from({ length: pdf.numPages });
32
- const pageEntries = pages.map((_, index) => ({
33
- id: `page-${index}`,
34
- resourcePath: `${index}.pdf`
35
- }));
36
- const opfFileData = `
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("pdfjs-dist"),require("rxjs"),require("@prose-reader/core")):typeof define==`function`&&define.amd?define([`exports`,`pdfjs-dist`,`rxjs`,`@prose-reader/core`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e[`prose-reader-enhancer-pdf`]={},e.pdfjs_dist,e.rxjs,e._prose_reader_core))})(this,function(e,t,n,r){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var i=Object.create,a=Object.defineProperty,o=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,c=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty,u=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=s(t),c=0,u=i.length,d;c<u;c++)d=i[c],!l.call(e,d)&&d!==n&&a(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=o(t,d))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:i(c(e)),u(t||!e||!e.__esModule?a(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1);var d=Symbol(`pdfjs`),f=e=>`_symbol`in e&&e._symbol===d,p=async(e,n)=>{let r=await t.getDocument(await e.arrayBuffer()).promise,i=Array.from({length:r.numPages}),a=i.map((e,t)=>({id:`page-${t}`,resourcePath:`${t}.pdf`})),o=`
37
2
  <?xml version="1.0" encoding="UTF-8"?><package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
38
3
  <metadata>
39
4
  <meta property="rendition:layout">pre-paginated</meta>
40
5
  </metadata>
41
6
  <manifest>
42
- ${pageEntries.map(({ id, resourcePath }) => `<item id="${id}" href="${resourcePath}" />`).join(`
7
+ ${a.map(({id:e,resourcePath:t})=>`<item id="${e}" href="${t}" />`).join(`
43
8
  `)}
44
9
  </manifest>
45
10
  <spine>
46
- ${pageEntries.map(({ id }) => `<itemref idref="${id}" />`).join(`
11
+ ${a.map(({id:e})=>`<itemref idref="${e}" />`).join(`
47
12
  `)}
48
13
  </spine>
49
14
  </package>
50
- `;
51
- const opfFile = {
52
- dir: false,
53
- basename: `content.opf`,
54
- uri: `content.opf`,
55
- size: 0,
56
- blob: async () => new Blob(),
57
- string: async () => opfFileData
58
- };
59
- const archive = {
60
- filename,
61
- encodingFormat: "application/pdf",
62
- proxyDocument: pdf,
63
- _symbol: PDF_SYMBOL,
64
- records: [
65
- opfFile,
66
- ...pages.map((_, index) => ({
67
- dir: false,
68
- blob: async () => {
69
- throw new Error("Unable to get blob from pdf");
70
- },
71
- basename: `${index}.pdf`,
72
- size: 0,
73
- string: () => {
74
- throw new Error("Unable to get blob from pdf");
75
- },
76
- uri: `${index}.pdf`
77
- }))
78
- ],
79
- close: () => {
80
- return pdf.cleanup();
81
- }
82
- };
83
- return archive;
84
- };
85
-
86
- const pdfFrameStyle = "html {\n /* Pdf are always pre-paginated so its safe to disable touch action */\n touch-action: none;\n}\n\nbody {\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n /* This will prevent scrollbar and wrong offset of annotation layer */\n overflow: hidden;\n}\n";
87
-
88
- const layoutContainer = (container, spreadPosition, viewport) => {
89
- if (!container) return;
90
- const { height: pageHeight, width: pageWidth } = viewport.pageSize;
91
- core.setStylePropertyIfChanged(container.style, `width`, `${pageWidth}px`);
92
- core.setStylePropertyIfChanged(container.style, `height`, `${pageHeight}px`);
93
- if (spreadPosition === `right`) {
94
- core.setStylePropertyIfChanged(container.style, `justify-content`, `flex-start`);
95
- } else if (spreadPosition === `left`) {
96
- core.setStylePropertyIfChanged(container.style, `justify-content`, `flex-end`);
97
- } else {
98
- core.setStylePropertyIfChanged(container.style, `justify-content`, `center`);
99
- }
100
- };
101
- const layoutCanvas = (pageProxy, canvas, readerViewport) => {
102
- const pixelRatioScale = window.devicePixelRatio || 1;
103
- const { height: pageHeight, width: pageWidth } = readerViewport.pageSize;
104
- const { width: viewportWidth, height: viewportHeight } = pageProxy.getViewport({ scale: 1 });
105
- const pageScale = Math.max(
106
- pageWidth / viewportWidth,
107
- pageHeight / viewportHeight
108
- );
109
- const viewport = pageProxy.getViewport({ scale: pageScale });
110
- const viewportRatio = viewport.width / viewport.height;
111
- const pageRatio = pageWidth / pageHeight;
112
- const isWiderThanPage = viewportRatio > pageRatio;
113
- const canvasWidth = isWiderThanPage ? pageWidth : pageHeight * viewportRatio;
114
- const canvasHeight = viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight;
115
- core.setPropertyIfChanged(
116
- canvas,
117
- `width`,
118
- Math.floor(viewport.width * pixelRatioScale)
119
- );
120
- core.setPropertyIfChanged(
121
- canvas,
122
- `height`,
123
- Math.floor(viewport.height * pixelRatioScale)
124
- );
125
- core.setStylePropertyIfChanged(
126
- canvas.style,
127
- `width`,
128
- `${Math.floor(canvasWidth)}px`
129
- );
130
- core.setStylePropertyIfChanged(
131
- canvas.style,
132
- `height`,
133
- `${Math.floor(canvasHeight)}px`
134
- );
135
- };
136
-
137
- const pdfScaleStyle = `:root {
15
+ `;return{filename:n,encodingFormat:`application/pdf`,proxyDocument:r,_symbol:d,records:[{dir:!1,basename:`content.opf`,uri:`content.opf`,size:0,blob:async()=>new Blob,string:async()=>o},...i.map((e,t)=>({dir:!1,blob:async()=>{throw Error(`Unable to get blob from pdf`)},basename:`${t}.pdf`,size:0,string:()=>{throw Error(`Unable to get blob from pdf`)},uri:`${t}.pdf`}))],close:()=>r.cleanup()}},m=`html{touch-action:none}body{width:100%;height:100%;margin:0;padding:0;overflow:hidden}`,h=(e,t,n)=>{if(!e)return;let{height:i,width:a}=n.pageSize;(0,r.setStylePropertyIfChanged)(e.style,`width`,`${a}px`),(0,r.setStylePropertyIfChanged)(e.style,`height`,`${i}px`),t===`right`?(0,r.setStylePropertyIfChanged)(e.style,`justify-content`,`flex-start`):t===`left`?(0,r.setStylePropertyIfChanged)(e.style,`justify-content`,`flex-end`):(0,r.setStylePropertyIfChanged)(e.style,`justify-content`,`center`)},g=(e,t,n)=>{let i=window.devicePixelRatio||1,{height:a,width:o}=n.pageSize,{width:s,height:c}=e.getViewport({scale:1}),l=Math.max(o/s,a/c),u=e.getViewport({scale:l}),d=u.width/u.height,f=o/a,p=d>f?o:a*d,m=d>f?o/d:a;(0,r.setPropertyIfChanged)(t,`width`,Math.floor(u.width*i)),(0,r.setPropertyIfChanged)(t,`height`,Math.floor(u.height*i)),(0,r.setStylePropertyIfChanged)(t.style,`width`,`${Math.floor(p)}px`),(0,r.setStylePropertyIfChanged)(t.style,`height`,`${Math.floor(m)}px`)},_=`:root {
138
16
  --scale-factor: 1;
139
17
  --user-unit: 1;
140
18
  --total-scale-factor: calc(var(--scale-factor) * var(--user-unit));
141
19
  --scale-round-x: 1px;
142
20
  --scale-round-y: 1px;
143
- }`;
144
- class PdfRenderer extends core.DocumentRenderer {
145
- constructor(pdfViewerStyle, params) {
146
- super(params);
147
- this.pdfViewerStyle = pdfViewerStyle;
148
- }
149
- pdfViewerStyle;
150
- pageProxy;
151
- renderTask;
152
- textLayer;
153
- getCanvas() {
154
- const element = this.documentContainer?.children[0];
155
- if (!(element instanceof HTMLCanvasElement)) return;
156
- return element;
157
- }
158
- getFrameElement() {
159
- const frame = this.documentContainer?.children[1].children[0];
160
- if (!(frame instanceof HTMLIFrameElement)) return;
161
- return frame;
162
- }
163
- getPageProxy() {
164
- if (this.pageProxy) return rxjs.of(this.pageProxy);
165
- return rxjs.from(this.resourcesHandler.fetchResource()).pipe(
166
- rxjs.switchMap((resource) => {
167
- if (!("custom" in resource)) return rxjs.EMPTY;
168
- this.pageProxy = resource.data;
169
- return rxjs.of(this.pageProxy);
170
- })
171
- );
172
- }
173
- onUnload() {
174
- this.detach();
175
- if (this.renderTask) {
176
- this.renderTask.cancel();
177
- }
178
- this.textLayer?.cancel();
179
- this.pageProxy?.cleanup();
180
- return rxjs.EMPTY;
181
- }
182
- onCreateDocument() {
183
- const frameElement = document.createElement(`iframe`);
184
- frameElement.style.cssText = `
21
+ }`,v=class extends r.DocumentRenderer{pdfViewerStyle;pageProxy;renderTask;textLayer;constructor(e,t){super(t),this.pdfViewerStyle=e}getCanvas(){let e=this.documentContainer?.children[0];if(e instanceof HTMLCanvasElement)return e}getFrameElement(){let e=this.documentContainer?.children[1]?.children[0];if(e instanceof HTMLIFrameElement)return e}getPageProxy(){return this.pageProxy?(0,n.of)(this.pageProxy):(0,n.from)(this.resourcesHandler.fetchResource()).pipe((0,n.switchMap)(e=>`custom`in e?(this.pageProxy=e.data,(0,n.of)(this.pageProxy)):n.EMPTY))}onUnload(){return this.detach(),this.renderTask&&this.renderTask.cancel(),this.textLayer?.cancel(),this.pageProxy?.cleanup(),n.EMPTY}onCreateDocument(){let e=document.createElement(`iframe`);e.style.cssText=`
185
22
  overflow: hidden;
186
23
  height: 100%;
187
24
  width: 100%;
188
- `;
189
- frameElement.setAttribute("tabIndex", "0");
190
- frameElement.setAttribute("frameBorder", "0");
191
- frameElement.setAttribute(`src`, "about:blank");
192
- const frameContainer = this.containerElement.ownerDocument.createElement("div");
193
- frameContainer.style.cssText = `
25
+ `,e.setAttribute(`tabIndex`,`0`),e.setAttribute(`frameBorder`,`0`),e.setAttribute(`src`,`about:blank`);let t=this.containerElement.ownerDocument.createElement(`div`);t.style.cssText=`
194
26
  mix-blend-mode: multiply;
195
27
  -webkit-transform: translateZ(0);
196
28
  transform: translateZ(0);
@@ -198,199 +30,9 @@
198
30
  height: 100%;
199
31
  width: 100%;
200
32
  top: 0;
201
- `;
202
- const canvas = this.containerElement.ownerDocument.createElement("canvas");
203
- frameContainer.appendChild(frameElement);
204
- const rootElement = this.containerElement.ownerDocument.createElement(`div`);
205
- rootElement.style.cssText = `
33
+ `;let r=this.containerElement.ownerDocument.createElement(`canvas`);t.appendChild(e);let i=this.containerElement.ownerDocument.createElement(`div`);return i.style.cssText=`
206
34
  display: flex;
207
35
  align-items: center;
208
36
  justify-content: center;
209
- `;
210
- rootElement.appendChild(canvas);
211
- rootElement.appendChild(frameContainer);
212
- this.setDocumentContainer(rootElement);
213
- return rxjs.of(rootElement);
214
- }
215
- onLoadDocument() {
216
- return this.getPageProxy().pipe(
217
- rxjs.switchMap(() => {
218
- const frameElement = this.getFrameElement();
219
- const pageProxy = this.pageProxy;
220
- if (!frameElement || !pageProxy) return rxjs.EMPTY;
221
- return rxjs.of(frameElement).pipe(
222
- core.waitForSwitch(this.context.bridgeEvent.viewportFree$),
223
- rxjs.tap(() => {
224
- this.attach();
225
- }),
226
- core.waitForFrameLoad,
227
- rxjs.switchMap(() => {
228
- core.injectCSSToFrame(
229
- frameElement,
230
- "pdfjs-viewer-style",
231
- this.pdfViewerStyle
232
- );
233
- core.injectCSSToFrame(frameElement, "enhancer-pdf-style", pdfFrameStyle);
234
- core.upsertCSSToFrame(frameElement, "pdf-scale-scale", pdfScaleStyle);
235
- const frameBody = frameElement.contentDocument?.body;
236
- if (!frameBody || !this.pageProxy) return rxjs.EMPTY;
237
- core.setAttributeIfChanged(frameBody, "class", "textLayer");
238
- this.textLayer = new pdfjsLib.TextLayer({
239
- container: frameBody,
240
- textContentSource: this.pageProxy.streamTextContent(),
241
- viewport: this.pageProxy.getViewport({ scale: 1 })
242
- });
243
- return rxjs.from(this.textLayer.render());
244
- }),
245
- core.waitForFrameReady
246
- );
247
- })
248
- );
249
- }
250
- onLayout({
251
- spreadPosition
252
- }) {
253
- const frameElement = this.getFrameElement();
254
- const canvas = this.getCanvas();
255
- if (!frameElement || !canvas) return rxjs.of(void 0);
256
- const { height: pageHeight, width: pageWidth } = this.viewport.pageSize;
257
- layoutContainer(this.documentContainer, spreadPosition, this.viewport);
258
- const context = canvas.getContext("2d");
259
- const pixelRatioScale = window.devicePixelRatio || 1;
260
- if (!this.pageProxy || !context) return rxjs.of(void 0);
261
- if (this.renderTask) {
262
- this.renderTask.cancel();
263
- this.renderTask = void 0;
264
- }
265
- layoutCanvas(this.pageProxy, canvas, this.viewport);
266
- const { width: viewportWidth, height: viewportHeight } = this.pageProxy.getViewport({ scale: 1 });
267
- const pageScale = Math.max(
268
- pageWidth / viewportWidth,
269
- pageHeight / viewportHeight
270
- );
271
- const viewport = this.pageProxy.getViewport({ scale: pageScale });
272
- const transform = pixelRatioScale !== 1 ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0] : null;
273
- this.renderTask = this.pageProxy.render({
274
- ...transform && { transform },
275
- canvasContext: context,
276
- viewport,
277
- canvas
278
- });
279
- return rxjs.from(this.renderTask.promise).pipe(
280
- rxjs.switchMap(() => {
281
- this.renderTask = void 0;
282
- const frameDoc = frameElement?.contentDocument;
283
- const pdfPage = this.pageProxy;
284
- if (!frameDoc || !frameElement || !pdfPage || !this.textLayer) {
285
- throw new Error("Unable to update text layer due to missing elements");
286
- }
287
- const textLayerElement = frameDoc.body;
288
- const canvasScale = canvas.clientWidth / viewportWidth;
289
- core.setStylePropertyIfChanged(
290
- textLayerElement.style,
291
- `top`,
292
- `${canvas.offsetTop}px`
293
- );
294
- core.setStylePropertyIfChanged(
295
- textLayerElement.style,
296
- `left`,
297
- `${canvas.offsetLeft}px`
298
- );
299
- core.setStylePropertyIfChanged(
300
- textLayerElement.style,
301
- `height`,
302
- canvas.style.height
303
- );
304
- core.setStylePropertyIfChanged(
305
- textLayerElement.style,
306
- `width`,
307
- canvas.style.width
308
- );
309
- core.setStylePropertyIfChanged(
310
- frameDoc.documentElement.style,
311
- `--scale-factor`,
312
- `${canvasScale}`
313
- );
314
- this.textLayer.update({
315
- viewport
316
- });
317
- return rxjs.of(void 0);
318
- }),
319
- rxjs.catchError((e) => {
320
- if (!(e instanceof pdfjsLib.RenderingCancelledException)) console.error(e);
321
- return rxjs.of(void 0);
322
- })
323
- );
324
- }
325
- /**
326
- * @important
327
- * We should keep the same node structure to preserve CFI integrity.
328
- */
329
- onRenderHeadless() {
330
- return this.getPageProxy().pipe(
331
- rxjs.switchMap((pageProxy) => {
332
- const headlessDocument = document.implementation.createHTMLDocument();
333
- const textLayerElement = headlessDocument.body;
334
- const textLayer = new pdfjsLib.TextLayer({
335
- container: textLayerElement,
336
- textContentSource: pageProxy.streamTextContent(),
337
- viewport: pageProxy.getViewport({ scale: 1 })
338
- });
339
- return rxjs.from(textLayer.render()).pipe(rxjs.map(() => headlessDocument));
340
- })
341
- );
342
- }
343
- getDocumentFrame() {
344
- return this.getFrameElement();
345
- }
346
- }
347
-
348
- const pdfEnhancer = (next) => (options) => {
349
- const reader = next({
350
- ...options,
351
- /**
352
- * We have a special renderer for pdf so we need to inject it
353
- * for the relevant items. The enhancer could be configurable but for
354
- * the sake of simplicity we will assume that an item ending with .pdf should
355
- * be treated as a pdf document.
356
- *
357
- * The `getRenderer` hook should be non destructive, if we detect a renderer already
358
- * setup we should return it.
359
- */
360
- getRenderer(item) {
361
- const maybeFactory = options.getRenderer?.(item);
362
- if (!maybeFactory && item.href.endsWith(`.pdf`)) {
363
- return (params) => new PdfRenderer(options.pdf.pdfjsViewerInlineCss, params);
364
- }
365
- return maybeFactory;
366
- },
367
- getResource: (item) => options.pdf.getArchiveForItem(item).pipe(
368
- rxjs.mergeMap((archive) => {
369
- if (!archive) return rxjs.of(void 0);
370
- if (!isPdfJsArchive(archive)) {
371
- console.warn(`You provided an invalid pdf archive`);
372
- return rxjs.of(void 0);
373
- }
374
- const fileIndex = archive.records.findIndex(
375
- (file) => item.href.endsWith(file.uri)
376
- ) - 1;
377
- return rxjs.from(archive.proxyDocument.getPage(fileIndex + 1)).pipe(
378
- rxjs.map((pageProxy) => ({
379
- custom: true,
380
- data: pageProxy
381
- }))
382
- );
383
- })
384
- )
385
- });
386
- return reader;
387
- };
388
-
389
- exports.createArchiveFromPdf = createArchiveFromPdf;
390
- exports.isPdfJsArchive = isPdfJsArchive;
391
- exports.pdfEnhancer = pdfEnhancer;
392
-
393
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
394
-
395
- }));
396
- //# sourceMappingURL=index.umd.cjs.map
37
+ `,i.appendChild(r),i.appendChild(t),this.setDocumentContainer(i),(0,n.of)(i)}onLoadDocument(){return this.getPageProxy().pipe((0,n.switchMap)(()=>{let e=this.getFrameElement(),i=this.pageProxy;return!e||!i?n.EMPTY:(0,n.of)(e).pipe((0,r.waitForSwitch)(this.context.bridgeEvent.viewportFree$),(0,n.tap)(()=>{this.attach()}),r.waitForFrameLoad,(0,n.switchMap)(()=>{(0,r.injectCSSToFrame)(e,`pdfjs-viewer-style`,this.pdfViewerStyle),(0,r.injectCSSToFrame)(e,`enhancer-pdf-style`,m),(0,r.upsertCSSToFrame)(e,`pdf-scale-scale`,_);let i=e.contentDocument?.body;return!i||!this.pageProxy?n.EMPTY:((0,r.setAttributeIfChanged)(i,`class`,`textLayer`),this.textLayer=new t.TextLayer({container:i,textContentSource:this.pageProxy.streamTextContent(),viewport:this.pageProxy.getViewport({scale:1})}),(0,n.from)(this.textLayer.render()))}),r.waitForFrameReady)}))}onLayout({spreadPosition:e}){let i=this.getFrameElement(),a=this.getCanvas();if(!i||!a)return(0,n.of)(void 0);let{height:o,width:s}=this.viewport.pageSize;h(this.documentContainer,e,this.viewport);let c=a.getContext(`2d`),l=window.devicePixelRatio||1;if(!this.pageProxy||!c)return(0,n.of)(void 0);this.renderTask&&=(this.renderTask.cancel(),void 0),g(this.pageProxy,a,this.viewport);let{width:u,height:d}=this.pageProxy.getViewport({scale:1}),f=Math.max(s/u,o/d),p=this.pageProxy.getViewport({scale:f}),m=l===1?null:[l,0,0,l,0,0];return this.renderTask=this.pageProxy.render({...m&&{transform:m},canvasContext:c,viewport:p,canvas:a}),(0,n.from)(this.renderTask.promise).pipe((0,n.switchMap)(()=>{this.renderTask=void 0;let e=i?.contentDocument,t=this.pageProxy;if(!e||!i||!t||!this.textLayer)throw Error(`Unable to update text layer due to missing elements`);let o=e.body,s=a.clientWidth/u;return(0,r.setStylePropertyIfChanged)(o.style,`top`,`${a.offsetTop}px`),(0,r.setStylePropertyIfChanged)(o.style,`left`,`${a.offsetLeft}px`),(0,r.setStylePropertyIfChanged)(o.style,`height`,a.style.height),(0,r.setStylePropertyIfChanged)(o.style,`width`,a.style.width),(0,r.setStylePropertyIfChanged)(e.documentElement.style,`--scale-factor`,`${s}`),this.textLayer.update({viewport:p}),(0,n.of)(void 0)}),(0,n.catchError)(e=>(e instanceof t.RenderingCancelledException||console.error(e),(0,n.of)(void 0))))}onRenderHeadless(){return this.getPageProxy().pipe((0,n.switchMap)(e=>{let r=document.implementation.createHTMLDocument(),i=r.body;return(0,n.from)(new t.TextLayer({container:i,textContentSource:e.streamTextContent(),viewport:e.getViewport({scale:1})}).render()).pipe((0,n.map)(()=>r))}))}getDocumentFrame(){return this.getFrameElement()}};e.createArchiveFromPdf=p,e.isPdfJsArchive=f,e.pdfEnhancer=e=>t=>e({...t,getRenderer(e){let n=t.getRenderer?.(e);return!n&&e.href.endsWith(`.pdf`)?e=>new v(t.pdf.pdfjsViewerInlineCss,e):n},getResource:e=>t.pdf.getArchiveForItem(e).pipe((0,n.mergeMap)(t=>{if(!t)return(0,n.of)(void 0);if(!f(t))return console.warn(`You provided an invalid pdf archive`),(0,n.of)(void 0);let r=t.records.findIndex(t=>e.href.endsWith(t.uri))-1;return(0,n.from)(t.proxyDocument.getPage(r+1)).pipe((0,n.map)(e=>({custom:!0,data:e})))}))})});
38
+ //# sourceMappingURL=index.umd.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.cjs","sources":["../src/createArchiveFromPdf.ts","../src/renderer/layout.ts","../src/renderer/PdfRenderer.ts","../src/pdfEnhancer.ts"],"sourcesContent":["import type { Archive } from \"@prose-reader/streamer\"\nimport * as pdfjsLib from \"pdfjs-dist\"\n\ntype PdfJsArchive = Archive & {\n _symbol: symbol\n proxyDocument: pdfjsLib.PDFDocumentProxy\n}\n\nconst PDF_SYMBOL = Symbol(`pdfjs`)\n\nexport const isPdfJsArchive = (archive: Archive): archive is PdfJsArchive =>\n \"_symbol\" in archive && archive._symbol === PDF_SYMBOL\n\n/**\n * @important\n * Make sure the urls are on the same origin or the cors header is set otherwise\n * the resource cannot be consumed as it is on the web.\n */\nexport const createArchiveFromPdf = async (\n file: Blob,\n filename: string,\n): Promise<Archive> => {\n const loadingTask = pdfjsLib.getDocument(await file.arrayBuffer())\n\n const pdf = await loadingTask.promise\n\n const pages = Array.from({ length: pdf.numPages })\n const pageEntries = pages.map((_, index) => ({\n id: `page-${index}`,\n resourcePath: `${index}.pdf`,\n }))\n\n const opfFileData = `\n <?xml version=\"1.0\" encoding=\"UTF-8\"?><package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"bookid\">\n <metadata>\n <meta property=\"rendition:layout\">pre-paginated</meta>\n </metadata>\n <manifest>\n ${pageEntries.map(({ id, resourcePath }) => `<item id=\"${id}\" href=\"${resourcePath}\" />`).join(`\\n`)}\n </manifest>\n <spine>\n ${pageEntries.map(({ id }) => `<itemref idref=\"${id}\" />`).join(`\\n`)}\n </spine>\n </package>\n `\n\n const opfFile: Archive[`records`][number] = {\n dir: false,\n basename: `content.opf`,\n uri: `content.opf`,\n size: 0,\n blob: async () => new Blob(),\n string: async () => opfFileData,\n }\n\n const archive = {\n filename,\n encodingFormat: \"application/pdf\",\n proxyDocument: pdf,\n _symbol: PDF_SYMBOL,\n records: [\n opfFile,\n ...pages.map((_, index) => ({\n dir: false,\n blob: async () => {\n throw new Error(\"Unable to get blob from pdf\")\n },\n basename: `${index}.pdf`,\n size: 0,\n string: () => {\n throw new Error(\"Unable to get blob from pdf\")\n },\n uri: `${index}.pdf`,\n })),\n ],\n close: () => {\n return pdf.cleanup()\n },\n } satisfies PdfJsArchive\n\n return archive as Archive\n}\n","import {\n setPropertyIfChanged,\n setStylePropertyIfChanged,\n type Viewport,\n} from \"@prose-reader/core\"\nimport type { PDFPageProxy } from \"pdfjs-dist\"\n\nexport const layoutContainer = (\n container: HTMLElement | undefined,\n spreadPosition: `none` | `left` | `right`,\n viewport: Viewport,\n) => {\n if (!container) return\n\n // first we try to get the desired viewport for a comfortable reading based on theh current page size\n const { height: pageHeight, width: pageWidth } = viewport.pageSize\n\n setStylePropertyIfChanged(container.style, `width`, `${pageWidth}px`)\n setStylePropertyIfChanged(container.style, `height`, `${pageHeight}px`)\n\n if (spreadPosition === `right`) {\n setStylePropertyIfChanged(container.style, `justify-content`, `flex-start`)\n } else if (spreadPosition === `left`) {\n setStylePropertyIfChanged(container.style, `justify-content`, `flex-end`)\n } else {\n setStylePropertyIfChanged(container.style, `justify-content`, `center`)\n }\n}\n\nexport const layoutCanvas = (\n pageProxy: PDFPageProxy,\n canvas: HTMLCanvasElement,\n readerViewport: Viewport,\n) => {\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n const { height: pageHeight, width: pageWidth } = readerViewport.pageSize\n const { width: viewportWidth, height: viewportHeight } =\n pageProxy.getViewport({ scale: 1 })\n const pageScale = Math.max(\n pageWidth / viewportWidth,\n pageHeight / viewportHeight,\n )\n\n // then we generate the viewport for the canvas based on the page scale\n const viewport = pageProxy.getViewport({ scale: pageScale })\n\n // Then we define which axis should stretch or shrink to ratio\n const viewportRatio = viewport.width / viewport.height\n const pageRatio = pageWidth / pageHeight\n const isWiderThanPage = viewportRatio > pageRatio\n const canvasWidth = isWiderThanPage ? pageWidth : pageHeight * viewportRatio\n const canvasHeight =\n viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight\n\n setPropertyIfChanged(\n canvas,\n `width`,\n Math.floor(viewport.width * pixelRatioScale),\n )\n setPropertyIfChanged(\n canvas,\n `height`,\n Math.floor(viewport.height * pixelRatioScale),\n )\n setStylePropertyIfChanged(\n canvas.style,\n `width`,\n `${Math.floor(canvasWidth)}px`,\n )\n setStylePropertyIfChanged(\n canvas.style,\n `height`,\n `${Math.floor(canvasHeight)}px`,\n )\n}\n","import {\n DocumentRenderer,\n injectCSSToFrame,\n setAttributeIfChanged,\n setStylePropertyIfChanged,\n upsertCSSToFrame,\n waitForFrameLoad,\n waitForFrameReady,\n waitForSwitch,\n} from \"@prose-reader/core\"\nimport {\n type PDFPageProxy,\n RenderingCancelledException,\n type RenderTask,\n TextLayer,\n} from \"pdfjs-dist\"\nimport {\n catchError,\n EMPTY,\n from,\n map,\n type Observable,\n of,\n switchMap,\n tap,\n} from \"rxjs\"\nimport pdfFrameStyle from \"./frame.css?inline\"\nimport { layoutCanvas, layoutContainer } from \"./layout\"\n\nconst pdfScaleStyle = `:root {\n --scale-factor: 1;\n --user-unit: 1;\n --total-scale-factor: calc(var(--scale-factor) * var(--user-unit));\n --scale-round-x: 1px;\n --scale-round-y: 1px;\n}`\n\nexport class PdfRenderer extends DocumentRenderer {\n private pageProxy: PDFPageProxy | undefined\n private renderTask: RenderTask | undefined\n private textLayer: TextLayer | undefined\n\n constructor(\n private pdfViewerStyle: string,\n params: ConstructorParameters<typeof DocumentRenderer>[0],\n ) {\n super(params)\n }\n\n private getCanvas() {\n const element = this.documentContainer?.children[0]\n\n if (!(element instanceof HTMLCanvasElement)) return\n\n return element\n }\n\n private getFrameElement() {\n const frame = this.documentContainer?.children[1].children[0]\n\n if (!(frame instanceof HTMLIFrameElement)) return\n\n return frame\n }\n\n private getPageProxy() {\n if (this.pageProxy) return of(this.pageProxy)\n\n return from(this.resourcesHandler.fetchResource()).pipe(\n switchMap((resource) => {\n if (!(\"custom\" in resource)) return EMPTY\n\n this.pageProxy = resource.data as PDFPageProxy\n\n return of(this.pageProxy)\n }),\n )\n }\n\n onUnload(): Observable<unknown> {\n this.detach()\n\n if (this.renderTask) {\n this.renderTask.cancel()\n }\n\n this.textLayer?.cancel()\n this.pageProxy?.cleanup()\n\n return EMPTY\n }\n\n onCreateDocument(): Observable<HTMLElement> {\n const frameElement = document.createElement(`iframe`)\n frameElement.style.cssText = `\n overflow: hidden;\n height: 100%;\n width: 100%;\n `\n\n frameElement.setAttribute(\"tabIndex\", \"0\")\n frameElement.setAttribute(\"frameBorder\", \"0\")\n frameElement.setAttribute(`src`, \"about:blank\")\n\n const frameContainer =\n this.containerElement.ownerDocument.createElement(\"div\")\n frameContainer.style.cssText = `\n mix-blend-mode: multiply;\n -webkit-transform: translateZ(0);\n transform: translateZ(0);\n position: absolute;\n height: 100%;\n width: 100%;\n top: 0;\n `\n\n /**\n * The canvas is never attached to the DOM and will be used for offscreen rendering\n * then copied into the frame.\n */\n const canvas = this.containerElement.ownerDocument.createElement(\"canvas\")\n\n frameContainer.appendChild(frameElement)\n\n const rootElement = this.containerElement.ownerDocument.createElement(`div`)\n rootElement.style.cssText = `\n display: flex;\n align-items: center;\n justify-content: center;\n `\n\n rootElement.appendChild(canvas)\n rootElement.appendChild(frameContainer)\n\n this.setDocumentContainer(rootElement)\n\n return of(rootElement)\n }\n\n onLoadDocument(): Observable<unknown> {\n return this.getPageProxy().pipe(\n switchMap(() => {\n const frameElement = this.getFrameElement()\n const pageProxy = this.pageProxy\n\n if (!frameElement || !pageProxy) return EMPTY\n\n return of(frameElement).pipe(\n waitForSwitch(this.context.bridgeEvent.viewportFree$),\n tap(() => {\n this.attach()\n }),\n waitForFrameLoad,\n switchMap(() => {\n injectCSSToFrame(\n frameElement,\n \"pdfjs-viewer-style\",\n this.pdfViewerStyle,\n )\n injectCSSToFrame(frameElement, \"enhancer-pdf-style\", pdfFrameStyle)\n upsertCSSToFrame(frameElement, \"pdf-scale-scale\", pdfScaleStyle)\n\n /**\n * We make sure to render the text layer to simulate the document being loaded.\n * It will be correctly re-layout later. Consumers looking for document load have at least\n * the actual text document ready. (cfi lookup, etc.)\n */\n const frameBody = frameElement.contentDocument?.body\n\n if (!frameBody || !this.pageProxy) return EMPTY\n\n setAttributeIfChanged(frameBody, \"class\", \"textLayer\")\n\n this.textLayer = new TextLayer({\n container: frameBody,\n textContentSource: this.pageProxy.streamTextContent(),\n viewport: this.pageProxy.getViewport({ scale: 1 }),\n })\n\n return from(this.textLayer.render())\n }),\n waitForFrameReady,\n )\n }),\n )\n }\n\n onLayout({\n spreadPosition,\n }: {\n minPageSpread: number\n blankPagePosition: `before` | `after` | `none`\n spreadPosition: `none` | `left` | `right`\n }) {\n const frameElement = this.getFrameElement()\n const canvas = this.getCanvas()\n\n if (!frameElement || !canvas) return of(undefined)\n\n // first we try to get the desired viewport for a comfortable reading based on the current page size\n const { height: pageHeight, width: pageWidth } = this.viewport.pageSize\n\n layoutContainer(this.documentContainer, spreadPosition, this.viewport)\n\n const context = canvas.getContext(\"2d\")\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n\n if (!this.pageProxy || !context) return of(undefined)\n\n if (this.renderTask) {\n this.renderTask.cancel()\n this.renderTask = undefined\n }\n\n layoutCanvas(this.pageProxy, canvas, this.viewport)\n\n const { width: viewportWidth, height: viewportHeight } =\n this.pageProxy.getViewport({ scale: 1 })\n\n const pageScale = Math.max(\n pageWidth / viewportWidth,\n pageHeight / viewportHeight,\n )\n\n // then we generate the viewport for the canvas based on the page scale\n const viewport = this.pageProxy.getViewport({ scale: pageScale })\n\n const transform =\n pixelRatioScale !== 1\n ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0]\n : null\n\n this.renderTask = this.pageProxy.render({\n ...(transform && { transform }),\n canvasContext: context,\n viewport,\n canvas,\n })\n\n return from(this.renderTask.promise).pipe(\n switchMap(() => {\n this.renderTask = undefined\n\n const frameDoc = frameElement?.contentDocument\n const pdfPage = this.pageProxy\n\n if (!frameDoc || !frameElement || !pdfPage || !this.textLayer) {\n throw new Error(\"Unable to update text layer due to missing elements\")\n }\n\n const textLayerElement = frameDoc.body\n const canvasScale = canvas.clientWidth / viewportWidth\n\n setStylePropertyIfChanged(\n textLayerElement.style,\n `top`,\n `${canvas.offsetTop}px`,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `left`,\n `${canvas.offsetLeft}px`,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `height`,\n canvas.style.height,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `width`,\n canvas.style.width,\n )\n\n /**\n * Taking inspiration from https://github.com/mozilla/pdf.js/blob/master/web/pdf_viewer.css.\n * Not sure why pdfjs DOES rely on css from the viewer to works. Or in another words, why is it\n * not more obvious that TextLayer requires a set of variables to work correctly.\n */\n setStylePropertyIfChanged(\n frameDoc.documentElement.style,\n `--scale-factor`,\n `${canvasScale}`,\n )\n\n this.textLayer.update({\n viewport,\n })\n\n return of(undefined)\n }),\n catchError((e) => {\n if (!(e instanceof RenderingCancelledException)) console.error(e)\n\n return of(undefined)\n }),\n )\n }\n\n /**\n * @important\n * We should keep the same node structure to preserve CFI integrity.\n */\n onRenderHeadless() {\n return this.getPageProxy().pipe(\n switchMap((pageProxy) => {\n const headlessDocument = document.implementation.createHTMLDocument()\n const textLayerElement = headlessDocument.body\n\n const textLayer = new TextLayer({\n container: textLayerElement,\n textContentSource: pageProxy.streamTextContent(),\n viewport: pageProxy.getViewport({ scale: 1 }),\n })\n\n return from(textLayer.render()).pipe(map(() => headlessDocument))\n }),\n )\n }\n\n getDocumentFrame() {\n return this.getFrameElement()\n }\n}\n","import type { createReader, Reader } from \"@prose-reader/core\"\nimport { from, map, mergeMap, of } from \"rxjs\"\nimport { isPdfJsArchive } from \"./createArchiveFromPdf\"\nimport { PdfRenderer } from \"./renderer/PdfRenderer\"\nimport type { EnhancerOptions } from \"./types\"\n\ntype CreateReader = typeof createReader\ntype CreateReaderOptions = Parameters<CreateReader>[0]\n\nexport const pdfEnhancer =\n <InheritOptions extends CreateReaderOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (options: InheritOptions & EnhancerOptions): InheritOutput => {\n const reader = next({\n ...options,\n /**\n * We have a special renderer for pdf so we need to inject it\n * for the relevant items. The enhancer could be configurable but for\n * the sake of simplicity we will assume that an item ending with .pdf should\n * be treated as a pdf document.\n *\n * The `getRenderer` hook should be non destructive, if we detect a renderer already\n * setup we should return it.\n */\n getRenderer(item) {\n const maybeFactory = options.getRenderer?.(item)\n\n if (!maybeFactory && item.href.endsWith(`.pdf`)) {\n return (params) =>\n new PdfRenderer(options.pdf.pdfjsViewerInlineCss, params)\n }\n\n return maybeFactory\n },\n getResource: (item) =>\n options.pdf.getArchiveForItem(item).pipe(\n mergeMap((archive) => {\n if (!archive) return of(undefined)\n\n if (!isPdfJsArchive(archive)) {\n console.warn(`You provided an invalid pdf archive`)\n\n return of(undefined)\n }\n\n // we account for opf file\n const fileIndex =\n archive.records.findIndex((file) =>\n item.href.endsWith(file.uri),\n ) - 1\n\n return from(archive.proxyDocument.getPage(fileIndex + 1)).pipe(\n map((pageProxy) => ({\n custom: true as const,\n data: pageProxy,\n })),\n )\n }),\n ),\n })\n\n return reader\n }\n"],"names":["pdfjsLib","setStylePropertyIfChanged","setPropertyIfChanged","DocumentRenderer","of","from","switchMap","EMPTY","waitForSwitch","tap","waitForFrameLoad","injectCSSToFrame","upsertCSSToFrame","setAttributeIfChanged","TextLayer","waitForFrameReady","catchError","RenderingCancelledException","map","mergeMap"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EAQA,MAAM,UAAA,0BAAoB,CAAA,KAAA,CAAO,CAAA;AAE1B,QAAM,iBAAiB,CAAC,OAAA,KAC7B,SAAA,IAAa,OAAA,IAAW,QAAQ,OAAA,KAAY;AAOvC,QAAM,oBAAA,GAAuB,OAClC,IAAA,EACA,QAAA,KACqB;EACrB,EAAA,MAAM,cAAcA,mBAAA,CAAS,WAAA,CAAY,MAAM,IAAA,CAAK,aAAa,CAAA;EAEjE,EAAA,MAAM,GAAA,GAAM,MAAM,WAAA,CAAY,OAAA;EAE9B,EAAA,MAAM,QAAQ,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,GAAA,CAAI,UAAU,CAAA;EACjD,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,GAAA,CAAI,CAAC,GAAG,KAAA,MAAW;EAAA,IAC3C,EAAA,EAAI,QAAQ,KAAK,CAAA,CAAA;EAAA,IACjB,YAAA,EAAc,GAAG,KAAK,CAAA,IAAA;EAAA,GACxB,CAAE,CAAA;EAEF,EAAA,MAAM,WAAA,GAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,EAMZ,WAAA,CAAY,GAAA,CAAI,CAAC,EAAE,EAAA,EAAI,YAAA,EAAa,KAAM,CAAA,UAAA,EAAa,EAAE,CAAA,QAAA,EAAW,YAAY,CAAA,IAAA,CAAM,EAAE,IAAA,CAAK;AAAA,CAAI,CAAC;AAAA;AAAA;AAAA,QAAA,EAGlG,WAAA,CAAY,GAAA,CAAI,CAAC,EAAE,EAAA,OAAS,CAAA,gBAAA,EAAmB,EAAE,CAAA,IAAA,CAAM,CAAA,CAAE,IAAA,CAAK;AAAA,CAAI,CAAC;AAAA;AAAA;AAAA,EAAA,CAAA;EAK3E,EAAA,MAAM,OAAA,GAAsC;EAAA,IAC1C,GAAA,EAAK,KAAA;EAAA,IACL,QAAA,EAAU,CAAA,WAAA,CAAA;EAAA,IACV,GAAA,EAAK,CAAA,WAAA,CAAA;EAAA,IACL,IAAA,EAAM,CAAA;EAAA,IACN,IAAA,EAAM,YAAY,IAAI,IAAA,EAAK;EAAA,IAC3B,QAAQ,YAAY;EAAA,GACtB;EAEA,EAAA,MAAM,OAAA,GAAU;EAAA,IACd,QAAA;EAAA,IACA,cAAA,EAAgB,iBAAA;EAAA,IAChB,aAAA,EAAe,GAAA;EAAA,IACf,OAAA,EAAS,UAAA;EAAA,IACT,OAAA,EAAS;EAAA,MACP,OAAA;EAAA,MACA,GAAG,KAAA,CAAM,GAAA,CAAI,CAAC,GAAG,KAAA,MAAW;EAAA,QAC1B,GAAA,EAAK,KAAA;EAAA,QACL,MAAM,YAAY;EAChB,UAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;EAAA,QAC/C,CAAA;EAAA,QACA,QAAA,EAAU,GAAG,KAAK,CAAA,IAAA,CAAA;EAAA,QAClB,IAAA,EAAM,CAAA;EAAA,QACN,QAAQ,MAAM;EACZ,UAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;EAAA,QAC/C,CAAA;EAAA,QACA,GAAA,EAAK,GAAG,KAAK,CAAA,IAAA;EAAA,OACf,CAAE;EAAA,KACJ;EAAA,IACA,OAAO,MAAM;EACX,MAAA,OAAO,IAAI,OAAA,EAAQ;EAAA,IACrB;EAAA,GACF;EAEA,EAAA,OAAO,OAAA;EACT;;;;EC1EO,MAAM,eAAA,GAAkB,CAC7B,SAAA,EACA,cAAA,EACA,QAAA,KACG;EACH,EAAA,IAAI,CAAC,SAAA,EAAW;EAGhB,EAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAY,KAAA,EAAO,SAAA,KAAc,QAAA,CAAS,QAAA;EAE1D,EAAAC,8BAAA,CAA0B,SAAA,CAAU,KAAA,EAAO,CAAA,KAAA,CAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAA,CAAI,CAAA;EACpE,EAAAA,8BAAA,CAA0B,SAAA,CAAU,KAAA,EAAO,CAAA,MAAA,CAAA,EAAU,CAAA,EAAG,UAAU,CAAA,EAAA,CAAI,CAAA;EAEtE,EAAA,IAAI,mBAAmB,CAAA,KAAA,CAAA,EAAS;EAC9B,IAAAA,8BAAA,CAA0B,SAAA,CAAU,KAAA,EAAO,CAAA,eAAA,CAAA,EAAmB,CAAA,UAAA,CAAY,CAAA;EAAA,EAC5E,CAAA,MAAA,IAAW,mBAAmB,CAAA,IAAA,CAAA,EAAQ;EACpC,IAAAA,8BAAA,CAA0B,SAAA,CAAU,KAAA,EAAO,CAAA,eAAA,CAAA,EAAmB,CAAA,QAAA,CAAU,CAAA;EAAA,EAC1E,CAAA,MAAO;EACL,IAAAA,8BAAA,CAA0B,SAAA,CAAU,KAAA,EAAO,CAAA,eAAA,CAAA,EAAmB,CAAA,MAAA,CAAQ,CAAA;EAAA,EACxE;EACF,CAAA;EAEO,MAAM,YAAA,GAAe,CAC1B,SAAA,EACA,MAAA,EACA,cAAA,KACG;EAEH,EAAA,MAAM,eAAA,GAAkB,OAAO,gBAAA,IAAoB,CAAA;EACnD,EAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAY,KAAA,EAAO,SAAA,KAAc,cAAA,CAAe,QAAA;EAChE,EAAA,MAAM,EAAE,KAAA,EAAO,aAAA,EAAe,MAAA,EAAQ,cAAA,EAAe,GACnD,SAAA,CAAU,WAAA,CAAY,EAAE,KAAA,EAAO,CAAA,EAAG,CAAA;EACpC,EAAA,MAAM,YAAY,IAAA,CAAK,GAAA;EAAA,IACrB,SAAA,GAAY,aAAA;EAAA,IACZ,UAAA,GAAa;EAAA,GACf;EAGA,EAAA,MAAM,WAAW,SAAA,CAAU,WAAA,CAAY,EAAE,KAAA,EAAO,WAAW,CAAA;EAG3D,EAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,KAAA,GAAQ,QAAA,CAAS,MAAA;EAChD,EAAA,MAAM,YAAY,SAAA,GAAY,UAAA;EAC9B,EAAA,MAAM,kBAAkB,aAAA,GAAgB,SAAA;EACxC,EAAA,MAAM,WAAA,GAAc,eAAA,GAAkB,SAAA,GAAY,UAAA,GAAa,aAAA;EAC/D,EAAA,MAAM,YAAA,GACJ,aAAA,GAAgB,SAAA,GAAY,SAAA,GAAY,aAAA,GAAgB,UAAA;EAE1D,EAAAC,yBAAA;EAAA,IACE,MAAA;EAAA,IACA,CAAA,KAAA,CAAA;EAAA,IACA,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,KAAA,GAAQ,eAAe;EAAA,GAC7C;EACA,EAAAA,yBAAA;EAAA,IACE,MAAA;EAAA,IACA,CAAA,MAAA,CAAA;EAAA,IACA,IAAA,CAAK,KAAA,CAAM,QAAA,CAAS,MAAA,GAAS,eAAe;EAAA,GAC9C;EACA,EAAAD,8BAAA;EAAA,IACE,MAAA,CAAO,KAAA;EAAA,IACP,CAAA,KAAA,CAAA;EAAA,IACA,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,WAAW,CAAC,CAAA,EAAA;EAAA,GAC5B;EACA,EAAAA,8BAAA;EAAA,IACE,MAAA,CAAO,KAAA;EAAA,IACP,CAAA,MAAA,CAAA;EAAA,IACA,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,YAAY,CAAC,CAAA,EAAA;EAAA,GAC7B;EACF,CAAA;;EC9CA,MAAM,aAAA,GAAgB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;EAQf,MAAM,oBAAoBE,qBAAA,CAAiB;EAAA,EAKhD,WAAA,CACU,gBACR,MAAA,EACA;EACA,IAAA,KAAA,CAAM,MAAM,CAAA;EAHJ,IAAA,IAAA,CAAA,cAAA,GAAA,cAAA;EAAA,EAIV;EAAA,EAJU,cAAA;EAAA,EALF,SAAA;EAAA,EACA,UAAA;EAAA,EACA,SAAA;EAAA,EASA,SAAA,GAAY;EAClB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,iBAAA,EAAmB,QAAA,CAAS,CAAC,CAAA;EAElD,IAAA,IAAI,EAAE,mBAAmB,iBAAA,CAAA,EAAoB;EAE7C,IAAA,OAAO,OAAA;EAAA,EACT;EAAA,EAEQ,eAAA,GAAkB;EACxB,IAAA,MAAM,QAAQ,IAAA,CAAK,iBAAA,EAAmB,SAAS,CAAC,CAAA,CAAE,SAAS,CAAC,CAAA;EAE5D,IAAA,IAAI,EAAE,iBAAiB,iBAAA,CAAA,EAAoB;EAE3C,IAAA,OAAO,KAAA;EAAA,EACT;EAAA,EAEQ,YAAA,GAAe;EACrB,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,OAAOC,OAAA,CAAG,KAAK,SAAS,CAAA;EAE5C,IAAA,OAAOC,SAAA,CAAK,IAAA,CAAK,gBAAA,CAAiB,aAAA,EAAe,CAAA,CAAE,IAAA;EAAA,MACjDC,cAAA,CAAU,CAAC,QAAA,KAAa;EACtB,QAAA,IAAI,EAAE,QAAA,IAAY,QAAA,CAAA,EAAW,OAAOC,UAAA;EAEpC,QAAA,IAAA,CAAK,YAAY,QAAA,CAAS,IAAA;EAE1B,QAAA,OAAOH,OAAA,CAAG,KAAK,SAAS,CAAA;EAAA,MAC1B,CAAC;EAAA,KACH;EAAA,EACF;EAAA,EAEA,QAAA,GAAgC;EAC9B,IAAA,IAAA,CAAK,MAAA,EAAO;EAEZ,IAAA,IAAI,KAAK,UAAA,EAAY;EACnB,MAAA,IAAA,CAAK,WAAW,MAAA,EAAO;EAAA,IACzB;EAEA,IAAA,IAAA,CAAK,WAAW,MAAA,EAAO;EACvB,IAAA,IAAA,CAAK,WAAW,OAAA,EAAQ;EAExB,IAAA,OAAOG,UAAA;EAAA,EACT;EAAA,EAEA,gBAAA,GAA4C;EAC1C,IAAA,MAAM,YAAA,GAAe,QAAA,CAAS,aAAA,CAAc,CAAA,MAAA,CAAQ,CAAA;EACpD,IAAA,YAAA,CAAa,MAAM,OAAA,GAAU;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;EAM7B,IAAA,YAAA,CAAa,YAAA,CAAa,YAAY,GAAG,CAAA;EACzC,IAAA,YAAA,CAAa,YAAA,CAAa,eAAe,GAAG,CAAA;EAC5C,IAAA,YAAA,CAAa,YAAA,CAAa,OAAO,aAAa,CAAA;EAE9C,IAAA,MAAM,cAAA,GACJ,IAAA,CAAK,gBAAA,CAAiB,aAAA,CAAc,cAAc,KAAK,CAAA;EACzD,IAAA,cAAA,CAAe,MAAM,OAAA,GAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;EAc/B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,gBAAA,CAAiB,aAAA,CAAc,cAAc,QAAQ,CAAA;EAEzE,IAAA,cAAA,CAAe,YAAY,YAAY,CAAA;EAEvC,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,gBAAA,CAAiB,aAAA,CAAc,cAAc,CAAA,GAAA,CAAK,CAAA;EAC3E,IAAA,WAAA,CAAY,MAAM,OAAA,GAAU;AAAA;AAAA;AAAA;AAAA,IAAA,CAAA;EAM5B,IAAA,WAAA,CAAY,YAAY,MAAM,CAAA;EAC9B,IAAA,WAAA,CAAY,YAAY,cAAc,CAAA;EAEtC,IAAA,IAAA,CAAK,qBAAqB,WAAW,CAAA;EAErC,IAAA,OAAOH,QAAG,WAAW,CAAA;EAAA,EACvB;EAAA,EAEA,cAAA,GAAsC;EACpC,IAAA,OAAO,IAAA,CAAK,cAAa,CAAE,IAAA;EAAA,MACzBE,eAAU,MAAM;EACd,QAAA,MAAM,YAAA,GAAe,KAAK,eAAA,EAAgB;EAC1C,QAAA,MAAM,YAAY,IAAA,CAAK,SAAA;EAEvB,QAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,SAAA,EAAW,OAAOC,UAAA;EAExC,QAAA,OAAOH,OAAA,CAAG,YAAY,CAAA,CAAE,IAAA;EAAA,UACtBI,kBAAA,CAAc,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,aAAa,CAAA;EAAA,UACpDC,SAAI,MAAM;EACR,YAAA,IAAA,CAAK,MAAA,EAAO;EAAA,UACd,CAAC,CAAA;EAAA,UACDC,qBAAA;EAAA,UACAJ,eAAU,MAAM;EACd,YAAAK,qBAAA;EAAA,cACE,YAAA;EAAA,cACA,oBAAA;EAAA,cACA,IAAA,CAAK;EAAA,aACP;EACA,YAAAA,qBAAA,CAAiB,YAAA,EAAc,sBAAsB,aAAa,CAAA;EAClE,YAAAC,qBAAA,CAAiB,YAAA,EAAc,mBAAmB,aAAa,CAAA;EAO/D,YAAA,MAAM,SAAA,GAAY,aAAa,eAAA,EAAiB,IAAA;EAEhD,YAAA,IAAI,CAAC,SAAA,IAAa,CAAC,IAAA,CAAK,WAAW,OAAOL,UAAA;EAE1C,YAAAM,0BAAA,CAAsB,SAAA,EAAW,SAAS,WAAW,CAAA;EAErD,YAAA,IAAA,CAAK,SAAA,GAAY,IAAIC,kBAAA,CAAU;EAAA,cAC7B,SAAA,EAAW,SAAA;EAAA,cACX,iBAAA,EAAmB,IAAA,CAAK,SAAA,CAAU,iBAAA,EAAkB;EAAA,cACpD,UAAU,IAAA,CAAK,SAAA,CAAU,YAAY,EAAE,KAAA,EAAO,GAAG;EAAA,aAClD,CAAA;EAED,YAAA,OAAOT,SAAA,CAAK,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,CAAA;EAAA,UACrC,CAAC,CAAA;EAAA,UACDU;EAAA,SACF;EAAA,MACF,CAAC;EAAA,KACH;EAAA,EACF;EAAA,EAEA,QAAA,CAAS;EAAA,IACP;EAAA,GACF,EAIG;EACD,IAAA,MAAM,YAAA,GAAe,KAAK,eAAA,EAAgB;EAC1C,IAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;EAE9B,IAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,MAAA,EAAQ,OAAOX,QAAG,MAAS,CAAA;EAGjD,IAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAY,OAAO,SAAA,EAAU,GAAI,KAAK,QAAA,CAAS,QAAA;EAE/D,IAAA,eAAA,CAAgB,IAAA,CAAK,iBAAA,EAAmB,cAAA,EAAgB,IAAA,CAAK,QAAQ,CAAA;EAErE,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;EAEtC,IAAA,MAAM,eAAA,GAAkB,OAAO,gBAAA,IAAoB,CAAA;EAEnD,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,IAAa,CAAC,OAAA,EAAS,OAAOA,QAAG,MAAS,CAAA;EAEpD,IAAA,IAAI,KAAK,UAAA,EAAY;EACnB,MAAA,IAAA,CAAK,WAAW,MAAA,EAAO;EACvB,MAAA,IAAA,CAAK,UAAA,GAAa,MAAA;EAAA,IACpB;EAEA,IAAA,YAAA,CAAa,IAAA,CAAK,SAAA,EAAW,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA;EAElD,IAAA,MAAM,EAAE,KAAA,EAAO,aAAA,EAAe,MAAA,EAAQ,cAAA,EAAe,GACnD,IAAA,CAAK,SAAA,CAAU,WAAA,CAAY,EAAE,KAAA,EAAO,CAAA,EAAG,CAAA;EAEzC,IAAA,MAAM,YAAY,IAAA,CAAK,GAAA;EAAA,MACrB,SAAA,GAAY,aAAA;EAAA,MACZ,UAAA,GAAa;EAAA,KACf;EAGA,IAAA,MAAM,WAAW,IAAA,CAAK,SAAA,CAAU,YAAY,EAAE,KAAA,EAAO,WAAW,CAAA;EAEhE,IAAA,MAAM,SAAA,GACJ,eAAA,KAAoB,CAAA,GAChB,CAAC,eAAA,EAAiB,GAAG,CAAA,EAAG,eAAA,EAAiB,CAAA,EAAG,CAAC,CAAA,GAC7C,IAAA;EAEN,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO;EAAA,MACtC,GAAI,SAAA,IAAa,EAAE,SAAA,EAAU;EAAA,MAC7B,aAAA,EAAe,OAAA;EAAA,MACf,QAAA;EAAA,MACA;EAAA,KACD,CAAA;EAED,IAAA,OAAOC,SAAA,CAAK,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA,CAAE,IAAA;EAAA,MACnCC,eAAU,MAAM;EACd,QAAA,IAAA,CAAK,UAAA,GAAa,MAAA;EAElB,QAAA,MAAM,WAAW,YAAA,EAAc,eAAA;EAC/B,QAAA,MAAM,UAAU,IAAA,CAAK,SAAA;EAErB,QAAA,IAAI,CAAC,YAAY,CAAC,YAAA,IAAgB,CAAC,OAAA,IAAW,CAAC,KAAK,SAAA,EAAW;EAC7D,UAAA,MAAM,IAAI,MAAM,qDAAqD,CAAA;EAAA,QACvE;EAEA,QAAA,MAAM,mBAAmB,QAAA,CAAS,IAAA;EAClC,QAAA,MAAM,WAAA,GAAc,OAAO,WAAA,GAAc,aAAA;EAEzC,QAAAL,8BAAA;EAAA,UACE,gBAAA,CAAiB,KAAA;EAAA,UACjB,CAAA,GAAA,CAAA;EAAA,UACA,CAAA,EAAG,OAAO,SAAS,CAAA,EAAA;EAAA,SACrB;EACA,QAAAA,8BAAA;EAAA,UACE,gBAAA,CAAiB,KAAA;EAAA,UACjB,CAAA,IAAA,CAAA;EAAA,UACA,CAAA,EAAG,OAAO,UAAU,CAAA,EAAA;EAAA,SACtB;EACA,QAAAA,8BAAA;EAAA,UACE,gBAAA,CAAiB,KAAA;EAAA,UACjB,CAAA,MAAA,CAAA;EAAA,UACA,OAAO,KAAA,CAAM;EAAA,SACf;EACA,QAAAA,8BAAA;EAAA,UACE,gBAAA,CAAiB,KAAA;EAAA,UACjB,CAAA,KAAA,CAAA;EAAA,UACA,OAAO,KAAA,CAAM;EAAA,SACf;EAOA,QAAAA,8BAAA;EAAA,UACE,SAAS,eAAA,CAAgB,KAAA;EAAA,UACzB,CAAA,cAAA,CAAA;EAAA,UACA,GAAG,WAAW,CAAA;EAAA,SAChB;EAEA,QAAA,IAAA,CAAK,UAAU,MAAA,CAAO;EAAA,UACpB;EAAA,SACD,CAAA;EAED,QAAA,OAAOG,QAAG,MAAS,CAAA;EAAA,MACrB,CAAC,CAAA;EAAA,MACDY,eAAA,CAAW,CAAC,CAAA,KAAM;EAChB,QAAA,IAAI,EAAE,CAAA,YAAaC,oCAAA,CAAA,EAA8B,OAAA,CAAQ,MAAM,CAAC,CAAA;EAEhE,QAAA,OAAOb,QAAG,MAAS,CAAA;EAAA,MACrB,CAAC;EAAA,KACH;EAAA,EACF;EAAA;EAAA;EAAA;EAAA;EAAA,EAMA,gBAAA,GAAmB;EACjB,IAAA,OAAO,IAAA,CAAK,cAAa,CAAE,IAAA;EAAA,MACzBE,cAAA,CAAU,CAAC,SAAA,KAAc;EACvB,QAAA,MAAM,gBAAA,GAAmB,QAAA,CAAS,cAAA,CAAe,kBAAA,EAAmB;EACpE,QAAA,MAAM,mBAAmB,gBAAA,CAAiB,IAAA;EAE1C,QAAA,MAAM,SAAA,GAAY,IAAIQ,kBAAA,CAAU;EAAA,UAC9B,SAAA,EAAW,gBAAA;EAAA,UACX,iBAAA,EAAmB,UAAU,iBAAA,EAAkB;EAAA,UAC/C,UAAU,SAAA,CAAU,WAAA,CAAY,EAAE,KAAA,EAAO,GAAG;EAAA,SAC7C,CAAA;EAED,QAAA,OAAOT,SAAA,CAAK,UAAU,MAAA,EAAQ,EAAE,IAAA,CAAKa,QAAA,CAAI,MAAM,gBAAgB,CAAC,CAAA;EAAA,MAClE,CAAC;EAAA,KACH;EAAA,EACF;EAAA,EAEA,gBAAA,GAAmB;EACjB,IAAA,OAAO,KAAK,eAAA,EAAgB;EAAA,EAC9B;EACF;;AC3TO,QAAM,WAAA,GACX,CACE,IAAA,KAEF,CAAC,OAAA,KAA6D;EAC5D,EAAA,MAAM,SAAS,IAAA,CAAK;EAAA,IAClB,GAAG,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA,IAUH,YAAY,IAAA,EAAM;EAChB,MAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,WAAA,GAAc,IAAI,CAAA;EAE/C,MAAA,IAAI,CAAC,YAAA,IAAgB,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,EAAG;EAC/C,QAAA,OAAO,CAAC,MAAA,KACN,IAAI,YAAY,OAAA,CAAQ,GAAA,CAAI,sBAAsB,MAAM,CAAA;EAAA,MAC5D;EAEA,MAAA,OAAO,YAAA;EAAA,IACT,CAAA;EAAA,IACA,aAAa,CAAC,IAAA,KACZ,QAAQ,GAAA,CAAI,iBAAA,CAAkB,IAAI,CAAA,CAAE,IAAA;EAAA,MAClCC,aAAA,CAAS,CAAC,OAAA,KAAY;EACpB,QAAA,IAAI,CAAC,OAAA,EAAS,OAAOf,OAAA,CAAG,MAAS,CAAA;EAEjC,QAAA,IAAI,CAAC,cAAA,CAAe,OAAO,CAAA,EAAG;EAC5B,UAAA,OAAA,CAAQ,KAAK,CAAA,mCAAA,CAAqC,CAAA;EAElD,UAAA,OAAOA,QAAG,MAAS,CAAA;EAAA,QACrB;EAGA,QAAA,MAAM,SAAA,GACJ,QAAQ,OAAA,CAAQ,SAAA;EAAA,UAAU,CAAC,IAAA,KACzB,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,KAAK,GAAG;EAAA,SAC7B,GAAI,CAAA;EAEN,QAAA,OAAOC,UAAK,OAAA,CAAQ,aAAA,CAAc,QAAQ,SAAA,GAAY,CAAC,CAAC,CAAA,CAAE,IAAA;EAAA,UACxDa,QAAA,CAAI,CAAC,SAAA,MAAe;EAAA,YAClB,MAAA,EAAQ,IAAA;EAAA,YACR,IAAA,EAAM;EAAA,WACR,CAAE;EAAA,SACJ;EAAA,MACF,CAAC;EAAA;EACH,GACH,CAAA;EAED,EAAA,OAAO,MAAA;EACT;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.umd.cjs","names":[],"sources":["../src/createArchiveFromPdf.ts","../src/renderer/frame.css?inline","../src/renderer/layout.ts","../src/renderer/PdfRenderer.ts","../src/pdfEnhancer.ts"],"sourcesContent":["import type { Archive } from \"@prose-reader/streamer\"\nimport * as pdfjsLib from \"pdfjs-dist\"\n\ntype PdfJsArchive = Archive & {\n _symbol: symbol\n proxyDocument: pdfjsLib.PDFDocumentProxy\n}\n\nconst PDF_SYMBOL = Symbol(`pdfjs`)\n\nexport const isPdfJsArchive = (archive: Archive): archive is PdfJsArchive =>\n \"_symbol\" in archive && archive._symbol === PDF_SYMBOL\n\n/**\n * @important\n * Make sure the urls are on the same origin or the cors header is set otherwise\n * the resource cannot be consumed as it is on the web.\n */\nexport const createArchiveFromPdf = async (\n file: Blob,\n filename: string,\n): Promise<Archive> => {\n const loadingTask = pdfjsLib.getDocument(await file.arrayBuffer())\n\n const pdf = await loadingTask.promise\n\n const pages = Array.from({ length: pdf.numPages })\n const pageEntries = pages.map((_, index) => ({\n id: `page-${index}`,\n resourcePath: `${index}.pdf`,\n }))\n\n const opfFileData = `\n <?xml version=\"1.0\" encoding=\"UTF-8\"?><package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"bookid\">\n <metadata>\n <meta property=\"rendition:layout\">pre-paginated</meta>\n </metadata>\n <manifest>\n ${pageEntries.map(({ id, resourcePath }) => `<item id=\"${id}\" href=\"${resourcePath}\" />`).join(`\\n`)}\n </manifest>\n <spine>\n ${pageEntries.map(({ id }) => `<itemref idref=\"${id}\" />`).join(`\\n`)}\n </spine>\n </package>\n `\n\n const opfFile: Archive[`records`][number] = {\n dir: false,\n basename: `content.opf`,\n uri: `content.opf`,\n size: 0,\n blob: async () => new Blob(),\n string: async () => opfFileData,\n }\n\n const archive = {\n filename,\n encodingFormat: \"application/pdf\",\n proxyDocument: pdf,\n _symbol: PDF_SYMBOL,\n records: [\n opfFile,\n ...pages.map((_, index) => ({\n dir: false,\n blob: async () => {\n throw new Error(\"Unable to get blob from pdf\")\n },\n basename: `${index}.pdf`,\n size: 0,\n string: () => {\n throw new Error(\"Unable to get blob from pdf\")\n },\n uri: `${index}.pdf`,\n })),\n ],\n close: () => {\n return pdf.cleanup()\n },\n } satisfies PdfJsArchive\n\n return archive as Archive\n}\n","html {\n /* Pdf are always pre-paginated so its safe to disable touch action */\n touch-action: none;\n}\n\nbody {\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n /* This will prevent scrollbar and wrong offset of annotation layer */\n overflow: hidden;\n}\n","import {\n setPropertyIfChanged,\n setStylePropertyIfChanged,\n type Viewport,\n} from \"@prose-reader/core\"\nimport type { PDFPageProxy } from \"pdfjs-dist\"\n\nexport const layoutContainer = (\n container: HTMLElement | undefined,\n spreadPosition: `none` | `left` | `right`,\n viewport: Viewport,\n) => {\n if (!container) return\n\n // first we try to get the desired viewport for a comfortable reading based on theh current page size\n const { height: pageHeight, width: pageWidth } = viewport.pageSize\n\n setStylePropertyIfChanged(container.style, `width`, `${pageWidth}px`)\n setStylePropertyIfChanged(container.style, `height`, `${pageHeight}px`)\n\n if (spreadPosition === `right`) {\n setStylePropertyIfChanged(container.style, `justify-content`, `flex-start`)\n } else if (spreadPosition === `left`) {\n setStylePropertyIfChanged(container.style, `justify-content`, `flex-end`)\n } else {\n setStylePropertyIfChanged(container.style, `justify-content`, `center`)\n }\n}\n\nexport const layoutCanvas = (\n pageProxy: PDFPageProxy,\n canvas: HTMLCanvasElement,\n readerViewport: Viewport,\n) => {\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n const { height: pageHeight, width: pageWidth } = readerViewport.pageSize\n const { width: viewportWidth, height: viewportHeight } =\n pageProxy.getViewport({ scale: 1 })\n const pageScale = Math.max(\n pageWidth / viewportWidth,\n pageHeight / viewportHeight,\n )\n\n // then we generate the viewport for the canvas based on the page scale\n const viewport = pageProxy.getViewport({ scale: pageScale })\n\n // Then we define which axis should stretch or shrink to ratio\n const viewportRatio = viewport.width / viewport.height\n const pageRatio = pageWidth / pageHeight\n const isWiderThanPage = viewportRatio > pageRatio\n const canvasWidth = isWiderThanPage ? pageWidth : pageHeight * viewportRatio\n const canvasHeight =\n viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight\n\n setPropertyIfChanged(\n canvas,\n `width`,\n Math.floor(viewport.width * pixelRatioScale),\n )\n setPropertyIfChanged(\n canvas,\n `height`,\n Math.floor(viewport.height * pixelRatioScale),\n )\n setStylePropertyIfChanged(\n canvas.style,\n `width`,\n `${Math.floor(canvasWidth)}px`,\n )\n setStylePropertyIfChanged(\n canvas.style,\n `height`,\n `${Math.floor(canvasHeight)}px`,\n )\n}\n","import {\n DocumentRenderer,\n injectCSSToFrame,\n setAttributeIfChanged,\n setStylePropertyIfChanged,\n upsertCSSToFrame,\n waitForFrameLoad,\n waitForFrameReady,\n waitForSwitch,\n} from \"@prose-reader/core\"\nimport {\n type PDFPageProxy,\n RenderingCancelledException,\n type RenderTask,\n TextLayer,\n} from \"pdfjs-dist\"\nimport {\n catchError,\n EMPTY,\n from,\n map,\n type Observable,\n of,\n switchMap,\n tap,\n} from \"rxjs\"\nimport pdfFrameStyle from \"./frame.css?inline\"\nimport { layoutCanvas, layoutContainer } from \"./layout\"\n\nconst pdfScaleStyle = `:root {\n --scale-factor: 1;\n --user-unit: 1;\n --total-scale-factor: calc(var(--scale-factor) * var(--user-unit));\n --scale-round-x: 1px;\n --scale-round-y: 1px;\n}`\n\nexport class PdfRenderer extends DocumentRenderer {\n private pageProxy: PDFPageProxy | undefined\n private renderTask: RenderTask | undefined\n private textLayer: TextLayer | undefined\n\n constructor(\n private pdfViewerStyle: string,\n params: ConstructorParameters<typeof DocumentRenderer>[0],\n ) {\n super(params)\n }\n\n private getCanvas() {\n const element = this.documentContainer?.children[0]\n\n if (!(element instanceof HTMLCanvasElement)) return\n\n return element\n }\n\n private getFrameElement() {\n const frame = this.documentContainer?.children[1]?.children[0]\n\n if (!(frame instanceof HTMLIFrameElement)) return\n\n return frame\n }\n\n private getPageProxy() {\n if (this.pageProxy) return of(this.pageProxy)\n\n return from(this.resourcesHandler.fetchResource()).pipe(\n switchMap((resource) => {\n if (!(\"custom\" in resource)) return EMPTY\n\n this.pageProxy = resource.data as PDFPageProxy\n\n return of(this.pageProxy)\n }),\n )\n }\n\n onUnload(): Observable<unknown> {\n this.detach()\n\n if (this.renderTask) {\n this.renderTask.cancel()\n }\n\n this.textLayer?.cancel()\n this.pageProxy?.cleanup()\n\n return EMPTY\n }\n\n onCreateDocument(): Observable<HTMLElement> {\n const frameElement = document.createElement(`iframe`)\n frameElement.style.cssText = `\n overflow: hidden;\n height: 100%;\n width: 100%;\n `\n\n frameElement.setAttribute(\"tabIndex\", \"0\")\n frameElement.setAttribute(\"frameBorder\", \"0\")\n frameElement.setAttribute(`src`, \"about:blank\")\n\n const frameContainer =\n this.containerElement.ownerDocument.createElement(\"div\")\n frameContainer.style.cssText = `\n mix-blend-mode: multiply;\n -webkit-transform: translateZ(0);\n transform: translateZ(0);\n position: absolute;\n height: 100%;\n width: 100%;\n top: 0;\n `\n\n /**\n * The canvas is never attached to the DOM and will be used for offscreen rendering\n * then copied into the frame.\n */\n const canvas = this.containerElement.ownerDocument.createElement(\"canvas\")\n\n frameContainer.appendChild(frameElement)\n\n const rootElement = this.containerElement.ownerDocument.createElement(`div`)\n rootElement.style.cssText = `\n display: flex;\n align-items: center;\n justify-content: center;\n `\n\n rootElement.appendChild(canvas)\n rootElement.appendChild(frameContainer)\n\n this.setDocumentContainer(rootElement)\n\n return of(rootElement)\n }\n\n onLoadDocument(): Observable<unknown> {\n return this.getPageProxy().pipe(\n switchMap(() => {\n const frameElement = this.getFrameElement()\n const pageProxy = this.pageProxy\n\n if (!frameElement || !pageProxy) return EMPTY\n\n return of(frameElement).pipe(\n waitForSwitch(this.context.bridgeEvent.viewportFree$),\n tap(() => {\n this.attach()\n }),\n waitForFrameLoad,\n switchMap(() => {\n injectCSSToFrame(\n frameElement,\n \"pdfjs-viewer-style\",\n this.pdfViewerStyle,\n )\n injectCSSToFrame(frameElement, \"enhancer-pdf-style\", pdfFrameStyle)\n upsertCSSToFrame(frameElement, \"pdf-scale-scale\", pdfScaleStyle)\n\n /**\n * We make sure to render the text layer to simulate the document being loaded.\n * It will be correctly re-layout later. Consumers looking for document load have at least\n * the actual text document ready. (cfi lookup, etc.)\n */\n const frameBody = frameElement.contentDocument?.body\n\n if (!frameBody || !this.pageProxy) return EMPTY\n\n setAttributeIfChanged(frameBody, \"class\", \"textLayer\")\n\n this.textLayer = new TextLayer({\n container: frameBody,\n textContentSource: this.pageProxy.streamTextContent(),\n viewport: this.pageProxy.getViewport({ scale: 1 }),\n })\n\n return from(this.textLayer.render())\n }),\n waitForFrameReady,\n )\n }),\n )\n }\n\n onLayout({\n spreadPosition,\n }: {\n minPageSpread: number\n blankPagePosition: `before` | `after` | `none`\n spreadPosition: `none` | `left` | `right`\n }) {\n const frameElement = this.getFrameElement()\n const canvas = this.getCanvas()\n\n if (!frameElement || !canvas) return of(undefined)\n\n // first we try to get the desired viewport for a comfortable reading based on the current page size\n const { height: pageHeight, width: pageWidth } = this.viewport.pageSize\n\n layoutContainer(this.documentContainer, spreadPosition, this.viewport)\n\n const context = canvas.getContext(\"2d\")\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n\n if (!this.pageProxy || !context) return of(undefined)\n\n if (this.renderTask) {\n this.renderTask.cancel()\n this.renderTask = undefined\n }\n\n layoutCanvas(this.pageProxy, canvas, this.viewport)\n\n const { width: viewportWidth, height: viewportHeight } =\n this.pageProxy.getViewport({ scale: 1 })\n\n const pageScale = Math.max(\n pageWidth / viewportWidth,\n pageHeight / viewportHeight,\n )\n\n // then we generate the viewport for the canvas based on the page scale\n const viewport = this.pageProxy.getViewport({ scale: pageScale })\n\n const transform =\n pixelRatioScale !== 1\n ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0]\n : null\n\n this.renderTask = this.pageProxy.render({\n ...(transform && { transform }),\n canvasContext: context,\n viewport,\n canvas,\n })\n\n return from(this.renderTask.promise).pipe(\n switchMap(() => {\n this.renderTask = undefined\n\n const frameDoc = frameElement?.contentDocument\n const pdfPage = this.pageProxy\n\n if (!frameDoc || !frameElement || !pdfPage || !this.textLayer) {\n throw new Error(\"Unable to update text layer due to missing elements\")\n }\n\n const textLayerElement = frameDoc.body\n const canvasScale = canvas.clientWidth / viewportWidth\n\n setStylePropertyIfChanged(\n textLayerElement.style,\n `top`,\n `${canvas.offsetTop}px`,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `left`,\n `${canvas.offsetLeft}px`,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `height`,\n canvas.style.height,\n )\n setStylePropertyIfChanged(\n textLayerElement.style,\n `width`,\n canvas.style.width,\n )\n\n /**\n * Taking inspiration from https://github.com/mozilla/pdf.js/blob/master/web/pdf_viewer.css.\n * Not sure why pdfjs DOES rely on css from the viewer to works. Or in another words, why is it\n * not more obvious that TextLayer requires a set of variables to work correctly.\n */\n setStylePropertyIfChanged(\n frameDoc.documentElement.style,\n `--scale-factor`,\n `${canvasScale}`,\n )\n\n this.textLayer.update({\n viewport,\n })\n\n return of(undefined)\n }),\n catchError((e) => {\n if (!(e instanceof RenderingCancelledException)) console.error(e)\n\n return of(undefined)\n }),\n )\n }\n\n /**\n * @important\n * We should keep the same node structure to preserve CFI integrity.\n */\n onRenderHeadless() {\n return this.getPageProxy().pipe(\n switchMap((pageProxy) => {\n const headlessDocument = document.implementation.createHTMLDocument()\n const textLayerElement = headlessDocument.body\n\n const textLayer = new TextLayer({\n container: textLayerElement,\n textContentSource: pageProxy.streamTextContent(),\n viewport: pageProxy.getViewport({ scale: 1 }),\n })\n\n return from(textLayer.render()).pipe(map(() => headlessDocument))\n }),\n )\n }\n\n getDocumentFrame() {\n return this.getFrameElement()\n }\n}\n","import type { createReader, Reader } from \"@prose-reader/core\"\nimport { from, map, mergeMap, of } from \"rxjs\"\nimport { isPdfJsArchive } from \"./createArchiveFromPdf\"\nimport { PdfRenderer } from \"./renderer/PdfRenderer\"\nimport type { EnhancerOptions } from \"./types\"\n\ntype CreateReader = typeof createReader\ntype CreateReaderOptions = Parameters<CreateReader>[0]\n\nexport const pdfEnhancer =\n <InheritOptions extends CreateReaderOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (options: InheritOptions & EnhancerOptions): InheritOutput => {\n const reader = next({\n ...options,\n /**\n * We have a special renderer for pdf so we need to inject it\n * for the relevant items. The enhancer could be configurable but for\n * the sake of simplicity we will assume that an item ending with .pdf should\n * be treated as a pdf document.\n *\n * The `getRenderer` hook should be non destructive, if we detect a renderer already\n * setup we should return it.\n */\n getRenderer(item) {\n const maybeFactory = options.getRenderer?.(item)\n\n if (!maybeFactory && item.href.endsWith(`.pdf`)) {\n return (params) =>\n new PdfRenderer(options.pdf.pdfjsViewerInlineCss, params)\n }\n\n return maybeFactory\n },\n getResource: (item) =>\n options.pdf.getArchiveForItem(item).pipe(\n mergeMap((archive) => {\n if (!archive) return of(undefined)\n\n if (!isPdfJsArchive(archive)) {\n console.warn(`You provided an invalid pdf archive`)\n\n return of(undefined)\n }\n\n // we account for opf file\n const fileIndex =\n archive.records.findIndex((file) =>\n item.href.endsWith(file.uri),\n ) - 1\n\n return from(archive.proxyDocument.getPage(fileIndex + 1)).pipe(\n map((pageProxy) => ({\n custom: true as const,\n data: pageProxy,\n })),\n )\n }),\n ),\n })\n\n return reader\n }\n"],"mappings":"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"}
@@ -17,10 +17,6 @@ export declare class PdfRenderer extends DocumentRenderer {
17
17
  blankPagePosition: `before` | `after` | `none`;
18
18
  spreadPosition: `none` | `left` | `right`;
19
19
  }): Observable<undefined>;
20
- /**
21
- * @important
22
- * We should keep the same node structure to preserve CFI integrity.
23
- */
24
20
  onRenderHeadless(): Observable<Document>;
25
21
  getDocumentFrame(): HTMLIFrameElement | undefined;
26
22
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prose-reader/enhancer-pdf",
3
- "version": "1.303.0",
3
+ "version": "1.305.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.umd.cjs",
6
6
  "module": "./dist/index.js",
@@ -26,5 +26,5 @@
26
26
  "pdfjs-dist": "5.x",
27
27
  "rxjs": "*"
28
28
  },
29
- "gitHead": "dddc06869ba852fa280e050c1c1929433bb91c5e"
29
+ "gitHead": "9c94c0d55718d2054c2f12702d05464a361c717f"
30
30
  }