blob: d04bf76fe615216b1965b6a81614330cc667b00a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
;(function ($, undefined) {
'use strict';
if (!pdfjsLib.getDocument) {
console.error("Missing pdf.mjs prerequisites.");
exit;
}
if (typeof(WicketStuff) !== 'object') {
window.WicketStuff = {};
}
if (typeof(WicketStuff.PDFJS) === 'object') {
return;
}
WicketStuff.PDFJS = {
Topic: {
TOTAL_PAGES: 'Wicket.PDFJS.TotalPages',
NEXT_PAGE: 'Wicket.PDFJS.NextPage',
PREVIOUS_PAGE: 'Wicket.PDFJS.PreviousPage',
PAGE_TO: 'Wicket.PDFJS.PageTo',
ZOOM_TO: 'Wicket.PDFJS.ZoomTo',
HEIGHT_TO: 'Wicket.PDFJS.HeightTo',
CURRENT_PAGE: 'Wicket.PDFJS.CurrentPage',
CURRENT_ZOOM : 'Wicket.PDFJS.CurrentZoom',
CURRENT_HEIGHT : 'Wicket.PDFJS.CurrentHeight',
CURRENT_PRINT_PAGE : 'Wicket.PDFJS.CurrentPrintPage',
PRINT : 'Wicket.PDFJS.Print'
},
init: function (config) {
pdfjsLib.GlobalWorkerOptions.workerSrc = config.workerUrl;
var pdfDoc = null,
pageNum = config.initialPage || 1,
pageRendering = false,
pageNumPending = null,
scaleValue = config.initialScale || "1.0",
scale = 1.0, // will be initialized below, based on config.initialScale
autoScale = "", // will be initialized below, based on config.initialScale
canvas = $('#'+config.canvasId)[0],
canvasDiv = $(canvas).parent(),
ctx = canvas.getContext('2d'),
abortingPrinting = false;
var scaleValueFloat = parseFloat(scaleValue);
if (isNaN(scaleValueFloat)){
autoScale = config.initialScale;
} else {
scale = parseFloat(scaleValueFloat.toFixed(2));
}
var MIN_SCALE = 0.25;
var MAX_SCALE = 10.0;
var DEFAULT_SCALE_DELTA = 1.1;
var MAX_AUTO_SCALE = 1.25;
var container = $('#'+canvas.id).closest('.pdfPanel');
$(canvasDiv).height(config.initialHeight || 800);
canvas.height = 2000;
canvas.width = container.width();
$(window).on('resize', function(){
var win = $(this); //this = window
var container = $('#'+canvas.id).closest('.pdfPanel');
canvas.width = container.width();
queueRenderPage(pageNum);
});
function printDocument() {
pageRendering = true;
abortingPrinting = false;
var pages = pdfDoc.numPages;
var pc = $('<div/>');
pc.attr('id', 'pdf-js-print-container');
$('body').append(pc);
for (var i = 0; i < pages; i++){
var wrapper = $('<div/>');
pc.append(wrapper);
}
for (var i = 1; i <= pages; i++){
printPage(i, pages);
}
}
function cleanUp(error) {
if (abortingPrinting) { return; }
if (error) {
abortingPrinting = true;
var printError = -1; // use -1 to indicate error printing
Wicket.Event.publish(WicketStuff.PDFJS.Topic.CURRENT_PRINT_PAGE, printError, {"canvasId": config.canvasId});
}
pageRendering = false;
var body = $('body').removeAttr('pdf-js-printing');
$('#pdf-js-print-container').remove();
}
function printPage(num, total) {
// Using promise to fetch the page
pdfDoc.getPage(num).then(function(page) {
if (abortingPrinting) { return; }
var viewport = page.getViewport({scale: 1});
var offScreenCanvas = $('<canvas/>')[0];
offScreenCanvas.width = viewport.width;
offScreenCanvas.height = viewport.height;
var offScreenCanvasCtx = offScreenCanvas.getContext('2d');
// Render PDF page into canvas context
var renderContext = {
canvasContext: offScreenCanvasCtx,
viewport: viewport
};
var renderTask = page.render(renderContext);
// Wait for rendering to finish
renderTask.promise.then(function () {
var img = $('<img/>')[0];
$(img).width(viewport.width);
$(img).height(viewport.height);
img.onload = function() {
if (abortingPrinting) { return; }
// image loaded so append to appropriate div.
var wrapper = $('#pdf-js-print-container > div:nth-child(' + num + ')');
var renderedPages = 0;
if (wrapper.length) {
wrapper.append(img);
// get count of loaded images so that once all loaded we can print
renderedPages = $('#pdf-js-print-container img').length;
// publish for progress bar
Wicket.Event.publish(WicketStuff.PDFJS.Topic.CURRENT_PRINT_PAGE, renderedPages, {"canvasId": config.canvasId});
}
if (renderedPages === total) {
try {
$('body').attr('pdf-js-printing', true);
print.call(window);
}
catch(e) {
cleanUp(true);
}
finally{
// will do nothing if we have already aborted
cleanUp(false);
}
} else if (renderedPages === 0 || renderedPages > total) {
// should be at least one so abort printing
// don't see how can ever be greater but treat as error as well;
cleanUp(true);
}
}
img.onerror = function() {
if (abortingPrinting) { return; }
cleanUp(true);
}
img.src = offScreenCanvas.toDataURL();
});
});
}
/**
* If another page rendering in progress, waits until the rendering is
* finished. Otherwise, executes rendering immediately.
*/
function queueRenderPage(num) {
if (pageRendering) {
pageNumPending = num;
} else {
renderPage(num);
}
}
function renderIfRescaled(newScale, newAutoScale){
if (newAutoScale && newAutoScale !== autoScale) {
autoScale = newAutoScale;
queueRenderPage(pageNum);
}
else if (newScale !== scale){
autoScale = "";
scale = newScale;
queueRenderPage(pageNum);
}
}
function calculateAutoScale(page) {
var viewport = page.getViewport({scale: 1});
var pageWidth = viewport.width;
var pageHeight = viewport.height;
var containerWidth = $(canvasDiv).width();
var containerHeight = $(canvasDiv).height();
//console.log("page (width, height) = (" + pageWidth + "," + pageHeight + ")")
//console.log("container (width, height) = (" + containerWidth + "," + containerHeight + ")")
var pageWidthScale = containerWidth / pageWidth;
var pageHeightScale = containerHeight / pageHeight;
switch (autoScale) {
case 'page-actual':
return 0.99; // if set to 1, then see two 100% in the drop-down; not sure why...
case 'page-width':
return pageWidthScale;
case 'page-height':
return pageHeightScale;
case 'page-fit':
return Math.min(pageWidthScale, pageHeightScale);
case 'auto':
var isLandscape = pageWidth > pageHeight;
var horizontalScale = isLandscape ? Math.min(pageHeightScale, pageWidthScale) : pageWidthScale;
return Math.min(MAX_AUTO_SCALE, horizontalScale);
default:
return scale;
}
}
/**
* Displays previous page.
*/
Wicket.Event.subscribe(WicketStuff.PDFJS.Topic.PREVIOUS_PAGE, function (jqEvent, data) {
if (config.canvasId !== data.canvasId || pageNum <= 1) {
return;
}
pageNum--;
queueRenderPage(pageNum);
});
/**
* Displays next page.
*/
Wicket.Event.subscribe(WicketStuff.PDFJS.Topic.NEXT_PAGE, function (jqEvent, data) {
if (config.canvasId !== data.canvasId || pageNum >= pdfDoc.numPages) {
return;
}
pageNum++;
queueRenderPage(pageNum);
});
/**
* Displays selected page
*/
Wicket.Event.subscribe(WicketStuff.PDFJS.Topic.PAGE_TO, function (jqEvent, data) {
if (config.canvasId !== data.canvasId) {
return;
}
if (!data.page || data.page > pdfDoc.numPages || data.page < 1 || data.page === pageNum) {
return;
}
pageNum = data.page;
queueRenderPage(pageNum);
});
Wicket.Event.subscribe(WicketStuff.PDFJS.Topic.ZOOM_TO, function (jqEvent, data) {
if (config.canvasId !== data.canvasId || !data.scale) {
return;
}
scaleValue = data.scale;
var scaleValueFloat = parseFloat(scaleValue);
var newScale;
var newAutoScale;
if (isNaN(scaleValueFloat)){
newAutoScale = scaleValue;
}
else {
newScale = parseFloat(scaleValueFloat.toFixed(2));
}
renderIfRescaled(newScale, newAutoScale);
});
Wicket.Event.subscribe(WicketStuff.PDFJS.Topic.HEIGHT_TO, function (jqEvent, data) {
if (config.canvasId !== data.canvasId || !data.height) {
return;
}
var previousHeight = $(canvasDiv).height();
var newHeight = data.height;
$(canvasDiv).height(newHeight);
queueRenderPage(pageNum);
});
/**
* Print document
*/
Wicket.Event.subscribe(WicketStuff.PDFJS.Topic.PRINT, function (jqEvent, data) {
if (config.canvasId !== data.canvasId) {
return;
}
if (pageRendering) {
// rendering or printing
return;
}
printDocument();
});
function boundedPageNumber(num) {
if(num > pdfDoc.numPages) {
return pdfDoc.numPages;
}
if(num < 1) {
return 1;
}
return num;
}
/**
* Get page info from document, resize canvas accordingly, and render page.
* @param num Page number.
*/
function renderPage(num_) {
const num = boundedPageNumber(num_);
// console.log("renderPage: " + num);
pageRendering = true;
// Using promise to fetch the page
pdfDoc.getPage(num).then(function(page) {
if (autoScale) {
scale = calculateAutoScale(page);
}
//console.log("page ready for rendering, scale: " + scale);
var viewport = page.getViewport({scale: scale});
canvas.height = viewport.height;
canvas.width = viewport.width;
//console.log("viewport.height: " + viewport.height);
//console.log("viewport.width: " + viewport.width);
// Render PDF page into canvas context
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
// Wait for rendering to finish
renderTask.promise.then(function () {
pageRendering = false;
if (pageNumPending !== null) {
// New page rendering is pending
renderPage(pageNumPending);
pageNumPending = null;
}
});
Wicket.Event.publish(WicketStuff.PDFJS.Topic.CURRENT_PAGE, pageNum, {"canvasId": config.canvasId});
Wicket.Event.publish(WicketStuff.PDFJS.Topic.CURRENT_ZOOM, scaleValue, {"canvasId": config.canvasId});
Wicket.Event.publish(WicketStuff.PDFJS.Topic.CURRENT_HEIGHT, $(canvasDiv).height(), {"canvasId": config.canvasId});
});
}
//console.log("url: " + config.documentUrl);
//console.log("cMapUrl: " + config.cmapsUrl);
//console.log("canvasId: " + config.canvasId);
/**
* Asynchronously downloads PDF.
*/
const loadingTask = pdfjsLib.getDocument({
url: config.documentUrl,
cMapUrl: config.cmapsUrl,
cMapPacked: true,
enableXfa: false,
});
loadingTask.promise.then(function (pdfDoc_) {
pdfDoc = pdfDoc_;
Wicket.Event.publish(WicketStuff.PDFJS.Topic.TOTAL_PAGES, pdfDoc.numPages, {"canvasId": config.canvasId});
renderPage(pageNum);
});
}
};
})(jQuery);