217 lines
8.6 KiB
JavaScript

/**
Homemade helper for browsing PDF document from page to page.
This is hightly inspired from https://github.com/mozilla/pdf.js/blob/master/examples/learning/prevnext.html
This lib requires PDF JS. It simply uses PDFjs and its promises.
DOC : http://mozilla.github.io/pdf.js/api/draft/api.js.html
*/
// !!!!!!!!! use window.pdfjsLib and not pdfjsLib
var PDFSlidesViewer = (function(){
function PDFSlidesViewer(pdf_url, $canvas) {
// pdf variables
this.pdf = null;
this.pdf_url = pdf_url;
this.pdf_page_total = 0;
this.pdf_page_current = 1; // default is the first page
this.pdf_zoom = 1; // 1 = scale to fit to available space
// promise business
this.pageRendering = false;
this.pageNumPending = null;
//canvas
this.canvas = $canvas;
this.canvas_context = $canvas.getContext('2d');
}
/**
* Load the PDF document
*/
PDFSlidesViewer.prototype.loadDocument = async function() {
const file_content = await window.pdfjsLib.getDocument(this.pdf_url).promise;
this.pdf = file_content;
this.pdf_page_total = file_content.numPages;
return file_content;
};
/**
* Get page info from document, resize canvas accordingly, and render page.
* @param page_number : Page number.
*/
PDFSlidesViewer.prototype.renderPage = function(page_number) {
var self = this;
this.pageRendering = true;
return this.pdf.getPage(page_number).then(function(page) {
// Each PDF page has its own viewport which defines the size in pixels and initial rotation.
// We provide the scale at which to render it (relative to the natural size of the document)
var scale = self.getScaleToFit(page) * self.pdf_zoom;
var viewport = page.getViewport({ scale: scale });
// important to match, otherwise the browser will scale the rendered output and it will be ugly
self.canvas.height = viewport.height;
self.canvas.width = viewport.width;
// Render PDF page into canvas context
var renderContext = {
canvasContext: self.canvas_context,
viewport: viewport
};
var renderTask = page.render(renderContext);
// Wait for rendering to finish
return renderTask.promise.then(function () {
self.pageRendering = false;
if (self.pdf_zoom === 1 && scale > self.getScaleToFit(page)) {
// if the scale has changed (because we just added scrollbars) and we no longer fit the space
return self.renderPage(page_number);
}
if (self.pageNumPending !== null) {
// New page rendering is pending
self.renderPage(self.pageNumPending);
self.pageNumPending = null;
}
self.pdf_page_current = page_number;
return page_number;
});
});
};
/**
* If another page rendering in progress, waits until the rendering is
* finised. Otherwise, executes rendering immediately.
*/
PDFSlidesViewer.prototype.queueRenderPage = function(num) {
if(this.pageRendering) {
this.pageNumPending = num; // the queue is only the last elem
return Promise.resolve(num);
} else {
return this.renderPage(num);
}
}
/**
* Displays previous page.
*/
PDFSlidesViewer.prototype.previousPage = function() {
if (this.pdf_page_current <= 1) {
return Promise.resolve(false);
}
this.pdf_page_current--;
return this.queueRenderPage(this.pdf_page_current);
};
/**
* Displays next page.
*/
PDFSlidesViewer.prototype.nextPage = function() {
if (this.pdf_page_current >= this.pdf_page_total) {
return Promise.resolve(false);
}
this.pdf_page_current++;
return this.queueRenderPage(this.pdf_page_current);
};
/*
* Calculate a scale to fit the document on the available space.
*/
PDFSlidesViewer.prototype.getScaleToFit = function(page) {
var maxWidth = this.canvas.parentNode.clientWidth;
var maxHeight = this.canvas.parentNode.clientHeight;
var hScale = maxWidth / page.view[2];
var vScale = maxHeight / page.view[3];
return Math.min(hScale, vScale);
};
/**
* Displays the given page.
*/
PDFSlidesViewer.prototype.changePage = function(num){
if(1 <= num <= this.pdf_page_total){
this.pdf_page_current = num;
return this.queueRenderPage(num);
}
return Promise.resolve(false);
}
/**
* Displays first page.
*/
PDFSlidesViewer.prototype.firstPage = function(){
this.pdf_page_current = 1;
return this.queueRenderPage(1);
}
/**
* Displays last page.
*/
PDFSlidesViewer.prototype.lastPage = function(){
this.pdf_page_current = this.pdf_page_total;
return this.queueRenderPage(this.pdf_page_total);
}
PDFSlidesViewer.prototype.toggleFullScreenFooter = function(){
if(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
var $navBarFooter = $('div#PDFViewer div.oe_slides_panel_footer').parent();
$navBarFooter.toggleClass('oe_show_footer');
$navBarFooter.toggle();
}
}
PDFSlidesViewer.prototype.toggleFullScreen = function(){
// The canvas and the navigation bar needs to be fullscreened
var el = this.canvas.parentNode.parentNode;
var isFullscreenAvailable = document.fullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled || document.msFullscreenEnabled || false;
if(isFullscreenAvailable){ // Full screen supported
// get the actual element in FullScreen mode (Null if no element)
var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement;
if (fullscreenElement) { // Exit the full screen mode
if (document.exitFullscreen) {
// W3C standard
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
// Firefox 10+, Firefox for Android
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
// Chrome 20+, Safari 6+, Opera 15+, Chrome for Android, Opera Mobile 16+
document.webkitExitFullscreen();
} else if (document.webkitCancelFullScreen) {
// Chrome 15+, Safari 5.1+
document.webkitCancelFullScreen();
} else if (document.msExitFullscreen) {
// IE 11+
document.msExitFullscreen();
}
}else { // Request to put the 'el' element in FullScreen mode
if (el.requestFullscreen) {
// W3C standard
el.requestFullscreen();
} else if (el.mozRequestFullScreen) {
// Firefox 10+, Firefox for Android
el.mozRequestFullScreen();
} else if (el.msRequestFullscreen) {
// IE 11+
el.msRequestFullscreen();
} else if (el.webkitRequestFullscreen) {
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
// Safari 6+
el.webkitRequestFullscreen();
} else {
// Chrome 20+, Opera 15+, Chrome for Android, Opera Mobile 16+
el.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
} else if (el.webkitRequestFullScreen) {
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
// Safari 5.1+
el.webkitRequestFullScreen();
} else {
// Chrome 15+
el.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
}
}
}
}else{
// Full screen not supported by the browser
console.error("ERROR : full screen not supported by web browser");
}
}
return PDFSlidesViewer;
})();