@prose-reader/enhancer-pdf 1.301.0 → 1.304.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,369 +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
- proxyDocument: pdf,
42
- _symbol: PDF_SYMBOL,
43
- records: [
44
- opfFile,
45
- ...pages.map((_, index) => ({
46
- dir: false,
47
- blob: async () => {
48
- throw new Error("Unable to get blob from pdf");
49
- },
50
- basename: `${index}.pdf`,
51
- size: 0,
52
- string: () => {
53
- throw new Error("Unable to get blob from pdf");
54
- },
55
- uri: `${index}.pdf`
56
- }))
57
- ],
58
- close: () => {
59
- return pdf.cleanup();
60
- }
61
- };
62
- return archive;
63
- };
64
-
65
- 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";
66
-
67
- const layoutContainer = (container, spreadPosition, viewport) => {
68
- if (!container) return;
69
- const { height: pageHeight, width: pageWidth } = viewport.pageSize;
70
- setStylePropertyIfChanged(container.style, `width`, `${pageWidth}px`);
71
- setStylePropertyIfChanged(container.style, `height`, `${pageHeight}px`);
72
- if (spreadPosition === `right`) {
73
- setStylePropertyIfChanged(container.style, `justify-content`, `flex-start`);
74
- } else if (spreadPosition === `left`) {
75
- setStylePropertyIfChanged(container.style, `justify-content`, `flex-end`);
76
- } else {
77
- setStylePropertyIfChanged(container.style, `justify-content`, `center`);
78
- }
79
- };
80
- const layoutCanvas = (pageProxy, canvas, readerViewport) => {
81
- const pixelRatioScale = window.devicePixelRatio || 1;
82
- const { height: pageHeight, width: pageWidth } = readerViewport.pageSize;
83
- const { width: viewportWidth, height: viewportHeight } = pageProxy.getViewport({ scale: 1 });
84
- const pageScale = Math.max(
85
- pageWidth / viewportWidth,
86
- pageHeight / viewportHeight
87
- );
88
- const viewport = pageProxy.getViewport({ scale: pageScale });
89
- const viewportRatio = viewport.width / viewport.height;
90
- const pageRatio = pageWidth / pageHeight;
91
- const isWiderThanPage = viewportRatio > pageRatio;
92
- const canvasWidth = isWiderThanPage ? pageWidth : pageHeight * viewportRatio;
93
- const canvasHeight = viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight;
94
- setPropertyIfChanged(
95
- canvas,
96
- `width`,
97
- Math.floor(viewport.width * pixelRatioScale)
98
- );
99
- setPropertyIfChanged(
100
- canvas,
101
- `height`,
102
- Math.floor(viewport.height * pixelRatioScale)
103
- );
104
- setStylePropertyIfChanged(
105
- canvas.style,
106
- `width`,
107
- `${Math.floor(canvasWidth)}px`
108
- );
109
- setStylePropertyIfChanged(
110
- canvas.style,
111
- `height`,
112
- `${Math.floor(canvasHeight)}px`
113
- );
114
- };
115
-
116
- const pdfScaleStyle = `:root {
117
- --scale-factor: 1;
118
- --user-unit: 1;
119
- --total-scale-factor: calc(var(--scale-factor) * var(--user-unit));
120
- --scale-round-x: 1px;
121
- --scale-round-y: 1px;
122
- }`;
123
- class PdfRenderer extends DocumentRenderer {
124
- constructor(pdfViewerStyle, params) {
125
- super(params);
126
- this.pdfViewerStyle = pdfViewerStyle;
127
- }
128
- pdfViewerStyle;
129
- pageProxy;
130
- renderTask;
131
- textLayer;
132
- getCanvas() {
133
- const element = this.documentContainer?.children[0];
134
- if (!(element instanceof HTMLCanvasElement)) return;
135
- return element;
136
- }
137
- getFrameElement() {
138
- const frame = this.documentContainer?.children[1].children[0];
139
- if (!(frame instanceof HTMLIFrameElement)) return;
140
- return frame;
141
- }
142
- getPageProxy() {
143
- if (this.pageProxy) return of(this.pageProxy);
144
- return from(this.resourcesHandler.fetchResource()).pipe(
145
- switchMap((resource) => {
146
- if (!("custom" in resource)) return EMPTY;
147
- this.pageProxy = resource.data;
148
- return of(this.pageProxy);
149
- })
150
- );
151
- }
152
- onUnload() {
153
- this.detach();
154
- if (this.renderTask) {
155
- this.renderTask.cancel();
156
- }
157
- this.textLayer?.cancel();
158
- this.pageProxy?.cleanup();
159
- return EMPTY;
160
- }
161
- onCreateDocument() {
162
- const frameElement = document.createElement(`iframe`);
163
- frameElement.style.cssText = `
164
- overflow: hidden;
165
- height: 100%;
166
- width: 100%;
167
- `;
168
- frameElement.setAttribute("tabIndex", "0");
169
- frameElement.setAttribute("frameBorder", "0");
170
- frameElement.setAttribute(`src`, "about:blank");
171
- const frameContainer = this.containerElement.ownerDocument.createElement("div");
172
- frameContainer.style.cssText = `
173
- mix-blend-mode: multiply;
174
- -webkit-transform: translateZ(0);
175
- transform: translateZ(0);
176
- position: absolute;
177
- height: 100%;
178
- width: 100%;
179
- top: 0;
180
- `;
181
- const canvas = this.containerElement.ownerDocument.createElement("canvas");
182
- frameContainer.appendChild(frameElement);
183
- const rootElement = this.containerElement.ownerDocument.createElement(`div`);
184
- rootElement.style.cssText = `
185
- display: flex;
186
- align-items: center;
187
- justify-content: center;
188
- `;
189
- rootElement.appendChild(canvas);
190
- rootElement.appendChild(frameContainer);
191
- this.setDocumentContainer(rootElement);
192
- return of(rootElement);
193
- }
194
- onLoadDocument() {
195
- return this.getPageProxy().pipe(
196
- switchMap(() => {
197
- const frameElement = this.getFrameElement();
198
- const pageProxy = this.pageProxy;
199
- if (!frameElement || !pageProxy) return EMPTY;
200
- return of(frameElement).pipe(
201
- waitForSwitch(this.context.bridgeEvent.viewportFree$),
202
- tap(() => {
203
- this.attach();
204
- }),
205
- waitForFrameLoad,
206
- switchMap(() => {
207
- injectCSSToFrame(
208
- frameElement,
209
- "pdfjs-viewer-style",
210
- this.pdfViewerStyle
211
- );
212
- injectCSSToFrame(frameElement, "enhancer-pdf-style", pdfFrameStyle);
213
- upsertCSSToFrame(frameElement, "pdf-scale-scale", pdfScaleStyle);
214
- const frameBody = frameElement.contentDocument?.body;
215
- if (!frameBody || !this.pageProxy) return EMPTY;
216
- setAttributeIfChanged(frameBody, "class", "textLayer");
217
- this.textLayer = new TextLayer({
218
- container: frameBody,
219
- textContentSource: this.pageProxy.streamTextContent(),
220
- viewport: this.pageProxy.getViewport({ scale: 1 })
221
- });
222
- return from(this.textLayer.render());
223
- }),
224
- waitForFrameReady
225
- );
226
- })
227
- );
228
- }
229
- onLayout({
230
- spreadPosition
231
- }) {
232
- const frameElement = this.getFrameElement();
233
- const canvas = this.getCanvas();
234
- if (!frameElement || !canvas) return of(void 0);
235
- const { height: pageHeight, width: pageWidth } = this.viewport.pageSize;
236
- layoutContainer(this.documentContainer, spreadPosition, this.viewport);
237
- const context = canvas.getContext("2d");
238
- const pixelRatioScale = window.devicePixelRatio || 1;
239
- if (!this.pageProxy || !context) return of(void 0);
240
- if (this.renderTask) {
241
- this.renderTask.cancel();
242
- this.renderTask = void 0;
243
- }
244
- layoutCanvas(this.pageProxy, canvas, this.viewport);
245
- const { width: viewportWidth, height: viewportHeight } = this.pageProxy.getViewport({ scale: 1 });
246
- const pageScale = Math.max(
247
- pageWidth / viewportWidth,
248
- pageHeight / viewportHeight
249
- );
250
- const viewport = this.pageProxy.getViewport({ scale: pageScale });
251
- const transform = pixelRatioScale !== 1 ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0] : null;
252
- this.renderTask = this.pageProxy.render({
253
- ...transform && { transform },
254
- canvasContext: context,
255
- viewport,
256
- canvas
257
- });
258
- return from(this.renderTask.promise).pipe(
259
- switchMap(() => {
260
- this.renderTask = void 0;
261
- const frameDoc = frameElement?.contentDocument;
262
- const pdfPage = this.pageProxy;
263
- if (!frameDoc || !frameElement || !pdfPage || !this.textLayer) {
264
- throw new Error("Unable to update text layer due to missing elements");
265
- }
266
- const textLayerElement = frameDoc.body;
267
- const canvasScale = canvas.clientWidth / viewportWidth;
268
- setStylePropertyIfChanged(
269
- textLayerElement.style,
270
- `top`,
271
- `${canvas.offsetTop}px`
272
- );
273
- setStylePropertyIfChanged(
274
- textLayerElement.style,
275
- `left`,
276
- `${canvas.offsetLeft}px`
277
- );
278
- setStylePropertyIfChanged(
279
- textLayerElement.style,
280
- `height`,
281
- canvas.style.height
282
- );
283
- setStylePropertyIfChanged(
284
- textLayerElement.style,
285
- `width`,
286
- canvas.style.width
287
- );
288
- setStylePropertyIfChanged(
289
- frameDoc.documentElement.style,
290
- `--scale-factor`,
291
- `${canvasScale}`
292
- );
293
- this.textLayer.update({
294
- viewport
295
- });
296
- return of(void 0);
297
- }),
298
- catchError((e) => {
299
- if (!(e instanceof RenderingCancelledException)) console.error(e);
300
- return of(void 0);
301
- })
302
- );
303
- }
304
- /**
305
- * @important
306
- * We should keep the same node structure to preserve CFI integrity.
307
- */
308
- onRenderHeadless() {
309
- return this.getPageProxy().pipe(
310
- switchMap((pageProxy) => {
311
- const headlessDocument = document.implementation.createHTMLDocument();
312
- const textLayerElement = headlessDocument.body;
313
- const textLayer = new TextLayer({
314
- container: textLayerElement,
315
- textContentSource: pageProxy.streamTextContent(),
316
- viewport: pageProxy.getViewport({ scale: 1 })
317
- });
318
- return from(textLayer.render()).pipe(map(() => headlessDocument));
319
- })
320
- );
321
- }
322
- getDocumentFrame() {
323
- return this.getFrameElement();
324
- }
325
- }
326
-
327
- const pdfEnhancer = (next) => (options) => {
328
- const reader = next({
329
- ...options,
330
- /**
331
- * We have a special renderer for pdf so we need to inject it
332
- * for the relevant items. The enhancer could be configurable but for
333
- * the sake of simplicity we will assume that an item ending with .pdf should
334
- * be treated as a pdf document.
335
- *
336
- * The `getRenderer` hook should be non destructive, if we detect a renderer already
337
- * setup we should return it.
338
- */
339
- getRenderer(item) {
340
- const maybeFactory = options.getRenderer?.(item);
341
- if (!maybeFactory && item.href.endsWith(`.pdf`)) {
342
- return (params) => new PdfRenderer(options.pdf.pdfjsViewerInlineCss, params);
343
- }
344
- return maybeFactory;
345
- },
346
- getResource: (item) => options.pdf.getArchiveForItem(item).pipe(
347
- mergeMap((archive) => {
348
- if (!archive) return of(void 0);
349
- if (!isPdfJsArchive(archive)) {
350
- console.warn(`You provided an invalid pdf archive`);
351
- return of(void 0);
352
- }
353
- const fileIndex = archive.records.findIndex(
354
- (file) => item.href.endsWith(file.uri)
355
- ) - 1;
356
- return from(archive.proxyDocument.getPage(fileIndex + 1)).pipe(
357
- map((pageProxy) => ({
358
- custom: true,
359
- data: pageProxy
360
- }))
361
- );
362
- })
363
- )
364
- });
365
- return reader;
366
- };
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 };
367
164
 
