Line-Breaking Bugfix: break before an inline element if the first word of the element exceeds the current line
This commit is contained in:
parent
b701127f04
commit
a341071e91
@ -51,6 +51,23 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
|
|||||||
return isLineNumber;
|
return isLineNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._createLineBreak = function () {
|
||||||
|
var br = document.createElement('br');
|
||||||
|
br.setAttribute('class', 'os-line-break');
|
||||||
|
return br;
|
||||||
|
};
|
||||||
|
|
||||||
|
this._createLineNumber = function () {
|
||||||
|
var node = document.createElement('span');
|
||||||
|
var lineNumber = this._currentLineNumber;
|
||||||
|
this._currentLineNumber++;
|
||||||
|
node.setAttribute('class', 'os-line-number line-number-' + lineNumber);
|
||||||
|
node.setAttribute('data-line-number', lineNumber + '');
|
||||||
|
node.setAttribute('contenteditable', 'false');
|
||||||
|
node.innerHTML = ' '; // Prevent tinymce from stripping out empty span's
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits a TEXT_NODE into an array of TEXT_NODEs and BR-Elements separating them into lines.
|
* Splits a TEXT_NODE into an array of TEXT_NODEs and BR-Elements separating them into lines.
|
||||||
* Each line has a maximum length of 'length', with one exception: spaces are accepted to exceed the length.
|
* Each line has a maximum length of 'length', with one exception: spaces are accepted to exceed the length.
|
||||||
@ -69,28 +86,13 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
|
|||||||
lastBreakableIndex = null,
|
lastBreakableIndex = null,
|
||||||
service = this;
|
service = this;
|
||||||
|
|
||||||
var createLineBreak = function() {
|
|
||||||
var br = document.createElement('br');
|
|
||||||
br.setAttribute('class', 'os-line-break');
|
|
||||||
return br;
|
|
||||||
};
|
|
||||||
var createLineNumber = function() {
|
|
||||||
var node = document.createElement('span');
|
|
||||||
var lineNumber = service._currentLineNumber;
|
|
||||||
service._currentLineNumber++;
|
|
||||||
node.setAttribute('class', 'os-line-number line-number-' + lineNumber);
|
|
||||||
node.setAttribute('data-line-number', lineNumber + '');
|
|
||||||
node.setAttribute('contenteditable', 'false');
|
|
||||||
node.innerHTML = ' '; // Prevent tinymce from stripping out empty span's
|
|
||||||
return node;
|
|
||||||
};
|
|
||||||
var addLine = function (text) {
|
var addLine = function (text) {
|
||||||
var newNode = document.createTextNode(text);
|
var newNode = document.createTextNode(text);
|
||||||
if (firstTextNode) {
|
if (firstTextNode) {
|
||||||
firstTextNode = false;
|
firstTextNode = false;
|
||||||
} else {
|
} else {
|
||||||
out.push(createLineBreak());
|
out.push(service._createLineBreak());
|
||||||
out.push(createLineNumber());
|
out.push(service._createLineNumber());
|
||||||
}
|
}
|
||||||
out.push(newNode);
|
out.push(newNode);
|
||||||
};
|
};
|
||||||
@ -101,11 +103,11 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
|
|||||||
|
|
||||||
// This happens if a previous inline element exactly stretches to the end of the line
|
// This happens if a previous inline element exactly stretches to the end of the line
|
||||||
if (this._currentInlineOffset >= length) {
|
if (this._currentInlineOffset >= length) {
|
||||||
out.push(createLineBreak());
|
out.push(service._createLineBreak());
|
||||||
out.push(createLineNumber());
|
out.push(service._createLineNumber());
|
||||||
this._currentInlineOffset = 0;
|
this._currentInlineOffset = 0;
|
||||||
} else if (this._prependLineNumberToFirstText) {
|
} else if (this._prependLineNumberToFirstText) {
|
||||||
out.push(createLineNumber());
|
out.push(service._createLineNumber());
|
||||||
}
|
}
|
||||||
this._prependLineNumberToFirstText = false;
|
this._prependLineNumberToFirstText = false;
|
||||||
|
|
||||||
@ -163,6 +165,17 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._lengthOfFirstInlineWord = function (node) {
|
||||||
|
if (!node.firstChild) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (node.firstChild.nodeType == TEXT_NODE) {
|
||||||
|
var parts = node.firstChild.nodeValue.split(' ');
|
||||||
|
return parts[0].length;
|
||||||
|
} else {
|
||||||
|
return this._lengthOfFirstInlineWord(node.firstChild);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this._insertLineNumbersToInlineNode = function (node, length) {
|
this._insertLineNumbersToInlineNode = function (node, length) {
|
||||||
var oldChildren = [], i;
|
var oldChildren = [], i;
|
||||||
@ -181,6 +194,14 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
|
|||||||
node.appendChild(ret[j]);
|
node.appendChild(ret[j]);
|
||||||
}
|
}
|
||||||
} else if (oldChildren[i].nodeType == ELEMENT_NODE) {
|
} else if (oldChildren[i].nodeType == ELEMENT_NODE) {
|
||||||
|
var firstword = this._lengthOfFirstInlineWord(oldChildren[i]),
|
||||||
|
overlength = ((this._currentInlineOffset + firstword) > length && this._currentInlineOffset > 0);
|
||||||
|
if (overlength && this._isInlineElement(oldChildren[i])) {
|
||||||
|
this._currentInlineOffset = 0;
|
||||||
|
node.appendChild(this._createLineBreak());
|
||||||
|
node.appendChild(this._createLineNumber());
|
||||||
|
}
|
||||||
|
|
||||||
var changedNode = this._insertLineNumbersToNode(oldChildren[i], length);
|
var changedNode = this._insertLineNumbersToNode(oldChildren[i], length);
|
||||||
this._moveLeadingLineBreaksToOuterNode(changedNode, node);
|
this._moveLeadingLineBreaksToOuterNode(changedNode, node);
|
||||||
node.appendChild(changedNode);
|
node.appendChild(changedNode);
|
||||||
@ -252,6 +273,14 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
|
|||||||
node.appendChild(ret[j]);
|
node.appendChild(ret[j]);
|
||||||
}
|
}
|
||||||
} else if (oldChildren[i].nodeType == ELEMENT_NODE) {
|
} else if (oldChildren[i].nodeType == ELEMENT_NODE) {
|
||||||
|
var firstword = this._lengthOfFirstInlineWord(oldChildren[i]),
|
||||||
|
overlength = ((this._currentInlineOffset + firstword) > length && this._currentInlineOffset > 0);
|
||||||
|
if (overlength && this._isInlineElement(oldChildren[i])) {
|
||||||
|
this._currentInlineOffset = 0;
|
||||||
|
node.appendChild(this._createLineBreak());
|
||||||
|
node.appendChild(this._createLineNumber());
|
||||||
|
}
|
||||||
|
|
||||||
var changedNode = this._insertLineNumbersToNode(oldChildren[i], length);
|
var changedNode = this._insertLineNumbersToNode(oldChildren[i], length);
|
||||||
this._moveLeadingLineBreaksToOuterNode(changedNode, node);
|
this._moveLeadingLineBreaksToOuterNode(changedNode, node);
|
||||||
node.appendChild(changedNode);
|
node.appendChild(changedNode);
|
||||||
|
@ -212,5 +212,19 @@ describe('linenumbering', function () {
|
|||||||
expect(outHtml).toBe(expected);
|
expect(outHtml).toBe(expected);
|
||||||
expect(lineNumberingService.stripLineNumbers(outHtml)).toBe(inHtml);
|
expect(lineNumberingService.stripLineNumbers(outHtml)).toBe(inHtml);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('breaks before an inline element, if the first word of the new inline element is longer than the remaining line (1)', function () {
|
||||||
|
var inHtml = "<p>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie <strong>consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio</strong>.</p>";
|
||||||
|
var outHtml = lineNumberingService.insertLineNumbers(inHtml, 80);
|
||||||
|
expect(outHtml).toBe('<p>' + noMarkup(1) + 'Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie ' + brMarkup(2) + '<strong>consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan ' + brMarkup(3) + 'et iusto odio</strong>.</p>');
|
||||||
|
expect(lineNumberingService.stripLineNumbers(outHtml)).toBe(inHtml);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('breaks before an inline element, if the first word of the new inline element is longer than the remaining line (2)', function () {
|
||||||
|
var inHtml = "<p><span>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie <strong>consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio</strong>.</span></p>";
|
||||||
|
var outHtml = lineNumberingService.insertLineNumbers(inHtml, 80);
|
||||||
|
expect(outHtml).toBe('<p>' + noMarkup(1) + '<span>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie ' + brMarkup(2) + '<strong>consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan ' + brMarkup(3) + 'et iusto odio</strong>.</span></p>');
|
||||||
|
expect(lineNumberingService.stripLineNumbers(outHtml)).toBe(inHtml);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user