Skip to content

Commit 35cfca4

Browse files
committed
Add contextmenu for map-extent layercontrol
1 parent d94145a commit 35cfca4

File tree

3 files changed

+93
-14
lines changed

3 files changed

+93
-14
lines changed

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
<mapml-viewer projection="OSMTILE" zoom="14" lat="45.406314" lon="-75.6883335" controls controlslist="geolocation">
7777
<layer- data-testid="osm-layer" label="OpenStreetMap" checked >
7878
<map-link rel="license" title="© OpenStreetMap contributors CC BY-SA" href="https://www.openstreetmap.org/copyright"></map-link>
79-
<map-extent units="OSMTILE" checked="checked" hidden="hidden">
79+
<map-extent units="OSMTILE" checked="checked">
8080
<map-input name="z" type="zoom" value="18" min="0" max="18"></map-input>
8181
<map-input name="x" type="location" units="tilematrix" axis="column" min="0" max="262144"></map-input>
8282
<map-input name="y" type="location" units="tilematrix" axis="row" min="0" max="262144"></map-input>

src/mapml/elementSupport/extents/createLayerControlForExtent.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ export var createLayerControlExtentHTML = function () {
124124

125125
var extentItemNameSpan = L.DomUtil.create(
126126
'span',
127-
'mapml-layer-item-name',
127+
'mapml-extent-item-name',
128128
extentLabel
129129
);
130130
input.type = 'checkbox';

src/mapml/handlers/ContextMenu.js

Lines changed: 91 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,13 @@ export var ContextMenu = L.Handler.extend({
125125
// should be public as they are used in tests
126126
this.defExtCS = M.options.defaultExtCoor;
127127
this.defLocCS = M.options.defaultLocCoor;
128+
129+
// Used for layer and map-extent contextmenu
128130
const LYRZOOMTO = 0,
129131
LYRCOPY = 1;
130132
this._menuItems.LYRZOOMTO = LYRZOOMTO;
131133
this._menuItems.LYRCOPY = LYRCOPY;
134+
132135
this._layerItems = [
133136
{
134137
// 0
@@ -141,6 +144,19 @@ export var ContextMenu = L.Handler.extend({
141144
callback: this._copyLayer
142145
}
143146
];
147+
148+
this._extentLayerItems = [
149+
{
150+
// 0
151+
text: 'Zoom to Sub Layer' + ' (<kbd>Z</kbd>)',
152+
callback: this._zoomToMapExtent
153+
},
154+
{
155+
// 1
156+
text: 'Copy Sub Layer' + ' (<kbd>L</kbd>)',
157+
callback: this._copyMapExtent
158+
}
159+
];
144160
this._mapMenuVisible = false;
145161
this._keyboardEvent = false;
146162

@@ -238,14 +254,27 @@ export var ContextMenu = L.Handler.extend({
238254
this._createItem(this._layerMenu, this._layerItems[LYRZOOMTO]);
239255
this._createItem(this._layerMenu, this._layerItems[LYRCOPY]);
240256

257+
this._extentLayerMenu = L.DomUtil.create(
258+
'div',
259+
'mapml-contextmenu mapml-layer-menu',
260+
map.getContainer()
261+
);
262+
this._extentLayerMenu.setAttribute('hidden', '');
263+
this._createItem(this._extentLayerMenu, this._extentLayerItems[LYRZOOMTO]);
264+
this._createItem(this._extentLayerMenu, this._extentLayerItems[LYRCOPY]);
265+
241266
L.DomEvent.on(this._container, 'click', L.DomEvent.stop)
242267
.on(this._container, 'mousedown', L.DomEvent.stop)
243268
.on(this._container, 'dblclick', L.DomEvent.stop)
244269
.on(this._container, 'contextmenu', L.DomEvent.stop)
245270
.on(this._layerMenu, 'click', L.DomEvent.stop)
246271
.on(this._layerMenu, 'mousedown', L.DomEvent.stop)
247272
.on(this._layerMenu, 'dblclick', L.DomEvent.stop)
248-
.on(this._layerMenu, 'contextmenu', L.DomEvent.stop);
273+
.on(this._layerMenu, 'contextmenu', L.DomEvent.stop)
274+
.on(this._extentLayerMenu, 'click', L.DomEvent.stop)
275+
.on(this._extentLayerMenu, 'mousedown', L.DomEvent.stop)
276+
.on(this._extentLayerMenu, 'dblclick', L.DomEvent.stop)
277+
.on(this._extentLayerMenu, 'contextmenu', L.DomEvent.stop);
249278

250279
this.t = document.createElement('template');
251280
this.t.innerHTML = `<map-feature zoom="">
@@ -379,6 +408,19 @@ export var ContextMenu = L.Handler.extend({
379408
context._copyData(layerElem.getOuterHTML());
380409
},
381410

411+
_zoomToMapExtent: function (e) {
412+
let context =
413+
e instanceof KeyboardEvent ? this._map.contextMenu : this.contextMenu;
414+
context._layerClicked.extent.zoomTo();
415+
},
416+
417+
_copyMapExtent: function (e) {
418+
let context =
419+
e instanceof KeyboardEvent ? this._map.contextMenu : this.contextMenu,
420+
extentElem = context._layerClicked.extent;
421+
context._copyData(extentElem.outerHTML);
422+
},
423+
382424
_goForward: function (e) {
383425
let mapEl =
384426
e instanceof KeyboardEvent ? this._map.options.mapEl : this.options.mapEl;
@@ -790,18 +832,23 @@ export var ContextMenu = L.Handler.extend({
790832
if (this._mapMenuVisible) this._hide();
791833
this._clickEvent = e;
792834
let elem = e.originalEvent.target;
835+
// Opening contextmenu for layercontrol
793836
if (elem.closest('fieldset')) {
794837
elem = elem.closest('fieldset');
795-
elem =
796-
elem.className === 'mapml-layer-extent'
797-
? elem
798-
.closest('fieldset')
799-
.parentNode.parentNode.parentNode.querySelector('span')
800-
: elem.querySelector('span');
838+
// layer layercontrol
839+
if (elem.className === 'mapml-layer-item') {
840+
elem = elem.querySelector('span');
841+
this._layerMenu.removeAttribute('hidden');
842+
this._showAtPoint(e.containerPoint, e, this._layerMenu);
843+
// map-extent layercontrol
844+
} else if (elem.className === 'mapml-layer-extent') {
845+
elem = elem.querySelector('span');
846+
this._extentLayerMenu.removeAttribute('hidden');
847+
this._showAtPoint(e.containerPoint, e, this._extentLayerMenu);
848+
}
801849
this._layerClicked = elem;
802-
this._layerMenu.removeAttribute('hidden');
803-
this._showAtPoint(e.containerPoint, e, this._layerMenu);
804850
} else if (
851+
// map contextmenu
805852
elem.classList.contains('leaflet-container') ||
806853
elem.classList.contains('mapml-debug-extent') ||
807854
elem.tagName === 'path'
@@ -826,13 +873,20 @@ export var ContextMenu = L.Handler.extend({
826873
this._showAtPoint(pt, e, this._container);
827874
this._updateCS();
828875
}
876+
// Once contextmenu is opened, focus the first item
829877
if (e.originalEvent.button === 0 || e.originalEvent.button === -1) {
830878
this._keyboardEvent = true;
831879
if (this._layerClicked.className.includes('mapml-layer-item')) {
832880
let activeEl = document.activeElement;
833881
this._elementInFocus = activeEl.shadowRoot.activeElement;
834882
this._layerMenuTabs = 1;
835883
this._layerMenu.firstChild.focus();
884+
//
885+
} else if (this._layerClicked.className.includes('mapml-extent-item')) {
886+
let activeEl = document.activeElement;
887+
this._elementInFocus = activeEl.shadowRoot.activeElement;
888+
this._extentLayerMenuTabs = 1;
889+
this._extentLayerMenu.firstChild.focus();
836890
} else {
837891
this._container.querySelectorAll('button:not([disabled])')[0].focus();
838892
}
@@ -868,6 +922,7 @@ export var ContextMenu = L.Handler.extend({
868922
this._container.setAttribute('hidden', '');
869923
this._copySubMenu.setAttribute('hidden', '');
870924
this._layerMenu.setAttribute('hidden', '');
925+
this._extentLayerMenu.setAttribute('hidden', '');
871926
this._map.fire('contextmenu.hide', { contextmenu: this });
872927
setTimeout(() => this._map._container.focus(), 0);
873928
this.activeIndex = 0;
@@ -932,11 +987,13 @@ export var ContextMenu = L.Handler.extend({
932987
return size;
933988
},
934989

935-
// once tab is clicked on the layer menu, change the focus back to the layer control
990+
// once Esc is clicked on the layer/extent contextMenu, change the focus back to the layer control
936991
_focusOnLayerControl: function () {
937992
this._mapMenuVisible = false;
938993
delete this._layerMenuTabs;
994+
delete this._extentLayerMenuTabs;
939995
this._layerMenu.setAttribute('hidden', '');
996+
this._extentLayerMenu.setAttribute('hidden', '');
940997
if (this._elementInFocus) {
941998
this._elementInFocus.focus();
942999
} else {
@@ -1043,6 +1100,15 @@ export var ContextMenu = L.Handler.extend({
10431100
this._layerMenu.children[this._menuItems.LYRCOPY].focus();
10441101
} else if (!this._layerMenu.hasAttribute('hidden')) {
10451102
this._layerMenu.children[this._menuItems.LYRZOOMTO].focus();
1103+
} else if (
1104+
!this._extentLayerMenu.hasAttribute('hidden') &&
1105+
document.activeElement.shadowRoot.activeElement.innerHTML ===
1106+
this._extentLayerMenu.children[this._menuItems.LYRZOOMTO].innerHTML
1107+
) {
1108+
//"zoom to extent" on layermenu
1109+
this._extentLayerMenu.children[this._menuItems.LYRCOPY].focus();
1110+
} else if (!this._extentLayerMenu.hasAttribute('hidden')) {
1111+
this._extentLayerMenu.children[this._menuItems.LYRZOOMTO].focus();
10461112
} else {
10471113
if (this.activeIndex > 0) {
10481114
let prevIndex = this.activeIndex - 1;
@@ -1085,6 +1151,14 @@ export var ContextMenu = L.Handler.extend({
10851151
this._layerMenu.children[this._menuItems.LYRCOPY].focus();
10861152
} else if (!this._layerMenu.hasAttribute('hidden')) {
10871153
this._layerMenu.children[this._menuItems.LYRZOOMTO].focus();
1154+
} else if (
1155+
!this._extentLayerMenu.hasAttribute('hidden') &&
1156+
document.activeElement.shadowRoot.activeElement.innerHTML ===
1157+
this._extentLayerMenu.children[this._menuItems.LYRZOOMTO].innerHTML
1158+
) {
1159+
this._extentLayerMenu.children[this._menuItems.LYRCOPY].focus();
1160+
} else if (!this._extentLayerMenu.hasAttribute('hidden')) {
1161+
this._extentLayerMenu.children[this._menuItems.LYRZOOMTO].focus();
10881162
} else {
10891163
if (this.activeIndex < this._items.length - 1) {
10901164
//edge case at index 0
@@ -1152,7 +1226,7 @@ export var ContextMenu = L.Handler.extend({
11521226
}
11531227
}
11541228
} else if (e.code === 'Escape') {
1155-
if (this._layerMenuTabs) {
1229+
if (this._layerMenuTabs || this._extentLayerMenuTabs) {
11561230
L.DomEvent.stop(e);
11571231
this._focusOnLayerControl();
11581232
return;
@@ -1226,8 +1300,11 @@ export var ContextMenu = L.Handler.extend({
12261300
this._copyMapML(e);
12271301
break;
12281302
case 'KeyL':
1229-
if (this._layerClicked.className.includes('mapml-layer-item'))
1303+
if (this._layerClicked.className.includes('mapml-layer-item')) {
12301304
this._copyLayer(e);
1305+
} else if (this._layerClicked.className.includes('mapml-extent-item')) {
1306+
this._copyMapExtent(e);
1307+
}
12311308
break;
12321309
case 'KeyF':
12331310
this._toggleFullScreen(e);
@@ -1244,6 +1321,8 @@ export var ContextMenu = L.Handler.extend({
12441321
case 'KeyZ':
12451322
if (this._layerClicked.className.includes('mapml-layer-item')) {
12461323
this._zoomToLayer(e);
1324+
} else if (this._layerClicked.className.includes('mapml-extent-item')) {
1325+
this._zoomToMapExtent(e);
12471326
}
12481327
break;
12491328
}

0 commit comments

Comments
 (0)