From adb079c50a0b1745422f1e0122815159a4999bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Arranz?= Date: Fri, 23 Jul 2021 18:16:15 +0200 Subject: [PATCH 1/4] Allow passing a list of ids to the poiInputCenter endpoint --- src/config.xml | 2 +- src/js/main.js | 6 ++- src/js/ol3-map-widget.js | 33 ++++++++----- tests/js/OpenlayersWidgetSpec.js | 82 ++++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 13 deletions(-) diff --git a/src/config.xml b/src/config.xml index d843abb..5993f4b 100644 --- a/src/config.xml +++ b/src/config.xml @@ -31,7 +31,7 @@ - + diff --git a/src/js/main.js b/src/js/main.js index 353b053..df6c0c6 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -101,7 +101,11 @@ poi_info = [poi_info]; } - poi_info.forEach(widget.registerPoI, widget); + poi_info.forEach((poi) => { + if (poi != null && typeof poi === "object") { + widget.registerPoI(poi) + } + }); widget.centerPoI(poi_info); }); diff --git a/src/js/ol3-map-widget.js b/src/js/ol3-map-widget.js index a2d9ef4..824785d 100644 --- a/src/js/ol3-map-widget.js +++ b/src/js/ol3-map-widget.js @@ -98,8 +98,9 @@ if (this.selected_feature != feature) { this.selected_feature = feature; if (feature == null && this.popover != null) { - this.popover.hide(); + const popover = this.popover; this.popover = null; + popover.hide(); } MashupPlatform.widget.outputs.poiOutput.pushEvent(feature != null ? feature.get('data') : null); } @@ -782,33 +783,35 @@ * @param poi_info */ Widget.prototype.centerPoI = function centerPoI(poi_info) { - if (poi_info.length === 0) { + const geometries = poi_info.map((poi) => { + const feature = this.vector_source.getFeatureById(typeof poi === "string" ? poi : poi.id); + return feature != null ? feature.getGeometry() : null; + }).filter((geometry) => geometry != null); + + if (geometries.length === 0) { // Just empty current selection unselect.call(this, this.selected_feature); return update_selected_feature.call(this, null); } - const geometry = new ol.geom.GeometryCollection(poi_info.map((poi) => { - const feature = this.vector_source.getFeatureById(poi.id); - return feature.getGeometry(); - })); + const geometryset = new ol.geom.GeometryCollection(geometries); // Update map view const zoom = parseInt(MashupPlatform.prefs.get('poiZoom'), 10); const currentZoom = this.map.getView().getZoom(); if (currentZoom < zoom) { - this.map.getView().fit(geometry.getExtent(), { + this.map.getView().fit(geometryset.getExtent(), { maxZoom: zoom }); } else { const view_extent = this.map.getView().calculateExtent(this.map.getSize()); - const geometry_extent = geometry.getExtent(); + const geometry_extent = geometryset.getExtent(); if (!ol.extent.containsExtent(view_extent, geometry_extent)) { const view_size = ol.extent.getSize(view_extent); const geometry_size = ol.extent.getSize(geometry_extent); if (view_size[0] < geometry_size[0] && view_size[1] < geometry_size[1]) { - this.map.getView().fit(geometry.getExtent(), { + this.map.getView().fit(geometryset.getExtent(), { maxZoom: zoom }); } else { @@ -819,7 +822,7 @@ } if (poi_info.length == 1) { - this.select_feature(this.vector_source.getFeatureById(poi_info[0].id)); + this.select_feature(this.vector_source.getFeatureById(typeof poi_info[0] === "string" ? poi_info[0] : poi_info[0].id)); } }; @@ -1253,6 +1256,10 @@ }; Widget.prototype.select_feature = function select_feature(feature) { + if (this.selected_feature === feature) { + // Selection is not changing + return; + } unselect.call(this, this.selected_feature); @@ -1262,7 +1269,7 @@ update_selected_feature.call(this, feature); - if (feature.get('content') != null) { + if (this.popover == null && feature.get('content') != null) { // The feature has content to be used on a popover const popover = this.popover = new StyledElements.Popover({ placement: ['top', 'bottom', 'right', 'left'], @@ -1292,6 +1299,10 @@ update_selected_feature.call(this, feature); this.popover.show(this.refpos); }, 100); + } else if (this.popover != null && feature.get("content") == null) { + const popover = this.popover; + this.popover = null; + popover.hide().hide(); } }; diff --git a/tests/js/OpenlayersWidgetSpec.js b/tests/js/OpenlayersWidgetSpec.js index 837d871..7f56d3c 100644 --- a/tests/js/OpenlayersWidgetSpec.js +++ b/tests/js/OpenlayersWidgetSpec.js @@ -1509,6 +1509,88 @@ expect(widget.map.getView().fit).not.toHaveBeenCalled(); expect(MashupPlatform.widget.outputs.poiOutput.pushEvent).toHaveBeenCalledTimes(1); expect(MashupPlatform.widget.outputs.poiOutput.pushEvent).toHaveBeenCalledWith(poi_info2); + expect(widget.popover).toBe(null); + expect(widget.selected_feature).toBe(feature); + done(); + }); + }, 300); + }); + + it("should manage selection changes (by id)", (done) => { + widget.init(); + spyOn(widget.map.getView(), 'fit').and.callThrough(); + const poi_info1 = deepFreeze({ + id: '1', + infoWindow: "Hello world!", + location: { + type: 'Point', + coordinates: [0, 0] + } + }); + widget.registerPoI(poi_info1); + spyOn(widget.vector_source, 'addFeature').and.callThrough(); + const poi_info2 = deepFreeze({ + id: '2', + data: { + iconHighlighted: { + src: "https://www.example.com/image.png", + opacity: 0.2, + scale: 0.1 + } + }, + location: { + type: 'Point', + coordinates: [0, 0] + } + }); + widget.registerPoI(poi_info2); + const feature = widget.vector_source.addFeature.calls.argsFor(0)[0]; + spyOn(widget.map, 'getPixelFromCoordinate').and.returnValue([0, 0]); + widget.centerPoI(["1"]); + widget.map.getView().fit.calls.reset(); + MashupPlatform.widget.outputs.poiOutput.pushEvent.calls.reset(); + + setTimeout(() => { + expect(widget.popover).not.toBe(null); + widget.centerPoI(['2']); + + setTimeout(() => { + expect(widget.map.getView().fit).not.toHaveBeenCalled(); + expect(MashupPlatform.widget.outputs.poiOutput.pushEvent).toHaveBeenCalledTimes(1); + expect(MashupPlatform.widget.outputs.poiOutput.pushEvent).toHaveBeenCalledWith(poi_info2); + expect(widget.popover).toBe(null); + expect(widget.selected_feature).toBe(feature); + done(); + }); + }, 300); + }); + + it("should mantain selection (by id)", (done) => { + widget.init(); + spyOn(widget.map.getView(), 'fit').and.callThrough(); + spyOn(widget.vector_source, 'addFeature').and.callThrough(); + const poi_info1 = deepFreeze({ + id: '1', + infoWindow: "Hello world!", + location: { + type: 'Point', + coordinates: [0, 0] + } + }); + widget.registerPoI(poi_info1); + const feature = widget.vector_source.addFeature.calls.argsFor(0)[0]; + spyOn(widget.map, 'getPixelFromCoordinate').and.returnValue([0, 0]); + widget.centerPoI(["1"]); + widget.map.getView().fit.calls.reset(); + MashupPlatform.widget.outputs.poiOutput.pushEvent.calls.reset(); + + setTimeout(() => { + expect(widget.popover).not.toBe(null); + widget.centerPoI(["1"]); + + setTimeout(() => { + expect(widget.map.getView().fit).not.toHaveBeenCalled(); + expect(MashupPlatform.widget.outputs.poiOutput.pushEvent).not.toHaveBeenCalled(); expect(widget.popover).not.toBe(null); expect(widget.selected_feature).toBe(feature); done(); From 482ad93a5a06b4395055ac84cfd079edaf6d241e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Arranz?= Date: Mon, 26 Jul 2021 03:51:57 +0200 Subject: [PATCH 2/4] Updated documentation --- src/doc/changelog.md | 1 + src/doc/userguide.md | 49 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/doc/changelog.md b/src/doc/changelog.md index 0916cd3..1d6dcf4 100644 --- a/src/doc/changelog.md +++ b/src/doc/changelog.md @@ -8,6 +8,7 @@ - Fix placement of popovers when icon anchor is different to `[0.5, 1]` - Switch code to use let and const - Update popover contents when the selected PoI is updated +- Allow to pass a list of feature ids to the `poiInputCenter` endpoint ## v1.2.3 (2021-03-25) diff --git a/src/doc/userguide.md b/src/doc/userguide.md index 574df14..13e0faf 100644 --- a/src/doc/userguide.md +++ b/src/doc/userguide.md @@ -68,13 +68,13 @@ Map viewer widget using OpenLayers. It can receive Layers or Point of Interest d - `anchor`: Anchor position. Default value is `[0.5, 0.5]` (icon center). - `anchorXUnits`: Units in which the anchor x value is specified. A - value of `'fraction'` indicates the x value is a fraction of the - icon. A value of `'pixels'` indicates the x value in pixels. Default - is `'fraction'`. + value of `"fraction"` indicates the x value is a fraction of the + icon. A value of `"pixels"` indicates the x value in pixels. Default + is `"fraction"`. - `anchorYUnits`: Units in which the anchor y value is specified. A - value of `'fraction'` indicates the y value is a fraction of the - icon. A value of `'pixels'` indicates the y value in pixels. Default - is `'fraction'`. + value of `"fraction"` indicates the y value is a fraction of the + icon. A value of `"pixels"` indicates the y value in pixels. Default + is `"fraction"`. - `opacity`: Opacity of the icon (range from 0 to 1). Default is `1`. - `scale`: Scale. Default is `1`. - `src`: Image source URI. @@ -117,9 +117,40 @@ Map viewer widget using OpenLayers. It can receive Layers or Point of Interest d - `subtitle`: subtitle associated to the PoI - `title`: title associated to the PoI - `tooltip`: text to be displayed as tooltip when the mouse is over the PoI. -- **Insert/Update Centered PoI**: Insert or update a PoI and change the viewport - centering the map on it. Uses the same format used by the **Insert/Update PoI** - endpoint. +- **Center PoI**: Updates the viewport to make visible the provided list of + PoIs. If the viewport is already displaying the provide list of PoIs, the + viewport is not modified. This endpoint can also be used to update or to insert + new PoIs by providing PoI information using the same format used in the + **Insert/Update PoI** endpoint. + + Examples: + + - `null`: Clears current selection. + - `["vehicle-1", "vehicle-2"]`: Ensures `vehicle-1` and `vehicle-2` are + visible. + - ```json + [{ + "id": "vehicle-1", + "location": { + "type": "Point", + "coordinates": [ + -8.51, + 41.11 + ] + }, + "infoWindow": "test1", + "icon": { + "fontawesome": { + "glyph": "fa-motorcycle" + } + } + }] + ``` + + Updates `vehicle-1` and makes it visible on the map. If `vehicle-1` is + not the current selecte PoI, selection will be udpated to make it the + selected PoI. + - **Delete PoI**: Removes a point or more point of interests from the map. - **Replace PoIs**: Replace all the rendered PoIs by the ones provided in the event. Uses the same format used by the **Insert/Update PoI** From f8e9cbc63452d2415f9c0d4b7e92d686ed356159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Arranz?= Date: Mon, 26 Jul 2021 03:52:40 +0200 Subject: [PATCH 3/4] Fixes on WireCloud 1.3 --- src/js/ol3-map-widget.js | 114 +++++++++++++++---------------- tests/js/OpenlayersWidgetSpec.js | 91 +++++++++++++----------- 2 files changed, 108 insertions(+), 97 deletions(-) diff --git a/src/js/ol3-map-widget.js b/src/js/ol3-map-widget.js index 824785d..7f70c88 100644 --- a/src/js/ol3-map-widget.js +++ b/src/js/ol3-map-widget.js @@ -94,6 +94,43 @@ CORE_LAYERS.GOOGLE_HYBRID = CORE_LAYERS.MAPQUEST_HYBRID; CORE_LAYERS.GOOGLE_SATELLITE = CORE_LAYERS.MAPQUEST_SATELLITE; + const create_popover = function create_popover(feature) { + // The feature has content to be used on a popover + this.popover = new StyledElements.Popover({ + placement: ['top', 'bottom', 'right', 'left'], + title: feature.get('title'), + content: new StyledElements.Fragment(feature.get('content')), + sticky: true + }); + this.popover.on('hide', (popover) => { + // The popover can be hidden by clicking outside the widget. So we have to listen to this event + // On the other side, we have to detect if this popover is applying to current state + if (this.popover === popover) { + this.popover = null; + update_selected_feature.call(this, null); + } + }); + this.popover.show(this.refpos); + }; + + const update_popover = function update_popover(feature) { + if ("update" in this.popover) { + // WireCloud 1.4+ + this.popover.update( + feature.get("title"), + new StyledElements.Fragment(feature.get("content")) + ); + } else { + // Workaround for WireCloud 1.3 and below + const popover = this.popover; + this.popover = null; + popover.hide().hide(); + create_popover.call(this, feature); + // Call show method again to cancel fade animation + this.popover.show(this.refpos); + } + }; + const update_selected_feature = function update_selected_feature(feature) { if (this.selected_feature != feature) { this.selected_feature = feature; @@ -395,6 +432,7 @@ this.base_layer = null; this.popover = null; this.layers = {}; + this.centering = false; }; Widget.prototype.init = function init() { @@ -625,7 +663,9 @@ }); this.map.on("movestart", () => { if (this.popover != null && !("disablePointerEvents" in this.popover)) { - this.popover.hide(); + if (!this.centering) { + this.popover.hide(); + } } else if (this.popover != null) { this.popover.disablePointerEvents(); } @@ -638,6 +678,7 @@ this.popover.repaint(); } send_visible_pois.call(this); + this.centering = false; }); this.geojsonparser = new ol.format.GeoJSON(); @@ -712,22 +753,7 @@ if (this.selected_feature === iconFeature) { if (this.popover != null) { - if ("update" in this.popover) { - // WireCloud 1.4+ - this.popover.update( - iconFeature.get("title"), - new StyledElements.Fragment(iconFeature.get("content")) - ); - } else { - // Workaround for WireCloud 1.3 and below - const popover = this.popover; - this.popover = null; - popover.hide().hide(); - this.popover = popover; - popover.options.title = iconFeature.get("title"); - popover.options.content = new StyledElements.Fragment(iconFeature.get("content")); - popover.show(this.refpos); - } + update_popover.call(this, iconFeature); } MashupPlatform.widget.outputs.poiOutput.pushEvent(iconFeature.get('data')); } @@ -752,22 +778,7 @@ if (this.popover != null) { if (new_selected_feature != null) { - if ("update" in this.popover) { - // WireCloud 1.4+ - this.popover.update( - new_selected_feature.get("title"), - new StyledElements.Fragment(new_selected_feature.get("content")) - ); - } else { - // Workaround for WireCloud 1.3 and below - const popover = this.popover; - this.popover = null; - popover.hide().hide(); - this.popover = popover; - popover.options.title = new_selected_feature.get("title"); - popover.options.content = new StyledElements.Fragment(new_selected_feature.get("content")); - popover.show(this.refpos); - } + update_popover.call(this, new_selected_feature); } else { this.popover.hide(); this.popover = null; @@ -800,6 +811,7 @@ const zoom = parseInt(MashupPlatform.prefs.get('poiZoom'), 10); const currentZoom = this.map.getView().getZoom(); if (currentZoom < zoom) { + this.centering = true; this.map.getView().fit(geometryset.getExtent(), { maxZoom: zoom }); @@ -810,6 +822,7 @@ const view_size = ol.extent.getSize(view_extent); const geometry_size = ol.extent.getSize(geometry_extent); + this.centering = true; if (view_size[0] < geometry_size[0] && view_size[1] < geometry_size[1]) { this.map.getView().fit(geometryset.getExtent(), { maxZoom: zoom @@ -1270,39 +1283,22 @@ update_selected_feature.call(this, feature); if (this.popover == null && feature.get('content') != null) { - // The feature has content to be used on a popover - const popover = this.popover = new StyledElements.Popover({ - placement: ['top', 'bottom', 'right', 'left'], - title: feature.get('title'), - content: new StyledElements.Fragment(feature.get('content')), - sticky: true - }); - popover.on('show', () => { - update_selected_feature.call(this, feature); - }); - popover.on('hide', (popover) => { - // The popover can be hidden by clicking outside the widget. So we have to listen to this event - // On the other side, we have to detect if this popover is applying to current state - if (this.popover === popover) { - this.popover = null; - update_selected_feature.call(this, null); - } - }); + create_popover.call(this, feature); - // Delay popover show action + // Repaint popover after 200ms, to handle the situation where the + // marker is not yet loaded + // TODO, do this with events instead of using a fixed time setTimeout(() => { - if (this.popover !== popover) { - // Selection has changed in the middle - return; + if (this.popover != null) { + this.popover.repaint(); } - - update_selected_feature.call(this, feature); - this.popover.show(this.refpos); - }, 100); + }, 200); } else if (this.popover != null && feature.get("content") == null) { const popover = this.popover; this.popover = null; popover.hide().hide(); + } else if (this.popover != null /* && feature.get("content") != null */) { + update_popover.call(this, feature); } }; diff --git a/tests/js/OpenlayersWidgetSpec.js b/tests/js/OpenlayersWidgetSpec.js index 7f56d3c..f85177d 100644 --- a/tests/js/OpenlayersWidgetSpec.js +++ b/tests/js/OpenlayersWidgetSpec.js @@ -456,6 +456,7 @@ // Check popover is placed taking into account the poi marker position expect(style_mock.getImage().getSize).toHaveBeenCalledTimes(1); expect(widget.select_feature).toHaveBeenCalledWith(feature_mock); + widget.popover = null; done(); }, 150); }); @@ -553,7 +554,7 @@ expect(MashupPlatform.widget.outputs.poiOutput.pushEvent).not.toHaveBeenCalled(); }); - it("outside any feature (but while there is a selected feature)", (done) => { + it("outside any feature (but while there is a selected feature)", () => { const pixel_mock = jasmine.createSpy('pixel'); const feature_mock = new ol.Feature(); feature_mock.set('selectable', true); @@ -565,33 +566,31 @@ widget.init(); spyOn(widget.map, 'getPixelFromCoordinate').and.returnValue([0, 0]); widget.select_feature(feature_mock); - widget.popover.addEventListener('show', () => { - MashupPlatform.widget.outputs.poiOutput.reset(); - const popover = widget.popover; - // TODO, the following line is required as the CSS - // animation is not processed - document.body.querySelector('.popover').classList.remove('in'); - spyOn(popover, "on"); - spyOn(popover, "hide").and.callThrough(); - spyOn(widget, "select_feature"); - - spyOn(widget.map, 'forEachFeatureAtPixel').and.callFake((pixel, listener) => { - expect(pixel).toBe(pixel_mock); - return undefined; - }); - - widget.map.dispatchEvent({ - type: "click", - pixel: pixel_mock - }); - - expect(widget.popover).toBe(null) - expect(widget.selected_feature).toBe(null); - expect(popover.hide).toHaveBeenCalled(); - expect(widget.select_feature).not.toHaveBeenCalled(); - expect(MashupPlatform.widget.outputs.poiOutput.pushEvent).toHaveBeenCalledWith(null); - done(); + + MashupPlatform.widget.outputs.poiOutput.reset(); + const popover = widget.popover; + // TODO, the following line is required as the CSS + // animation is not processed + document.body.querySelector('.popover').classList.remove('in'); + spyOn(popover, "on"); + spyOn(popover, "hide").and.callThrough(); + spyOn(widget, "select_feature"); + + spyOn(widget.map, 'forEachFeatureAtPixel').and.callFake((pixel, listener) => { + expect(pixel).toBe(pixel_mock); + return undefined; + }); + + widget.map.dispatchEvent({ + type: "click", + pixel: pixel_mock }); + + expect(widget.popover).toBe(null) + expect(widget.selected_feature).toBe(null); + expect(popover.hide).toHaveBeenCalled(); + expect(widget.select_feature).not.toHaveBeenCalled(); + expect(MashupPlatform.widget.outputs.poiOutput.pushEvent).toHaveBeenCalledWith(null); }); it("outside the widget (but while there is a selected feature)", () => { @@ -603,10 +602,11 @@ feature_mock.set("data", {}); widget.init(); + const popover = new StyledElements.Popover(); + spyOn(popover, "show"); + spyOn(StyledElements, "Popover").and.returnValue(popover); widget.select_feature(feature_mock); MashupPlatform.widget.outputs.poiOutput.reset(); - const popover = widget.popover; - spyOn(popover, "on"); spyOn(widget, "select_feature"); // Simulate the popover has been hidden by a third party code @@ -1017,11 +1017,18 @@ const feature_mock = new ol.Feature(); widget.init(); widget.selected_feature = feature_mock; - const mock_popover = widget.popover = { + const oldpopover = widget.popover = { options: {}, - hide: jasmine.createSpy("hide").and.callFake(() => mock_popover), + hide: jasmine.createSpy("hide").and.callFake(() => oldpopover), show: jasmine.createSpy("show") }; + const newpopover = { + options: {}, + on: jasmine.createSpy("on"), + hide: jasmine.createSpy("hide"), + show: jasmine.createSpy("show") + }; + spyOn(StyledElements, "Popover").and.returnValue(newpopover); spyOn(feature_mock, 'set'); spyOn(feature_mock, 'setGeometry'); spyOn(feature_mock, 'setStyle'); @@ -1046,8 +1053,9 @@ }); widget.registerPoI(poi_info); - expect(widget.popover.hide).toHaveBeenCalledTimes(2); - expect(widget.popover.show).toHaveBeenCalledTimes(1); + expect(oldpopover.hide).toHaveBeenCalledTimes(2); + expect(newpopover.show).toHaveBeenCalledTimes(2); + expect(widget.popover).toBe(newpopover); expect(widget.selected_feature).toBe(feature_mock); }); @@ -1334,11 +1342,18 @@ const initial_feature_mock = new ol.Feature(); initial_feature_mock.setId("1"); widget.selected_feature = initial_feature_mock; - const popover = widget.popover = { + const oldpopover = widget.popover = { options: {}, - hide: jasmine.createSpy("hide").and.callFake(() => popover), + hide: jasmine.createSpy("hide").and.callFake(() => oldpopover), show: jasmine.createSpy("show") }; + const newpopover = { + options: {}, + on: jasmine.createSpy("on"), + hide: jasmine.createSpy("hide"), + show: jasmine.createSpy("show") + }; + spyOn(StyledElements, "Popover").and.returnValue(newpopover); const new_feature_mock = new ol.Feature(); spyOn(new_feature_mock, "get").and.callFake((attr) => attr == "data" ? poi_info : poi_info[attr]); spyOn(widget, "registerPoI"); @@ -1351,9 +1366,9 @@ expect(widget.registerPoI).toHaveBeenCalledTimes(1); expect(widget.vector_source.getFeatureById).toHaveBeenCalledTimes(1); expect(widget.vector_source.getFeatureById).toHaveBeenCalledWith("1"); - expect(widget.popover).toBe(popover); - expect(popover.hide).toHaveBeenCalledTimes(2); - expect(popover.show).toHaveBeenCalledTimes(1); + expect(widget.popover).toBe(newpopover); + expect(oldpopover.hide).toHaveBeenCalledTimes(2); + expect(newpopover.show).toHaveBeenCalledTimes(2); expect(widget.selected_feature).toBe(new_feature_mock); expect(MashupPlatform.widget.outputs.poiOutput.pushEvent).toHaveBeenCalledTimes(1); expect(MashupPlatform.widget.outputs.poiOutput.pushEvent).toHaveBeenCalledWith(poi_info); From c130d409580d92c393ecd11968e4518f7874040c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Arranz?= Date: Fri, 21 Jan 2022 18:00:34 +0100 Subject: [PATCH 4/4] Code clean up --- src/js/ol3-map-widget.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/ol3-map-widget.js b/src/js/ol3-map-widget.js index 7f70c88..b5c3ead 100644 --- a/src/js/ol3-map-widget.js +++ b/src/js/ol3-map-widget.js @@ -579,7 +579,7 @@ }); // display popup on click - this.map.on('click', function (event) { + this.map.on("click", (event) => { const features = []; this.map.forEachFeatureAtPixel( event.pixel, @@ -635,10 +635,10 @@ } else if (this.selected_feature != null && this.selected_feature.get('content') == null) { unselect.call(this, this.selected_feature); update_selected_feature.call(this, null); - } else if (feature !== this.selected_feature) { + } else { update_selected_feature.call(this, null); } - }.bind(this)); + }); // change mouse cursor when over marker this.map.on('pointermove', (event) => {