From 26313386552123e46e4492fa0aabf5562da99309 Mon Sep 17 00:00:00 2001 From: Rodrigo Vieira Date: Thu, 23 May 2019 13:39:12 -0400 Subject: [PATCH 1/5] Add custom html deep clone function --- src/js/functions.js | 2 +- src/js/html.js | 52 +++++++++++++++++++++++++++++++++++++----- test/manual/index.html | 2 +- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/js/functions.js b/src/js/functions.js index b2360dc..d2b10ba 100644 --- a/src/js/functions.js +++ b/src/js/functions.js @@ -80,7 +80,7 @@ export function loopNodesCollectStyles (elements, params) { currentElement.setAttribute('style', collectStyles(currentElement, params)) } - // Check if more elements in tree + // Check if we have more elements in the tree let children = currentElement.children if (children && children.length) { diff --git a/src/js/html.js b/src/js/html.js index 698a68d..8e846bd 100644 --- a/src/js/html.js +++ b/src/js/html.js @@ -3,19 +3,18 @@ import Print from './print' export default { print: (params, printFrame) => { - // Get HTML printable element + // Get the DOM printable element let printElement = document.getElementById(params.printable) - // Check if element exists + // Check if the element exists if (!printElement) { window.console.error('Invalid HTML element id: ' + params.printable) - - return false + return } - // Make a copy of the printElement to prevent DOM changes + // Clone the target element including its children (if any) into a div container / wrapper let printableElement = document.createElement('div') - printableElement.appendChild(printElement.cloneNode(true)) + printableElement.appendChild(cloneElement(printElement, params)) // Add cloned element to DOM, to have DOM element methods available. It will also be easier to colect styles printableElement.setAttribute('style', 'height:0; overflow:hidden;') @@ -58,3 +57,44 @@ export default { Print.send(params, printFrame) } } + +function cloneElement (element, params) { + // Clone the main node (if not already inside the recursion process) + const clone = element.cloneNode() + + // Loop over and process the children elements / nodes (including text nodes) + for (let child of element.childNodes) { + // Check if we are skiping the current element + if (params.ignoreElements.indexOf(child.id) !== -1) { + continue + } + + // Clone the child element + const clonedChild = cloneElement(child, params) + + // Attach the cloned child to the cloned parent node + clone.appendChild(clonedChild) + } + + // Check if the element needs any state processing (copy user input data) + switch (element.tagName) { + case 'INPUT': + switch (element.type) { + case 'checkbox': + // TODO + break + } + break + case 'TEXTAREA': + // TODO + break + case 'SELECT': + // TODO + break + case 'CANVAS': + // TODO + break + } + + return clone +} diff --git a/test/manual/index.html b/test/manual/index.html index 0996e74..d0eb8ad 100644 --- a/test/manual/index.html +++ b/test/manual/index.html @@ -222,7 +222,7 @@
-

+

Print.js Test Page

+
+

Form Elements

