Skip to content

Commit

Permalink
Fixes ether#4228 Performance degradation for long pads
Browse files Browse the repository at this point in the history
Due to layout trashing when calculating new heights
  • Loading branch information
seballot committed Sep 8, 2020
1 parent 8213cb7 commit c6dead9
Showing 1 changed file with 49 additions and 59 deletions.
108 changes: 49 additions & 59 deletions src/static/js/ace2_inner.js
Original file line number Diff line number Diff line change
Expand Up @@ -5224,86 +5224,76 @@ function Ace2Inner(){
$(sideDiv).addClass("sidediv");
}

// We apply the height of a line in the doc body, to the corresponding sidediv line number
function updateLineNumbers()
{
if (!currentCallStack || currentCallStack && !currentCallStack.domClean) return;

// Refs #4228, to avoid layout trashing, we need to first calculate all the heights,
// and then apply at once all new height to div elements
var lineHeights = [];
var docLine = doc.body.firstChild;
var currentLine = 0;
var h = null;

// First loop to calculate the heights from doc body
while (docLine)
{
if (docLine.nextSibling) {
if (currentLine === 0) {
// It's the first line. For line number alignment purposes, its
// height is taken to be the top offset of the next line. If we
// didn't do this special case, we would miss out on any top margin
// included on the first line. The default stylesheet doesn't add
// extra margins/padding, but plugins might.
h = docLine.nextSibling.offsetTop - parseInt(window.getComputedStyle(doc.body).getPropertyValue("padding-top").split('px')[0]);
} else {
h = docLine.nextSibling.offsetTop - docLine.offsetTop;
}
} else {
// last line
h = (docLine.clientHeight || docLine.offsetHeight);
}
lineHeights.push(h)
docLine = docLine.nextSibling;
currentLine++;
}

var newNumLines = rep.lines.length();
if (newNumLines < 1) newNumLines = 1;
//update height of all current line numbers

var a = sideDivInner.firstChild;
var b = doc.body.firstChild;
var n = 0;
var sidebarLine = sideDivInner.firstChild;

if (currentCallStack && currentCallStack.domClean)
{

while (a && b)
{
if(n > lineNumbersShown) //all updated, break
break;
var h = (b.clientHeight || b.offsetHeight);
if (b.nextSibling)
{
// when text is zoomed in mozilla, divs have fractional
// heights (though the properties are always integers)
// and the line-numbers don't line up unless we pay
// attention to where the divs are actually placed...
// (also: padding on TTs/SPANs in IE...)
if (b === doc.body.firstChild) {
// It's the first line. For line number alignment purposes, its
// height is taken to be the top offset of the next line. If we
// didn't do this special case, we would miss out on any top margin
// included on the first line. The default stylesheet doesn't add
// extra margins/padding, but plugins might.
h = b.nextSibling.offsetTop - parseInt(window.getComputedStyle(doc.body).getPropertyValue("padding-top").split('px')[0]);
} else {
h = b.nextSibling.offsetTop - b.offsetTop;
}
}
if (h)
{
var hpx = h + "px";
if (a.style.height != hpx) {
a.style.height = hpx;
}
}
a = a.nextSibling;
b = b.nextSibling;
n++;
// Apply height to existing sidediv lines
currentLine = 0
while (sidebarLine && currentLine <= lineNumbersShown) {
if (lineHeights[currentLine]) {
sidebarLine.style.height = lineHeights[currentLine] + "px";
}
sidebarLine = sidebarLine.nextSibling;
currentLine++;
}

if (newNumLines != lineNumbersShown)
{
var container = sideDivInner;
var odoc = outerWin.document;
var fragment = odoc.createDocumentFragment();

// Create missing line and apply height
while (lineNumbersShown < newNumLines)
{
lineNumbersShown++;
var n = lineNumbersShown;
var div = odoc.createElement("DIV");
//calculate height for new line number
if(b){
var h = (b.clientHeight || b.offsetHeight);

if (b.nextSibling){
h = b.nextSibling.offsetTop - b.offsetTop;
}
if (lineHeights[currentLine]) {
div.style.height = lineHeights[currentLine] +"px";
}

if(h){ // apply style to div
div.style.height = h +"px";
}

$(div).append($("<span class='line-number'>" + String(n) + "</span>"));
$(div).append($("<span class='line-number'>" + String(lineNumbersShown) + "</span>"));
fragment.appendChild(div);
if(b){
b = b.nextSibling;
}
currentLine++;
}

container.appendChild(fragment);

// Remove extra lines
while (lineNumbersShown > newNumLines)
{
container.removeChild(container.lastChild);
Expand Down

0 comments on commit c6dead9

Please sign in to comment.