From 06e387052a0d39b176d32b4a333c47eb14a2f6cc Mon Sep 17 00:00:00 2001 From: Steven Spungin Date: Mon, 8 Dec 2014 11:49:32 -0500 Subject: [PATCH 1/4] added header and body to test harness --- test/test_harness.js | 147 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 test/test_harness.js diff --git a/test/test_harness.js b/test/test_harness.js new file mode 100644 index 000000000..c6ba0c96f --- /dev/null +++ b/test/test_harness.js @@ -0,0 +1,147 @@ +onload = function() { + + var harness = new pdf_test_harness(); + + var body = document.getElementsByTagName('body')[0]; + body.style.display = 'flex'; + + var div = document.createElement('div'); + div.setAttribute('style', 'position:fixed;height:20px;width:100%;background:lightblue'); + body.appendChild(div); + harness.header = div; + + var div2 = document.createElement('div'); + div2.setAttribute('style', 'position:fixed;display:flex;top:20px; bottom:0;width:100%'); + body.appendChild(div2); + harness.body = div2; + + var btn1 = document.createElement('input'); + btn1.setAttribute('type', 'radio'); + btn1.setAttribute('name', 'view'); + div.appendChild(btn1); + btn1.checked = true; + + var lbl1 = document.createElement('label'); + lbl1.setAttribute('for', 'btn1'); + lbl1.innerHTML = 'PDF' + div.appendChild(lbl1); + + var btn2 = document.createElement('input'); + btn2.setAttribute('type', 'radio'); + btn2.setAttribute('name', 'view'); + div.appendChild(btn2); + + var lbl2 = document.createElement('label'); + lbl2.setAttribute('for', 'btn2'); + lbl2.innerHTML = 'Source' + div.appendChild(lbl2); + + var btn3 = document.createElement('input'); + btn3.setAttribute('type', 'radio'); + btn3.setAttribute('name', 'view'); + div.appendChild(btn3); + + var lbl3 = document.createElement('label'); + lbl3.setAttribute('for', 'btn3'); + lbl3.innerHTML = 'Both' + div.appendChild(lbl3); + + harness.source = document.createElement('pre'); + harness.source.setAttribute('style', 'margin-top:0;width:100%;height:100%;position:absolute;top:0px;bottom:0px;overflow:auto'); + div2.appendChild(harness.source); + + harness.iframe = document.createElement('iframe'); + harness.iframe.setAttribute('style', 'width:100%;height:100%;position:absolute;overflow:auto;top:0px;bottom:0px'); + div2.appendChild(harness.iframe); + + if (pdf_test_harness.onload) { + harness.pdf = pdf_test_harness.onload(harness); + if (harness.message){ + var popup = document.createElement('div'); + popup.setAttribute('style', 'position:fixed;margin:auto;top:50px;background-color:beige;padding:1em;border:1px solid black'); + popup.innerHTML = harness.message; + body.appendChild(popup); + popup.onclick = function(){ + popup.parentNode.removeChild(popup); + } + + } + } + + harness.render('pdf'); + + btn1.onclick = function() { + harness.render('pdf'); + } + btn2.onclick = function() { + harness.render('source'); + } + btn3.onclick = function() { + harness.render('both'); + } +} + +pdf_test_harness = function(pdf) { + this.pdf = pdf; + this.onload = undefined; + this.iframe = undefined; + + this.entityMap = { + "&" : "&", + "<" : "<", + ">" : ">", + '"' : '"', + "'" : ''', + "/" : '/' + }; + + this.escapeHtml = function(string) { + return String(string).replace(/[&<>"'\/]/g, function(s) { + return this.entityMap[s]; + }.bind(this)); + }; + + this.getParameterByName = function(name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search); + return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); + }; + + this.setPdf = function(pdf) { + this.pdf = pdf; + this.rendered = undefined; + this.render(this.view); + }; + + // generate the pdf, the source code, or both + this.render = function(view) { + this.view = view; + //Current code only lets us render one time. + if (!this.rendered) { + this.rendered = this.pdf.output('datauristring'); + this.iframe.src = this.rendered; + var raw = this.pdf.output(); + raw = this.escapeHtml(raw); + this.source.innerHTML = raw; + } + if ('pdf' === view) { + this.source.style.display = 'none'; + this.iframe.style.display = 'block'; + this.iframe.style.width = '100%'; + } else if ('source' === view) { + this.iframe.style.display = 'none'; + this.source.style.display = 'block'; + this.source.style.width = '100%'; + } + + if ('both' === view) { + raw = this.escapeHtml(raw); + this.iframe.style.width = '50%'; + this.iframe.style.position = 'relative'; + this.iframe.style.display = 'inline-block'; + this.source.style.width = '50%'; + this.source.style.position = 'relative'; + this.source.style.display = 'inline-block'; + } + } +} \ No newline at end of file From f085fb1cb5baddb7a8d9af375f4225dfc6e1d8c5 Mon Sep 17 00:00:00 2001 From: Steven Spungin Date: Tue, 9 Dec 2014 09:29:25 -0500 Subject: [PATCH 2/4] test harness formatting fixes --- test/test_harness.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_harness.js b/test/test_harness.js index c6ba0c96f..b95456939 100644 --- a/test/test_harness.js +++ b/test/test_harness.js @@ -6,12 +6,12 @@ onload = function() { body.style.display = 'flex'; var div = document.createElement('div'); - div.setAttribute('style', 'position:fixed;height:20px;width:100%;background:lightblue'); + div.setAttribute('style', 'position:fixed;height:20px;left:0;right:0;background:lightblue'); body.appendChild(div); harness.header = div; var div2 = document.createElement('div'); - div2.setAttribute('style', 'position:fixed;display:flex;top:20px; bottom:0;width:100%'); + div2.setAttribute('style', 'position:fixed;display:flex;top:20px; bottom:0;left:0;right:0'); body.appendChild(div2); harness.body = div2; @@ -53,7 +53,7 @@ onload = function() { harness.iframe = document.createElement('iframe'); harness.iframe.setAttribute('style', 'width:100%;height:100%;position:absolute;overflow:auto;top:0px;bottom:0px'); div2.appendChild(harness.iframe); - + if (pdf_test_harness.onload) { harness.pdf = pdf_test_harness.onload(harness); if (harness.message){ From bbd00a3505865245ebf9ed85ee121a2985cf7c40 Mon Sep 17 00:00:00 2001 From: Steven Spungin Date: Tue, 9 Dec 2014 09:30:18 -0500 Subject: [PATCH 3/4] [from_html plugin] support for page-break-before --- jspdf.plugin.from_html.js | 8 +++ test/test_from_html_css_page_breaks.html | 75 ++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 test/test_from_html_css_page_breaks.html diff --git a/jspdf.plugin.from_html.js b/jspdf.plugin.from_html.js index 79395fcd9..9142c27f9 100644 --- a/jspdf.plugin.from_html.js +++ b/jspdf.plugin.from_html.js @@ -212,6 +212,8 @@ css["padding-left"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-left")) || 0; css["padding-right"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-right")) || 0; + css["page-break-before"] = computedCSSElement("page-break-before") || "auto"; + //float and clearing of floats css["float"] = FloatMap[computedCSSElement("cssFloat")] || "none"; css["clear"] = ClearMap[computedCSSElement("clear")] || "none"; @@ -838,6 +840,12 @@ paragraphspacing_after = ((blockstyle["margin-bottom"] || 0) + (blockstyle["padding-bottom"] || 0)) * fontToUnitRatio; this.priorMarginBottom = blockstyle["margin-bottom"] || 0; + if (blockstyle['page-break-before'] === 'always'){ + this.pdf.addPage(); + this.y = 0; + paragraphspacing_before = ((blockstyle["margin-top"] || 0) + (blockstyle["padding-top"] || 0)) * fontToUnitRatio; + } + out = this.pdf.internal.write; i = void 0; l = void 0; diff --git a/test/test_from_html_css_page_breaks.html b/test/test_from_html_css_page_breaks.html new file mode 100644 index 000000000..dd62b69c7 --- /dev/null +++ b/test/test_from_html_css_page_breaks.html @@ -0,0 +1,75 @@ + + + + + + + +Test HTML + + + + + + + + + + + + + + + + + + + From 6e678a556fb07df467430b92abeda382fd30cf42 Mon Sep 17 00:00:00 2001 From: Steven Spungin Date: Tue, 9 Dec 2014 09:30:48 -0500 Subject: [PATCH 4/4] internal plugin documentation --- doc/plugins/from_html.md | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 doc/plugins/from_html.md diff --git a/doc/plugins/from_html.md b/doc/plugins/from_html.md new file mode 100644 index 000000000..ad7468e77 --- /dev/null +++ b/doc/plugins/from_html.md @@ -0,0 +1,43 @@ + + +# from_html Plugin CSS Support +This document lists the CSS styles supported by the from_html jsPDF plugin. +Each style indicates restrictions and issues. +This file is intended for development purposes and may not be up to date. +Refer to the source code for the lastest developments. + +# Implemented + +* margin +* margin-top +* margin-right +* margin-left +* margin-bottom +* padding +* padding-top +* padding-right +* padding-left +* padding-bottom +* font-family +* font-style +* text-align +* font-size +* line-height +* display +* float +* clear +* page-break-before +> Only _always_ is implemented. + +# Implemented But Not Merged +* color + +# Not Implemented +* page-break-after \ No newline at end of file