From 4ed39faa7bb6c0bd2e1c7010752ad54593808c25 Mon Sep 17 00:00:00 2001 From: Peter Rushforth Date: Fri, 13 Dec 2024 15:48:30 -0500 Subject: [PATCH] Add media attribute to map-layer, map-link Remove prefers-map-content hardcoded demo hack Add implementation of _changeHandler that invokes _onAdd, _onRemove. Add media query matches to map-layer._validateDisabled Re-organize _onRemove so that stuff isn't deleted until it's no longer needed, Make call to registerMediaQuery(mq) conditional on there being a mq, make it the path through which a layer gets initialized only when that is true, so as to not perform _onAdd twice. Move detection of media query matches check out of core if (map) block in map-layer._validateDisabled() Remove vestige of old prefers-map-content demo implementation from both map-link.js and layer.js Make execution of map-extent's map-projectionchange handler conditional on the there being a parentLayer._layer property value. This specifically covers the case when this handler is invoked by the projection change event happening, in which the parent layer may be disabled due to a media condition and therefore there is no LayerGroup to add the extentLayer to. add map-layer media attribute as an observed attribute Make map-link._registerMediaQuery async, wait on mapml-viewer to be ready before trying to register a media query (which may depend on mapml-viewer.extent). Remove map-link media attribute from those attributes that are copied onto the 'rendered' element, because the link element actually supports the media attribute, but not the media features we are designing (hence it always forces the element to be disabled). Update map-layer._registerMediaQuery so that when the observed media attribute is removed or set to the empty string, the map-layer goes through the initialization life cycle, as though it was newly connected to the DOM (it may go from disabled to enabled due to the removal). Clean up map-layer _registerMediaQuery Add tests for attribute Add tests for attributes Add test for attribute cycling Update linux image for map-link-media test Co-authored-by: Yushan Mu --- src/layer.js | 154 +++++++++--------- src/map-extent.js | 2 +- src/map-link.js | 32 ++-- test/e2e/data/restaurants/restaurants.mapml | 16 +- .../elements/map-layer/map-layer-media.html | 44 +++++ .../map-layer/map-layer-media.test.js | 90 ++++++++++ .../map-link/map-link-disabled.test.js | 9 +- .../e2e/elements/map-link/map-link-media.html | 4 +- .../elements/map-link/map-link-media.test.js | 16 ++ .../default-styled-markers-linux.png | Bin 0 -> 9793 bytes .../default-styled-markers-win32.png | Bin 0 -> 9712 bytes .../map-link/map-link-stylesheet-media.html | 49 ++++++ .../map-link-stylesheet-media.test.js | 69 ++++++++ .../default-styled-markers-linux.png | Bin 0 -> 8513 bytes .../default-styled-markers-win32.png | Bin 0 -> 8513 bytes .../red-styled-markers-linux.png | Bin 0 -> 7688 bytes .../red-styled-markers-win32.png | Bin 0 -> 7688 bytes test/e2e/elements/map-link/red.css | 4 + 18 files changed, 388 insertions(+), 101 deletions(-) create mode 100644 test/e2e/elements/map-layer/map-layer-media.html create mode 100644 test/e2e/elements/map-layer/map-layer-media.test.js create mode 100644 test/e2e/elements/map-link/map-link-media.test.js-snapshots/default-styled-markers-linux.png create mode 100644 test/e2e/elements/map-link/map-link-media.test.js-snapshots/default-styled-markers-win32.png create mode 100644 test/e2e/elements/map-link/map-link-stylesheet-media.html create mode 100644 test/e2e/elements/map-link/map-link-stylesheet-media.test.js create mode 100644 test/e2e/elements/map-link/map-link-stylesheet-media.test.js-snapshots/default-styled-markers-linux.png create mode 100644 test/e2e/elements/map-link/map-link-stylesheet-media.test.js-snapshots/default-styled-markers-win32.png create mode 100644 test/e2e/elements/map-link/map-link-stylesheet-media.test.js-snapshots/red-styled-markers-linux.png create mode 100644 test/e2e/elements/map-link/map-link-stylesheet-media.test.js-snapshots/red-styled-markers-win32.png create mode 100644 test/e2e/elements/map-link/red.css diff --git a/src/layer.js b/src/layer.js index 2ce4c1f50..defa1932b 100644 --- a/src/layer.js +++ b/src/layer.js @@ -6,7 +6,7 @@ import { createLayerControlHTML } from './mapml/elementSupport/layers/createLaye export class BaseLayerElement extends HTMLElement { static get observedAttributes() { - return ['src', 'label', 'checked', 'hidden', 'opacity']; + return ['src', 'label', 'checked', 'hidden', 'opacity', 'media']; } /* jshint ignore:start */ #hasConnected; @@ -53,6 +53,13 @@ export class BaseLayerElement extends HTMLElement { } } + get media() { + return this.getAttribute('media'); + } + set media(val) { + this.setAttribute('media', val); + } + get opacity() { // use ?? since 0 is falsy, || would return rhs in that case return +(this._opacity ?? this.getAttribute('opacity')); @@ -114,17 +121,59 @@ export class BaseLayerElement extends HTMLElement { this._onAdd(); } } + break; + case 'media': + if (oldValue !== newValue) { + this._registerMediaQuery(newValue); + } + break; } } } + _registerMediaQuery(mq) { + if (!this._changeHandler) { + this._changeHandler = () => { + this._onRemove(); + if (this._mql.matches) { + this._onAdd(); + } + // set the disabled 'read-only' attribute indirectly, via _validateDisabled + this._validateDisabled(); + }; + } + + if (mq) { + // a new media query is being established + let map = this.getMapEl(); + if (!map) return; + // Remove listener from the old media query (if it exists) + if (this._mql) { + this._mql.removeEventListener('change', this._changeHandler); + } + + this._mql = map.matchMedia(mq); + this._changeHandler(); + this._mql.addEventListener('change', this._changeHandler); + } else if (this._mql) { + // the media attribute removed or query set to '' + this._mql.removeEventListener('change', this._changeHandler); + delete this._mql; + // effectively, no / empty media attribute matches, do what changeHandler does + this._onRemove(); + this._onAdd(); + this._validateDisabled(); + } + } + getMapEl() { + return Util.getClosest(this, 'mapml-viewer,map[is=web-map]'); + } constructor() { // Always call super first in constructor super(); // this._opacity is used to record the current opacity value (with or without updates), // the initial value of this._opacity should be set as opacity attribute value, if exists, or the default value 1.0 this._opacity = this.opacity || 1.0; - this._renderingMapContent = M.options.contentPreference; this.attachShadow({ mode: 'open' }); } disconnectedCallback() { @@ -132,6 +181,13 @@ export class BaseLayerElement extends HTMLElement { // removed from the map and the layer control if (this.hasAttribute('data-moving')) return; this._onRemove(); + + if (this._mql) { + if (this._changeHandler) { + this._mql.removeEventListener('change', this._changeHandler); + } + delete this._mql; + } } _onRemove() { @@ -141,13 +197,6 @@ export class BaseLayerElement extends HTMLElement { let l = this._layer, lc = this._layerControl, lchtml = this._layerControlHTML; - // remove properties of layer involved in whenReady() logic - delete this._layer; - delete this._layerControl; - delete this._layerControlHTML; - delete this._fetchError; - this.shadowRoot.innerHTML = ''; - if (this.src) this.innerHTML = ''; if (l) { l.off(); @@ -158,8 +207,16 @@ export class BaseLayerElement extends HTMLElement { } if (lc && !this.hidden) { + // lc.removeLayer depends on this._layerControlHTML, can't delete it until after lc.removeLayer(l); } + // remove properties of layer involved in whenReady() logic + delete this._layer; + delete this._layerControl; + delete this._layerControlHTML; + delete this._fetchError; + this.shadowRoot.innerHTML = ''; + if (this.src) this.innerHTML = ''; } connectedCallback() { @@ -170,11 +227,17 @@ export class BaseLayerElement extends HTMLElement { this._createLayerControlHTML = createLayerControlHTML.bind(this); const doConnected = this._onAdd.bind(this); const doRemove = this._onRemove.bind(this); + const registerMediaQuery = this._registerMediaQuery.bind(this); + let mq = this.media; this.parentElement .whenReady() .then(() => { doRemove(); - doConnected(); + if (mq) { + registerMediaQuery(mq); + } else { + doConnected(); + } }) .catch((error) => { throw new Error('Map never became ready: ' + error); @@ -189,20 +252,11 @@ export class BaseLayerElement extends HTMLElement { e.stopPropagation(); // if user changes the style in layer control if (e.detail) { - this._renderingMapContent = e.detail._renderingMapContent; this.src = e.detail.src; } }, { once: true } ); - this.addEventListener( - 'zoomchangesrc', - function (e) { - e.stopPropagation(); - this.src = e.detail.href; - }, - { once: true } - ); let base = this.baseURI ? this.baseURI : document.baseURI; const headers = new Headers(); headers.append('Accept', 'text/mapml'); @@ -240,7 +294,6 @@ export class BaseLayerElement extends HTMLElement { .then(() => { // may throw: this.selectAlternateOrChangeProjection(); - this.checkForPreferredContent(); }) .then(() => { this._layer = mapMLLayer(new URL(this.src, base).href, this, { @@ -278,7 +331,6 @@ export class BaseLayerElement extends HTMLElement { .then(() => { // may throw: this.selectAlternateOrChangeProjection(); - this.checkForPreferredContent(); }) .then(() => { this._layer = mapMLLayer(null, this, { @@ -317,13 +369,6 @@ export class BaseLayerElement extends HTMLElement { ); this.parentElement.projection = e.cause.mapprojection; } - } else if (e.message === 'findmatchingpreferredcontent') { - if (e.cause.href) { - console.log( - 'Changing layer to matching preferred content at: ' + e.cause.href - ); - this.src = e.cause.href; - } } else if (e.message === 'Failed to fetch') { // cut short whenReady with the _fetchError property this._fetchError = true; @@ -372,23 +417,6 @@ export class BaseLayerElement extends HTMLElement { } } - checkForPreferredContent() { - let mapml = this.src ? this.shadowRoot : this; - let availablePreferMapContents = mapml.querySelector( - `map-link[rel="style"][media="prefers-map-content=${this._renderingMapContent}"][href]` - ); - if (availablePreferMapContents) { - // resolve href - let url = new URL( - availablePreferMapContents.getAttribute('href'), - availablePreferMapContents.getBase() - ).href; - throw new Error('findmatchingpreferredcontent', { - cause: { href: url } - }); - } - } - copyRemoteContentToShadowRoot(mapml) { let shadowRoot = this.shadowRoot; // get the map-meta[name=projection/cs/extent/zoom] from map-head of remote mapml, attach them to the shadowroot @@ -610,8 +638,13 @@ export class BaseLayerElement extends HTMLElement { setTimeout(() => { let layer = this._layer, map = layer?._map; + // if there's a media query in play, check it early + if (this._mql && !this._mql.matches) { + this.setAttribute('disabled', ''); + this.disabled = true; + return; + } if (map) { - this._validateLayerZoom({ zoom: map.getZoom() }); // prerequisite: no inline and remote mapml elements exists at the same time const mapExtents = this.src ? this.shadowRoot.querySelectorAll('map-extent') @@ -664,35 +697,6 @@ export class BaseLayerElement extends HTMLElement { } }, 0); } - _validateLayerZoom(e) { - // get the min and max zooms from all extents - let toZoom = e.zoom; - let min = this.extent.zoom.minZoom; - let max = this.extent.zoom.maxZoom; - let inLink = this.src - ? this.shadowRoot.querySelector('map-link[rel=zoomin]') - : this.querySelector('map-link[rel=zoomin]'), - outLink = this.src - ? this.shadowRoot.querySelector('map-link[rel=zoomout]') - : this.querySelector('map-link[rel=zoomout]'); - let targetURL; - if (!(min <= toZoom && toZoom <= max)) { - if (inLink && toZoom > max) { - targetURL = inLink.href; - } else if (outLink && toZoom < min) { - targetURL = outLink.href; - } - if (targetURL) { - this.dispatchEvent( - new CustomEvent('zoomchangesrc', { - detail: { - href: targetURL - } - }) - ); - } - } - } // disable/italicize layer control elements based on the map-layer.disabled property toggleLayerControlDisabled() { let input = this._layerControlCheckbox, diff --git a/src/map-extent.js b/src/map-extent.js index b94b34271..e34267bef 100644 --- a/src/map-extent.js +++ b/src/map-extent.js @@ -431,7 +431,7 @@ export class HTMLExtentElement extends HTMLElement { _handleChange() { // add _extentLayer to map if map-extent is checked, otherwise remove it - if (this.checked && !this.disabled) { + if (this.checked && !this.disabled && this.parentLayer._layer) { // can be added to mapmllayer layerGroup no matter map-layer is checked or not this._extentLayer.addTo(this.parentLayer._layer); this._extentLayer.setZIndex( diff --git a/src/map-link.js b/src/map-link.js index bcc1fa7d6..f2811b4f5 100644 --- a/src/map-link.js +++ b/src/map-link.js @@ -277,6 +277,9 @@ export class HTMLLinkElement extends HTMLElement { case 'image': case 'features': case 'query': + // because we skip the attributeChangedCallback for initialization, + // respect the disabled attribute which can be set by the author prior + // to initialization if (!this.disabled) { this._initTemplateVars(); await this._createTemplatedLink(); @@ -296,7 +299,9 @@ export class HTMLLinkElement extends HTMLElement { //this._createLegendLink(); break; case 'stylesheet': - this._createStylesheetLink(); + if (!this.disabled) { + this._createStylesheetLink(); + } break; case 'alternate': this._createAlternateLink(); // add media attribute @@ -305,7 +310,10 @@ export class HTMLLinkElement extends HTMLElement { // this._createLicenseLink(); break; } - this._registerMediaQuery(this.media); + // the media attribute uses / overrides the disabled attribute to enable or + // disable the link, so at this point the #hasConnected must be true so + // that the disabled attributeChangedCallback can have its desired side effect + await this._registerMediaQuery(this.media); // create the type of templated leaflet layer appropriate to the rel value // image/map/features = templated(Image/Feature), tile=templatedTile, // this._tempatedTileLayer = Util.templatedTile(pane: this.extentElement._leafletLayer._container) @@ -361,18 +369,16 @@ export class HTMLLinkElement extends HTMLElement { case 'image': case 'features': case 'query': - if (!this.disabled) { - this._initTemplateVars(); - await this._createTemplatedLink(); - this.getLayerEl()._validateDisabled(); - } + this._initTemplateVars(); + await this._createTemplatedLink(); + this.getLayerEl()._validateDisabled(); break; case 'stylesheet': this._createStylesheetLink(); break; } } - _registerMediaQuery(mq) { + async _registerMediaQuery(mq) { if (!this._changeHandler) { // Define and bind the change handler once this._changeHandler = () => { @@ -383,6 +389,9 @@ export class HTMLLinkElement extends HTMLElement { if (mq) { let map = this.getMapEl(); if (!map) return; + // have to wait until map has an extent i.e. is ready, because the + // matchMedia function below relies on it for map related queries + await map.whenReady(); // Remove listener from the old media query (if it exists) if (this._mql) { @@ -397,6 +406,8 @@ export class HTMLLinkElement extends HTMLElement { // Clean up the existing listener this._mql.removeEventListener('change', this._changeHandler); delete this._mql; + // unlike map-layer.disabled, map-link.disabled is an observed attribute + this.disabled = false; } } _createAlternateLink(mapml) { @@ -451,7 +462,7 @@ export class HTMLLinkElement extends HTMLElement { function copyAttributes(source, target) { return Array.from(source.attributes).forEach((attribute) => { - if (attribute.nodeName !== 'href') + if (attribute.nodeName !== 'href' && attribute.nodeName !== 'media') target.setAttribute(attribute.nodeName, attribute.nodeValue); }); } @@ -989,8 +1000,7 @@ export class HTMLLinkElement extends HTMLElement { layerEl.dispatchEvent( new CustomEvent('changestyle', { detail: { - src: e.target.getAttribute('data-href'), - preference: this.media['prefers-map-content'] + src: e.target.getAttribute('data-href') } }) ); diff --git a/test/e2e/data/restaurants/restaurants.mapml b/test/e2e/data/restaurants/restaurants.mapml index 50616d7d8..07e9ab57f 100644 --- a/test/e2e/data/restaurants/restaurants.mapml +++ b/test/e2e/data/restaurants/restaurants.mapml @@ -10,7 +10,7 @@ - + Hung Sum Restaurant @@ -50,7 +50,7 @@ - + Big Daddy's @@ -90,7 +90,7 @@ - + Hareg Cafe & Variety @@ -130,7 +130,7 @@ - + Phucket Royal @@ -170,7 +170,7 @@ - + Sushi 88 @@ -242,7 +242,7 @@ - + Banditos @@ -286,7 +286,7 @@ - + India Palace @@ -338,7 +338,7 @@ - + The Prescott diff --git a/test/e2e/elements/map-layer/map-layer-media.html b/test/e2e/elements/map-layer/map-layer-media.html new file mode 100644 index 000000000..61d4d5989 --- /dev/null +++ b/test/e2e/elements/map-layer/map-layer-media.html @@ -0,0 +1,44 @@ + + + + <map-layer> media attribute test + + + + + + + + + media query: (0 <= map-zoom <=3) + + + + -87 68 + + + + + + + + + + \ No newline at end of file diff --git a/test/e2e/elements/map-layer/map-layer-media.test.js b/test/e2e/elements/map-layer/map-layer-media.test.js new file mode 100644 index 000000000..29b785db5 --- /dev/null +++ b/test/e2e/elements/map-layer/map-layer-media.test.js @@ -0,0 +1,90 @@ +import { test, expect, chromium } from '@playwright/test'; + +test.describe('map-layer media attribute', () => { + let page; + let context; + let viewer; + test.beforeAll(async function () { + context = await chromium.launchPersistentContext(''); + page = + context.pages().find((page) => page.url() === 'about:blank') || + (await context.newPage()); + await page.goto('map-layer-media.html'); + await page.waitForTimeout(1000); + viewer = page.getByTestId('viewer'); + }); + test('On initial load, a matching media queried layer is enabled', async () => { + const matchedQueryLayer = page.getByTestId('initial-mq'); + // map loads at z=2, query matches 0 <= z <= 3 + await expect(matchedQueryLayer).not.toHaveAttribute('disabled', ''); + }); + test(`A visible (enabled) map-layer with no media query should remain enabled \ +when a matching mq is added`, async () => { + const noInitialQueryLayer = page.getByTestId('no-initial-mq'); + await expect(noInitialQueryLayer).not.toHaveAttribute('disabled', ''); + await viewer.evaluate((v) => v.zoomTo(v.lat, v.lon, 4)); + await page.waitForTimeout(200); + // should still be enabled: + await expect(noInitialQueryLayer).not.toHaveAttribute('disabled', ''); + }); + test(`A visible (enabled) map-layer with no media query should be disabled \ +when a non-matching media query attribute is set`, async () => { + await expect(viewer).toHaveAttribute('zoom', '4'); + const presentInLayerControl = await viewer.evaluate((v) => { + let lc = v._layerControl; + let layers = lc._layers.map((e) => e.layer._layerEl); + let noInitialQueryLayer = v.querySelector('[data-testid=no-initial-mq]'); + return layers.some((e) => e === noInitialQueryLayer); + }); + expect(presentInLayerControl).toBe(true); + const noInitialQueryLayer = page.getByTestId('no-initial-mq'); + await expect(noInitialQueryLayer).not.toHaveAttribute('disabled', ''); + await noInitialQueryLayer.evaluate( + (l) => (l.media = '(0 <= map-zoom <=3)') + ); + await expect(noInitialQueryLayer).toHaveAttribute('disabled', ''); + }); + test(`A mq-disabled layer is removed from the layer control`, async () => { + const noInitialQueryLayer = page.getByTestId('no-initial-mq'); + await expect(noInitialQueryLayer).toHaveAttribute( + 'media', + '(0 <= map-zoom <=3)' + ); + await expect(noInitialQueryLayer).toHaveAttribute('disabled', ''); + const presentInLayerControl = await viewer.evaluate((v) => { + let lc = v._layerControl; + let layers = lc._layers.map((e) => e.layer._layerEl); + let noInitialQueryLayer = v.querySelector('[data-testid=no-initial-mq]'); + return layers.some((e) => e === noInitialQueryLayer); + }); + expect(presentInLayerControl).toBe(false); + }); + test(`A layer disabled due to mq would otherwise be enabled is \ +enabled and added to the layer control when mq removed`, async () => { + const noInitialQueryLayer = page.getByTestId('no-initial-mq'); + await expect(noInitialQueryLayer).toHaveAttribute( + 'media', + '(0 <= map-zoom <=3)' + ); + await expect(noInitialQueryLayer).toHaveAttribute('disabled', ''); + await noInitialQueryLayer.evaluate((l) => l.removeAttribute('media')); + await expect(noInitialQueryLayer).not.toHaveAttribute('disabled', ''); + const presentInLayerControl = await viewer.evaluate((v) => { + let lc = v._layerControl; + let layers = lc._layers.map((e) => e.layer._layerEl); + let noInitialQueryLayer = v.querySelector('[data-testid=no-initial-mq]'); + return layers.some((e) => e === noInitialQueryLayer); + }); + expect(presentInLayerControl).toBe(true); + }); + test(`An empty media query is the same as no media query`, async () => { + const noInitialQueryLayer = page.getByTestId('no-initial-mq'); + await noInitialQueryLayer.evaluate((l) => l.setAttribute('media', ' ')); + await expect(noInitialQueryLayer).not.toHaveAttribute('disabled', ''); + }); + test(`An invalid media query is the same as a non-matching media query`, async () => { + const noInitialQueryLayer = page.getByTestId('no-initial-mq'); + await noInitialQueryLayer.evaluate((l) => l.setAttribute('media', '(foo ')); + await expect(noInitialQueryLayer).toHaveAttribute('disabled', ''); + }); +}); diff --git a/test/e2e/elements/map-link/map-link-disabled.test.js b/test/e2e/elements/map-link/map-link-disabled.test.js index a577fdbd7..5799c1c6d 100644 --- a/test/e2e/elements/map-link/map-link-disabled.test.js +++ b/test/e2e/elements/map-link/map-link-disabled.test.js @@ -15,10 +15,6 @@ test.describe('map-link disabled', () => { }); test('rel=stylesheet disabled attribute', async () => { const viewer = page.getByTestId('viewer'); - // there's a problem when attempting to select this link by testid. The map-link - // code copies all the attributes of the map-link element onto the generated - // element it uses to render the content, including the data-testid, - // resulting in duplicate ids that mess up the getByTestId algorithm. const featuresLink = page.getByTestId('restaurants_templated_link'); // test that a templated content link can be disabled by the HTML author at // page load, and the bounds of the extent do not include the disabled link @@ -29,6 +25,11 @@ test.describe('map-link disabled', () => { maxDiffPixels: 20 }); await featuresLink.evaluate((fl) => (fl.disabled = false)); + // there's a problem when attempting to select this link by testid. The map-link + // code copies all the attributes of the map-link element onto the generated + // element it uses to render the content, including the data-testid, + // resulting in duplicate ids that mess up the getByTestId algorithm. + // // selecting it this way seems unambiguous at least const stylesheetLink = page.locator( 'map-link[rel=stylesheet][href="restaurants/restaurants.css"]' diff --git a/test/e2e/elements/map-link/map-link-media.html b/test/e2e/elements/map-link/map-link-media.html index 7f1b4919e..21dd8dd79 100644 --- a/test/e2e/elements/map-link/map-link-media.html +++ b/test/e2e/elements/map-link/map-link-media.html @@ -104,7 +104,7 @@ - + @@ -117,7 +117,7 @@ Italian Mexican - + diff --git a/test/e2e/elements/map-link/map-link-media.test.js b/test/e2e/elements/map-link/map-link-media.test.js index ec6ed6be1..e6e9b6ee8 100644 --- a/test/e2e/elements/map-link/map-link-media.test.js +++ b/test/e2e/elements/map-link/map-link-media.test.js @@ -1,3 +1,7 @@ +/* to do: test that map-link rel=features is re-enabled when the media attribute + * is removed + */ + import { test, expect, chromium } from '@playwright/test'; test.describe('map-link media attribute', () => { @@ -98,4 +102,16 @@ test.describe('map-link media attribute', () => { await expect(layer).not.toHaveAttribute('disabled'); await expect(mapLink).not.toHaveAttribute('disabled'); }); + test('map-link rel=features is enabled when non-matching media attribute removed', async () => { + const viewer = page.getByTestId('viewer'); + const featuresLink = page.getByTestId('features-link'); + await featuresLink.evaluate((l) => (l.media = '(16 < map-zoom <= 18)')); + await expect(featuresLink).toHaveAttribute('disabled'); + await featuresLink.evaluate((l) => l.removeAttribute('media')); + await expect(featuresLink).not.toHaveAttribute('disabled'); + await page.waitForTimeout(500); + await expect(viewer).toHaveScreenshot('default_styled_markers.png', { + maxDiffPixels: 100 + }); + }); }); diff --git a/test/e2e/elements/map-link/map-link-media.test.js-snapshots/default-styled-markers-linux.png b/test/e2e/elements/map-link/map-link-media.test.js-snapshots/default-styled-markers-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..306346c49008c804170312b3ae687617d21fae09 GIT binary patch literal 9793 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 W0|G9dk$jcU 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 + + + + + map-link-stylesheet-media.html + + + + + + + + + + + + + All cuisines + African + Asian + Cajun + Indian + Italian + Mexican + + + + + + + diff --git a/test/e2e/elements/map-link/map-link-stylesheet-media.test.js b/test/e2e/elements/map-link/map-link-stylesheet-media.test.js new file mode 100644 index 000000000..9652b4360 --- /dev/null +++ b/test/e2e/elements/map-link/map-link-stylesheet-media.test.js @@ -0,0 +1,69 @@ +import { test, expect, chromium } from '@playwright/test'; + +test.describe('map-layer rel=stylesheet media attribute', () => { + let page; + let context; + let viewer; + let stylesheetLink; + test.beforeAll(async function () { + context = await chromium.launchPersistentContext(''); + page = + context.pages().find((page) => page.url() === 'about:blank') || + (await context.newPage()); + await page.goto('map-link-stylesheet-media.html'); + await page.waitForTimeout(1000); + viewer = page.getByTestId('viewer'); + stylesheetLink = page.locator('map-link[rel=stylesheet][href="red.css"]'); + }); + test(`when a map-link disables due to a media query, the styles\ + should be removed`, async () => { + // map starts off at + await expect(viewer).toHaveScreenshot('red_styled_markers.png', { + maxDiffPixels: 20 + }); + await stylesheetLink.evaluate((l) => (l.media = '(14 < map-zoom <= 18)')); + await page.waitForTimeout(500); + await expect(viewer).toHaveScreenshot('default_styled_markers.png', { + maxDiffPixels: 20 + }); + }); + test(`when a map-link enables due to a mq being removed, the \ + styles should apply`, async () => { + await stylesheetLink.evaluate((l) => l.removeAttribute('media')); + await expect(viewer).toHaveScreenshot('red_styled_markers.png', { + maxDiffPixels: 20 + }); + }); + + test(`when a map-link enables due to disabled attribute removed\ + ensure styles change`, async () => { + await stylesheetLink.evaluate((l) => (l.disabled = true)); + await page.waitForTimeout(500); + await expect(viewer).toHaveScreenshot('default_styled_markers.png', { + maxDiffPixels: 20 + }); + await stylesheetLink.evaluate((l) => (l.disabled = false)); + await page.waitForTimeout(500); + await expect(viewer).toHaveScreenshot('red_styled_markers.png', { + maxDiffPixels: 20 + }); + }); + test(`when a map-link does not enable due to disabled attribute \ +removed while a non-matching media query is present, ensure that style does not \ +change`, async () => { + await stylesheetLink.evaluate((l) => (l.disabled = true)); + await page.waitForTimeout(500); + await expect(viewer).toHaveScreenshot('default_styled_markers.png', { + maxDiffPixels: 20 + }); + // non-matching query (map z=14) + await stylesheetLink.evaluate((l) => (l.media = '(14 < map-zoom <= 18)')); + await page.waitForTimeout(500); + // disabled overrides the media query because they compete to change it + await stylesheetLink.evaluate((l) => (l.disabled = false)); + await page.waitForTimeout(500); + await expect(viewer).toHaveScreenshot('red_styled_markers.png', { + maxDiffPixels: 20 + }); + }); +}); diff --git a/test/e2e/elements/map-link/map-link-stylesheet-media.test.js-snapshots/default-styled-markers-linux.png b/test/e2e/elements/map-link/map-link-stylesheet-media.test.js-snapshots/default-styled-markers-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..3f7a30a23c11f27780c8a81dbded13de747dad62 GIT binary patch literal 8513 zcmeHtXH-+)mv(?4O{yYDs8J9^0TDq2q)QP2Dbj?9RHX?>uLguD0zU+#H)$5SO0NPU z2q98J3q^WINGPGsiTIy)=AAX~r}xXOHFqsm?%COA?|shM_qosB;f1cY8a*usEd&Cg z*HBl{gFwi3NPpDiKq91RF9<%!-1XFyAVp}-1qg%}qM@Q_;GMcM>fp%PKial_#X{93UYg1&q`dtgwRwjrG(uq|Li5o=uO|Jw zcY6FHg-~Wb8Vm}P_t;twsga(;dZ+Zgs-{>}gv+|k)$WL@L5t!68JVf1p(B5J(dG5k zq;*Bw2I-r7@^&nKTg%LlV7;!cEFMRZN$UvwmYVd9I1v;&T^+Ha~LmRc3GT%6XiVQrNmujDDsh}$VK6IVs^MB z*J#=G#8{>Dg(Px{dsZT31 z^81EQKdZx*Ub$UAR~kn2#IE6lGfs9{F+M9{BIrKc=3C$?jk>Kt)bLz7WcJx8Svw&A zs@6|0F~5*7puP7b?cl=9$kO!2ZU4&CFCVxnH&XlBm&~Eq`6YzEme{#&amJWC1#Z$2 zjd4u0dCt1)-`qDAg^Jl+ZT%S1U#GUEoS>DK;+08{4@U^y>m2@hnX&%TxQ~S|v82Ta zDtB>gom)7$j&V`d`qG6oxq1R!EU+Vjw)5cdP z7vMf?6)pGm{23_~GR5eZQYQPWMFnmrWDxK2w&@~ZaAc-h>ykUNF`qerr+xAiP=f-s zxoNkrBd9Uy8ka$bgo(Auup|G)W{=5NK-p}1TcDZlV?g}_Sz=kG;&LnfZ<39g?EV{K zwKFf>J^dWk!xCY@^m8C~aEZ?``SGi*@6HVk%wBLSeT)(&d-8I@o0K$F{LJi2_pv)a zlB(Cq{-}qaFe|Qz?%?W^nY&{_%Ux2*r$^epGDQwHvo;%O#MP>XT8n!UJ42;|V3|3j z^BCb+%6#>}RbYGV;q^6A^t9jzB`ehLd^>EqQ+eIVLA(b$>DTb^02$f~p&i0?9MrVISM(QDC zc+y@99eXiMom8(NDjDWB9BUew3`j_eWw`6E)glnWOUbhpR##dk!{&MCvozlpuxNa^ zI7blydmEA&E}7fSaP>%L9L!^e%6%4c^-Ls=L%?d`)V_iS9m`_)1~QO3Dqwx~=poD5 zAd2S6FhO8PfBip=V*ZT2O@?8Z37GeTqf^R#>@@` z&w;?hWJsdUxV}(zu`Fxz0vZ@OgXG?wxw8W%ojKMC6oySF^JCY)+)g~AKNSH}QpB7) zQ$F&kd1N3A7n=xT64bNwf>3|WJ9CyZ-tm_6Bay6Yv%T1*nfbl1lVQBf1Qgw4Y53Rs zxZgj6H?u8urb;R;55+tvc zC03I`W~hB3x>1=_|9kWQYZF9RJ*jlp!`h~&O#pBOD8u0qk8|qp-IGw4pqL21 zr{iNcHfW@`6n}XQT#6qliZx3PS!E5Dh01lfIxBdtq+FZ4!!_FT^YWhd_j45;HrJXq z=@qzV=YN^1RXFecNd)TWh?kbJxIs61SU`;D5E-;y9Cf!a6DRB0;W zU%xVsIo_S7d~uGNaShQ)_)Y zMuli(#!rpiBA|x?n$wFY8d;GyJ)^db`y)ke&80gC<1ZC#5s{FWyz^FbiQ(6ZxD)P3 z+f`KfRx?11sCNgYdmVVHbes@*&OI7PZt%Y3k%?s$b=DgZd@>z%jOAqHs+cykb?a@P z81vQ4F=>~jO&bd`1s^cm6*<-~+u2ucgX2wYKbYApd)stCgvbJ4c6Y0~51wq)y}DB8 zu3r`LOP1+6h-FVY2(bT2Sh3)EQ5j6s6KVUyJwm zK9j(_`Y;zF3kTLLzu<6=N4mhhAzH>OuEwZl&jaEQHtVPLXhecy-H((O5}GgV4v_th z%8bsAr|+p8ydmOO_;DnO=fg$PtNzLtr$~lN&csZ(60hB{^08oQL(^U}sm{_J#!E}RyW@6i$R-XGSGGx?G6G=+ z{s-bc+?2CDmditDZ`i>?hSpddohiT@m&ZXHT5~yzm;sx6H$s|ygL>E4Y(Ts%>N1Io4zgJmDCZ^t7x8;Q~)nPSEF65ln=i|>!Rl%?gWYjd2>}0x10BXrpwVo zhGd#nG5U3Ry^yhzeywwOms2o`cmB#YR!UXV{$<~at|1NZ&6woAlmh3MSW3yG9~lBx zc#+(brJ;EbMi~s_6`nE?n4&>?zR*A7P27bCKVc@6#F;DUC&b_BRoivCte21$E-|sZBArAg91b^wnHS#WQcd*QfXAN`BxC_XC^}8bZ)3^jd{hVfEC$I28AT> z8sNS7-(d&RV_{s?+3=a?5v78R@?ulX-$)B3S$i{Vto#%;B81w^pj2lJa>=?R)1{ zSYmZ7E=yhlaj3 zvyt!dLpDMUqs9@+V|n%2;9t@yTRpU0q)NvxAxJ^V@bh%B^lo~f&&p@UfuSJ1L;QQj z0WyiKM!vF1R)SyDX&++?jgxyz>E{lg(qNvEhYLpB#YE3d_v>4TPIhi_%JNG`OVKOP z8BsFOxC=Y(1!erD!xDK9PZQew3hcLRbmiZ~qPY>flm?PIlnij&XU!Ls@q@}Og7eYD zYmZBgJjCm$cZ?^3iKntN%-#&2G$s1I-IZl24@;6PxOFezyrI zJX2Oh-NkH6S1tFV>Z3E&YVS_y3Qe*TuJU9|0}eS}G9W_68c80m$()^unBL~7ecpc) z!SwFZ>FWkB*(ndW3b9R{7Z5d*siR}2wS1YJlnn9kTZ-dj7d70u!g=(i7S1b1R|3y^ zz%$#uA6@7$pBV;)RJ^k(x{rP`>ez6`R!NQ<6))OH){7>Sq$@mcB&k02aH;YYABsda z)8|CUfX7$flyxXaGb^sRD^S<4%gg-?x)ZvJ;9yeBas;f7CT0=&z2ySuoG#aI)4h`= zg*ZqVa6_n~xGaj^=;+2ujthc+A?JvT;vxenPESR7kI7bmOjd7djP}O)GnK&NnZe?X zuFHWgaIk?%g_ zAiOBM#dPvUaFXB?RDI%!x{n=Vj~jv~!KiZQM8J!9%f3J|_qUCFlanw4|Glugdz5iV zQc`$ex=qgBT4B?L({jGOgjJNcvtj>&Pj7tBEr2dYMzpDTv z0c2p*AAdb}Cz$TMFOgxQF)L2UUc22?rFw!ZSa<~ceTpilmOT8|6=|P)XnJEtq5B5s zHoug;RV-T|F1wy&BEaEGDS$!T%wsmvQhZnS#9u&ob~q=ffYIsL!^KBi zJ}YA#+WqGL@eeZ8Jsj+!4GI)~EoS#@+3(vF)pX&i&tj!E^dKjm-mQyeX=j)pta!$3 zT%u4!+QmJEL`&AD&2k+>Z0YeUbSt136+Rh7R}&jB+VovnjmvSd?V37s>MDqMcQS z->g-)`71IccjJDtshu<^Px)u^aTng@iBjrIL6E(3(`9WMzI!)+s$mj>GpU$3FC@(Q z7dg6;_=`o&X)35(@WiDL>qMliNBL>e0Qd7TS0}E&hjngw3p+{A2V@FgDl~g=?|P!& zr#yX~DM|xMh3j-5XKd}xy?3M9MEgixwp+|QPg1aoRjJ3`w%=I?YBB@?ZiyJXA zX$$*!w=Rva^6`8cp~1?O8Pp^bTD6rOK6YcXq;gZ^3X)rax~L!)#!+Zh5s~lgn7TFX z+W7()X2`$Zvob04;o>MT7iwkRJKgAyR;)WFB+27Z3(6P@YPI7E^M?Yszq4RAUQ!jw z2G)a#t0YkmZxtZc7y2Vs17fkRsy|{iAU0VqbQ#2blL7v}zjO=$yrP~L_$e5~N;x`D zQ33Ie?Z|FemlL2*6x4`g?Q=kU{`Amp*ayvMP*TN|)IS<7Ndr2-5$Yw9GS0xz7Z^v; z=5N_9=9lRsRD6Ki-Mb{x5HT}inj-=;4eA4aRMf}jiu_M5(E)>@1&;qXyfJPY5CH@z z2qe#2o0_`KuB|V8+bWTy&QkCr$uFRxV|^9$jA#n)l7l(Zx_S$udCrjk0qrtUbF5L8 zgF80XZUz@jpnrk7^dV-~)Z{1c(9=OV3MO8pMZS@C$BzrsgH+GQ%|979*JwLGVyHHP zC@Eqb-2dB3NiZ?nDEAn@X6Tul4{h0dIe19$)#Z8{k_k~PZi`5BJ8~D76@cH%gTZNH zLXF2+Xp+txz(cajrc8VmM*s0+AXQYFPoMrcMOA2}T%e_M`thS%4KXEU7AoBGye=M8 zSbd1%x%q4JT(7CNOxwO)BBr--%#N5exEK42OGL{-nczr^kkRm*pq3jV{4*DZ3is5e z+nd4bP~kiifwedvVIi~9?6H**_ot5pQK45vtZ#8LXNTIVvTqH@sqHVY1grDS3y*kf zTgc69!qJZ1P5Q6#-n|eeIcR{5%zr?ZogPsLvl7Or+$u0$by$iPt3$TSM2KI}Dh`-- zRd>-D2c?l!G(?3#5iukXF+Lh^h<-2*@Pvv0?3-o8{z=f23A!AUBqikhUe(WskwlKRr@atCtdWV&_gSQtuXR;vLG5#Ppj%~?lH?? z6jTATp7*+G z#K%;xS*KNtm7s(_R$Km78=mWZf16i-OmJ(v=8UxJ8yJ#TGZTCZ9FjQ`yQSZGjTINi zd)&c~T!H+8&u^;78NxLT`7^l{i#7iM3Oy4KwC*CmGYKLT3YZAPf6JOuC5*$>ITBh> zw9qRS>;6HA6DSzcA`4DJ9C{{YXq{4Pc|EDD38eN-JBE{BcKE!<#ri*$5is%5(0U05 zN-1N$`F_)J38z6c@Z!i!NM^m1ne%~#WbW#}zy!)f1+BCFPn{?#1wm@xnT?xXGgijD zVc_jFns3SG*J>8mb4lwxRWC=$K?y{M=P#X|Z(ZT{@FCNKJb zyF~w2hb(wr{A9D($!InWV&7Rvu#s(^&cO{sc+B@bQ#kmE;;UWf*GK;(stU1Pm?z`a z(#}KFdaqBmMub_OXL<4A!v|~eN8BhB(bpmb3|OYpGpT|x*O@bZ%!pXjCTa<=T{0H? zlyr8x-MVMr)zQ)M;lr=BXA@mmyM0Nvf1T`cuS!K37#ZnwEj8@Vh?<+5+jXb2#)O51 z<=##RT)2%8AMdah53_s~6{W4Em1yD;wQ9Gg3YCL|HlF>SVufE^e2m}R9`jpklRsRK z5Un2^AJ6dW$W5^DolEmt#Z}=yd@RyD&(h!Df9~A5si~>=1|6K6-ETJIjK~!*d3pX9 z2L7JCh6$Ook}%R!(WoKNT6s_u& zqPgXUM@D4C#4uQ_EqaVS?APgml*^*`D;vR2W5}yt9*-3y$h%Iq;Jf8T;VDusf%946 z8^aBFvG^kJ)PT57x5&IlztP5iY^Rws?+)M z2k%jReSL{M3Dp}Z!^0}mh@;(s@uNd8_h{%X0)$Dx?nvByY!*l=h`S#Q zKhl=3fo<~N`TeUooUSN?B}UZ$7u{?V*v+}lF|oH)!D4r~er|7VC5wufet!303XRsr zHxHuGXe2!c4AvF0Jsy++4mb3Yi@T4VjwW+bVxr($GMcs1>8I_U2Y5`NU7a>_6oZWN z`z5tYiO=KVZmq0Fr(gM;Q&FkkEObdyeG?KAGHXR?7d1ar#{xmxvVVI{ z$5uAv2#+yt2n4x!w0C%TD1We^6K3g%tNi)sp1FA)c&==Iyty-4t*25C@>QNV9Sbk> zCvLD=cw06hDcM9VIN901TZ{Xc^?dT`MqHZQ>CHr9zo|3XAK7TX|H28^upA;`yL)10eF*EQd3|yS^&4VL0p7~cuz!AjUX3Rpu3b|i@D}*TfHl(p0$4wGaOmPl@mRvL z%5HysPDepOVP$2Nq$QBjm25>s3ax>xId#vng;P9gutWo&Fi7?n#=t;z^w?Eh-`jFb)n5PEH9ac`+E+ zA<~}hI|rsYJvZP6nXNSCsI_K&&?=N_rz$NKB8#4tZVdu`REVW`?6BC$s~wRG8_8V; z9mS-0{Izj1euijVY0s<8_lVn|&QdVwJn3q;`0a;{KD-CCyRoL^5W@S%&ZLW>1_lWx aZXEFzWo(xPHz2{%AsVXMDn&{UkpBi@;S4JP literal 0 HcmV?d00001 diff --git a/test/e2e/elements/map-link/map-link-stylesheet-media.test.js-snapshots/default-styled-markers-win32.png b/test/e2e/elements/map-link/map-link-stylesheet-media.test.js-snapshots/default-styled-markers-win32.png new file mode 100644 index 0000000000000000000000000000000000000000..3f7a30a23c11f27780c8a81dbded13de747dad62 GIT binary patch literal 8513 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 aZXEFzWo(xPHz2{%AsVXMDn&{UkpBi@;S4JP literal 0 HcmV?d00001 diff --git a/test/e2e/elements/map-link/map-link-stylesheet-media.test.js-snapshots/red-styled-markers-linux.png b/test/e2e/elements/map-link/map-link-stylesheet-media.test.js-snapshots/red-styled-markers-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..80bf5288ac5025d633fda9e7357b89ee4bdc0154 GIT binary patch literal 7688 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