add an observeElement option to Handler.Keyboard and Control.KeyboardDefaults to control the DOM element on which key events are observed

This commit is contained in:
Éric Lemoine
2012-01-26 13:11:33 +01:00
parent 2ecec3ddc3
commit c0b02b278a
4 changed files with 95 additions and 27 deletions

View File

@@ -46,7 +46,11 @@
var map = null; var map = null;
function init(){ function init(){
var options = { var options = {
controls: [new OpenLayers.Control.KeyboardDefaults()] controls: [
new OpenLayers.Control.KeyboardDefaults({
observeElement: 'map'
})
]
}; };
map = new OpenLayers.Map('map', options); map = new OpenLayers.Map('map', options);
var wms = new OpenLayers.Layer.WMS( var wms = new OpenLayers.Layer.WMS(

View File

@@ -34,6 +34,15 @@ OpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {
*/ */
slideFactor: 75, slideFactor: 75,
/**
* APIProperty: observeElement
* {DOMelement|String} The DOM element to handle keys for. You
* can use the map div here, to have the navigation keys
* work when the map div has the focus. If undefined the
* document is used.
*/
observeElement: null,
/** /**
* Constructor: OpenLayers.Control.KeyboardDefaults * Constructor: OpenLayers.Control.KeyboardDefaults
*/ */
@@ -43,8 +52,11 @@ OpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {
* Create handler. * Create handler.
*/ */
draw: function() { draw: function() {
this.handler = new OpenLayers.Handler.Keyboard( this, { var observeElement = this.observeElement || document;
"keydown": this.defaultKeyPress }); this.handler = new OpenLayers.Handler.Keyboard( this,
{"keydown": this.defaultKeyPress},
{observeElement: observeElement}
);
}, },
/** /**

View File

@@ -33,6 +33,13 @@ OpenLayers.Handler.Keyboard = OpenLayers.Class(OpenLayers.Handler, {
*/ */
eventListener: null, eventListener: null,
/**
* Property: observeElement
* {DOMElement|String} The DOM element on which we listen for
* key events. Default to the document.
*/
observeElement: null,
/** /**
* Constructor: OpenLayers.Handler.Keyboard * Constructor: OpenLayers.Handler.Keyboard
* Returns a new keyboard handler. * Returns a new keyboard handler.
@@ -71,9 +78,10 @@ OpenLayers.Handler.Keyboard = OpenLayers.Class(OpenLayers.Handler, {
*/ */
activate: function() { activate: function() {
if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) { if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
this.observeElement = this.observeElement || document;
for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) { for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) {
OpenLayers.Event.observe( OpenLayers.Event.observe(
this.map.div, this.KEY_EVENTS[i], this.eventListener); this.observeElement, this.KEY_EVENTS[i], this.eventListener);
} }
return true; return true;
} else { } else {
@@ -89,7 +97,7 @@ OpenLayers.Handler.Keyboard = OpenLayers.Class(OpenLayers.Handler, {
if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) { if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) { for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) {
OpenLayers.Event.stopObserving( OpenLayers.Event.stopObserving(
this.map.div, this.KEY_EVENTS[i], this.eventListener); this.observeElement, this.KEY_EVENTS[i], this.eventListener);
} }
deactivated = true; deactivated = true;
} }

View File

@@ -42,59 +42,103 @@
} }
function test_Handler_Keyboard_activate(t) { function test_Handler_Keyboard_activate(t) {
t.plan(8); t.plan(15);
var log;
var map = new OpenLayers.Map('map'); var map = new OpenLayers.Map('map');
var control = new OpenLayers.Control(); var control = new OpenLayers.Control();
map.addControl(control); map.addControl(control);
var handler = new OpenLayers.Handler.Keyboard(control); var handler = new OpenLayers.Handler.Keyboard(control);
handler.active = true;
var activated = handler.activate(); // mock OpenLayers.Event.observe
t.ok(!activated,
"activate returns false if the handler was already active");
handler.active = false;
handler.dragging = true;
var old = OpenLayers.Event.stopObserving; var old = OpenLayers.Event.stopObserving;
var types = ["keydown", "keyup"];
OpenLayers.Event.observe = function(obj, type, method) { OpenLayers.Event.observe = function(obj, type, method) {
t.ok(obj == map.div, log[type] = obj;
"activate calls observing with correct object"); var validType = OpenLayers.Util.indexOf(["keydown", "keyup"], type) != -1;
var validType = (OpenLayers.Util.indexOf(types, type) != -1);
t.ok(validType, "activate calls observe for " + type); t.ok(validType, "activate calls observe for " + type);
t.ok(method == handler.eventListener, t.ok(method == handler.eventListener,
"activate calls observing with correct method"); "activate calls observing with correct method");
}; };
handler.active = true;
var activated = handler.activate();
t.ok(!activated,
"activate returns false if the handler was already active");
log = {};
handler.active = false;
handler.observeElement = map.div;
activated = handler.activate(); activated = handler.activate();
t.ok(log['keydown'] == map.div,
"activate calls observing for keydown with correct object");
t.ok(log['keyup'] == map.div,
"activate calls observing for keyup with correct object");
t.ok(activated, t.ok(activated,
"activate returns true if the handler was not already active"); "activate returns true if the handler was not already active");
OpenLayers.Event.observe = old;
log = {};
handler.active = false;
handler.observeElement = null;
activated = handler.activate();
t.ok(log['keydown'] == document,
"activate calls observing for keydown with correct object");
t.ok(log['keyup'] == document,
"activate calls observing for keyup with correct object");
t.ok(activated,
"activate returns true if the handler was not already active");
OpenLayers.Event.observe = old;
map.destroy();
} }
function test_Handler_Keyboard_deactivate(t) { function test_Handler_Keyboard_deactivate(t) {
t.plan(8); t.plan(15);
var log;
var map = new OpenLayers.Map('map'); var map = new OpenLayers.Map('map');
var control = new OpenLayers.Control(); var control = new OpenLayers.Control();
map.addControl(control); map.addControl(control);
var handler = new OpenLayers.Handler.Keyboard(control); var handler = new OpenLayers.Handler.Keyboard(control);
handler.active = false;
var deactivated = handler.deactivate(); // mock OpenLayers.Event.stopObserving
t.ok(!deactivated,
"deactivate returns false if the handler was not already active");
handler.active = true;
var old = OpenLayers.Event.stopObserving; var old = OpenLayers.Event.stopObserving;
var types = ["keydown", "keyup"];
OpenLayers.Event.stopObserving = function(obj, type, method) { OpenLayers.Event.stopObserving = function(obj, type, method) {
t.ok(obj == map.div, log[type] = obj;
"deactivate calls stopObserving with correct object"); var validType = OpenLayers.Util.indexOf(["keydown", "keyup"], type) != -1;
var validType = (OpenLayers.Util.indexOf(types, type) != -1);
t.ok(validType, "deactivate calls stopObserving for " + type); t.ok(validType, "deactivate calls stopObserving for " + type);
t.ok(method == handler.eventListener, t.ok(method == handler.eventListener,
"deactivate calls stopObserving with correct method"); "deactivate calls stopObserving with correct method");
}; };
handler.active = false;
var deactivated = handler.deactivate();
t.ok(!deactivated,
"deactivate returns false if the handler was not already active");
log = {};
handler.active = true;
handler.observeElement = map.div;
deactivated = handler.deactivate(); deactivated = handler.deactivate();
t.ok(log['keydown'] == map.div,
"deactivate calls stopObserving for keydown with correct object");
t.ok(log['keyup'] == map.div,
"deactivate calls stopObserving for keyup with correct object");
t.ok(deactivated, t.ok(deactivated,
"deactivate returns true if the handler was active already"); "deactivate returns true if the handler was active already");
log = {};
handler.active = true;
handler.observeElement = document;
deactivated = handler.deactivate();
t.ok(log['keydown'] == document,
"deactivate calls stopObserving for keydown with correct object");
t.ok(log['keyup'] == document,
"deactivate calls stopObserving for keyup with correct object");
t.ok(deactivated,
"deactivate returns true if the handler was active already");
OpenLayers.Event.stopObserving = old; OpenLayers.Event.stopObserving = old;
map.destroy();
} }