diff --git a/src/mapml/layers/DebugOverlay.js b/src/mapml/layers/DebugOverlay.js index caeea2cd1..7f8605487 100644 --- a/src/mapml/layers/DebugOverlay.js +++ b/src/mapml/layers/DebugOverlay.js @@ -255,7 +255,7 @@ export var DebugVectors = L.LayerGroup.extend({ .getLayerEl() .getAttribute('data-testid') : layers[i].layerBounds && - layers[i].options?._leafletLayer?._layerEl.hasAttribute( + layers[i].options?._leafletLayer?._layerEl?.hasAttribute( 'data-testid' ) ? layers[i].options._leafletLayer._layerEl.getAttribute( diff --git a/src/mapml/layers/TemplatedFeaturesLayer.js b/src/mapml/layers/TemplatedFeaturesLayer.js index af4f08933..5213945fe 100644 --- a/src/mapml/layers/TemplatedFeaturesLayer.js +++ b/src/mapml/layers/TemplatedFeaturesLayer.js @@ -65,6 +65,7 @@ export var TemplatedFeaturesLayer = L.Layer.extend({ geometry.bindPopup(c, { autoClose: false, minWidth: 108 }); } }); + L.extend(this._features.options, { _leafletLayer: this._features }); } else { this._features.eachLayer((layer) => layer.addTo(map)); } diff --git a/test/e2e/elements/map-a/map-a-inline-or-remote-templated-issue-968.test.js b/test/e2e/elements/map-a/map-a-inline-or-remote-templated-issue-968.test.js new file mode 100644 index 000000000..9d9a12886 --- /dev/null +++ b/test/e2e/elements/map-a/map-a-inline-or-remote-templated-issue-968.test.js @@ -0,0 +1,75 @@ +import { test, expect, chromium } from '@playwright/test'; + +test.describe('map-a loaded inline or remote, directly or via templated map-link tests', () => { + let page; + let context; + test.beforeAll(async function () { + context = await chromium.launchPersistentContext(''); + page = + context.pages().find((page) => page.url() === 'about:blank') || + (await context.newPage()); + await page.goto('map-a.html'); + }); + + const contentLocations = ['inline', 'remote']; + for (const inlineOrRemote of contentLocations) { + test(`${inlineOrRemote} map-a-wrapped-map-geometry loaded directly creates a hyperlink`, async () => { + const directlyLoadedFeaturesLayer = await page.getByTestId( + `${inlineOrRemote}-features` + ); + const directlyLoadedFeaturesCount = + await directlyLoadedFeaturesLayer.evaluate((l) => { + let node = l.hasAttribute('src') ? l.shadowRoot : l; + return node.querySelectorAll('map-feature').length; + }); + expect(directlyLoadedFeaturesCount).toBe(2); + // one of them contains a map-a wrapping its map-geometry + const directlyLoadedHyperlinksCount = + await directlyLoadedFeaturesLayer.evaluate((l) => { + let node = l.hasAttribute('src') ? l.shadowRoot : l; + return node.querySelectorAll('map-feature:has(map-a)').length; + }); + expect(directlyLoadedHyperlinksCount).toBe(1); + // all features should have a _groupEl prop (i.e. all features are rendered) + const directlyLoadedFeaturesRenderedCount = + await directlyLoadedFeaturesLayer.evaluate((l) => { + let node = l.hasAttribute('src') ? l.shadowRoot : l; + const hasRendering = (f) => Boolean(f._groupEl); + return Array.from(node.querySelectorAll('map-feature')).filter( + hasRendering + ).length; + }); + expect(directlyLoadedFeaturesRenderedCount).toEqual( + directlyLoadedFeaturesCount + ); + }); + test(`${inlineOrRemote} map-a-wrapped-map-geometry loaded via templated map-link creates a hyperlink`, async () => { + await page.waitForTimeout(500); + const templatedLoadedFeaturesContainer = await page.getByTestId( + `${inlineOrRemote}-templated-link` + ); + const templatedLoadedFeaturesCount = + await templatedLoadedFeaturesContainer.evaluate((l) => { + return l.shadowRoot.querySelectorAll('map-feature').length; + }); + expect(templatedLoadedFeaturesCount).toBe(2); + // one of them contains a map-a wrapping its map-geometry + const templatedLoadedHyperlinksCount = + await templatedLoadedFeaturesContainer.evaluate((l) => { + return l.shadowRoot.querySelectorAll('map-feature:has(map-a)').length; + }); + expect(templatedLoadedHyperlinksCount).toBe(1); + // all features should have a _groupEl prop (i.e. all features are rendered) + const templatedLoadedFeaturesRenderedCount = + await templatedLoadedFeaturesContainer.evaluate((l) => { + const hasRendering = (f) => Boolean(f._groupEl); + return Array.from( + l.shadowRoot.querySelectorAll('map-feature') + ).filter(hasRendering).length; + }); + expect(templatedLoadedFeaturesRenderedCount).toEqual( + templatedLoadedFeaturesCount + ); + }); + } +}); diff --git a/test/e2e/elements/map-a/map-a.html b/test/e2e/elements/map-a/map-a.html new file mode 100644 index 000000000..b011380f0 --- /dev/null +++ b/test/e2e/elements/map-a/map-a.html @@ -0,0 +1,98 @@ + + + + Remote layer with map-link rel=features + + + + + + + + + + + .poi-r1-s1.poi-r1-s2 {opacity:1.0; fill:rebeccapurple; stroke:rebeccapurple; fill-opacity:0.7} + + + + -8238848.744948964 4969300.121476209 + + + + + + + + + + + + + + + + +
Property nameProperty value
MAINPAGEpics/22037829-L.jpg
+
+
+ + + + + -8238806.8429565085 4969306.111096254 + + + + + + + + + + + + + + + + + +
Property nameProperty value
MAINPAGEpics/22037827-L.jpg
+
+
+
+ + + + + + + + +
+ + \ No newline at end of file diff --git a/test/e2e/elements/map-a/remote-features.mapml b/test/e2e/elements/map-a/remote-features.mapml new file mode 100644 index 000000000..373fffc74 --- /dev/null +++ b/test/e2e/elements/map-a/remote-features.mapml @@ -0,0 +1,61 @@ + + + remote-features.mapml + + + + + + .poi-r1-s1.poi-r1-s2 {opacity:1.0; fill:red; stroke:red; fill-opacity:0.7} + + + + + + -8238848.744948964 4969300.121476209 + + + + + + + + + + + + + + + + +
Property nameProperty value
MAINPAGEpics/22037829-L.jpg
+
+
+ + + + + -8238806.8429565085 4969306.111096254 + + + + + + + + + + + + + + + + + +
Property nameProperty value
MAINPAGEpics/22037827-L.jpg
+
+
+
+
\ No newline at end of file diff --git a/test/e2e/elements/map-a/remote-rel-features.mapml b/test/e2e/elements/map-a/remote-rel-features.mapml new file mode 100644 index 000000000..e77265996 --- /dev/null +++ b/test/e2e/elements/map-a/remote-rel-features.mapml @@ -0,0 +1,20 @@ + + + remote-rel-features.mapml + + .poi-r1-s1.poi-r1-s2 {opacity:1.0; fill:blue; stroke:blue; fill-opacity:0.7} + + + + + + \ No newline at end of file diff --git a/test/server.js b/test/server.js index fff36e81c..22d184d3e 100644 --- a/test/server.js +++ b/test/server.js @@ -10,6 +10,7 @@ app.use(express.static(path.join(__dirname, 'e2e/elements/map-extent'))); app.use(express.static(path.join(__dirname, 'e2e/elements/mapml-viewer'))); app.use(express.static(path.join(__dirname, 'e2e/elements/map'))); app.use(express.static(path.join(__dirname, 'e2e/elements/map-feature'))); +app.use(express.static(path.join(__dirname, 'e2e/elements/map-a'))); app.use(express.static(path.join(__dirname, 'e2e/elements/map-input'))); app.use(express.static(path.join(__dirname, 'e2e/elements/map-link'))); app.use(express.static(path.join(__dirname, 'e2e/elements/map-style')));