diff --git a/src/l-tile-layer-wms.js b/src/l-tile-layer-wms.js index 7baafbb..5cbd327 100644 --- a/src/l-tile-layer-wms.js +++ b/src/l-tile-layer-wms.js @@ -5,12 +5,28 @@ import { layerConnected } from "./events.js"; import { htmlAttribute, optional, parse, partial } from "./parse.js"; class LTileLayerWMS extends LLayer { + static get observedAttributes() { + return ["options"]; + } + constructor() { super(); this.layer = null; } connectedCallback() { + this.initLayer(); + } + + attributeChangedCallback(name, oldValue, newValue) { + if (name === "options" && oldValue !== newValue) { + if (this.isConnected) { + this.reloadLayer(); + } + } + } + + initLayer() { const urlTemplate = parse(htmlAttribute("url-template"), this); const name = this.getAttribute("name"); @@ -47,16 +63,16 @@ class LTileLayerWMS extends LLayer { }; // Pane options - const paneOptions = {} + const paneOptions = {}; // Support parent element if (this.parentElement.tagName.toLowerCase() === "l-pane") { - paneOptions["pane"] = this.parentElement.getAttribute("name") + paneOptions["pane"] = this.parentElement.getAttribute("name"); } this.layer = tileLayer.wms(urlTemplate, { ...standardOptions, ...nonStandardOptions(), - ...paneOptions + ...paneOptions, }); const event = new CustomEvent(layerConnected, { detail: { name, layer: this.layer }, @@ -64,5 +80,13 @@ class LTileLayerWMS extends LLayer { }); this.dispatchEvent(event); } + + reloadLayer() { + if (this.layer) { + this.layer.remove(); + } + this.initLayer(); + } } + export default LTileLayerWMS; diff --git a/src/l-tile-layer-wms.test.js b/src/l-tile-layer-wms.test.js index 001946b..8663534 100644 --- a/src/l-tile-layer-wms.test.js +++ b/src/l-tile-layer-wms.test.js @@ -91,3 +91,79 @@ it("should handle invalid JSON in the options attribute gracefully", () => { const expected = tileLayer.wms(urlTemplate, { layers: "example layer ere" }); 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 +});