From 159720b98392389eea455f5a8b28803493c731bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Ho=CC=88=C3=9Fl?= Date: Sat, 17 Dec 2016 12:55:50 +0100 Subject: [PATCH] Bugfix for PDF-export - fixes #2777 --- openslides/core/static/js/core/pdf.js | 27 ++--- tests/karma/core/pdf.service.test.js | 162 ++++++++++++++++++++++++-- 2 files changed, 164 insertions(+), 25 deletions(-) diff --git a/openslides/core/static/js/core/pdf.js b/openslides/core/static/js/core/pdf.js index f4980aefe..13445e74b 100644 --- a/openslides/core/static/js/core/pdf.js +++ b/openslides/core/static/js/core/pdf.js @@ -559,7 +559,7 @@ angular.module('OpenSlidesApp.core.pdf', []) currentParagraph = create("text"); /* falls through */ case "a": - parseChildren(alreadyConverted, element, currentParagraph, styles.concat(elementStyles[nodeName]), diff_mode); + currentParagraph = parseChildren(alreadyConverted, element, currentParagraph, styles.concat(elementStyles[nodeName]), diff_mode); alreadyConverted.push(currentParagraph); break; case "b": @@ -569,7 +569,7 @@ angular.module('OpenSlidesApp.core.pdf', []) case "i": case "ins": case "del": - parseChildren(alreadyConverted, element, currentParagraph, styles.concat(elementStyles[nodeName]), diff_mode); + currentParagraph = parseChildren(alreadyConverted, element, currentParagraph, styles.concat(elementStyles[nodeName]), diff_mode); break; case "table": var t = create("table", { @@ -581,7 +581,7 @@ angular.module('OpenSlidesApp.core.pdf', []) if (border) if (parseInt(border) == 1) isBorder = true; if (!isBorder) t.layout = 'noBorders'; - parseChildren(t.table.body, element, currentParagraph, styles, diff_mode); + currentParagraph = parseChildren(t.table.body, element, currentParagraph, styles, diff_mode); var widths = element.getAttribute("widths"); if (!widths) { if (t.table.body.length !== 0) { @@ -596,11 +596,11 @@ angular.module('OpenSlidesApp.core.pdf', []) alreadyConverted.push(t); break; case "tbody": - parseChildren(alreadyConverted, element, currentParagraph, styles, diff_mode); + currentParagraph = parseChildren(alreadyConverted, element, currentParagraph, styles, diff_mode); break; case "tr": var row = []; - parseChildren(row, element, currentParagraph, styles, diff_mode); + currentParagraph = parseChildren(row, element, currentParagraph, styles, diff_mode); alreadyConverted.push(row); break; case "td": @@ -613,7 +613,7 @@ angular.module('OpenSlidesApp.core.pdf', []) var cspan = element.getAttribute("colspan"); if (cspan) st.colSpan = parseInt(cspan); - parseChildren(st.stack, element, currentParagraph, styles, diff_mode); + currentParagraph = parseChildren(st.stack, element, currentParagraph, styles, diff_mode); alreadyConverted.push(st); break; case "span": @@ -628,7 +628,6 @@ angular.module('OpenSlidesApp.core.pdf', []) }; currentParagraph.text.push(lineNumberObjInline); } - parseChildren(alreadyConverted, element, currentParagraph, styles, diff_mode); } else if (lineNumberMode == "outside") { var lineNumberOutline; if (diff_mode == DIFF_MODE_INSERT) { @@ -650,14 +649,11 @@ angular.module('OpenSlidesApp.core.pdf', []) }; currentParagraph = create("text"); col.columns.push(currentParagraph); - parseChildren(col.columns[0], element, currentParagraph, styles, diff_mode); alreadyConverted.push(col); } } else { - var spanText = create("text", element.textContent.replace(/\n/g, "")); - ComputeStyle(spanText, styles); - currentParagraph.text.push(spanText); + currentParagraph = parseChildren(alreadyConverted, element, currentParagraph, styles, diff_mode); } break; case "br": @@ -673,7 +669,7 @@ angular.module('OpenSlidesApp.core.pdf', []) var stackDiv = create("stack"); stackDiv.stack.push(currentParagraph); ComputeStyle(stackDiv, styles); - parseChildren(stackDiv.stack, element, currentParagraph, [], diff_mode); + currentParagraph = parseChildren(stackDiv.stack, element, currentParagraph, [], diff_mode); alreadyConverted.push(stackDiv); break; case "p": @@ -682,7 +678,7 @@ angular.module('OpenSlidesApp.core.pdf', []) var stackP = create("stack"); stackP.stack.push(currentParagraph); ComputeStyle(stackP, styles); - parseChildren(stackP.stack, element, currentParagraph, [], diff_mode); + currentParagraph = parseChildren(stackP.stack, element, currentParagraph, [], diff_mode); alreadyConverted.push(stackP); break; case "img": @@ -718,7 +714,7 @@ angular.module('OpenSlidesApp.core.pdf', []) var list = create(nodeName); if (lineNumberMode == "outside") { var lines = extractLineNumbers(element); - parseChildren(list[nodeName], element, currentParagraph, styles, diff_mode); + currentParagraph = parseChildren(list[nodeName], element, currentParagraph, styles, diff_mode); if (lines.length > 0) { var listCol = { columns: [{ @@ -742,12 +738,13 @@ angular.module('OpenSlidesApp.core.pdf', []) alreadyConverted.push(list); } } else { - parseChildren(list[nodeName], element, currentParagraph, styles, diff_mode); + currentParagraph = parseChildren(list[nodeName], element, currentParagraph, styles, diff_mode); alreadyConverted.push(list); } break; default: var defaultText = create("text", element.textContent.replace(/\n/g, "")); + ComputeStyle(defaultText, styles); if (!currentParagraph) { currentParagraph = {}; currentParagraph.text = []; diff --git a/tests/karma/core/pdf.service.test.js b/tests/karma/core/pdf.service.test.js index c97671b80..009af7bc5 100644 --- a/tests/karma/core/pdf.service.test.js +++ b/tests/karma/core/pdf.service.test.js @@ -70,12 +70,6 @@ describe('pdf', function () { "stack": [{ "text": [ {"text": "1", "color": "gray", "fontSize": 5}, - {"text": " "}, - { - "text": null, - "color": "gray", - "fontSize": 5 - }, {"text": "Test"} ], "margin": [0, 5] }] @@ -99,7 +93,7 @@ describe('pdf', function () { "color": "gray", "fontSize": 8, "margin": [0, 2, 0, 0] - }, {"text": [{"text": " "}, {"text": "Test "}]}] + }, {"text": [{"text": "Test "}]}] }, {"text": []}, { "columns": [{ "width": 20, @@ -107,7 +101,7 @@ describe('pdf', function () { "color": "gray", "fontSize": 8, "margin": [0, 2, 0, 0] - }, {"text": [{"text": " "}, {"text": "Test2 "}]}] + }, {"text": [{"text": "Test2 "}]}] }, {"text": []}, { "columns": [{ "width": 20, @@ -115,7 +109,7 @@ describe('pdf', function () { "color": "gray", "fontSize": 8, "margin": [0, 2, 0, 0] - }, {"text": [{"text": " "}, {"text": "Test3"}]}] + }, {"text": [{"text": "Test3"}]}] }] })); expect(JSON.stringify(pdfmake[2])).toBe(emptyline); @@ -170,5 +164,153 @@ describe('pdf', function () { // the actual result is's the point here; only that it doesn't throw an exception expect(JSON.stringify(pdfmake[0])).toBe(emptyline); }); + + it('handles line breaks inside inline elements (outside)', function() { + var inHtml = '

tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.

', + numberedHtml = lineNumberingService.insertLineNumbers(inHtml, 80); + + var instance = PdfMakeConverter.createInstance(); + var pdfmake = instance.convertHTML(numberedHtml, 'outside'); + expect(JSON.stringify(pdfmake[1])).toBe(JSON.stringify( + { + "stack": [ + {"text": [], "margin": [0, 5]}, + { + "columns": [ + { + "width": 20, + "text": "1", + "color": "gray", + "fontSize": 8, + "margin": [0, 2, 0, 0] + }, + { + "text": [ + {"text": "tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "}, + {"text": "At ", "bold": true} + ] + } + ] + }, + {"text": []}, + { + "columns": [ + { + "width": 20, + "text": "2", + "color": "gray", + "fontSize": 8, + "margin": [0, 2, 0, 0] + }, + { + "text": [ + {"text": "vero eos et accusam", "bold": true}, + {"text": " et justo duo dolores et ea rebum."} + ] + } + ] + } + ] + } + )); + }); + + it('handles line breaks inside inline elements (inline)', function() { + var inHtml = '

tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.

', + numberedHtml = lineNumberingService.insertLineNumbers(inHtml, 80); + + var instance = PdfMakeConverter.createInstance(); + var pdfmake = instance.convertHTML(numberedHtml, 'inline'); + expect(JSON.stringify(pdfmake[1])).toBe(JSON.stringify( + {"stack": [ + {"text": [ + {"text": "1", "color": "gray", "fontSize": 5 }, + {"text": "tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "}, + {"text": "At ", "bold": true }, + {"text": "2", "color": "gray", "fontSize": 5}, + {"text": "vero eos et accusam", "bold": true }, + {"text": " et justo duo dolores et ea rebum."} + ], "margin": [0, 5] + } + ]} + )); + }); + + it('handles line breaks inside lists', function() { + var inHtml = '
  1. Lorem ipsum dolor sit
    amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
