Skip to content

Commit 8bd8717

Browse files
committed
Fix edge case where rolling buffer would jump in console.
1 parent f7c2856 commit 8bd8717

File tree

1 file changed

+26
-14
lines changed

1 file changed

+26
-14
lines changed

plugins/editor/scroller.js

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
var _ = require('lodash');
44

5-
function generateContent(lines, start, minLength) {
5+
function generateContent(lines, start, end, minLength) {
66
return _(lines)
7-
.slice(start)
7+
.slice(start, end)
88
.thru(function(array){
99
if(array.length < minLength){
1010
// pad whitespace at top of array
@@ -51,12 +51,15 @@ Scroller.prototype.setLines = function(newLines) {
5151
this.lines = newLines;
5252
if(this.sticky){
5353
this.startPosition = Math.max(0, len - this.minVisible);
54-
}else if(newLines.length === 1 && newLines[0].length === 0){
54+
}else if(len === 1 && newLines[0].length === 0){
5555
// ^^ `lines` is reset to an array with one empty line. ugh.
5656

5757
// handle the reset case when lines is replaced with an empty array
5858
// we don't have a direct event that can call this
5959
this.reset();
60+
}else if(len < this.startPosition){
61+
// handle buffer rollover, where number of lines will go from 2048 to ~1900
62+
this.startPosition = Math.max(0, len - this.minVisible);
6063
}
6164
this.dirty = true;
6265
};
@@ -81,9 +84,10 @@ Scroller.prototype._renderVisible = function(){
8184
if(this.sticky){
8285
this.startPosition = Math.max(0, this.lines.length - this.minVisible);
8386
}
84-
this.console.innerHTML = generateContent(this.lines, this.startPosition, this.minVisible);
87+
console.log('_renderVisible', this.startPosition, this.sticky, top);
88+
this.console.innerHTML = generateContent(this.lines, this.startPosition, this.lines.length, this.minVisible);
8589
if(this.jumpToBottom){
86-
this.console.scrollTop = 350000;
90+
this.console.scrollTop = 2000;
8791
this.jumpToBottom = false;
8892
}else if(!this.sticky && this.startPosition > 0 && top === 0){
8993
//cover the situation where the window was fully scrolled faster than expand could keep up and locked to the top
@@ -101,7 +105,7 @@ Scroller.prototype._expand = function(){
101105
var scrollTop = this.console.scrollTop;
102106

103107
// do an inline scroll to avoid potential scroll interleaving
104-
this.console.innerHTML = generateContent(this.lines, this.startPosition, this.minVisible);
108+
this.console.innerHTML = generateContent(this.lines, this.startPosition, this.lines.length, this.minVisible);
105109
var newScrollHeight = this.console.scrollHeight;
106110
this.console.scrollTop = scrollTop + newScrollHeight - scrollHeight;
107111

@@ -110,17 +114,25 @@ Scroller.prototype._expand = function(){
110114
};
111115

112116
Scroller.prototype._onScroll = function(){
117+
if(this.jumpToBottom){
118+
// do nothing, prepare to jump
119+
return;
120+
}
113121
var height = this.console.offsetHeight;
114122
var scrollHeight = this.console.scrollHeight;
115123
var scrollTop = this.console.scrollTop;
116-
if(!this.jumpToBottom && scrollTop < 15 && this.startPosition > 0){
117-
this.expand();
118-
}else if(!this.sticky && scrollTop + height > scrollHeight - 30){
119-
this.jumpToBottom = true;
120-
this.sticky = true;
121-
this.dirty = true;
122-
}else if(this.sticky && scrollTop + height < scrollHeight - 30){
123-
this.sticky = false;
124+
if(this.sticky){
125+
if(scrollTop + height < scrollHeight - 30){
126+
this.sticky = false;
127+
}
128+
}else{
129+
if(scrollTop < 15 && this.startPosition > 0){
130+
this.expand();
131+
}else if(scrollTop + height > scrollHeight - 30){
132+
this.jumpToBottom = true;
133+
this.sticky = true;
134+
this.dirty = true;
135+
}
124136
}
125137

126138
if(this.dirty && !this.animateRequest){

0 commit comments

Comments
 (0)