@prose-reader/enhancer-pdf 1.125.0 → 1.127.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 +105 -33
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +102 -30
- package/dist/index.umd.cjs.map +1 -1
- package/dist/{PdfRenderer.d.ts → renderer/PdfRenderer.d.ts} +4 -1
- package/dist/renderer/frames.d.ts +2 -0
- package/dist/types.d.ts +1 -0
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -1,38 +1,70 @@
|
|
|
1
|
-
import { EMPTY, from, switchMap,
|
|
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 /* This will prevent scrollbars and wrong offset of annotation layer */\n overflow: hidden;\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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
24
|
-
|
|
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:
|
|
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
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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.
|
|
99
|
+
const canvas = this.containerElement.ownerDocument.createElement("canvas");
|
|
57
100
|
const context = canvas?.getContext("2d");
|
|
58
101
|
const pixelRatioScale = window.devicePixelRatio || 1;
|
|
59
|
-
if (!
|
|
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.
|
|
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
|
|
133
|
-
if (!
|
|
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
|
|
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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"}
|
package/dist/index.umd.cjs
CHANGED
|
@@ -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 /* This will prevent scrollbars and wrong offset of annotation layer */\n overflow: hidden;\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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
44
|
-
|
|
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:
|
|
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
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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.
|
|
119
|
+
const canvas = this.containerElement.ownerDocument.createElement("canvas");
|
|
77
120
|
const context = canvas?.getContext("2d");
|
|
78
121
|
const pixelRatioScale = window.devicePixelRatio || 1;
|
|
79
|
-
if (!
|
|
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.
|
|
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
|
|
153
|
-
if (!
|
|
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
|
|
228
|
+
return maybeFactory;
|
|
157
229
|
},
|
|
158
230
|
getResource: (item) => options.pdf.getArchiveForItem(item).pipe(
|
|
159
231
|
rxjs.mergeMap((archive) => {
|
package/dist/index.umd.cjs.map
CHANGED
|
@@ -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":"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"}
|
|
@@ -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
|
-
|
|
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>;
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prose-reader/enhancer-pdf",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.127.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": "
|
|
31
|
+
"gitHead": "3853ad2ffb4f4b4ae690cc35e9cee025e0fc5a97"
|
|
29
32
|
}
|