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 showContent: getAttr(marker, 'show-content'), 101 content: marker.innerHTML, 102 animation: google.maps.Animation.DROP 103 } 104 }, this); 105 106 list.forEach(function (marker)Â { 107 this.addMarker(marker); 108 }, this); 109 }, 110 111 /** 112 * Processes a single marker and attaches to ``this.map``. 113 * 114 * @method addMarker 115 * @param {HTMLElement} marker single marker node 116 */ 117 addMarker: function addMarker(marker) { 118 var that = this; 119 var latLng = { 120 lat: parseFloat(marker.lat), 121 lng: parseFloat(marker.lng) 122 }; 123 var geocoder = new google.maps.Geocoder(); 124 var pin; 125 var coords; 126 127 // if there is no manual latlng defined, start geocoder 128 if (!latLng.lat || !latLng.lng) { 129 geocoder.geocode({ address: marker.address }, function (results, status) { 130 if (status === google.maps.GeocoderStatus.OK) { 131 coords = results[0].geometry.location; 132 marker.lat = coords.lat(); 133 marker.lng = coords.lng(); 134 that.addMarker(marker); 135 } 136 }); 137 } else { 138 // marker data is ready, add to map 139 marker.position = latLng; 140 marker.map = this.map; 141 pin = new google.maps.Marker(marker); 142 // updated related components 143 pin.setMap(this.map); 144 this.markers.push(pin); 145 this.bounds.extend(pin.position); 146 this._addInfoWindow(pin); 147 this._addEditing(pin); 148 } 149 150 // call update every time a new marker has been added 151 if (this.map) { 152 this.update(); 153 } 154 }, 155 156 /** 157 * Update map position and bounds. 158 * 159 * @method update 160 */
161 update: function update() { 162 this.map.fitBounds(this.bounds); 163 if (this.map.getZoom() > this.settings.zoom) { 164 this.map.setZoom(this.settings.zoom); 165 } 166 }, 167 168 /** 169 * Processes a collection of routes and passes to ``addRoute``. 170 * Only one route can be displayed by the default Google Maps 171 * interface. Feel free to use this functionality to enhance the 172 * default UI with more route options. 173 * 174 * @method addRoutes 175 * @param {Array} routes collection of route nodes 176 */ 177 addRoutes: function addRoutes(routes) { 178 routes.forEach(function (route) { 179 this.addRoute(route); 180 }, this); 181 }, 182 183 /** 184 * Processes a single route and attaches to ``this.map``. 185 * 186 * @method addRoute 187 * @param {HTMLElement} route single route node 188 */ 189 addRoute: function addRoute(route) { 190 var that = this; 191 var el = 'js-djangocms-googlemap-direction'; 192 var directions = route.getElementsByClassName(el); 193 var title = getAttr(route, 'title'); 194 var request = { 195 origin: getAttr(route, 'origin'), 196 destination: getAttr(route, 'destination'), 197 travelMode: getAttr(route, 'travel-mode') 198 }; 199 200 this.directionsDisplay = new google.maps.DirectionsRenderer(); 201 this.directionsService = new google.maps.DirectionsService(); 202 203 this.directionsDisplay.setPanel(directions[0]); 204 this.directionsDisplay.setMap(this.map); 205 206 // if origin is not provided ask for your location 207 if (!request.origin && 'geolocation' in navigator) { 208 navigator.geolocation.getCurrentPosition(function(position) { 209 request.origin = position.coords.latitude + ',' + position.coords.longitude; 210 that.setDirection(request); 211 }); 212 } else { 213 that.setDirection(request); 214 } 215 }, 216 217 /** 218 * Adds the direction to the ``djangocms-googlemap-direction``dom node. 219 * 220 * @method setDirection 221 * @param {Object} request request to be passed to the ``directionsService`` 222 */ 223 setDirection: function setDirection(request) { 224 var that = this; 225 226 this.directionsService.route(request, function(result, status) { 227 if (status === 'OK') { 228 that.directionsDisplay.setDirections(result); 229 } 230 }); 231 }, 232 233 /** 234 * Attaches the GoogleMap info window to the marker pin. 235 * 236 * @method _addInfoWindow 237 * @private 238 * @param {Object} marker google map marker node 239 */ 240 _addInfoWindow: function _addInfoWindow(marker) { 241 if (marker.content.trim() === '') { 242 return false; 243 } 244 var that = this; 245 var infoWindow = new google.maps.InfoWindow({ 246 disableAutoPan: true, 247 content: marker.content 248 }); 249 250 google.maps.event.addListener(marker, 'click', function () { 251 infoWindow.open(that.map, marker); 252 marker.setAnimation(google.maps.Animation.BOUNCE); 253 // stop animation after a certain timeframe 254 setTimeout(function () { 255 marker.setAnimation(null); 256 }, 750); 257 }); 258 259 if (marker.showContent) { 260 infoWindow.open(this.map, marker); 261 } 262 }, 263 264 /** 265 * Adds double-clock to edit on the google map pin. 266 * 267 * @method _addEditing 268 * @private 269 * @param {Object} marker google map marker node 270 */ 271 _addEditing: function _addEditing(marker)Â { 272 // attach double-click to edit for markers 273 if (window.CMS && window.CMS.Modal) { 274 google.maps.event.addListener(marker, 'dblclick', function (e) { 275 // the native event in google.maps is stored in e.xa 276 // there's no need to continue if google decides to rename it 277 if (!e.xa) { 278 return false;
279 } 280 e.xa.stopPropagation(); 281 282 var modal = new CMS.Modal(); 283 284 modal.open({ 285 url: marker.admin 286 }); 287 }); 288 } 289 } 290 }; 291 292 return GoogleMapConstructor; 293 })(); 294 295 // make sure google maps is loaded after our dom is ready 296 window.addEventListener('load', function () { 297 var elements = document.getElementsByClassName('js-djangocms-googlemap'); 298 299 elements = [].slice.call(elements); 300 elements.forEach(function (element) { 301 new GoogleMap(element); 302 }, this); 303 }); 304})();
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.