Merge pull request #445 from Tyriar/444_rate_limit_viewport_refresh
Rate limit Viewport.refresh
This commit is contained in:
@@ -1,6 +1,11 @@
|
|||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
import { Viewport } from './Viewport';
|
import { Viewport } from './Viewport';
|
||||||
|
|
||||||
|
class MockWindow {
|
||||||
|
// Disable refreshLoop in test
|
||||||
|
public requestAnimationFrame() { }
|
||||||
|
}
|
||||||
|
|
||||||
describe('Viewport', () => {
|
describe('Viewport', () => {
|
||||||
var terminal;
|
var terminal;
|
||||||
var viewportElement;
|
var viewportElement;
|
||||||
@@ -11,6 +16,7 @@ describe('Viewport', () => {
|
|||||||
const CHARACTER_HEIGHT = 10;
|
const CHARACTER_HEIGHT = 10;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
(<any>global).window = new MockWindow();
|
||||||
terminal = {
|
terminal = {
|
||||||
lines: [],
|
lines: [],
|
||||||
rows: 0,
|
rows: 0,
|
||||||
@@ -73,10 +79,14 @@ describe('Viewport', () => {
|
|||||||
terminal.rows = 1;
|
terminal.rows = 1;
|
||||||
assert.equal(scrollAreaElement.style.height, 0 * CHARACTER_HEIGHT + 'px');
|
assert.equal(scrollAreaElement.style.height, 0 * CHARACTER_HEIGHT + 'px');
|
||||||
viewport.syncScrollArea();
|
viewport.syncScrollArea();
|
||||||
|
assert.ok(viewport.isRefreshQueued);
|
||||||
|
viewport.refresh();
|
||||||
assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
|
assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
|
||||||
assert.equal(scrollAreaElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
|
assert.equal(scrollAreaElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
|
||||||
terminal.lines.push('');
|
terminal.lines.push('');
|
||||||
viewport.syncScrollArea();
|
viewport.syncScrollArea();
|
||||||
|
assert.ok(viewport.isRefreshQueued);
|
||||||
|
viewport.refresh();
|
||||||
assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
|
assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
|
||||||
assert.equal(scrollAreaElement.style.height, 2 * CHARACTER_HEIGHT + 'px');
|
assert.equal(scrollAreaElement.style.height, 2 * CHARACTER_HEIGHT + 'px');
|
||||||
});
|
});
|
||||||
|
|||||||
+17
-3
@@ -12,6 +12,7 @@ export class Viewport {
|
|||||||
private currentRowHeight: number;
|
private currentRowHeight: number;
|
||||||
private lastRecordedBufferLength: number;
|
private lastRecordedBufferLength: number;
|
||||||
private lastRecordedViewportHeight: number;
|
private lastRecordedViewportHeight: number;
|
||||||
|
private isRefreshQueued: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Viewport.
|
* Creates a new Viewport.
|
||||||
@@ -29,12 +30,25 @@ export class Viewport {
|
|||||||
this.currentRowHeight = 0;
|
this.currentRowHeight = 0;
|
||||||
this.lastRecordedBufferLength = 0;
|
this.lastRecordedBufferLength = 0;
|
||||||
this.lastRecordedViewportHeight = 0;
|
this.lastRecordedViewportHeight = 0;
|
||||||
|
this.isRefreshQueued = false;
|
||||||
|
|
||||||
this.terminal.on('scroll', this.syncScrollArea.bind(this));
|
this.terminal.on('scroll', this.syncScrollArea.bind(this));
|
||||||
this.terminal.on('resize', this.syncScrollArea.bind(this));
|
this.terminal.on('resize', this.syncScrollArea.bind(this));
|
||||||
this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));
|
this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));
|
||||||
|
|
||||||
this.syncScrollArea();
|
this.syncScrollArea();
|
||||||
|
this.refreshLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queues a refresh to be done on next animation frame.
|
||||||
|
*/
|
||||||
|
private refreshLoop(): void {
|
||||||
|
if (this.isRefreshQueued) {
|
||||||
|
this.refresh();
|
||||||
|
this.isRefreshQueued = false;
|
||||||
|
}
|
||||||
|
window.requestAnimationFrame(this.refreshLoop.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,15 +82,15 @@ export class Viewport {
|
|||||||
if (this.lastRecordedBufferLength !== this.terminal.lines.length) {
|
if (this.lastRecordedBufferLength !== this.terminal.lines.length) {
|
||||||
// If buffer height changed
|
// If buffer height changed
|
||||||
this.lastRecordedBufferLength = this.terminal.lines.length;
|
this.lastRecordedBufferLength = this.terminal.lines.length;
|
||||||
this.refresh();
|
this.isRefreshQueued = true;
|
||||||
} else if (this.lastRecordedViewportHeight !== this.terminal.rows) {
|
} else if (this.lastRecordedViewportHeight !== this.terminal.rows) {
|
||||||
// If viewport height changed
|
// If viewport height changed
|
||||||
this.refresh();
|
this.isRefreshQueued = true;
|
||||||
} else {
|
} else {
|
||||||
// If size has changed, refresh viewport
|
// If size has changed, refresh viewport
|
||||||
var size = this.charMeasureElement.getBoundingClientRect();
|
var size = this.charMeasureElement.getBoundingClientRect();
|
||||||
if (size.height !== this.currentRowHeight) {
|
if (size.height !== this.currentRowHeight) {
|
||||||
this.refresh(size);
|
this.isRefreshQueued = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user