+ };
+ kbd._handleKeyDown(keyevent('keydown', {code: 'AltLeft', key: 'Alt', location: 1}));
+ kbd._handleKeyDown(keyevent('keydown', {code: 'AltRight', key: 'Alt', location: 2}));
+ expect(count).to.be.equal(2);
+ });
+ it('should change left Super to Alt', function(done) {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = (keysym, code, down) => {
+ expect(keysym).to.be.equal(0xFFE9);
+ expect(code).to.be.equal('MetaLeft');
+ done();
+ };
+ kbd._handleKeyDown(keyevent('keydown', {code: 'MetaLeft', key: 'Meta', location: 1}));
+ });
+ it('should change right Super to left Super', function(done) {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = (keysym, code, down) => {
+ expect(keysym).to.be.equal(0xFFEB);
+ expect(code).to.be.equal('MetaRight');
+ done();
+ };
+ kbd._handleKeyDown(keyevent('keydown', {code: 'MetaRight', key: 'Meta', location: 2}));
+ });
+ });
+
+ describe('Escape AltGraph on Windows', function() {
+ let origNavigator;
+ beforeEach(function () {
+ // window.navigator is a protected read-only property in many
+ // environments, so we need to redefine it whilst running these
+ // tests.
+ origNavigator = Object.getOwnPropertyDescriptor(window, "navigator");
+ if (origNavigator === undefined) {
+ // Object.getOwnPropertyDescriptor() doesn't work
+ // properly in any version of IE
+ this.skip();
+ }
+
+ Object.defineProperty(window, "navigator", {value: {}});
+ if (window.navigator.platform !== undefined) {
+ // Object.defineProperty() doesn't work properly in old
+ // versions of Chrome
+ this.skip();
+ }
+
+ window.navigator.platform = "Windows x86_64";
+
+ this.clock = sinon.useFakeTimers();
+ });
+ afterEach(function () {
+ Object.defineProperty(window, "navigator", origNavigator);
+ this.clock.restore();
+ });
+
+ it('should supress ControlLeft until it knows if it is AltGr', function () {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = sinon.spy();
+ kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
+ expect(kbd.onkeyevent).to.not.have.been.called;
+ });
+
+ it('should not trigger on repeating ControlLeft', function () {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = sinon.spy();
+ kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
+ kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
+ expect(kbd.onkeyevent).to.have.been.calledTwice;
+ expect(kbd.onkeyevent.firstCall).to.have.been.calledWith(0xffe3, "ControlLeft", true);
+ expect(kbd.onkeyevent.secondCall).to.have.been.calledWith(0xffe3, "ControlLeft", true);
+ });
+
+ it('should not supress ControlRight', function () {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = sinon.spy();
+ kbd._handleKeyDown(keyevent('keydown', {code: 'ControlRight', key: 'Control', location: 2}));
+ expect(kbd.onkeyevent).to.have.been.calledOnce;
+ expect(kbd.onkeyevent).to.have.been.calledWith(0xffe4, "ControlRight", true);
+ });
+
+ it('should release ControlLeft after 100 ms', function () {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = sinon.spy();
+ kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
+ expect(kbd.onkeyevent).to.not.have.been.called;
+ this.clock.tick(100);
+ expect(kbd.onkeyevent).to.have.been.calledOnce;
+ expect(kbd.onkeyevent).to.have.been.calledWith(0xffe3, "ControlLeft", true);
+ });
+
+ it('should release ControlLeft on other key press', function () {
+ const kbd = new Keyboard(document);
+ kbd.onkeyevent = sinon.spy();
+ kbd._handleKeyDown(keyevent('keydown', {code: 'ControlLeft', key: 'Control', location: 1}));
+ expect(kbd.onkeyevent).to.not.have.been.called;