]> git.proxmox.com Git - mirror_xterm.js.git/commitdiff
Merge pull request #810 from Tyriar/809_onSingleClick_null_check
authorDaniel Imms <tyriar@tyriar.com>
Fri, 21 Jul 2017 13:30:56 +0000 (06:30 -0700)
committerGitHub <noreply@github.com>
Fri, 21 Jul 2017 13:30:56 +0000 (06:30 -0700)
Make SelectionManager more resilient

src/SelectionManager.ts
src/utils/Mouse.ts

index 78494ae19304c195e0770a412de889a1eeec1433..8f1d0e2084a2426dddd56b14e07f9c4c610fcf76 100644 (file)
@@ -277,6 +277,10 @@ export class SelectionManager extends EventEmitter {
    */
   private _getMouseBufferCoords(event: MouseEvent): [number, number] {
     const coords = Mouse.getCoords(event, this._rowContainer, this._charMeasure, this._terminal.cols, this._terminal.rows, true);
+    if (!coords) {
+      return null;
+    }
+
     // Convert to 0-based
     coords[0]--;
     coords[1]--;
@@ -377,15 +381,25 @@ export class SelectionManager extends EventEmitter {
     this._model.selectionStartLength = 0;
     this._model.isSelectAllActive = false;
     this._activeSelectionMode = SelectionMode.NORMAL;
+
+    // Initialize the new selection
     this._model.selectionStart = this._getMouseBufferCoords(event);
-    if (this._model.selectionStart) {
-      this._model.selectionEnd = null;
-      // If the mouse is over the second half of a wide character, adjust the
-      // selection to cover the whole character
-      const char = this._buffer.get(this._model.selectionStart[1])[this._model.selectionStart[0]];
-      if (char[LINE_DATA_WIDTH_INDEX] === 0) {
-        this._model.selectionStart[0]++;
-      }
+    if (!this._model.selectionStart) {
+      return;
+    }
+    this._model.selectionEnd = null;
+
+    // Ensure the line exists
+    const line = this._buffer.get(this._model.selectionStart[1]);
+    if (!line) {
+      return;
+    }
+
+    // If the mouse is over the second half of a wide character, adjust the
+    // selection to cover the whole character
+    const char = line[this._model.selectionStart[0]];
+    if (char[LINE_DATA_WIDTH_INDEX] === 0) {
+      this._model.selectionStart[0]++;
     }
   }
 
@@ -426,6 +440,10 @@ export class SelectionManager extends EventEmitter {
 
     // Set the initial selection end based on the mouse coordinates
     this._model.selectionEnd = this._getMouseBufferCoords(event);
+    if (!this._model.selectionEnd) {
+      this.refresh(true);
+      return;
+    }
 
     // Select the entire line if line select mode is active.
     if (this._activeSelectionMode === SelectionMode.LINE) {
index a5d72c1e9310b199ca8df8b0c449548d7912795d..c61624e9ffdd6ef8e5dfbcfd088245ca1f444c1d 100644 (file)
@@ -37,7 +37,15 @@ export function getCoordsRelativeToElement(event: MouseEvent, element: HTMLEleme
  * select that cell and the right half will select the next cell.
  */
 export function getCoords(event: MouseEvent, rowContainer: HTMLElement, charMeasure: CharMeasure, colCount: number, rowCount: number, isSelection?: boolean): [number, number] {
+  // Coordinates cannot be measured if charMeasure has not been initialized
+  if (!charMeasure.width || !charMeasure.height) {
+    return null;
+  }
+
   const coords = getCoordsRelativeToElement(event, rowContainer);
+  if (!coords) {
+    return null;
+  }
 
   // Convert to cols/rows.
   coords[0] = Math.ceil((coords[0] + (isSelection ? charMeasure.width / 2 : 0)) / charMeasure.width);