368
- export { createArchiveFromPdf, isPdfJsArchive, pdfEnhancer };
369
- //# 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 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,195 +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
- proxyDocument: pdf,
62
- _symbol: PDF_SYMBOL,
63
- records: [
64
- opfFile,
65
- ...pages.map((_, index) => ({
66
- dir: false,
67
- blob: async () => {
68
- throw new Error("Unable to get blob from pdf");
69
- },
70
- basename: `${index}.pdf`,
71
- size: 0,
72
- string: () => {
73
- throw new Error("Unable to get blob from pdf");
74
- },
75
- uri: `${index}.pdf`
76
- }))
77
- ],
78
- close: () => {
79
- return pdf.cleanup();
80
- }
81
- };
82
- return archive;
83
- };
84
-
85
- 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";
86
-
87
- const layoutContainer = (container, spreadPosition, viewport) => {
88
- if (!container) return;
89
- const { height: pageHeight, width: pageWidth } = viewport.pageSize;
90
- core.setStylePropertyIfChanged(container.style, `width`, `${pageWidth}px`);
91
- core.setStylePropertyIfChanged(container.style, `height`, `${pageHeight}px`);
92
- if (spreadPosition === `right`) {
93
- core.setStylePropertyIfChanged(container.style, `justify-content`, `flex-start`);
94
- } else if (spreadPosition === `left`) {
95
- core.setStylePropertyIfChanged(container.style, `justify-content`, `flex-end`);
96
- } else {
97
- core.setStylePropertyIfChanged(container.style, `justify-content`, `center`);
98
- }
99
- };
100
- const layoutCanvas = (pageProxy, canvas, readerViewport) => {
101
- const pixelRatioScale = window.devicePixelRatio || 1;
102
- const { height: pageHeight, width: pageWidth } = readerViewport.pageSize;
103
- const { width: viewportWidth, height: viewportHeight } = pageProxy.getViewport({ scale: 1 });
104
- const pageScale = Math.max(
105
- pageWidth / viewportWidth,
106
- pageHeight / viewportHeight
107
- );
108
- const viewport = pageProxy.getViewport({ scale: pageScale });
109
- const viewportRatio = viewport.width / viewport.height;
110
- const pageRatio = pageWidth / pageHeight;
111
- const isWiderThanPage = viewportRatio > pageRatio;
112
- const canvasWidth = isWiderThanPage ? pageWidth : pageHeight * viewportRatio;
113
- const canvasHeight = viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight;
114
- core.setPropertyIfChanged(
115
- canvas,
116
- `width`,
117
- Math.floor(viewport.width * pixelRatioScale)
118
- );
119
- core.setPropertyIfChanged(
120
- canvas,
121
- `height`,
122
- Math.floor(viewport.height * pixelRatioScale)
123
- );
124
- core.setStylePropertyIfChanged(
125
- canvas.style,
126
- `width`,
127
- `${Math.floor(canvasWidth)}px`
128
- );
129
- core.setStylePropertyIfChanged(
130
- canvas.style,
131
- `height`,
132
- `${Math.floor(canvasHeight)}px`
133
- );
134
- };
135
-
136
- 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 {
137
16
  --scale-factor: 1;
138
17
  --user-unit: 1;
139
18
  --total-scale-factor: calc(var(--scale-factor) * var(--user-unit));
140
19
  --scale-round-x: 1px;
141
20
  --scale-round-y: 1px;
142
- }`;
143
- class PdfRenderer extends core.DocumentRenderer {
144
- constructor(pdfViewerStyle, params) {
145
- super(params);
146
- this.pdfViewerStyle = pdfViewerStyle;
147
- }
148
- pdfViewerStyle;
149
- pageProxy;
150
- renderTask;
151
- textLayer;
152
- getCanvas() {
153
- const element = this.documentContainer?.children[0];
154
- if (!(element instanceof HTMLCanvasElement)) return;
155
- return element;
156
- }
157
- getFrameElement() {
158
- const frame = this.documentContainer?.children[1].children[0];
159
- if (!(frame instanceof HTMLIFrameElement)) return;
160
- return frame;
161
- }
162
- getPageProxy() {
163
- if (this.pageProxy) return rxjs.of(this.pageProxy);
164
- return rxjs.from(this.resourcesHandler.fetchResource()).pipe(
165
- rxjs.switchMap((resource) => {
166
- if (!("custom" in resource)) return rxjs.EMPTY;
167
- this.pageProxy = resource.data;
168
- return rxjs.of(this.pageProxy);
169
- })
170
- );
171
- }
172
- onUnload() {
173
- this.detach();
174
- if (this.renderTask) {
175
- this.renderTask.cancel();
176
- }
177
- this.textLayer?.cancel();
178
- this.pageProxy?.cleanup();
179
- return rxjs.EMPTY;
180
- }
181
- onCreateDocument() {
182
- const frameElement = document.createElement(`iframe`);
183
- 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=`
184
22
  overflow: hidden;
