Skip to content

Commit

Permalink
Added support for 'keydown' and 'keyup' events (#6421)
Browse files Browse the repository at this point in the history
* Added support for 'keydown' and 'keyup' events, as requested in issue #5734

* Added tests for 'keydown', 'keypress' and 'keyup' events binding and constified the key codes used in the test file
  • Loading branch information
OrBin authored and perliedman committed Jan 14, 2019
1 parent 62ee339 commit 59a2d75
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 34 deletions.
117 changes: 87 additions & 30 deletions spec/suites/map/handler/Map.KeyboardSpec.js
@@ -1,5 +1,14 @@
describe("Map.Keyboard", function () {

const KEYCODE_LOWERCASE_A = 65;
const KEYCODE_ARROW_LEFT = 37;
const KEYCODE_ARROW_UP = 38;
const KEYCODE_ARROW_RIGHT = 39;
const KEYCODE_ARROW_DOWN = 40;
const KEYCODE_PLUS = 171;
const KEYCODE_MINUS = 173;
const KEYCODE_ESC = 27;

var map, container;

beforeEach(function () {
Expand All @@ -25,12 +34,12 @@ describe("Map.Keyboard", function () {
document.body.removeChild(container);
});

describe("cursor keys", function () {
describe("arrow keys", function () {
it("move the map north", function (done) {

happen.keydown(document, {keyCode: 38}); // 38 = cursor up
happen.keypress(document, {keyCode: 38});
happen.keyup(document, {keyCode: 38});
happen.keydown(document, {keyCode: KEYCODE_ARROW_UP});
happen.keypress(document, {keyCode: KEYCODE_ARROW_UP});
happen.keyup(document, {keyCode: KEYCODE_ARROW_UP});

setTimeout(function () {
expect(map.getCenter().lat).to.be.greaterThan(0);
Expand All @@ -40,9 +49,9 @@ describe("Map.Keyboard", function () {

it("move the map south", function (done) {

happen.keydown(document, {keyCode: 40}); // 40 = cursor down
happen.keypress(document, {keyCode: 40});
happen.keyup(document, {keyCode: 40});
happen.keydown(document, {keyCode: KEYCODE_ARROW_DOWN});
happen.keypress(document, {keyCode: KEYCODE_ARROW_DOWN});
happen.keyup(document, {keyCode: KEYCODE_ARROW_DOWN});

setTimeout(function () {
expect(map.getCenter().lat).to.be.lessThan(0);
Expand All @@ -52,9 +61,9 @@ describe("Map.Keyboard", function () {

it("move the map west", function (done) {

happen.keydown(document, {keyCode: 37}); // 37 = cursor left
happen.keypress(document, {keyCode: 37});
happen.keyup(document, {keyCode: 37});
happen.keydown(document, {keyCode: KEYCODE_ARROW_LEFT});
happen.keypress(document, {keyCode: KEYCODE_ARROW_LEFT});
happen.keyup(document, {keyCode: KEYCODE_ARROW_LEFT});

setTimeout(function () {
expect(map.getCenter().lng).to.be.lessThan(0);
Expand All @@ -64,9 +73,9 @@ describe("Map.Keyboard", function () {

it("move the map east", function (done) {

happen.keydown(document, {keyCode: 39}); // 39 = cursor right
happen.keypress(document, {keyCode: 39});
happen.keyup(document, {keyCode: 39});
happen.keydown(document, {keyCode: KEYCODE_ARROW_RIGHT});
happen.keypress(document, {keyCode: KEYCODE_ARROW_RIGHT});
happen.keyup(document, {keyCode: KEYCODE_ARROW_RIGHT});

setTimeout(function () {
expect(map.getCenter().lng).to.be.greaterThan(0);
Expand All @@ -78,9 +87,9 @@ describe("Map.Keyboard", function () {
describe("plus/minus keys", function () {
it("zoom in", function (done) {

happen.keydown(document, {keyCode: 171}); // 171 = +
happen.keypress(document, {keyCode: 171});
happen.keyup(document, {keyCode: 171});
happen.keydown(document, {keyCode: KEYCODE_PLUS});
happen.keypress(document, {keyCode: KEYCODE_PLUS});
happen.keyup(document, {keyCode: KEYCODE_PLUS});

setTimeout(function () {
expect(map.getZoom()).to.be.greaterThan(5);
Expand All @@ -90,9 +99,9 @@ describe("Map.Keyboard", function () {

it("zoom out", function (done) {

happen.keydown(document, {keyCode: 173}); // 173 = - (in firefox)
happen.keypress(document, {keyCode: 173});
happen.keyup(document, {keyCode: 173});
happen.keydown(document, {keyCode: KEYCODE_MINUS});
happen.keypress(document, {keyCode: KEYCODE_MINUS});
happen.keyup(document, {keyCode: KEYCODE_MINUS});

setTimeout(function () {
expect(map.getZoom()).to.be.lessThan(5);
Expand All @@ -106,9 +115,9 @@ describe("Map.Keyboard", function () {

map.keyboard.disable();

happen.keydown(document, {keyCode: 171}); // 171 = +
happen.keypress(document, {keyCode: 171});
happen.keyup(document, {keyCode: 171});
happen.keydown(document, {keyCode: KEYCODE_PLUS});
happen.keypress(document, {keyCode: KEYCODE_PLUS});
happen.keyup(document, {keyCode: KEYCODE_PLUS});

setTimeout(function () {
expect(map.getZoom()).to.eql(5);
Expand All @@ -120,9 +129,9 @@ describe("Map.Keyboard", function () {

map.keyboard.disable();

happen.keydown(document, {keyCode: 38}); // 38 = cursor up
happen.keypress(document, {keyCode: 38});
happen.keyup(document, {keyCode: 38});
happen.keydown(document, {keyCode: KEYCODE_ARROW_UP});
happen.keypress(document, {keyCode: KEYCODE_ARROW_UP});
happen.keyup(document, {keyCode: KEYCODE_ARROW_UP});

setTimeout(function () {
expect(map.getCenter().lat).to.eql(0);
Expand All @@ -140,9 +149,8 @@ describe("Map.Keyboard", function () {

expect(popup.isOpen()).to.be(true);

happen.keydown(document, {keyCode: 27}); // 27 = Esc
// happen.keypress(document, {keyCode: 27});
happen.keyup(document, {keyCode: 27});
happen.keydown(document, {keyCode: KEYCODE_ESC});
happen.keyup(document, {keyCode: KEYCODE_ESC});

expect(popup.isOpen()).to.be(false);
});
Expand All @@ -156,11 +164,60 @@ describe("Map.Keyboard", function () {

expect(popup.isOpen()).to.be(true);

happen.keydown(document, {keyCode: 27});
happen.keyup(document, {keyCode: 27});
happen.keydown(document, {keyCode: KEYCODE_ESC});
happen.keyup(document, {keyCode: KEYCODE_ESC});

expect(popup.isOpen()).to.be(true);
});
});

describe("keys events binding", function () {
it("keypress", function (done) {
var keyDownSpy = sinon.spy();
var keyPressSpy = sinon.spy();
var keyUpSpy = sinon.spy();

map.on('keypress', keyPressSpy);
happen.keypress(container, {keyCode: KEYCODE_LOWERCASE_A});

setTimeout(function () {
expect(keyDownSpy.called).to.be(false);
expect(keyPressSpy.called).to.be.ok();
expect(keyUpSpy.called).to.be(false);
done();
}, 50);
});

it("keydown", function (done) {
var keyDownSpy = sinon.spy();
var keyPressSpy = sinon.spy();
var keyUpSpy = sinon.spy();

map.on('keydown', keyDownSpy);
happen.keydown(container, {keyCode: KEYCODE_LOWERCASE_A});

setTimeout(function () {
expect(keyDownSpy.called).to.be.ok();
expect(keyPressSpy.called).to.be(false);
expect(keyUpSpy.called).to.be(false);
done();
}, 50);
});

it("keyup", function (done) {
var keyDownSpy = sinon.spy();
var keyPressSpy = sinon.spy();
var keyUpSpy = sinon.spy();

map.on('keyup', keyUpSpy);
happen.keyup(container, {keyCode: KEYCODE_LOWERCASE_A});

setTimeout(function () {
expect(keyDownSpy.called).to.be(false);
expect(keyPressSpy.called).to.be(false);
expect(keyUpSpy.called).to.be.ok();
done();
}, 50);
});
});
});
14 changes: 10 additions & 4 deletions src/map/Map.js
Expand Up @@ -1316,9 +1316,15 @@ export var Map = Evented.extend({
// this event. Also fired on mobile when the user holds a single touch
// for a second (also called long press).
// @event keypress: KeyboardEvent
// Fired when the user presses a key from the keyboard while the map is focused.
// Fired when the user presses a key from the keyboard that produces a character value while the map is focused.
// @event keydown: KeyboardEvent
// Fired when the user presses a key from the keyboard while the map is focused. Unlike the `keypress` event,
// the `keydown` event is fired for keys that produce a character value and for keys
// that do not produce a character value.
// @event keyup: KeyboardEvent
// Fired when the user releases a key from the keyboard while the map is focused.
onOff(this._container, 'click dblclick mousedown mouseup ' +
'mouseover mouseout mousemove contextmenu keypress', this._handleDOMEvent, this);
'mouseover mouseout mousemove contextmenu keypress keydown keyup', this._handleDOMEvent, this);

if (this.options.trackResize) {
onOff(window, 'resize', this._onResize, this);
Expand Down Expand Up @@ -1382,7 +1388,7 @@ export var Map = Evented.extend({

var type = e.type;

if (type === 'mousedown' || type === 'keypress') {
if (type === 'mousedown' || type === 'keypress' || type === 'keyup' || type === 'keydown') {
// prevents outline when clicking on keyboard-focusable element
DomUtil.preventOutline(e.target || e.srcElement);
}
Expand Down Expand Up @@ -1421,7 +1427,7 @@ export var Map = Evented.extend({
originalEvent: e
};

if (e.type !== 'keypress') {
if (e.type !== 'keypress' && e.type !== 'keydown' && e.type !== 'keyup') {
var isMarker = target.getLatLng && (!target._radius || target._radius <= 10);
data.containerPoint = isMarker ?
this.latLngToContainerPoint(target.getLatLng()) : this.mouseEventToContainerPoint(e);
Expand Down

0 comments on commit 59a2d75

Please sign in to comment.