diff --git a/package-lock.json b/package-lock.json index 6c3bbfda5..bf3c0dbaa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@maps4html/web-map-custom-element", - "version": "0.8.3", + "version": "0.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/mapml-viewer.js b/src/mapml-viewer.js index ae5168ece..1d18f8242 100644 --- a/src/mapml-viewer.js +++ b/src/mapml-viewer.js @@ -200,6 +200,7 @@ export class MapViewer extends HTMLElement { query: true, contextMenu: true, announceMovement: M.options.announceMovement, + featureIndex: true, mapEl: this, crs: M[this.projection], zoom: this.zoom, diff --git a/src/mapml/features/feature.js b/src/mapml/features/feature.js index 8e6083736..60ba12936 100644 --- a/src/mapml/features/feature.js +++ b/src/mapml/features/feature.js @@ -284,13 +284,19 @@ export var Feature = L.Path.extend({ this._coordinateToArrays(span, main, subParts, false, span.getAttribute("class"), parents.concat([span])); } let noSpan = coords.textContent.replace(/(<([^>]+)>)/ig, ''), - pairs = noSpan.match(/(\S+\s+\S+)/gim), local = []; + pairs = noSpan.match(/(\S+\s+\S+)/gim), local = [], bounds; for (let p of pairs) { let numPair = []; p.split(/\s+/gim).forEach(M.parseNumber, numPair); let point = M.pointToPCRSPoint(L.point(numPair), this.options.zoom, this.options.projection, this.options.nativeCS); local.push(point); - this._bounds = this._bounds ? this._bounds.extend(point) : L.bounds(point, point); + bounds = bounds ? bounds.extend(point) : L.bounds(point, point); + } + if (this._bounds) { + this._bounds.extend(bounds.min); + this._bounds.extend(bounds.max); + } else { + this._bounds = bounds; } if (isFirst) { main.push({ points: local }); @@ -303,6 +309,7 @@ export var Feature = L.Path.extend({ } subParts.unshift({ points: local, + center: bounds.getCenter(), cls: `${cls || ""} ${wrapperAttr.className || ""}`.trim(), attr: attrMap, link: wrapperAttr.link, @@ -339,6 +346,10 @@ export var Feature = L.Path.extend({ if (!this._bounds) return null; return this._map.options.crs.unproject(this._bounds.getCenter()); }, + + getPCRSCenter: function () { + return this._bounds.getCenter(); + }, }); /** diff --git a/src/mapml/features/featureGroup.js b/src/mapml/features/featureGroup.js index bcf3688ee..90a109a62 100644 --- a/src/mapml/features/featureGroup.js +++ b/src/mapml/features/featureGroup.js @@ -12,7 +12,6 @@ export var FeatureGroup = L.FeatureGroup.extend({ L.LayerGroup.prototype.initialize.call(this, layers, options); if((this.options.onEachFeature && this.options.properties) || this.options.link) { - this.options.group.setAttribute('tabindex', '0'); L.DomUtil.addClass(this.options.group, "leaflet-interactive"); L.DomEvent.on(this.options.group, "keyup keydown mousedown", this._handleFocus, this); let firstLayer = layers[Object.keys(layers)[0]]; @@ -32,12 +31,59 @@ export var FeatureGroup = L.FeatureGroup.extend({ if(this.options.featureID) this.options.group.setAttribute("data-fid", this.options.featureID); }, + onAdd: function (map) { + L.LayerGroup.prototype.onAdd.call(this, map); + this.updateInteraction(); + }, + + updateInteraction: function () { + let map = this._map || this.options._leafletLayer._map; + if((this.options.onEachFeature && this.options.properties) || this.options.link) + map.featureIndex.addToIndex(this, this.getPCRSCenter(), this.options.group); + + for (let layerID in this._layers) { + let layer = this._layers[layerID]; + for(let part of layer._parts){ + if(layer.featureAttributes && layer.featureAttributes.tabindex) + map.featureIndex.addToIndex(layer, layer.getPCRSCenter(), part.path); + for(let subPart of part.subrings) { + if(subPart.attr && subPart.attr.tabindex) map.featureIndex.addToIndex(layer, subPart.center, subPart.path); + } + } + } + }, + /** * Handler for focus events * @param {L.DOMEvent} e - Event that occurred * @private */ _handleFocus: function(e) { + if((e.keyCode === 9 || e.keyCode === 16) && e.type === "keydown"){ + let index = this._map.featureIndex.currentIndex; + if(e.keyCode === 9 && e.shiftKey) { + if(index === this._map.featureIndex.inBoundFeatures.length - 1) + this._map.featureIndex.inBoundFeatures[index].path.setAttribute("tabindex", -1); + if(index !== 0){ + L.DomEvent.stop(e); + this._map.featureIndex.inBoundFeatures[index - 1].path.focus(); + this._map.featureIndex.currentIndex--; + } + } else if (e.keyCode === 9) { + if(index !== this._map.featureIndex.inBoundFeatures.length - 1) { + L.DomEvent.stop(e); + this._map.featureIndex.inBoundFeatures[index + 1].path.focus(); + this._map.featureIndex.currentIndex++; + } else { + this._map.featureIndex.inBoundFeatures[0].path.setAttribute("tabindex", -1); + this._map.featureIndex.inBoundFeatures[index].path.setAttribute("tabindex", 0); + } + } + } else if (!(e.keyCode === 9 || e.keyCode === 16 || e.keyCode === 13)){ + this._map.featureIndex.currentIndex = 0; + this._map.featureIndex.inBoundFeatures[0].path.focus(); + } + if(e.target.tagName.toUpperCase() !== "G") return; if((e.keyCode === 9 || e.keyCode === 16 || e.keyCode === 13) && e.type === "keyup") { this.openTooltip(); @@ -69,22 +115,10 @@ export var FeatureGroup = L.FeatureGroup.extend({ * @private */ _previousFeature: function(e){ - let group = this._source.group.previousSibling; - if(!group){ - let currentIndex = this._source.group.closest("div.mapml-layer").style.zIndex; - let overlays = this._map.getPane("overlayPane").children; - for(let i = overlays.length - 1; i >= 0; i--){ - let layer = overlays[i]; - if(layer.style.zIndex >= currentIndex) continue; - group = layer.querySelector("g.leaflet-interactive"); - if(group){ - group = group.parentNode.lastChild; - break; - } - } - if (!group) group = this._source.group; - } - group.focus(); + L.DomEvent.stop(e); + this._map.featureIndex.currentIndex = Math.max(this._map.featureIndex.currentIndex - 1, 0); + let prevFocus = this._map.featureIndex.inBoundFeatures[this._map.featureIndex.currentIndex]; + prevFocus.path.focus(); this._map.closePopup(); }, @@ -94,19 +128,24 @@ export var FeatureGroup = L.FeatureGroup.extend({ * @private */ _nextFeature: function(e){ - let group = this._source.group.nextSibling; - if(!group){ - let currentIndex = this._source.group.closest("div.mapml-layer").style.zIndex; + L.DomEvent.stop(e); + this._map.featureIndex.currentIndex = Math.min(this._map.featureIndex.currentIndex + 1, this._map.featureIndex.inBoundFeatures.length - 1); + let nextFocus = this._map.featureIndex.inBoundFeatures[this._map.featureIndex.currentIndex]; + nextFocus.path.focus(); + this._map.closePopup(); + }, - for(let layer of this._map.getPane("overlayPane").children){ - if(layer.style.zIndex <= currentIndex) continue; - group = layer.querySelectorAll("g.leaflet-interactive"); - if(group.length > 0)break; + getPCRSCenter: function () { + let bounds; + for(let l in this._layers){ + let layer = this._layers[l]; + if (!bounds) { + bounds = L.bounds(layer.getPCRSCenter(), layer.getPCRSCenter()); + } else { + bounds.extend(layer.getPCRSCenter()); } - group = group && group.length > 0 ? group[0] : this._source.group; } - group.focus(); - this._map.closePopup(); + return bounds.getCenter(); }, }); diff --git a/src/mapml/features/featureRenderer.js b/src/mapml/features/featureRenderer.js index 7ec5cde7c..89a428648 100644 --- a/src/mapml/features/featureRenderer.js +++ b/src/mapml/features/featureRenderer.js @@ -4,8 +4,6 @@ * @returns {*} */ export var FeatureRenderer = L.SVG.extend({ - - /** * Override method of same name from L.SVG, use the this._container property * to set up the role="none presentation" on featureGroupu container, @@ -48,9 +46,6 @@ export var FeatureRenderer = L.SVG.extend({ if (p.subrings) { for (let r of p.subrings) { this._createPath(r, layer.options.className, r.attr['aria-label'], (r.link !== undefined), r.attr); - if(r.attr && r.attr.tabindex){ - p.path.setAttribute('tabindex', r.attr.tabindex || '0'); - } } } this._updateStyle(layer); @@ -77,7 +72,7 @@ export var FeatureRenderer = L.SVG.extend({ if (title) p.setAttribute('aria-label', title); } else { for(let [name, value] of Object.entries(attr)){ - if(name === "id") continue; + if(name === "id" || name === "tabindex") continue; p.setAttribute(name, value); } } diff --git a/src/mapml/handlers/FeatureIndex.js b/src/mapml/handlers/FeatureIndex.js new file mode 100644 index 000000000..0011fd51d --- /dev/null +++ b/src/mapml/handlers/FeatureIndex.js @@ -0,0 +1,110 @@ +export var FeatureIndex = L.Handler.extend({ + initialize: function (map) { + L.Handler.prototype.initialize.call(this, map); + this.inBoundFeatures = []; + this.outBoundFeatures = []; + this.currentIndex = 0; + this._mapPCRSBounds = M.pixelToPCRSBounds( + map.getPixelBounds(), + map.getZoom(), + map.options.projection); + }, + + addHooks: function () { + this._map.on("mapkeyboardfocused", this._updateMapBounds, this); + this._map.on('mapkeyboardfocused', this._sortIndex, this); + }, + + removeHooks: function () { + this._map.off("mapkeyboardfocused", this._updateMapBounds); + this._map.off('mapkeyboardfocused', this._sortIndex); + }, + + /** + * Adds a svg element to the index of tabbable features, it also keeps track of the layer it's associated + center + * @param layer - the layer object the feature is associated with + * @param lc - the layer center + * @param path - the svg element that needs to be focused, can be a path or g + */ + addToIndex: function (layer, lc, path) { + let mc = this._mapPCRSBounds.getCenter(); + let dist = Math.sqrt(Math.pow(lc.x - mc.x, 2) + Math.pow(lc.y - mc.y, 2)); + let index = this._mapPCRSBounds.contains(lc) ? this.inBoundFeatures : this.outBoundFeatures; + + let elem = {path: path, layer: layer, center: lc, dist: dist}; + path.setAttribute("tabindex", -1); + + index.push(elem); + + // TODO: this insertion loop has potential to be improved slightly + for (let i = index.length - 1; i > 0 && index[i].dist < index[i-1].dist; i--) { + let tmp = index[i]; + index[i] = index[i-1]; + index[i-1] = tmp; + } + + if (this._mapPCRSBounds.contains(lc)) + this.inBoundFeatures = index; + else + this.outBoundFeatures = index; + }, + + /** + * Removes features that are no longer on the map, also moves features to the respective array depending + * on whether the feature is in the maps viewport or not + */ + cleanIndex: function() { + this.currentIndex = 0; + this.inBoundFeatures = this.inBoundFeatures.filter((elem) => { + let inbound = this._mapPCRSBounds.contains(elem.center); + elem.path.setAttribute("tabindex", -1); + if (elem.layer._map && !inbound) { + this.outBoundFeatures.push(elem); + } + return elem.layer._map && inbound; + }); + this.outBoundFeatures = this.outBoundFeatures.filter((elem) => { + let inbound = this._mapPCRSBounds.contains(elem.center); + elem.path.setAttribute("tabindex", -1); + if (elem.layer._map && inbound) { + this.inBoundFeatures.push(elem); + } + return elem.layer._map && !inbound; + }); + }, + + /** + * Sorts the index of features in the map's viewport based on distance from center + * @private + */ + _sortIndex: function() { + this.cleanIndex(); + if(this.inBoundFeatures.length === 0) return; + + let mc = this._mapPCRSBounds.getCenter(); + + this.inBoundFeatures.sort(function(a, b) { + let ac = a.center; + let bc = b.center; + a.dist = Math.sqrt(Math.pow(ac.x - mc.x, 2) + Math.pow(ac.y - mc.y, 2)); + b.dist = Math.sqrt(Math.pow(bc.x - mc.x, 2) + Math.pow(bc.y - mc.y, 2)); + return a.dist - b.dist; + }); + + this.inBoundFeatures[0].path.setAttribute("tabindex", 0); + }, + + /** + * Event handler for 'mapfocused' event to update the map's bounds in terms of PCRS + * @param e - the event object + * @private + */ + _updateMapBounds: function (e) { + // TODO: map's PCRS bounds is used in other parts of the viewer, can be moved out to the map object directly + this._mapPCRSBounds = M.pixelToPCRSBounds( + this._map.getPixelBounds(), + this._map.getZoom(), + this._map.options.projection); + }, +}); + diff --git a/src/mapml/index.js b/src/mapml/index.js index c29c5aee9..6d587d814 100644 --- a/src/mapml/index.js +++ b/src/mapml/index.js @@ -58,6 +58,7 @@ import { Feature, feature } from "./features/feature"; import { FeatureRenderer, featureRenderer } from './features/featureRenderer'; import { FeatureGroup, featureGroup} from './features/featureGroup'; import {AnnounceMovement} from "./handlers/AnnounceMovement"; +import { FeatureIndex } from "./handlers/FeatureIndex"; import { Options } from "./options"; import "./keyboard"; @@ -607,11 +608,13 @@ M.gcrsToTileMatrix = Util.gcrsToTileMatrix; M.QueryHandler = QueryHandler; M.ContextMenu = ContextMenu; M.AnnounceMovement = AnnounceMovement; +M.FeatureIndex = FeatureIndex; // see https://leafletjs.com/examples/extending/extending-3-controls.html#handlers L.Map.addInitHook('addHandler', 'query', M.QueryHandler); L.Map.addInitHook('addHandler', 'contextMenu', M.ContextMenu); L.Map.addInitHook('addHandler', 'announceMovement', M.AnnounceMovement); +L.Map.addInitHook('addHandler', 'featureIndex', M.FeatureIndex); M.MapMLLayer = MapMLLayer; M.mapMLLayer = mapMLLayer; diff --git a/src/mapml/layers/Crosshair.js b/src/mapml/layers/Crosshair.js index b63ae5a54..5793439c2 100644 --- a/src/mapml/layers/Crosshair.js +++ b/src/mapml/layers/Crosshair.js @@ -85,6 +85,7 @@ export var Crosshair = L.Layer.extend({ return false; }, + // TODO: should be merged with the 'mapfocused' event emitted by mapml-viewer and map, not trivial _isMapFocused: function (e) { //set this._map.isFocused = true if arrow buttons are used if(!this._map._container.parentNode.activeElement){ @@ -96,6 +97,7 @@ export var Crosshair = L.Layer.extend({ this._map.isFocused = false; } else this._map.isFocused = isLeafletContainer && ["keyup", "keydown"].includes(e.type); + if(this._map.isFocused) this._map.fire("mapkeyboardfocused"); this._addOrRemoveMapOutline(); this._addOrRemoveCrosshair(); }, diff --git a/src/mapml/layers/FeatureLayer.js b/src/mapml/layers/FeatureLayer.js index c4fac3245..13185ec74 100644 --- a/src/mapml/layers/FeatureLayer.js +++ b/src/mapml/layers/FeatureLayer.js @@ -55,6 +55,7 @@ export var MapMLFeatures = L.FeatureGroup.extend({ L.DomUtil.remove(this._container); } L.FeatureGroup.prototype.onRemove.call(this, map); + this._map.featureIndex.cleanIndex(); }, getEvents: function(){ @@ -146,6 +147,8 @@ export var MapMLFeatures = L.FeatureGroup.extend({ _resetFeatures : function (zoom){ this.clearLayers(); + // since features are removed and re-added by zoom level, need to clean the feature index before re-adding + if(this._map) this._map.featureIndex.cleanIndex(); if(this._features && this._features[zoom]){ for(let k =0;k < this._features[zoom].length;k++){ this.addLayer(this._features[zoom][k]); diff --git a/src/mapml/layers/MapLayer.js b/src/mapml/layers/MapLayer.js index 6ccf7b6d7..3cdae03b3 100644 --- a/src/mapml/layers/MapLayer.js +++ b/src/mapml/layers/MapLayer.js @@ -1182,9 +1182,9 @@ export var MapMLLayer = L.Layer.extend({ mapFocusButton.type = "button"; mapFocusButton.title = "Focus Map"; mapFocusButton.innerHTML = ""; - L.DomEvent.disableClickPropagation(mapFocusButton); - L.DomEvent.on(mapFocusButton, 'click', L.DomEvent.stop); L.DomEvent.on(mapFocusButton, 'click', (e)=>{ + L.DomEvent.stop(e); + map.featureIndex._sortIndex(); map.closePopup(); map._container.focus(); }, popup); @@ -1194,8 +1194,6 @@ export var MapMLLayer = L.Layer.extend({ previousButton.type = "button"; previousButton.title = "Previous Feature"; previousButton.innerHTML = ""; - L.DomEvent.disableClickPropagation(previousButton); - L.DomEvent.on(previousButton, 'click', L.DomEvent.stop); L.DomEvent.on(previousButton, 'click', layer._previousFeature, popup); // static feature counter that 1/1 @@ -1208,8 +1206,6 @@ export var MapMLLayer = L.Layer.extend({ nextButton.type = "button"; nextButton.title = "Next Feature"; nextButton.innerHTML = ""; - L.DomEvent.disableClickPropagation(nextButton); - L.DomEvent.on(nextButton, 'click', L.DomEvent.stop); L.DomEvent.on(nextButton, 'click', layer._nextFeature, popup); // creates >| button, focuses map controls @@ -1217,9 +1213,12 @@ export var MapMLLayer = L.Layer.extend({ controlFocusButton.type = "button"; controlFocusButton.title = "Focus Controls"; controlFocusButton.innerHTML = ""; - L.DomEvent.disableClickPropagation(controlFocusButton); - L.DomEvent.on(controlFocusButton, 'click', L.DomEvent.stop); L.DomEvent.on(controlFocusButton, 'click', (e) => { + map.featureIndex._sortIndex(); + map.featureIndex.currentIndex = map.featureIndex.inBoundFeatures.length - 1; + map.featureIndex.inBoundFeatures[0].path.setAttribute("tabindex", -1); + map.featureIndex.inBoundFeatures[map.featureIndex.currentIndex].path.setAttribute("tabindex", 0); + L.DomEvent.stop(e); map.closePopup(); map._controlContainer.querySelector("A").focus(); }, popup); @@ -1246,9 +1245,11 @@ export var MapMLLayer = L.Layer.extend({ let isTab = focusEvent.originalEvent.keyCode === 9, shiftPressed = focusEvent.originalEvent.shiftKey; if((path[0].classList.contains("leaflet-popup-close-button") && isTab && !shiftPressed) || focusEvent.originalEvent.keyCode === 27){ - L.DomEvent.stop(focusEvent); - map.closePopup(popup); - group.focus(); + setTimeout(() => { + L.DomEvent.stop(focusEvent); + map.closePopup(popup); + group.focus(); + }, 0); } else if ((path[0].title==="Focus Map" || path[0].classList.contains("mapml-popup-content")) && isTab && shiftPressed){ setTimeout(() => { //timeout needed so focus of the feature is done even after the keypressup event occurs L.DomEvent.stop(focusEvent); diff --git a/src/web-map.js b/src/web-map.js index 7d6cf6c2d..866611ecf 100644 --- a/src/web-map.js +++ b/src/web-map.js @@ -170,6 +170,7 @@ export class WebMap extends HTMLMapElement { }); this.controlsListObserver.observe(this, {attributes:true}); } + connectedCallback() { if (this.isConnected) { @@ -214,6 +215,7 @@ export class WebMap extends HTMLMapElement { query: true, contextMenu: true, announceMovement: M.options.announceMovement, + featureIndex: true, mapEl: this, crs: M[this.projection], zoom: this.zoom, diff --git a/test/e2e/core/featureLinks.test.js b/test/e2e/core/featureLinks.test.js index 85e89c92e..2655851e6 100644 --- a/test/e2e/core/featureLinks.test.js +++ b/test/e2e/core/featureLinks.test.js @@ -9,11 +9,11 @@ describe("Playwright Feature Links Tests", () => { describe("Sub Part Link Tests", () => { test("Sub-point link adds new layer", async () => { - for(let i = 0; i < 4; i++) { + for(let i = 0; i < 5; i++) { await page.keyboard.press("Tab"); await page.waitForTimeout(200); } - await page.keyboard.press("Enter"); + await page.keyboard.press("Enter"); // Press enter on the point subpart of the 'Accessible Square' feature await page.waitForTimeout(1000); const layers = await page.$eval( "body > map", @@ -27,7 +27,7 @@ describe("Playwright Feature Links Tests", () => { await page.click("div > div.leaflet-control-container > div.leaflet-top.leaflet-right > div > section > div.leaflet-control-layers-overlays > fieldset:nth-child(2) > div:nth-child(1) > div > button:nth-child(1)"); await page.waitForTimeout(850); await page.click("body > map"); - for(let i = 0; i < 6; i++) { + for(let i = 0; i < 10; i++) { await page.keyboard.press("Tab"); await page.waitForTimeout(200); } @@ -35,7 +35,7 @@ describe("Playwright Feature Links Tests", () => { "body > map", (map) => map.extent ); - await page.keyboard.press("Enter"); + await page.keyboard.press("Enter"); // Press enter on the point of the 'Inplace' feature const layers = await page.$eval( "body > map", (map) => map.childElementCount @@ -62,11 +62,11 @@ describe("Playwright Feature Links Tests", () => { await page.click("div > div.leaflet-control-container > div.leaflet-top.leaflet-right > div > section > div.leaflet-control-layers-overlays > fieldset:nth-child(2) > div:nth-child(1) > div > button:nth-child(1)"); await page.waitForTimeout(850); await page.click("body > map"); - for(let i = 0; i < 5; i++) { + for(let i = 0; i < 9; i++) { await page.keyboard.press("Tab"); await page.waitForTimeout(200); } - await page.keyboard.press("Enter"); + await page.keyboard.press("Enter"); // Press enter on main part of 'Inplace' feature const layers = await page.$eval( "body > map", (map) => map.childElementCount diff --git a/test/e2e/core/linkTypes.test.js b/test/e2e/core/linkTypes.test.js index ebf105626..76751ff26 100644 --- a/test/e2e/core/linkTypes.test.js +++ b/test/e2e/core/linkTypes.test.js @@ -10,11 +10,11 @@ describe("Playwright Feature Links Tests", () => { describe("HTML Link Type Tests", () => { test("HTML _self target navigates to new page", async () => { await page.click("body > map"); - for(let i = 0; i < 7; i++) { + for(let i = 0; i < 9; i++) { await page.keyboard.press("Tab"); await page.waitForTimeout(200); } - await page.keyboard.press("Enter"); + await page.keyboard.press("Enter"); // Press enter on the feature in the top-left await page.waitForTimeout(1000); const url = await page.url(); await expect(url).toEqual("http://geogratis.gc.ca/mapml/en/cbmtile/cbmtgeom/"); @@ -23,11 +23,11 @@ describe("Playwright Feature Links Tests", () => { await page.goBack(); await page.waitForTimeout(1000); await page.click("body > map"); - for(let i = 0; i < 8; i++) { + for(let i = 0; i < 2; i++) { await page.keyboard.press("Tab"); await page.waitForTimeout(200); } - await page.keyboard.press("Enter"); + await page.keyboard.press("Enter"); // Press enter on the top point feature in the top left await page.waitForTimeout(1000); const url = await page.url(); await expect(url).toEqual("http://geogratis.gc.ca/mapml/en/cbmtile/fdi/"); @@ -40,7 +40,7 @@ describe("Playwright Feature Links Tests", () => { await page.keyboard.press("Tab"); await page.waitForTimeout(200); } - await page.keyboard.press("Enter"); + await page.keyboard.press("Enter"); // Press enter on the second feature in the top left await page.waitForTimeout(1000); const url = await page.url(); await expect(url).toEqual("http://geogratis.gc.ca/mapml/en/cbmtile/cbmtgeom/"); @@ -49,11 +49,11 @@ describe("Playwright Feature Links Tests", () => { await page.goBack(); await page.waitForTimeout(1000); await page.click("body > map"); - for(let i = 0; i < 11; i++) { + for(let i = 0; i < 1; i++) { await page.keyboard.press("Tab"); await page.waitForTimeout(200); } - await page.keyboard.press("Enter"); + await page.keyboard.press("Enter"); // Press enter on the second point in the top left await page.waitForTimeout(1000); const extent = await page.$eval( "body > map", diff --git a/test/layers/mapMLStaticTileLayer.spec.js b/test/layers/mapMLStaticTileLayer.spec.js index c95161617..059bf31c3 100644 --- a/test/layers/mapMLStaticTileLayer.spec.js +++ b/test/layers/mapMLStaticTileLayer.spec.js @@ -2,7 +2,8 @@ describe("MapMLStaticTileLayer Tests", function () { var map, container; beforeEach(() => { - map = L.map(document.createElement("map")); + map = L.map(document.createElement("map"), {center:[0, 0], zoom: 0}); + map.options.projection = "CBMTILE"; container = document.createElement("div"); });