1import { Controller } from "@hotwired/stimulus"; 2import "leaflet/dist/leaflet.min.css"; 3import * as L from "leaflet"; 4const IconTypes = { 5 Url: "url", 6 Svg: "svg", 7 UxIcon: "ux-icon" 8}; 9var _Class = class extends Controller { 10 constructor(..._args) { 11 super(..._args); 12 this.markers = /* @__PURE__ */ new Map(); 13 this.polygons = /* @__PURE__ */ new Map(); 14 this.polylines = /* @__PURE__ */ new Map(); 15 this.circles = /* @__PURE__ */ new Map(); 16 this.rectangles = /* @__PURE__ */ new Map(); 17 this.infoWindows = []; 18 this.isConnected = false; 19 } 20 connect() { 21 const extra = this.hasExtraValue ? this.extraValue : {}; 22 const mapDefinition = { 23 center: this.hasCenterValue ? this.centerValue : null, 24 zoom: this.hasZoomValue ? this.zoomValue : null, 25 minZoom: this.hasMinZoomValue ? this.minZoomValue : null, 26 maxZoom: this.hasMaxZoomValue ? this.maxZoomValue : null, 27 options: this.optionsValue, 28 extra 29 }; 30 this.dispatchEvent("pre-connect", mapDefinition); 31 this.createMarker = this.createDrawingFactory("marker", this.markers, this.doCreateMarker.bind(this)); 32 this.createPolygon = this.createDrawingFactory("polygon", this.polygons, this.doCreatePolygon.bind(this)); 33 this.createPolyline = this.createDrawingFactory("polyline", this.polylines, this.doCreatePolyline.bind(this)); 34 this.createCircle = this.createDrawingFactory("circle", this.circles, this.doCreateCircle.bind(this)); 35 this.createRectangle = this.createDrawingFactory("rectangle", this.rectangles, this.doCreateRectangle.bind(this)); 36 this.map = this.doCreateMap({ definition: mapDefinition }); 37 this.markersValue.forEach((definition) => { 38 this.createMarker({ definition }); 39 }); 40 this.polygonsValue.forEach((definition) => { 41 this.createPolygon({ definition }); 42 }); 43 this.polylinesValue.forEach((definition) => { 44 this.createPolyline({ definition }); 45 }); 46 this.circlesValue.forEach((definition) => { 47 this.createCircle({ definition }); 48 }); 49 this.rectanglesValue.forEach((definition) => { 50 this.createRectangle({ definition }); 51 }); 52 if (this.fitBoundsToMarkersValue) this.doFitBoundsToMarkers(); 53 this.dispatchEvent("connect", { 54 map: this.map, 55 markers: [...this.markers.values()], 56 polygons: [...this.polygons.values()], 57 polylines: [...this.polylines.values()], 58 circles: [...this.circles.values()], 59 rectangles: [...this.rectangles.values()], 60 infoWindows: this.infoWindows, 61 extra 62 }); 63 this.isConnected = true; 64 } 65 createInfoWindow({ definition, element }) { 66 this.dispatchEvent("info-window:before-create", { 67 definition, 68 element 69 }); 70 const infoWindow = this.doCreateInfoWindow({ 71 definition, 72 element 73 }); 74 this.dispatchEvent("info-window:after-create", { 75 infoWindow, 76 definition, 77 element 78 }); 79 this.infoWindows.push(infoWindow); 80 return infoWindow; 81 } 82 markersValueChanged() { 83 if (!this.isConnected) return; 84 this.onDrawChanged(this.markers, this.markersValue, this.createMarker, this.doRemoveMarker); 85 if (this.fitBoundsToMarkersValue) this.doFitBoundsToMarkers(); 86 } 87 polygonsValueChanged() { 88 if (!this.isConnected) return; 89 this.onDrawChanged(this.polygons, this.polygonsValue, this.createPolygon, this.doRemovePolygon); 90 } 91 polylinesValueChanged() { 92 if (!this.isConnected) return; 93 this.onDrawChanged(this.polylines, this.polylinesValue, this.createPolyline, this.doRemovePolyline); 94 } 95 circlesValueChanged() { 96 if (!this.isConnected) return; 97 this.onDrawChanged(this.circles, this.circlesValue, this.createCircle, this.doRemoveCircle); 98 } 99 rectanglesValueChanged() { 100 if (!this.isConnected) return; 101 this.onDrawChanged(this.rectangles, this.rectanglesValue, this.createRectangle, this.doRemoveRectangle); 102 } 103 createDrawingFactory(type, draws, factory) { 104 const eventBefore = `${type}:before-create`; 105 const eventAfter = `${type}:after-create`; 106 return ({ definition }) => { 107 this.dispatchEvent(eventBefore, { definition }); 108 if (typeof definition.rawOptions !== "undefined") console.warn(`[Symfony UX Map] The event "${eventBefore}" added a deprecated "rawOptions" property to the definition, it will be removed in a next major version, replace it with "bridgeOptions" instead.`, definition); 109 const drawing = factory({ definition }); 110 this.dispatchEvent(eventAfter, { 111 [type]: drawing, 112 definition 113 }); 114 draws.set(definition["@id"], drawing); 115 return drawing; 116 }; 117 } 118 onDrawChanged(draws, newDrawDefinitions, factory, remover) { 119 const idsToRemove = new Set(draws.keys()); 120 newDrawDefinitions.forEach((definition) => { 121 idsToRemove.delete(definition["@id"]); 122 }); 123 idsToRemove.forEach((id) => { 124 remover(draws.get(id)); 125 draws.delete(id); 126 }); 127 newDrawDefinitions.forEach((definition) => { 128 if (!draws.has(definition["@id"])) factory({ definition }); 129 }); 130 } 131}; 132_Class.values = { 133 providerOptions: Object, 134 center: Object, 135 zoom: Number, 136 minZoom: Number, 137 maxZoom: Number, 138 fitBoundsToMarkers: Boolean, 139 markers: Array, 140 polygons: Array, 141 polylines: Array, 142 circles: Array, 143 rectangles: Array, 144 options: Object, 145 extra: Object 146}; 147var map_controller_default = class extends _Class { 148 connect() { 149 L.Marker.prototype.options.icon = L.divIcon({ 150 html: "<svg xmlns=\"http://www.w3.org/2000/svg\" xml:space=\"preserve\" fill-rule=\"evenodd\" stroke-linecap=\"round\" clip-rule=\"evenodd\" viewBox=\"0 0 500 820\"><defs><linearGradient id=\"__sf_ux_map_gradient_marker_fill\" x1=\"0\" x2=\"1\" y1=\"0\" y2=\"0\" gradientTransform=\"matrix(0 -37.57 37.57 0 416.45 541)\" gradientUnits=\"userSpaceOnUse\"><stop offset=\"0\" stop-color=\"#126FC6\"/><stop offset=\"1\" stop-color=\"#4C9CD1\"/></linearGradient><linearGradient id=\"__sf_ux_map_gradient_marker_border\" x1=\"0\" x2=\"1\" y1=\"0\" y2=\"0\" gradientTransform=\"matrix(0 -19.05 19.05 0 414.48 522.49)\" gradientUnits=\"userSpaceOnUse\"><stop offset=\"0\" stop-color=\"#2E6C97\"/><stop offset=\"1\" stop-color=\"#3883B7\"/></linearGradient></defs><circle cx=\"252.31\" cy=\"266.24\" r=\"83.99\" fill=\"#fff\"/><path fill=\"url(#__sf_ux_map_gradient_marker_fill)\" stroke=\"url(#__sf_ux_map_gradient_marker_border)\" stroke-width=\"1.1\" d=\"M4
15016.54 503.61c-6.57 0-12.04 5.7-12.04 11.87 0 2.78 1.56 6.3 2.7 8.74l9.3 17.88 9.26-17.88c1.13-2.43 2.74-5.79 2.74-8.74 0-6.18-5.38-11.87-11.96-11.87Zm0 7.16a4.69 4.69 0 1 1-.02 9.4 4.69 4.69 0 0 1 .02-9.4Z\" transform=\"translate(-7889.1 -9807.44) scale(19.54)\"/></svg>", 151 iconSize: [25, 41], 152 iconAnchor: [12.5, 41], 153 popupAnchor: [0, -41], 154 className: "" 155 }); 156 super.connect(); 157 } 158 centerValueChanged() { 159 if (this.map && this.hasCenterValue && this.centerValue && this.hasZoomValue && this.zoomValue) this.map.setView(this.centerValue, this.zoomValue); 160 } 161 zoomValueChanged() { 162 if (this.map && this.hasZoomValue && this.zoomValue) this.map.setZoom(this.zoomValue); 163 } 164 minZoomValueChanged() { 165 if (this.map && this.hasMinZoomValue && this.minZoomValue) this.map.setMinZoom(this.minZoomValue); 166 } 167 maxZoomValueChanged() { 168 if (this.map && this.hasMaxZoomValue && this.maxZoomValue) this.map.setMaxZoom(this.maxZoomValue); 169 } 170 dispatchEvent(name, payload = {}) { 171 payload.L = L; 172 this.dispatch(name, { 173 prefix: "ux:map", 174 detail: payload 175 }); 176 } 177 doCreateMap({ definition }) { 178 const { center, zoom, minZoom, maxZoom, options, bridgeOptions = {} } = definition; 179 const map = L.map(this.element, { 180 center: center === null ? void 0 : center, 181 zoom: zoom === null ? void 0 : zoom, 182 minZoom: minZoom === null ? void 0 : minZoom, 183 maxZoom: maxZoom === null ? void 0 : maxZoom, 184 attributionControl: false, 185 zoomControl: false, 186 ...options, 187 ...bridgeOptions 188 }); 189 if (options.tileLayer) L.tileLayer(options.tileLayer.url, { 190 attribution: options.tileLayer.attribution, 191 ...options.tileLayer.options 192 }).addTo(map); 193 if (typeof options.attributionControlOptions !== "undefined") L.control.attribution({ ...options.attributionControlOptions }).addTo(map); 194 if (typeof options.zoomControlOptions !== "undefined") L.control.zoom({ ...options.zoomControlOptions }).addTo(map); 195 return map; 196 } 197 doCreateMarker({ definition }) { 198 const { "@id": _id, position, title, infoWindow, icon, rawOptions = {}, bridgeOptions = {} } = definition; 199 const marker = L.marker(position, { 200 title: title || void 0, 201 ...rawOptions, 202 ...bridgeOptions, 203 riseOnHover: true 204 }).addTo(this.map); 205 if (infoWindow) this.createInfoWindow({ 206 definition: infoWindow, 207 element: marker 208 }); 209 if (icon) { 210 if (Object.prototype.hasOwnProperty.call(bridgeOptions, "icon")) console.warn("[Symfony UX Map] Defining \"bridgeOptions.icon\" for a marker with a custom icon is not supported and will be ignored."); 211 else if (Object.prototype.hasOwnProperty.call(rawOptions, "icon")) console.warn("[Symfony UX Map] Defining \"rawOptions.icon\" for a marker with a custom icon is not supported and will be ignored."); 212 this.doCreateIcon({ 213 definition: icon, 214 element: marker 215 }); 216 } 217 return marker; 218 } 219 doRemoveMarker(marker) { 220 marker.remove(); 221 } 222 doCreatePolygon({ definition }) { 223 const { "@id": _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition; 224 const polygon = L.polygon(points, { 225 ...rawOptions, 226 ...bridgeOptions 227 }).addTo(this.map); 228 /** 229 * @deprecated since Symfony UX Map 2.29 230 */ 231 if (title) polygon.bindPopup(title); 232 if (infoWindow) this.createInfoWindow({ 233 definition: infoWindow, 234 element: polygon 235 }); 236 return polygon; 237 } 238 doRemovePolygon(polygon) { 239 polygon.remove(); 240 } 241 doCreatePolyline({ definition }) { 242 const { "@id": _id, points, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition; 243 const polyline = L.polyline(points, { 244 ...rawOptions, 245 ...bridgeOptions 246 }).addTo(this.map); 247 /** 248 * @deprecated since Symfony UX Map 2.29 249 */ 250 if (title) polyline.bindPopup(title); 251 if (infoWindow) this.createInfoWindow({ 252 definition: infoWindow, 253 element: polyline 254 }); 255 return polyline; 256 } 257 doRemovePolyline(polyline) { 258 polyline.remove(); 259 } 260 doCreateCircle({ definition }) { 261 const { "@id": _id, center, radius, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition; 262 const circle = L.circle(center, { 263 radius, 264 ...rawOptions, 265 ...bridgeOptions 266 }).addTo(this.map); 267 /** 268 * @deprecated since Symfony UX Map 2.29 269 */ 270 if (title) circle.bindPopup(title); 271 if (infoWindow) this.createInfoWindow({ 272 definition: infoWindow, 273 element: circle 274 });
275 return circle; 276 } 277 doRemoveCircle(circle) { 278 circle.remove(); 279 } 280 doCreateRectangle({ definition }) { 281 const { "@id": _id, southWest, northEast, title, infoWindow, rawOptions = {}, bridgeOptions = {} } = definition; 282 const rectangle = L.rectangle([[southWest.lat, southWest.lng], [northEast.lat, northEast.lng]], { 283 ...rawOptions, 284 ...bridgeOptions 285 }).addTo(this.map); 286 /** 287 * @deprecated since Symfony UX Map 2.29 288 */ 289 if (title) rectangle.bindPopup(title); 290 if (infoWindow) this.createInfoWindow({ 291 definition: infoWindow, 292 element: rectangle 293 }); 294 return rectangle; 295 } 296 doRemoveRectangle(rectangle) { 297 rectangle.remove(); 298 } 299 doCreateInfoWindow({ definition, element }) { 300 const { headerContent, content, opened, autoClose, rawOptions = {}, bridgeOptions = {} } = definition; 301 element.bindPopup([headerContent, content].filter((x) => x).join("<br>"), { 302 ...rawOptions, 303 ...bridgeOptions 304 }); 305 if (opened) { 306 if (autoClose) this.closePopups(); 307 setTimeout(() => element.openPopup(), 0); 308 } 309 const popup = element.getPopup(); 310 if (!popup) throw new Error("Unable to get the Popup associated with the element."); 311 popup.on("click", () => { 312 if (autoClose) this.closePopups({ except: popup }); 313 }); 314 return popup; 315 } 316 doCreateIcon({ definition, element }) { 317 const { type, width, height } = definition; 318 let icon; 319 if (type === IconTypes.Svg) icon = L.divIcon({ 320 html: definition.html, 321 iconSize: [width, height], 322 className: "" 323 }); 324 else if (type === IconTypes.UxIcon) icon = L.divIcon({ 325 html: definition._generated_html, 326 iconSize: [width, height], 327 className: "" 328 }); 329 else if (type === IconTypes.Url) icon = L.icon({ 330 iconUrl: definition.url, 331 iconSize: [width, height], 332 className: "" 333 }); 334 else throw new Error(`Unsupported icon type: ${type}.`); 335 element.setIcon(icon); 336 } 337 doFitBoundsToMarkers() { 338 if (this.markers.size === 0) return; 339 const bounds = []; 340 this.markers.forEach((marker) => { 341 const position = marker.getLatLng(); 342 bounds.push([position.lat, position.lng]); 343 }); 344 this.map.fitBounds(bounds); 345 } 346 closePopups(options = {}) { 347 this.infoWindows.forEach((popup) => { 348 if (options.except && popup === options.except) return; 349 popup.close(); 350 }); 351 } 352}; 353export { map_controller_default as default };
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.