', + numberedHtml = lineNumberingService.insertLineNumbers(inHtml, 80) + + var instance = PdfMakeConverter.createInstance(); + var pdfmake = instance.convertHTML(numberedHtml, 'outside'); + expect(JSON.stringify(pdfmake[1])).toBe(JSON.stringify( + { + "columns":[ + { + "width": 20, + "stack": [ + {"width": 20,"text": "1","color": "gray","fontSize": 8,"margin": [0, 2.35, 0, 0]}, + {"width": 20,"text": "2","color": "gray","fontSize": 8,"margin": [0, 2.35, 0, 0]}, + {"width": 20,"text": "3","color": "gray","fontSize": 8,"margin": [0, 2.35, 0, 0]} + ] + }, + {"ol": [ + {"stack": [ + { + "text": [ + {"text": "Lorem ipsum dolor sit"} + ] + }, + { + "text": [ + {"text": "amet, "}, + {"text": "consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ","decoration": "underline"} + ] + }, + { + "text": [ + {"text": "ut labore et dolore magna aliquyam erat","decoration": "underline"}, + {"text": ", sed diam voluptua."} + ] + } + ]} + ]} + ], + "margin":[0,10,0,0] + } + )); + }); + + it('handles styled SPANs within Ps', function() { + var inHtml = '

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.

', + numberedHtml = lineNumberingService.insertLineNumbers(inHtml, 80) + + var instance = PdfMakeConverter.createInstance(); + var pdfmake = instance.convertHTML(numberedHtml, 'outside'); + expect(JSON.stringify(pdfmake[1])).toBe(JSON.stringify( + { + "stack": [ + {"text": [], "margin": [0, 5]}, + { + "columns": [ + { "width": 20, "text": "1", "color": "gray", "fontSize": 8, "margin": [0, 2, 0, 0]}, + { "text": [ + { "text": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod ", "bold": true } + ]} + ] + }, + {"text":[]}, + { + "columns": [ + { "width": 20, "text": "2", "color": "gray", "fontSize": 8, "margin": [0, 2, 0, 0] }, + { "text": [ + { "text": "tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.", "bold": true } + ]} + ] + } + ] + } + )); + }); }); -}); \ No newline at end of file +}); +