2020-12-22 22:25:30 +08:00
|
|
|
/* global pdfjsLib animateSpinner dropdownSelector pdfjsLibUtils PerfectScrollbar */
|
|
|
|
/* eslint-disable no-param-reassign, no-use-before-define */
|
|
|
|
|
|
|
|
var PdfPreview = (function() {
|
|
|
|
const MIN_ZOOM = 0.25;
|
|
|
|
const MAX_ZOOM = 3;
|
|
|
|
const DEFAULT_ZOOM = 1;
|
|
|
|
const ZOOM_STEP = 0.25;
|
2021-01-29 18:34:53 +08:00
|
|
|
const MAX_LOAD_ATTEMPTS = 5;
|
2020-12-22 22:25:30 +08:00
|
|
|
|
|
|
|
var pageRendering = false;
|
|
|
|
|
|
|
|
function initActionButtons() {
|
|
|
|
$(document)
|
|
|
|
// Next page
|
|
|
|
.on('click', '.pdf-viewer .next-page', function() {
|
|
|
|
var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
|
|
|
|
renderPdfPage($canvas[0], $canvas.data('current-page') + 1);
|
|
|
|
})
|
|
|
|
// Previous field
|
|
|
|
.on('click', '.pdf-viewer .prev-page', function() {
|
|
|
|
var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
|
|
|
|
renderPdfPage($canvas[0], $canvas.data('current-page') - 1);
|
|
|
|
})
|
|
|
|
// Page change field
|
|
|
|
.on('change', '.pdf-viewer .current-page', function() {
|
|
|
|
var page = parseInt($(this).val(), 10) || 1;
|
|
|
|
var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
|
|
|
|
var totalPage = $canvas.data('total-page');
|
|
|
|
if (page < 1) page = 1;
|
|
|
|
if (page > totalPage) page = totalPage;
|
|
|
|
renderPdfPage($canvas[0], page);
|
|
|
|
})
|
|
|
|
// Zoom out button
|
|
|
|
.on('click', '.pdf-viewer .zoom-out', function() {
|
|
|
|
var zoomSelector = $(this).closest('.pdf-viewer').find('.zoom-page-selector');
|
|
|
|
var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
|
|
|
|
if (zoomSelector.val() === 'auto') {
|
|
|
|
dropdownSelector.selectValues(zoomSelector, DEFAULT_ZOOM);
|
|
|
|
} else {
|
|
|
|
dropdownSelector.selectValues(zoomSelector, parseFloat(zoomSelector.val()) - ZOOM_STEP);
|
|
|
|
}
|
|
|
|
renderPdfPage($canvas[0], $canvas.data('current-page'));
|
|
|
|
})
|
|
|
|
// Zoom in button
|
|
|
|
.on('click', '.pdf-viewer .zoom-in', function() {
|
|
|
|
var zoomSelector = $(this).closest('.pdf-viewer').find('.zoom-page-selector');
|
|
|
|
var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
|
|
|
|
if (zoomSelector.val() === 'auto') {
|
|
|
|
dropdownSelector.selectValues(zoomSelector, DEFAULT_ZOOM);
|
|
|
|
} else {
|
|
|
|
dropdownSelector.selectValues(zoomSelector, parseFloat(zoomSelector.val()) + ZOOM_STEP);
|
|
|
|
}
|
|
|
|
renderPdfPage($canvas[0], $canvas.data('current-page'));
|
|
|
|
})
|
|
|
|
// Zoom dropdown
|
|
|
|
.on('change', '.pdf-viewer .zoom-page-selector', function() {
|
|
|
|
var $canvas = $(this).closest('.pdf-viewer').find('.pdf-canvas');
|
|
|
|
renderPdfPage($canvas[0], $canvas.data('current-page'));
|
|
|
|
})
|
|
|
|
// Load big pdf
|
|
|
|
.on('click', '.pdf-viewer .load-blocked-pdf', function() {
|
|
|
|
var $viewer = $(this).closest('.pdf-viewer');
|
|
|
|
$viewer.removeClass('blocked');
|
|
|
|
$viewer.find('.pdf-canvas').addClass('ready');
|
|
|
|
PdfPreview.initCanvas();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function initZoomDropdown($canvas) {
|
|
|
|
var zoomSelector = $canvas.closest('.pdf-viewer').find('.zoom-page-selector');
|
|
|
|
dropdownSelector.init(zoomSelector, {
|
|
|
|
noEmptyOption: true,
|
|
|
|
singleSelect: true,
|
|
|
|
closeOnSelect: true,
|
|
|
|
selectAppearance: 'simple',
|
|
|
|
disableSearch: true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function refreshPageCounter(canvas) {
|
|
|
|
var $canvas = $(canvas);
|
|
|
|
var currentPage = $canvas.data('current-page');
|
|
|
|
var totalPage = $canvas.data('total-page');
|
|
|
|
var counterContainer = $canvas.closest('.pdf-viewer').find('.page-counter');
|
|
|
|
counterContainer.find('.current-page').val(currentPage);
|
|
|
|
counterContainer.find('.total-page').text(totalPage);
|
|
|
|
$canvas.closest('.pdf-viewer').find('.prev-page')
|
|
|
|
.attr('disabled', currentPage === 1);
|
|
|
|
$canvas.closest('.pdf-viewer').find('.next-page')
|
|
|
|
.attr('disabled', currentPage === totalPage);
|
|
|
|
}
|
|
|
|
|
|
|
|
function refreshZoomButtons(canvas) {
|
|
|
|
var $viewer = $(canvas).closest('.pdf-viewer');
|
|
|
|
var zoomSelector = $viewer.find('.zoom-page-selector');
|
|
|
|
$viewer.find('.zoom-out').attr('disabled', parseFloat(zoomSelector.val()) === MIN_ZOOM);
|
|
|
|
$viewer.find('.zoom-in').attr('disabled', parseFloat(zoomSelector.val()) === MAX_ZOOM);
|
|
|
|
}
|
|
|
|
|
|
|
|
function renderPdfPreview(canvas) {
|
|
|
|
$(canvas).removeClass('ready');
|
|
|
|
initZoomDropdown($(canvas));
|
|
|
|
animateSpinner($(canvas).closest('.pdf-viewer'), true);
|
|
|
|
$(canvas).data(
|
|
|
|
'custom-scrollbar',
|
|
|
|
new PerfectScrollbar($(canvas).closest('.page-container')[0])
|
2021-01-29 18:34:53 +08:00
|
|
|
).data('load-attempts', 0);
|
2020-12-22 22:25:30 +08:00
|
|
|
pdfjsLib.GlobalWorkerOptions.workerSrc = canvas.dataset.pdfWorkerUrl;
|
|
|
|
loadPdfDocument(canvas);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function loadPdfDocument(canvas, page = 1) {
|
|
|
|
var loadingPdf = pdfjsLib.getDocument(canvas.dataset.pdfUrl);
|
2021-01-29 18:34:53 +08:00
|
|
|
$(canvas).data('load-attempts', $(canvas).data('load-attempts') + 1);
|
2020-12-22 22:25:30 +08:00
|
|
|
loadingPdf.promise
|
|
|
|
.then(function(pdfDocument) {
|
|
|
|
$(canvas).data('pdfDocument', pdfDocument);
|
|
|
|
return renderPdfPage(canvas, page);
|
|
|
|
})
|
|
|
|
.catch(function(reason) {
|
|
|
|
pageRendering = false;
|
|
|
|
if (reason.status === 202) {
|
|
|
|
setTimeout(function() {
|
|
|
|
loadPdfDocument(canvas, page);
|
|
|
|
}, 5000);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function renderPdfPage(canvas, page = 1) {
|
|
|
|
var pdfDocument = $(canvas).data('pdfDocument');
|
|
|
|
if (pageRendering) return false;
|
|
|
|
pageRendering = true;
|
|
|
|
pdfDocument.getPage(page).then(function(pdfPage) {
|
|
|
|
var ctx;
|
|
|
|
var renderTask;
|
|
|
|
var userScale = $(canvas).closest('.pdf-viewer').find('.zoom-page-selector').val();
|
|
|
|
var $layersContainer = $(canvas).closest('.pdf-viewer').find('.layers-container');
|
|
|
|
var scale = userScale === 'auto' ? DEFAULT_ZOOM : userScale;
|
|
|
|
var viewport = pdfPage.getViewport({ scale: scale });
|
|
|
|
var previewContainer = $(canvas).closest('.page-container')[0];
|
|
|
|
var $textLayer = $(canvas).closest('.pdf-viewer').find('.textLayer');
|
|
|
|
if (previewContainer.clientHeight < viewport.height && userScale === 'auto') {
|
|
|
|
scale = previewContainer.clientHeight / viewport.height;
|
|
|
|
}
|
|
|
|
viewport = pdfPage.getViewport({ scale: scale });
|
|
|
|
canvas.width = viewport.width;
|
|
|
|
canvas.height = viewport.height;
|
|
|
|
ctx = canvas.getContext('2d');
|
|
|
|
renderTask = pdfPage.render({
|
|
|
|
canvasContext: ctx,
|
|
|
|
viewport: viewport
|
|
|
|
});
|
|
|
|
|
|
|
|
// Text layer draw
|
|
|
|
$layersContainer.css({
|
|
|
|
height: viewport.height + 'px',
|
|
|
|
width: viewport.width + 'px'
|
|
|
|
});
|
|
|
|
|
|
|
|
pdfPage.getTextContent().then(function(textContent) {
|
|
|
|
var textLayer = new pdfjsLibUtils.TextLayerBuilder({
|
|
|
|
textLayerDiv: $textLayer[0],
|
|
|
|
pageIndex: page - 1,
|
|
|
|
viewport: viewport
|
|
|
|
});
|
|
|
|
textLayer.eventBus = new pdfjsLibUtils.EventBus();
|
|
|
|
textLayer.setTextContent(textContent);
|
|
|
|
textLayer.render();
|
|
|
|
});
|
|
|
|
|
|
|
|
$(canvas)
|
|
|
|
.data('current-page', page)
|
|
|
|
.data('total-page', pdfDocument.numPages);
|
|
|
|
$(canvas).data('custom-scrollbar').update();
|
|
|
|
animateSpinner($(canvas).closest('.pdf-viewer'), false);
|
|
|
|
refreshPageCounter(canvas);
|
|
|
|
refreshZoomButtons(canvas);
|
|
|
|
pageRendering = false;
|
|
|
|
return renderTask.promise;
|
2021-01-29 18:34:53 +08:00
|
|
|
}).catch(function() {
|
|
|
|
pageRendering = false;
|
|
|
|
if ($(canvas).data('load-attempts') <= MAX_LOAD_ATTEMPTS) {
|
|
|
|
setTimeout(function() {
|
|
|
|
loadPdfDocument(canvas, page);
|
|
|
|
}, 5000);
|
|
|
|
}
|
2020-12-22 22:25:30 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
initCanvas: function() {
|
|
|
|
$.each($('.pdf-canvas.ready'), function(i, canvas) {
|
|
|
|
renderPdfPreview(canvas);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
init: function() {
|
|
|
|
initActionButtons();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}());
|
|
|
|
|
|
|
|
PdfPreview.init();
|