185
23
  height: 100%;
186
24
  width: 100%;
187
- `;
188
- frameElement.setAttribute("tabIndex", "0");
189
- frameElement.setAttribute("frameBorder", "0");
190
- frameElement.setAttribute(`src`, "about:blank");
191
- const frameContainer = this.containerElement.ownerDocument.createElement("div");
192
- 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=`
193
26
  mix-blend-mode: multiply;
194
27
  -webkit-transform: translateZ(0);
195
28
  transform: translateZ(0);
@@ -197,199 +30,9 @@
197
30
  height: 100%;
198
31
  width: 100%;
199
32
  top: 0;
200
- `;
201
- const canvas = this.containerElement.ownerDocument.createElement("canvas");
202
- frameContainer.appendChild(frameElement);
203
- const rootElement = this.containerElement.ownerDocument.createElement(`div`);
204
- 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=`
205
34
  display: flex;
206
35
  align-items: center;
207
36
  justify-content: center;
208
- `;
209
- rootElement.appendChild(canvas);
210
- rootElement.appendChild(frameContainer);
211
- this.setDocumentContainer(rootElement);
212
- return rxjs.of(rootElement);
213
- }
214
- onLoadDocument() {
215
- return this.getPageProxy().pipe(
216
- rxjs.switchMap(() => {
217
- const frameElement = this.getFrameElement();
218
- const pageProxy = this.pageProxy;
219
- if (!frameElement || !pageProxy) return rxjs.EMPTY;
220
- return rxjs.of(frameElement).pipe(
221
- core.waitForSwitch(this.context.bridgeEvent.viewportFree$),
222
- rxjs.tap(() => {
223
- this.attach();
224
- }),
225
- core.waitForFrameLoad,
226
- rxjs.switchMap(() => {
227
- core.injectCSSToFrame(
228
- frameElement,
229
- "pdfjs-viewer-style",
230
- this.pdfViewerStyle
231
- );
232
- core.injectCSSToFrame(frameElement, "enhancer-pdf-style", pdfFrameStyle);
233
- core.upsertCSSToFrame(frameElement, "pdf-scale-scale", pdfScaleStyle);
234
- const frameBody = frameElement.contentDocument?.body;
235
- if (!frameBody || !this.pageProxy) return rxjs.EMPTY;
236
- core.setAttributeIfChanged(frameBody, "class", "textLayer");
237
- this.textLayer = new pdfjsLib.TextLayer({
238
- container: frameBody,
239
- textContentSource: this.pageProxy.streamTextContent(),
240
- viewport: this.pageProxy.getViewport({ scale: 1 })
241
- });
242
- return rxjs.from(this.textLayer.render());
243
- }),
244
- core.waitForFrameReady
245
- );
246
- })
247
- );
248
- }
249
- onLayout({
250
- spreadPosition
251
- }) {
252
- const frameElement = this.getFrameElement();
253
- const canvas = this.getCanvas();
254
- if (!frameElement || !canvas) return rxjs.of(void 0);
255
- const { height: pageHeight, width: pageWidth } = this.viewport.pageSize;
256
- layoutContainer(this.documentContainer, spreadPosition, this.viewport);
257
- const context = canvas.getContext("2d");
258
- const pixelRatioScale = window.devicePixelRatio || 1;
259
- if (!this.pageProxy || !context) return rxjs.of(void 0);
260
- if (this.renderTask) {
261
- this.renderTask.cancel();
262
- this.renderTask = void 0;
263
- }
264
- layoutCanvas(this.pageProxy, canvas, this.viewport);
265
- const { width: viewportWidth, height: viewportHeight } = this.pageProxy.getViewport({ scale: 1 });
266
- const pageScale = Math.max(
267
- pageWidth / viewportWidth,
268
- pageHeight / viewportHeight
269
- );
270
- const viewport = this.pageProxy.getViewport({ scale: pageScale });
271
- const transform = pixelRatioScale !== 1 ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0] : null;
272
- this.renderTask = this.pageProxy.render({
273
- ...transform && { transform },
274
- canvasContext: context,
275
- viewport,
276
- canvas
277
- });
278
- return rxjs.from(this.renderTask.promise).pipe(
279
- rxjs.switchMap(() => {
280
- this.renderTask = void 0;
281
- const frameDoc = frameElement?.contentDocument;
282
- const pdfPage = this.pageProxy;
283
- if (!frameDoc || !frameElement || !pdfPage || !this.textLayer) {
284
- throw new Error("Unable to update text layer due to missing elements");
285
- }
286
- const textLayerElement = frameDoc.body;
287
- const canvasScale = canvas.clientWidth / viewportWidth;
288
- core.setStylePropertyIfChanged(
289
- textLayerElement.style,
290
- `top`,
291
- `${canvas.offsetTop}px`
292
- );
293
- core.setStylePropertyIfChanged(
294
- textLayerElement.style,
295
- `left`,
296
- `${canvas.offsetLeft}px`
297
- );
298
- core.setStylePropertyIfChanged(
299
- textLayerElement.style,
300
- `height`,
301
- canvas.style.height
302
- );
303
- core.setStylePropertyIfChanged(
304
- textLayerElement.style,
305
- `width`,
306
- canvas.style.width
307
- );
308
- core.setStylePropertyIfChanged(
309
- frameDoc.documentElement.style,
310
- `--scale-factor`,
311
- `${canvasScale}`
312
- );
313
- this.textLayer.update({
314
- viewport
315
- });
316
- return rxjs.of(void 0);
317
- }),
318
- rxjs.catchError((e) => {
319
- if (!(e instanceof pdfjsLib.RenderingCancelledException)) console.error(e);
320
- return rxjs.of(void 0);
321
- })
322
- );
323
- }
324
- /**
325
- * @important
326
- * We should keep the same node structure to preserve CFI integrity.
327
- */
328
- onRenderHeadless() {
329
- return this.getPageProxy().pipe(
330
- rxjs.switchMap((pageProxy) => {
331
- const headlessDocument = document.implementation.createHTMLDocument();
332
- const textLayerElement = headlessDocument.body;
333
- const textLayer = new pdfjsLib.TextLayer({
334
- container: textLayerElement,
335
- textContentSource: pageProxy.streamTextContent(),
336
- viewport: pageProxy.getViewport({ scale: 1 })
337
- });
338
- return rxjs.from(textLayer.render()).pipe(rxjs.map(() => headlessDocument));
339
- })
340
- );
341
- }
342
- getDocumentFrame() {
343
- return this.getFrameElement();
344
- }
345
- }
346
-
347
- const pdfEnhancer = (next) => (options) => {
348
- const reader = next({
349
- ...options,
350
- /**
351
- * We have a special renderer for pdf so we need to inject it
352
- * for the relevant items. The enhancer could be configurable but for
353
- * the sake of simplicity we will assume that an item ending with .pdf should
354
- * be treated as a pdf document.
355
- *
356
- * The `getRenderer` hook should be non destructive, if we detect a renderer already
357
- * setup we should return it.
358
- */
359
- getRenderer(item) {
360
- const maybeFactory = options.getRenderer?.(item);
361
- if (!maybeFactory && item.href.endsWith(`.pdf`)) {
362
- return (params) => new PdfRenderer(options.pdf.pdfjsViewerInlineCss, params);
363
- }
364
- return maybeFactory;
365
- },
366
- getResource: (item) => options.pdf.getArchiveForItem(item).pipe(
367
- rxjs.mergeMap((archive) => {
368
- if (!archive) return rxjs.of(void 0);
369
- if (!isPdfJsArchive(archive)) {
370
- console.warn(`You provided an invalid pdf archive`);
371
- return rxjs.of(void 0);
372
- }
373
- const fileIndex = archive.records.findIndex(
374
- (file) => item.href.endsWith(file.uri)
375
- ) - 1;
376
- return rxjs.from(archive.proxyDocument.getPage(fileIndex + 1)).pipe(
377
- rxjs.map((pageProxy) => ({
378
- custom: true,
379
- data: pageProxy
380
- }))
381
- );
382
- })
383
- )
384
- });
385
- return reader;
386
- };
387
-
388
- exports.createArchiveFromPdf = createArchiveFromPdf;
389
- exports.isPdfJsArchive = isPdfJsArchive;
390
- exports.pdfEnhancer = pdfEnhancer;
391
-
392
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
393
-
394
- }));
395
- //# 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 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,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;;;;ECzEO,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.301.0",
3
+ "version": "1.304.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": "c8e649c793f0b56c63d9fe3d50d5b5cef4fcbf23"
29
+ "gitHead": "1f4e4822d4d74fc2f6025409133db0f4f7f152af"
30
30
  }