Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/mapml.css
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,19 @@ the browser)' */
color: revert;
}

.mapml-layer-item-legend-link {
display: inline-block;
margin-block-start: .25rem;
}

.mapml-layer-item-legend-image {
display: block;
max-width: min(100%, 16rem);
height: auto;
border: 1px solid #e3e3e3;
border-radius: 2px;
}

.leaflet-top .leaflet-control {
margin-top: 5px;
}
Expand Down Expand Up @@ -801,7 +814,7 @@ label.mapml-layer-item-toggle {
padding-block-start: .25rem;
padding-block-end: .25rem;
padding-inline-start: .25rem;
padding-inline-end: 1rem;
display: inline-block;
}

.mapml-layer-item-settings > * {
Expand Down
32 changes: 29 additions & 3 deletions src/mapml/elementSupport/layers/createLayerControlForLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,38 @@ export var createLayerControlHTML = async function () {
};
input.addEventListener('change', changeCheck.bind(this));
if (this._layer._legendUrl) {
var legendLink = document.createElement('a');
legendLink.text = ' ' + this._layer._title;
layerItemName.innerText = this._layer._title;

let legendControl = DomUtil.create(
'details',
'mapml-layer-item-legend mapml-control-layers',
layerItemSettings
),
legendSummary = DomUtil.create('summary'),
legendLink = document.createElement('a'),
legendImage = document.createElement('img');

legendSummary.innerText = mapEl.locale.lmLegend;
legendControl.appendChild(legendSummary);

legendLink.href = this._layer._legendUrl;
legendLink.target = '_blank';
legendLink.rel = 'noopener noreferrer';
legendLink.draggable = false;
layerItemName.appendChild(legendLink);
legendLink.className = 'mapml-layer-item-legend-link';

legendImage.src = this._layer._legendUrl;
legendImage.alt = `${this._layer._title} legend`;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to localize

legendImage.loading = 'lazy';
legendImage.decoding = 'async';
legendImage.className = 'mapml-layer-item-legend-image';
legendImage.addEventListener('error', () => {
legendLink.textContent = mapEl.locale.lmOpenInNewTab;
legendImage.remove();
});

legendLink.appendChild(legendImage);
legendControl.appendChild(legendLink);
} else {
layerItemName.innerHTML = this._layer._title;
}
Expand Down
60 changes: 60 additions & 0 deletions test/e2e/layers/layerLegend.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en">

<head>
<title>Layer Legend Control Tests</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="module" src="mapml.js"></script>
<style>
html,
body {
height: 100%;
}

* {
margin: 0;
padding: 0;
}

mapml-viewer:defined {
max-width: 100%;
width: 100%;
height: 100%;
}

mapml-viewer:not(:defined) > * {
display: none;
}

map-layer {
display: none;
}
</style>
</head>

<body>
<mapml-viewer projection="CBMTILE" zoom="2" lat="45" lon="-95" controls>
<map-layer label="Toporama" src="data/templatedImage.mapml" checked></map-layer>

<map-layer label="Inline No Legend" checked>
<map-meta name="zoom" content="min=0,max=3,value=2"></map-meta>
<map-meta name="projection" content="CBMTILE"></map-meta>
<map-tile zoom="2" row="10" col="11" src="data/cbmt/2/c11_r10.png"></map-tile>
</map-layer>

<map-layer label="html legend" checked>
<map-meta name="zoom" content="min=0,max=3,value=2"></map-meta>
<map-meta name="projection" content="CBMTILE"></map-meta>
<map-link rel="legend" href="https://maps4html.org/web-map-doc/"></map-link>
<map-feature>
<map-geometry cs="gcrs">
<map-point class="ottawa">
<map-coordinates>-75.697193 45.421530</map-coordinates>
</map-point>
</map-geometry>
</map-feature>
</mapml-viewer>
</body>

</html>
93 changes: 93 additions & 0 deletions test/e2e/layers/layerLegend.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { test, expect, chromium } from '@playwright/test';

test.describe('Layer legend tests', () => {
let page;
let context;

test.beforeAll(async () => {
context = await chromium.launchPersistentContext('', { slowMo: 250 });
page = await context.newPage();
await page.goto('layerLegend.html');
await page.locator('mapml-viewer').hover();
});

test.afterAll(async () => {
await context.close();
});

test('Legend layer has legend details in layer settings', async () => {
// Get the first layer in the overlay list (the one with an img legend)
const layer = page
.locator('.leaflet-control-layers-overlays > fieldset')
.first();

// Open the settings for that layer and check that the legend details are present
const settings = layer.locator('.mapml-layer-item-settings');

// Check that the legend details, name, and link are present and correct
const legendDetails = settings.locator('details.mapml-layer-item-legend');
await expect(legendDetails).toHaveCount(1);
await expect(legendDetails.locator('summary')).toHaveText('Legend');
await expect(
legendDetails.locator('a.mapml-layer-item-legend-link')
).toHaveAttribute(
'href',
'http://maps.geogratis.gc.ca/wms/toporama_en?SERVICE=WMS&REQUEST=GetLegendGraphic&LAYER=WMS-Toporama&VERSION=1.1&FORMAT=image/png'
);
await expect(
legendDetails.locator('img.mapml-layer-item-legend-image')
).toHaveAttribute(
'src',
'http://maps.geogratis.gc.ca/wms/toporama_en?SERVICE=WMS&REQUEST=GetLegendGraphic&LAYER=WMS-Toporama&VERSION=1.1&FORMAT=image/png'
);

// check that the legend details are the second details element in the settings
const secondDetails = settings.locator('> details').nth(1);
await expect(secondDetails).toHaveClass(
'mapml-layer-item-legend mapml-control-layers'
);
});

test('Layer without legend does not render legend details in settings', async () => {
// Get the second layer in the overlay list (the one without a legend)
const layer = page
.locator('.leaflet-control-layers-overlays > fieldset')
.nth(1);

// check that the settings for that layer do not contain any legend details
const settings = layer.locator('.mapml-layer-item-settings');
await expect(
settings.locator('details.mapml-layer-item-legend')
).toHaveCount(0);
});

test('Layer with a non img legend renders a legend link', async () => {
// Get the third layer in the overlay list (the one with a non img legend)
const layer = page
.locator('.leaflet-control-layers-overlays > fieldset')
.nth(2);

// check that the settings for that layer contain a legend link
const settings = layer.locator('.mapml-layer-item-settings');

// Check that the legend details, name, and link are present and correct
const legendDetails = settings.locator('details.mapml-layer-item-legend');
await expect(legendDetails).toHaveCount(1);
await expect(legendDetails.locator('summary')).toHaveText('Legend');
await expect(
legendDetails.locator('a.mapml-layer-item-legend-link')
).toHaveAttribute('href', 'https://maps4html.org/web-map-doc/');

// not working, need to manually open the legend for it to update.
/*await expect(
legendDetails.locator('a.mapml-layer-item-legend-link')
).toHaveText("Open Legend");
*/

// check that the legend details are the second details element in the settings
const secondDetails = settings.locator('> details').nth(1);
await expect(secondDetails).toHaveClass(
'mapml-layer-item-legend mapml-control-layers'
);
});
});
Loading