'use strict'; (function () { //Setup map events from a google map object to trigger on a given element too, //then we just use ui-event to catch events from an element function bindMapEvents(scope, eventsStr, googleObject, element) { angular.forEach(eventsStr.split(' '), function (eventName) { //Prefix all googlemap events with 'map-', so eg 'click' //for the googlemap doesn't interfere with a normal 'click' event window.google.maps.event.addListener(googleObject, eventName, function (event) { element.triggerHandler('map-' + eventName, event); //We create an $apply if it isn't happening. we need better support for this //We don't want to use timeout because tons of these events fire at once, //and we only need one $apply if (!scope.$$phase){ scope.$apply();} }); }); } app.value('uiMapConfig', {}); app.directive('uiMap', ['uiMapConfig', '$parse', function (uiMapConfig, $parse) { var mapEvents = 'bounds_changed center_changed click dblclick drag dragend ' + 'dragstart heading_changed idle maptypeid_changed mousemove mouseout ' + 'mouseover projection_changed resize rightclick tilesloaded tilt_changed ' + 'zoom_changed'; var options = uiMapConfig || {}; return { restrict: 'A', //doesn't work as E for unknown reason link: function (scope, elm, attrs) { var opts = angular.extend({}, options, scope.$eval(attrs.uiOptions)); var map = new window.google.maps.Map(elm[0], opts); var model = $parse(attrs.uiMap); //Set scope variable for the map model.assign(scope, map); bindMapEvents(scope, mapEvents, map, elm); } }; }]); app.value('uiMapInfoWindowConfig', {}); app.directive('uiMapInfoWindow', ['uiMapInfoWindowConfig', '$parse', '$compile', function (uiMapInfoWindowConfig, $parse, $compile) { var infoWindowEvents = 'closeclick content_change domready ' + 'position_changed zindex_changed'; var options = uiMapInfoWindowConfig || {}; return { link: function (scope, elm, attrs) { var opts = angular.extend({}, options, scope.$eval(attrs.uiOptions)); opts.content = elm[0]; var model = $parse(attrs.uiMapInfoWindow); var infoWindow = model(scope); if (!infoWindow) { infoWindow = new window.google.maps.InfoWindow(opts); model.assign(scope, infoWindow); } bindMapEvents(scope, infoWindowEvents, infoWindow, elm); /* The info window's contents dont' need to be on the dom anymore, google maps has them stored. So we just replace the infowindow element with an empty div. (we don't just straight remove it from the dom because straight removing things from the dom can mess up angular) */ elm.replaceWith('
'); //Decorate infoWindow.open to $compile contents before opening var _open = infoWindow.open; infoWindow.open = function open(a1, a2, a3, a4, a5, a6) { $compile(elm.contents())(scope); _open.call(infoWindow, a1, a2, a3, a4, a5, a6); }; } }; }]); /* * Map overlay directives all work the same. Take map marker for example *