+
+ Checkbox Example +
+
+ +
+
+ +
+
+ + Your browser does not support the canvas element. + + + +
+
+ +
+
\ No newline at end of file From 37628cb5af804a58d4dcf23eac05c4a659285a5a Mon Sep 17 00:00:00 2001 From: Rodrigo Vieira Date: Fri, 24 May 2019 17:27:42 -0400 Subject: [PATCH 3/5] Refactor print element implementation --- src/js/functions.js | 31 ++++++++++++++++++++----------- src/js/html.js | 7 ++----- src/js/image.js | 11 ++++------- src/js/init.js | 2 +- src/js/json.js | 21 ++++++--------------- src/js/print.js | 4 ++-- test/manual/index.html | 3 ++- 7 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/js/functions.js b/src/js/functions.js index d2b10ba..72a2e67 100644 --- a/src/js/functions.js +++ b/src/js/functions.js @@ -89,18 +89,27 @@ export function loopNodesCollectStyles (elements, params) { } } -export function addHeader (printElement, header, headerStyle) { - // Create header element - let headerElement = document.createElement('h1') - - // Create header text node - let headerNode = document.createTextNode(header) - - // Build and style - headerElement.appendChild(headerNode) - headerElement.setAttribute('style', headerStyle) +export function addHeader (printElement, params) { + // Create the header container div + let headerContainer = document.createElement('div') + + // Check if the header is text or raw html + if (isRawHTML(params.header)) { + headerContainer.innerHTML = params.header + } else { + // Create header element + let headerElement = document.createElement('h1') + + // Create header text node + let headerNode = document.createTextNode(params.header) + + // Build and style + headerElement.appendChild(headerNode) + headerElement.setAttribute('style', params.headerStyle) + headerContainer.appendChild(headerElement) + } - printElement.insertBefore(headerElement, printElement.childNodes[0]) + printElement.insertBefore(headerContainer, printElement.childNodes[0]) } export function cleanUp (params) { diff --git a/src/js/html.js b/src/js/html.js index 02e3116..547dfb1 100644 --- a/src/js/html.js +++ b/src/js/html.js @@ -13,16 +13,13 @@ export default { } // Clone the target element including its children (if available) - const printableElement = cloneElement(printElement, params) + params.printableElement = cloneElement(printElement, params) // Add header if (params.header) { - addHeader(printableElement, params.header, params.headerStyle) + addHeader(params.printableElement, params) } - // Store html data - params.htmlData = printableElement - // Print html element contents Print.send(params, printFrame) } diff --git a/src/js/image.js b/src/js/image.js index b683663..002ec44 100644 --- a/src/js/image.js +++ b/src/js/image.js @@ -10,8 +10,8 @@ export default { } // Create printable element (container) - let printableElement = document.createElement('div') - printableElement.setAttribute('style', 'width:100%') + params.printableElement = document.createElement('div') + params.printableElement.setAttribute('style', 'width:100%') // Create all image elements and append them to the printable container params.printable.forEach(src => { @@ -29,14 +29,11 @@ export default { imageWrapper.appendChild(img) // Append wrapper to the printable element - printableElement.appendChild(imageWrapper) + params.printableElement.appendChild(imageWrapper) }) // Check if we are adding a print header - if (params.header) addHeader(printableElement, params.header, params.headerStyle) - - // Store html data - params.htmlData = printableElement.outerHTML + if (params.header) addHeader(params.printableElement, params) // Print image Print.send(params, printFrame) diff --git a/src/js/init.js b/src/js/init.js index 7e70814..18cc85c 100644 --- a/src/js/init.js +++ b/src/js/init.js @@ -35,7 +35,7 @@ export default { onBrowserIncompatible: () => true, modalMessage: 'Retrieving Document...', frameId: 'printJS', - htmlData: '', + printableElement: null, documentTitle: 'Document', targetStyle: ['clear', 'display', 'width', 'min-width', 'height', 'min-height', 'max-height'], targetStyles: ['border', 'box', 'break', 'text-decoration'], diff --git a/src/js/json.js b/src/js/json.js index 4953bf5..2cea6b7 100644 --- a/src/js/json.js +++ b/src/js/json.js @@ -1,8 +1,4 @@ -import { - addWrapper, - capitalizePrint, - isRawHTML -} from './functions' +import { capitalizePrint, addHeader} from './functions' import Print from './print' export default { @@ -31,21 +27,16 @@ export default { } }) - // Variable to hold the html string - let htmlData = '' + // Create a print container element + params.printableElement = document.createElement('div') - // Check if there is a header on top of the table + // Check if we are adding a print header if (params.header) { - htmlData += isRawHTML(params.header) - ? params.header - : '

' + params.header + '

' + addHeader(params.printableElement, params) } // Build the printable html data - htmlData += jsonToHTML(params) - - // Store the data - params.htmlData = addWrapper(htmlData, params) + params.printableElement.innerHTML += jsonToHTML(params) // Print the json data Print.send(params, printFrame) diff --git a/src/js/print.js b/src/js/print.js index 2011f2d..82468fb 100644 --- a/src/js/print.js +++ b/src/js/print.js @@ -21,10 +21,10 @@ const Print = { if (printDocument.document) printDocument = printDocument.document // Append printable element to the iframe body - printDocument.body.appendChild(params.htmlData) + printDocument.body.appendChild(params.printableElement) // Add custom style - if (params.type !== 'pdf' && params.style !== null) { + if (params.type !== 'pdf' && params.style) { // Create style element const style = document.createElement('style') style.innerHTML = params.style diff --git a/test/manual/index.html b/test/manual/index.html index ead1788..003ad0b 100644 --- a/test/manual/index.html +++ b/test/manual/index.html @@ -106,7 +106,8 @@ columnSize: 4 } ], - type: 'json' + type: 'json', + header: 'JSON Print Test' }) } From eae6b27d9f26a6a71c45bde93913062f08573d53 Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Fri, 24 May 2019 20:28:31 -0400 Subject: [PATCH 4/5] Update raw html processing --- src/js/raw-html.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/js/raw-html.js b/src/js/raw-html.js index 856d931..ac19b0b 100644 --- a/src/js/raw-html.js +++ b/src/js/raw-html.js @@ -3,8 +3,12 @@ import Print from './print' export default { print: (params, printFrame) => { - // Store html data - params.htmlData = addWrapper(params.printable, params) + // Create printable element (container) + params.printableElement = document.createElement('div') + params.printableElement.setAttribute('style', 'width:100%') + + // Set our raw html as the printable element inner html content + params.printableElement.innerHTML = params.printable // Print html contents Print.send(params, printFrame) From c0168f9e71524fa600bac8cc35ad967aa847972c Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Sat, 25 May 2019 14:46:23 -0400 Subject: [PATCH 5/5] Prevent oversized images from being cut off if no style is passed --- src/js/html.js | 2 +- src/js/image.js | 3 +-- src/js/init.js | 2 +- src/js/json.js | 2 +- src/js/raw-html.js | 1 - test/manual/index.html | 1 - 6 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/js/html.js b/src/js/html.js index 547dfb1..d740a85 100644 --- a/src/js/html.js +++ b/src/js/html.js @@ -51,7 +51,7 @@ function cloneElement (element, params) { break case 'CANVAS': // Copy the canvas content to its clone - clone.getContext('2d').drawImage(element, 0, 0); + clone.getContext('2d').drawImage(element, 0, 0) break } diff --git a/src/js/image.js b/src/js/image.js index 002ec44..18458d6 100644 --- a/src/js/image.js +++ b/src/js/image.js @@ -11,19 +11,18 @@ export default { // Create printable element (container) params.printableElement = document.createElement('div') - params.printableElement.setAttribute('style', 'width:100%') // Create all image elements and append them to the printable container params.printable.forEach(src => { // Create the image element let img = document.createElement('img') + img.setAttribute('style', params.imageStyle) // Set image src with the file url img.src = src // Create the image wrapper let imageWrapper = document.createElement('div') - imageWrapper.setAttribute('style', params.imageStyle) // Append image to the wrapper element imageWrapper.appendChild(img) diff --git a/src/js/init.js b/src/js/init.js index 18cc85c..0ce00b7 100644 --- a/src/js/init.js +++ b/src/js/init.js @@ -40,7 +40,7 @@ export default { targetStyle: ['clear', 'display', 'width', 'min-width', 'height', 'min-height', 'max-height'], targetStyles: ['border', 'box', 'break', 'text-decoration'], ignoreElements: [], - imageStyle: 'width:100%;', + imageStyle: 'max-width: 100%;', repeatTableHeader: true, css: null, style: null, diff --git a/src/js/json.js b/src/js/json.js index 2cea6b7..d02b3db 100644 --- a/src/js/json.js +++ b/src/js/json.js @@ -1,4 +1,4 @@ -import { capitalizePrint, addHeader} from './functions' +import { capitalizePrint, addHeader } from './functions' import Print from './print' export default { diff --git a/src/js/raw-html.js b/src/js/raw-html.js index ac19b0b..66566ff 100644 --- a/src/js/raw-html.js +++ b/src/js/raw-html.js @@ -1,4 +1,3 @@ -import { addWrapper } from './functions' import Print from './print' export default { diff --git a/test/manual/index.html b/test/manual/index.html index 003ad0b..00b3146 100644 --- a/test/manual/index.html +++ b/test/manual/index.html @@ -215,7 +215,6 @@ 'https://printjs.crabbly.com/images/print-03-highres.jpg' ], type: 'image', - style: 'img { max-width: 300px; margin: 30px; }', showModal: true, modalMessage: 'Printing...' })