1/** 2 * @file 3 * Initiates map(s) for the Styled Google Map module. 4 * 5 * A single or multiple Styled Google Maps will be initiated. 6 * Drupal behaviors are used to make sure ajax called map(s) are correctly 7 * loaded. 8 */ 9 10(function (Drupal) { 11 12 /** 13 * Calculates the route and displays it on the map. 14 */ 15 function calculateAndDisplayRoute(directionsService, directionsDisplay, map_id, destination) { 16 var selectedMode = document.getElementById('getting_directions_mode-' + map_id).value; 17 var address = document.getElementById('getting_directions_address-' + map_id).value; 18 if (document.getElementById('getting_directions_location-' + map_id).checked) { 19 if (typeof window.drupalSettings.user_current_location === 'object' && typeof window.drupalSettings.user_current_location.getPosition === 'function') { 20 address = window.drupalSettings.user_current_location.getPosition(); 21 } 22 } 23 directionsService.route({ 24 origin: address, 25 destination: {lat: destination.lat, lng: destination.lon}, 26 travelMode: google.maps.TravelMode[selectedMode] 27 }, function(response, status) { 28 if (status === 'OK') { 29 directionsDisplay.setDirections(response); 30 } else { 31 const messages = new Drupal.Message(); 32 var message = Drupal.t('Directions request failed due to @status', {'@status': status}); 33 if (typeof Drupal.Message !== 'undefined') { 34 messages.add(message, {type: 'error'}); 35 } else { 36 window.alert(message); 37 } 38 } 39 }); 40 41 } 42 43 /** 44 * Behavior to display the map. 45 * 46 * @type {{attach: Drupal.behaviors.styled_google_maps.attach}} 47 */ 48 Drupal.behaviors.styled_google_maps = { 49 attach: function (context, settings) { 50 var maps = settings.styled_google_map; 51 var markers = []; 52 // There can be multiple maps on a page, let's iterate over them. 53 for (var i in maps) { 54 var current_map = settings.maps['id' + maps[i]]; 55 var map_id = current_map.id; 56 var map_container = document.getElementById(map_id); 57 // Continue in case we find the map object on the current page. 58 if (map_container) { 59 // Declare the map locations, style, bounds, settings and types. 60 var map_locations = current_map.locations; 61 var map_settings = current_map.settings; 62 var bounds = new google.maps.LatLngBounds(); 63 var map_types = { 64 'ROADMAP': google.maps.MapTypeId.ROADMAP, 65 'SATELLITE': google.maps.MapTypeId.SATELLITE, 66 'HYBRID': google.maps.MapTypeId.HYBRID, 67 'TERRAIN': google.maps.MapTypeId.TERRAIN 68 }; 69 var map_style = (map_settings.style.style !== '' ? map_settings.style.style : '[]'); 70 71 // Set the map inline style width and height. 72 map_container.style.width = current_map.settings.width; 73 map_container.style.height = current_map.settings.height; 74 75 // Disable scrolling on screens smaller than 480 pixels. 76 // TODO: This is deprecated and should be removed due to gesture handling. 77 map_settings.draggable = document.documentElement.clientWidth > 480 ? map_settings.draggable : map_settings.mobile_draggable; 78 79 // Declare and initialize the base settings of the Google Map. 80 var init_map = { 81 gestureHandling: map_settings.gestureHandling, 82 zoom: parseInt(map_settings.zoom.default), 83 mapTypeId: map_types[map_settings.style.maptype], 84 disableDefaultUI: !map_settings.ui, 85 maxZoom: parseInt(map_settings.zoom.max), 86 minZoom: parseInt(map_settings.zoom.min), 87 styles: JSON.parse(map_style), 88 mapTypeControl: map_settings.maptypecontrol, 89 scaleControl: map_settings.scalecontrol, 90 rotateControl: map_settings.rotatecontrol, 91 streetViewControl: map_settings.streetviewcontrol, 92 zoomControl: map_settings.zoomcontrol, 93 fullscreenControl: map_settings.fullscreen, 94 draggable: map_settings.draggable 95 }; 96 var map = new google.maps.Map(map_container, init_map); 97 98 var heatmap = {}; 99 100 // Additional functionality to enable a heatmap. 101 if (typeof map_settings.heat_map != 'undefined' && map_settings.heat_map.heatmap_enabled) { 102 var heatmap_data = []; 103 for (var k = 0; k < map_settings.heat_map.data.length; k++) { 104 var heatmap_item = { 105 location: new google.maps.LatLng(map_settings.heat_map.data[k].lat, map_settings.heat_map.data[k].lon), 106 weight: map_settings.heat_map.data[k].weight, 107 }; 108 heatmap_data.push(heatmap_item); 109 } 110 heatmap = new google.maps.visualization.HeatmapLayer({ 111 data: heatmap_data, 112 gradient: map_settings.heat_map.gradient, 113 opacity: map_settings.heat_map.opacity, 114 maxIntensity: map_settings.heat_map.maxIntensity, 115 dissipating: map_settings.heat_map.dissipating, 116 radius: map_settings.heat_map.radius 117 });
118 heatmap.setMap(map); 119 } 120 else { 121 // Declare the infoBubble (popup) settings. 122 var infoBubble = new InfoBubble({ 123 shadowStyle: parseInt(map_settings.popup.shadow_style), 124 padding: parseInt(map_settings.popup.padding), 125 borderRadius: parseInt(map_settings.popup.border_radius), 126 borderWidth: parseInt(map_settings.popup.border_width), 127 borderColor: map_settings.popup.border_color, 128 backgroundColor: map_settings.popup.background_color, 129 minWidth: map_settings.popup.min_width, 130 maxWidth: map_settings.popup.max_width, 131 maxHeight: map_settings.popup.min_height, 132 minHeight: map_settings.popup.max_height, 133 arrowStyle: parseInt(map_settings.popup.arrow_style), 134 arrowSize: parseInt(map_settings.popup.arrow_size), 135 arrowPosition: parseInt(map_settings.popup.arrow_position), 136 disableAutoPan: parseInt(map_settings.popup.disable_autopan), 137 disableAnimation: parseInt(map_settings.popup.disable_animation), 138 hideCloseButton: parseInt(map_settings.popup.hide_close_button), 139 backgroundClassName: map_settings.popup.classes.background 140 }); 141 142 // Set extra custom classes for easy styling. 143 if (typeof map_settings.popup.close_button_source != 'undefined' && map_settings.popup.close_button_source) { 144 infoBubble.close_.src = map_settings.popup.close_button_source; 145 } 146 infoBubble.contentContainer_.className = map_settings.popup.classes.container; 147 infoBubble.arrow_.className = map_settings.popup.classes.arrow; 148 infoBubble.arrowOuter_.className = map_settings.popup.classes.arrow_outer; 149 infoBubble.arrowInner_.className = map_settings.popup.classes.arrow_inner; 150 151 // Loop each location (pin) our map contains. 152 for (var j in map_locations) { 153 // Set the image icon of our pin as well as the image for its active state. 154 var icon = map_locations[j].pin; 155 if (map_settings.style.pin_width !== '' && map_settings.style.pin_height !== '') { 156 icon = { 157 url: map_locations[j].pin, 158 scaledSize: new google.maps.Size(map_settings.style.pin_width, map_settings.style.pin_height) 159 } 160 } 161 if (typeof map_locations[j].active_pin !== 'undefined') { 162 var active_icon = map_locations[j].active_pin; 163 if (map_settings.style.pin_width !== '' && map_settings.style.pin_height !== '') { 164 active_icon = { 165 url: map_locations[j].active_pin, 166 scaledSize: new google.maps.Size(map_settings.style.pin_width, map_settings.style.pin_height) 167 } 168 } 169 } 170 else { 171 active_icon = icon; 172 } 173 // Create the Marker (pin) object with all its information and add it to the Markers array. 174 var marker = new google.maps.Marker({ 175 position: new google.maps.LatLng(map_locations[j].lat, map_locations[j].lon), 176 map: map, 177 html: map_locations[j].popup, 178 label: map_locations[j].marker_label, 179 icon: icon, 180 original_icon: icon, 181 active_icon: active_icon, 182 category: map_locations[j].category 183 }); 184 markers.push(marker); 185 186 // Handle all popup functionality. 187 if (map_locations[j].popup) { 188 // Set the default open/close state of the popup. 189 if (typeof map_settings.popup.default_state != 'undefined' && map_settings.popup.default_state == 1 && j == 0) { 190 infoBubble.setContent(marker.html); 191 infoBubble.bubble_.className = 'sgmpopup sgmpopup-' + marker.category; 192 marker.setZIndex(1); 193 marker.setIcon(marker.active_icon); 194 infoBubble.open(map, marker); 195 } 196 var open_event = map_settings.popup.open_event; 197 // Event handler when clicking a marker (pin). 198 google.maps.event.addListener(marker, open_event, (function (map) { 199 return function () { 200 if (infoBubble.isOpen() && map_settings.popup.second_click == 1 && this.getZIndex()) { 201 infoBubble.close(map, this); 202 this.setIcon(this.original_icon); 203 this.setZIndex(0); 204 } 205 else { 206 infoBubble.setContent(this.html); 207 for (var i = 0; i < markers.length; i++) { 208 markers[i].setIcon(markers[i].original_icon); 209 infoBubble.bubble_.className = 'sgmpopup sgmpopup-' + markers[i].category; 210 markers[i].setZIndex(0); 211 } 212 this.setIcon(this.active_icon); 213 this.setZIndex(1); 214 infoBubble.open(map, this); 215 } 216 }; 217 218 }(map))); 219 } 220 bounds.extend(marker.getPosition()); 221 } 222 223 var markerCluster = {}; 224 225 // Additional functionality to enable clustering of pins. 226 if (typeof map_settings.cluster != 'undefined' && map_settings.cluster.cluster_enabled) { 227 var clusterStyles = [ 228 { 229 textColor: map_settings.cluster.text_color, 230 url: map_settings.cluster.pin_image, 231 height: parseInt(map_settings.cluster.height), 232 width: parseInt(map_settings.cluster.width), 233 textSize: parseInt(map_settings.cluster.text_size) 234 } 235 ]; 236 var mcOptions = { 237 gridSize: 60, 238 zoomOnClick: map_settings.cluster.zoomOnClick, 239 maxZoom: map_settings.zoom.max - 1, 240 styles: clusterStyles, 241 minimumClusterSize: parseInt(map_settings.cluster.min_size), 242 }; 243 // Handle clustering of the map. 244 if (typeof map_settings.cluster != 'undefined' && map_settings.cluster.cluster_enabled) { 245 markerCluster = new MarkerClusterer(map, markers, mcOptions); 246 markerCluster.setMaxZoom(mcOptions.maxZoom); 247 } 248 } 249 250 var markerSpiderfier = {}; 251 252 // Additional functionality to spiderify multiple close pins. 253 if (typeof map_settings.spider != 'undefined' && map_settings.spider.spider_enabled) { 254 var spidericonSize = new google.maps.Size(map_settings.spider.width, map_settings.spider.height); 255 var spiderConfig = { 256 markersWontMove: map_settings.spider.markers_wont_move, 257 markersWontHide: map_settings.spider.markers_wont_hide, 258 basicFormatEvents: map_settings.spider.basic_format_events, 259 keepSpiderfied: map_settings.spider.keep_spiderfied, 260 nearbyDistance: map_settings.spider.nearby_distance, 261 circleSpiralSwitchover: map_settings.spider.circle_spiral_switchover, 262 legWeight: map_settings.spider.leg_weight, 263 spiralFootSeparation: map_settings.spider.spiralFootSeparation, 264 circleFootSeparation: map_settings.spider.circleFootSeparation, 265 icon: { 266 url: map_settings.spider.pin_image, 267 size: spidericonSize, 268 scaledSize: spidericonSize 269 } 270 }; 271 // Init OverlappingMarkerSpiderfier with map. 272 markerSpiderfier = new OverlappingMarkerSpiderfier(map, spiderConfig); 273 for (var m in markers ) { 274 // Add the Marker to OverlappingMarkerSpiderfier. 275 markerSpiderfier.addMarker(markers[m]); 276 } 277 // Set original pins when spiderify. 278 markerSpiderfier.addListener('spiderfy', function (markers) { 279 for (var i = 0; i < markers.length; i++) { 280 markers[i].setIcon(markers[i].original_icon); 281 markers[i].setZIndex(1); 282 } 283 }); 284 // Set pin icon when unspiderfy. 285 markerSpiderfier.addListener('unspiderfy', function (markers) { 286 for (var i = 0; i < markers.length; i++) { 287 markers[i].setIcon(spiderConfig.icon); 288 infoBubble.close(); 289 } 290 }); 291 google.maps.event.addListener(map, 'idle', function (marker) { 292 // Change spiderable markers to plus sign markers 293 // and subsequently any other zoom/idle. 294 var spidered = markerSpiderfier.markersNearAnyOtherMar
294ker(); 295 for (var i = 0; i < spidered.length; i++) { 296 // Set spidered icon when inside cluster. 297 spidered[i].setIcon(spiderConfig.icon); 298 spidered[i].setZIndex(0); 299 } 300 }); 301 // triggering drag event so that the spider pin icons get enabled again 302 google.maps.event.addListener(map, 'dragend', function() { 303 google.maps.event.trigger(map, 'click'); 304 }); 305 } 306 307 } 308 309 // Add controls that are configured for views. 310 var map_view = map_container.closest('.view'); 311 if (map_view) { 312 // Try to find the map controls. 313 var custom_controls = map_view.getElementsByClassName('google-map-control'); 314 if (custom_controls) { 315 // Add controls to the positions that are provided. 316 for (var index = 0; index < custom_controls.length; index++) { 317 var position = custom_controls[index].getAttribute('data-position'); 318 var id = custom_controls[index].getAttribute('id'); 319 map.controls[google.maps.ControlPosition[position]].push(document.getElementById(id)); 320 } 321 } 322 } 323 324 // Handle centering of the map. 325 if (map_settings.map_center && map_settings.map_center.center_coordinates) { 326 if (!isNaN(parseInt(map_settings.map_center.center_coordinates.lat)) && !isNaN(parseInt(map_settings.map_center.center_coordinates.lon))) { 327 var map_center = new google.maps.LatLng(map_settings.map_center.center_coordinates.lat, map_settings.map_center.center_coordinates.lon); 328 bounds.extend(map_center); 329 map.setCenter(map_center); 330 } 331 } 332 else { 333 map.setCenter(bounds.getCenter()); 334 } 335 336 // Process settings of the directions plugin. 337 if (typeof map_settings.directions != 'undefined' && map_settings.directions.enabled) { 338 var directionsDisplay = new google.maps.DirectionsRenderer; 339 var directionsService = new google.maps.DirectionsService; 340 directionsDisplay.setMap(map); 341 if (map_settings.directions.steps) { 342 var route_details_id = 'steps-' + maps[i]; 343 directionsDisplay.setPanel(document.getElementById(route_details_id)); 344 } 345 var button_id = 'find-directions-' + maps[i]; 346 347 var current_location = 'getting_directions_location-' + maps[i]; 348 if (document.location.protocol === 'https:') { 349 document.addEventListener('geolocation_error', function(error){ 350 document.getElementById('directions' + maps[i]).getElementsByClassName('error-message').item(0).textContent = error.code; 351 }); 352 document.getElementById(current_location).addEventListener('change', function () { 353 var address = 'getting_directions_address-' + maps[i]; 354 if (this.checked) { 355 settings.user_current_location = settings.user_current_location || false; 356 var user_location = new GeolocationMarker(map); 357 if (user_location) { 358 settings.user_current_location = user_location; 359 document.getElementById(address).style.display = 'none'; 360 } 361 } else { 362 document.getElementById(address).style.display = 'block'; 363 } 364 }); 365 } else { 366 document.getElementById(current_location).parentNode.style.display = 'none'; 367 } 368 document.getElementById(button_id).addEventListener('click', function() { 369 calculateAndDisplayRoute(directionsService, directionsDisplay, maps[i], map_locations[0]); 370 }); 371 } 372 373 // This is needed to set the zoom after fitbounds. 374 google.maps.event.addListener(map, 'zoom_changed', function () { 375 var zoomChangeBoundsListener = 376 google.maps.event.addListener(map, 'bounds_changed', function (event) { 377 var current_zoom = this.getZoom(); 378 if (current_zoom > parseInt(map_settings.zoom.default) && map.initialZoom == true) { 379 // Change max/min zoom here. 380 this.setZoom(parseInt(map_settings.zoom.default) - 1); 381 } 382 map.initialZoom = false; 383 google.maps.event.removeListener(zoomChangeBoundsListener); 384 }); 385 }); 386 387 map.initialZoom = true; 388 map.fitBounds(bounds); 389 settings.initialized_styles_google_maps = settings.initialized_styles_google_maps || []; 390 settings.initialized_styles_google_maps[maps[i]] = {map: map, markers: markers, cluster: markerCluster, spider: markerSpiderfier, heatmap: heatmap}; 391 } 392 } 393 // Prevents piling up generated map ids. 394 settings.styled_google_map = []; 395 } 396 }; 397 398})(Drupal); 399;
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.