From a69477abcf2a82b2597355b79c4c9bf71886422c Mon Sep 17 00:00:00 2001 From: Eric Martinez Date: Fri, 4 May 2012 23:46:15 -0600 Subject: [PATCH] Created a focus handler for the map. Converted keyboard handler to make use of new focus events. --- build/deps.js | 8 +++- dist/leaflet.css | 3 ++ src/map/handler/Map.Focus.js | 69 +++++++++++++++++++++++++++++++++ src/map/handler/Map.Keyboard.js | 32 +++------------ 4 files changed, 85 insertions(+), 27 deletions(-) create mode 100644 src/map/handler/Map.Focus.js diff --git a/build/deps.js b/build/deps.js index fd546d69..a0f21771 100644 --- a/build/deps.js +++ b/build/deps.js @@ -180,9 +180,15 @@ var deps = { desc: 'Enables zooming to bounding box by shift-dragging the map.' }, + Focus: { + src: ['map/handler/Map.Focus.js'], + desc: 'Enables map to gain focus.' + }, + Keyboard: { src: ['map/handler/Map.Keyboard.js'], - desc: 'Enables keyboard pan/zoom when map is active.' + deps: ['Focus'], + desc: 'Enables keyboard pan/zoom when map is focused.' }, MarkerDrag: { diff --git a/dist/leaflet.css b/dist/leaflet.css index b089b330..140a76ea 100644 --- a/dist/leaflet.css +++ b/dist/leaflet.css @@ -338,6 +338,9 @@ a.leaflet-active { .leaflet-container { background: #ddd; } +.leaflet-container-nofocus { + outline:0; +} .leaflet-container a { color: #0078A8; } diff --git a/src/map/handler/Map.Focus.js b/src/map/handler/Map.Focus.js new file mode 100644 index 00000000..3e05cf28 --- /dev/null +++ b/src/map/handler/Map.Focus.js @@ -0,0 +1,69 @@ +/* + * L.Handler.Focus is used internally by L.Map to make the map focusable. + */ + +L.Map.mergeOptions({ + focus: true +}); + +L.Map.Focus = L.Handler.extend({ + _focused: false, + + initialize: function (map) { + this._map = map; + this._container = map._container; + + this._makeFocusable(); + this._focused = false; + }, + + addHooks: function () { + var container = this._container; + L.DomEvent + .addListener(container, 'focus', this.onFocus, this) + .addListener(container, 'blur', this.onBlur, this) + .addListener(container, 'click', this.onClick, this); + }, + + removeHooks: function () { + var container = this._container; + L.DomEvent + .removeListener(container, 'focus', this.onFocus, this) + .removeListener(container, 'blur', this.onBlur, this) + .removeListener(container, 'click', this.onClick, this); + }, + + onClick: function (e) { + if (!this._focused) { + this._container.focus(); + } + }, + + onFocus: function (e) { + this._focused = true; + this._map.fire('focus'); + }, + + onBlur: function (e) { + this._focused = false; + this._map.fire('blur'); + }, + + _makeFocusable: function () { + var map = this._map, container = this._container; + + + // While we want the map to be "focusable", we don't want the map to + // appear focused (i.e. no outline etc...) + L.DomUtil.addClass(container, 'leaflet-container-nofocus'); + + // Allows user to tab to the container. + // -1 => User can focus container by clicks, but not tabs + // 0 => User can focus container by clicks or tabs. Order is based on + // DOM source order. + // N => User can focus container by clicks or tabs. N = tab order. + container.tabIndex = "0"; + } +}); + +L.Map.addInitHook('addHandler', 'focus', L.Map.Focus); diff --git a/src/map/handler/Map.Keyboard.js b/src/map/handler/Map.Keyboard.js index 5a4d974b..d5b91d23 100644 --- a/src/map/handler/Map.Keyboard.js +++ b/src/map/handler/Map.Keyboard.js @@ -47,11 +47,15 @@ L.Map.Keyboard = L.Handler.extend({ }, addHooks: function () { - L.DomEvent.addListener(this._container, 'click', this._onClick, this); + this._map.on('focus', this._addHooks, this) + .on('blur', this._removeHooks, this); }, removeHooks: function () { - L.DomEvent.removeListener(this._container, 'click', this._onClick, this); + this._removeHooks(); + + this._map.off('focus', this._addHooks, this) + .off('blur', this._addHooks, this); }, _setPanOffset: function (pan) { @@ -114,16 +118,6 @@ L.Map.Keyboard = L.Handler.extend({ this.zoomKeys = zoomKeys; }, - _onClick: function (e) { - this._addHooks(); - }, - - _onClickOut: function (e) { - if (!this._checkInMap(e.target || e.srcElement)) { - this._removeHooks(); - } - }, - _addHooks: function () { L.DomEvent .addListener(document, 'keydown', this._onKeyDown, this) @@ -149,20 +143,6 @@ L.Map.Keyboard = L.Handler.extend({ return; } L.DomEvent.stop(e); - }, - - _checkInMap: function (element) { - try { - if (element === this._container) { - return true; - } else if (!element.parentNode) { - return false; - } else { - return this._checkInMap(element.parentNode); - } - } catch (e) { - return false; - } } });