PageSourceSearch

https://www.vittoriaassicurazioni.com/wp-content/themes/vittoria-theme/src/js/poi.js

js vittoriaassicurazioni.com collected 2026-09-24 09:00:07 UTC 10,702 bytes, 336 lines download raw bytes

1( function( $, win ) {
2
3
4	async function getColoredMarkerIcon(markerType, desiredColor) {
5		const svgUrl = window.location.origin + '/wp-content/themes/vittoria-theme/img/pins/' + markerType + '.svg';
6		if(markerType == "pin-default" || markerType == "pin-convenzionati"){
7			return window.location.origin + '/wp-content/themes/vittoria-theme/img/pins/' + markerType + '.png';
8		}
9		try {
10			const response = await fetch(svgUrl);
11			if (!response.ok) return window.location.origin + '/wp-content/themes/vittoria-theme/img/pins/default.svg';
12			
13			let svgText = await response.text();
14
15			if (desiredColor) {
16				const parser = new DOMParser();
17				const doc = parser.parseFromString(svgText, "image/svg+xml");
18				
19				// Tutti gli attributi fill/stroke che non sono 'none' o 'white'
20				const allElements = doc.querySelectorAll('*');
21				const colorCounts = {};
22
23				allElements.forEach(el => {
24					['fill', 'stroke'].forEach(attr => {
25						const val = el.getAttribute(attr);
26						// Esclude bianco, trasparente e 'none'
27						if (val && val !== 'none' && !/#([fF]{3,6})/i.test(val) && !/white/i.test(val)) {
28							colorCounts[val] = (colorCounts[val] || 0) + 1;
29						}
30					});
31				});
32
33				// Trova il colore che appare più spesso (il colore principale dell'icona)
34				const mainColor = Object.keys(colorCounts).reduce((a, b) => colorCounts[a] > colorCounts[b] ? a : b, null);
35
36				// Applicha la sostituzione solo a quel colore
37				if (mainColor) {
38					const replaceRegex = new RegExp(mainColor, 'gi');
39					svgText = svgText.replace(replaceRegex, desiredColor);
40				}
41			}
42
43			const encodedSvg = encodeURIComponent(svgText).replace(/'/g, '%27').replace(/"/g, '%22');
44			return `data:image/svg+xml;charset=UTF-8,${encodedSvg}`;
45
46		} catch (error) {
47			console.error("Errore:", error);
48			return svgUrl;
49		}
50	}
51
52	/**
53	 * Vittoria POI search.
54	 */
55	var VittoriaPoiSearch = function() {
56
57		var self = this;
58
59		self.form = $( 'form[data-vittoria-poi-search]' );
60		self.map = $( '#vittoria-poi-results-map' );
61
62		/**
63		 * Setup map.
64		 */
65		this.setupMap = async function() {
66			$( '.card-item-poi' ).css( 'cursor', 'pointer' );
67			let data = null;
68			let zoom = 14;
69			try {
70				data = JSON.parse( self.map.attr( 'data-map' ) );
71			} catch( e ) {}
72
73			if ( ! data ) {
74				return;
75			}
76			if(data.pois[0].type && (data.pois[0].type == "centro-grandine" || data.pois[0].type == "centro-convenzionato-cristalli" || data.pois[0].type == "carrozzeria-camper" || data.pois[0].type == "carrozzeria")){
77				zoom = 12;
78			}
79
80			self.map = new google.maps.Map(
81				self.map[ 0 ],
82				{
83					zoom: zoom,
84					center: {
85						lat: data.center.lat,
86						lng: data.center.long
87					},
88					scrollwheel: false
89				}
90			);
91			const centerPosition = {
92        		lat: data.center.lat,
93        		lng: data.center.long
94    		};
95			const centerMarker = new google.maps.Marker( {
96				position: centerPosition,
97				map: self.map,
98				icon: window.location.origin + '/wp-content/themes/vittoria-theme/img/VittoriaPin.svg'
99			} );
100			
101			const bounds = new google.maps.LatLngBounds();
102    		
103			let markers = {};
104			let infowindows = [];
105			let poisPosition = [];
106			poisPosition.push( centerPosition );
107			let distance = 0;
108			let markerType = null;
109			let dynamicColor = null;
110			let zIndexPoi = 9999999;
111			
112			for (const poi of data.pois) {
113				dynamicColor = null;
114				zIndexPoi = 9999999;
115				if(poi.priority){
116					zIndexPoi = 99999999;
117				}
118				if(poi.color){
119					dynamicColor = poi.color;
120				}
121				markerType = "default";	
122				if(poi.url_logo){
123					markerType = poi.url_logo;
124					// Solo per Centri Cristalli
125					if(markerType == "cristalli" 
126						|| markerType == "agenzia"
127						|| markerType == "carrozzeria"
128					){
129						markerType = "default";
130					}
131				}
132				
133				if(poi.type == "centro-convenzionato-cristalli" || poi.type == "centro-grandine"){
134					
135					if(markerType == "default" || markerType == "grandine"){
136						markerType = "pin-default"; 
137					}
138					else{
139						markerType = "pin-convenzionati";
140					}
141				}
142				if(markerType == "default"){
143					markerType = "pin-default"; 
144				}
145				if(poi.distance != 0 && poi.distance > distance){
146					distance = poi.distance;
147				}
148				const customIconUrl = await getColoredMarkerIcon(markerType, dynamicColor);
149				const poiPosition = {
150					lat: parseFloat( poi.lat ),
151					lng: parseFloat( poi.long )
152				};
153
154        		const marker = new google.maps.Marker( {
155					position: poiPosition,
156					map: self.map,
157					icon: customIconUrl,
158					zIndex: zIndexPoi
159				} );
160				poisPosition.push( poiPosition );
161				if (data.pois && data.pois.length <= 3) {
162					bounds.extend(poiPosition);
163				}
164				const infowindow = new google.maps.InfoWindow( {
165					content: poi.title,
166				} );
167
168				const poiKey = poi.cod_vittoria;
169				markers[poiKey] = {
170					marker: marker,
171					infowindow: infowindow
172				};
173
174				marker.addListener( "click", function() {
175					$.each( infowindows, function( i, iw ) {
176						iw.close();
177					} );
178					infowindow.open( {
179						anchor: marker,
180						map: self.map,
181						shouldFocus: false,
182					} );
183
184					$( '.card-item-poi' ).removeClass( 'active' );
185					let $targetCard = $( '#search-map-result-id-' + poiKey );
186            		if ( ! $targetCard.length ) {
187                		$targetCard = $( '.card-item-poi[data-poi-id="' + poiKey + '"]' );
188            		}
189					if ( $targetCard.length ) {
190						$targetCard.addClass( 'active' );
191
192						// 4. Esegue lo scroll verso la card selezionata
193						if ( document.documentElement.scrollIntoView ) {
194							$targetCard[ 0 ].scrollIntoView( {
195								behavior: 'smooth',
196								block: 'center'
197							} );
198						}
199					}
200				} );
201				infowindows.push( infowindow );
202				if (distance > 20) {
203					for(const d of poisPosition){
204						bounds.extend(d);
205					}
206					
207				}
208			}
209			if (!bounds.isEmpty()) {
210				self.map.fitBounds(bounds, {
211					top: 190, 
212					bottom: 50,
213					left: 50,
214					right: 50
215				}); 
216			}
217
218			$( document ).off( 'click', '.card-item-poi' ).on( 'click', '.card-item-poi', function(e) {
219				if ($(e.target).closest('a, button').length) {
220					return;
221				}
222				let poiKey = $( this ).data( 'poi-id' );
223				if ( ! poiKey && $( this ).attr('id') ) {
224					poiKey = $( this ).attr( 'id' ).replace( 'search-map-result-id-', '' );
225				}
226        		if ( ! poiKey ) return;
227				$( '.card-item-poi' ).removeClass( 'active' );
228        		$( this ).addClass( 'active' );
229				if ( markers[ poiKey ] ) {
230					google.maps.event.trigger( markers[ poiKey ].marker, 'click' );
231        			self.map.panTo( markers[ poiKey ].marker.getPosition() );
232        		}
233    		});
234		};
235
236		this.init = function() {
237			this.setupMap();
238			const urlParams = new URLSearchParams(window.location.search);
239			if (urlParams.has('search') && urlParams.get('search').trim() !== '') {
240				const $target = $('.map-fullwidth');
241				if ($target.length) {
242					$target[0].scrollIntoView({
243						behavior: 'smooth',
244						block: 'start'
245					});
246				}
247			}
248			const autocomplete = new google.maps.places.Autocomplete(
249				$( '#cerca_citta', self.form )[ 0 ],
250				{
251					// componentRestrictions: { country: "it" }
252				}
253			);
254
255			$( '#cerca_citta', self.form ).on( 'focus', function () {
256				var pacContainer = $('.pac-container');
257				$($( '#cerca_citta', self.form ).parent()).append(pacContainer);
258			} );
259
260			autocomplete.addListener( 'place_changed', function() {
261				var place = autocomplete.getPlace();
262
263				$( 'input[name="search"]', self.form ).val( $( '#cerca_citta', self.form ).val() );
264				$( 'input[name="lat"]', self.form ).val( place.geometry.location.lat() );
265				$( 'input[name="long"]', self.form ).val( place.geometry.location.lng() );
266
267				$( 'button[type="submit"]', self.form ).prop( 'disabled', false );
268			} );
269
270			var $geoBtn = $( '#vittoria-btn-geo' );
271
272            if ( $geoBtn.length ) {
273                if ( ! navigator.geolocation ) {
274                    $geoBtn.hide();
275                } else {
276                    $geoBtn.on( 'click', function() {
277                        var $btnText = $geoBtn.find( 'span' );
278                        var originalText = $btnText.text();
279				        $btnText.text( 'Ricerca posizione...' );
280                        $geoBtn.prop( 'disabled', true );
281
282                        navigator.geolocation.getCurrentPosition(
283                            function( position ) {
284                                var lat = position.coords.latitude;
285                                var long = position.coords.longitude;
286                                var searchLabel = 'La mia posizione';
287
288                                $( 'input[name="lat"]', self.form ).val( lat );
289                                $( 'input[name="long"]', self.form ).val( long );
290                                $( 'input[name="search"]', self.form ).val( searchLabel );
291                                $( '#cerca_citta', self.form ).val( searchLabel );
292
293                                $btnText.text( originalText );
294                                $geoBtn.prop( 'disabled', false );
295
296                                self.form.submit();
297                            },
298                            function( error ) {
299                                $btnText.text( originalText );
300                                $geoBtn.prop( 'disabled', false );
301
302                                switch( error.code ) {
303                                    case error.PERMISSION_DENIED:
304                                        alert( "Per accedere ai centri più vicini, autorizza il browser a condividere la tua posizione." );
305                                        break;
306                                    case error.POSITION_UNAVAILABLE:
307                                        alert( "Informazioni sulla posizione non disponibili." );
308                                        break;
309                                    case error.TIMEOUT:
310                                        alert( "Il recupero della posizione è andato in timeout." );
311                                        break;
312                                    default:
313                                        alert( "Si è verificato un errore nel rilevamento della posizione." );
314                                        break;
315                                }
316                            },
317                            {
318                                enableHighAccuracy: true,
319                                timeout: 8000,
320                                maximumAge: 0
321                            }
322                        );
323                    });
324                }
325            }
326		}
327
328	};
329
330	let instance = new VittoriaPoiSearch();
331
332	window.VittoriaPoiSearch = function() {
333		instance.init();
334	};
335
336} )( jQuery, window );

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.