1'use strict'; 2/* 3 * Copyright https://github.com/divio/djangocms-googlemap 4 */ 5 6(function () { 7 var GoogleMap = (function () { 8 /** 9 * Helper function that retrieves a data-attribute value. 10 * 11 * @function getAttr 12 * @param {HTMLElement} element single document node 13 * @param {String} data data-attribute to retrieve 14 * @return {String} value returns the value from the data-attribute 15 */ 16 function getAttr(element, data) { 17 var value = element.getAttribute('data-' + data); 18 19 // true/false values need to be parsed from string to boolean 20 // from the attributes data 21 if (value === 'true') { 22 return true; 23 } else if (value === 'false') { 24 return false; 25 } 26 return value; 27 } 28 29 /** 30 * Initiates the GoogleMap plugin inside the ``djangocms-googlemap-container`` container. 31 * 32 * <div class="djangocms-googlemap js-djangocms-googlemap"> 33 * <div class="djangocms-googlemap-container js-djangocms-googlemap-container"></div> 34 * </div> 35 * 36 * @class GoogleMap 37 * @constructor 38 * @param {HTMLElement} container single document node 39 */ 40 function GoogleMapConstructor(container) { 41 this.container = container; 42 this.markers = []; 43 this.bounds = new google.maps.LatLngBounds(); 44 this.settings = { 45 zoom: parseInt(getAttr(container, 'zoom')), 46 styles: JSON.parse(getAttr(container, 'style') ||Â false), 47 zoomControl: getAttr(container, 'zoom-control'), 48 streetViewControl: getAttr(container, 'street-view-control'), 49 rotateControl: getAttr(container, 'rotate-control'), 50 scaleControl: getAttr(container, 'scale-control'), 51 fullscreenControl: getAttr(container, 'fullscreen-control'), 52 panControl: getAttr(container, 'pan-control'), 53 disableDoubleClickZoom: getAttr(container, 'double-click-zoom') === false, 54 draggable: getAttr(container, 'draggable'), 55 keyboardShortcuts: getAttr(container, 'keyboard-shortcuts'), 56 scrollwheel: getAttr(container, 'scrollwheel'), 57 mapTypeId: google.maps.MapTypeId[getAttr(container, 'map-type-control')], 58 center: { 59 lat: parseFloat(getAttr(container, 'lat')) || 0, 60 lng: parseFloat(getAttr(container, 'lng')) || 0 61 } 62 }; 63 var mapContainer = container.getElementsByClassName('js-djangocms-googlemap-container'); 64 var markers = container.getElementsByClassName('js-djangocms-googlemap-marker'); 65 var routes = container.getElementsByClassName('js-djangocms-googlemap-route'); 66 67 // create iterable arrays 68 markers = [].slice.call(markers); 69 routes = [].slice.call(routes); 70 71 // init the map 72 this.map = new google.maps.Map(mapContainer[0], this.settings); 73 74 // the markers and routes need to be loaded after the map has been 75 // initialised as we need to access ``this.map`` 76 if (markers.length) { 77 this.addMarkers(markers); 78 } 79 if (routes.length) { 80 this.addRoutes(routes); 81 } 82 } 83 84 // attach methods 85 GoogleMapConstructor.prototype = { 86 /** 87 * Processes a collection of markers and passes to ``addMarker``. 88 * 89 * @method addMarkers 90 * @param {Array} markers collection of marker nodes 91 */ 92 addMarkers: function addMarkers(markers) { 93 var list = markers.map(function (marker) { 94 return { 95 admin: getAttr(marker, 'admin'), 96 title: getAttr(marker, 'title'), 97 address: getAttr(marker, 'address'), 98 lat: getAttr(marker, 'lat'), 99 lng: getAttr(marker, 'lng'), 100 icon: getAttr(marker, 'icon'), 101 showContent: getAttr(marker, 'show-content'), 102 content: marker.innerHTML, 103 animation: google.maps.Animation.DROP 104 } 105 }, this); 106 107 list.forEach(function (marker)Â { 108 this.addMarker(marker); 109 }, this); 110 }, 111 112 /** 113 * Processes a single marker and attaches to ``this.map``. 114 * 115 * @method addMarker 116 * @param {HTMLElement} marker single marker node 117 */ 118 addMarker: function addMarker(marker) { 119 var that = this; 120 var latLng = { 121 lat: parseFloat(marker.lat), 122 lng: parseFloat(marker.lng) 123 }; 124 var geocoder = new google.maps.Geocoder(); 125 var pin; 126 var coords; 127 128 // if there is no manual latlng defined, start geocoder 129 if (!latLng.lat || !latLng.lng) { 130 geocoder.geocode({ address: marker.address }, function (results, status) { 131 if (status === google.maps.GeocoderStatus.OK) { 132 coords = results[0].geometry.location; 133 marker.lat = coords.lat(); 134 marker.lng = coords.lng(); 135 that.addMarker(marker); 136 } 137 }); 138 } else { 139 // marker data is ready, add to map 140 marker.position = latLng; 141 marker.map = this.map; 142 pin = new google.maps.Marker(marker); 143 // updated related components 144 pin.setMap(this.map); 145 this.markers.push(pin); 146 this.bounds.extend(pin.position); 147 this._addInfoWindow(pin); 148 this._addEditing(pin); 149 } 150 151 // call update every time a new marker has been added 152 if (this.map) { 153 this.update(); 154 } 155 }, 156 157 /** 158 * Update map position and bounds. 159 * 160 * @method update 161 */
162 update: function update() { 163 google.maps.event.addListenerOnce(this.map, 'bounds_changed', 164 function () { 165 if (this.map.getZoom() > this.settings.zoom) { 166 this.map.setZoom(this.settings.zoom); 167 } 168 }.bind(this)); 169 this.map.fitBounds(this.bounds); 170 }, 171 172 /** 173 * Processes a collection of routes and passes to ``addRoute``. 174 * Only one route can be displayed by the default Google Maps 175 * interface. Feel free to use this functionality to enhance the 176 * default UI with more route options. 177 * 178 * @method addRoutes 179 * @param {Array} routes collection of route nodes 180 */ 181 addRoutes: function addRoutes(routes) { 182 routes.forEach(function (route) { 183 this.addRoute(route); 184 }, this); 185 }, 186 187 /** 188 * Processes a single route and attaches to ``this.map``. 189 * 190 * @method addRoute 191 * @param {HTMLElement} route single route node 192 */ 193 addRoute: function addRoute(route) { 194 var that = this; 195 var el = 'js-djangocms-googlemap-direction'; 196 var directions = route.getElementsByClassName(el); 197 var title = getAttr(route, 'title'); 198 var request = { 199 origin: getAttr(route, 'origin'), 200 destination: getAttr(route, 'destination'), 201 travelMode: getAttr(route, 'travel-mode') 202 }; 203 204 this.directionsDisplay = new google.maps.DirectionsRenderer(); 205 this.directionsService = new google.maps.DirectionsService(); 206 207 this.directionsDisplay.setPanel(directions[0]); 208 this.directionsDisplay.setMap(this.map); 209 210 // if origin is not provided ask for your location 211 if (!request.origin && 'geolocation' in navigator) { 212 navigator.geolocation.getCurrentPosition(function(position) { 213 request.origin = position.coords.latitude + ',' + position.coords.longitude; 214 that.setDirection(request); 215 }); 216 } else { 217 that.setDirection(request); 218 } 219 }, 220 221 /** 222 * Adds the direction to the ``djangocms-googlemap-direction``dom node. 223 * 224 * @method setDirection 225 * @param {Object} request request to be passed to the ``directionsService`` 226 */ 227 setDirection: function setDirection(request) { 228 var that = this; 229 230 this.directionsService.route(request, function(result, status) { 231 if (status === 'OK') { 232 that.directionsDisplay.setDirections(result); 233 } 234 }); 235 }, 236 237 /** 238 * Attaches the GoogleMap info window to the marker pin. 239 * 240 * @method _addInfoWindow 241 * @private 242 * @param {Object} marker google map marker node 243 */ 244 _addInfoWindow: function _addInfoWindow(marker) { 245 if (marker.content.trim() === '') { 246 return false; 247 } 248 var that = this; 249 var infoWindow = new google.maps.InfoWindow({ 250 disableAutoPan: true, 251 content: marker.content 252 }); 253 254 google.maps.event.addListener(marker, 'click', function () { 255 infoWindow.open(that.map, marker); 256 marker.setAnimation(google.maps.Animation.BOUNCE); 257 // stop animation after a certain timeframe 258 setTimeout(function () { 259 marker.setAnimation(null); 260 }, 750); 261 }); 262 263 if (marker.showContent) { 264 infoWindow.open(this.map, marker); 265 } 266 }, 267 268 /** 269 * Adds double-clock to edit on the google map pin. 270 * 271 * @method _addEditing 272 * @private 273 * @param {Object} marker google map marker node 274 */ 275 _addEditing: function _addEditing(marker)Â { 276 // attach double-click to edit for markers 277 if (window.CMS && window.CMS.Modal) { 278 google.maps.event.addListener(marker, 'dblclick', function (e) { 279 // the native event in google.maps is stored in e.xa 280 // there's no need to continue if google decides to rename it 281 if (!e.xa) { 282 return false;
283 } 284 e.xa.stopPropagation(); 285 286 var modal = new CMS.Modal(); 287 288 modal.open({ 289 url: marker.admin 290 }); 291 }); 292 } 293 } 294 }; 295 296 return GoogleMapConstructor; 297 })(); 298 299 // make sure google maps is loaded after our dom is ready 300 window.addEventListener('load', function () { 301 var elements = document.getElementsByClassName('js-djangocms-googlemap'); 302 303 elements = [].slice.call(elements); 304 elements.forEach(function (element) { 305 new GoogleMap(element); 306 }, this); 307 }); 308})();
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.