Skip to content

Commit 64eaf78

Browse files
committed
Experimental auto-expanding console
1 parent a0a35a0 commit 64eaf78

File tree

2 files changed

+75
-16
lines changed

2 files changed

+75
-16
lines changed

plugins/editor/index.js

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,25 @@ const TransmitPane = require('./transmit-pane');
2828

2929
const makeToasts = require('../../src/lib/toasts');
3030

31+
const Scroller = require('./scroller');
32+
3133
function editor(app, opts, done){
3234

3335
var codeEditor;
3436
var outputConsole;
3537
var transmission;
3638
var transmitPane;
37-
var scrollDown = false;
39+
var scroller = new Scroller();
3840

3941
function refreshConsole(){
40-
const { text } = consoleStore.getState();
42+
const { lines } = consoleStore.getState();
43+
scroller.setLines(lines);
4144

4245
if(outputConsole){
43-
scrollDown = true;
44-
outputConsole.innerHTML = text;
45-
// outputConsole.scrollTop = outputConsole.scrollHeight;
46-
}
47-
}
48-
49-
function updateScroll(){
50-
requestAnimationFrame(updateScroll);
51-
52-
if(outputConsole && scrollDown){
53-
scrollDown = false;
54-
outputConsole.scrollTop = 350000;
46+
requestAnimationFrame(scroller.refresh);
5547
}
5648
}
5749

58-
requestAnimationFrame(updateScroll);
59-
6050
function highlighter(position, length) {
6151
if(!codeEditor){
6252
return;
@@ -140,6 +130,10 @@ function editor(app, opts, done){
140130
outputConsole.style.overflow = 'auto';
141131
outputConsole.style.whiteSpace = 'pre-wrap';
142132
el.appendChild(outputConsole);
133+
134+
scroller.setConsole(outputConsole);
135+
136+
outputConsole.addEventListener('scroll', scroller.scroll, false);
143137
}
144138
if(!transmission) {
145139
transmission = document.createElement('div');

plugins/editor/scroller.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
'use strict';
2+
3+
function generateContent(lines, num) {
4+
return lines.slice(-num).join('\n');
5+
}
6+
7+
var Scroller = function() {
8+
this.lines = [];
9+
this.minVisible = 30;
10+
this.visibleCount = this.minVisible;
11+
this.sticky = true;
12+
this.dirty = false;
13+
this.console = null;
14+
this.refresh = this.renderVisible.bind(this);
15+
this.scroll = this.onScroll.bind(this);
16+
};
17+
18+
Scroller.prototype.setLines = function(lines) {
19+
if(this.sticky){
20+
this.visibleCount = this.minVisible;
21+
}else{
22+
//keep sticky position within view
23+
this.visibleCount += Math.max(0, lines.length - this.lines.length);
24+
}
25+
this.lines = lines;
26+
this.dirty = true;
27+
};
28+
29+
Scroller.prototype.renderVisible = function(){
30+
if(this.dirty && this.console){
31+
this.console.innerHTML = generateContent(this.lines, this.visibleCount);
32+
if(this.sticky){
33+
this.console.scrollTop = 350000;
34+
}
35+
this.dirty = false;
36+
}
37+
};
38+
39+
Scroller.prototype.onScroll = function(){
40+
var height = this.console.offsetHeight;
41+
var scrollHeight = this.console.scrollHeight;
42+
var scrollTop = this.console.scrollTop;
43+
if(scrollTop < 30 && this.visibleCount < this.lines.length){
44+
this.visibleCount += this.minVisible;
45+
this.sticky = false;
46+
this.dirty = true;
47+
}else if(scrollTop + height > scrollHeight - 30){
48+
if(!this.sticky){
49+
this.sticky = true;
50+
this.dirty = true;
51+
}
52+
}else{
53+
this.sicky = false;
54+
}
55+
56+
if(this.dirty){
57+
requestAnimationFrame(this.refresh);
58+
}
59+
};
60+
61+
Scroller.prototype.setConsole = function(console){
62+
this.console = console;
63+
};
64+
65+
module.exports = Scroller;

0 commit comments

Comments
 (0)