@prose-reader/enhancer-pdf 1.124.0 → 1.126.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.
package/dist/index.js CHANGED
@@ -1,38 +1,70 @@
1
- import { EMPTY, from, switchMap, mergeMap, of, map } from 'rxjs';
1
+ import { EMPTY, from, switchMap, of, tap, mergeMap, map } from 'rxjs';
2
2
  import * as pdfjsLib from 'pdfjs-dist';
3
- import { RenderingCancelledException } from 'pdfjs-dist';
4
- import { DocumentRenderer } from '@prose-reader/core';
3
+ import { TextLayer, RenderingCancelledException } from 'pdfjs-dist';
4
+ import { DocumentRenderer, waitForSwitch, injectCSS, waitForFrameReady, removeCSS } from '@prose-reader/core';
5
+
6
+ const createPdfFrameElement = () => {
7
+ const frame = document.createElement(`iframe`);
8
+ frame.tabIndex = 0;
9
+ frame.style.cssText = `
10
+ overflow: hidden;
11
+ height: 100%;
12
+ width: 100%;
13
+ padding: 0px;
14
+ position: absolute;
15
+ left: 0;
16
+ top: 0;
17
+ `;
18
+ frame.setAttribute("frameBorder", "0");
19
+ return frame;
20
+ };
21
+ const copyCanvasToFrame = (canvas, frameDoc) => {
22
+ const iframeCanvas = frameDoc.createElement("canvas");
23
+ iframeCanvas.width = canvas.width;
24
+ iframeCanvas.height = canvas.height;
25
+ iframeCanvas.style.width = canvas.style.width;
26
+ iframeCanvas.style.height = canvas.style.height;
27
+ const ctx = iframeCanvas.getContext("2d");
28
+ if (ctx) {
29
+ ctx.drawImage(canvas, 0, 0);
30
+ }
31
+ frameDoc.body.appendChild(iframeCanvas);
32
+ return iframeCanvas;
33
+ };
34
+
35
+ const pdfFrameStyle = ".textLayer {\n position: absolute;\n width: 100%;\n height: 100%;\n color: black;\n overflow: hidden;\n line-height: 1;\n}\n\nbody {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n margin: 0;\n padding: 0;\n}\n";
5
36
 
6
37
  class PdfRenderer extends DocumentRenderer {
38
+ constructor(pdfViewerStyle, params) {
39
+ super(params);
40
+ this.pdfViewerStyle = pdfViewerStyle;
41
+ }
7
42
  pageProxy;
8
43
  renderTask;
9
- getCanvas() {
10
- const element = this.layers[0]?.element.children[0];
11
- if (element instanceof HTMLCanvasElement) return element;
12
- return void 0;
44
+ textLayer;
45
+ getFrameElement() {
46
+ const frame = this.layers[0]?.element;
47
+ if (!(frame instanceof HTMLIFrameElement)) return;
48
+ return frame;
13
49
  }
14
50
  onUnload() {
15
51
  this.layers.forEach(({ element }) => {
16
52
  element.remove();
17
53
  });
18
54
  this.layers = [];
55
+ if (this.renderTask) {
56
+ this.renderTask.cancel();
57
+ }
58
+ this.textLayer?.cancel();
19
59
  this.pageProxy?.cleanup();
20
60
  return EMPTY;
21
61
  }
22
62
  onCreateDocument() {
23
- const canvasContainer = this.containerElement.ownerDocument.createElement(`div`);
24
- canvasContainer.style.cssText = `
25
- width: 100%;
26
- height: 100%;
27
- display: flex;
28
- justify-content: center;
29
- align-items: center;
30
- `;
31
- const canvas = this.containerElement.ownerDocument.createElement(`canvas`);
32
- canvasContainer.appendChild(canvas);
63
+ const frameElement = createPdfFrameElement();
64
+ frameElement.setAttribute(`src`, "about:blank");
33
65
  this.layers = [
34
66
  {
35
- element: canvasContainer
67
+ element: frameElement
36
68
  }
37
69
  ];
38
70
  return EMPTY;
@@ -43,20 +75,35 @@ class PdfRenderer extends DocumentRenderer {
43
75
  if (!("custom" in resource)) return EMPTY;
44
76
  const pageProxy = resource.data;
45
77
  this.pageProxy = pageProxy;
46
- const container = this.layers[0]?.element;
47
- if (container) {
48
- this.containerElement.appendChild(container);
49
- }
50
- return EMPTY;
78
+ const frameElement = this.getFrameElement();
79
+ if (!frameElement) return EMPTY;
80
+ return of(frameElement).pipe(
81
+ waitForSwitch(this.context.bridgeEvent.viewportFree$),
82
+ tap(() => {
83
+ this.containerElement.appendChild(frameElement);
84
+ injectCSS(frameElement, "pdfjs-viewer-style", this.pdfViewerStyle);
85
+ injectCSS(frameElement, "enhancer-pdf-style", pdfFrameStyle);
86
+ const body = frameElement?.contentDocument?.body;
87
+ if (body) {
88
+ const canvas = body.ownerDocument.createElement(`canvas`);
89
+ body.appendChild(canvas);
90
+ }
91
+ }),
92
+ waitForFrameReady
93
+ );
51
94
  })
52
95
  );
53
96
  }
