| /* |
| * 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); |