'use strict'; var isFunction = require('../helpers').isFunction; var isUndefined = require('../helpers').isUndefined; var isNull = require('../helpers').isNull; var FileSaver = require('file-saver'); var saveAs = FileSaver.saveAs; var defaultClientFonts = { Roboto: { normal: 'Roboto-Regular.ttf', bold: 'Roboto-Medium.ttf', italics: 'Roboto-Italic.ttf', bolditalics: 'Roboto-MediumItalic.ttf' } }; function Document(docDefinition, tableLayouts, fonts, vfs) { this.docDefinition = docDefinition; this.tableLayouts = tableLayouts || null; this.fonts = fonts || defaultClientFonts; this.vfs = vfs; } function canCreatePdf() { // Ensure the browser provides the level of support needed if (!Object.keys || typeof Uint16Array === 'undefined') { return false; } return true; } Document.prototype._createDoc = function (options) { options = options || {}; if (this.tableLayouts) { options.tableLayouts = this.tableLayouts; } var PdfPrinter = require('../printer'); var printer = new PdfPrinter(this.fonts); require('fs').bindFS(this.vfs); // bind virtual file system to file system var doc = printer.createPdfKitDocument(this.docDefinition, options); return doc; }; Document.prototype._flushDoc = function (doc, callback) { var chunks = []; var result; doc.on('readable', function () { var chunk; while ((chunk = doc.read(9007199254740991)) !== null) { chunks.push(chunk); } }); doc.on('end', function () { result = Buffer.concat(chunks); callback(result, doc._pdfMakePages); }); doc.end(); }; Document.prototype._getPages = function (options, cb) { if (!cb) { throw '_getPages is an async method and needs a callback argument'; } var doc = this._createDoc(options); this._flushDoc(doc, function (ignoreBuffer, pages) { cb(pages); }); }; Document.prototype._bufferToBlob = function (buffer) { var blob; try { blob = new Blob([buffer], { type: 'application/pdf' }); } catch (e) { // Old browser which can't handle it without making it an byte array (ie10) if (e.name === 'InvalidStateError') { var byteArray = new Uint8Array(buffer); blob = new Blob([byteArray.buffer], { type: 'application/pdf' }); } } if (!blob) { throw 'Could not generate blob'; } return blob; }; Document.prototype._openWindow = function () { // we have to open the window immediately and store the reference // otherwise popup blockers will stop us var win = window.open('', '_blank'); if (win === null) { throw 'Open PDF in new window blocked by browser'; } return win; }; Document.prototype._openPdf = function (options, win) { if (!win) { win = this._openWindow(); } try { this.getBlob(function (result) { var urlCreator = window.URL || window.webkitURL; var pdfUrl = urlCreator.createObjectURL(result); win.location.href = pdfUrl; /* temporarily disabled if (win !== window) { setTimeout(function () { if (isNull(win.window)) { // is closed by AdBlock window.location.href = pdfUrl; // open in actual window } }, 500); } */ }, options); } catch (e) { win.close(); throw e; } }; Document.prototype.open = function (options, win) { options = options || {}; options.autoPrint = false; win = win || null; this._openPdf(options, win); }; Document.prototype.print = function (options, win) { options = options || {}; options.autoPrint = true; win = win || null; this._openPdf(options, win); }; /** * download(defaultFileName = 'file.pdf', cb = null, options = {}) * or * download(cb, options = {}) */ Document.prototype.download = function (defaultFileName, cb, options) { if (isFunction(defaultFileName)) { if (!isUndefined(cb)) { options = cb; } cb = defaultFileName; defaultFileName = null; } defaultFileName = defaultFileName || 'file.pdf'; this.getBlob(function (result) { saveAs(result, defaultFileName); if (isFunction(cb)) { cb(); } }, options); }; Document.prototype.getBase64 = function (cb, options) { if (!cb) { throw 'getBase64 is an async method and needs a callback argument'; } this.getBuffer(function (buffer) { cb(buffer.toString('base64')); }, options); }; Document.prototype.getDataUrl = function (cb, options) { if (!cb) { throw 'getDataUrl is an async method and needs a callback argument'; } this.getBuffer(function (buffer) { cb('data:application/pdf;base64,' + buffer.toString('base64')); }, options); }; Document.prototype.getBlob = function (cb, options) { if (!cb) { throw 'getBlob is an async method and needs a callback argument'; } var that = this; this.getBuffer(function (result) { var blob = that._bufferToBlob(result); cb(blob); }, options); }; Document.prototype.getBuffer = function (cb, options) { if (!cb) { throw 'getBuffer is an async method and needs a callback argument'; } var doc = this._createDoc(options); this._flushDoc(doc, function (buffer) { cb(buffer); }); }; Document.prototype.getStream = function (options) { var doc = this._createDoc(options); return doc; }; module.exports = { createPdf: function (docDefinition, tableLayouts, fonts, vfs) { if (!canCreatePdf()) { throw 'Your browser does not provide the level of support needed'; } return new Document( docDefinition, tableLayouts || global.pdfMake.tableLayouts, fonts || global.pdfMake.fonts, vfs || global.pdfMake.vfs ); } };