Skip to content

Commit

Permalink
Fix selection algorithm for pmtiles stylesheet map-link
Browse files Browse the repository at this point in the history
Close #977
  • Loading branch information
prushforth committed Aug 28, 2024
1 parent 80f7d94 commit b90da21
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 13 deletions.
21 changes: 9 additions & 12 deletions src/map-link.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,26 +370,23 @@ export class MapLink extends HTMLElement {
(this.rel === 'tile' && this.type === 'application/pmtiles') ||
this.type === 'application/vnd.mapbox-vector-tile'
) {
let relativeSelector =
let s =
'map-link[rel="stylesheet"][type="application/pmtiles+stylesheet"]';
let rules = M.getClosest(
this,
'map-extent:has(' +
relativeSelector +
'),layer-:has(' +
relativeSelector +
'),mapml-viewer:has(' +
relativeSelector +
')'
)?.querySelector(relativeSelector)._pmtilesRules;
let pmtilesStylesheetLink = this.getLayerEl().src
? this.closest('map-extent')?.querySelector(s) ??
this.getRootNode().querySelector(':host > ' + s)
: M.getClosest(
this,
'map-extent:has(' + s + '),layer-:has(' + s + ')'
)?.querySelector(s);
let options = {
zoomBounds: this.getZoomBounds(),
extentBounds: this.getBounds(),
crs: M[this.parentExtent.units],
zIndex: this.zIndex,
pane: this.parentExtent._extentLayer.getContainer(),
linkEl: this,
pmtilesRules: rules
pmtilesRules: pmtilesStylesheetLink?._pmtilesRules
};
this._templatedLayer = M.templatedPMTilesLayer(
this._templateVars,
Expand Down
32 changes: 32 additions & 0 deletions test/e2e/elements/map-link/pmtiles/dark.mapml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<mapml- xmlns="http://www.w3.org/1999/xhtml">
<map-head>
<map-title>pmtiles dark</map-title>

<map-link data-testid="operative-light" rel="stylesheet" type="application/pmtiles+stylesheet" href="lightTheme.js"></map-link>

<!-- only the first stylesheet in document order is used... -->
<map-link data-testid="inoperative-dark" rel="stylesheet" type="application/pmtiles+stylesheet" href="darkTheme.js"></map-link>

<map-link rel="license" title="© OpenStreetMap contributors CC BY-SA" href="https://www.openstreetmap.org/copyright"></map-link>
<map-link rel="self style" title="Dark theme" href="dark.mapml"></map-link>
<map-link rel="style" title="Light theme" href="light.mapml"></map-link>
<map-meta name="extent" content="top-left-easting=-11593204, top-left-northing=5581432, bottom-right-easting=-11516767, bottom-right-northing=5504995"></map-meta>
</map-head>
<map-body>
<map-extent data-testid="light-me" label="light" units="OSMTILE" checked="checked" >

<!-- this guy should use the operative-light stylesheet in the map-head -->
<map-link rel="tile" type="application/pmtiles" tref="../spearfish.pmtiles?theme=light"></map-link>

</map-extent>
<map-extent data-testid="dark-me" label="dark" units="OSMTILE" checked="checked" >

<map-link data-testid="operative-dark" rel="stylesheet" type="application/pmtiles+stylesheet" href="darkTheme.js"></map-link>
<map-link data-testid="inoperative-light" rel="stylesheet" type="application/pmtiles+stylesheet" href="lightTheme.js"></map-link>

<!-- this guy should use the operative-dark stylesheet -->
<map-link rel="tile" type="application/pmtiles" tref="../spearfish.pmtiles?theme=dark"></map-link>

</map-extent>
</map-body>
</mapml->
5 changes: 5 additions & 0 deletions test/e2e/elements/map-link/pmtiles/darkTheme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const pmtilesRules = new Map();
pmtilesRules.set('http://localhost:30001/spearfish.pmtiles?theme=dark', {
theme: { theme: 'dark' }
});
export { pmtilesRules };
14 changes: 14 additions & 0 deletions test/e2e/elements/map-link/pmtiles/light.mapml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<mapml- xmlns="http://www.w3.org/1999/xhtml">
<map-head>
<map-title>pmtiles light</map-title>
<map-link rel="stylesheet" type="application/pmtiles+stylesheet" href="lightTheme.js"></map-link>
<map-link rel="license" title="© OpenStreetMap contributors CC BY-SA" href="https://www.openstreetmap.org/copyright"></map-link>
<map-link rel="style" title="Dark theme" href="dark.mapml"></map-link>
<map-link rel="self style" title="Light theme" href="light.mapml"></map-link>
</map-head>
<map-body>
<map-extent units="OSMTILE" checked="checked" hidden="hidden">
<map-link rel="tile" type="application/pmtiles" tref="../spearfish.pmtiles?theme=light"></map-link>
</map-extent>
</map-body>
</mapml->
5 changes: 5 additions & 0 deletions test/e2e/elements/map-link/pmtiles/lightTheme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const pmtilesRules = new Map();
pmtilesRules.set('http://localhost:30001/spearfish.pmtiles?theme=light', {
theme: { theme: 'light' }
});
export { pmtilesRules };
35 changes: 35 additions & 0 deletions test/e2e/elements/map-link/pmtiles/map-link-pmtiles-styles.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>map-link-pmtiles-styles.html</title>
<script type="module" src="../mapml-viewer.js"></script>
</head>
<body>
<mapml-viewer data-testid="viewer" controls style="width: 500px;height: 500px;" projection="OSMTILE" zoom="10" lat="44.5" lon="-103.8">
<layer- data-testid="dark" src="dark.mapml" ></layer->
<layer- data-testid="local-layer">
<map-link data-testid="local-operative-light" rel="stylesheet" type="application/pmtiles+stylesheet" href="lightTheme.js"></map-link>

<!-- only the first stylesheet within scope in document order is used... -->
<map-link data-testid="local-inoperative-dark" rel="stylesheet" type="application/pmtiles+stylesheet" href="darkTheme.js"></map-link>
<map-extent data-testid="local-light-me" label="light" units="OSMTILE" checked="checked" >

<!-- this guy should use the local-operative-light stylesheet in the local-layer -->
<map-link rel="tile" type="application/pmtiles" tref="../spearfish.pmtiles?theme=light"></map-link>

</map-extent>
<map-extent data-testid="local-dark-me" label="dark" units="OSMTILE" checked="checked" >

<map-link data-testid="local-operative-dark" rel="stylesheet" type="application/pmtiles+stylesheet" href="darkTheme.js"></map-link>
<map-link data-testid="local-inoperative-light" rel="stylesheet" type="application/pmtiles+stylesheet" href="lightTheme.js"></map-link>

<!-- this guy should use the local-operative-dark stylesheet -->
<map-link rel="tile" type="application/pmtiles" tref="../spearfish.pmtiles?theme=dark"></map-link>

</map-extent>
</layer->
</mapml-viewer>
</body>
</html>
65 changes: 65 additions & 0 deletions test/e2e/elements/map-link/pmtiles/map-link-pmtiles-styles.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { test, expect, chromium } from '@playwright/test';

test.describe('pmtiles map-link with associated style can be in a remote mapml document', () => {
let page;
let context;
test.beforeAll(async function () {
context = await chromium.launchPersistentContext('');
page =
context.pages().find((page) => page.url() === 'about:blank') ||
(await context.newPage());
});

test.beforeEach(async function () {
await page.goto('pmtiles/map-link-pmtiles-styles.html');
});
test('map-link styles load correctly from within remote mapml', async () => {
const viewer = page.getByTestId('viewer');
await expect(viewer).toBeTruthy();
const layer = viewer.getByTestId('dark');
layer.evaluate((l) => (l.checked = true));
await page.waitForTimeout(500);
await expect(viewer).toHaveScreenshot('pmtiles-dark.png', {
maxDiffPixels: 100
});
});

test('map-link in remote content selects correct stylesheet link from context', async () => {
const viewer = page.getByTestId('viewer');
await expect(viewer).toBeTruthy();
const darkExtent = viewer.getByTestId('dark-me');
const lightExtent = viewer.getByTestId('light-me');

await darkExtent.evaluate((e) => {
e.removeAttribute('checked');
});
await lightExtent.evaluate((e) => {
e.checked = true;
});
await page.waitForTimeout(500);
await expect(viewer).toHaveScreenshot('pmtiles-light.png', {
maxDiffPixels: 100
});
});
test('map-link in local content selects correct stylesheet link from context', async () => {
const viewer = page.getByTestId('viewer');
await expect(viewer).toBeTruthy();
const remoteLayer = viewer.getByTestId('dark');
const layer = viewer.getByTestId('local-layer');
await layer.evaluate((l) => (l.checked = true));

const darkExtent = viewer.getByTestId('local-dark-me');
const lightExtent = viewer.getByTestId('local-light-me');

await darkExtent.evaluate((e) => {
e.removeAttribute('checked');
});
await lightExtent.evaluate((e) => {
e.checked = true;
});
await page.waitForTimeout(500);
await expect(viewer).toHaveScreenshot('pmtiles-local-light.png', {
maxDiffPixels: 100
});
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test/e2e/layers/templatedPMTilesMVTLayer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ test.describe('Playwright templatedPMTilesLayer Tests', () => {
await hardCodedVariablesLayer.evaluate((l) => (l.checked = true));
await page.waitForTimeout(1000);
await expect(viewer).toHaveScreenshot('mvt-blank.png', {
maxDiffPixels: 1500
maxDiffPixels: 100
});
let errorLoadingModule = false;
let errorFindingRules = false;
Expand Down

0 comments on commit b90da21

Please sign in to comment.