From 0ed3cfd6242ca080ff954cfaf39d4f468ab15061 Mon Sep 17 00:00:00 2001 From: Ana Lameira Date: Thu, 2 Jan 2025 17:58:47 +0000 Subject: [PATCH 1/3] Fix change options attribute handling --- src/l-tile-layer-wms.js | 39 +++++++----------- src/l-tile-layer-wms.test.js | 76 ------------------------------------ 2 files changed, 15 insertions(+), 100 deletions(-) diff --git a/src/l-tile-layer-wms.js b/src/l-tile-layer-wms.js index ebc7e6e..f90e2bd 100644 --- a/src/l-tile-layer-wms.js +++ b/src/l-tile-layer-wms.js @@ -20,10 +20,8 @@ class LTileLayerWMS extends LLayer { } attributeChangedCallback(name, oldValue, newValue) { - if (name === "options" && oldValue !== newValue) { - if (this.isConnected) { - this.reloadLayer(); - } + if (name === "options" && oldValue !== newValue && this.layer) { + this.layer.setParams(this._parseNonStandardOptions(newValue)); } } @@ -47,21 +45,6 @@ class LTileLayerWMS extends LLayer { const standardOptions = parse(schema, this); const nonStandardOptionsElement = this.getAttribute("options"); - const nonStandardOptions = () => { - if (nonStandardOptionsElement) { - try { - return JSON.parse(nonStandardOptionsElement); - } catch (e) { - console.error( - "Error whilst parsing JSON for options attribute in l-tile-layer-wms", - e, - ); - return {}; - } - } else { - return {}; - } - }; // Pane options const paneOptions = {}; @@ -75,7 +58,7 @@ class LTileLayerWMS extends LLayer { this.layer = tileLayer.wms(urlTemplate, { ...standardOptions, - ...nonStandardOptions(), + ...this._parseNonStandardOptions(nonStandardOptionsElement), ...paneOptions, ...gridOptions, }); @@ -86,11 +69,19 @@ class LTileLayerWMS extends LLayer { this.dispatchEvent(event); } - reloadLayer() { - if (this.layer) { - this.layer.remove(); + _parseNonStandardOptions(nonStandardOptionsElement) { + if (nonStandardOptionsElement) { + try { + return JSON.parse(nonStandardOptionsElement); + } catch (e) { + console.error( + "Error whilst parsing JSON for options attribute in l-tile-layer-wms", + e, + ); + } } - this.initLayer(); + + return {}; } } diff --git a/src/l-tile-layer-wms.test.js b/src/l-tile-layer-wms.test.js index 8bece42..fb1054f 100644 --- a/src/l-tile-layer-wms.test.js +++ b/src/l-tile-layer-wms.test.js @@ -92,82 +92,6 @@ it("should handle invalid JSON in the options attribute gracefully", () => { expect(actual).toEqual(expected); }); -it("should reload the layer when the options attribute changes", async () => { - const urlTemplate = "http://example.com/wms"; - const initialOptions = JSON.stringify({ height: 101, bbox: "coords ere" }); - const updatedOptions = JSON.stringify({ height: 202, bbox: "new coords" }); - - const el = document.createElement("l-tile-layer-wms"); - el.setAttribute("url-template", urlTemplate); - el.setAttribute("layers", "example layer ere"); - el.setAttribute("options", initialOptions); - - let layerConnectedEventEmittedCount = 0; - let promise = new Promise((resolve) => { - el.addEventListener(layerConnected, (ev) => { - layerConnectedEventEmittedCount += 1; - resolve(ev.detail); - }); - }); - - document.body.appendChild(el); - - // Wait for the initial layer to be created - let detail = await promise; - expect(detail.layer.options.height).toBe(101); - expect(detail.layer.options.bbox).toBe("coords ere"); - - // Change the options attribute - promise = new Promise((resolve) => { - el.addEventListener(layerConnected, (ev) => { - resolve(ev.detail); - }); - }); - - // Update the options attribute - el.setAttribute("options", updatedOptions); - - // Wait for the layer to reload - detail = await promise; - expect(detail.layer.options.height).toBe(202); - expect(detail.layer.options.bbox).toBe("new coords"); - expect(layerConnectedEventEmittedCount).toBe(2); // initial layer creation + reload -}); - -it("should not reload the layer when non-options attributes are changed", async () => { - const urlTemplate = "http://example.com/wms"; - const initialOptions = JSON.stringify({ height: 101, bbox: "coords ere" }); - - const el = document.createElement("l-tile-layer-wms"); - el.setAttribute("url-template", urlTemplate); - el.setAttribute("layers", "example layer ere"); - el.setAttribute("options", initialOptions); - - let layerConnectedEventEmittedCount = 0; - let promise = new Promise((resolve) => { - el.addEventListener(layerConnected, (ev) => { - layerConnectedEventEmittedCount += 1; - resolve(ev.detail); - }); - }); - - document.body.appendChild(el); - - // Wait for the initial layer to be created - let detail = await promise; - expect(detail.layer.options.height).toBe(101); - expect(detail.layer.options.bbox).toBe("coords ere"); - - // Update the a different attribute to options - el.setAttribute("a-different-attribute", "with different value"); - - // Give the layer a chance to reload - detail = await promise; - expect(detail.layer.options.height).toBe(101); - expect(detail.layer.options.bbox).toBe("coords ere"); - expect(layerConnectedEventEmittedCount).toBe(1); // initial layer creation only -}); - it.each([ ["512", 512], ["[256, 512]", point({ x: 256, y: 512 })], From 215c1b4481211a7aeee37d3ea712f58db4a0f36e Mon Sep 17 00:00:00 2001 From: Ana Lameira Date: Fri, 3 Jan 2025 11:20:24 +0000 Subject: [PATCH 2/3] Add support for standard attribute changes as well (grid options not included) --- src/l-tile-layer-wms.js | 31 +++++++++++++++++++------------ src/l-tile-layer-wms.test.js | 22 +++++++++++++++++++++- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/l-tile-layer-wms.js b/src/l-tile-layer-wms.js index f90e2bd..d93cda5 100644 --- a/src/l-tile-layer-wms.js +++ b/src/l-tile-layer-wms.js @@ -7,7 +7,7 @@ import { gridLayerOptions } from "./grid-layer.js"; class LTileLayerWMS extends LLayer { static get observedAttributes() { - return ["options"]; + return ["options", "layers", "styles", "format", "transparent", "version", "crs", "uppercase"]; } constructor() { @@ -20,8 +20,15 @@ class LTileLayerWMS extends LLayer { } attributeChangedCallback(name, oldValue, newValue) { - if (name === "options" && oldValue !== newValue && this.layer) { - this.layer.setParams(this._parseNonStandardOptions(newValue)); + if (this.layer && oldValue !== newValue) { + switch (name) { + case "options": + this.layer.setParams(this._parseNonStandardOptions(newValue)); + break; + default: + this.layer.setParams({ [name]: newValue }); + break; + } } } @@ -40,11 +47,11 @@ class LTileLayerWMS extends LLayer { uppercase: optional(htmlAttribute("uppercase")), // Inherited option from Layer: https://leafletjs.com/reference.html#tilelayer-wms-attribution - attribution: optional(htmlAttribute("attribution")), + attribution: optional(htmlAttribute("attribution")) }); const standardOptions = parse(schema, this); - const nonStandardOptionsElement = this.getAttribute("options"); + const nonStandardOptions = this.getAttribute("options"); // Pane options const paneOptions = {}; @@ -58,25 +65,25 @@ class LTileLayerWMS extends LLayer { this.layer = tileLayer.wms(urlTemplate, { ...standardOptions, - ...this._parseNonStandardOptions(nonStandardOptionsElement), + ...this._parseNonStandardOptions(nonStandardOptions), ...paneOptions, - ...gridOptions, + ...gridOptions }); const event = new CustomEvent(layerConnected, { detail: { name, layer: this.layer }, - bubbles: true, + bubbles: true }); this.dispatchEvent(event); } - _parseNonStandardOptions(nonStandardOptionsElement) { - if (nonStandardOptionsElement) { + _parseNonStandardOptions(nonStandardOptions) { + if (nonStandardOptions) { try { - return JSON.parse(nonStandardOptionsElement); + return JSON.parse(nonStandardOptions); } catch (e) { console.error( "Error whilst parsing JSON for options attribute in l-tile-layer-wms", - e, + e ); } } diff --git a/src/l-tile-layer-wms.test.js b/src/l-tile-layer-wms.test.js index fb1054f..f27e5c0 100644 --- a/src/l-tile-layer-wms.test.js +++ b/src/l-tile-layer-wms.test.js @@ -1,8 +1,9 @@ // @vitest-environment happy-dom import { point, tileLayer } from "leaflet"; -import { it, expect } from "vitest"; +import { it, expect, vi } from "vitest"; import { layerConnected } from "./events"; import "./index"; +import { waitFor } from "@storybook/test"; it("should create an l-tile-layer-wms with the correct options", async () => { const urlTemplate = "http://ows.mundialis.de/services/service?"; @@ -108,3 +109,22 @@ it.each([ const expected = tileLayer.wms(baseUrl, { layers, tileSize }); expect(actual).toEqual(expected); }); + +it.each([ + ["options", '{"banana": "yo"}', '{"banana": "ok"}', true], + ["transparent", "TRUE", "FALSE", false], +])("should update layer params when non-standard or standard attributes change", (attributeName, attributeInitialValue, attributeNewValue, isJson) => { + const baseUrl = "/"; + const layers = "layer-1"; + const el = document.createElement("l-tile-layer-wms"); + el.setAttribute("url-template", baseUrl); + el.setAttribute("layers", layers); + el.setAttribute(attributeName, attributeInitialValue); + + document.body.appendChild(el); + const setParams = vi.spyOn(el.layer, "setParams"); + + el.setAttribute(attributeName, attributeNewValue); + + expect(setParams).toHaveBeenCalledWith(isJson ? JSON.parse(attributeNewValue) : {[attributeName]: attributeNewValue}) +}); From 3e28a69224ee8052afe8e3c3d8f0ab860cc07e03 Mon Sep 17 00:00:00 2001 From: andrewgryan Date: Fri, 3 Jan 2025 12:29:32 +0000 Subject: [PATCH 3/3] Release 0.13.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 763f43d..64d265c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "leaflet-html", "type": "module", - "version": "0.13.7", + "version": "0.13.8", "description": "Leaflet maps expressed in HTML suitable for HTMX", "keywords": [ "leaflet",