From 018cc9ed8e0ec878300bd5e0c1f19c6c1b3d498d Mon Sep 17 00:00:00 2001
From: Malvoz <26493779+Malvoz@users.noreply.github.com>
Date: Mon, 20 Dec 2021 14:42:48 +0100
Subject: [PATCH 01/14] Collapse attribution behind a button
---
src/mapml.css | 45 ++++++++--
src/mapml/control/AttributionButton.js | 110 +++++++++++++++++++++++++
src/mapml/index.js | 4 +
test/e2e/core/mapElement.test.js | 6 --
4 files changed, 153 insertions(+), 12 deletions(-)
create mode 100644 src/mapml/control/AttributionButton.js
diff --git a/src/mapml.css b/src/mapml.css
index 3f747e39d..b6b834e89 100644
--- a/src/mapml.css
+++ b/src/mapml.css
@@ -140,13 +140,9 @@
.leaflet-tooltip-pane .leaflet-tooltip,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar,
-.leaflet-popup-tip {
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgb(0, 0, 0, 0.3);
-}
-
-/* Increase contrast between the attribution container and the underlying content. */
+.leaflet-popup-tip,
.leaflet-container .leaflet-control-attribution {
- background-color: rgba(255, 255, 255, 0.95);
+ box-shadow: rgb(0 0 0 / 30%) 0px 1px 4px -1px;
}
/* Remove opinionated styles of attribution links. */
@@ -155,6 +151,43 @@
text-decoration: revert;
}
+
+/*
+ * Attribution.
+ */
+
+.leaflet-container .leaflet-control-attribution {
+ background-color: #fff;
+ border-radius: 1.5em;
+ color: currentColor;
+ margin: 5px;
+ min-height: 30px;
+ min-width: 30px;
+ padding: 0;
+}
+
+.leaflet-control-attribution summary {
+ display: block;
+ list-style: none;
+ border-radius: 100%;
+ position: absolute;
+ bottom: 0;
+ left: calc(100% - 30px);
+ line-height: 0;
+ width: 30px;
+ height: 30px;
+}
+
+.leaflet-control-attribution summary svg {
+ border-radius: 100%;
+ width: inherit;
+ height: inherit;
+}
+
+.mapml-attribution-container {
+ padding: 5px 35px 5px 10px;
+}
+
/*
* Zoom controls.
*/
diff --git a/src/mapml/control/AttributionButton.js b/src/mapml/control/AttributionButton.js
new file mode 100644
index 000000000..969df8865
--- /dev/null
+++ b/src/mapml/control/AttributionButton.js
@@ -0,0 +1,110 @@
+export var AttributionButton = L.Control.extend({
+ options: {
+ position: 'bottomright',
+ prefix: 'Maps4HTML | Leaflet'
+ },
+
+ initialize: function (options) {
+ L.Util.setOptions(this, options);
+ this._attributions = {};
+ },
+
+ onAdd: function (map) {
+ map.attributionControl = this;
+ this._container = L.DomUtil.create('details', 'leaflet-control-attribution');
+ L.DomEvent.disableClickPropagation(this._container);
+
+ for (var i in map._layers) {
+ if (map._layers[i].getAttribution) {
+ this.addAttribution(map._layers[i].getAttribution());
+ }
+ }
+
+ this._update();
+
+ map.on('layeradd', this._addAttribution, this);
+
+ return this._container;
+ },
+
+ onRemove: function (map) {
+ map.off('layeradd', this._addAttribution, this);
+ },
+
+ _addAttribution: function (ev) {
+ if (ev.layer.getAttribution) {
+ this.addAttribution(ev.layer.getAttribution());
+ ev.layer.once('remove', function () {
+ this.removeAttribution(ev.layer.getAttribution());
+ }, this);
+ }
+ },
+
+ setPrefix: function (prefix) {
+ this.options.prefix = prefix;
+ this._update();
+ return this;
+ },
+
+ addAttribution: function (text) {
+ if (!text) { return this; }
+
+ if (!this._attributions[text]) {
+ this._attributions[text] = 0;
+ }
+ this._attributions[text]++;
+
+ this._update();
+
+ return this;
+ },
+
+ removeAttribution: function (text) {
+ if (!text) { return this; }
+
+ if (this._attributions[text]) {
+ this._attributions[text]--;
+ this._update();
+ }
+
+ return this;
+ },
+
+ _update: function () {
+ if (!this._map) { return; }
+
+ var attribs = [];
+
+ for (var i in this._attributions) {
+ if (this._attributions[i]) {
+ attribs.push(i);
+ }
+ }
+
+ var prefixAndAttribs = [];
+
+ if (this.options.prefix) {
+ prefixAndAttribs.push(this.options.prefix);
+ }
+ if (attribs.length) {
+ prefixAndAttribs.push(attribs.join(', '));
+ }
+
+ this._container.innerHTML = '' + '
' + prefixAndAttribs.join(' | ') + '
';
+
+ }
+});
+
+L.Map.mergeOptions({
+ attributionControl: true
+});
+
+L.Map.addInitHook(function () {
+ if (this.options.attributionControl) {
+ new AttributionButton().addTo(this);
+ }
+});
+
+export var attributionButton = function (options) {
+ return new AttributionButton(options);
+};
diff --git a/src/mapml/index.js b/src/mapml/index.js
index df601a660..18b8a9ea3 100644
--- a/src/mapml/index.js
+++ b/src/mapml/index.js
@@ -51,6 +51,7 @@ import { DebugOverlay, debugOverlay} from './layers/DebugOverlay';
import { QueryHandler } from './handlers/QueryHandler';
import { ContextMenu } from './handlers/ContextMenu';
import { Util } from './utils/Util';
+import { AttributionButton, attributionButton } from './control/AttributionButton';
import { ReloadButton, reloadButton } from './control/ReloadButton';
import { FullscreenButton, fullscreenButton } from './control/FullscreenButton';
import {attributionControl} from "./control/AttributionControl";
@@ -652,6 +653,9 @@ M.featureLayer = featureLayer;
M.LayerControl = LayerControl;
M.layerControl = layerControl;
+M.AttributionButton = AttributionButton;
+M.attributionButton = attributionButton;
+
M.ReloadButton = ReloadButton;
M.reloadButton = reloadButton;
diff --git a/test/e2e/core/mapElement.test.js b/test/e2e/core/mapElement.test.js
index 7fdcda663..9191cd760 100644
--- a/test/e2e/core/mapElement.test.js
+++ b/test/e2e/core/mapElement.test.js
@@ -89,10 +89,4 @@ test.describe("Playwright Map Element Tests", () => {
await expect(projection).toEqual("OSMTILE");
});
- test("Ensure attribution control has role='group' aria-label='Map data attribution'", async () => {
- let role = await page.evaluate(`document.querySelector('map')._attributionControl.getContainer().getAttribute('role')`);
- await expect(role).toEqual("group");
- let arialabel = await page.evaluate(`document.querySelector('map')._attributionControl.getContainer().getAttribute('aria-label')`);
- await expect(arialabel).toEqual("Map data attribution");
- });
});
\ No newline at end of file
From 847231847f2d151f99bc9bbe4db96ee49fb20d71 Mon Sep 17 00:00:00 2001
From: Malvoz <26493779+Malvoz@users.noreply.github.com>
Date: Mon, 20 Dec 2021 15:50:26 +0100
Subject: [PATCH 02/14] Update attribution
---
src/mapml/control/AttributionButton.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/mapml/control/AttributionButton.js b/src/mapml/control/AttributionButton.js
index 969df8865..50491a98d 100644
--- a/src/mapml/control/AttributionButton.js
+++ b/src/mapml/control/AttributionButton.js
@@ -1,7 +1,7 @@
export var AttributionButton = L.Control.extend({
options: {
position: 'bottomright',
- prefix: 'Maps4HTML | Leaflet'
+ prefix: 'Maps for HTML Community Group | Leaflet'
},
initialize: function (options) {
From f3cacc2c9f82df6a59df305183005e03cb562885 Mon Sep 17 00:00:00 2001
From: Malvoz <26493779+Malvoz@users.noreply.github.com>
Date: Mon, 10 Jan 2022 07:22:02 +0100
Subject: [PATCH 03/14] Change the attribution control SVG to dark on light
---
src/mapml/control/AttributionButton.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/mapml/control/AttributionButton.js b/src/mapml/control/AttributionButton.js
index 50491a98d..a8681e12a 100644
--- a/src/mapml/control/AttributionButton.js
+++ b/src/mapml/control/AttributionButton.js
@@ -90,7 +90,7 @@ export var AttributionButton = L.Control.extend({
prefixAndAttribs.push(attribs.join(', '));
}
- this._container.innerHTML = '' + '' + prefixAndAttribs.join(' | ') + '
';
+ this._container.innerHTML = '' + '' + prefixAndAttribs.join(' | ') + '
';
}
});
From 17f4b9283a47462c49d4317e69e47ace640ccec7 Mon Sep 17 00:00:00 2001
From: Jacky0299
Date: Thu, 13 Apr 2023 10:01:32 -0400
Subject: [PATCH 04/14] attribution control
---
src/mapml-viewer.js | 1 -
src/mapml/control/AttributionButton.js | 23 ++++++++++++++----
src/mapml/control/AttributionControl.js | 30 ++++++++++++------------
src/mapml/index.js | 4 ++--
test/e2e/core/kbdAttribution.test.js | 2 ++
test/e2e/core/popupTabNavigation.test.js | 10 ++++++++
6 files changed, 47 insertions(+), 23 deletions(-)
diff --git a/src/mapml-viewer.js b/src/mapml-viewer.js
index 903059d8a..0f48bf3d3 100644
--- a/src/mapml-viewer.js
+++ b/src/mapml-viewer.js
@@ -266,7 +266,6 @@ export class MapViewer extends HTMLElement {
});
this._addToHistory();
// the attribution control is not optional
- M.attributionControl(this);
this._createControls();
this._toggleControls();
diff --git a/src/mapml/control/AttributionButton.js b/src/mapml/control/AttributionButton.js
index a8681e12a..d0517207d 100644
--- a/src/mapml/control/AttributionButton.js
+++ b/src/mapml/control/AttributionButton.js
@@ -1,4 +1,4 @@
-export var AttributionButton = L.Control.extend({
+export var AttributionButton = L.Control.Attribution.extend({
options: {
position: 'bottomright',
prefix: 'Maps for HTML Community Group | Leaflet'
@@ -24,6 +24,17 @@ export var AttributionButton = L.Control.extend({
map.on('layeradd', this._addAttribution, this);
+ let dialog = document.createElement("dialog");
+ dialog.setAttribute("class", "shortcuts-dialog");
+ dialog.setAttribute("autofocus", "");
+ dialog.onclick = function (e) {
+ e.stopPropagation();
+ };
+ dialog.innerHTML = `${M.options.locale.kbdShortcuts} ` +
+ `${M.options.locale.kbdMovement}- ↑ ${M.options.locale.kbdPanUp}
- ↓ ${M.options.locale.kbdPanDown}
- ← ${M.options.locale.kbdPanLeft}
- → ${M.options.locale.kbdPanRight}
- + ${M.options.locale.btnZoomIn}
- - ${M.options.locale.btnZoomOut}
- shift + ←/↑/→/↓ 3x ${M.options.locale.kbdPanIncrement}
- ctrl + ←/↑/→/↓ 0.2x ${M.options.locale.kbdPanIncrement}
- shift + +/- ${M.options.locale.kbdZoom}
` +
+ `${M.options.locale.kbdFeature}- ←/↑ ${M.options.locale.kbdPrevFeature}
- →/↓ ${M.options.locale.kbdNextFeature}
`;
+ map._container.appendChild(dialog);
+
return this._container;
},
@@ -90,17 +101,19 @@ export var AttributionButton = L.Control.extend({
prefixAndAttribs.push(attribs.join(', '));
}
- this._container.innerHTML = '' + '' + prefixAndAttribs.join(' | ') + '
';
-
+ this._container.innerHTML = '' + '';
+ this._container.setAttribute("role","group");
+ this._container.setAttribute("aria-label","Map data attribution");
}
});
L.Map.mergeOptions({
- attributionControl: true
+ attributionControl: false,
+ toggleableAttributionControl: true,
});
L.Map.addInitHook(function () {
- if (this.options.attributionControl) {
+ if (this.options.toggleableAttributionControl) {
new AttributionButton().addTo(this);
}
});
diff --git a/src/mapml/control/AttributionControl.js b/src/mapml/control/AttributionControl.js
index f7b3d8171..7291b40a3 100644
--- a/src/mapml/control/AttributionControl.js
+++ b/src/mapml/control/AttributionControl.js
@@ -1,17 +1,17 @@
-export var attributionControl = function (map) {
- map._attributionControl = map._map.attributionControl.setPrefix(` | Maps4HTML | Leaflet`);
+// export var attributionControl = function (map) {
+// map._attributionControl = map._map.attributionControl.setPrefix(` | Maps4HTML | Leaflet`);
- let dialog = document.createElement("dialog");
- dialog.setAttribute("class", "shortcuts-dialog");
- dialog.setAttribute("autofocus", "");
- dialog.onclick = function (e) {
- e.stopPropagation();
- };
- dialog.innerHTML = `${M.options.locale.kbdShortcuts} ` +
- `${M.options.locale.kbdMovement}- ↑ ${M.options.locale.kbdPanUp}
- ↓ ${M.options.locale.kbdPanDown}
- ← ${M.options.locale.kbdPanLeft}
- → ${M.options.locale.kbdPanRight}
- + ${M.options.locale.btnZoomIn}
- - ${M.options.locale.btnZoomOut}
- shift + ←/↑/→/↓ 3x ${M.options.locale.kbdPanIncrement}
- ctrl + ←/↑/→/↓ 0.2x ${M.options.locale.kbdPanIncrement}
- shift + +/- ${M.options.locale.kbdZoom}
` +
- `${M.options.locale.kbdFeature}- ←/↑ ${M.options.locale.kbdPrevFeature}
- →/↓ ${M.options.locale.kbdNextFeature}
`;
- map._container.appendChild(dialog);
+// let dialog = document.createElement("dialog");
+// dialog.setAttribute("class", "shortcuts-dialog");
+// dialog.setAttribute("autofocus", "");
+// dialog.onclick = function (e) {
+// e.stopPropagation();
+// };
+// dialog.innerHTML = `${M.options.locale.kbdShortcuts} ` +
+// `${M.options.locale.kbdMovement}- ↑ ${M.options.locale.kbdPanUp}
- ↓ ${M.options.locale.kbdPanDown}
- ← ${M.options.locale.kbdPanLeft}
- → ${M.options.locale.kbdPanRight}
- + ${M.options.locale.btnZoomIn}
- - ${M.options.locale.btnZoomOut}
- shift + ←/↑/→/↓ 3x ${M.options.locale.kbdPanIncrement}
- ctrl + ←/↑/→/↓ 0.2x ${M.options.locale.kbdPanIncrement}
- shift + +/- ${M.options.locale.kbdZoom}
` +
+// `${M.options.locale.kbdFeature}- ←/↑ ${M.options.locale.kbdPrevFeature}
- →/↓ ${M.options.locale.kbdNextFeature}
`;
+// map._container.appendChild(dialog);
- map._attributionControl.getContainer().setAttribute("role","group");
- map._attributionControl.getContainer().setAttribute("aria-label","Map data attribution");
-};
\ No newline at end of file
+// map._attributionControl.getContainer().setAttribute("role","group");
+// map._attributionControl.getContainer().setAttribute("aria-label","Map data attribution");
+// };
\ No newline at end of file
diff --git a/src/mapml/index.js b/src/mapml/index.js
index 18b8a9ea3..45b6e5678 100644
--- a/src/mapml/index.js
+++ b/src/mapml/index.js
@@ -54,7 +54,7 @@ import { Util } from './utils/Util';
import { AttributionButton, attributionButton } from './control/AttributionButton';
import { ReloadButton, reloadButton } from './control/ReloadButton';
import { FullscreenButton, fullscreenButton } from './control/FullscreenButton';
-import {attributionControl} from "./control/AttributionControl";
+// import {attributionControl} from "./control/AttributionControl";
import {geolocationButton} from "./control/GeolocationButton";
import { Crosshair, crosshair } from "./layers/Crosshair";
import { Feature, feature } from "./features/feature";
@@ -662,7 +662,7 @@ M.reloadButton = reloadButton;
M.FullscreenButton = FullscreenButton;
M.fullscreenButton = fullscreenButton;
-M.attributionControl = attributionControl;
+// M.attributionControl = attributionControl;
M.geolocationButton = geolocationButton;
diff --git a/test/e2e/core/kbdAttribution.test.js b/test/e2e/core/kbdAttribution.test.js
index 903d16187..55b63b972 100644
--- a/test/e2e/core/kbdAttribution.test.js
+++ b/test/e2e/core/kbdAttribution.test.js
@@ -18,6 +18,8 @@ test.describe("Keyboard shortcut attribution test", ()=> {
await page.keyboard.press("Tab");
}
+ await page.keyboard.press("Enter");
+ await page.keyboard.press("Tab");
await page.keyboard.press("Enter");
const dialog = await page.$eval("body > mapml-viewer div > dialog",
(dialog) => dialog.hasAttribute("open")
diff --git a/test/e2e/core/popupTabNavigation.test.js b/test/e2e/core/popupTabNavigation.test.js
index 4f0cfe0d1..966039729 100644
--- a/test/e2e/core/popupTabNavigation.test.js
+++ b/test/e2e/core/popupTabNavigation.test.js
@@ -191,6 +191,16 @@ test.describe("Playwright Keyboard Navigation + Query Layer Tests" , () => {
});
test("Focus Controls focuses the first