diff --git a/package.json b/package.json index 93ed9a7b..519b7400 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ "repository": "https://github.com/sourcelair/xterm.js", "license": "MIT", "devDependencies": { + "@types/chai": "^3.4.34", + "@types/mocha": "^2.2.33", "@types/node": "^6.0.41", "browserify": "^13.1.0", "chai": "3.5.0", diff --git a/src/test/test.js b/src/test/test.js index 08593e12..6f700002 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -194,7 +194,7 @@ describe('xterm.js', function() { terminal.ydisp = 0; terminal.ybase = 40; - terminal.keyDown(); + terminal.keyDown({ keyCode: 0 }); // Ensure that now the terminal is scrolled to bottom assert.equal(terminal.ydisp, terminal.ybase); diff --git a/src/utils/Keyboard.test.ts b/src/utils/Keyboard.test.ts new file mode 100644 index 00000000..618d3331 --- /dev/null +++ b/src/utils/Keyboard.test.ts @@ -0,0 +1,21 @@ +import { assert } from 'chai'; +import * as Keyboard from './Keyboard'; + +describe('Keyboard', () => { + describe('isModifierOnlyKeyboardEvent', () => { + it('should return true when only modifier keys are used', () => { + // Note that KeyboardEvent.keyCode is deprecated but we're using it to improve browser + // compatibility. This helper returns the `any` type because KeyboardEvent doesn't exist under + // NodeJS. + function createEvent(keyCode: number): any { + return { keyCode }; + } + assert.isTrue(Keyboard.isModifierOnlyKeyboardEvent(createEvent(16))); + assert.isTrue(Keyboard.isModifierOnlyKeyboardEvent(createEvent(17))); + assert.isTrue(Keyboard.isModifierOnlyKeyboardEvent(createEvent(18))); + assert.isTrue(Keyboard.isModifierOnlyKeyboardEvent(createEvent(91))); + assert.isFalse(Keyboard.isModifierOnlyKeyboardEvent(createEvent(19))); + assert.isFalse(Keyboard.isModifierOnlyKeyboardEvent(createEvent(90))); + }); + }); +}); diff --git a/src/utils/Keyboard.ts b/src/utils/Keyboard.ts new file mode 100644 index 00000000..e43cba45 --- /dev/null +++ b/src/utils/Keyboard.ts @@ -0,0 +1,22 @@ +/** + * xterm.js: xterm, in the browser + * Copyright (c) 2016, SourceLair Private Company (MIT License) + */ + +/** + * Keyboard utilities module. This module contains utilities for dealing with keyboard interaction. + * @module xterm/utils/Keyboard + */ + +/** + * Gets whether a KeyboardEvent is made up entirely of modifier keys. + * + * @param event The event to check. + * @return Whether the KeyboardEvent is made up entirely of modifier keys. + */ +export function isModifierOnlyKeyboardEvent(event: KeyboardEvent): boolean { + return event.keyCode === 16 || // Shift + event.keyCode === 17 || // Control + event.keyCode === 18 || // Alt + event.keyCode === 91; // Meta +} diff --git a/src/xterm.js b/src/xterm.js index 85efc223..5924b796 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -36,6 +36,7 @@ import { EventEmitter } from './EventEmitter.js'; import { Viewport } from './Viewport.js'; import { rightClickHandler, pasteHandler, copyHandler } from './handlers/Clipboard.js'; import * as Browser from './utils/Browser'; +import * as Keyboard from './utils/Keyboard'; /** * Terminal Emulation References: @@ -2426,7 +2427,7 @@ Terminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) { */ Terminal.prototype.keyDown = function(ev) { // Scroll down to prompt, whenever the user presses a key. - if (this.ybase !== this.ydisp) { + if (!Keyboard.isModifierOnlyKeyboardEvent(ev) && this.ybase !== this.ydisp) { this.scrollToBottom(); }