mapSize.x) {
+ menu.style.left = 'auto';
+ menu.style.right = 150 + 'px';
+ } else {
+ menu.style.left = 150 + 'px';
+ menu.style.right = 'auto';
+ }
+
+ if (click.containerPoint.y + 150 > mapSize.y) {
+ menu.style.top = 'auto';
+ menu.style.bottom = 20 + 'px';
+ } else {
+ menu.style.top = 100 + 'px';
+ menu.style.bottom = 'auto';
+ }
+ if(this._keyboardEvent)menu.firstChild.focus();
+ },
+
+ _hideCoordMenu: function(e){
+ if(e.srcElement.parentElement.classList.contains("mapml-submenu") ||
+ e.srcElement.innerText === "Copy Coordinates (C) >")return;
+ let menu = this._coordMenu;
+ menu.style.display = "none";
+ },
+
_onItemMouseOver: function (e) {
- L.DomUtil.addClass(e.target || e.srcElement, 'over');
+ L.DomUtil.addClass(e.target || e.srcElement, 'over');
+ if(e.srcElement.innerText === "Copy Coordinates (C) >") this._showCoordMenu(e);
},
_onItemMouseOut: function (e) {
- L.DomUtil.removeClass(e.target || e.srcElement, 'over');
+ L.DomUtil.removeClass(e.target || e.srcElement, 'over');
+ this._hideCoordMenu(e);
}
});
diff --git a/src/mm-mapp.js b/src/mm-mapp.js
index b045883be..df1f3326c 100644
--- a/src/mm-mapp.js
+++ b/src/mm-mapp.js
@@ -69,10 +69,28 @@ export class MmMapp extends HTMLElement {
get layers() {
return this.getElementsByTagName('layer-');
}
+
+ get extent(){
+ let map = this._map,
+ pcrsBounds = M.pixelToPCRSBounds(
+ map.getPixelBounds(),
+ map.getZoom(),
+ map.options.projection);
+ let formattedExtent = M.convertAndFormatPCRS(pcrsBounds, map);
+ if(map.getMaxZoom() !== Infinity){
+ formattedExtent.zoom = {
+ minZoom:map.getMinZoom(),
+ maxZoom:map.getMaxZoom()
+ };
+ }
+ return (formattedExtent);
+ }
+
constructor() {
// Always call super first in constructor
super();
+ this._source = this.outerHTML;
let tmpl = document.createElement('template');
tmpl.innerHTML =
`` +
@@ -135,12 +153,21 @@ export class MmMapp extends HTMLElement {
} else {
this._container.style.height = this.height+"px";
}
+
+ // create an array to track the history of the map and the current index
+ if(!this._history){
+ this._history = [];
+ this._historyIndex = -1;
+ this._traversalCall = false;
+ }
+
// create the Leaflet map if this is the first time attached is called
if (!this._map) {
this._map = L.map(this._container, {
center: new L.LatLng(this.lat, this.lon),
projection: this.projection,
query: true,
+ contextMenu: true,
mapEl: this,
crs: M[this.projection],
zoom: this.zoom,
@@ -320,6 +347,7 @@ export class MmMapp extends HTMLElement {
this._map.on('moveend',
function () {
this._updateMapCenter();
+ this._addToHistory();
this.dispatchEvent(new CustomEvent('moveend', {detail:
{target: this}}));
}, this);
@@ -384,7 +412,7 @@ export class MmMapp extends HTMLElement {
}
}
zoomTo(lat, lon, zoom) {
- zoom = zoom||this.zoom;
+ zoom = Number.isInteger(zoom)? zoom:this.zoom;
var location = new L.LatLng(lat,lon);
this._map.setView(location, zoom);
this.zoom = zoom;
@@ -398,6 +426,60 @@ export class MmMapp extends HTMLElement {
this.lon = this._map.getCenter().lng;
this.zoom = this._map.getZoom();
}
+
+ _addToHistory(){
+ if(this._traversalCall){
+ this._traversalCall = false;
+ return;
+ }
+ let mapLocation = this._map.getCenter();
+ let location ={
+ zoom:this._map.getZoom(),
+ lat:mapLocation.lat,
+ lng:mapLocation.lng,
+ };
+ this._historyIndex++;
+ this._history.push(location);
+ }
+
+ back(){
+ let mapEl = this,
+ history = mapEl._history;
+ if(mapEl._historyIndex > 0){
+ mapEl._historyIndex--;
+ }
+ let prev = history[mapEl._historyIndex];
+ mapEl._traversalCall = true;
+ mapEl.zoomTo(prev.lat,prev.lng,prev.zoom);
+ }
+
+ forward(){
+ let mapEl = this,
+ history = this._history;
+ if(mapEl._historyIndex < history.length -1){
+ mapEl._historyIndex++;
+ }
+ let next = history[this._historyIndex];
+ mapEl._traversalCall = true;
+ mapEl.zoomTo(next.lat,next.lng,next.zoom);
+ }
+
+ reload(){
+ let mapEl = this,
+ initialLocation = mapEl._history.shift();
+ mapEl._history = [initialLocation];
+ mapEl._historyIndex = -1;
+ mapEl._traversalCall = true;
+ mapEl.zoomTo(initialLocation.lat,initialLocation.lng,initialLocation.zoom);
+ }
+
+ viewSource(){
+ let blob = new Blob([this._source],{type:"text/plain"}),
+ url = URL.createObjectURL(blob);
+ window.open(url);
+ URL.revokeObjectURL(url);
+ }
+
_ready() {
// when used in a custom element, the leaflet script element is hidden inside
// the import's shadow dom.
diff --git a/src/web-map.js b/src/web-map.js
index e70d5ef35..cf4ee6656 100644
--- a/src/web-map.js
+++ b/src/web-map.js
@@ -94,6 +94,7 @@ export class WebMap extends HTMLMapElement {
// Always call super first in constructor
super();
+ this._source = this.outerHTML;
let tmpl = document.createElement('template');
tmpl.innerHTML =
`` +
@@ -499,17 +500,13 @@ export class WebMap extends HTMLMapElement {
let mapEl = this,
initialLocation = mapEl._history.shift();
mapEl._history = [initialLocation];
+ mapEl._historyIndex = -1;
mapEl._traversalCall = true;
mapEl.zoomTo(initialLocation.lat,initialLocation.lng,initialLocation.zoom);
}
viewSource(){
- let mapHTML = this.outerHTML,
- divIndex = mapHTML.indexOf(" {
+ await page.click("body > map");
+ await page.keyboard.press("Shift+F10");
+ const aHandle = await page.evaluateHandle(() => document.querySelector(".web-map"));
+ const nextHandle = await page.evaluateHandle(doc => doc.shadowRoot, aHandle);
+ const resultHandle = await page.evaluateHandle(root => root.activeElement, nextHandle);
+ const nameHandle = await page.evaluateHandle(name => name.outerText, resultHandle);
+ let name = await nameHandle.jsonValue();
+ await nameHandle.dispose();
+ expect(name).toEqual("Back (B)");
+ });
+
+ test("[" + browserType + "]" + " Context menu tab goes to next item", async () => {
+ await page.keyboard.press("Tab");
+ const aHandle = await page.evaluateHandle(() => document.querySelector(".web-map"));
+ const nextHandle = await page.evaluateHandle(doc => doc.shadowRoot, aHandle);
+ const resultHandle = await page.evaluateHandle(root => root.activeElement, nextHandle);
+ const nameHandle = await page.evaluateHandle(name => name.outerText, resultHandle);
+ let name = await nameHandle.jsonValue();
+ await nameHandle.dispose();
+ expect(name).toEqual("Forward (F)");
+ });
+
+ test("[" + browserType + "]" + " Submenu opens on C with focus on first item", async () => {
+ await page.keyboard.press("c");
+ await page.keyboard.press("Tab");
+ const aHandle = await page.evaluateHandle(() => document.querySelector(".web-map"));
+ const nextHandle = await page.evaluateHandle(doc => doc.shadowRoot, aHandle);
+ const resultHandle = await page.evaluateHandle(root => root.activeElement, nextHandle);
+ const nameHandle = await page.evaluateHandle(name => name.outerText, resultHandle);
+ let name = await nameHandle.jsonValue();
+ await nameHandle.dispose();
+ expect(name).toEqual("tile");
+ });
+
test("[" + browserType + "]" + " Context menu displaying on map", async () => {
await page.click("body > map", { button: "right" });
const contextMenu = await page.$eval(