54
97
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
55
98
  layout(_) {
56
- const canvas = this.getCanvas();
99
+ const canvas = this.containerElement.ownerDocument.createElement("canvas");
57
100
  const context = canvas?.getContext("2d");
58
101
  const pixelRatioScale = window.devicePixelRatio || 1;
59
- if (!canvas || !this.pageProxy || !context) return void 0;
102
+ if (!this.pageProxy || !context) return void 0;
103
+ if (this.renderTask) {
104
+ this.renderTask.cancel();
105
+ this.renderTask = void 0;
106
+ }
60
107
  const { height: pageHeight, width: pageWidth } = this.context.getPageSize();
61
108
  const { width: viewportWidth, height: viewportHeight } = this.pageProxy.getViewport({ scale: 1 });
62
109
  const pageScale = Math.max(pageWidth / viewportWidth, pageHeight / viewportHeight);
@@ -70,19 +117,44 @@ class PdfRenderer extends DocumentRenderer {
70
117
  canvas.height = Math.floor(viewport.height * pixelRatioScale);
71
118
  canvas.style.width = Math.floor(canvasWidth) + "px";
72
119
  canvas.style.height = Math.floor(canvasHeight) + "px";
73
- if (this.renderTask) {
74
- this.renderTask.cancel();
75
- }
76
120
  const transform = pixelRatioScale !== 1 ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0] : null;
77
121
  this.renderTask = this.pageProxy?.render({
78
122
  ...transform && { transform },
79
123
  canvasContext: context,
80
124
  viewport
81
125
  });
82
- this.renderTask?.promise.catch((e) => {
126
+ this.renderTask?.promise.then(() => {
127
+ const frameElement = this.getFrameElement();
128
+ const frameDoc = frameElement?.contentDocument;
129
+ if (!frameDoc || !frameElement) {
130
+ return;
131
+ }
132
+ frameDoc.body.innerHTML = ``;
133
+ const frameCanvas = copyCanvasToFrame(canvas, frameDoc);
134
+ const pdfPage = this.pageProxy;
135
+ if (!pdfPage) return;
136
+ const textLayerElement = frameDoc.createElement(`div`);
137
+ textLayerElement.setAttribute("class", "textLayer");
138
+ frameDoc.body.appendChild(textLayerElement);
139
+ const canvasScale = canvasWidth / viewportWidth;
140
+ textLayerElement.style.top = frameCanvas.offsetTop + "px";
141
+ textLayerElement.style.left = frameCanvas.offsetLeft + "px";
142
+ removeCSS(frameElement, "pdf-scale-scale");
143
+ injectCSS(frameElement, "pdf-scale-scale", `:root { --scale-factor: ${canvasScale}; }`);
144
+ if (this.textLayer) {
145
+ this.textLayer.cancel();
146
+ }
147
+ this.textLayer = new TextLayer({
148
+ container: textLayerElement,
149
+ textContentSource: pdfPage.streamTextContent(),
150
+ viewport
151
+ });
152
+ this.textLayer.render();
153
+ }).catch((e) => {
83
154
  if (!(e instanceof RenderingCancelledException)) console.error(e);
84
155
  }).finally(() => {
85
156
  this.renderTask = void 0;
157
+ canvas.remove();
86
158
  });
87
159
  return void 0;
88
160
  }
@@ -129,11 +201,11 @@ const pdfEnhancer = (next) => (options) => {
129
201
  * setup we should return it.
130
202
  */
131
203
  getRenderer(item) {
132
- const MaybeRenderer = options.getRenderer?.(item);
133
- if (!MaybeRenderer && item.href.endsWith(`.pdf`)) {
134
- return PdfRenderer;
204
+ const maybeFactory = options.getRenderer?.(item);
205
+ if (!maybeFactory && item.href.endsWith(`.pdf`)) {
206
+ return (params) => new PdfRenderer(options.pdf.pdfjsViewerInlineCss, params);
135
207
  }
136
- return MaybeRenderer;
208
+ return maybeFactory;
137
209
  },
138
210
  getResource: (item) => options.pdf.getArchiveForItem(item).pipe(
139
211
  mergeMap((archive) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/PdfRenderer.ts","../src/createArchiveFromPdf.ts","../src/pdfEnhancer.ts"],"sourcesContent":["import { EMPTY, from, Observable, switchMap } from \"rxjs\"\nimport { PDFPageProxy, RenderingCancelledException, RenderTask } from \"pdfjs-dist\"\nimport { DocumentRenderer } from \"@prose-reader/core\"\n\nexport class PdfRenderer extends DocumentRenderer {\n private pageProxy: PDFPageProxy | undefined\n private renderTask: RenderTask | undefined\n\n getCanvas() {\n const element = this.layers[0]?.element.children[0]\n\n if (element instanceof HTMLCanvasElement) return element\n\n return undefined\n }\n\n onUnload(): Observable<unknown> {\n this.layers.forEach(({ element }) => {\n element.remove()\n })\n\n this.layers = []\n\n this.pageProxy?.cleanup()\n\n return EMPTY\n }\n\n onCreateDocument(): Observable<unknown> {\n const canvasContainer = this.containerElement.ownerDocument.createElement(`div`)\n canvasContainer.style.cssText = `\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n `\n\n const canvas = this.containerElement.ownerDocument.createElement(`canvas`)\n\n canvasContainer.appendChild(canvas)\n\n this.layers = [\n {\n element: canvasContainer,\n },\n ]\n\n return EMPTY\n }\n\n onLoadDocument(): Observable<unknown> {\n return from(this.resourcesHandler.fetchResource()).pipe(\n switchMap((resource) => {\n if (!(\"custom\" in resource)) return EMPTY\n\n const pageProxy = resource.data as PDFPageProxy\n\n this.pageProxy = pageProxy\n\n const container = this.layers[0]?.element\n\n if (container) {\n this.containerElement.appendChild(container)\n }\n\n return EMPTY\n }),\n )\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n layout(_: {\n minPageSpread: number\n blankPagePosition: `before` | `after` | `none`\n spreadPosition: `none` | `left` | `right`\n }): { width: number; height: number } | undefined {\n const canvas = this.getCanvas()\n const context = canvas?.getContext(\"2d\")\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n\n if (!canvas || !this.pageProxy || !context) return undefined\n\n // first we try to get the desired viewport for a confortable reading based on theh current page size\n const { height: pageHeight, width: pageWidth } = this.context.getPageSize()\n const { width: viewportWidth, height: viewportHeight } = this.pageProxy.getViewport({ scale: 1 })\n const pageScale = Math.max(pageWidth / viewportWidth, pageHeight / viewportHeight)\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 // Then wedefine 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 = viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight\n\n canvas.width = Math.floor(viewport.width * pixelRatioScale)\n canvas.height = Math.floor(viewport.height * pixelRatioScale)\n canvas.style.width = Math.floor(canvasWidth) + \"px\"\n canvas.style.height = Math.floor(canvasHeight) + \"px\"\n\n if (this.renderTask) {\n this.renderTask.cancel()\n }\n\n const transform = pixelRatioScale !== 1 ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0] : null\n\n this.renderTask = this.pageProxy?.render({\n ...(transform && { transform }),\n canvasContext: context,\n viewport,\n })\n\n this.renderTask?.promise\n .catch((e) => {\n if (!(e instanceof RenderingCancelledException)) console.error(e)\n })\n .finally(() => {\n this.renderTask = undefined\n })\n\n return undefined\n }\n}\n","import { 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 (file: Blob): Promise<Archive> => {\n const loadingTask = pdfjsLib.getDocument(await file.arrayBuffer())\n\n const pdf = await loadingTask.promise\n\n const archive = {\n filename: file.name,\n proxyDocument: pdf,\n _symbol: PDF_SYMBOL,\n files: Array.from(Array(pdf.numPages)).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 close: () => {\n return pdf.cleanup()\n },\n } satisfies PdfJsArchive\n\n return archive as Archive\n}\n","import { createReader, Reader } from \"@prose-reader/core\"\nimport { PdfRenderer } from \"./PdfRenderer\"\nimport { EnhancerOptions } from \"./types\"\nimport { from, map, mergeMap, of } from \"rxjs\"\nimport { isPdfJsArchive } from \"./createArchiveFromPdf\"\n\ntype CreateReader = typeof createReader\ntype CreateReaderOptions = Parameters<CreateReader>[0]\n\nexport const pdfEnhancer =\n <InheritOptions extends CreateReaderOptions, InheritOutput extends Reader>(next: (options: InheritOptions) => InheritOutput) =>\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 MaybeRenderer = options.getRenderer?.(item)\n\n if (!MaybeRenderer && item.href.endsWith(`.pdf`)) {\n return PdfRenderer\n }\n\n return MaybeRenderer\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 const fileIndex = archive.files.findIndex((file) => item.href.endsWith(file.uri))\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","sources":["../src/renderer/frames.ts","../src/renderer/PdfRenderer.ts","../src/createArchiveFromPdf.ts","../src/pdfEnhancer.ts"],"sourcesContent":["export const createPdfFrameElement = () => {\n const frame = document.createElement(`iframe`)\n frame.tabIndex = 0\n frame.style.cssText = `\n overflow: hidden;\n height: 100%;\n width: 100%;\n padding: 0px;\n position: absolute;\n left: 0;\n top: 0;\n `\n\n frame.setAttribute(\"frameBorder\", \"0\")\n\n return frame\n}\n\nexport const copyCanvasToFrame = (canvas: HTMLCanvasElement, frameDoc: Document) => {\n // Create a new canvas in the iframe\n const iframeCanvas = frameDoc.createElement(\"canvas\")\n iframeCanvas.width = canvas.width\n iframeCanvas.height = canvas.height\n iframeCanvas.style.width = canvas.style.width\n iframeCanvas.style.height = canvas.style.height\n\n // Copy the content\n const ctx = iframeCanvas.getContext(\"2d\")\n if (ctx) {\n ctx.drawImage(canvas, 0, 0)\n }\n\n frameDoc.body.appendChild(iframeCanvas)\n\n return iframeCanvas\n}\n","import { EMPTY, from, Observable, of, switchMap, tap } from \"rxjs\"\nimport { PDFPageProxy, RenderingCancelledException, RenderTask, TextLayer } from \"pdfjs-dist\"\nimport { DocumentRenderer, injectCSS, removeCSS, waitForFrameReady, waitForSwitch } from \"@prose-reader/core\"\nimport { copyCanvasToFrame, createPdfFrameElement } from \"./frames\"\nimport pdfFrameStyle from \"./frame.css?inline\"\n\nexport class PdfRenderer extends DocumentRenderer {\n private pageProxy: PDFPageProxy | undefined\n private renderTask: RenderTask | undefined\n private textLayer: TextLayer | undefined\n private getFrameElement() {\n const frame = this.layers[0]?.element\n\n if (!(frame instanceof HTMLIFrameElement)) return\n\n return frame\n }\n\n constructor(\n private pdfViewerStyle: string,\n params: ConstructorParameters<typeof DocumentRenderer>[0],\n ) {\n super(params)\n }\n\n onUnload(): Observable<unknown> {\n this.layers.forEach(({ element }) => {\n element.remove()\n })\n\n this.layers = []\n\n if (this.renderTask) {\n this.renderTask.cancel()\n }\n this.textLayer?.cancel()\n this.pageProxy?.cleanup()\n\n return EMPTY\n }\n\n onCreateDocument(): Observable<unknown> {\n const frameElement = createPdfFrameElement()\n\n frameElement.setAttribute(`src`, \"about:blank\")\n\n this.layers = [\n {\n element: frameElement,\n },\n ]\n\n return EMPTY\n }\n\n onLoadDocument(): Observable<unknown> {\n return from(this.resourcesHandler.fetchResource()).pipe(\n switchMap((resource) => {\n if (!(\"custom\" in resource)) return EMPTY\n\n const pageProxy = resource.data as PDFPageProxy\n\n this.pageProxy = pageProxy\n\n const frameElement = this.getFrameElement()\n\n if (!frameElement) return EMPTY\n\n return of(frameElement).pipe(\n waitForSwitch(this.context.bridgeEvent.viewportFree$),\n tap(() => {\n this.containerElement.appendChild(frameElement)\n // frame will instantly load, no need to wait for event\n\n injectCSS(frameElement, \"pdfjs-viewer-style\", this.pdfViewerStyle)\n injectCSS(frameElement, \"enhancer-pdf-style\", pdfFrameStyle)\n\n const body = frameElement?.contentDocument?.body\n\n if (body) {\n const canvas = body.ownerDocument.createElement(`canvas`)\n\n body.appendChild(canvas)\n }\n }),\n waitForFrameReady,\n )\n }),\n )\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n layout(_: {\n minPageSpread: number\n blankPagePosition: `before` | `after` | `none`\n spreadPosition: `none` | `left` | `right`\n }): { width: number; height: number } | undefined {\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 const context = canvas?.getContext(\"2d\")\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n\n if (!this.pageProxy || !context) return undefined\n\n if (this.renderTask) {\n this.renderTask.cancel()\n this.renderTask = undefined\n }\n\n // first we try to get the desired viewport for a confortable reading based on theh current page size\n const { height: pageHeight, width: pageWidth } = this.context.getPageSize()\n const { width: viewportWidth, height: viewportHeight } = this.pageProxy.getViewport({ scale: 1 })\n const pageScale = Math.max(pageWidth / viewportWidth, pageHeight / viewportHeight)\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 // Then wedefine 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 = viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight\n\n canvas.width = Math.floor(viewport.width * pixelRatioScale)\n canvas.height = Math.floor(viewport.height * pixelRatioScale)\n canvas.style.width = Math.floor(canvasWidth) + \"px\"\n canvas.style.height = Math.floor(canvasHeight) + \"px\"\n\n const transform = pixelRatioScale !== 1 ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0] : null\n\n this.renderTask = this.pageProxy?.render({\n ...(transform && { transform }),\n canvasContext: context,\n viewport,\n })\n\n this.renderTask?.promise\n .then(() => {\n const frameElement = this.getFrameElement()\n const frameDoc = frameElement?.contentDocument\n if (!frameDoc || !frameElement) {\n return\n }\n frameDoc.body.innerHTML = ``\n const frameCanvas = copyCanvasToFrame(canvas, frameDoc)\n const pdfPage = this.pageProxy\n if (!pdfPage) return\n const textLayerElement = frameDoc.createElement(`div`)\n // Set it's class to textLayer which have required CSS styles\n textLayerElement.setAttribute(\"class\", \"textLayer\")\n frameDoc.body.appendChild(textLayerElement)\n // scale between original viewport size and the rendererd canvas size. (not the rendering scale)\n const canvasScale = canvasWidth / viewportWidth\n textLayerElement.style.top = frameCanvas.offsetTop + \"px\"\n textLayerElement.style.left = frameCanvas.offsetLeft + \"px\"\n\n removeCSS(frameElement, \"pdf-scale-scale\")\n injectCSS(frameElement, \"pdf-scale-scale\", `:root { --scale-factor: ${canvasScale}; }`)\n\n if (this.textLayer) {\n this.textLayer.cancel()\n }\n\n this.textLayer = new TextLayer({\n container: textLayerElement,\n textContentSource: pdfPage.streamTextContent(),\n viewport,\n })\n\n this.textLayer.render()\n })\n .catch((e) => {\n if (!(e instanceof RenderingCancelledException)) console.error(e)\n })\n .finally(() => {\n this.renderTask = undefined\n\n canvas.remove()\n })\n\n return undefined\n }\n}\n","import { 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 (file: Blob): Promise<Archive> => {\n const loadingTask = pdfjsLib.getDocument(await file.arrayBuffer())\n\n const pdf = await loadingTask.promise\n\n const archive = {\n filename: file.name,\n proxyDocument: pdf,\n _symbol: PDF_SYMBOL,\n files: Array.from(Array(pdf.numPages)).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 close: () => {\n return pdf.cleanup()\n },\n } satisfies PdfJsArchive\n\n return archive as Archive\n}\n","import { createReader, Reader } from \"@prose-reader/core\"\nimport { PdfRenderer } from \"./renderer/PdfRenderer\"\nimport { EnhancerOptions } from \"./types\"\nimport { from, map, mergeMap, of } from \"rxjs\"\nimport { isPdfJsArchive } from \"./createArchiveFromPdf\"\n\ntype CreateReader = typeof createReader\ntype CreateReaderOptions = Parameters<CreateReader>[0]\n\nexport const pdfEnhancer =\n <InheritOptions extends CreateReaderOptions, InheritOutput extends Reader>(next: (options: InheritOptions) => InheritOutput) =>\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) => 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 const fileIndex = archive.files.findIndex((file) => item.href.endsWith(file.uri))\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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"}
@@ -23,36 +23,68 @@
23
23
 
24
24
  const pdfjsLib__namespace = /*#__PURE__*/_interopNamespaceDefault(pdfjsLib);
25
25
 
26
+ const createPdfFrameElement = () => {
27
+ const frame = document.createElement(`iframe`);
28
+ frame.tabIndex = 0;
29
+ frame.style.cssText = `
30
+ overflow: hidden;
31
+ height: 100%;
32
+ width: 100%;
33
+ padding: 0px;
34
+ position: absolute;
35
+ left: 0;
36
+ top: 0;
37
+ `;
38
+ frame.setAttribute("frameBorder", "0");
39
+ return frame;
40
+ };
41
+ const copyCanvasToFrame = (canvas, frameDoc) => {
42
+ const iframeCanvas = frameDoc.createElement("canvas");
43
+ iframeCanvas.width = canvas.width;
44
+ iframeCanvas.height = canvas.height;
45
+ iframeCanvas.style.width = canvas.style.width;
46
+ iframeCanvas.style.height = canvas.style.height;
47
+ const ctx = iframeCanvas.getContext("2d");
48
+ if (ctx) {
49
+ ctx.drawImage(canvas, 0, 0);
50
+ }
51
+ frameDoc.body.appendChild(iframeCanvas);
52
+ return iframeCanvas;
53
+ };
54
+
55
+ const pdfFrameStyle = ".textLayer {\n position: absolute;\n width: 100%;\n height: 100%;\n color: black;\n overflow: hidden;\n line-height: 1;\n}\n\nbody {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n margin: 0;\n padding: 0;\n}\n";
56
+
26
57
  class PdfRenderer extends core.DocumentRenderer {
58
+ constructor(pdfViewerStyle, params) {
59
+ super(params);
60
+ this.pdfViewerStyle = pdfViewerStyle;
61
+ }
27
62
  pageProxy;
28
63
  renderTask;
29
- getCanvas() {
30
- const element = this.layers[0]?.element.children[0];
31
- if (element instanceof HTMLCanvasElement) return element;
32
- return void 0;
64
+ textLayer;
65
+ getFrameElement() {
66
+ const frame = this.layers[0]?.element;
67
+ if (!(frame instanceof HTMLIFrameElement)) return;
68
+ return frame;
33
69
  }
34
70
  onUnload() {
35
71
  this.layers.forEach(({ element }) => {
36
72
  element.remove();
37
73
  });
38
74
  this.layers = [];
75
+ if (this.renderTask) {
76
+ this.renderTask.cancel();
77
+ }
78
+ this.textLayer?.cancel();
39
79
  this.pageProxy?.cleanup();
40
80
  return rxjs.EMPTY;
41
81
  }
42
82
  onCreateDocument() {
43
- const canvasContainer = this.containerElement.ownerDocument.createElement(`div`);
44
- canvasContainer.style.cssText = `
45
- width: 100%;
46
- height: 100%;
47
- display: flex;
48
- justify-content: center;
49
- align-items: center;
50
- `;
51
- const canvas = this.containerElement.ownerDocument.createElement(`canvas`);
52
- canvasContainer.appendChild(canvas);
83
+ const frameElement = createPdfFrameElement();
84
+ frameElement.setAttribute(`src`, "about:blank");
53
85
  this.layers = [
54
86
  {
55
- element: canvasContainer
87
+ element: frameElement
56
88
  }
57
89
  ];
58
90
  return rxjs.EMPTY;
@@ -63,20 +95,35 @@
63
95
  if (!("custom" in resource)) return rxjs.EMPTY;
64
96
  const pageProxy = resource.data;
65
97
  this.pageProxy = pageProxy;
66
- const container = this.layers[0]?.element;
67
- if (container) {
68
- this.containerElement.appendChild(container);
69
- }
70
- return rxjs.EMPTY;
98
+ const frameElement = this.getFrameElement();
99
+ if (!frameElement) return rxjs.EMPTY;
100
+ return rxjs.of(frameElement).pipe(
101
+ core.waitForSwitch(this.context.bridgeEvent.viewportFree$),
102
+ rxjs.tap(() => {
103
+ this.containerElement.appendChild(frameElement);
104
+ core.injectCSS(frameElement, "pdfjs-viewer-style", this.pdfViewerStyle);
105
+ core.injectCSS(frameElement, "enhancer-pdf-style", pdfFrameStyle);
106
+ const body = frameElement?.contentDocument?.body;
107
+ if (body) {
108
+ const canvas = body.ownerDocument.createElement(`canvas`);
109
+ body.appendChild(canvas);
110
+ }
111
+ }),
112
+ core.waitForFrameReady
113
+ );
71
114
  })
72
115
  );
73
116
  }
74
117
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
75
118
  layout(_) {
76
- const canvas = this.getCanvas();
119
+ const canvas = this.containerElement.ownerDocument.createElement("canvas");
77
120
  const context = canvas?.getContext("2d");
78
121
  const pixelRatioScale = window.devicePixelRatio || 1;
79
- if (!canvas || !this.pageProxy || !context) return void 0;
122
+ if (!this.pageProxy || !context) return void 0;
123
+ if (this.renderTask) {
124
+ this.renderTask.cancel();
125
+ this.renderTask = void 0;
126
+ }
80
127
  const { height: pageHeight, width: pageWidth } = this.context.getPageSize();
81
128
  const { width: viewportWidth, height: viewportHeight } = this.pageProxy.getViewport({ scale: 1 });
82
129
  const pageScale = Math.max(pageWidth / viewportWidth, pageHeight / viewportHeight);
@@ -90,19 +137,44 @@
90
137
  canvas.height = Math.floor(viewport.height * pixelRatioScale);
91
138
  canvas.style.width = Math.floor(canvasWidth) + "px";
92
139
  canvas.style.height = Math.floor(canvasHeight) + "px";
93
- if (this.renderTask) {
94
- this.renderTask.cancel();
95
- }
96
140
  const transform = pixelRatioScale !== 1 ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0] : null;
97
141
  this.renderTask = this.pageProxy?.render({
98
142
  ...transform && { transform },
99
143
  canvasContext: context,
100
144
  viewport
101
145
  });
102
- this.renderTask?.promise.catch((e) => {
146
+ this.renderTask?.promise.then(() => {
147
+ const frameElement = this.getFrameElement();
148
+ const frameDoc = frameElement?.contentDocument;
149
+ if (!frameDoc || !frameElement) {
150
+ return;
151
+ }
152
+ frameDoc.body.innerHTML = ``;
153
+ const frameCanvas = copyCanvasToFrame(canvas, frameDoc);
154
+ const pdfPage = this.pageProxy;
155
+ if (!pdfPage) return;
156
+ const textLayerElement = frameDoc.createElement(`div`);
157
+ textLayerElement.setAttribute("class", "textLayer");
158
+ frameDoc.body.appendChild(textLayerElement);
159
+ const canvasScale = canvasWidth / viewportWidth;
160
+ textLayerElement.style.top = frameCanvas.offsetTop + "px";
161
+ textLayerElement.style.left = frameCanvas.offsetLeft + "px";
162
+ core.removeCSS(frameElement, "pdf-scale-scale");
163
+ core.injectCSS(frameElement, "pdf-scale-scale", `:root { --scale-factor: ${canvasScale}; }`);
164
+ if (this.textLayer) {
165
+ this.textLayer.cancel();
166
+ }
167
+ this.textLayer = new pdfjsLib.TextLayer({
168
+ container: textLayerElement,
169
+ textContentSource: pdfPage.streamTextContent(),
170
+ viewport
171
+ });
172
+ this.textLayer.render();
173
+ }).catch((e) => {
103
174
  if (!(e instanceof pdfjsLib.RenderingCancelledException)) console.error(e);
104
175
  }).finally(() => {
105
176
  this.renderTask = void 0;
177
+ canvas.remove();
106
178
  });
107
179
  return void 0;
108
180
  }
@@ -149,11 +221,11 @@
149
221
  * setup we should return it.
150
222
  */
151
223
  getRenderer(item) {
152
- const MaybeRenderer = options.getRenderer?.(item);
153
- if (!MaybeRenderer && item.href.endsWith(`.pdf`)) {
154
- return PdfRenderer;
224
+ const maybeFactory = options.getRenderer?.(item);
225
+ if (!maybeFactory && item.href.endsWith(`.pdf`)) {
226
+ return (params) => new PdfRenderer(options.pdf.pdfjsViewerInlineCss, params);
155
227
  }
156
- return MaybeRenderer;
228
+ return maybeFactory;
157
229
  },
158
230
  getResource: (item) => options.pdf.getArchiveForItem(item).pipe(
159
231
  rxjs.mergeMap((archive) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.cjs","sources":["../src/PdfRenderer.ts","../src/createArchiveFromPdf.ts","../src/pdfEnhancer.ts"],"sourcesContent":["import { EMPTY, from, Observable, switchMap } from \"rxjs\"\nimport { PDFPageProxy, RenderingCancelledException, RenderTask } from \"pdfjs-dist\"\nimport { DocumentRenderer } from \"@prose-reader/core\"\n\nexport class PdfRenderer extends DocumentRenderer {\n private pageProxy: PDFPageProxy | undefined\n private renderTask: RenderTask | undefined\n\n getCanvas() {\n const element = this.layers[0]?.element.children[0]\n\n if (element instanceof HTMLCanvasElement) return element\n\n return undefined\n }\n\n onUnload(): Observable<unknown> {\n this.layers.forEach(({ element }) => {\n element.remove()\n })\n\n this.layers = []\n\n this.pageProxy?.cleanup()\n\n return EMPTY\n }\n\n onCreateDocument(): Observable<unknown> {\n const canvasContainer = this.containerElement.ownerDocument.createElement(`div`)\n canvasContainer.style.cssText = `\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n `\n\n const canvas = this.containerElement.ownerDocument.createElement(`canvas`)\n\n canvasContainer.appendChild(canvas)\n\n this.layers = [\n {\n element: canvasContainer,\n },\n ]\n\n return EMPTY\n }\n\n onLoadDocument(): Observable<unknown> {\n return from(this.resourcesHandler.fetchResource()).pipe(\n switchMap((resource) => {\n if (!(\"custom\" in resource)) return EMPTY\n\n const pageProxy = resource.data as PDFPageProxy\n\n this.pageProxy = pageProxy\n\n const container = this.layers[0]?.element\n\n if (container) {\n this.containerElement.appendChild(container)\n }\n\n return EMPTY\n }),\n )\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n layout(_: {\n minPageSpread: number\n blankPagePosition: `before` | `after` | `none`\n spreadPosition: `none` | `left` | `right`\n }): { width: number; height: number } | undefined {\n const canvas = this.getCanvas()\n const context = canvas?.getContext(\"2d\")\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n\n if (!canvas || !this.pageProxy || !context) return undefined\n\n // first we try to get the desired viewport for a confortable reading based on theh current page size\n const { height: pageHeight, width: pageWidth } = this.context.getPageSize()\n const { width: viewportWidth, height: viewportHeight } = this.pageProxy.getViewport({ scale: 1 })\n const pageScale = Math.max(pageWidth / viewportWidth, pageHeight / viewportHeight)\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 // Then wedefine 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 = viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight\n\n canvas.width = Math.floor(viewport.width * pixelRatioScale)\n canvas.height = Math.floor(viewport.height * pixelRatioScale)\n canvas.style.width = Math.floor(canvasWidth) + \"px\"\n canvas.style.height = Math.floor(canvasHeight) + \"px\"\n\n if (this.renderTask) {\n this.renderTask.cancel()\n }\n\n const transform = pixelRatioScale !== 1 ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0] : null\n\n this.renderTask = this.pageProxy?.render({\n ...(transform && { transform }),\n canvasContext: context,\n viewport,\n })\n\n this.renderTask?.promise\n .catch((e) => {\n if (!(e instanceof RenderingCancelledException)) console.error(e)\n })\n .finally(() => {\n this.renderTask = undefined\n })\n\n return undefined\n }\n}\n","import { 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 (file: Blob): Promise<Archive> => {\n const loadingTask = pdfjsLib.getDocument(await file.arrayBuffer())\n\n const pdf = await loadingTask.promise\n\n const archive = {\n filename: file.name,\n proxyDocument: pdf,\n _symbol: PDF_SYMBOL,\n files: Array.from(Array(pdf.numPages)).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 close: () => {\n return pdf.cleanup()\n },\n } satisfies PdfJsArchive\n\n return archive as Archive\n}\n","import { createReader, Reader } from \"@prose-reader/core\"\nimport { PdfRenderer } from \"./PdfRenderer\"\nimport { EnhancerOptions } from \"./types\"\nimport { from, map, mergeMap, of } from \"rxjs\"\nimport { isPdfJsArchive } from \"./createArchiveFromPdf\"\n\ntype CreateReader = typeof createReader\ntype CreateReaderOptions = Parameters<CreateReader>[0]\n\nexport const pdfEnhancer =\n <InheritOptions extends CreateReaderOptions, InheritOutput extends Reader>(next: (options: InheritOptions) => InheritOutput) =>\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 MaybeRenderer = options.getRenderer?.(item)\n\n if (!MaybeRenderer && item.href.endsWith(`.pdf`)) {\n return PdfRenderer\n }\n\n return MaybeRenderer\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 const fileIndex = archive.files.findIndex((file) => item.href.endsWith(file.uri))\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":["DocumentRenderer","EMPTY","from","switchMap","RenderingCancelledException","pdfjsLib","mergeMap","of","map"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.cjs","sources":["../src/renderer/frames.ts","../src/renderer/PdfRenderer.ts","../src/createArchiveFromPdf.ts","../src/pdfEnhancer.ts"],"sourcesContent":["export const createPdfFrameElement = () => {\n const frame = document.createElement(`iframe`)\n frame.tabIndex = 0\n frame.style.cssText = `\n overflow: hidden;\n height: 100%;\n width: 100%;\n padding: 0px;\n position: absolute;\n left: 0;\n top: 0;\n `\n\n frame.setAttribute(\"frameBorder\", \"0\")\n\n return frame\n}\n\nexport const copyCanvasToFrame = (canvas: HTMLCanvasElement, frameDoc: Document) => {\n // Create a new canvas in the iframe\n const iframeCanvas = frameDoc.createElement(\"canvas\")\n iframeCanvas.width = canvas.width\n iframeCanvas.height = canvas.height\n iframeCanvas.style.width = canvas.style.width\n iframeCanvas.style.height = canvas.style.height\n\n // Copy the content\n const ctx = iframeCanvas.getContext(\"2d\")\n if (ctx) {\n ctx.drawImage(canvas, 0, 0)\n }\n\n frameDoc.body.appendChild(iframeCanvas)\n\n return iframeCanvas\n}\n","import { EMPTY, from, Observable, of, switchMap, tap } from \"rxjs\"\nimport { PDFPageProxy, RenderingCancelledException, RenderTask, TextLayer } from \"pdfjs-dist\"\nimport { DocumentRenderer, injectCSS, removeCSS, waitForFrameReady, waitForSwitch } from \"@prose-reader/core\"\nimport { copyCanvasToFrame, createPdfFrameElement } from \"./frames\"\nimport pdfFrameStyle from \"./frame.css?inline\"\n\nexport class PdfRenderer extends DocumentRenderer {\n private pageProxy: PDFPageProxy | undefined\n private renderTask: RenderTask | undefined\n private textLayer: TextLayer | undefined\n private getFrameElement() {\n const frame = this.layers[0]?.element\n\n if (!(frame instanceof HTMLIFrameElement)) return\n\n return frame\n }\n\n constructor(\n private pdfViewerStyle: string,\n params: ConstructorParameters<typeof DocumentRenderer>[0],\n ) {\n super(params)\n }\n\n onUnload(): Observable<unknown> {\n this.layers.forEach(({ element }) => {\n element.remove()\n })\n\n this.layers = []\n\n if (this.renderTask) {\n this.renderTask.cancel()\n }\n this.textLayer?.cancel()\n this.pageProxy?.cleanup()\n\n return EMPTY\n }\n\n onCreateDocument(): Observable<unknown> {\n const frameElement = createPdfFrameElement()\n\n frameElement.setAttribute(`src`, \"about:blank\")\n\n this.layers = [\n {\n element: frameElement,\n },\n ]\n\n return EMPTY\n }\n\n onLoadDocument(): Observable<unknown> {\n return from(this.resourcesHandler.fetchResource()).pipe(\n switchMap((resource) => {\n if (!(\"custom\" in resource)) return EMPTY\n\n const pageProxy = resource.data as PDFPageProxy\n\n this.pageProxy = pageProxy\n\n const frameElement = this.getFrameElement()\n\n if (!frameElement) return EMPTY\n\n return of(frameElement).pipe(\n waitForSwitch(this.context.bridgeEvent.viewportFree$),\n tap(() => {\n this.containerElement.appendChild(frameElement)\n // frame will instantly load, no need to wait for event\n\n injectCSS(frameElement, \"pdfjs-viewer-style\", this.pdfViewerStyle)\n injectCSS(frameElement, \"enhancer-pdf-style\", pdfFrameStyle)\n\n const body = frameElement?.contentDocument?.body\n\n if (body) {\n const canvas = body.ownerDocument.createElement(`canvas`)\n\n body.appendChild(canvas)\n }\n }),\n waitForFrameReady,\n )\n }),\n )\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n layout(_: {\n minPageSpread: number\n blankPagePosition: `before` | `after` | `none`\n spreadPosition: `none` | `left` | `right`\n }): { width: number; height: number } | undefined {\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 const context = canvas?.getContext(\"2d\")\n // Support HiDPI-screens.\n const pixelRatioScale = window.devicePixelRatio || 1\n\n if (!this.pageProxy || !context) return undefined\n\n if (this.renderTask) {\n this.renderTask.cancel()\n this.renderTask = undefined\n }\n\n // first we try to get the desired viewport for a confortable reading based on theh current page size\n const { height: pageHeight, width: pageWidth } = this.context.getPageSize()\n const { width: viewportWidth, height: viewportHeight } = this.pageProxy.getViewport({ scale: 1 })\n const pageScale = Math.max(pageWidth / viewportWidth, pageHeight / viewportHeight)\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 // Then wedefine 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 = viewportRatio > pageRatio ? pageWidth / viewportRatio : pageHeight\n\n canvas.width = Math.floor(viewport.width * pixelRatioScale)\n canvas.height = Math.floor(viewport.height * pixelRatioScale)\n canvas.style.width = Math.floor(canvasWidth) + \"px\"\n canvas.style.height = Math.floor(canvasHeight) + \"px\"\n\n const transform = pixelRatioScale !== 1 ? [pixelRatioScale, 0, 0, pixelRatioScale, 0, 0] : null\n\n this.renderTask = this.pageProxy?.render({\n ...(transform && { transform }),\n canvasContext: context,\n viewport,\n })\n\n this.renderTask?.promise\n .then(() => {\n const frameElement = this.getFrameElement()\n const frameDoc = frameElement?.contentDocument\n if (!frameDoc || !frameElement) {\n return\n }\n frameDoc.body.innerHTML = ``\n const frameCanvas = copyCanvasToFrame(canvas, frameDoc)\n const pdfPage = this.pageProxy\n if (!pdfPage) return\n const textLayerElement = frameDoc.createElement(`div`)\n // Set it's class to textLayer which have required CSS styles\n textLayerElement.setAttribute(\"class\", \"textLayer\")\n frameDoc.body.appendChild(textLayerElement)\n // scale between original viewport size and the rendererd canvas size. (not the rendering scale)\n const canvasScale = canvasWidth / viewportWidth\n textLayerElement.style.top = frameCanvas.offsetTop + \"px\"\n textLayerElement.style.left = frameCanvas.offsetLeft + \"px\"\n\n removeCSS(frameElement, \"pdf-scale-scale\")\n injectCSS(frameElement, \"pdf-scale-scale\", `:root { --scale-factor: ${canvasScale}; }`)\n\n if (this.textLayer) {\n this.textLayer.cancel()\n }\n\n this.textLayer = new TextLayer({\n container: textLayerElement,\n textContentSource: pdfPage.streamTextContent(),\n viewport,\n })\n\n this.textLayer.render()\n })\n .catch((e) => {\n if (!(e instanceof RenderingCancelledException)) console.error(e)\n })\n .finally(() => {\n this.renderTask = undefined\n\n canvas.remove()\n })\n\n return undefined\n }\n}\n","import { 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 (file: Blob): Promise<Archive> => {\n const loadingTask = pdfjsLib.getDocument(await file.arrayBuffer())\n\n const pdf = await loadingTask.promise\n\n const archive = {\n filename: file.name,\n proxyDocument: pdf,\n _symbol: PDF_SYMBOL,\n files: Array.from(Array(pdf.numPages)).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 close: () => {\n return pdf.cleanup()\n },\n } satisfies PdfJsArchive\n\n return archive as Archive\n}\n","import { createReader, Reader } from \"@prose-reader/core\"\nimport { PdfRenderer } from \"./renderer/PdfRenderer\"\nimport { EnhancerOptions } from \"./types\"\nimport { from, map, mergeMap, of } from \"rxjs\"\nimport { isPdfJsArchive } from \"./createArchiveFromPdf\"\n\ntype CreateReader = typeof createReader\ntype CreateReaderOptions = Parameters<CreateReader>[0]\n\nexport const pdfEnhancer =\n <InheritOptions extends CreateReaderOptions, InheritOutput extends Reader>(next: (options: InheritOptions) => InheritOutput) =>\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) => 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 const fileIndex = archive.files.findIndex((file) => item.href.endsWith(file.uri))\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":["DocumentRenderer","EMPTY","from","switchMap","of","waitForSwitch","tap","injectCSS","waitForFrameReady","removeCSS","TextLayer","RenderingCancelledException","pdfjsLib","mergeMap","map"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EAAO,MAAM,wBAAwB,MAAM;EACzC,EAAM,MAAA,KAAA,GAAQ,QAAS,CAAA,aAAA,CAAc,CAAQ,MAAA,CAAA,CAAA;EAC7C,EAAA,KAAA,CAAM,QAAW,GAAA,CAAA;EACjB,EAAA,KAAA,CAAM,MAAM,OAAU,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAAA;EAUtB,EAAM,KAAA,CAAA,YAAA,CAAa,eAAe,GAAG,CAAA;EAErC,EAAO,OAAA,KAAA;EACT,CAAA;EAEa,MAAA,iBAAA,GAAoB,CAAC,MAAA,EAA2B,QAAuB,KAAA;EAElF,EAAM,MAAA,YAAA,GAAe,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA;EACpD,EAAA,YAAA,CAAa,QAAQ,MAAO,CAAA,KAAA;EAC5B,EAAA,YAAA,CAAa,SAAS,MAAO,CAAA,MAAA;EAC7B,EAAa,YAAA,CAAA,KAAA,CAAM,KAAQ,GAAA,MAAA,CAAO,KAAM,CAAA,KAAA;EACxC,EAAa,YAAA,CAAA,KAAA,CAAM,MAAS,GAAA,MAAA,CAAO,KAAM,CAAA,MAAA;EAGzC,EAAM,MAAA,GAAA,GAAM,YAAa,CAAA,UAAA,CAAW,IAAI,CAAA;EACxC,EAAA,IAAI,GAAK,EAAA;EACP,IAAI,GAAA,CAAA,SAAA,CAAU,MAAQ,EAAA,CAAA,EAAG,CAAC,CAAA;EAAA;EAG5B,EAAS,QAAA,CAAA,IAAA,CAAK,YAAY,YAAY,CAAA;EAEtC,EAAO,OAAA,YAAA;EACT,CAAA;;;;EC7BO,MAAM,oBAAoBA,qBAAiB,CAAA;EAAA,EAYhD,WAAA,CACU,gBACR,MACA,EAAA;EACA,IAAA,KAAA,CAAM,MAAM,CAAA;EAHJ,IAAA,IAAA,CAAA,cAAA,GAAA,cAAA;EAAA;EAIV,EAhBQ,SAAA;EAAA,EACA,UAAA;EAAA,EACA,SAAA;EAAA,EACA,eAAkB,GAAA;EACxB,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,MAAO,CAAA,CAAC,CAAG,EAAA,OAAA;EAE9B,IAAI,IAAA,EAAE,iBAAiB,iBAAoB,CAAA,EAAA;EAE3C,IAAO,OAAA,KAAA;EAAA;EACT,EASA,QAAgC,GAAA;EAC9B,IAAA,IAAA,CAAK,MAAO,CAAA,OAAA,CAAQ,CAAC,EAAE,SAAc,KAAA;EACnC,MAAA,OAAA,CAAQ,MAAO,EAAA;EAAA,KAChB,CAAA;EAED,IAAA,IAAA,CAAK,SAAS,EAAC;EAEf,IAAA,IAAI,KAAK,UAAY,EAAA;EACnB,MAAA,IAAA,CAAK,WAAW,MAAO,EAAA;EAAA;EAEzB,IAAA,IAAA,CAAK,WAAW,MAAO,EAAA;EACvB,IAAA,IAAA,CAAK,WAAW,OAAQ,EAAA;EAExB,IAAO,OAAAC,UAAA;EAAA;EACT,EAEA,gBAAwC,GAAA;EACtC,IAAA,MAAM,eAAe,qBAAsB,EAAA;EAE3C,IAAa,YAAA,CAAA,YAAA,CAAa,OAAO,aAAa,CAAA;EAE9C,IAAA,IAAA,CAAK,MAAS,GAAA;EAAA,MACZ;EAAA,QACE,OAAS,EAAA;EAAA;EACX,KACF;EAEA,IAAO,OAAAA,UAAA;EAAA;EACT,EAEA,cAAsC,GAAA;EACpC,IAAA,OAAOC,SAAK,CAAA,IAAA,CAAK,gBAAiB,CAAA,aAAA,EAAe,CAAE,CAAA,IAAA;EAAA,MACjDC,cAAA,CAAU,CAAC,QAAa,KAAA;EACtB,QAAI,IAAA,EAAE,QAAY,IAAA,QAAA,CAAA,EAAkB,OAAAF,UAAA;EAEpC,QAAA,MAAM,YAAY,QAAS,CAAA,IAAA;EAE3B,QAAA,IAAA,CAAK,SAAY,GAAA,SAAA;EAEjB,QAAM,MAAA,YAAA,GAAe,KAAK,eAAgB,EAAA;EAE1C,QAAI,IAAA,CAAC,cAAqB,OAAAA,UAAA;EAE1B,QAAO,OAAAG,OAAA,CAAG,YAAY,CAAE,CAAA,IAAA;EAAA,UACtBC,kBAAc,CAAA,IAAA,CAAK,OAAQ,CAAA,WAAA,CAAY,aAAa,CAAA;EAAA,UACpDC,SAAI,MAAM;EACR,YAAK,IAAA,CAAA,gBAAA,CAAiB,YAAY,YAAY,CAAA;EAG9C,YAAUC,cAAA,CAAA,YAAA,EAAc,oBAAsB,EAAA,IAAA,CAAK,cAAc,CAAA;EACjE,YAAUA,cAAA,CAAA,YAAA,EAAc,sBAAsB,aAAa,CAAA;EAE3D,YAAM,MAAA,IAAA,GAAO,cAAc,eAAiB,EAAA,IAAA;EAE5C,YAAA,IAAI,IAAM,EAAA;EACR,cAAA,MAAM,MAAS,GAAA,IAAA,CAAK,aAAc,CAAA,aAAA,CAAc,CAAQ,MAAA,CAAA,CAAA;EAExD,cAAA,IAAA,CAAK,YAAY,MAAM,CAAA;EAAA;EACzB,WACD,CAAA;EAAA,UACDC;EAAA,SACF;EAAA,OACD;EAAA,KACH;EAAA;EACF;EAAA,EAGA,OAAO,CAI2C,EAAA;EAKhD,IAAA,MAAM,MAAS,GAAA,IAAA,CAAK,gBAAiB,CAAA,aAAA,CAAc,cAAc,QAAQ,CAAA;EACzE,IAAM,MAAA,OAAA,GAAU,MAAQ,EAAA,UAAA,CAAW,IAAI,CAAA;EAEvC,IAAM,MAAA,eAAA,GAAkB,OAAO,gBAAoB,IAAA,CAAA;EAEnD,IAAA,IAAI,CAAC,IAAA,CAAK,SAAa,IAAA,CAAC,SAAgB,OAAA,KAAA,CAAA;EAExC,IAAA,IAAI,KAAK,UAAY,EAAA;EACnB,MAAA,IAAA,CAAK,WAAW,MAAO,EAAA;EACvB,MAAA,IAAA,CAAK,UAAa,GAAA,KAAA,CAAA;EAAA;EAIpB,IAAM,MAAA,EAAE,QAAQ,UAAY,EAAA,KAAA,EAAO,WAAc,GAAA,IAAA,CAAK,QAAQ,WAAY,EAAA;EAC1E,IAAA,MAAM,EAAE,KAAA,EAAO,aAAe,EAAA,MAAA,EAAQ,cAAe,EAAA,GAAI,IAAK,CAAA,SAAA,CAAU,WAAY,CAAA,EAAE,KAAO,EAAA,CAAA,EAAG,CAAA;EAChG,IAAA,MAAM,YAAY,IAAK,CAAA,GAAA,CAAI,SAAY,GAAA,aAAA,EAAe,aAAa,cAAc,CAAA;EAGjF,IAAA,MAAM,WAAW,IAAK,CAAA,SAAA,CAAU,YAAY,EAAE,KAAA,EAAO,WAAW,CAAA;EAGhE,IAAM,MAAA,aAAA,GAAgB,QAAS,CAAA,KAAA,GAAQ,QAAS,CAAA,MAAA;EAChD,IAAA,MAAM,YAAY,SAAY,GAAA,UAAA;EAC9B,IAAA,MAAM,kBAAkB,aAAgB,GAAA,SAAA;EACxC,IAAM,MAAA,WAAA,GAAc,eAAkB,GAAA,SAAA,GAAY,UAAa,GAAA,aAAA;EAC/D,IAAA,MAAM,YAAe,GAAA,aAAA,GAAgB,SAAY,GAAA,SAAA,GAAY,aAAgB,GAAA,UAAA;EAE7E,IAAA,MAAA,CAAO,KAAQ,GAAA,IAAA,CAAK,KAAM,CAAA,QAAA,CAAS,QAAQ,eAAe,CAAA;EAC1D,IAAA,MAAA,CAAO,MAAS,GAAA,IAAA,CAAK,KAAM,CAAA,QAAA,CAAS,SAAS,eAAe,CAAA;EAC5D,IAAA,MAAA,CAAO,KAAM,CAAA,KAAA,GAAQ,IAAK,CAAA,KAAA,CAAM,WAAW,CAAI,GAAA,IAAA;EAC/C,IAAA,MAAA,CAAO,KAAM,CAAA,MAAA,GAAS,IAAK,CAAA,KAAA,CAAM,YAAY,CAAI,GAAA,IAAA;EAEjD,IAAM,MAAA,SAAA,GAAY,eAAoB,KAAA,CAAA,GAAI,CAAC,eAAA,EAAiB,GAAG,CAAG,EAAA,eAAA,EAAiB,CAAG,EAAA,CAAC,CAAI,GAAA,IAAA;EAE3F,IAAK,IAAA,CAAA,UAAA,GAAa,IAAK,CAAA,SAAA,EAAW,MAAO,CAAA;EAAA,MACvC,GAAI,SAAa,IAAA,EAAE,SAAU,EAAA;EAAA,MAC7B,aAAe,EAAA,OAAA;EAAA,MACf;EAAA,KACD,CAAA;EAED,IAAK,IAAA,CAAA,UAAA,EAAY,OACd,CAAA,IAAA,CAAK,MAAM;EACV,MAAM,MAAA,YAAA,GAAe,KAAK,eAAgB,EAAA;EAC1C,MAAA,MAAM,WAAW,YAAc,EAAA,eAAA;EAC/B,MAAI,IAAA,CAAC,QAAY,IAAA,CAAC,YAAc,EAAA;EAC9B,QAAA;EAAA;EAEF,MAAA,QAAA,CAAS,KAAK,SAAY,GAAA,CAAA,CAAA;EAC1B,MAAM,MAAA,WAAA,GAAc,iBAAkB,CAAA,MAAA,EAAQ,QAAQ,CAAA;EACtD,MAAA,MAAM,UAAU,IAAK,CAAA,SAAA;EACrB,MAAA,IAAI,CAAC,OAAS,EAAA;EACd,MAAM,MAAA,gBAAA,GAAmB,QAAS,CAAA,aAAA,CAAc,CAAK,GAAA,CAAA,CAAA;EAErD,MAAiB,gBAAA,CAAA,YAAA,CAAa,SAAS,WAAW,CAAA;EAClD,MAAS,QAAA,CAAA,IAAA,CAAK,YAAY,gBAAgB,CAAA;EAE1C,MAAA,MAAM,cAAc,WAAc,GAAA,aAAA;EAClC,MAAiB,gBAAA,CAAA,KAAA,CAAM,GAAM,GAAA,WAAA,CAAY,SAAY,GAAA,IAAA;EACrD,MAAiB,gBAAA,CAAA,KAAA,CAAM,IAAO,GAAA,WAAA,CAAY,UAAa,GAAA,IAAA;EAEvD,MAAAC,cAAA,CAAU,cAAc,iBAAiB,CAAA;EACzC,MAAAF,cAAA,CAAU,YAAc,EAAA,iBAAA,EAAmB,CAA2B,wBAAA,EAAA,WAAW,CAAK,GAAA,CAAA,CAAA;EAEtF,MAAA,IAAI,KAAK,SAAW,EAAA;EAClB,QAAA,IAAA,CAAK,UAAU,MAAO,EAAA;EAAA;EAGxB,MAAK,IAAA,CAAA,SAAA,GAAY,IAAIG,kBAAU,CAAA;EAAA,QAC7B,SAAW,EAAA,gBAAA;EAAA,QACX,iBAAA,EAAmB,QAAQ,iBAAkB,EAAA;EAAA,QAC7C;EAAA,OACD,CAAA;EAED,MAAA,IAAA,CAAK,UAAU,MAAO,EAAA;EAAA,KACvB,CAAA,CACA,KAAM,CAAA,CAAC,CAAM,KAAA;EACZ,MAAA,IAAI,EAAE,CAAA,YAAaC,oCAA8B,CAAA,EAAA,OAAA,CAAQ,MAAM,CAAC,CAAA;EAAA,KACjE,CACA,CAAA,OAAA,CAAQ,MAAM;EACb,MAAA,IAAA,CAAK,UAAa,GAAA,KAAA,CAAA;EAElB,MAAA,MAAA,CAAO,MAAO,EAAA;EAAA,KACf,CAAA;EAEH,IAAO,OAAA,KAAA,CAAA;EAAA;EAEX;;ECnLA,MAAM,UAAA,GAAa,OAAO,CAAO,KAAA,CAAA,CAAA;AAE1B,QAAM,iBAAiB,CAAC,OAAA,KAC7B,SAAa,IAAA,OAAA,IAAW,QAAQ,OAAY,KAAA;AAOjC,QAAA,oBAAA,GAAuB,OAAO,IAAiC,KAAA;EAC1E,EAAA,MAAM,cAAcC,mBAAS,CAAA,WAAA,CAAY,MAAM,IAAA,CAAK,aAAa,CAAA;EAEjE,EAAM,MAAA,GAAA,GAAM,MAAM,WAAY,CAAA,OAAA;EAE9B,EAAA,MAAM,OAAU,GAAA;EAAA,IACd,UAAU,IAAK,CAAA,IAAA;EAAA,IACf,aAAe,EAAA,GAAA;EAAA,IACf,OAAS,EAAA,UAAA;EAAA,IACT,KAAA,EAAO,KAAM,CAAA,IAAA,CAAK,KAAM,CAAA,GAAA,CAAI,QAAQ,CAAC,CAAE,CAAA,GAAA,CAAI,CAAC,CAAA,EAAG,KAAW,MAAA;EAAA,MACxD,GAAK,EAAA,KAAA;EAAA,MACL,MAAM,YAAY;EAChB,QAAM,MAAA,IAAI,MAAM,6BAA6B,CAAA;EAAA,OAC/C;EAAA,MACA,QAAA,EAAU,GAAG,KAAK,CAAA,IAAA,CAAA;EAAA,MAClB,IAAM,EAAA,CAAA;EAAA,MACN,QAAQ,MAAM;EACZ,QAAM,MAAA,IAAI,MAAM,6BAA6B,CAAA;EAAA,OAC/C;EAAA,MACA,GAAA,EAAK,GAAG,KAAK,CAAA,IAAA;EAAA,KACb,CAAA,CAAA;EAAA,IACF,OAAO,MAAM;EACX,MAAA,OAAO,IAAI,OAAQ,EAAA;EAAA;EACrB,GACF;EAEA,EAAO,OAAA,OAAA;EACT;;ACpCO,QAAM,WACX,GAAA,CAA2E,IAC3E,KAAA,CAAC,OAA6D,KAAA;EAC5D,EAAA,MAAM,SAAS,IAAK,CAAA;EAAA,IAClB,GAAG,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA,IAUH,YAAY,IAAM,EAAA;EAChB,MAAM,MAAA,YAAA,GAAe,OAAQ,CAAA,WAAA,GAAc,IAAI,CAAA;EAE/C,MAAA,IAAI,CAAC,YAAgB,IAAA,IAAA,CAAK,IAAK,CAAA,QAAA,CAAS,MAAM,CAAG,EAAA;EAC/C,QAAA,OAAO,CAAC,MAAW,KAAA,IAAI,YAAY,OAAQ,CAAA,GAAA,CAAI,sBAAsB,MAAM,CAAA;EAAA;EAG7E,MAAO,OAAA,YAAA;EAAA,KACT;EAAA,IACA,aAAa,CAAC,IAAA,KACZ,QAAQ,GAAI,CAAA,iBAAA,CAAkB,IAAI,CAAE,CAAA,IAAA;EAAA,MAClCC,aAAA,CAAS,CAAC,OAAY,KAAA;EACpB,QAAA,IAAI,CAAC,OAAA,EAAgB,OAAAT,OAAA,CAAG,KAAS,CAAA,CAAA;EAEjC,QAAI,IAAA,CAAC,cAAe,CAAA,OAAO,CAAG,EAAA;EAC5B,UAAA,OAAA,CAAQ,KAAK,CAAqC,mCAAA,CAAA,CAAA;EAElD,UAAA,OAAOA,QAAG,KAAS,CAAA,CAAA;EAAA;EAGrB,QAAM,MAAA,SAAA,GAAY,OAAQ,CAAA,KAAA,CAAM,SAAU,CAAA,CAAC,IAAS,KAAA,IAAA,CAAK,IAAK,CAAA,QAAA,CAAS,IAAK,CAAA,GAAG,CAAC,CAAA;EAEhF,QAAA,OAAOF,UAAK,OAAQ,CAAA,aAAA,CAAc,QAAQ,SAAY,GAAA,CAAC,CAAC,CAAE,CAAA,IAAA;EAAA,UACxDY,QAAA,CAAI,CAAC,SAAe,MAAA;EAAA,YAClB,MAAQ,EAAA,IAAA;EAAA,YACR,IAAM,EAAA;EAAA,WACN,CAAA;EAAA,SACJ;EAAA,OACD;EAAA;EACH,GACH,CAAA;EAED,EAAO,OAAA,MAAA;EACT;;;;;;;;;;;;"}
@@ -1,9 +1,12 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { DocumentRenderer } from '@prose-reader/core';
3
3
  export declare class PdfRenderer extends DocumentRenderer {
4
+ private pdfViewerStyle;
4
5
  private pageProxy;
5
6
  private renderTask;
6
- getCanvas(): HTMLCanvasElement | undefined;
7
+ private textLayer;
8
+ private getFrameElement;
9
+ constructor(pdfViewerStyle: string, params: ConstructorParameters<typeof DocumentRenderer>[0]);
7
10
  onUnload(): Observable<unknown>;
8
11
  onCreateDocument(): Observable<unknown>;
9
12
  onLoadDocument(): Observable<unknown>;
@@ -0,0 +1,2 @@
1
+ export declare const createPdfFrameElement: () => HTMLIFrameElement;
2
+ export declare const copyCanvasToFrame: (canvas: HTMLCanvasElement, frameDoc: Document) => HTMLCanvasElement;
package/dist/types.d.ts CHANGED
@@ -3,6 +3,7 @@ import { Archive } from '@prose-reader/streamer';
3
3
  import { Observable } from 'rxjs';
4
4
  export type EnhancerOptions = {
5
5
  pdf: {
6
- getArchiveForItem: (item: Manifest["spineItems"][number]) => Observable<Archive | undefined>;
6
+ getArchiveForItem: (item: Manifest["items"][number]) => Observable<Archive | undefined>;
7
+ pdfjsViewerInlineCss: string;
7
8
  };
8
9
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prose-reader/enhancer-pdf",
3
- "version": "1.124.0",
3
+ "version": "1.126.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.umd.cjs",
6
6
  "module": "./dist/index.js",
@@ -20,10 +20,13 @@
20
20
  "lint:read": "prettier --check . && eslint . --ext .ts,.tsx,.js,.jsx",
21
21
  "lint:write": "prettier --write . && eslint --fix . --ext .ts,.tsx,.js,.jsx"
22
22
  },
23
+ "devDependencies": {
24
+ "pdfjs-dist": "^4.8.69"
25
+ },
23
26
  "peerDependencies": {
24
27
  "@prose-reader/core": "^1.117.0",
25
28
  "pdfjs-dist": "^4.8.69",
26
29
  "rxjs": "*"
27
30
  },
28
- "gitHead": "8d9f9991a83dd1d21270a58d3aef48379e8f5e57"
31
+ "gitHead": "f17c8db176c5f917d91776aeb1e6f31f99abd0b7"
29
32
  }