PageSourceSearch

https://manilva.ws/wp-content/plugins/inmo-portal/assets/js/map.js?ver=1.39.0

js manilva.ws collected 2026-10-01 13:02:02 UTC 5,585 bytes, 182 lines download raw bytes

1/**
2 * InmoPortal — Leaflet glue (depends on inmo-leaflet, inmo-markercluster, inmo-public).
3 *
4 * window.InmoMap = {
5 *   create(el, opts)        → L.map with the tiles/attribution from InmoCfg.map
6 *   icon()                  → L.icon built from the pin SVG
7 *   cluster(map)            → L.markerClusterGroup added to the map (or null)
8 *   priceMarker(point)      → L.marker with a price-label divIcon
9 *   addPoints(map, points, opts) → layer with every point (clustered), fitBounds
10 * }
11 *
12 * Points are the arrays produced by Inmo_Index::map_points():
13 * { id, lat, lng, price, op, type, zone, title, url, thumb, m2, rooms, baths, featured }.
14 */
15( function () {
16	'use strict';
17
18	if ( typeof window.L === 'undefined' ) {
19		return;
20	}
21
22	function cfg() {
23		return ( window.InmoCfg && window.InmoCfg.map ) || {};
24	}
25
26	function esc( s ) {
27		if ( window.Inmo && window.Inmo.esc ) {
28			return window.Inmo.esc( s );
29		}
30		return String( s == null ? '' : s ).replace( /[&<>"']/g, function ( c ) {
31			return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[ c ];
32		} );
33	}
34
35	/**
36	 * Create a map on an element with our tiles and defaults.
37	 * opts: center [lat,lng], zoom, scrollWheelZoom (default false).
38	 */
39	function create( el, opts ) {
40		opts = opts || {};
41		var c = cfg();
42		var center = opts.center || [ ( c.center && c.center.lat ) || 0, ( c.center && c.center.lng ) || 0 ];
43		var map = L.map( el, {
44			center: center,
45			zoom: opts.zoom || c.zoom || 13,
46			scrollWheelZoom: typeof opts.scrollWheelZoom !== 'undefined' ? opts.scrollWheelZoom : false,
47			attributionControl: true
48		} );
49		L.tileLayer( c.tiles, {
50			attribution: c.attribution || '',
51			maxZoom: c.max_zoom || 19
52		} ).addTo( map );
53		return map;
54	}
55
56	/**
57	 * The default pin icon (SVG with the brand color).
58	 */
59	function icon() {
60		var c = cfg();
61		var size = c.marker_size || [ 32, 42 ];
62		return L.icon( {
63			iconUrl: c.marker_icon,
64			iconSize: size,
65			iconAnchor: [ size[ 0 ] / 2, size[ 1 ] ],
66			popupAnchor: [ 0, -size[ 1 ] + 4 ]
67		} );
68	}
69
70	/**
71	 * A cluster group added to the map, or null when the plugin is missing.
72	 */
73	function cluster( map ) {
74		if ( typeof L.markerClusterGroup !== 'function' ) {
75			return null;
76		}
77		var g = L.markerClusterGroup( {
78			showCoverageOnHover: false,
79			maxClusterRadius: 48,
80			spiderfyOnMaxZoom: true
81		} );
82		map.addLayer( g );
83		return g;
84	}
85
86	/**
87	 * "245.000 €" → "245k", "1.250.000 €" → "1,3M", rent "850 €/mes" → "850€".
88	 */
89	function shortPrice( point ) {
90		var n = parseInt( String( point.price || '' ).replace( /[^\d]/g, '' ), 10 );
91		if ( ! n ) {
92			return String( point.price || '' );
93		}
94		if ( point.op === 'rent' ) {
95			return n >= 10000 ? Math.round( n / 1000 ) + 'k€' : n.toLocaleString( 'es-ES' ) + '€';
96		}
97		if ( n >= 1000000 ) {
98			var m = Math.round( n / 100000 ) / 10;
99			return String( m % 1 === 0 ? m.toFixed( 0 ) : m.toFixed( 1 ) ).replace( '.', ',' ) + 'M';
100		}
101		if ( n >= 1000 ) {
102			return Math.round( n / 1000 ) + 'k';
103		}
104		return String( n );
105	}
106
107	/**
108	 * Marker with the price as a pill label (divIcon).
109	 */
110	function priceMarker( point ) {
111		var html = '<span class="inmo-price-marker' + ( point.featured ? ' is-featured' : '' ) + '">' + esc( shortPrice( point ) ) + '</span>';
112		return L.marker( [ point.lat, point.lng ], {
113			icon: L.divIcon( { className: 'inmo-pmark', html: html, iconSize: [ 0, 0 ], iconAnchor: [ 0, 0 ] } ),
114			riseOnHover: true,
115			title: point.title || ''
116		} );
117	}
118
119	/**
120	 * Popup mini-card for a point.
121	 */
122	function popupHtml( point ) {
123		var meta = [];
124		if ( point.m2 ) {
125			meta.push( point.m2 + ' m²' );
126		}
127		if ( point.rooms ) {
128			meta.push( point.rooms + ' hab.' );
129		}
130		if ( point.baths ) {
131			meta.push( point.baths + ' baños' );
132		}
133		return '<a class="inmo-map-pop" href="' + esc( point.url ) + '">' +
134			'<span class="inmo-map-pop__img"><img src="' + esc( point.thumb ) + '" alt="" loading="lazy" /></span>' +
135			'<span class="inmo-map-pop__body">' +
136			'<strong class="inmo-map-pop__price">' + esc( point.price ) + '</strong>' +
137			'<span class="inmo-map-pop__title">' + esc( point.title ) + '</span>' +
138			( meta.length ? '<span class="inmo-map-pop__meta">' + esc( meta.join( ' · ' ) ) + '</span>' : '' ) +
139			'</span></a>';
140	}
141
142	/**
143	 * Add a set of points (clustered when available) and fit the view.
144	 * opts: popup (default true), prices (price labels, default true), cluster (default cfg), fit (default true).
145	 * Returns the layer so callers can remove it later.
146	 */
147	function addPoints( map, points, opts ) {
148		opts = opts || {};
149		var c = cfg();
150		var useCluster = typeof opts.cluster !== 'undefined' ? opts.cluster : ( c.cluster !== false );
151		var group = useCluster ? cluster( map ) : null;
152		if ( ! group ) {
153			group = L.layerGroup().addTo( map );
154		}
155		var bounds = [];
156		( points || [] ).forEach( function ( pt ) {
157			if ( typeof pt.lat === 'undefined' || typeof pt.lng === 'undefined' ) {
158				return;
159			}
160			var m = opts.prices === false
161				? L.marker( [ pt.lat, pt.lng ], { icon: icon(), riseOnHover: true, title: pt.title || '' } )
162				: priceMarker( pt );
163			if ( opts.popup !== false ) {
164				m.bindPopup( popupHtml( pt ), { maxWidth: 280, minWidth: 220 } );
165			}
166			group.addLayer( m );
167			bounds.push( [ pt.lat, pt.lng ] );
168		} );
169		if ( opts.fit !== false && bounds.length ) {
170			map.fitBounds( bounds, { padding: [ 40, 40 ], maxZoom: 16 } );
171		}
172		return group;
173	}
174
175	window.InmoMap = {
176		create: create,
177		icon: icon,
178		cluster: cluster,
179		priceMarker: priceMarker,
180		addPoints: addPoints
181	};
182} )();

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.