149 lines
6.2 KiB
JavaScript
149 lines
6.2 KiB
JavaScript
/*
|
|
* For future reference, quite a lot of this code is based on the following, and potentially more, but these are the links I remember:
|
|
* https://github.com/mozilla/pdf.js/tree/master/examples/components
|
|
* https://github.com/mozilla/pdf.js/tree/master/examples/acroforms
|
|
* https://github.com/mozilla/pdfjs-dist/tree/master/web
|
|
* https://github.com/mozilla/pdf.js/tree/master/web
|
|
*
|
|
* JSFiddle examples: https://jsfiddle.net/redfox05/btaqyse6/ , https://jsfiddle.net/redfox05/xvpzwLc2/ , https://jsfiddle.net/redfox05/rdyzef3o/
|
|
*/
|
|
|
|
import * as pdfjsLib from 'pdfjs-dist';
|
|
import * as pdfjsViewer from 'pdfjs-dist/web/pdf_viewer';
|
|
import 'pdfjs-dist/web/pdf_viewer.css';
|
|
|
|
// window.pdfjsLib = pdfjsLib;
|
|
// window.pdfjsViewer = pdfjsViewer;
|
|
|
|
export class TTPDFViewer {
|
|
constructor( options ) {
|
|
this.pdf_count = 0;
|
|
this.url_array = [];
|
|
this.target = null;
|
|
|
|
return this.initPDFViewer( options.urls, options.target );
|
|
}
|
|
|
|
initPDFViewer( url_array, target ) {
|
|
this.url_array = url_array; // needed as a global for the eventBus to trigger the next document load.
|
|
this.target = target; // Also needed for the eventBus next doc loading.
|
|
|
|
if( !Array.isArray( url_array )) {
|
|
url_array = [ url_array ];
|
|
}
|
|
|
|
if( url_array.length > 1 ) {
|
|
$('.resume-label .label' ).text( $.i18n._( 'Resume' ) + ' (' + url_array.length + ' ' + $.i18n._( 'documents' ) + ')');
|
|
}
|
|
this.loadMultiplePDF( url_array, target );
|
|
}
|
|
|
|
loadMultiplePDF( url_array, target ) {
|
|
// Load first PDF via initPDFViewer, and loads the rest in callbacks.
|
|
if( Array.isArray( url_array ) && url_array.length > 0 ) {
|
|
var current_url = url_array.pop();
|
|
|
|
// If not the first page, then add a divider between multiple PDF documents.
|
|
if( this.pdf_count !== 0 ) {
|
|
var document_divider = document.createElement( 'hr' );
|
|
target.appendChild( document_divider );
|
|
}
|
|
|
|
// Start to cycle through each pdf, loading the first one
|
|
var container = document.createElement( 'div' );
|
|
container.className = 'pdfContainer';
|
|
container.setAttribute('data-document-index', this.pdf_count);
|
|
target.appendChild( container );
|
|
|
|
this.loadPDF( current_url, container, this.pdf_count );
|
|
|
|
this.pdf_count++;
|
|
}
|
|
}
|
|
|
|
loadPDF( pdf_url, container, pdf_id ) {
|
|
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFPageView) {
|
|
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
|
|
}
|
|
|
|
// The workerSrc property shall be specified.
|
|
// pdfjsLib.GlobalWorkerOptions.workerSrc = "../../node_modules/pdfjs-dist/build/pdf.worker.js";
|
|
pdfjsLib.GlobalWorkerOptions.workerSrc = "dist/pdf.worker.js";
|
|
|
|
// Some PDFs need external cmaps.
|
|
// var CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
|
|
var CMAP_URL = "dist/pdfjs-cmaps/"; // This cmap directory is automatically copied by webpack config from from node_modules into dist at build.
|
|
var CMAP_PACKED = true;
|
|
|
|
// var DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
|
var DEFAULT_URL = pdf_url;
|
|
var DEFAULT_SCALE = 1.0;
|
|
var CSS_UNITS = 96/72; // Fixed scale calculations by taking into account CSS units. https://github.com/mozilla/pdf.js/issues/5628#issuecomment-367399215
|
|
|
|
// Already passed into the function.
|
|
// var container = document.getElementById("pageContainer");
|
|
|
|
var eventBus = new pdfjsViewer.EventBus();
|
|
|
|
// AlternativeLoadNextPDFDocument - In case the current logic does not work out. See code at bottom of loadingTask.
|
|
// eventBus.on("pagesloaded", () => {
|
|
// console.log('pagesloaded');
|
|
// this.loadMultiplePDF( this.url_array, this.target );
|
|
// });
|
|
|
|
// Loading document.
|
|
var loadingTask = pdfjsLib.getDocument({
|
|
url: DEFAULT_URL,
|
|
cMapUrl: CMAP_URL,
|
|
cMapPacked: CMAP_PACKED,
|
|
});
|
|
|
|
// Most of this logic is taken from the pdfjs acroforms example at https://github.com/mozilla/pdf.js/blob/master/examples/acroforms/acroforms.js
|
|
|
|
loadingTask.promise.then((pdfDocument) => {
|
|
// Use a promise to fetch and render the next page.
|
|
var promise = Promise.resolve();
|
|
|
|
for (var i = 1; i <= pdfDocument.numPages; i++) {
|
|
promise = promise.then(function( pageNum ) {
|
|
|
|
// Document loaded, retrieving the page.
|
|
return pdfDocument.getPage( pageNum ).then(function (pdfPage) {
|
|
|
|
var available_space = container.clientWidth;
|
|
var desired_width = available_space - 10 - 5 - 20;// 10px: margin on row, 5px: margin-right on column. The extra 20px was trial and error, likely the scrollbar, which will vary on browser.
|
|
var viewport = pdfPage.getViewport({ scale: DEFAULT_SCALE });
|
|
var scaled_scale = desired_width / (viewport.width * CSS_UNITS); // Fixed scale calculations by taking into account CSS units. https://github.com/mozilla/pdf.js/issues/5628#issuecomment-367399215
|
|
// var scaled_viewport = pdfPage.getViewport({ scale: scaled_scale });
|
|
|
|
|
|
// Creating the page view with default parameters.
|
|
var pdfPageView = new pdfjsViewer.PDFPageView({
|
|
container: container,
|
|
id: pageNum,
|
|
// scale: SCALE,
|
|
scale: scaled_scale,
|
|
defaultViewport: pdfPage.getViewport({ scale: scaled_scale }),
|
|
eventBus: eventBus,
|
|
// We can enable text/annotations layers, if needed
|
|
textLayerFactory: new pdfjsViewer.DefaultTextLayerFactory(),
|
|
annotationLayerFactory: new pdfjsViewer.DefaultAnnotationLayerFactory(),
|
|
renderInteractiveForms: true, // inspired from the acroforms example at https://github.com/mozilla/pdf.js/tree/master/examples/acroforms - a quick one-line win, so might as well enable it.
|
|
});
|
|
// Associates the actual page with the view, and drawing it
|
|
pdfPageView.setPdfPage(pdfPage);
|
|
return pdfPageView.draw().then(() => {
|
|
$('.pdfContainer a').attr('target', '_blank'); // #2662 and #2819 Needed to open PDF links in a new window, rather than active. PDFJS documentation is lacking on how to do this properly. So this will change the link target to _blank for all the PDF docs on the page. For future attemps, I looked into LinkService, externalLinkTarget, and newWindow, but examples did not work for our solution.
|
|
});
|
|
});
|
|
}.bind(null, i) );
|
|
}
|
|
// Either load the next file here, or use the eventBus code, which is commented out further up. See AlternativeLoadNextPDFDocument
|
|
this.loadMultiplePDF( this.url_array, this.target );
|
|
});
|
|
|
|
}
|
|
}
|
|
|
|
window.TTPDFViewer = TTPDFViewer;
|