1/** 2 * UpSolution Element: Leaflet Maps 3 * 4 * Used for [us_gmaps] shortcode 5 * 6 * Leaflet JS Official Docs https://leafletjs.com/ 7 * @requires jQuery 8 */ 9! function( $, undefined ) { 10 "use strict"; 11 12 // Private variables that are used only in the context of this function, it is necessary to optimize the code 13 var _document = document, 14 _window = window, 15 _null = null; 16 17 // Check for is set objects 18 _window.$us = _window.$us || {}; 19 20 /** 21 * @type {RegExp} Regular expression to check or extract coordinates. 22 */ 23 const _REGEXP_EXTRACT_COORDINATES_ = /^(-?[\d\.]+),(-?[\d\.]+)$/; 24 25 /** 26 * @class wLmaps 27 * @param {Node} container The node container 28 * @param {{}} options The map options 29 */ 30 $us.wLmaps = function( container, options ) { 31 var self = this; 32 33 // Elements 34 self.$container = $( container ); 35 36 // Prevent double init 37 if ( self.$container.data( '_inited' ) ) { 38 return; 39 } 40 self.$container.data( '_inited', 1 ); 41 42 // Variables 43 self._mapInstance = _null; 44 self.cookieName = self.$container.data( 'cookie-name' ); 45 self.options = options || {}; 46 47 /** 48 * @var {{}} Bindable events 49 */ 50 self._events = { 51 confirmInit: self._confirmInit.bind( self ), 52 redraw: self._redraw.bind( self ) 53 }; 54 55 // Confirm initialization 56 if ( self.cookieName ) { 57 self.$container.on( 'click', '.action_confirm_load', self._events.confirmInit ); 58 return; 59 } 60 61 self._init(); 62 }; 63 64 /** 65 * Export API 66 */ 67 $.extend( $us.wLmaps.prototype, { 68 69 /** 70 * Map initialization handler after confirmation 71 * 72 * @event handler 73 */ 74 _confirmInit: function() { 75 var self = this; 76 77 // Save permission to loading maps in cookies 78 if ( $( 'input[name^=' + self.cookieName + ']:checked', self.$container ).length ) { 79 $ush.setCookie( self.cookieName, /* value */1, /* days */365 ); 80 } 81 82 self.$container 83 // Add map html markup to element 84 .html( $ush.base64Decode( $( 'script[type="text/template"]', self.$container ).text() ) ) 85 .removeAttr( 'data-cookie-name' ); 86 87 self._init(); 88 }, 89 90 /** 91 * Map the init 92 */ 93 _init: function() { 94 var self = this; 95 96 // Get map options 97 var $mapJson = $( '.w-map-json', self.$container ); 98 if ( $mapJson.is( '[onclick]' ) ) { 99 $.extend( self.options, $mapJson[0].onclick() || {} ); 100 $mapJson.remove(); 101 } 102 103 $us.$canvas.on( 'contentChange', self._events.redraw ); 104 self._beforeRender(); 105 }, 106 107 /** 108 * Get data before rendering the map 109 */ 110 _beforeRender: function() { 111 var self = this, 112 address = ( '' + self.options.address ), 113 matches = $ush.removeSpaces( address ) // Remove all spaces and tabs 114 .match( _REGEXP_EXTRACT_COORDINATES_ ); // Example: -0.00000,0.00000 115 116 if ( matches ) { 117 self.center = [ matches[1], matches[2] ]; 118 self._render(); 119 } else { 120 self._geocoder( address ); 121 } 122 }, 123 124 /** 125 * Map render 126 */ 127 _render: function() { 128 var self = this, 129 mapId = self.$container.attr( 'id' ), 130 // Basic Map setup 131 lmapsOptions = { 132 center: self.center, 133 zoom: self.options.zoom 134 }; 135 136 if ( self.options.hideControls ) { 137 lmapsOptions.zoomControl = false; // Hide zooming buttons 138 } 139 if ( self.options.disableZoom ) { 140 lmapsOptions.scrollWheelZoom = false; // Disable Mouse Zooming 141 } 142 143 // Create an instance of the L.map class 144 self._mapInstance = L.map( mapId, lmapsOptions ); 145 146 // Add a Raster layer to the map. Copyright layer required by OSM https://www.openstreetmap.org/copyright 147 L.tileLayer( 148 self.options.style, 149 { 150 attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' 151 } 152 ).addTo( self._mapInstance ); 153 154 // Add all markers to the map 155 self._renderMarkers(); 156 157 if ( 158 $us.usbPreview() 159 || self.options.disableDragging && ! $us.$html.hasClass( 'no-touch' ) 160 ) { 161 // Disable dragging on mobiles 162 self._mapInstance.dragging.disable(); 163 } 164 }, 165 166 /** 167 * Set a markers at an address 168 * 169 * @param {String} text The request text 170 * @param {{}} markerOptions The marker options 171 * @param {String} popup The popup 172 */ 173 _geocoder: function( text, markerOptions, popup ) { 174 var self = this, 175 osmUrl = 'https://nominatim.openstreetmap.org/search?format=json&limit=1&q=' + encodeURI( text ); 176 177 // Get coordinates from the search engine
178 $.getJSON( osmUrl, /* First Success */$.noop ).done( function( json ) { 179 if ( ! json.length ) { 180 // Return in case no coordinates were found 181 return; 182 } 183 // Get Coordinates 184 var boundingBox = json[0].boundingbox; 185 if ( ! markerOptions ) { 186 // Get coordinates to set map center and add 1st marker 187 self.center = [ boundingBox[/* latitude */1], boundingBox[/* longitude */3] ]; 188 self._render(); 189 } else { 190 self.marker = L 191 .marker( [ boundingBox[/* latitude */1], boundingBox[/* longitude */3] ], markerOptions ) 192 .addTo( self._mapInstance ); 193 // Add marker popups 194 if ( popup ) { 195 self.marker.bindPopup( popup ); 196 } 197 } 198 }); 199 }, 200 201 /** 202 * Map redraw 203 * 204 * @event handler 205 */ 206 _redraw: function() { 207 var self = this; 208 if ( ! self._mapInstance || self.$container.is( ':hidden' ) ) { 209 return; 210 } 211 $ush.timeout( self._mapInstance.invalidateSize.bind( self._mapInstance, /* animate */true ), 100 ); 212 }, 213 214 /** 215 * Add all markers to the map 216 */ 217 _renderMarkers: function() { 218 var self = this; 219 if ( ! self.options.markers.length ) { 220 return; 221 } 222 // Add markers 223 var mainOptions = {}; 224 for ( var i = 0; i < self.options.markers.length; i++ ) { 225 var item = self.options.markers[ i ]; 226 if ( i == 0 ) { 227 // Handle first marker separately 228 if ( self.options.icon != _null ) { 229 var mainMarkerSizes = self.options.icon.size[0], 230 markerImg = L.icon( { 231 iconUrl: self.options.icon.url, 232 iconSize: mainMarkerSizes, 233 } ); 234 // Set icon offset 235 markerImg.options.iconAnchor = [ mainMarkerSizes / 2, mainMarkerSizes ]; 236 // Set popup offset 237 markerImg.options.popupAnchor = [ 0, - mainMarkerSizes ]; 238 // Push Marker Icons to Options object 239 mainOptions.icon = markerImg; 240 } 241 // Add main marker with calculated coordinates 242 var marker = L.marker( self.center, mainOptions ).addTo( self._mapInstance ); 243 // Add a popup to the 1st marker 244 if ( item.html ) { 245 if ( item.infowindow ) { 246 marker.bindPopup( item.html ).openPopup(); 247 } else { 248 marker.bindPopup( item.html ); 249 } 250 } 251 } 252 else { 253 var markerOptions = {}; 254 // All markers but first 255 if ( item.marker_img != _null ) { 256 var markerSizes = item.marker_size[0], 257 markerImg = L.icon( { 258 iconUrl: item.marker_img[0], 259 iconSize: markerSizes, 260 } ); 261 // Set icon offset 262 markerImg.options.iconAnchor = [ markerSizes / 2, markerSizes ]; 263 // Set popup offset 264 markerImg.options.popupAnchor = [ 0, - markerSizes ]; 265 markerOptions.icon = markerImg; 266 } else { 267 markerOptions = mainOptions; 268 } 269 var matches = $ush.removeSpaces( item.address ) // Remove all spaces and tabs 270 .match( _REGEXP_EXTRACT_COORDINATES_ ); 271 if ( matches ) { 272 self.marker = L.marker( [ matches[/* latitude */1], matches[/* longitude */2] ], markerOptions ).addTo( self._mapInstance ); 273 if ( item.html ) { 274 // Add a popup if marker has some text 275 self.marker.bindPopup( item.html ) 276 } 277 } else { 278 self._geocoder( item.address, markerOptions, item.html ); 279 } 280 } 281 } 282 } 283 284 } ); 285 286 /** 287 * Wrapper for jQuery 288 * 289 * @param {{}} options The map options 290 * @return self 291 */ 292 $.fn.wLmaps = function( options ) { 293 options = options || {}; 294 return this.each( function() { 295 this._wLmaps = new $us.wLmaps( this, $ush.clone( options ) ); 296 } ); 297 }; 298 299 // Initializing an element after loading a document 300 $( function() { 301 $( '.w-map.provider_osm' ).wLmaps(); 302 } ); 303 304}( 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.