PageSourceSearch

https://swh.de/assets/@symfony/ux-leaflet-map/map_controller-sycosys.js

js swh.de collected 2026-10-01 14:43:03 UTC 12,750 bytes, 353 lines download raw bytes

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.