Skip to content

Commit b90da21

Browse files
committed
Fix selection algorithm for pmtiles stylesheet map-link
Close #977
1 parent 80f7d94 commit b90da21

14 files changed

+166
-13
lines changed

src/map-link.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -370,26 +370,23 @@ export class MapLink extends HTMLElement {
370370
(this.rel === 'tile' && this.type === 'application/pmtiles') ||
371371
this.type === 'application/vnd.mapbox-vector-tile'
372372
) {
373-
let relativeSelector =
373+
let s =
374374
'map-link[rel="stylesheet"][type="application/pmtiles+stylesheet"]';
375-
let rules = M.getClosest(
376-
this,
377-
'map-extent:has(' +
378-
relativeSelector +
379-
'),layer-:has(' +
380-
relativeSelector +
381-
'),mapml-viewer:has(' +
382-
relativeSelector +
383-
')'
384-
)?.querySelector(relativeSelector)._pmtilesRules;
375+
let pmtilesStylesheetLink = this.getLayerEl().src
376+
? this.closest('map-extent')?.querySelector(s) ??
377+
this.getRootNode().querySelector(':host > ' + s)
378+
: M.getClosest(
379+
this,
380+
'map-extent:has(' + s + '),layer-:has(' + s + ')'
381+
)?.querySelector(s);
385382
let options = {
386383
zoomBounds: this.getZoomBounds(),
387384
extentBounds: this.getBounds(),
388385
crs: M[this.parentExtent.units],
389386
zIndex: this.zIndex,
390387
pane: this.parentExtent._extentLayer.getContainer(),
391388
linkEl: this,
392-
pmtilesRules: rules
389+
pmtilesRules: pmtilesStylesheetLink?._pmtilesRules
393390
};
394391
this._templatedLayer = M.templatedPMTilesLayer(
395392
this._templateVars,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<mapml- xmlns="http://www.w3.org/1999/xhtml">
2+
<map-head>
3+
<map-title>pmtiles dark</map-title>
4+
5+
<map-link data-testid="operative-light" rel="stylesheet" type="application/pmtiles+stylesheet" href="lightTheme.js"></map-link>
6+
7+
<!-- only the first stylesheet in document order is used... -->
8+
<map-link data-testid="inoperative-dark" rel="stylesheet" type="application/pmtiles+stylesheet" href="darkTheme.js"></map-link>
9+
10+
<map-link rel="license" title="© OpenStreetMap contributors CC BY-SA" href="https://www.openstreetmap.org/copyright"></map-link>
11+
<map-link rel="self style" title="Dark theme" href="dark.mapml"></map-link>
12+
<map-link rel="style" title="Light theme" href="light.mapml"></map-link>
13+
<map-meta name="extent" content="top-left-easting=-11593204, top-left-northing=5581432, bottom-right-easting=-11516767, bottom-right-northing=5504995"></map-meta>
14+
</map-head>
15+
<map-body>
16+
<map-extent data-testid="light-me" label="light" units="OSMTILE" checked="checked" >
17+
18+
<!-- this guy should use the operative-light stylesheet in the map-head -->
19+
<map-link rel="tile" type="application/pmtiles" tref="../spearfish.pmtiles?theme=light"></map-link>
20+
21+
</map-extent>
22+
<map-extent data-testid="dark-me" label="dark" units="OSMTILE" checked="checked" >
23+
24+
<map-link data-testid="operative-dark" rel="stylesheet" type="application/pmtiles+stylesheet" href="darkTheme.js"></map-link>
25+
<map-link data-testid="inoperative-light" rel="stylesheet" type="application/pmtiles+stylesheet" href="lightTheme.js"></map-link>
26+
27+
<!-- this guy should use the operative-dark stylesheet -->
28+
<map-link rel="tile" type="application/pmtiles" tref="../spearfish.pmtiles?theme=dark"></map-link>
29+
30+
</map-extent>
31+
</map-body>
32+
</mapml->
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const pmtilesRules = new Map();
2+
pmtilesRules.set('http://localhost:30001/spearfish.pmtiles?theme=dark', {
3+
theme: { theme: 'dark' }
4+
});
5+
export { pmtilesRules };
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<mapml- xmlns="http://www.w3.org/1999/xhtml">
2+
<map-head>
3+
<map-title>pmtiles light</map-title>
4+
<map-link rel="stylesheet" type="application/pmtiles+stylesheet" href="lightTheme.js"></map-link>
5+
<map-link rel="license" title="© OpenStreetMap contributors CC BY-SA" href="https://www.openstreetmap.org/copyright"></map-link>
6+
<map-link rel="style" title="Dark theme" href="dark.mapml"></map-link>
7+
<map-link rel="self style" title="Light theme" href="light.mapml"></map-link>
8+
</map-head>
9+
<map-body>
10+
<map-extent units="OSMTILE" checked="checked" hidden="hidden">
11+
<map-link rel="tile" type="application/pmtiles" tref="../spearfish.pmtiles?theme=light"></map-link>
12+
</map-extent>
13+
</map-body>
14+
</mapml->
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const pmtilesRules = new Map();
2+
pmtilesRules.set('http://localhost:30001/spearfish.pmtiles?theme=light', {
3+
theme: { theme: 'light' }
4+
});
5+
export { pmtilesRules };
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width,initial-scale=1">
6+
<title>map-link-pmtiles-styles.html</title>
7+
<script type="module" src="../mapml-viewer.js"></script>
8+
</head>
9+
<body>
10+
<mapml-viewer data-testid="viewer" controls style="width: 500px;height: 500px;" projection="OSMTILE" zoom="10" lat="44.5" lon="-103.8">
11+
<layer- data-testid="dark" src="dark.mapml" ></layer->
12+
<layer- data-testid="local-layer">
13+
<map-link data-testid="local-operative-light" rel="stylesheet" type="application/pmtiles+stylesheet" href="lightTheme.js"></map-link>
14+
15+
<!-- only the first stylesheet within scope in document order is used... -->
16+
<map-link data-testid="local-inoperative-dark" rel="stylesheet" type="application/pmtiles+stylesheet" href="darkTheme.js"></map-link>
17+
<map-extent data-testid="local-light-me" label="light" units="OSMTILE" checked="checked" >
18+
19+
<!-- this guy should use the local-operative-light stylesheet in the local-layer -->
20+
<map-link rel="tile" type="application/pmtiles" tref="../spearfish.pmtiles?theme=light"></map-link>
21+
22+
</map-extent>
23+
<map-extent data-testid="local-dark-me" label="dark" units="OSMTILE" checked="checked" >
24+
25+
<map-link data-testid="local-operative-dark" rel="stylesheet" type="application/pmtiles+stylesheet" href="darkTheme.js"></map-link>
26+
<map-link data-testid="local-inoperative-light" rel="stylesheet" type="application/pmtiles+stylesheet" href="lightTheme.js"></map-link>
27+
28+
<!-- this guy should use the local-operative-dark stylesheet -->
29+
<map-link rel="tile" type="application/pmtiles" tref="../spearfish.pmtiles?theme=dark"></map-link>
30+
31+
</map-extent>
32+
</layer->
33+
</mapml-viewer>
34+
</body>
35+
</html>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { test, expect, chromium } from '@playwright/test';
2+
3+
test.describe('pmtiles map-link with associated style can be in a remote mapml document', () => {
4+
let page;
5+
let context;
6+
test.beforeAll(async function () {
7+
context = await chromium.launchPersistentContext('');
8+
page =
9+
context.pages().find((page) => page.url() === 'about:blank') ||
10+
(await context.newPage());
11+
});
12+
13+
test.beforeEach(async function () {
14+
await page.goto('pmtiles/map-link-pmtiles-styles.html');
15+
});
16+
test('map-link styles load correctly from within remote mapml', async () => {
17+
const viewer = page.getByTestId('viewer');
18+
await expect(viewer).toBeTruthy();
19+
const layer = viewer.getByTestId('dark');
20+
layer.evaluate((l) => (l.checked = true));
21+
await page.waitForTimeout(500);
22+
await expect(viewer).toHaveScreenshot('pmtiles-dark.png', {
23+
maxDiffPixels: 100
24+
});
25+
});
26+
27+
test('map-link in remote content selects correct stylesheet link from context', async () => {
28+
const viewer = page.getByTestId('viewer');
29+
await expect(viewer).toBeTruthy();
30+
const darkExtent = viewer.getByTestId('dark-me');
31+
const lightExtent = viewer.getByTestId('light-me');
32+
33+
await darkExtent.evaluate((e) => {
34+
e.removeAttribute('checked');
35+
});
36+
await lightExtent.evaluate((e) => {
37+
e.checked = true;
38+
});
39+
await page.waitForTimeout(500);
40+
await expect(viewer).toHaveScreenshot('pmtiles-light.png', {
41+
maxDiffPixels: 100
42+
});
43+
});
44+
test('map-link in local content selects correct stylesheet link from context', async () => {
45+
const viewer = page.getByTestId('viewer');
46+
await expect(viewer).toBeTruthy();
47+
const remoteLayer = viewer.getByTestId('dark');
48+
const layer = viewer.getByTestId('local-layer');
49+
await layer.evaluate((l) => (l.checked = true));
50+
51+
const darkExtent = viewer.getByTestId('local-dark-me');
52+
const lightExtent = viewer.getByTestId('local-light-me');
53+
54+
await darkExtent.evaluate((e) => {
55+
e.removeAttribute('checked');
56+
});
57+
await lightExtent.evaluate((e) => {
58+
e.checked = true;
59+
});
60+
await page.waitForTimeout(500);
61+
await expect(viewer).toHaveScreenshot('pmtiles-local-light.png', {
62+
maxDiffPixels: 100
63+
});
64+
});
65+
});

test/e2e/layers/templatedPMTilesMVTLayer.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ test.describe('Playwright templatedPMTilesLayer Tests', () => {
143143
await hardCodedVariablesLayer.evaluate((l) => (l.checked = true));
144144
await page.waitForTimeout(1000);
145145
await expect(viewer).toHaveScreenshot('mvt-blank.png', {
146-
maxDiffPixels: 1500
146+
maxDiffPixels: 100
147147
});
148148
let errorLoadingModule = false;
149149
let errorFindingRules = false;

0 commit comments

Comments
 (0)