diff --git a/openslides/motions/static/js/motions/base.js b/openslides/motions/static/js/motions/base.js index 008f449ec..f0e1abaae 100644 --- a/openslides/motions/static/js/motions/base.js +++ b/openslides/motions/static/js/motions/base.js @@ -278,11 +278,16 @@ angular.module('OpenSlidesApp.motions', [ html = lineNumberingService.insertLineNumbers(this.getVersion(versionId).text, lineLength); var data = diffService.extractRangeByLineNumbers(html, maxLine, null); - html = data.outerContextStart + data.innerContextStart + - data.html + - data.innerContextEnd + data.outerContextEnd; - html = lineNumberingService.insertLineNumbers(html, lineLength, highlight, null, maxLine); + if (data.html !== '') { + html = data.outerContextStart + data.innerContextStart + + data.html + + data.innerContextEnd + data.outerContextEnd; + html = lineNumberingService.insertLineNumbers(html, lineLength, highlight, null, maxLine); + } else { + // Prevents empty lines at the end of the motion + html = ''; + } return html; }, _getTextWithChangeRecommendations: function (versionId, highlight, statusCompareCb) { diff --git a/openslides/motions/static/js/motions/diff.js b/openslides/motions/static/js/motions/diff.js index f711bd815..6ad1578b8 100644 --- a/openslides/motions/static/js/motions/diff.js +++ b/openslides/motions/static/js/motions/diff.js @@ -836,8 +836,9 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi for (i = 0; i < out.n.length; i++) { if (out.n[i].text === undefined) { - //this._outputcharcode('ins', out.n[i]); - str += '' + out.n[i] + ""; + if (out.n[i] !== "") { + str += '' + out.n[i] + ""; + } } else { var pre = ""; @@ -973,6 +974,7 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi found = found.replace(/<\/(div|p|li)[^>]*>/gi, function(match) { return '' + match; }); return found; }); + diffUnnormalized = diffUnnormalized.replace(/^

(.*)<\/p><\/del>$/gi, function(match, inner) { return "

" + inner + "

"; }); var node = document.createElement('div'); node.innerHTML = diffUnnormalized; diff --git a/openslides/motions/static/js/motions/linenumbering.js b/openslides/motions/static/js/motions/linenumbering.js index 3b32a72fd..5a4833d08 100644 --- a/openslides/motions/static/js/motions/linenumbering.js +++ b/openslides/motions/static/js/motions/linenumbering.js @@ -24,6 +24,7 @@ angular.module('OpenSlidesApp.motions.lineNumbering', []) this._currentInlineOffset = null; this._currentLineNumber = null; this._prependLineNumberToFirstText = false; + this._ignoreNextRegularLineNumber = false; var lineNumberCache = $cacheFactory('linenumbering.service'); @@ -76,6 +77,10 @@ angular.module('OpenSlidesApp.motions.lineNumbering', []) }; this._createLineNumber = function () { + if (this._ignoreNextRegularLineNumber) { + this._ignoreNextRegularLineNumber = false; + return; + } var node = document.createElement('span'); var lineNumber = this._currentLineNumber; this._currentLineNumber++; @@ -142,7 +147,11 @@ angular.module('OpenSlidesApp.motions.lineNumbering', []) out.push(service._createLineNumber()); this._currentInlineOffset = 0; } else if (this._prependLineNumberToFirstText) { - out.push(service._createLineNumber()); + if (this._ignoreNextRegularLineNumber) { + this._ignoreNextRegularLineNumber = false; + } else { + out.push(service._createLineNumber()); + } } this._prependLineNumberToFirstText = false; @@ -342,6 +351,10 @@ angular.module('OpenSlidesApp.motions.lineNumbering', []) throw 'This method may only be called for ELEMENT-nodes: ' + node.nodeValue; } if (this._isIgnoredByLineNumbering(node)) { + if (this._currentInlineOffset === 0) { + node.insertBefore(this._createLineNumber(), node.firstChild); + this._ignoreNextRegularLineNumber = true; + } return node; } else if (this._isInlineElement(node)) { return this._insertLineNumbersToInlineNode(node, length, highlight); @@ -352,7 +365,6 @@ angular.module('OpenSlidesApp.motions.lineNumbering', []) }; this._stripLineNumbers = function (node) { - for (var i = 0; i < node.childNodes.length; i++) { if (this._isOsLineBreakNode(node.childNodes[i]) || this._isOsLineNumberNode(node.childNodes[i])) { node.removeChild(node.childNodes[i]); @@ -391,6 +403,7 @@ angular.module('OpenSlidesApp.motions.lineNumbering', []) this._currentLineNumber = 1; } this._prependLineNumberToFirstText = true; + this._ignoreNextRegularLineNumber = false; return this._insertLineNumbersToNode(root, lineLength, highlight); }; diff --git a/tests/karma/motions/diff.service.test.js b/tests/karma/motions/diff.service.test.js index 3f40e6585..0fae9e570 100644 --- a/tests/karma/motions/diff.service.test.js +++ b/tests/karma/motions/diff.service.test.js @@ -363,5 +363,12 @@ describe('linenumbering', function () { expect(diff).toBe("

liebliche Stimme, aber deine Stimme ist rauh; du bist der Wolf.' Wolf.'

Der Wolf hatte danach richtig schlechte laune, trank eine Flasche Rum,

machte eine Weltreise und kam danach wieder um die Ziegen zu fressen. Da gieng der

"); }); + + it('handles completely deleted paragraphs', function () { + var before = "

Ihr könnt ohne Sorge fortgehen.'Da meckerte die Alte und machte sich getrost auf den Weg.

", + after = ""; + var diff = diffService.diff(before, after); + expect(diff).toBe("

Ihr könnt ohne Sorge fortgehen.'Da meckerte die Alte und machte sich getrost auf den Weg.

"); + }); }); }); diff --git a/tests/karma/motions/linenumbering.service.test.js b/tests/karma/motions/linenumbering.service.test.js index 5b89ee212..785354ca4 100644 --- a/tests/karma/motions/linenumbering.service.test.js +++ b/tests/karma/motions/linenumbering.service.test.js @@ -250,6 +250,13 @@ describe('linenumbering', function () { expect(outHtml).toBe('

' + noMarkup(1) + 'et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata ' + brMarkup(2) + 'sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, conseteturdsfsdf23

'); expect(lineNumberingService.stripLineNumbers(outHtml)).toBe(inHtml); }); + + it('inserts the line number before the INS, if INS is the first element of the paragraph', function() { + var inHtml = "

lauthals 'liebe Kinder, ich will hinaus in den Wald, seid auf der Hut vor dem Wolf!' Und noch etwas mehr Text bis zur nächsten Zeile

"; + var outHtml = lineNumberingService.insertLineNumbers(inHtml, 80); + expect(outHtml).toBe("

" + noMarkup(1) + "lauthals 'liebe Kinder, ich will hinaus in den Wald, seid auf der Hut vor dem Wolf!' Und " + brMarkup(2) + "noch etwas mehr Text bis zur nächsten Zeile

"); + expect(lineNumberingService.stripLineNumbers(outHtml)).toBe(inHtml); + }); }); describe('behavior regarding ckeditor', function() {