PageSourceSearch

https://www.chatou.fr/wp-content/themes/chatou/assets/libs/nova-osm/nova-osm.js?ver=1.1.0

js chatou.fr collected 2026-10-02 09:56:22 UTC 20,847 bytes, 712 lines download raw bytes

1/*
2 * Nova OSM
3 *
4 * Copyright (c) Inovagora
5 * www.inovagora.net
6 *
7 * Version: 1.3.1
8 */
9( function ( $ ) {
10
11    $.fn.osm = function ( options ) {
12
13    	this.$canvas = $( this )
14    	this.$markers = this.$canvas.find( '.marker' )
15
16
17		this.throttle = function(callback, delay) {
18			var last;
19			var timer;
20			return function () {
21				var context = this;
22				var now = +new Date();
23				var args = arguments;
24				if (last && now < last + delay) {
25					// le délai n'est pas écoulé on reset le timer
26					clearTimeout(timer);
27					timer = setTimeout(function () {
28						last = now;
29						callback.apply(context, args);
30					}, delay);
31				} else {
32					last = now;
33					callback.apply(context, args);
34				}
35			};
36		}
37
38		this.debounce = function(callback, delay){
39			var timer;
40			return function(){
41				var args = arguments;
42				var context = this;
43				clearTimeout(timer);
44				timer = setTimeout(function(){
45					callback.apply(context, args);
46				}, delay)
47			}
48		}
49
50        this.initialize = function () {
51
52			var defaults_settings = {
53	            zoom: 14,
54	            lat: '',
55	            lng: '',
56		        paddingBreakpoint: 1200,   // Point de rupture à partir duquel le padding est pris en compte (en px)
57		        padding: [40, 40, 40, 40],  // Padding interne Top, Right, Bottom, Left
58		        markerCluster: true, 		// Activer le rassemblement des points
59		        markers: {}, 				// Liste des marqueurs
60		        mapboxToken: '',            // Clé d'API Mapbox,
61		        forceTileLayer: '',         // URL d'un layeur custom
62		        disableScrollZoom: true,    // Désactive le zoom au scroll (true par défaut)
63	        };
64
65			this.settings = $.extend( {}, defaults_settings, options );
66
67			if ( typeof L.markerClusterGroup !== 'function' ) {
68				this.settings.markerCluster = false;
69			}
70
71			this.settings.padding = {
72				top: this.settings.padding[ 0 ],
73				right: this.settings.padding[ 1 ],
74				bottom: this.settings.padding[ 2 ],
75				left: this.settings.padding[ 3 ],
76			}
77
78			this.initializeMap();
79
80			return this;
81		}
82
83
84		// Initialize the map
85		this.initializeMap = function () {
86
87			// Vars
88			var self = this,
89				map,
90				promises = [];
91
92			// renderMap = L.map(this).fitWorld();
93			map = L.map( self[ 0 ] )
94
95			if ( this.settings.lat != '' && this.settings.lng != '' ) {
96				var latLng = this.newLatLng( parseFloat( this.settings.lat ), parseFloat( this.settings.lng ) );
97				map.setView( latLng, parseInt( this.settings.zoom ) );
98			}
99
100			// Disable scroll zoom
101			if ( this.settings.disableScrollZoom == true ) {
102				map.scrollWheelZoom.disable();
103			}
104			// Define Tile layer
105			// Official OSM tile layer (OSM)
106			var tileLayer = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
107
108			// Mapbox tile layer
109			if ( this.settings.mapboxToken !== '' ) {
110				var tileLayer = 'https://api.mapbox.com/styles/v1/mapbox/streets-v9/tiles/256/{z}/{x}/{y}@2x?access_token=' + this.settings.mapboxToken;
111			}
112
113			/**
114			 * Forced tile layer settings
115			 * @since    1.1.0
116			 */
117			if ( this.settings.forceTileLayer !== '' ) {
118				var tileLayer = this.settings.forceTileLayer;
119			}
120
121			// Define attributions
122			var attribution = '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>';
123
124			// Set tile layer
125			L.tileLayer( tileLayer, {
126			    attribution: attribution,
127			} ).addTo( map );
128
129	        // Add markers
130	        map.markers = [];
131	        map.bounds = [];
132
133	    	if ( self.settings.markerCluster ) {
134	        	map.clusterGroup = L.markerClusterGroup();
135	    	}
136
137	        for ( var i = 0; i < self.settings.markers.length; i++ ) {
138				promises = self.addMarker( map, self.settings.markers[i], promises );
139	        }
140
141
142	    	if ( self.settings.markerCluster ) {
143	        	map.addLayer( map.clusterGroup );
144	    	}
145
146			// Add Events on map
147	    	self.addMapEvents( map );
148
149	    	// reference
150		 	self.map = map;
151
152			if ( this.settings.lat == '' || this.settings.lng == '' ) {
153		        Promise.all( promises ).then( function ( data ) {
154				 	// center the map
155				 	self.center();
156
157				 	setTimeout( function () {
158						if ( typeof map.markers[0] != 'undefined' && map.markers.length == 1 ) {
159							map.markers[0].openPopup()
160						}
161					}, 1000 );
162		        });
163		    }
164
165		}
166
167		this.newLatLng = function ( lat, lng ) {
168			return L.latLng( parseFloat( lat ), parseFloat( lng ) );
169		},
170
171		this.getWindowSize = function () {
172			var w = window,
173			    d = document,
174			    e = d.documentElement,
175			    g = d.getElementsByTagName( 'body' )[ 0 ],
176			    x = w.innerWidth || e.clientWidth || g.clientWidth,
177			    y = w.innerHeight|| e.clientHeight|| g.clientHeight;
178			return {
179				width: x,
180				height: y
181			}
182		},
183
184		this.addMarker = function ( map, marker, promises ) {
185
186	    	var self = this,
187	    		bounds;
188
189	    	// Defaults settings for marker
190			var marker_defaults_settings = {
191				file: '',
192				lat: '',
193				lng: '',
194				html: '',
195				hoverSelector: '',
196				iconUrl: '',
197				iconActiveUrl: '',
198				shadowUrl: '',
199				shadowActiveUrl: '',
200				iconSize: [32,37],
201		        tooltip: '',				// Activate tooltip on hover if set
202		        href: '',					// Activate open window on click if not empty
203		        hrefTarget: '',				// window target option if href is not empty
204	        };
205
206			marker = $.extend( {}, marker_defaults_settings, marker );
207
208
209			// Convert string to array for icon size
210			var advancedMarkersSettings = [
211				'iconSize',
212				'iconActiveSize',
213				'shadowSize',
214				'shadowActiveSize',
215				'iconAnchor',
216				'iconActiveAnchor',
217				'shadowAnchor',
218				'shadowActiveAnchor',
219				'popupAnchor',
220				'popupActiveAnchor'
221			];
222
223			for ( var i = advancedMarkersSettings.length - 1; i >= 0; i-- ) {
224				if ( typeof marker[ advancedMarkersSettings[ i ] ] === 'string' ) {
225					marker[ advancedMarkersSettings[ i ] ] = marker[ advancedMarkersSettings[ i ] ].split( ',' )
226					for ( var o = marker[ advancedMarkersSettings[ i ] ].length - 1; o >= 0; o-- ) {
227						marker[ advancedMarkersSettings[ i ] ][ o ] = parseInt( marker[ advancedMarkersSettings[ i ] ][ o ] )
228					}
229				}
230			}
231
232
233
234			// If file not empty
235			if ( marker.file !== '' ) {
236				var extension = marker.file.split( '.' ).pop()
237
238				// if filetype is kmz
239				if ( extension == 'kmz' ) {
240
241					var kmz = marker.file;
242
243					promises.push(
244						fetch( kmz ) // On récupère le fichier kmz
245							.then( function ( response ) {
246							    if ( response.status === 200 || response.status === 0 ) {
247							        return Promise.resolve( response.blob() );
248							    } else {
249							        return Promise.reject( new Error( response.statusText ) );
250							    }
251							})
252							.then( JSZip.loadAsync )
253							.then( function ( zip ) {
254								var kml = '';
255								var zipPromises = [];
256								var imgFormats = [ 'jpg', 'jpeg', 'png', 'gif', 'svg' ];
257
258								zip.forEach( function ( relativePath, file ) {
259									var extension = relativePath.split( '.' ).pop();
260									if ( extension == 'kml' ) {
261
262										zipPromises.push(
263											zip.file( relativePath ).async( 'string' ).then( function ( kml ) {
264												var imgPromises = [];
265												var editedKml = kml;
266
267												zip.forEach( function ( relativePath, file ) {
268													var extension = relativePath.split( '.' ).pop();
269													var mimetype = '';
270
271													if ( imgFormats.indexOf( extension ) ) {
272
273														if ( extension == 'jpg' ) {
274															mimetype = 'image/jpeg';
275														} else if ( extension == 'svg' ) {
276															mimetype = 'image/svg+xml';
277														} else {
278															mimetype = 'image/' + extension;
279														}
280
281														imgPromises.push(
282															zip.file( relativePath ).async( 'base64' ).then( function ( content ) {
283																editedKml = editedKml.replace( relativePath, 'data:' + mimetype + ';base64,' + content )
284															})
285														);
286													}
287												});
288												return Promise.all( imgPromises ).then( function ( data ) {
289													// console.log( 'kmz : mise en place terminée')
290													return editedKml;
291												});
292											})
293										)
294									}
295								});
296
297								return Promise.all( zipPromises ).then( function ( data ) {
298									return data[ 0 ]
299								});
300
301							})
302							.then( function success( kml ) {
303
304								var parser = new DOMParser();
305								kml = parser.parseFromString( kml, 'text/xml');
306
307								// Replace https, www, email with link
308								for (var i = kml.getElementsByTagName('description').length - 1; i >= 0; i--) {
309									kml.getElementsByTagName('description')[i].textContent = self.linkify( kml.getElementsByTagName('description')[i].textContent )
310								}
311
312								var track = new L.KML( kml )
313
314								if ( marker.html !== '' ) {
315						    		$.each( track._layers, function(index, val) {
316						    			 val.bindPopup( marker.html );
317						    		});
318						    	}
319
320								// Add to markerCluster if enable
321					    		if ( self.settings.markerCluster ) {
322									map.clusterGroup.addLayer( track );
323					    		} else {
324					    			track.addTo( map );
325					    		}
326
327								// get bounds of layer
328								bounds = track.getBounds()
329
330								// Adding coordinates to bounds
331								map.bounds.push( bounds.getNorthEast() );
332								map.bounds.push( bounds.getSouthWest() );
333
334								// map.fitBounds( bounds )
335
336							}, function error( e ) {
337								console.log( 'Une erreur est survenue sur l\'affichage d\'un kmz' );
338							})
339					)
340
341				} else if ( extension == 'kml' ) {
342
343					promises.push(
344						fetch( marker.file )
345							.then( function ( response ) {
346								return response.text()
347							})
348							.then( function( kml ) {
349
350								var parser = new DOMParser();
351								kml = parser.parseFromString( kml, 'text/xml' );
352
353								// Replace https, www, email with link
354								for ( var i = kml.getElementsByTagName( 'description' ).length - 1; i >= 0; i-- ) {
355									kml.getElementsByTagName( 'description' )[ i ].textContent = self.linkify( kml.getElementsByTagName('description')[i].textContent )
356								}
357
358								// Create new kml overlay
359								var track = new L.KML( kml )
360
361								if ( marker.html !== '' ) {
362						    		$.each( track._layers, function(index, val) {
363						    			 val.bindPopup( marker.html );
364						    		});
365						    	}
366
367								// Add to markerCluster if enable
368					    		if ( self.settings.markerCluster ) {
369									map.clusterGroup.addLayer( track );
370					    		} else {
371					    			track.addTo( map );
372					    		}
373
374								// get bounds of layer
375								bounds = track.getBounds()
376
377								// Adding coordinates to bounds
378								map.bounds.push( bounds.getNorthEast() );
379								map.bounds.push( bounds.getSouthWest() );
380
381								// @todo: Wait for all before centering
382								// map.fitBounds( bounds )
383							})
384					)
385
386				} else if ( extension == 'geojson' ) {
387
388					promises.push(
389						fetch( marker.file )
390							.then( function ( response ) {
391								return response.json()
392							})
393							.then( function( data ) {
394
395								// Add geoJson
396								var track = new L.geoJSON( data, {
397									onEachFeature: function ( feature, layer ) {
398
399									    if ( feature.properties && ( feature.properties.name || feature.properties.nom || feature.properties.popupContent ) ) {
400											var content = '<div class="infowindow">';
401												content += '<div class="infowindow-body">';
402
403										    	if ( feature.properties.name ) {
404										    		content += '<h3 class="infowindow-title">' + feature.properties.name + '</h3>';
405										    	}
406
407										    	if ( feature.properties.nom ) {
408										    		content += '<h3 class="infowindow-title">' + feature.properties.nom + '</h3>';
409										    	}
410
411										    	if ( feature.properties.popupContent ) {
412										    		content += '<div class="infowindow-text">' + feature.properties.popupContent + '</div>';
413										    	}
414
415										    	content += '</div>';
416									    	content += '</div>';
417
418									    	if ( content !== '' ) {
419									        	layer.bindPopup( content );
420									    	}
421
422									    }
423									}
424								} )
425
426								// Add to markerCluster if enable
427					    		if ( self.settings.markerCluster ) {
428									map.clusterGroup.addLayer( track );
429					    		} else {
430					    			track.addTo( map );
431					    		}
432
433								// get bounds of layer
434								bounds = track.getBounds()
435
436								// Adding coordinates to bounds
437								map.bounds.push( bounds.getNorthEast() );
438								map.bounds.push( bounds.getSouthWest() );
439
440							})
441					)
442
443				}
444
445			}
446
447
448    		if ( marker.lat !== '' && marker.lng !== '' ) {
449
450				var latLng = self.newLatLng( parseFloat( marker.lat ), parseFloat( marker.lng ) ),
451					new_marker;
452
453
454    			if (  marker.iconUrl !== '' ) {
455
456    				var iconSettings = {
457					    iconUrl: marker.iconUrl,
458					    iconSize: marker.iconSize, // size of the icon
459					    iconAnchor: ( marker.iconAnchor != undefined && marker.iconAnchor !== '' ) ? marker.iconAnchor : [ marker.iconSize[ 0 ] / 2, marker.iconSize[ 1 ] ], // point from which the popup should open relative to the iconAnchor
460					    popupAnchor: ( marker.popupAnchor != undefined && marker.popupAnchor !== '' ) ? marker.popupAnchor : [ 0, ( marker.iconSize[ 1 ] * -1 ) ] // point from which the popup should open relative to the iconAnchor
461    				};
462
463    				if ( marker.shadowUrl != undefined && marker.shadowUrl !== '' ) {
464    					iconSettings.shadowUrl = marker.shadowUrl;
465    				}
466
467    				if ( marker.shadowSize != undefined && marker.shadowSize !== '' ) {
468    					iconSettings.shadowSize = marker.shadowSize;
469    				}
470
471    				if ( marker.shadowAnchor != undefined && marker.shadowAnchor !== '' ) {
472    					iconSettings.shadowAnchor = marker.shadowAnchor;
473    				}
474
475    				var icon = L.icon( iconSettings );
476
477    				new_marker = L.marker( latLng, { icon: icon } );
478
479    			} else {
480
481    				new_marker = L.marker( latLng );
482
483    			}
484
485				if ( marker.html !== '' ) {
486					new_marker.bindPopup( marker.html, {
487						maxWidth: 600
488					} );
489				}
490
491				if ( marker.tooltip !== '' ) {
492					new_marker.on( 'mouseover', function ( e ) {
493						self.showTooltip( new_marker, marker.tooltip )
494					} );
495				}
496
497				if ( marker.href !== '' ) {
498					new_marker.on( 'click', function () {
499						var target = '_self';
500						if ( marker.hrefTarget != '' ) {
501							target = marker.hrefTarget;
502						}
503			  			window.open( marker.href, target );
504					} );
505				}
506
507
508				if ( marker.hoverSelector !== '' &&  marker.iconActiveUrl !== '' ) {
509
510					var icon = new_marker.getIcon();
511
512					if ( $( marker.hoverSelector ).length ) {
513						$( marker.hoverSelector )
514							.on( 'mouseenter', function () {
515
516								var iconSettings = {
517								    iconUrl: marker.iconActiveUrl,
518								};
519
520
521								if ( marker.iconActiveSize != undefined && marker.iconActiveSize !== '' ) {
522									iconSettings.iconSize = marker.iconActiveSize;
523
524									if ( marker.iconActiveAnchor != undefined && marker.iconActiveAnchor !== '' ) {
525										iconSettings.iconAnchor = marker.iconActiveAnchor;
526									} else {
527										iconSettings.iconAnchor = [ marker.iconActiveSize[ 0 ] / 2, marker.iconActiveSize[ 1 ] ];
528									}
529
530									if ( marker.popupActiveAnchor != undefined && marker.popupActiveAnchor !== '' ) {
531										iconSettings.popupAnchor = marker.popupActiveAnchor;
532									} else {
533										iconSettings.popupAnchor = [ 0, ( marker.iconActiveSize[ 1 ] * -1 ) ];
534									}
535
536								} else {
537									iconSettings.iconSize = marker.iconSize;
538
539									if ( marker.iconActiveAnchor != undefined && marker.iconActiveAnchor !== '' ) {
540										iconSettings.iconAnchor = marker.iconActiveAnchor;
541									} else {
542										iconSettings.iconAnchor = [ marker.iconSize[ 0 ] / 2, marker.iconSize[ 1 ] ];
543									}
544
545									if ( marker.popupActiveAnchor != undefined && marker.popupActiveAnchor !== '' ) {
546										iconSettings.popupAnchor = marker.popupActiveAnchor;
547									} else {
548										iconSettings.popupAnchor = [ 0, ( marker.iconSize[ 1 ] * -1 ) ];
549									}
550								}
551
552
553								if ( marker.shadowActiveUrl != undefined && marker.shadowActiveUrl !== '' ) {
554									iconSettings.shadowActiveUrl = marker.shadowActiveUrl;
555								}
556
557								if ( marker.shadowActiveSize != undefined && marker.shadowActiveSize !== '' ) {
558									iconSettings.shadowActiveSize = marker.shadowActiveSize;
559								}
560
561								if ( marker.shadowActiveAnchor != undefined && marker.shadowActiveAnchor !== '' ) {
562									iconSettings.shadowActiveAnchor = marker.shadowActiveAnchor;
563								}
564
565								var activeIcon = L.icon( iconSettings );
566
567					    		new_marker.setIcon( activeIcon )
568
569					    		new_marker._icon.classList.add( 'active' )
570
571							})
572							.on( 'mouseleave', function () {
573
574					    		new_marker._icon.classList.remove( 'active' )
575
576					    		new_marker.setIcon( icon )
577
578							});
579					}
580
581				}
582
583
584				map.bounds.push( [ marker.lat, marker.lng ] );
585				map.markers.push( new_marker );
586
587
588				// Add to markerCluster if enable
589	    		if ( self.settings.markerCluster ) {
590					map.clusterGroup.addLayer( new_marker );
591	    		} else {
592	    			new_marker.addTo( map );
593	    		}
594    		}
595
596
597   			if ( typeof marker.polyline != 'undefined' && marker.polyline !== '' ) {
598    			var polyline = L.polyline( marker.polyline ).addTo( map );
599
600				// get bounds of layer
601				bounds = polyline.getBounds()
602
603				// Adding coordinates to bounds
604				map.bounds.push( bounds.getNorthEast() );
605				map.bounds.push( bounds.getSouthWest() );
606
607    		}
608
609    		if ( typeof marker.polygon != 'undefined' && marker.polygon !== '' ) {
610    			var polygon = L.polygon( marker.polygon, {color: 'red'} ).addTo( map );
611
612				// get bounds of layer
613				bounds = polygon.getBounds()
614
615				// Adding coordinates to bounds
616				map.bounds.push( bounds.getNorthEast() );
617				map.bounds.push( bounds.getSouthWest() );
618
619    		}
620
621
622    		return promises;
623
624		}
625
626		this.showTooltip = function ( marker, content ) {
627		    marker.unbindTooltip();
628		    if ( ! marker.isPopupOpen() ) {
629		    	marker.bindTooltip( content, {
630		    		direction: 'top',
631		    	} ).openTooltip();
632		    }
633		}
634
635		// Add event on map (for popup)
636		this.addMapEvents = function ( map ) {
637			var self = this;
638
639    		// Center popup on opening
640			map.on( 'popupopen', function ( e ) {
641				var px = map.project( e.popup._latlng ); // find the pixel location on the map where the popup anchor is
642				px.y -= e.popup._container.clientHeight / 2 // find the height of the popup container, divide by 2, subtract from the Y axis of marker location
643
644
645				if ( self.getWindowSize().width > parseInt( self.settings.paddingBreakpoint ) ) {
646					px.x = px.x - ( self.settings.padding.left / 2 ) + ( self.settings.padding.right / 2 )
647					px.y = px.y - ( self.settings.padding.top / 2 ) + ( self.settings.padding.bottom / 2 )
648				}
649
650				map.panTo( map.unproject( px ), { animate: true } ); // pan to new center
651			});
652
653			$( window ).on( 'resize', self.debounce( function ( e ) {
654				if ( self.settings.lat != '' && self.settings.lng != '' ) {
655					map.panTo( new L.LatLng( parseFloat( self.settings.lat ), parseFloat( self.settings.lng ) ) );
656				} else {
657					self.center();
658				}
659			}, 150 ) );
660
661		}
662
663		// Center the map on markers
664		this.center = function () {
665			var self = this;
666
667			if ( self.map.bounds.length ) {
668				bounds = new L.LatLngBounds( self.map.bounds );
669
670				if ( self.getWindowSize().width > parseInt( self.settings.paddingBreakpoint ) ) {
671					self.map.fitBounds(bounds, {
672						paddingTopLeft: [ self.settings.padding.left, self.settings.padding.top ],
673						paddingBottomRight: [ self.settings.padding.right, self.settings.padding.bottom ],
674						maxZoom: this.settings.zoom,
675					} );
676				} else {
677					self.map.fitBounds( bounds, { maxZoom : this.settings.zoom } );
678				}
679			}
680		}
681
682		// Center the map on markers
683		this.refresh = function () {
684			var self = this;
685
686			// À utiliser après le resize
687			self.map.invalidateSize( true );
688		 	// self.center();
689		}
690
691		this.linkify = function ( inputText ) {
692		    var replacedText, replacePattern1, replacePattern2, replacePattern3;
693
694		    //URLs starting with http://, https://, or ftp://
695		    replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
696		    replacedText = inputText.replace(replacePattern1, '<a href="$1" target="_blank">$1</a>');
697
698		    //URLs starting with "www." (without // before it, or it'd re-link the ones done above).
699		    replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
700		    replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>');
701
702		    //Change email addresses to mailto:: links.
703		    replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
704		    replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>');
705
706		    return replacedText;
707		}
708
709		return this.initialize();
710    };
711
712}( 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.