]> git.proxmox.com Git - mirror_xterm.js.git/commitdiff
Merge pull request #370 from Tyriar/335_Viewport_ts
authorDaniel Imms <tyriar@tyriar.com>
Tue, 22 Nov 2016 15:59:46 +0000 (07:59 -0800)
committerGitHub <noreply@github.com>
Tue, 22 Nov 2016 15:59:46 +0000 (07:59 -0800)
Convert Viewport to TypeScript

src/Interfaces.ts [new file with mode: 0644]
src/Viewport.js [deleted file]
src/Viewport.test.ts [new file with mode: 0644]
src/Viewport.ts [new file with mode: 0644]
src/test/viewport-test.js [deleted file]

diff --git a/src/Interfaces.ts b/src/Interfaces.ts
new file mode 100644 (file)
index 0000000..14355e5
--- /dev/null
@@ -0,0 +1,14 @@
+/**
+ * xterm.js: xterm, in the browser
+ * Copyright (c) 2014-2016, SourceLair Private Company (www.sourcelair.com (MIT License)
+ */
+
+export interface ITerminal {
+  rowContainer: HTMLElement;
+  ydisp: number;
+  lines: string[];
+  rows: number;
+
+  on(event: string, callback: () => void);
+  scrollDisp(disp: number, suppressScrollEvent: boolean);
+}
diff --git a/src/Viewport.js b/src/Viewport.js
deleted file mode 100644 (file)
index b47e805..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * xterm.js: xterm, in the browser
- * Copyright (c) 2014-2016, SourceLair Private Company (www.sourcelair.com (MIT License)
- */
-
-/**
- * Represents the viewport of a terminal, the visible area within the larger buffer of output.
- * Logic for the virtual scroll bar is included in this object.
- * @param {Terminal} terminal The Terminal object.
- * @param {HTMLElement} viewportElement The DOM element acting as the viewport
- * @param {HTMLElement} charMeasureElement A DOM element used to measure the character size of
- *   the terminal.
- */
-function Viewport(terminal, viewportElement, scrollArea, charMeasureElement) {
-  this.terminal = terminal;
-  this.viewportElement = viewportElement;
-  this.scrollArea = scrollArea;
-  this.charMeasureElement = charMeasureElement;
-  this.currentRowHeight = 0;
-  this.lastRecordedBufferLength = 0;
-  this.lastRecordedViewportHeight = 0;
-
-  this.terminal.on('scroll', this.syncScrollArea.bind(this));
-  this.terminal.on('resize', this.syncScrollArea.bind(this));
-  this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));
-
-  this.syncScrollArea();
-}
-
-/**
- * Refreshes row height, setting line-height, viewport height and scroll area height if
- * necessary.
- * @param {number|undefined} charSize A character size measurement bounding rect object, if it
- *   doesn't exist it will be created.
- */
-Viewport.prototype.refresh = function(charSize) {
-  var size = charSize || this.charMeasureElement.getBoundingClientRect();
-  if (size.height > 0) {
-    var rowHeightChanged = size.height !== this.currentRowHeight;
-    if (rowHeightChanged) {
-      this.currentRowHeight = size.height;
-      this.viewportElement.style.lineHeight = size.height + 'px';
-      this.terminal.rowContainer.style.lineHeight = size.height + 'px';
-    }
-    var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;
-    if (rowHeightChanged || viewportHeightChanged) {
-      this.lastRecordedViewportHeight = this.terminal.rows;
-      this.viewportElement.style.height = size.height * this.terminal.rows + 'px';
-    }
-    this.scrollArea.style.height = (size.height * this.lastRecordedBufferLength) + 'px';
-  }
-};
-
-/**
- * Updates dimensions and synchronizes the scroll area if necessary.
- */
-Viewport.prototype.syncScrollArea = function() {
-  if (this.lastRecordedBufferLength !== this.terminal.lines.length) {
-    // If buffer height changed
-    this.lastRecordedBufferLength = this.terminal.lines.length;
-    this.refresh();
-  } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {
-    // If viewport height changed
-    this.refresh();
-  } else {
-    // If size has changed, refresh viewport
-    var size = this.charMeasureElement.getBoundingClientRect();
-    if (size.height !== this.currentRowHeight) {
-      this.refresh(size);
-    }
-  }
-
-  // Sync scrollTop
-  var scrollTop = this.terminal.ydisp * this.currentRowHeight;
-  if (this.viewportElement.scrollTop !== scrollTop) {
-    this.viewportElement.scrollTop = scrollTop;
-  }
-};
-
-/**
- * Handles scroll events on the viewport, calculating the new viewport and requesting the
- * terminal to scroll to it.
- * @param {Event} ev The scroll event.
- */
-Viewport.prototype.onScroll = function(ev) {
-  var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);
-  var diff = newRow - this.terminal.ydisp;
-  this.terminal.scrollDisp(diff, true);
-};
-
-/**
- * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual
- * scrolling to `onScroll`, this event needs to be attached manually by the consumer of
- * `Viewport`.
- * @param {WheelEvent} ev The mouse wheel event.
- */
-Viewport.prototype.onWheel = function(ev) {
-  if (ev.deltaY === 0) {
-    // Do nothing if it's not a vertical scroll event
-    return;
-  }
-  // Fallback to WheelEvent.DOM_DELTA_PIXEL
-  var multiplier = 1;
-  if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {
-    multiplier = this.currentRowHeight;
-  } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
-    multiplier = this.currentRowHeight * this.terminal.rows;
-  }
-  this.viewportElement.scrollTop += ev.deltaY * multiplier;
-  // Prevent the page from scrolling when the terminal scrolls
-  ev.preventDefault();
-};
-
-export { Viewport };
diff --git a/src/Viewport.test.ts b/src/Viewport.test.ts
new file mode 100644 (file)
index 0000000..5b106b4
--- /dev/null
@@ -0,0 +1,84 @@
+import { assert } from 'chai';
+import { Viewport } from './Viewport';
+
+describe('Viewport', () => {
+  var terminal;
+  var viewportElement;
+  var charMeasureElement;
+  var viewport;
+  var scrollAreaElement;
+
+  const CHARACTER_HEIGHT = 10;
+
+  beforeEach(() => {
+    terminal = {
+      lines: [],
+      rows: 0,
+      ydisp: 0,
+      on: () => {},
+      rowContainer: {
+        style: {
+          lineHeight: 0
+        }
+      }
+    };
+    viewportElement = {
+      addEventListener: () => {},
+      style: {
+        height: 0,
+        lineHeight: 0
+      }
+    };
+    scrollAreaElement = {
+      style: {
+        height: 0
+      }
+    };
+    charMeasureElement = {
+      getBoundingClientRect: () => {
+        return { width: null, height: CHARACTER_HEIGHT };
+      }
+    };
+    viewport = new Viewport(terminal, viewportElement, scrollAreaElement, charMeasureElement);
+  });
+
+  describe('refresh', () => {
+    it('should set the line-height of the terminal', () => {
+      assert.equal(viewportElement.style.lineHeight, CHARACTER_HEIGHT + 'px');
+      assert.equal(terminal.rowContainer.style.lineHeight, CHARACTER_HEIGHT + 'px');
+      charMeasureElement.getBoundingClientRect = () => {
+        return { width: null, height: 1 };
+      };
+      viewport.refresh();
+      assert.equal(viewportElement.style.lineHeight, '1px');
+      assert.equal(terminal.rowContainer.style.lineHeight, '1px');
+    });
+    it('should set the height of the viewport when the line-height changed', () => {
+      terminal.lines.push('');
+      terminal.lines.push('');
+      terminal.rows = 1;
+      viewport.refresh();
+      assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
+      charMeasureElement.getBoundingClientRect = () => {
+        return { width: null, height: 20 };
+      };
+      viewport.refresh();
+      assert.equal(viewportElement.style.height, 20 + 'px');
+    });
+  });
+
+  describe('syncScrollArea', () => {
+    it('should sync the scroll area', () => {
+      terminal.lines.push('');
+      terminal.rows = 1;
+      assert.equal(scrollAreaElement.style.height, 0 * CHARACTER_HEIGHT + 'px');
+      viewport.syncScrollArea();
+      assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
+      assert.equal(scrollAreaElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
+      terminal.lines.push('');
+      viewport.syncScrollArea();
+      assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
+      assert.equal(scrollAreaElement.style.height, 2 * CHARACTER_HEIGHT + 'px');
+    });
+  });
+});
diff --git a/src/Viewport.ts b/src/Viewport.ts
new file mode 100644 (file)
index 0000000..11889da
--- /dev/null
@@ -0,0 +1,120 @@
+/**
+ * xterm.js: xterm, in the browser
+ * Copyright (c) 2014-2016, SourceLair Private Company (www.sourcelair.com (MIT License)
+ */
+
+import { ITerminal } from './Interfaces';
+
+/**
+ * Represents the viewport of a terminal, the visible area within the larger buffer of output.
+ * Logic for the virtual scroll bar is included in this object.
+ * @param viewportElement The DOM element acting as the viewport.
+ * @param scrollArea The DOM element acting as the scroll area.
+ * @param charMeasureElement A DOM element used to measure the character size of. the terminal.
+ */
+export class Viewport {
+  private currentRowHeight: number;
+  private lastRecordedBufferLength: number;
+  private lastRecordedViewportHeight: number;
+
+  constructor(
+    private terminal: ITerminal,
+    private viewportElement: HTMLElement,
+    private scrollArea: HTMLElement,
+    private charMeasureElement: HTMLElement
+  ) {
+    this.currentRowHeight = 0;
+    this.lastRecordedBufferLength = 0;
+    this.lastRecordedViewportHeight = 0;
+
+    this.terminal.on('scroll', this.syncScrollArea.bind(this));
+    this.terminal.on('resize', this.syncScrollArea.bind(this));
+    this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));
+
+    this.syncScrollArea();
+  }
+
+  /**
+   * Refreshes row height, setting line-height, viewport height and scroll area height if
+   * necessary.
+   * @param charSize A character size measurement bounding rect object, if it doesn't exist it will
+   *   be created.
+   */
+  private refresh(charSize?: ClientRect): void {
+    var size = charSize || this.charMeasureElement.getBoundingClientRect();
+    if (size.height > 0) {
+      var rowHeightChanged = size.height !== this.currentRowHeight;
+      if (rowHeightChanged) {
+        this.currentRowHeight = size.height;
+        this.viewportElement.style.lineHeight = size.height + 'px';
+        this.terminal.rowContainer.style.lineHeight = size.height + 'px';
+      }
+      var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;
+      if (rowHeightChanged || viewportHeightChanged) {
+        this.lastRecordedViewportHeight = this.terminal.rows;
+        this.viewportElement.style.height = size.height * this.terminal.rows + 'px';
+      }
+      this.scrollArea.style.height = (size.height * this.lastRecordedBufferLength) + 'px';
+    }
+  }
+
+  /**
+   * Updates dimensions and synchronizes the scroll area if necessary.
+   */
+  public syncScrollArea(): void {
+    if (this.lastRecordedBufferLength !== this.terminal.lines.length) {
+      // If buffer height changed
+      this.lastRecordedBufferLength = this.terminal.lines.length;
+      this.refresh();
+    } else if (this.lastRecordedViewportHeight !== this.terminal.rows) {
+      // If viewport height changed
+      this.refresh();
+    } else {
+      // If size has changed, refresh viewport
+      var size = this.charMeasureElement.getBoundingClientRect();
+      if (size.height !== this.currentRowHeight) {
+        this.refresh(size);
+      }
+    }
+
+    // Sync scrollTop
+    var scrollTop = this.terminal.ydisp * this.currentRowHeight;
+    if (this.viewportElement.scrollTop !== scrollTop) {
+      this.viewportElement.scrollTop = scrollTop;
+    }
+  }
+
+  /**
+   * Handles scroll events on the viewport, calculating the new viewport and requesting the
+   * terminal to scroll to it.
+   * @param ev The scroll event.
+   */
+  private onScroll(ev: Event) {
+    var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);
+    var diff = newRow - this.terminal.ydisp;
+    this.terminal.scrollDisp(diff, true);
+  }
+
+  /**
+   * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual
+   * scrolling to `onScroll`, this event needs to be attached manually by the consumer of
+   * `Viewport`.
+   * @param ev The mouse wheel event.
+   */
+  public onWheel(ev: WheelEvent) {
+    if (ev.deltaY === 0) {
+      // Do nothing if it's not a vertical scroll event
+      return;
+    }
+    // Fallback to WheelEvent.DOM_DELTA_PIXEL
+    var multiplier = 1;
+    if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {
+      multiplier = this.currentRowHeight;
+    } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
+      multiplier = this.currentRowHeight * this.terminal.rows;
+    }
+    this.viewportElement.scrollTop += ev.deltaY * multiplier;
+    // Prevent the page from scrolling when the terminal scrolls
+    ev.preventDefault();
+  };
+}
diff --git a/src/test/viewport-test.js b/src/test/viewport-test.js
deleted file mode 100644 (file)
index 376fcdc..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-var assert = require('chai').assert;
-var Terminal = require('../xterm');
-
-describe('Viewport', function () {
-  var terminal;
-  var viewportElement;
-  var charMeasureElement;
-  var viewport;
-  var scrollAreaElement;
-
-  var CHARACTER_HEIGHT = 10;
-
-  beforeEach(function () {
-    terminal = {
-      lines: [],
-      rows: 0,
-      ydisp: 0,
-      on: function () {},
-      rowContainer: {
-        style: {
-          lineHeight: 0
-        }
-      }
-    };
-    viewportElement = {
-      addEventListener: function () {},
-      style: {
-        height: 0,
-        lineHeight: 0
-      }
-    };
-    scrollAreaElement = {
-      style: {
-        height: 0
-      }
-    };
-    charMeasureElement = {
-      getBoundingClientRect: function () {
-        return { width: null, height: CHARACTER_HEIGHT };
-      }
-    };
-    viewport = new Terminal.Viewport(terminal, viewportElement, scrollAreaElement, charMeasureElement);
-  });
-
-  describe('Public API', function () {
-    it('should define Viewport.prototype.onWheel', function () {
-      assert.isDefined(Terminal.Viewport.prototype.onWheel);
-    });
-  });
-
-  describe('refresh', function () {
-    it('should set the line-height of the terminal', function () {
-      assert.equal(viewportElement.style.lineHeight, CHARACTER_HEIGHT + 'px');
-      assert.equal(terminal.rowContainer.style.lineHeight, CHARACTER_HEIGHT + 'px');
-      charMeasureElement.getBoundingClientRect = function () {
-        return { width: null, height: 1 };
-      };
-      viewport.refresh();
-      assert.equal(viewportElement.style.lineHeight, '1px');
-      assert.equal(terminal.rowContainer.style.lineHeight, '1px');
-    });
-    it('should set the height of the viewport when the line-height changed', function () {
-      terminal.lines.push('');
-      terminal.lines.push('');
-      terminal.rows = 1;
-      viewport.refresh();
-      assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
-      charMeasureElement.getBoundingClientRect = function () {
-        return { width: null, height: 20 };
-      };
-      viewport.refresh();
-      assert.equal(viewportElement.style.height, 20 + 'px');
-    });
-  });
-
-  describe('syncScrollArea', function () {
-    it('should sync the scroll area', function () {
-      terminal.lines.push('');
-      terminal.rows = 1;
-      assert.equal(scrollAreaElement.style.height, 0 * CHARACTER_HEIGHT + 'px');
-      viewport.syncScrollArea();
-      assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
-      assert.equal(scrollAreaElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
-      terminal.lines.push('');
-      viewport.syncScrollArea();
-      assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
-      assert.equal(scrollAreaElement.style.height, 2 * CHARACTER_HEIGHT + 'px');
-    });
-  });
-});