PageSourceSearch

https://thefrenchgrocer.com/wp-content/plugins/mildhill-core/inc/m…?ver=45c82075415f1e13152139025c5e4240

js thefrenchgrocer.com collected 2026-10-07 19:41:03 UTC 17,587 bytes, 633 lines download raw bytes

1(function ( $ ) {
2	'use strict';
3
4	var qodefGoogleMap = {
5		mapHolder: '',
6		mapOptions: [],
7		mapElement: '',
8		map: {},
9		markers: {},
10		circleMap: {},
11		init: function ( $mapHolder, options ) {
12			// Set main map holder.
13			this.mapHolder = $mapHolder;
14
15			if ( typeof google !== 'object' || typeof this.mapHolder === 'undefined' || typeof this.mapHolder === '' ) {
16				return;
17			}
18
19			// Init map.
20			this.initMap( this.mapHolder, options );
21		},
22		getMapSettings: function () {
23			return {
24				mapId: "QODE_MAP_ID",
25				mapTypeId: google.maps.MapTypeId.ROADMAP,
26				scrollwheel: qodefMapsVariables.global.mapScrollable,
27				draggable: qodefMapsVariables.global.mapDraggable,
28				streetViewControl: qodefMapsVariables.global.streetViewControl,
29				zoomControl: qodefMapsVariables.global.zoomControl,
30				zoom: parseInt( qodefMapsVariables.global.mapZoom, 10 ),
31				mapTypeControl: qodefMapsVariables.global.mapTypeControl,
32				fullscreenControl: qodefMapsVariables.global.fullscreenControl,
33			};
34		},
35		getMapOptions: function ( $mapHolder, forwardOptions ) {
36			var options = {
37				uniqueId: '',
38				holderId: '',
39				mapHeight: 0,
40				addresses: [],
41				addressesLatLng: [],
42				pin: '',
43				selectorIsID: false,
44				multipleTrigger: false,
45				geolocation: false,
46			};
47
48			options = $.extend( options, forwardOptions );
49
50			if ( options.selectorIsID ) {
51				options.uniqueId = $mapHolder[0].id;
52				options.holderId = $mapHolder[0].id;
53			} else if ( typeof $mapHolder.data( 'unique-id' ) !== 'undefined' && $mapHolder.data( 'unique-id' ) !== false ) {
54				options.uniqueId = $mapHolder.data( 'unique-id' );
55				options.holderId = 'qodef-map-id--' + $mapHolder.data( 'unique-id' );
56			}
57
58			if ( typeof $mapHolder.data( 'height' ) !== 'undefined' && $mapHolder.data( 'height' ) !== false ) {
59				options.mapHeight = parseInt( $mapHolder.data( 'height' ), 10 );
60			}
61
62			if ( typeof qodefMapsVariables.multiple.addresses !== 'undefined' && qodefMapsVariables.multiple.addresses !== '' ) {
63				options.addresses = qodefMapsVariables.multiple.addresses;
64			} else if ( typeof $mapHolder.data( 'addresses' ) !== 'undefined' && $mapHolder.data( 'addresses' ) !== false ) {
65				options.addresses = $mapHolder.data( 'addresses' );
66			}
67
68			if ( typeof $mapHolder.data( 'pin' ) !== 'undefined' && $mapHolder.data( 'pin' ) !== false ) {
69				options.pin = $mapHolder.data( 'pin' );
70			}
71
72			return options;
73		},
74		initMap: function ( $mapHolder, options ) {
75			this.mapOptions = this.getMapOptions( $mapHolder, options );
76			this.mapElement = document.getElementById( this.mapOptions.holderId );
77			this.map        = new google.maps.Map( this.mapElement, this.getMapSettings() );
78
79			var mapStyles     = qodefMapsVariables.global.mapStyle;
80			var styledMapType = new google.maps.StyledMapType( mapStyles, {name: "Qode Google Map"} );
81
82			this.map.mapTypes.set( 'qodef_styled_map', styledMapType );
83			this.map.setMapTypeId( "qodef_styled_map" );
84
85			// Trigger geolocation.
86			this.triggerGeolocation();
87
88			// Set map addresses.
89			this.setAddress();
90
91			// Set map height.
92			this.setMapHeight();
93		},
94		triggerGeolocation: function () {
95
96			// If geolocation enabled set map center to user location.
97			if ( navigator.geolocation && this.mapOptions.geolocation ) {
98				this.centerMapToGeolocationAddress();
99			}
100		},
101		setAddress: function () {
102			for ( var index = 0; index < this.mapOptions.addresses.length; index++ ) {
103				var address = this.mapOptions.addresses[index];
104
105				if ( address === '' ) {
106					return;
107				}
108
109				if ( this.mapOptions.multipleTrigger ) {
110					var addressLocation = address.location;
111
112					if ( typeof addressLocation !== 'undefined' && addressLocation !== null && addressLocation.latitude !== '' && addressLocation.longitude !== '' ) {
113						this.mapOptions.addressesLatLng.push( $.extend( addressLocation, address ) );
114					}
115
116				} else {
117					this.setSingleAddress( address );
118				}
119			}
120
121			if ( this.mapOptions.multipleTrigger ) {
122
123				// Center map and set borders of map.
124				this.centerMapMultipleAddresses( this.map, this.mapOptions );
125
126				// Add markers to the map.
127				this.addMultipleMarkers();
128			}
129		},
130		setSingleAddress: function ( address ) {
131			var $infoWindow = new google.maps.InfoWindow(
132				{
133					content: '<div id="content"><div id="siteNotice"></div><div id="bodyContent"><p>' + address + '</p></div></div>',
134				}
135			);
136
137			var $geocoder = new google.maps.Geocoder();
138
139			if ( typeof $geocoder === 'object' ) {
140				var $map       = this.map,
141					mapOptions = this.mapOptions;
142
143				$geocoder.geocode(
144					{ 'address': address },
145					function ( results, status ) {
146						if ( status === google.maps.GeocoderStatus.OK && typeof results === 'object' ) {
147
148							var pinImg = document.createElement( 'img' );
149							pinImg.src = mapOptions.pin;
150
151							var $marker = new google.maps.marker.AdvancedMarkerElement(
152								{
153									map: $map,
154									position: results[0].geometry.location,
155									content: pinImg,
156									title: address.store_title,
157								}
158							);
159
160							google.maps.event.addListener(
161								$marker,
162								'click',
163								function () {
164									$infoWindow.open( $map, $marker );
165								}
166							);
167
168							var addressVariables = {
169								address: results[0].formatted_address,
170								latitude: results[0].geometry.location.lat(),
171								longitude: results[0].geometry.location.lng(),
172							};
173
174							mapOptions.addressesLatLng.push( addressVariables );
175
176							// Center map address.
177							qodefGoogleMap.centerMapAddress( $map, mapOptions, results );
178
179							// Re-init markers position on resize.
180							window.addEventListener(
181								'resize',
182								function () {
183									qodefGoogleMap.centerMapAddress( $map, mapOptions, results );
184								}
185							);
186						}
187					}
188				);
189			}
190		},
191		setMapHeight: function () {
192			var mapOptions = this.mapOptions;
193
194			if ( mapOptions.mapHeight > 0 && this.mapElement !== '' ) {
195				this.mapElement.style.height = mapOptions.mapHeight + 'px';
196			}
197		},
198		centerMapAddress: function ( $map, mapOptions, results ) {
199
200			// Different logic for single and multiple addresses.
201			if ( mapOptions.addresses.length === 1 ) {
202				$map.setCenter( results[0].geometry.location );
203			} else {
204				this.centerMapMultipleAddresses( $map, mapOptions );
205			}
206		},
207		centerMapMultipleAddresses: function ( $map, mapOptions ) {
208			var $bounds         = new google.maps.LatLngBounds(),
209				addressesLatLng = mapOptions.addressesLatLng;
210
211			if ( mapOptions.multipleTrigger && addressesLatLng.length === 1 ) {
212				$map.setCenter(
213					{
214						lat: parseFloat( addressesLatLng[0].latitude ),
215						lng: parseFloat( addressesLatLng[0].longitude ),
216					}
217				);
218			} else if ( typeof $bounds === 'object' && addressesLatLng.length ) {
219				for ( var index = 0; index < addressesLatLng.length; index++ ) {
220					$bounds.extend(
221						{
222							lat: parseFloat( addressesLatLng[index].latitude ),
223							lng: parseFloat( addressesLatLng[index].longitude ),
224						}
225					);
226				}
227
228				$map.fitBounds( $bounds );
229			}
230		},
231		centerMapToGeolocationAddress: function ( setInputAddressValue, placesInput, geoLocationLinkIcon, listHolder ) {
232
233			// Try HTML5 geolocation.
234			if ( navigator.geolocation ) {
235				var $map = this.map;
236
237				if ( setInputAddressValue ) {
238					geoLocationLinkIcon.addClass( 'fa-spinner fa-spin' );
239				}
240
241				navigator.geolocation.getCurrentPosition(
242					function ( position ) {
243						var lat    = position.coords.latitude,
244							lng    = position.coords.longitude,
245							latlng = {
246								lat: lat,
247								lng: lng,
248							};
249
250						if ( setInputAddressValue ) {
251							var $geocoder           = new google.maps.Geocoder(),
252								cityName            = '',
253								cityWithCountryName = '';
254
255							$geocoder.geocode(
256								{ 'latLng': latlng },
257								function ( results, status ) {
258									if ( status === google.maps.GeocoderStatus.OK && typeof results === 'object' ) {
259										var resultsObject = results;
260
261										for ( var $i = 0; $i <= resultsObject.length; $i++ ) {
262											var result = resultsObject[$i];
263
264											if ( typeof result === 'object' && result.types[0] === 'locality' ) {
265												var currentAddress = result.address_components;
266
267												cityName = currentAddress[0].long_name;
268
269												for ( var $j = 0; $j <= currentAddress.length; $j++ ) {
270													if ( typeof currentAddress[$j] === 'object' && currentAddress[$j].types[0] === 'country' ) {
271														cityWithCountryName = cityName + ',' + currentAddress[$j].long_name;
272													}
273												}
274											}
275										}
276
277										if ( typeof cityName === 'string' ) {
278											geoLocationLinkIcon.removeClass( 'fa-spinner fa-spin' );
279
280											if ( typeof cityWithCountryName === 'string' ) {
281												placesInput.val( cityWithCountryName );
282											} else {
283												placesInput.val( cityName );
284											}
285
286											window.qodefGeoLocation.showRangeSlider( latlng, true );
287											qodef.body.trigger( 'mildhill_core_trigger_after_autocomplete_places', [placesInput] );
288										}
289									}
290								}
291							);
292						} else {
293							$map.setCenter( latlng );
294						}
295					}
296				);
297			}
298		},
299		centerMapToForwardAddress: function ( addressName ) {
300
301			if ( typeof addressName === 'string' && typeof google === 'object' ) {
302				var $map        = this.map,
303					mapSettings = this.getMapSettings(),
304					$geocoder   = new google.maps.Geocoder();
305
306				$geocoder.geocode(
307					{ 'address': addressName },
308					function ( results, status ) {
309						if ( status === google.maps.GeocoderStatus.OK && typeof results[0] === 'object' ) {
310							$map.setZoom( mapSettings.zoom );
311							$map.setCenter( results[0].geometry.location );
312						}
313					}
314				);
315			}
316		},
317		addMultipleMarkers: function () {
318			var markers         = [],
319				addressesLatLng = this.mapOptions.addressesLatLng;
320
321			for ( var i = 0; i < addressesLatLng.length; i++ ) {
322				var latLng = {
323					lat: parseFloat( addressesLatLng[i].latitude ),
324					lng: parseFloat( addressesLatLng[i].longitude )
325				};
326
327				// Custom html markers.
328				// Insert marker data into info window template.
329				var templateData = {
330					latLng: latLng,
331				};
332
333				$.each(
334					addressesLatLng[i],
335					function ( key, value ) {
336						templateData[key] = value;
337					}
338				);
339
340				var $customMarker = new window.qodefCustomMarker(
341					{
342						position: latLng,
343						map: this.map,
344						templateData: templateData,
345						markerPin: addressesLatLng[i].markerPin,
346					}
347				);
348
349				markers.push( $customMarker );
350			}
351
352			this.markers = markers;
353
354			// Init map clusters ( Grouping map markers at small zoom values ).
355			this.initMarkerClusters();
356
357			// Init marker info.
358			this.initMarkerInfo();
359		},
360		initMarkerClusters: function () {
361			var markerOptions = {
362				minimumClusterSize: 2,
363				maxZoom: 12,
364				styles: [{
365					width: 50,
366					height: 60,
367					url: '',
368					textSize: 12,
369				}],
370			};
371
372			new MarkerClusterer(
373				this.map,
374				this.markers,
375				markerOptions
376			);
377		},
378		initMarkerInfo: function () {
379			var $map = this.map;
380
381			$( document ).off(
382				'click',
383				'.qodef-map-marker'
384			).on(
385				'click',
386				'.qodef-map-marker',
387				function () {
388					var self             = $( this ),
389						$markerHolders   = $( '.qodef-map-marker-holder' ),
390						$infoWindows     = $( '.qodef-info-window' ),
391						$markerHolder    = self.parent( '.qodef-map-marker-holder' ),
392						markerlatlngData = $markerHolder.data( 'latlng' ),
393						$infoWindow      = self.siblings( '.qodef-info-window' );
394
395					if ( $markerHolder.hasClass( 'qodef-active qodef-map-active' ) ) {
396						$markerHolder.removeClass( 'qodef-active qodef-map-active' );
397						$infoWindow.fadeOut( 0 );
398					} else {
399						$markerHolders.removeClass( 'qodef-active qodef-map-active' );
400						$infoWindows.fadeOut( 0 );
401						$markerHolder.addClass( 'qodef-active qodef-map-active' );
402						$infoWindow.fadeIn( 300 );
403
404						if ( markerlatlngData.length && markerlatlngData !== undefined ) {
405							var latlngStr = markerlatlngData.replace( '(', '' ).replace( ')', '' ).split( ',', 2 );
406
407							$map.panTo( new google.maps.LatLng( parseFloat( latlngStr[0] ), parseFloat( latlngStr[1] ) ) );
408						}
409					}
410				}
411			);
412		},
413		setGeoLocationRadius: function ( $geoLocation, radius, isActive ) {
414
415			if ( typeof $geoLocation === 'object' && typeof google === 'object' ) {
416				var $map     = this.map,
417					$markers = this.markers;
418
419				if ( isActive ) {
420					this.circleMap.setMap( null );
421				}
422
423				this.circleMap = new google.maps.Circle(
424					{
425						map: $map,
426						center: $geoLocation,
427						// 1000 change meters to kilometers.
428						radius: parseInt( radius, 10 ) * 1000,
429						strokeWeight: 0,
430						fillColor: '#fc475f',
431						fillOpacity: 0.15,
432					}
433				);
434
435				var $currentCircle = this.circleMap;
436
437				var itemsInArea = [];
438				$.each(
439					$markers,
440					function ( i, marker ) {
441						if ( $currentCircle.getBounds().contains( marker.latlng ) ) {
442							itemsInArea.push( marker.templateData.itemId );
443						}
444					}
445				);
446
447				window.qodefGeoLocation.disableItemsOutOfRange( itemsInArea );
448			}
449		},
450		createAutocompletePlaces: function ( placeInputID ) {
451
452			if ( typeof google === 'object' && typeof google.maps.places === 'object' ) {
453				var autocompleteConfig = {
454					types: ['(cities)']
455				};
456
457				var autocomplete = new google.maps.places.Autocomplete( placeInputID, autocompleteConfig );
458
459				autocomplete.addListener(
460					'place_changed',
461					function () {
462						// Enable reset icon in field.
463						$( placeInputID ).next().show();
464						window.qodefGeoLocation.reset();
465						qodef.body.trigger( 'mildhill_core_trigger_after_autocomplete_places', [placeInputID] );
466					}
467				);
468			}
469		},
470	};
471
472	window.qodefGoogleMap = qodefGoogleMap;
473
474	var qodefGeoLocation = {
475		holder: '',
476		radius: '',
477		slider: '',
478		init: function ( $holder = '' ) {
479			this.holder = $holder;
480
481			if ( this.holder.length ) {
482				this.radius = this.holder.find( '.qodef-places-geo-radius' );
483				this.slider = document.getElementById( 'qodef-range-slider-id' );
484
485				if ( this.radius.length && this.slider !== null ) {
486					this.createSlider();
487				}
488			}
489		},
490		createSlider: function () {
491			noUiSlider.create(
492				this.slider,
493				{
494					connect: [true, false],
495					start: 0,
496					step: 1,
497					tooltips: true,
498					format: {
499						from: function ( value ) {
500							return parseInt( value );
501						},
502						to: function ( value ) {
503							return parseInt( value );
504						},
505					},
506					range: {
507						min: 0,
508						max: 100,
509					}
510				}
511			);
512
513			this.updateMapRadius();
514		},
515		updateMapRadius: function () {
516			var sliderEventCount = 0;
517
518			this.slider.noUiSlider.on(
519				'set',
520				function ( values ) {
521					var $geoLocation = qodefGeoLocation.radius.data( 'geo-location' );
522
523					if ( typeof $geoLocation === 'object' ) {
524						window.qodefGoogleMap.setGeoLocationRadius( $geoLocation, values, sliderEventCount > 0 );
525						sliderEventCount++;
526					}
527				}
528			);
529		},
530		reset: function () {
531
532			if ( this.slider !== null && this.radius.length && this.radius.is( ':visible' ) ) {
533				this.setRadiusVisibility( '', false );
534				this.slider.noUiSlider.reset();
535			}
536		},
537		showRangeSlider: function ( latlng, visibility ) {
538
539			if ( this.radius.length ) {
540				this.setRadiusVisibility( latlng, visibility );
541			}
542		},
543		setRadiusVisibility: function ( latlng, visibility ) {
544			this.radius.data( 'geo-location', latlng );
545
546			if ( visibility ) {
547				this.radius.show();
548			} else {
549				this.radius.hide();
550			}
551		},
552		disableItemsOutOfRange: function ( $itemsInArea ) {
553			var $holder = this.holder;
554
555			if ( $holder.length && typeof $itemsInArea === 'object' ) {
556				var $items         = $holder.find( '.qodef-grid-inner article' ),
557					$outOfRangeHolder,
558					$outOfRangeItems,
559					$inRangeHolder = $holder.find( '.qodef-grid-inner' );
560
561				if ( ! $holder.children( '.qodef-out-of-range-holder' ).length ) {
562					$holder.append( '<div class="qodef-out-of-range-holder"></div>' );
563				}
564
565				$outOfRangeHolder = $holder.children( '.qodef-out-of-range-holder' );
566				$outOfRangeItems  = $outOfRangeHolder.children( 'article' );
567
568				if ( $items.length || $outOfRangeItems.length ) {
569
570					$items.each(
571						function () {
572							var $thisItem = $( this ),
573								itemID    = $thisItem.data( 'id' );
574
575							if ( itemID !== undefined && itemID !== false ) {
576								var itemInRange = false;
577
578								$.each(
579									$itemsInArea,
580									function ( i, id ) {
581										if ( parseInt( itemID, 10 ) === id ) {
582											itemInRange = true;
583											return true;
584										}
585									}
586								);
587
588								if ( ! itemInRange ) {
589									$thisItem.appendTo( $outOfRangeHolder );
590
591									if ( $holder.hasClass( 'qodef-layout--masonry' ) ) {
592										$inRangeHolder.isotope( 'layout' );
593									}
594								}
595							}
596						}
597					);
598
599					if ( $outOfRangeItems.length ) {
600						$outOfRangeItems.each(
601							function () {
602								var $thisOutItem = $( this ),
603									outItemID    = $thisOutItem.data( 'id' ),
604									itemInRange  = false;
605
606								$.each(
607									$itemsInArea,
608									function ( i, id ) {
609										if ( parseInt( outItemID, 10 ) === id ) {
610											itemInRange = true;
611											return true;
612										}
613									}
614								);
615
616								if ( itemInRange ) {
617									$thisOutItem.appendTo( $inRangeHolder );
618
619									if ( $holder.hasClass( 'qodef-layout--masonry' ) ) {
620										$inRangeHolder.isotope( 'layout' );
621									}
622								}
623							}
624						);
625					}
626				}
627			}
628		},
629	};
630
631	window.qodefGeoLocation = qodefGeoLocation;
632
633})( jQuery );

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.