From e37ce8e937b3bd1a9bcd4006fbadb922e5dd6993 Mon Sep 17 00:00:00 2001 From: Rodrigo Vieira Date: Wed, 26 Apr 2017 23:32:00 -0400 Subject: [PATCH] refactored es6 modules --- dist/print.min.js | 2 +- package.json | 2 +- src/index.js | 6 +-- src/js/browser.js | 23 ++++----- src/js/class.js | 41 ---------------- src/js/functions.js | 48 ++++++++----------- src/js/html.js | 45 +++++++++--------- src/js/image.js | 38 ++++++++------- src/js/init.js | 104 +++++++++++++++++++++++++---------------- src/js/json.js | 77 +++++++++++++++--------------- src/js/modal.js | 60 ++++++++++++------------ src/js/params.js | 16 ------- src/js/pdf.js | 42 ++++++++--------- src/js/print.js | 111 +++++++++++++++++++++++--------------------- 14 files changed, 287 insertions(+), 328 deletions(-) delete mode 100644 src/js/class.js delete mode 100644 src/js/params.js diff --git a/dist/print.min.js b/dist/print.min.js index bf56fe6..36607f2 100644 --- a/dist/print.min.js +++ b/dist/print.min.js @@ -1 +1 @@ -!function(t){function e(r){if(i[r])return i[r].exports;var n=i[r]={i:r,l:!1,exports:{}};return t[r].call(n.exports,n,n.exports,e),n.l=!0,n.exports}var i={};e.m=t,e.c=i,e.i=function(t){return t},e.d=function(t,i,r){e.o(t,i)||Object.defineProperty(t,i,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(i,"a",i),i},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="./",e(e.s=11)}([function(t,e,i){"use strict";e.a={isFirefox:function(){return"undefined"!=typeof InstallTrigger},isIE:function(){return!!document.documentMode},isEdge:function(){return!this.isIE()&&!!window.StyleMedia},isChrome:function(){return!!window.chrome&&!!window.chrome.webstore},isSafari:function(){return Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0}}},function(t,e,i){"use strict";function r(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i]);return t}function n(t,e){return'
'+t+"
"}function a(t){return t.charAt(0).toUpperCase()+t.slice(1)}function o(t,e){var i=document.defaultView||window,r=[],n="";if(i.getComputedStyle){r=i.getComputedStyle(t,"");var a=["border","float","box","break","text-decoration"],o=["clear","display","width","min-width","height","min-height","max-height"];e.honorMarginPadding&&a.push("margin","padding"),e.honorColor&&a.push("color");for(var s=0;s")};e.a=n},function(t,e,i){"use strict";var r=i(1);e.a=function(t){t.prototype.html=function(){var t=document.getElementById(this.params.printable);if(!t)return window.console.error("Invalid HTML element id: "+this.params.printable),!1;var e=document.createElement("div");e.appendChild(t.cloneNode(!0)),e.setAttribute("style","display:none;"),e.setAttribute("id","printJS-html"),t.parentNode.appendChild(e),e=document.getElementById("printJS-html"),e.setAttribute("style",i.i(r.d)(e,this.params)+"margin:0 !important;");var n=e.children;i.i(r.e)(n,this.params),this.params.header&&i.i(r.f)(e,this.params.header),e.parentNode.removeChild(e),this.params.htmlData=i.i(r.b)(e.innerHTML,this.params),this.print()}}},function(t,e,i){"use strict";var r=i(1),n=i(0);e.a=function(t){t.prototype.image=function(){var t=document.createElement("img");t.setAttribute("style","width:100%;"),t.setAttribute("id","printableImage"),t.src=this.params.printable;var e=document.createElement("div");if(e.setAttribute("style","width:100%"),n.a.isFirefox()){var a=document.createElement("canvas");a.setAttribute("width",t.width),a.setAttribute("height",t.height);a.getContext("2d").drawImage(t,0,0),t.setAttribute("src",a.toDataURL("JPEG",1))}e.appendChild(t),this.params.header&&i.i(r.f)(e),this.params.htmlData=e.outerHTML,this.print()}}},function(t,e,i){"use strict";var r=i(0),n=i(1),a=i(3),o=i(9),s=i(4),d=i(5),p=i(7),l=i(10),c=i(8),m="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};i.i(o.a)(a.a),i.i(d.a)(a.a),i.i(s.a)(a.a),i.i(p.a)(a.a),i.i(l.a)(a.a),i.i(c.a)(a.a);var u=["pdf","html","image","json"],f={printable:null,type:"pdf",header:null,maxWidth:800,font:"TimesNewRoman",font_size:"12pt",honorMarginPadding:!0,honorColor:!1,properties:null,showModal:!1,modalMessage:"Retrieving Document...",frameId:"printJS",border:!0,htmlData:""};e.a={init:function(){var t=arguments[0];if(void 0===t)throw new Error("printJS expects at least 1 attribute.");var e=i.i(n.a)({},f);switch(void 0===t?"undefined":m(t)){case"string":e.printable=encodeURI(t),e.type=arguments[1]||f.type;break;case"object":e.printable=t.printable,e.type=t.type||f.type,e.frameId=t.frameId||f.frameId,e.header=t.header||f.header,e.maxWidth=t.maxWidth||f.maxWidth,e.font=t.font||f.font,e.font_size=t.font_size||f.font_size,e.honorMarginPadding=void 0!==t.honorMarginPadding?t.honorMarginPadding:f.honorMarginPadding,e.properties=t.properties||f.properties,e.showModal=void 0!==t.showModal?t.showModal:f.showModal,e.modalMessage=t.modalMessage||f.modalMessage;break;default:throw new Error('Unexpected argument type! Expected "string" or "object", got '+(void 0===t?"undefined":m(t)))}if(!e.printable)throw new Error("Missing printable information.");if(!e.type||"string"!=typeof e.type||-1===u.indexOf(e.type.toLowerCase()))throw new Error("Invalid print type. Available types are: pdf, html, image and json.");var o=new a.a(e);switch(e.type){case"pdf":if(r.a.isFirefox()){window.open(e.printable,"_blank").focus(),e.showModal&&o.disablePrintModal()}else o.pdf();break;case"image":o.image();break;case"html":o.html();break;case"json":o.json();break;default:throw new Error("Invalid print type. Available types are: pdf, html, image and json.")}}}},function(t,e,i){"use strict";var r=i(1),n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};e.a=function(t){t.prototype.json=function(){if("object"!==n(this.params.printable))throw new Error("Invalid javascript data object (JSON).");if(!this.params.properties||"object"!==n(this.params.properties))throw new Error("Invalid properties array for your JSON data.");var t="";this.params.header&&(t+='

'+this.params.header+"

"),t+=this.jsonToHTML(),this.params.htmlData=i.i(r.b)(t,this.params),this.print()},t.prototype.jsonToHTML=function(){var t=this.params.printable,e=this.params.properties,n='
';n+='
';for(var a=0;a'+i.i(r.c)(e[a].displayName||e[a])+"
";n+="
";for(var o=0;o'+t[o][e[s].field||e[s]]+"";n+=""}return n+=""}}},function(t,e,i){"use strict";e.a=function(t){t.prototype.showModal=function(){var t=document.createElement("div");t.setAttribute("style","font-family:sans-serif; display:table; text-align:center; font-weight:300; font-size:30px; left:0; top:0;position:fixed; z-index: 9990;color: #0460B5; width: 100%; height: 100%; background-color:rgba(255,255,255,.9);transition: opacity .3s ease;"),t.setAttribute("id","printJS-Modal");var e=document.createElement("div");e.setAttribute("style","display:table-cell; vertical-align:middle; padding-bottom:100px;");var i=document.createElement("div");i.setAttribute("class","printClose"),i.setAttribute("id","printClose"),e.appendChild(i);var r=document.createElement("span");r.setAttribute("class","printSpinner"),e.appendChild(r);var n=document.createTextNode(this.params.modalMessage);e.appendChild(n),t.appendChild(e),document.getElementsByTagName("body")[0].appendChild(t);var a=this;document.getElementById("printClose").addEventListener("click",function(){a.disablePrintModal()})},t.prototype.disablePrintModal=function(){var t=document.getElementById("printJS-Modal");t.parentNode.removeChild(t)}}},function(t,e,i){"use strict";var r=i(0);e.a=function(t){t.prototype.pdf=function(){if(this.params.showModal&&!r.a.isIE()){var t=document.createElement("img");t.src=this.params.printable;var e=new Promise(function(e,i){function r(){t.complete&&(window.clearInterval(n),e("PrintJS: PDF loaded. Read to this."))}var n=setInterval(r,100)}),i=this;e.then(function(t){i.printFrame.setAttribute("src",i.params.printable),i.print()})}else this.printFrame.setAttribute("src",this.params.printable),this.print()}}},function(t,e,i){"use strict";var r=i(0);e.a=function(t){t.prototype.print=function(){function t(){if(n.focus(),r.a.isIE()||r.a.isEdge())try{n.contentWindow.document.execCommand("print",!1,null)}catch(t){n.contentWindow.print()}else n.contentWindow.print();i.params.showModal&&i.disablePrintModal()}function e(){void 0===n.print?setTimeout(function(){e()},1e3):(n.print(),setTimeout(function(){n.parentNode.removeChild(n)},2e3))}var i=this;document.getElementsByTagName("body")[0].appendChild(this.printFrame);var n=document.getElementById(this.params.frameId);r.a.isIE()&&"pdf"===this.params.type?e():this.printFrame.onload=function(){if("pdf"===i.params.type)t();else{var e=n.contentWindow||n.contentDocument;e.document&&(e=e.document),e.body.innerHTML=i.params.htmlData,"image"===i.params.type&&r.a.isChrome()?e.getElementById("printableImage").onload=function(){t()}:t()}}}}},function(t,e,i){t.exports=i(2)}]); \ No newline at end of file +!function(e){function t(i){if(n[i])return n[i].exports;var r=n[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="./",t(t.s=10)}([function(e,t,n){"use strict";var i={isFirefox:function(){return"undefined"!=typeof InstallTrigger},isIE:function(){return!!document.documentMode},isEdge:function(){return!i.isIE()&&!!window.StyleMedia},isChrome:function(){return!!window.chrome&&!!window.chrome.webstore},isSafari:function(){return Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0}};t.a=i},function(e,t,n){"use strict";function i(e,t){if(e.focus(),o.a.isIE()||o.a.isEdge())try{e.contentWindow.document.execCommand("print",!1,null)}catch(t){e.contentWindow.print()}else e.contentWindow.print();t.showModal&&a.a.close()}function r(e){void 0===e.print?setTimeout(function(){r()},1e3):(d.send(),setTimeout(function(){e.parentNode.removeChild(e)},2e3))}var o=n(0),a=n(3),d={send:function(e,t){document.getElementsByTagName("body")[0].appendChild(t);var n=document.getElementById(e.frameId);o.a.isIE()&&"pdf"===e.type?r(n):t.onload=function(){if("pdf"===e.type)i(n,e);else{var t=n.contentWindow||n.contentDocument;t.document&&(t=t.document),t.body.innerHTML=e.htmlData,"image"===e.type?t.getElementById("printableImage").onload=function(){i(n,e)}:i(n,e)}}}};t.a=d},function(e,t,n){"use strict";function i(e,t){return'
'+e+"
"}function r(e){return e.charAt(0).toUpperCase()+e.slice(1)}function o(e,t){var n=document.defaultView||window,i=[],r="";if(n.getComputedStyle){i=n.getComputedStyle(e,"");var o=["border","float","box","break","text-decoration"],a=["clear","display","width","min-width","height","min-height","max-height"];t.honorMarginPadding&&o.push("margin","padding"),t.honorColor&&o.push("color");for(var d=0;d"),p.type){case"pdf":if(i.a.isFirefox()){window.open(p.printable,"_blank").focus(),p.showModal&&r.a.close()}else o.a.print(p,n);break;case"image":d.a.print(p,n);break;case"html":a.a.print(p,n);break;case"json":l.a.print(p,n);break;default:throw new Error("Invalid print type. Available types are: pdf, html, image and json.")}}}},function(e,t,n){"use strict";function i(e){var t=e.printable,i=e.properties,o='
';o+='
';for(var a=0;a'+n.i(r.b)(i[a].displayName||i[a])+"
";o+="
";for(var d=0;d'+t[d][i[l].field||i[l]]+"";o+=""}return o+=""}var r=n(2),o=n(1),a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};t.a={print:function(e,t){if("object"!==a(e.printable))throw new Error("Invalid javascript data object (JSON).");if(!e.properties||"object"!==a(e.properties))throw new Error("Invalid properties array for your JSON data.");var d="";e.header&&(d+='

'+e.header+"

"),d+=i(e),e.htmlData=n.i(r.a)(d,e),o.a.send(e,t)}}},function(e,t,n){"use strict";function i(e,t){t.setAttribute("src",e.printable),o.a.send(e,t)}var r=n(0),o=n(1);t.a={print:function(e,t){if(e.showModal&&!r.a.isIE()){var n=document.createElement("img");n.src=e.printable;new Promise(function(e,t){function i(){n.complete&&(window.clearInterval(r),e("PrintJS: PDF loaded."))}var r=setInterval(i,100)}).then(function(n){i(e,t)})}else i(e,t)}}},function(e,t,n){e.exports=n(4)}]); \ No newline at end of file diff --git a/package.json b/package.json index 8ebb8d7..0bf0f2d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "print.js", "homepage": "http://printjs.crabbly.com", "description": "A tiny javascript library to help printing from the web.", - "version": "1.0.16", + "version": "1.0.17", "main": "src/print.js", "repository": { "type": "git", diff --git a/src/index.js b/src/index.js index c3631a3..2ef9d61 100644 --- a/src/index.js +++ b/src/index.js @@ -1,9 +1,9 @@ import print from './js/init' -const printJS = print.init +const printjs = print.init if (typeof window !== 'undefined') { - window.printJS = printJS + window.printjs = printjs } -export default printJS +export default printjs diff --git a/src/js/browser.js b/src/js/browser.js index 4a6955a..92c6bf9 100644 --- a/src/js/browser.js +++ b/src/js/browser.js @@ -1,29 +1,24 @@ -export default { +const Browser = { // Firefox 1.0+ - isFirefox: function () { + isFirefox: () => { return typeof InstallTrigger !== 'undefined' }, - // Internet Explorer 6-11 - isIE: function () { + isIE: () => { return !!document.documentMode }, - // Edge 20+ - isEdge: function () { - return !this.isIE() && !!window.StyleMedia + isEdge: () => { + return !Browser.isIE() && !!window.StyleMedia }, - // Chrome 1+ - isChrome: function () { + isChrome: () => { return !!window.chrome && !!window.chrome.webstore }, - - // Opera 8.0+ - // let isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0 - // At least Safari 3+: "[object HTMLElementConstructor]" - isSafari: function () { + isSafari: () => { return Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0 } } + +export default Browser diff --git a/src/js/class.js b/src/js/class.js deleted file mode 100644 index d75879a..0000000 --- a/src/js/class.js +++ /dev/null @@ -1,41 +0,0 @@ -import browser from './browser' - -let PrintJS = function (params) { - this.params = params - - // check if showing feedback to user (useful for large files) - if (this.params.showModal) { - this.showModal() - } - - // to prevent duplication and issues, remove this.printFrame from DOM, if it exists - let usedFrame = document.getElementById(this.params.frameId) - - if (usedFrame) { - usedFrame.parentNode.removeChild(usedFrame) - } - - // create a new iframe or embed element (IE prints blank pdf's if we use iframe) - if (browser.isIE() && this.params.type === 'pdf') { - // create embed element - this.printFrame = document.createElement('embed') - this.printFrame.setAttribute('type', 'application/pdf') - - // hide embed - this.printFrame.setAttribute('style', 'width:0px;height:0px;') - } else { - // create iframe element - this.printFrame = document.createElement('iframe') - - // hide iframe - this.printFrame.setAttribute('style', 'display:none;') - } - - // set element id - this.printFrame.setAttribute('id', this.params.frameId) - - // for non pdf printing, pass empty html document to srcdoc (force onload callback) - if (this.params.type !== 'pdf') this.printFrame.srcdoc = '' -} - -export default PrintJS diff --git a/src/js/functions.js b/src/js/functions.js index 90b857f..da1c7cb 100644 --- a/src/js/functions.js +++ b/src/js/functions.js @@ -1,13 +1,3 @@ -export function extend (a, b) { - for (let key in b) { - if (b.hasOwnProperty(key)) { - a[key] = b[key] - } - } - - return a -} - export function addWrapper (htmlData, params) { let bodyStyle = 'font-family:' + params.font + ' !important; font-size: ' + params.font_size + ' !important; width:100%;' return '
' + htmlData + '
' @@ -22,24 +12,24 @@ export function collectStyles (element, params) { let style = [] - // String variable to hold styling for each element + // String variable to hold styling for each element let elementStyle = '' if (win.getComputedStyle) { // modern browsers style = win.getComputedStyle(element, '') - // Styles including + // Styles including let targetStyles = ['border', 'float', 'box', 'break', 'text-decoration'] - // Exact match + // Exact match let targetStyle = ['clear', 'display', 'width', 'min-width', 'height', 'min-height', 'max-height'] - // Optional - include margin and padding + // Optional - include margin and padding if (params.honorMarginPadding) { targetStyles.push('margin', 'padding') } - // Optional - include color + // Optional - include color if (params.honorColor) { targetStyles.push('color') } @@ -61,7 +51,7 @@ export function collectStyles (element, params) { } } - // Print friendly defaults + // Print friendly defaults elementStyle += 'max-width: ' + params.maxWidth + 'px !important;' + params.font_size + ' !important;' return elementStyle @@ -71,38 +61,38 @@ export function loopNodesCollectStyles (elements, params) { for (let n = 0; n < elements.length; n++) { let currentElement = elements[n] - // Form Printing - check if is element Input + // Form Printing - check if is element Input let tag = currentElement.tagName if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') { - // save style to variable + // Save style to variable let textStyle = collectStyles(currentElement, params) - // remove INPUT element and insert a text node + // Remove INPUT element and insert a text node let parent = currentElement.parentNode - // get text value + // Get text value let textNode = tag === 'SELECT' ? document.createTextNode(currentElement.options[currentElement.selectedIndex].text) : document.createTextNode(currentElement.value) - // create text element + // Create text element let textElement = document.createElement('div') textElement.appendChild(textNode) - // add style to text + // Add style to text textElement.setAttribute('style', textStyle) - // add text + // Add text parent.appendChild(textElement) - // remove input + // Remove input parent.removeChild(currentElement) } else { - // get all styling for print element + // Get all styling for print element currentElement.setAttribute('style', collectStyles(currentElement, params)) } - // check if more elements in tree + // Check if more elements in tree let children = currentElement.children if (children && children.length) { @@ -112,13 +102,13 @@ export function loopNodesCollectStyles (elements, params) { } export function addHeader (printElement, header) { - // create header element + // Create header element let headerElement = document.createElement('h1') - // create header text node + // Create header text node let headerNode = document.createTextNode(header) - // build and style + // Build and style headerElement.appendChild(headerNode) headerElement.setAttribute('style', 'font-weight:300;') diff --git a/src/js/html.js b/src/js/html.js index e5b5dac..4316c48 100644 --- a/src/js/html.js +++ b/src/js/html.js @@ -1,50 +1,51 @@ import { collectStyles, loopNodesCollectStyles, addWrapper, addHeader } from './functions' +import Print from './print' -export default function (PrintJS) { - PrintJS.prototype.html = function () { - // get HTML printable element - let printElement = document.getElementById(this.params.printable) +export default { + print: (params, printFrame) => { + // Get HTML printable element + let printElement = document.getElementById(params.printable) - // check if element exists + // Check if element exists if (!printElement) { - window.console.error('Invalid HTML element id: ' + this.params.printable) + window.console.error('Invalid HTML element id: ' + params.printable) return false } - // make a copy of the printElement to prevent DOM changes + // Make a copy of the printElement to prevent DOM changes let printableElement = document.createElement('div') printableElement.appendChild(printElement.cloneNode(true)) - // add cloned element to DOM, to have DOM element methods available. It will also be easier to colect styles + // Add cloned element to DOM, to have DOM element methods available. It will also be easier to colect styles printableElement.setAttribute('style', 'display:none;') printableElement.setAttribute('id', 'printJS-html') printElement.parentNode.appendChild(printableElement) - // update printableElement variable with newly created DOM element + // Update printableElement variable with newly created DOM element printableElement = document.getElementById('printJS-html') - // get main element styling - printableElement.setAttribute('style', collectStyles(printableElement, this.params) + 'margin:0 !important;') + // Get main element styling + printableElement.setAttribute('style', collectStyles(printableElement, params) + 'margin:0 !important;') - // get all children elements + // Get all children elements let elements = printableElement.children - // get styles for all children elements - loopNodesCollectStyles(elements, this.params) + // Get styles for all children elements + loopNodesCollectStyles(elements, params) - // add header if any - if (this.params.header) { - addHeader(printableElement, this.params.header) + // Add header if any + if (params.header) { + addHeader(printableElement, params.header) } - // remove DOM printableElement + // Remove DOM printableElement printableElement.parentNode.removeChild(printableElement) - // store html data - this.params.htmlData = addWrapper(printableElement.innerHTML, this.params) + // Store html data + params.htmlData = addWrapper(printableElement.innerHTML, params) - // print html element contents - this.print() + // Print html element contents + Print.send(params, printFrame) } } diff --git a/src/js/image.js b/src/js/image.js index 052ddb8..efd8863 100644 --- a/src/js/image.js +++ b/src/js/image.js @@ -1,44 +1,46 @@ import { addHeader } from './functions' -import browser from './browser' +import Browser from './browser' +import Print from './print' -export default function (PrintJS) { - PrintJS.prototype.image = function () { - // create the image element +export default { + print: (params, printFrame) => { + // Create the image element let img = document.createElement('img') + + // Set image src with image file url + img.src = params.printable + img.setAttribute('style', 'width:100%;') img.setAttribute('id', 'printableImage') - // set image src with image file url - img.src = this.params.printable - - // create wrapper + // Create wrapper let printableElement = document.createElement('div') printableElement.setAttribute('style', 'width:100%') - // to prevent firefox from not loading images within iframe, we can use base64-encoded data URL of images pixel data - if (browser.isFirefox()) { - // let's make firefox happy + // To prevent firefox from not loading images within iframe, we can use base64-encoded data URL of images pixel data + if (Browser.isFirefox()) { + // Let's make firefox happy let canvas = document.createElement('canvas') canvas.setAttribute('width', img.width) canvas.setAttribute('height', img.height) let context = canvas.getContext('2d') context.drawImage(img, 0, 0) - // reset img src attribute with canvas dataURL + // Reset img src attribute with canvas dataURL img.setAttribute('src', canvas.toDataURL('JPEG', 1.0)) } printableElement.appendChild(img) - // add header if any - if (this.params.header) { + // Check if we are adding a header for the image + if (params.header) { addHeader(printableElement) } - // store html data - this.params.htmlData = printableElement.outerHTML + // Store html data + params.htmlData = printableElement.outerHTML - // print image - this.print() + // Print image + Print.send(params, printFrame) } } diff --git a/src/js/init.js b/src/js/init.js index 4727f84..808f7d3 100644 --- a/src/js/init.js +++ b/src/js/init.js @@ -1,24 +1,15 @@ 'use strict' -import browser from './browser' -import { extend } from './functions' -import PrintJS from './class' -import pdf from './pdf' -import html from './html' -import image from './image' -import json from './json' -import print from './print' -import modal from './modal' -pdf(PrintJS) -image(PrintJS) -html(PrintJS) -json(PrintJS) -print(PrintJS) -modal(PrintJS) +import Browser from './browser' +import Modal from './modal' +import Pdf from './pdf' +import Html from './html' +import Image from './image' +import Json from './json' let printTypes = ['pdf', 'html', 'image', 'json'] -let defaultParams = { +let params = { printable: null, type: 'pdf', header: null, @@ -37,32 +28,30 @@ let defaultParams = { export default { init () { - // Check if a printable document or object was supplied + // Check if a printable document or object was supplied let args = arguments[0] if (args === undefined) { throw new Error('printJS expects at least 1 attribute.') } - let params = extend({}, defaultParams) - switch (typeof args) { case 'string': params.printable = encodeURI(args) - params.type = arguments[1] || defaultParams.type + params.type = arguments[1] || params.type break case 'object': params.printable = args.printable - params.type = args.type || defaultParams.type - params.frameId = args.frameId || defaultParams.frameId - params.header = args.header || defaultParams.header - params.maxWidth = args.maxWidth || defaultParams.maxWidth - params.font = args.font || defaultParams.font - params.font_size = args.font_size || defaultParams.font_size - params.honorMarginPadding = (typeof args.honorMarginPadding !== 'undefined') ? args.honorMarginPadding : defaultParams.honorMarginPadding - params.properties = args.properties || defaultParams.properties - params.showModal = (typeof args.showModal !== 'undefined') ? args.showModal : defaultParams.showModal - params.modalMessage = args.modalMessage || defaultParams.modalMessage + params.type = args.type || params.type + params.frameId = args.frameId || params.frameId + params.header = (typeof args.header !== 'undefined') ? args.header : params.header + params.maxWidth = args.maxWidth || params.maxWidth + params.font = args.font || params.font + params.font_size = args.font_size || params.font_size + params.honorMarginPadding = (typeof args.honorMarginPadding !== 'undefined') ? args.honorMarginPadding : params.honorMarginPadding + params.properties = args.properties || params.properties + params.showModal = (typeof args.showModal !== 'undefined') ? args.showModal : params.showModal + params.modalMessage = (typeof args.modalMessage !== 'undefined') ? args.modalMessage : params.modalMessage break default: @@ -77,31 +66,64 @@ export default { throw new Error('Invalid print type. Available types are: pdf, html, image and json.') } - // Instantiate print object - let printJS = new PrintJS(params) + // Check if we are showing a feedback message to the user (useful for large files) + if (params.showModal) { + Modal.show(params) + } + + // To prevent duplication and issues, remove printFrame from the DOM, if it exists + let usedFrame = document.getElementById(params.frameId) + + if (usedFrame) { + usedFrame.parentNode.removeChild(usedFrame) + } + + // Create a new iframe or embed element (IE prints blank pdf's if we use iframe) + let printFrame + + if (Browser.isIE() && params.type === 'pdf') { + // Create embed element + printFrame = document.createElement('embed') + printFrame.setAttribute('type', 'application/pdf') + + // Hide embed + printFrame.setAttribute('style', 'width:0px;height:0px;') + } else { + // Create iframe element + printFrame = document.createElement('iframe') + + // Hide iframe + printFrame.setAttribute('style', 'display:none;') + } + + // Set element id + printFrame.setAttribute('id', params.frameId) + + // For non pdf printing, pass an empty html document to srcdoc (force onload callback) + if (params.type !== 'pdf') printFrame.srcdoc = '' - // Check printable type + // Check printable type switch (params.type) { case 'pdf': - // Firefox doesn't support iframe pdf printing, we will just open the pdf file instead - if (browser.isFirefox()) { + // Firefox doesn't support iframe pdf printing, we will just open the pdf file instead + if (Browser.isFirefox()) { console.log('PrintJS doesn\'t support PDF printing in Firefox.') let win = window.open(params.printable, '_blank') win.focus() - // Make sure there is no loading modal opened - if (params.showModal) printJS.disablePrintModal() + // Make sure there is no loading modal opened + if (params.showModal) Modal.close() } else { - printJS.pdf() + Pdf.print(params, printFrame) } break case 'image': - printJS.image() + Image.print(params, printFrame) break case 'html': - printJS.html() + Html.print(params, printFrame) break case 'json': - printJS.json() + Json.print(params, printFrame) break default: throw new Error('Invalid print type. Available types are: pdf, html, image and json.') diff --git a/src/js/json.js b/src/js/json.js index d53e483..01acbf8 100644 --- a/src/js/json.js +++ b/src/js/json.js @@ -1,65 +1,66 @@ import { addWrapper, capitalizePrint } from './functions' +import Print from './print' -export default function (PrintJS) { - PrintJS.prototype.json = function () { - // check if we received proper data - if (typeof this.params.printable !== 'object') { +export default { + print: (params, printFrame) => { + // Check if we received proper data + if (typeof params.printable !== 'object') { throw new Error('Invalid javascript data object (JSON).') } - // Check if properties were provided - if (!this.params.properties || typeof this.params.properties !== 'object') { + // Check if properties were provided + if (!params.properties || typeof params.properties !== 'object') { throw new Error('Invalid properties array for your JSON data.') } - // Variable to hold html string + // Variable to hold html string let htmlData = '' - // Check print has header - if (this.params.header) { - htmlData += '

' + this.params.header + '

' + // Check print has header + if (params.header) { + htmlData += '

' + params.header + '

' } - // Function to build html templates for json data - htmlData += this.jsonToHTML() + // Function to build html templates for json data + htmlData += jsonToHTML(params) - // Store html data - this.params.htmlData = addWrapper(htmlData, this.params) + // Store html data + params.htmlData = addWrapper(htmlData, params) - // Print json data - this.print() + // Print json data + Print.send(params, printFrame) } +} - PrintJS.prototype.jsonToHTML = function () { - let data = this.params.printable - let properties = this.params.properties - - let htmlData = '
' +function jsonToHTML (params) { + let data = params.printable + let properties = params.properties - // Header - htmlData += '
' + let htmlData = '
' - for (let a = 0; a < properties.length; a++) { - htmlData += '
' + capitalizePrint(properties[a]['displayName'] || properties[a]) + '
' - } + // Header + htmlData += '
' - htmlData += '
' + for (let a = 0; a < properties.length; a++) { + htmlData += '
' + capitalizePrint(properties[a]['displayName'] || properties[a]) + '
' + } - // Create html data - for (let i = 0; i < data.length; i++) { - htmlData += '
' + htmlData += '
' - for (let n = 0; n < properties.length; n++) { - htmlData += '
' + data[i][properties[n]['field'] || properties[n]] + '
' - } + // Create html data + for (let i = 0; i < data.length; i++) { + htmlData += '
' - htmlData += '
' + for (let n = 0; n < properties.length; n++) { + htmlData += '
' + data[i][properties[n]['field'] || properties[n]] + '
' } htmlData += '
' - - return htmlData } + + htmlData += '
' + + return htmlData } diff --git a/src/js/modal.js b/src/js/modal.js index 6f97c2c..8d0863d 100644 --- a/src/js/modal.js +++ b/src/js/modal.js @@ -1,60 +1,60 @@ -export default function (PrintJS) { - PrintJS.prototype.showModal = function () { - // build modal +const Modal = { + show (params) { + // Build modal let modalStyle = 'font-family:sans-serif; ' + - 'display:table; ' + - 'text-align:center; ' + - 'font-weight:300; ' + - 'font-size:30px; ' + - 'left:0; top:0;' + - 'position:fixed; ' + - 'z-index: 9990;' + - 'color: #0460B5; ' + - 'width: 100%; ' + - 'height: 100%; ' + - 'background-color:rgba(255,255,255,.9);' + - 'transition: opacity .3s ease;' - - // create wrapper + 'display:table; ' + + 'text-align:center; ' + + 'font-weight:300; ' + + 'font-size:30px; ' + + 'left:0; top:0;' + + 'position:fixed; ' + + 'z-index: 9990;' + + 'color: #0460B5; ' + + 'width: 100%; ' + + 'height: 100%; ' + + 'background-color:rgba(255,255,255,.9);' + + 'transition: opacity .3s ease;' + + // Create wrapper let printModal = document.createElement('div') printModal.setAttribute('style', modalStyle) printModal.setAttribute('id', 'printJS-Modal') - // create content div + // Create content div let contentDiv = document.createElement('div') contentDiv.setAttribute('style', 'display:table-cell; vertical-align:middle; padding-bottom:100px;') - // add close button (requires this.css) + // Add close button (requires print.css) let closeButton = document.createElement('div') closeButton.setAttribute('class', 'printClose') closeButton.setAttribute('id', 'printClose') contentDiv.appendChild(closeButton) - // add spinner (requires this.css) + // Add spinner (requires print.css) let spinner = document.createElement('span') spinner.setAttribute('class', 'printSpinner') contentDiv.appendChild(spinner) - // add message - let messageNode = document.createTextNode(this.params.modalMessage) + // Add message + let messageNode = document.createTextNode(params.modalMessage) contentDiv.appendChild(messageNode) - // add contentDiv to printModal + // Add contentDiv to printModal printModal.appendChild(contentDiv) - // append print modal element to document body + // Append print modal element to document body document.getElementsByTagName('body')[0].appendChild(printModal) - // add event listener to close button - let self = this + // Add event listener to close button document.getElementById('printClose').addEventListener('click', function () { - self.disablePrintModal() + Modal.close() }) - } - - PrintJS.prototype.disablePrintModal = function () { + }, + close () { let printFrame = document.getElementById('printJS-Modal') printFrame.parentNode.removeChild(printFrame) } } + +export default Modal diff --git a/src/js/params.js b/src/js/params.js deleted file mode 100644 index a3e68c9..0000000 --- a/src/js/params.js +++ /dev/null @@ -1,16 +0,0 @@ -export default { - printable: null, - type: 'pdf', - header: null, - maxWidth: 800, - font: 'TimesNewRoman', - font_size: '12pt', - honorMarginPadding: true, - honorColor: false, - properties: null, - showModal: false, - modalMessage: 'Retrieving Document...', - frameId: 'printJS', - border: true, - htmlData: '' -} diff --git a/src/js/pdf.js b/src/js/pdf.js index c5394a5..9ed1c50 100644 --- a/src/js/pdf.js +++ b/src/js/pdf.js @@ -1,38 +1,38 @@ -import browser from './browser' +import Browser from './browser' +import Print from './print' -export default function (PrintJS) { - PrintJS.prototype.pdf = function () { - // if showing feedback to user, pre load pdf files (hacky) - // since we will be using promises, we can't use this feature in IE - if (this.params.showModal && !browser.isIE()) { +export default { + print: (params, printFrame) => { + // If showing feedback to user, pre load pdf files (hacky) + // Since we will be using promises, we can't use this feature in IE + if (params.showModal && !Browser.isIE()) { let pdfObject = document.createElement('img') - pdfObject.src = this.params.printable + pdfObject.src = params.printable - let pdf = new Promise(function (resolve, reject) { + let pdf = new Promise((resolve, reject) => { let loadPDF = setInterval(checkPDFload, 100) function checkPDFload () { if (pdfObject.complete) { window.clearInterval(loadPDF) - resolve('PrintJS: PDF loaded. Read to this.') + resolve('PrintJS: PDF loaded.') } } }) - let self = this - pdf.then(function (result) { - // set iframe src with pdf document url - self.printFrame.setAttribute('src', self.params.printable) - - // print pdf document - self.print() + pdf.then(result => { + send(params, printFrame) }) } else { - // set iframe src with pdf document url - this.printFrame.setAttribute('src', this.params.printable) - - // print pdf - this.print() + send(params, printFrame) } } } + +function send (params, printFrame) { + // Set iframe src with pdf document url + printFrame.setAttribute('src', params.printable) + + // Print pdf document + Print.send(params, printFrame) +} diff --git a/src/js/print.js b/src/js/print.js index 0cc7834..8d57156 100644 --- a/src/js/print.js +++ b/src/js/print.js @@ -1,74 +1,79 @@ -import browser from './browser' +import Browser from './browser' +import Modal from './modal' -export default function (PrintJS) { - PrintJS.prototype.print = function () { - let self = this +const Print = { + send: (params, printFrame) => { + // Append iframe element to document body + document.getElementsByTagName('body')[0].appendChild(printFrame) - // append iframe element to document body - document.getElementsByTagName('body')[0].appendChild(this.printFrame) + // Get iframe element + let iframeElement = document.getElementById(params.frameId) - // get iframe element - let printJS = document.getElementById(this.params.frameId) - - // if printing pdf in IE - if (browser.isIE() && this.params.type === 'pdf') { - finishPrintPdfIe() + // If printing pdf in IE + if (Browser.isIE() && params.type === 'pdf') { + finishPrintPdfIe(iframeElement) } else { - // wait for iframe to load all content - this.printFrame.onload = function () { - if (self.params.type === 'pdf') { - finishPrint() + // Wait for iframe to load all content + printFrame.onload = () => { + if (params.type === 'pdf') { + finishPrint(iframeElement, params) } else { - // get iframe element document - let printDocument = (printJS.contentWindow || printJS.contentDocument) + // Get iframe element document + let printDocument = (iframeElement.contentWindow || iframeElement.contentDocument) if (printDocument.document) printDocument = printDocument.document - // inject printable html into iframe body - printDocument.body.innerHTML = self.params.htmlData + // Inject printable html into iframe body + printDocument.body.innerHTML = params.htmlData - // wait for image to load inside iframe (chrome only) - if (self.params.type === 'image' && browser.isChrome()) { - printDocument.getElementById('printableImage').onload = function () { - finishPrint() + // If printing image, wait for it to load inside theiframe + if (params.type === 'image') { + printDocument.getElementById('printableImage').onload = () => { + finishPrint(iframeElement, params) } } else { - finishPrint() + finishPrint(iframeElement, params) } } } } + } +} - function finishPrint () { - // print iframe document - printJS.focus() - - // if IE or Edge, try catch with execCommand - if (browser.isIE() || browser.isEdge()) { - try { - printJS.contentWindow.document.execCommand('print', false, null) - } catch (e) { - printJS.contentWindow.print() - } - } else { - printJS.contentWindow.print() - } +function finishPrint (iframeElement, params) { + // Print iframe document + iframeElement.focus() - // if showing feedback to user, close modal (printing / processing message) - if (self.params.showModal) { - self.disablePrintModal() - } + // If IE or Edge, try catch with execCommand + if (Browser.isIE() || Browser.isEdge()) { + try { + iframeElement.contentWindow.document.execCommand('print', false, null) + } catch (e) { + iframeElement.contentWindow.print() } + } else { + iframeElement.contentWindow.print() + } - function finishPrintPdfIe () { - // wait until pdf is ready to print - if (typeof printJS.print === 'undefined') { - setTimeout(function () { finishPrintPdfIe() }, 1000) - } else { - printJS.print() + // If we are showing a feedback message to user, remove it + if (params.showModal) { + Modal.close() + } +} - // remove embed (just because it isn't 100% hidden when using h/w = 0) - setTimeout(function () { printJS.parentNode.removeChild(printJS) }, 2000) - } - } +function finishPrintPdfIe (iframeElement) { + // Wait until pdf is ready to print + if (typeof iframeElement.print === 'undefined') { + setTimeout(() => { + finishPrintPdfIe() + }, 1000) + } else { + Print.send() + + // Remove embed (just because it isn't 100% hidden when using h/w = 0) + setTimeout(() => { + iframeElement.parentNode.removeChild(iframeElement) + }, 2000) } } + +export default Print