diff --git a/src/xterm.js b/src/xterm.js index 39b4eb16..9afc08fd 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -438,6 +438,7 @@ this.queue = ''; this.scrollTop = 0; this.scrollBottom = this.rows - 1; + this.customKeydownHandler = null; // modes this.applicationKeypad = false; @@ -2648,6 +2649,18 @@ this.write(data + '\r\n'); }; + /** + * Attaches a custom keydown handler which is run before keys are processed, giving consumers of + * xterm.js ultimate control as to what keys should be processed by the terminal and what keys + * should not. + * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a + * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent + * the default action. The function returns whether the event should be processed by xterm.js. + */ + Terminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) { + this.customKeydownHandler = customKeydownHandler; + } + /** * Handle a keydown event * Key Resources: @@ -2655,6 +2668,10 @@ * @param {KeyboardEvent} ev The keydown event to be handled. */ Terminal.prototype.keyDown = function(ev) { + if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) { + return false; + } + if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) { return false; } diff --git a/test/test.js b/test/test.js index efa25095..d2842f81 100644 --- a/test/test.js +++ b/test/test.js @@ -57,6 +57,39 @@ describe('xterm.js', function() { }); }); + describe('attachCustomEventHandler', function () { + var evKeyDown = { + preventDefault: function() {}, + stopPropagation: function() {}, + type: 'keydown' + } + + beforeEach(function() { + xterm.handler = function() {}; + xterm.showCursor = function() {}; + xterm.clearSelection = function() {}; + xterm.compositionHelper = { + keydown: { + bind: function() { + return function () { return true; } + } + } + } + }); + + it('should process the keydown event based on what the handler returns', function () { + assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), true); + xterm.attachCustomKeydownHandler(function (ev) { + return ev.keyCode === 77; + }); + assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), true); + xterm.attachCustomKeydownHandler(function (ev) { + return ev.keyCode !== 77; + }); + assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), false); + }); + }); + describe('evaluateCopiedTextProcessing', function () { it('should strip trailing whitespaces and replace nbsps with spaces', function () { var nonBreakingSpace = String.fromCharCode(160),