/**
* BeNomad BeMap JavaScript API - MapLibre v5 - Popup
*/
bemap.MapLibreMap.prototype.addPopup = function(popup, options) {
if (!popup || !bemap.inheritsof(popup, bemap.Popup)) return this;
popup.native = new maplibregl.Popup({ closeOnClick: true, maxWidth: '300px' });
if (popup.information) popup.native.setHTML(popup.information);
if (popup.map === null) popup.map = this;
// Track OUR popups per map instance so clearPopup() can be surgical. It used
// to sweep `document.querySelectorAll('.maplibregl-popup')`, which reached
// every popup on the page — other bemap maps' popups and any the host app had
// created itself (BEMAP-1898 audit).
if (!this._bemapPopups) this._bemapPopups = [];
if (this._bemapPopups.indexOf(popup) === -1) this._bemapPopups.push(popup);
if (popup.coordinate && popup.visible !== false) {
popup.native.setLngLat([popup.coordinate.getLon(), popup.coordinate.getLat()]);
popup.native.addTo(this.native);
popup.visible = true;
} else if (!popup.coordinate && popup.visible === true) {
// Fallback: use map center (same as OlMap behavior)
var center = this.native.getCenter();
popup.coordinate = new bemap.Coordinate(center.lng, center.lat);
popup.native.setLngLat([center.lng, center.lat]);
popup.native.addTo(this.native);
} else {
popup.visible = false;
}
return this;
};
bemap.MapLibreMap.prototype.removePopup = function(popup) {
if (popup && popup.native) {
popup.native.remove();
popup.visible = false;
popup.map = null;
popup.native = null;
}
// Drop the tracking entry whether or not it still had a native, so a repeated
// remove cannot leave a stale reference behind.
if (popup && this._bemapPopups) {
var at = this._bemapPopups.indexOf(popup);
if (at !== -1) this._bemapPopups.splice(at, 1);
}
return this;
};
bemap.MapLibreMap.prototype.setVisiblePopup = function(popup, visible) {
if (popup && popup.native) {
popup.visible = visible;
if (visible && popup.coordinate) {
popup.native.setLngLat([popup.coordinate.getLon(), popup.coordinate.getLat()]);
popup.native.addTo(this.native);
} else {
popup.native.remove();
}
}
return this;
};
/**
* Remove all the popups THIS map owns.
*
* Used to be `document.querySelectorAll('.maplibregl-popup')` + `Element.remove()`,
* which had three faults (BEMAP-1898 audit):
* • document-wide — it deleted popups belonging to other bemap maps on the
* page, and any `maplibregl.Popup` the host application had created itself;
* • it removed the DOM node instead of calling the popup's own `remove()`, so
* MapLibre never detached its map listeners — each open/clear cycle leaked a
* move + click + remove handler set;
* • the bemap.Popup models were left reporting `isVisible() === true`.
* @public
* @return {bemap.MapLibreMap} this
*/
bemap.MapLibreMap.prototype.clearPopup = function() {
var owned = this._bemapPopups ? this._bemapPopups.slice() : [];
for (var i = 0; i < owned.length; i++) {
// Goes through removePopup so the native's own remove() runs (detaching its
// listeners), the model is marked hidden, and the tracking entry is dropped.
this.removePopup(owned[i]);
}
this._bemapPopups = [];
return this;
};
bemap.MapLibreMap.prototype.setCoordinatePopup = function(popup, coordinate, options) {
if (popup && popup.native && coordinate) {
popup.coordinate = coordinate;
popup.native.setLngLat([coordinate.getLon(), coordinate.getLat()]);
if (popup.information) popup.native.setHTML(popup.information);
if (!popup.visible) {
popup.native.addTo(this.native);
popup.visible = true;
}
}
return this;
};