2019-06-28 05:22:08 +02:00
|
|
|
"use strict";
|
|
|
|
|
2021-11-21 21:39:19 +01:00
|
|
|
pdfjsLib.GlobalWorkerOptions.workerSrc = "/pdf.worker.js";
|
|
|
|
|
2019-08-20 18:47:01 +02:00
|
|
|
const padding = document.getElementById("padding");
|
2019-06-28 05:22:08 +02:00
|
|
|
let pdfDoc = null;
|
|
|
|
let pageRendering = false;
|
|
|
|
let renderPending = false;
|
2020-04-04 18:14:38 +02:00
|
|
|
let renderPendingZoom = 0;
|
2019-06-28 05:22:08 +02:00
|
|
|
const canvas = document.getElementById('content');
|
2017-11-14 18:29:10 +01:00
|
|
|
let orientationDegrees = 0;
|
2019-11-18 11:49:58 +01:00
|
|
|
let zoomRatio = 1;
|
2019-06-28 05:22:08 +02:00
|
|
|
let textLayerDiv = document.getElementById("text");
|
|
|
|
let task = null;
|
|
|
|
|
|
|
|
let newPageNumber = 0;
|
2019-11-18 11:49:58 +01:00
|
|
|
let newZoomRatio = 1;
|
2019-06-28 05:22:08 +02:00
|
|
|
let useRender;
|
|
|
|
|
|
|
|
const cache = [];
|
|
|
|
const maxCached = 6;
|
|
|
|
|
|
|
|
function maybeRenderNextPage() {
|
|
|
|
if (renderPending) {
|
|
|
|
pageRendering = false;
|
|
|
|
renderPending = false;
|
2020-04-04 17:31:16 +02:00
|
|
|
renderPage(channel.getPage(), renderPendingZoom, false);
|
2019-06-28 05:22:08 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleRenderingError(error) {
|
|
|
|
console.log("rendering error: " + error);
|
|
|
|
|
|
|
|
pageRendering = false;
|
|
|
|
maybeRenderNextPage();
|
|
|
|
}
|
|
|
|
|
|
|
|
function doPrerender(pageNumber, prerenderTrigger) {
|
|
|
|
if (useRender) {
|
|
|
|
if (pageNumber + 1 <= pdfDoc.numPages) {
|
|
|
|
renderPage(pageNumber + 1, false, true, pageNumber);
|
|
|
|
} else if (pageNumber - 1 > 0) {
|
|
|
|
renderPage(pageNumber - 1, false, true, pageNumber);
|
|
|
|
}
|
2019-07-01 07:56:54 +02:00
|
|
|
} else if (pageNumber === prerenderTrigger + 1) {
|
2019-06-28 05:22:08 +02:00
|
|
|
if (prerenderTrigger - 1 > 0) {
|
|
|
|
renderPage(prerenderTrigger - 1, false, true, prerenderTrigger);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-04 17:31:16 +02:00
|
|
|
function display(newCanvas, zoom) {
|
2019-06-28 05:22:08 +02:00
|
|
|
canvas.height = newCanvas.height;
|
|
|
|
canvas.width = newCanvas.width;
|
|
|
|
canvas.style.height = newCanvas.style.height;
|
|
|
|
canvas.style.width = newCanvas.style.width;
|
2019-08-20 18:47:01 +02:00
|
|
|
padding.style.width = canvas.style.width;
|
2019-06-28 05:22:08 +02:00
|
|
|
canvas.getContext("2d", { alpha: false }).drawImage(newCanvas, 0, 0);
|
2020-04-04 17:31:16 +02:00
|
|
|
if (!zoom) {
|
|
|
|
scrollTo(0, 0);
|
|
|
|
}
|
2019-06-28 05:22:08 +02:00
|
|
|
}
|
|
|
|
|
2020-04-04 17:31:16 +02:00
|
|
|
function renderPage(pageNumber, zoom, prerender, prerenderTrigger=0) {
|
2019-06-28 05:22:08 +02:00
|
|
|
pageRendering = true;
|
|
|
|
useRender = !prerender;
|
|
|
|
|
|
|
|
newPageNumber = pageNumber;
|
2019-11-18 11:49:58 +01:00
|
|
|
newZoomRatio = channel.getZoomRatio();
|
2017-11-14 18:29:10 +01:00
|
|
|
orientationDegrees = channel.getDocumentOrientationDegrees();
|
2019-11-18 11:49:58 +01:00
|
|
|
console.log("page: " + pageNumber + ", zoom: " + newZoomRatio +
|
2017-11-14 18:29:10 +01:00
|
|
|
", orientationDegrees: " + orientationDegrees + ", prerender: " + prerender);
|
2019-06-28 05:22:08 +02:00
|
|
|
for (let i = 0; i < cache.length; i++) {
|
|
|
|
const cached = cache[i];
|
2019-11-18 11:49:58 +01:00
|
|
|
if (cached.pageNumber === pageNumber && cached.zoomRatio === newZoomRatio &&
|
2019-07-01 07:56:54 +02:00
|
|
|
cache.orientationDegrees === orientationDegrees) {
|
2019-06-28 05:22:08 +02:00
|
|
|
if (useRender) {
|
|
|
|
cache.splice(i, 1);
|
|
|
|
cache.push(cached);
|
|
|
|
|
2020-04-04 17:31:16 +02:00
|
|
|
display(cached.canvas, zoom);
|
2019-06-28 05:22:08 +02:00
|
|
|
|
|
|
|
textLayerDiv.replaceWith(cached.textLayerDiv);
|
|
|
|
textLayerDiv = cached.textLayerDiv;
|
|
|
|
}
|
|
|
|
|
|
|
|
pageRendering = false;
|
|
|
|
doPrerender(pageNumber, prerenderTrigger);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pdfDoc.getPage(pageNumber).then(function(page) {
|
|
|
|
if (maybeRenderNextPage()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-11-18 11:49:58 +01:00
|
|
|
const viewport = page.getViewport({scale: newZoomRatio, rotation: orientationDegrees})
|
2019-06-28 05:22:08 +02:00
|
|
|
|
|
|
|
if (useRender) {
|
2019-11-18 11:49:58 +01:00
|
|
|
if (newZoomRatio !== zoomRatio) {
|
2019-06-28 05:22:08 +02:00
|
|
|
canvas.style.height = viewport.height + "px";
|
|
|
|
canvas.style.width = viewport.width + "px";
|
|
|
|
}
|
2019-11-18 11:49:58 +01:00
|
|
|
zoomRatio = newZoomRatio;
|
2019-06-28 05:22:08 +02:00
|
|
|
}
|
|
|
|
|
2020-04-04 18:14:38 +02:00
|
|
|
if (zoom == 2) {
|
|
|
|
pageRendering = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const newCanvas = document.createElement("canvas");
|
|
|
|
const ratio = window.devicePixelRatio;
|
|
|
|
newCanvas.height = viewport.height * ratio;
|
|
|
|
newCanvas.width = viewport.width * ratio;
|
|
|
|
newCanvas.style.height = viewport.height + "px";
|
|
|
|
newCanvas.style.width = viewport.width + "px";
|
|
|
|
const newContext = newCanvas.getContext("2d", { alpha: false });
|
|
|
|
newContext.scale(ratio, ratio);
|
|
|
|
|
2019-06-28 05:22:08 +02:00
|
|
|
task = page.render({
|
|
|
|
canvasContext: newContext,
|
|
|
|
viewport: viewport
|
|
|
|
});
|
|
|
|
|
2019-08-16 07:19:50 +02:00
|
|
|
task.promise.then(function() {
|
2019-06-28 05:22:08 +02:00
|
|
|
task = null;
|
|
|
|
|
|
|
|
let rendered = false;
|
|
|
|
function render() {
|
|
|
|
if (!useRender || rendered) {
|
|
|
|
return;
|
|
|
|
}
|
2020-04-04 17:31:16 +02:00
|
|
|
display(newCanvas, zoom);
|
2019-06-28 05:22:08 +02:00
|
|
|
rendered = true;
|
|
|
|
}
|
|
|
|
render();
|
|
|
|
|
|
|
|
const textLayerFrag = document.createDocumentFragment();
|
2019-08-16 07:19:50 +02:00
|
|
|
task = pdfjsLib.renderTextLayer({
|
2019-06-28 05:22:08 +02:00
|
|
|
textContentStream: page.streamTextContent(),
|
|
|
|
container: textLayerFrag,
|
|
|
|
viewport: viewport
|
|
|
|
});
|
|
|
|
task.promise.then(function() {
|
|
|
|
task = null;
|
|
|
|
|
|
|
|
render();
|
|
|
|
|
|
|
|
const newTextLayerDiv = textLayerDiv.cloneNode();
|
|
|
|
newTextLayerDiv.style.height = newCanvas.style.height;
|
|
|
|
newTextLayerDiv.style.width = newCanvas.style.width;
|
|
|
|
if (useRender) {
|
|
|
|
textLayerDiv.replaceWith(newTextLayerDiv);
|
|
|
|
textLayerDiv = newTextLayerDiv;
|
|
|
|
}
|
|
|
|
newTextLayerDiv.appendChild(textLayerFrag);
|
|
|
|
|
|
|
|
if (cache.length === maxCached) {
|
|
|
|
cache.shift()
|
|
|
|
}
|
|
|
|
cache.push({
|
|
|
|
pageNumber: pageNumber,
|
2019-11-18 11:49:58 +01:00
|
|
|
zoomRatio: newZoomRatio,
|
2017-11-14 18:29:10 +01:00
|
|
|
orientationDegrees: orientationDegrees,
|
2019-06-28 05:22:08 +02:00
|
|
|
canvas: newCanvas,
|
|
|
|
textLayerDiv: newTextLayerDiv
|
|
|
|
});
|
|
|
|
|
|
|
|
pageRendering = false;
|
|
|
|
doPrerender(pageNumber, prerenderTrigger);
|
|
|
|
}).catch(handleRenderingError);
|
|
|
|
}).catch(handleRenderingError);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-04-04 17:31:16 +02:00
|
|
|
function onRenderPage(zoom) {
|
2019-06-28 05:22:08 +02:00
|
|
|
if (pageRendering) {
|
2020-04-04 17:32:04 +02:00
|
|
|
if (newPageNumber === channel.getPage() && newZoomRatio === channel.getZoomRatio() &&
|
2017-11-14 18:29:10 +01:00
|
|
|
orientationDegrees === channel.getDocumentOrientationDegrees()) {
|
2019-06-28 05:22:08 +02:00
|
|
|
useRender = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
renderPending = true;
|
2020-04-04 17:31:16 +02:00
|
|
|
renderPendingZoom = zoom;
|
2019-06-28 05:22:08 +02:00
|
|
|
if (task !== null) {
|
|
|
|
task.cancel();
|
|
|
|
task = null;
|
|
|
|
}
|
|
|
|
} else {
|
2020-04-04 17:31:16 +02:00
|
|
|
renderPage(channel.getPage(), zoom, false);
|
2019-06-28 05:22:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-17 01:42:51 +02:00
|
|
|
function isTextSelected() {
|
|
|
|
return window.getSelection().toString() !== "";
|
|
|
|
}
|
|
|
|
|
2019-08-20 18:23:38 +02:00
|
|
|
function updateInset() {
|
|
|
|
const windowInsetTop = channel.getWindowInsetTop() / window.devicePixelRatio + "px";
|
|
|
|
padding.style.paddingTop = windowInsetTop;
|
|
|
|
textLayerDiv.style.top = windowInsetTop;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateInset();
|
|
|
|
|
2019-08-16 07:19:50 +02:00
|
|
|
pdfjsLib.getDocument("https://localhost/placeholder.pdf").promise.then(function(newDoc) {
|
2019-06-28 05:22:08 +02:00
|
|
|
pdfDoc = newDoc;
|
|
|
|
channel.setNumPages(pdfDoc.numPages);
|
|
|
|
pdfDoc.getMetadata().then(function(data) {
|
|
|
|
channel.setDocumentProperties(JSON.stringify(data.info));
|
|
|
|
}).catch(function(error) {
|
|
|
|
console.log("getMetadata error: " + error);
|
|
|
|
});
|
|
|
|
renderPage(channel.getPage(), false, false);
|
|
|
|
}).catch(function(error) {
|
|
|
|
console.log("getDocument error: " + error);
|
|
|
|
});
|