diff --git a/openslides/motions/static/js/motions/base.js b/openslides/motions/static/js/motions/base.js
index 0d82c2dcf..2e2a9d858 100644
--- a/openslides/motions/static/js/motions/base.js
+++ b/openslides/motions/static/js/motions/base.js
@@ -756,7 +756,8 @@ angular.module('OpenSlidesApp.motions', [
oldText = data.outerContextStart + data.innerContextStart +
data.html + data.innerContextEnd + data.outerContextEnd;
- var diff = diffService.diff(oldText, this.text, lineLength, this.line_from);
+ oldText = lineNumberingService.insertLineNumbers(oldText, lineLength, null, null, this.line_from);
+ var diff = diffService.diff(oldText, this.text);
if (highlight > 0) {
diff = lineNumberingService.highlightLine(diff, highlight);
diff --git a/openslides/motions/static/js/motions/diff.js b/openslides/motions/static/js/motions/diff.js
index fce756f35..37a6025fa 100644
--- a/openslides/motions/static/js/motions/diff.js
+++ b/openslides/motions/static/js/motions/diff.js
@@ -816,15 +816,14 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
arr = splitArrayEntriesSplitSeparator(arr, ".");
arr = splitArrayEntriesEmbedSeparator(arr, "\n", false);
- return arr;
- };
-
- this._outputcharcode = function (pre, str) {
- var arr = [];
- for (var i = 0; i < str.length; i++) {
- arr.push(str.charCodeAt(i));
+ var arrWithoutEmptes = [];
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] !== '') {
+ arrWithoutEmptes.push(arr[i]);
+ }
}
- console.log(str, pre, arr);
+
+ return arrWithoutEmptes;
};
/**
@@ -842,13 +841,11 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
if (out.n.length === 0) {
for (i = 0; i < out.o.length; i++) {
- //this._outputcharcode('del', out.o[i]);
str += '' + out.o[i] + "";
}
} else {
if (out.n[0].text === undefined) {
for (var k = 0; k < out.o.length && out.o[k].text === undefined; k++) {
- //this._outputcharcode('del', out.o[k]);
str += '' + out.o[k] + "";
}
}
@@ -862,7 +859,6 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
var pre = "";
for (var j = out.n[i].row + 1; j < out.o.length && out.o[j].text === undefined; j++) {
- //this._outputcharcode('del', out.o[j]);
pre += '' + out.o[j] + "";
}
str += out.n[i].text + pre;
@@ -1005,10 +1001,33 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
return cached;
}
- var str = this._diffString(htmlOld, htmlNew),
+ // This fixes a really strange artefact with the diff that occures under the following conditions:
+ // - The first tag of the two texts is identical, e.g.
+ // - A change happens in the next tag, e.g. inserted text + // - The first tag occures a second time in the text, e.g. another
+ // In this condition, the first tag is deleted first and inserted afterwards again
+ // Test case: "does not break when an insertion followes a beginning tag occuring twice"
+ // The work around inserts to tags at the beginning and removes them afterwards again,
+ // to make sure this situation does not happen (and uses invisible pseudo-tags in case something goes wrong)
+ var workaroundPrepend = " ]*)?>[\s\S]*?<\/p>)(\s*)<\/ins>/gim,
+ function(match, whiteBefore, inner, tagInner, whiteAfter) {
+ return whiteBefore +
+ inner
+ .replace(/ ]*)?>/gi, function(match) {
+ return match + "";
+ })
+ .replace(/<\/p>/gi, " ' +
noMarkup(1) + 'Line 1 ' + brMarkup(2) + 'Line 2 ' +
@@ -432,5 +433,53 @@ describe('linenumbering', function () {
expect(diff).toBe(" ...so frißt er Euch alle mit Haut und Haar und Augen und Därme und alles. ...so frißt er Euch alle mit Haut und Haar. Test Einfügung 1 ...so frißt er Euch alle mit Haut und Haar und Augen und Därme und alles. Test Einfügung 1 ...so frißt er Euch alle mit Haut und Haar und Augen und Därme und alles. Test ...so frißt er Euch alle mit Haut und Haar. ...so frißt er Euch alle mit Haut und Haar und Augen und Därme und alles. " + noMarkup(2) + "...so frißt er " + brMarkup(3) + "Euch alle mit " + brMarkup(4) + "Haut und Haar und Augen und Därme und alles. their grammar, their pronunciation and their most common words. Everyone realizes why a their grammar, their pronunciation and their most common words. Everyone realizes why a NEW PARAGRAPH 2. " + noMarkup(2) + "their grammar, their pronunciation and their most common words. Everyone " + brMarkup(3) + "realizes why a NEW PARAGRAPH 2. their grammar, their pronunciation and their most common words. Everyone realizes why a their grammar, their pronunciation and their most common words. Everyone realizes why a NEW PARAGRAPH 1. NEW PARAGRAPH 2. " + noMarkup(2) + "their grammar, their pronunciation and their most common words. Everyone " + brMarkup(3) + "realizes why a NEW PARAGRAPH 1. NEW PARAGRAPH 2./gi, '');
+ diffUnnormalized = diffUnnormalized.replace(
+ /(\s*)(([a-z0-9,_-]* ?)<\/del>([a-z0-9,_-]* ?)<\/ins>/gi, function (found, oldText, newText) {
var foundDiff = false, commonStart = '', commonEnd = '',
remainderOld = oldText, remainderNew = newText;
@@ -1046,6 +1065,17 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
return out;
});
+ diffUnnormalized = diffUnnormalized.replace(
+ /((
)?]+OS-LINE-NUMBER.+?)<\/del>/gi,
+ function(found,tag) {
+ return tag.toLowerCase().replace(/> <\/span/gi, "> ';
};
- beforeEach(inject(function (_diffService_) {
+ beforeEach(inject(function (_diffService_, _lineNumberingService_) {
diffService = _diffService_;
+ lineNumberingService = _lineNumberingService_;
baseHtml1 = '