Index: polymer_1.0.4/bower_components/google-map/google-map.html |
diff --git a/polymer_1.0.4/bower_components/google-map/google-map.html b/polymer_1.0.4/bower_components/google-map/google-map.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a0ce5d483040b4815d83c5aa5473fb3cc193fe82 |
--- /dev/null |
+++ b/polymer_1.0.4/bower_components/google-map/google-map.html |
@@ -0,0 +1,671 @@ |
+<!-- Copyright (c) 2015 Google Inc. All rights reserved. --> |
+ |
+<link rel="import" href="../polymer/polymer.html"> |
+<link rel="import" href="../google-apis/google-maps-api.html"> |
+<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html"> |
+<link rel="import" href="google-map-marker.html"> |
+<!-- |
+The `google-map` element renders a Google Map. |
+ |
+<b>Example</b>: |
+ |
+ <style> |
+ google-map { |
+ height: 600px; |
+ } |
+ </style> |
+ <google-map latitude="37.77493" longitude="-122.41942"></google-map> |
+ |
+<b>Example</b> - add markers to the map and ensure they're in view: |
+ |
+ <google-map latitude="37.77493" longitude="-122.41942" fit-to-markers> |
+ <google-map-marker latitude="37.779" longitude="-122.3892" |
+ draggable="true" title="Go Giants!"></google-map-marker> |
+ <google-map-marker latitude="37.777" longitude="-122.38911"></google-map-marker> |
+ </google-map> |
+ |
+<b>Example</b>: |
+ |
+ <google-map disable-default-ui zoom="15"></google-map> |
+ <script> |
+ var map = document.querySelector('google-map'); |
+ map.latitude = 37.77493; |
+ map.longitude = -122.41942; |
+ map.addEventListener('google-map-ready', function(e) { |
+ alert('Map loaded!'); |
+ }); |
+ </script> |
+ |
+<b>Example</b> - with Google directions, using data-binding inside another Polymer element |
+ |
+ <google-map map="{{map}}"></google-map> |
+ <google-map-directions map="{{map}}" |
+ start-address="San Francisco" end-address="Mountain View"> |
+ </google-map-directions> |
+ |
+@demo |
+--> |
+ |
+<dom-module id="google-map"> |
+ |
+ <style> |
+ :host { |
+ position: relative; |
+ display: block; |
+ height: 100%; |
+ } |
+ |
+ #map { |
+ position: absolute; |
+ top: 0; |
+ right: 0; |
+ bottom: 0; |
+ left: 0; |
+ } |
+ |
+ </style> |
+ <template> |
+ <google-maps-api |
+ api-key="[[apiKey]]" |
+ client-id="[[clientId]]" |
+ version="[[version]]" |
+ libraries="[[libraries]]" |
+ signed-in="[[signedIn]]" |
+ language="[[language]]" |
+ on-api-load="_mapApiLoaded"></google-maps-api> |
+ |
+ <div id="map"></div> |
+ |
+ <content id="markers" select="google-map-marker"></content> |
+ |
+ </template> |
+</dom-module> |
+ |
+<script> |
+ |
+ Polymer({ |
+ |
+ is: 'google-map', |
+ |
+ |
+ /** |
+ * Fired when the Maps API has fully loaded. |
+ * @event google-map-ready |
+ */ |
+ /** |
+ * Fired when the when the user clicks on the map (but not when they click on a marker, infowindow, or |
+ * other object). Requires the clickEvents attribute to be true. |
+ * @event google-map-click |
+ * @param {google.maps.MouseEvent} event The mouse event. |
+ */ |
+ /** |
+ * Fired when the user double-clicks on the map. Note that the google-map-click event will also fire, |
+ * right before this one. Requires the clickEvents attribute to be true. |
+ * @event google-map-dblclick |
+ * @param {google.maps.MouseEvent} event The mouse event. |
+ */ |
+ /** |
+ * Fired repeatedly while the user drags the map. Requires the dragEvents attribute to be true. |
+ * @event google-map-drag |
+ */ |
+ /** |
+ * Fired when the user stops dragging the map. Requires the dragEvents attribute to be true. |
+ * @event google-map-dragend |
+ */ |
+ /** |
+ * Fired when the user starts dragging the map. Requires the dragEvents attribute to be true. |
+ * @event google-map-dragstart |
+ */ |
+ /** |
+ * Fired whenever the user's mouse moves over the map container. Requires the mouseEvents attribute to |
+ * be true. |
+ * @event google-map-mousemove |
+ * @param {google.maps.MouseEvent} event The mouse event. |
+ */ |
+ /** |
+ * Fired when the user's mouse exits the map container. Requires the mouseEvents attribute to be true. |
+ * @event google-map-mouseout |
+ * @param {google.maps.MouseEvent} event The mouse event. |
+ */ |
+ /** |
+ * Fired when the user's mouse enters the map container. Requires the mouseEvents attribute to be true. |
+ * @event google-map-mouseover |
+ * @param {google.maps.MouseEvent} event The mouse event. |
+ */ |
+ /** |
+ * Fired when the DOM `contextmenu` event is fired on the map container. Requires the clickEvents |
+ * attribute to be true. |
+ * @event google-map-rightclick |
+ * @param {google.maps.MouseEvent} event The mouse event. |
+ */ |
+ properties: { |
+ /** |
+ * A Maps API key. To obtain an API key, see developers.google.com/maps/documentation/javascript/tutorial#api_key. |
+ */ |
+ apiKey: String, |
+ |
+ /** |
+ * A Maps API for Business Client ID. To obtain a Maps API for Business Client ID, see developers.google.com/maps/documentation/business/. |
+ * If set, a Client ID will take precedence over an API Key. |
+ */ |
+ clientId: String, |
+ |
+ /** |
+ * A latitude to center the map on. |
+ */ |
+ latitude: { |
+ type: Number, |
+ value: 37.77493, |
+ notify: true, |
+ reflectToAttribute: true |
+ }, |
+ |
+ /** |
+ * A Maps API object. |
+ */ |
+ map: { |
+ type: Object, |
+ notify: true, |
+ value: null |
+ }, |
+ |
+ /** |
+ * A comma separated list (e.g. "places,geometry") of libraries to load |
+ * with this map. Defaults to "places". For more information see |
+ * https://developers.google.com/maps/documentation/javascript/libraries. |
+ */ |
+ libraries: { |
+ type: String, |
+ value: 'places' |
+ }, |
+ |
+ /** |
+ * A longitude to center the map on. |
+ */ |
+ longitude: { |
+ type: Number, |
+ value: -122.41942, |
+ notify: true, |
+ reflectToAttribute: true |
+ }, |
+ |
+ /** |
+ * A zoom level to set the map to. |
+ */ |
+ zoom: { |
+ type: Number, |
+ value: 10, |
+ observer: '_zoomChanged' |
+ }, |
+ |
+ /** |
+ * When set, prevents the map from tilting (when the zoom level and viewport supports it). |
+ */ |
+ noAutoTilt: { |
+ type: Boolean, |
+ value: false |
+ }, |
+ |
+ /** |
+ * Map type to display. One of 'roadmap', 'satellite', 'hybrid', 'terrain'. |
+ */ |
+ mapType: { |
+ type: String, |
+ value: 'roadmap', // roadmap, satellite, hybrid, terrain, |
+ observer: '_mapTypeChanged' |
+ }, |
+ |
+ /** |
+ * Version of the Google Maps API to use. |
+ */ |
+ version: { |
+ type: String, |
+ value: '3.exp' |
+ }, |
+ |
+ /** |
+ * If set, removes the map's default UI controls. |
+ */ |
+ disableDefaultUi: { |
+ type: Boolean, |
+ value: false, |
+ observer: '_disableDefaultUiChanged' |
+ }, |
+ |
+ /** |
+ * If set, the zoom level is set such that all markers (google-map-marker children) are brought into view. |
+ */ |
+ fitToMarkers: { |
+ type: Boolean, |
+ value: false, |
+ observer: '_fitToMarkersChanged' |
+ }, |
+ |
+ /** |
+ * If true, prevent the user from zooming the map interactively. |
+ */ |
+ disableZoom: { |
+ type: Boolean, |
+ value: false, |
+ observer: '_disableZoomChanged' |
+ }, |
+ |
+ /** |
+ * If set, custom styles can be applied to the map. |
+ * For style documentation see developers.google.com/maps/documentation/javascript/reference#MapTypeStyle |
+ */ |
+ styles: { |
+ type: Object, |
+ value: function() { return {}; } |
+ }, |
+ |
+ /** |
+ * A maximum zoom level which will be displayed on the map. |
+ */ |
+ maxZoom: { |
+ type: Number, |
+ observer: '_maxZoomChanged' |
+ }, |
+ |
+ /** |
+ * A minimum zoom level which will be displayed on the map. |
+ */ |
+ minZoom: { |
+ type: Number, |
+ observer: '_minZoomChanged' |
+ }, |
+ |
+ /** |
+ * If true, sign-in is enabled. |
+ * See https://developers.google.com/maps/documentation/javascript/signedin#enable_sign_in |
+ */ |
+ signedIn: { |
+ type: Boolean, |
+ value: false |
+ }, |
+ |
+ /** |
+ * The localized language to load the Maps API with. For more information |
+ * see https://developers.google.com/maps/documentation/javascript/basics#Language |
+ * |
+ * Note: the Maps API defaults to the preffered language setting of the browser. |
+ * Use this parameter to override that behavior. |
+ */ |
+ language: { |
+ type: String |
+ }, |
+ |
+ /** |
+ * When true, map *click events are automatically registered. |
+ */ |
+ clickEvents: { |
+ type: Boolean, |
+ value: false, |
+ observer: '_clickEventsChanged' |
+ }, |
+ |
+ /** |
+ * When true, map drag* events are automatically registered. |
+ */ |
+ dragEvents: { |
+ type: Boolean, |
+ value: false, |
+ observer: '_dragEventsChanged' |
+ }, |
+ |
+ /** |
+ * When true, map mouse* events are automatically registered. |
+ */ |
+ mouseEvents: { |
+ type: Boolean, |
+ value: false, |
+ observer: '_mouseEventsChanged' |
+ }, |
+ |
+ /** |
+ * Additional map options for google.maps.Map constructor. |
+ * Use to specify additional options we do not expose as |
+ * properties. |
+ * Ex: `<google-map additional-map-options='{"mapTypeId":"satellite"}'>` |
+ */ |
+ additionalMapOptions: { |
+ type: Object, |
+ value: function() { return {}; } |
+ } |
+ |
+ }, |
+ |
+ behaviors: [ |
+ Polymer.IronResizableBehavior |
+ ], |
+ |
+ listeners: { |
+ 'iron-resize': 'resize' |
+ }, |
+ |
+ observers: [ |
+ '_debounceUpdateCenter(latitude, longitude)' |
+ ], |
+ |
+ created: function() { |
+ this.markers = []; |
+ }, |
+ |
+ attached: function() { |
+ this._initGMap(); |
+ }, |
+ |
+ detached: function() { |
+ if (this._mutationObserver) { |
+ this._mutationObserver.disconnect(); |
+ this._mutationObserver = null; |
+ } |
+ }, |
+ |
+ _initGMap: function() { |
+ if (this.map) { |
+ return; // already initialized |
+ } |
+ if (!(window.google && window.google.maps)) { |
+ return; // api not loaded |
+ } |
+ if (!this.isAttached) { |
+ return; // not attached |
+ } |
+ |
+ this.map = new google.maps.Map(this.$.map, this._getMapOptions()); |
+ this._listeners = {}; |
+ this._updateCenter(); |
+ this._updateMarkers(); |
+ this._addMapListeners(); |
+ this.fire('google-map-ready'); |
+ }, |
+ |
+ _mapApiLoaded: function() { |
+ this._initGMap(); |
+ }, |
+ |
+ _getMapOptions: function() { |
+ var mapOptions = { |
+ zoom: this.zoom, |
+ tilt: this.noAutoTilt ? 0 : 45, |
+ mapTypeId: this.mapType, |
+ disableDefaultUI: this.disableDefaultUi, |
+ disableDoubleClickZoom: this.disableZoom, |
+ scrollwheel: !this.disableZoom, |
+ styles: this.styles, |
+ maxZoom: Number(this.maxZoom), |
+ minZoom: Number(this.minZoom) |
+ }; |
+ |
+ // Only override the default if set. |
+ // We use getAttribute here because the default value of this.draggable = false even when not set. |
+ if (this.getAttribute('draggable') != null) { |
+ mapOptions.draggable = this.draggable |
+ } |
+ for (var p in this.additionalMapOptions) |
+ mapOptions[p] = this.additionalMapOptions[p]; |
+ |
+ return mapOptions; |
+ }, |
+ |
+ // watch for future updates |
+ _observeMarkers: function() { |
+ // Watch for future updates. |
+ if (this._mutationObserver) { |
+ return; |
+ } |
+ this._mutationObserver = new MutationObserver( this._updateMarkers.bind(this)); |
+ this._mutationObserver.observe(this, { |
+ childList: true |
+ }); |
+ }, |
+ |
+ _updateMarkers: function() { |
+ var newMarkers = Array.prototype.slice.call( |
+ Polymer.dom(this.$.markers).getDistributedNodes()); |
+ |
+ // do not recompute if markers have not been added or removed |
+ if (newMarkers.length === this.markers.length) { |
+ var added = newMarkers.filter(function(m) { |
+ return this.markers && this.markers.indexOf(m) === -1; |
+ }.bind(this)); |
+ if (added.length === 0) { |
+ // set up observer first time around |
+ if (!this._mutationObserver) { |
+ this._observeMarkers(); |
+ } |
+ return; |
+ } |
+ } |
+ |
+ this._observeMarkers(); |
+ |
+ this.markers = newMarkers; |
+ |
+ // Set the map on each marker and zoom viewport to ensure they're in view. |
+ if (this.markers.length && this.map) { |
+ for (var i = 0, m; m = this.markers[i]; ++i) { |
+ m.map = this.map; |
+ } |
+ } |
+ if (this.fitToMarkers) { |
+ this._fitToMarkersChanged(); |
+ } |
+ }, |
+ |
+ /** |
+ * Clears all markers from the map. |
+ * |
+ * @method clear |
+ */ |
+ clear: function() { |
+ for (var i = 0, m; m = this.markers[i]; ++i) { |
+ m.marker.setMap(null); |
+ } |
+ }, |
+ |
+ /** |
+ * Explicitly resizes the map, updating its center. This is useful if the |
+ * map does not show after you have unhidden it. |
+ * |
+ * @method resize |
+ */ |
+ resize: function() { |
+ if (this.map) { |
+ |
+ // saves and restores latitude/longitude because resize can move the center |
+ var oldLatitude = this.latitude; |
+ var oldLongitude = this.longitude; |
+ google.maps.event.trigger(this.map, 'resize'); |
+ this.latitude = oldLatitude; // restore because resize can move our center |
+ this.longitude = oldLongitude; |
+ |
+ if (this.fitToMarkers) { // we might not have a center if we are doing fit-to-markers |
+ this._fitToMarkersChanged(); |
+ } |
+ } |
+ }, |
+ |
+ _debounceUpdateCenter: function() { |
+ this.debounce('updateCenter', this._updateCenter); |
+ }, |
+ |
+ _updateCenter: function() { |
+ this.cancelDebouncer('updateCenter'); |
+ |
+ if (this.map && this.latitude !== undefined && this.longitude !== undefined) { |
+ // allow for latitude and longitude to be String-typed, but still Number valued |
+ var lati = Number(this.latitude); |
+ if (isNaN(lati)) { |
+ throw new TypeError('latitude must be a number'); |
+ } |
+ var longi = Number(this.longitude); |
+ if (isNaN(longi)) { |
+ throw new TypeError('longitude must be a number'); |
+ } |
+ |
+ var newCenter = new google.maps.LatLng(lati, longi); |
+ var oldCenter = this.map.getCenter(); |
+ |
+ if (!oldCenter) { |
+ // If the map does not have a center, set it right away. |
+ this.map.setCenter(newCenter); |
+ } else { |
+ // Using google.maps.LatLng returns corrected lat/lngs. |
+ oldCenter = new google.maps.LatLng(oldCenter.lat(), oldCenter.lng()); |
+ |
+ // If the map currently has a center, slowly pan to the new one. |
+ if (!oldCenter.equals(newCenter)) { |
+ this.map.panTo(newCenter); |
+ } |
+ } |
+ } |
+ }, |
+ |
+ _zoomChanged: function() { |
+ if (this.map) { |
+ this.map.setZoom(Number(this.zoom)); |
+ } |
+ }, |
+ |
+ _clickEventsChanged: function() { |
+ if (this.map) { |
+ if (this.clickEvents) { |
+ this._forwardEvent('click'); |
+ this._forwardEvent('dblclick'); |
+ this._forwardEvent('rightclick'); |
+ } else { |
+ this._clearListener('click'); |
+ this._clearListener('dblclick'); |
+ this._clearListener('rightclick'); |
+ } |
+ } |
+ }, |
+ |
+ _dragEventsChanged: function() { |
+ if (this.map) { |
+ if (this.dragEvents) { |
+ this._forwardEvent('drag'); |
+ this._forwardEvent('dragend'); |
+ this._forwardEvent('dragstart'); |
+ } else { |
+ this._clearListener('drag'); |
+ this._clearListener('dragend'); |
+ this._clearListener('dragstart'); |
+ } |
+ } |
+ }, |
+ |
+ _mouseEventsChanged: function() { |
+ if (this.map) { |
+ if (this.mouseEvents) { |
+ this._forwardEvent('mousemove'); |
+ this._forwardEvent('mouseout'); |
+ this._forwardEvent('mouseover'); |
+ } else { |
+ this._clearListener('mousemove'); |
+ this._clearListener('mouseout'); |
+ this._clearListener('mouseover'); |
+ } |
+ } |
+ }, |
+ |
+ _maxZoomChanged: function() { |
+ if (this.map) { |
+ this.map.setOptions({maxZoom: Number(this.maxZoom)}); |
+ } |
+ }, |
+ |
+ _minZoomChanged: function() { |
+ if (this.map) { |
+ this.map.setOptions({minZoom: Number(this.minZoom)}); |
+ } |
+ }, |
+ |
+ _mapTypeChanged: function() { |
+ if (this.map) { |
+ this.map.setMapTypeId(this.mapType); |
+ } |
+ }, |
+ |
+ _disableDefaultUiChanged: function() { |
+ if (!this.map) { |
+ return; |
+ } |
+ this.map.setOptions({disableDefaultUI: this.disableDefaultUi}); |
+ }, |
+ |
+ _disableZoomChanged: function() { |
+ if (!this.map) { |
+ return; |
+ } |
+ this.map.setOptions({ |
+ disableDoubleClickZoom: this.disableZoom, |
+ scrollwheel: !this.disableZoom |
+ }); |
+ }, |
+ |
+ attributeChanged: function(attrName, oldVal, newVal) { |
+ if (!this.map) { |
+ return; |
+ } |
+ // Cannot use *Changed watchers for native properties. |
+ switch (attrName) { |
+ case 'draggable': |
+ this.map.setOptions({draggable: this.draggable}); |
+ break; |
+ } |
+ }, |
+ |
+ _fitToMarkersChanged: function() { |
+ // TODO(ericbidelman): respect user's zoom level. |
+ |
+ if (this.map && this.fitToMarkers) { |
+ var latLngBounds = new google.maps.LatLngBounds(); |
+ for (var i = 0, m; m = this.markers[i]; ++i) { |
+ latLngBounds.extend( |
+ new google.maps.LatLng(m.latitude, m.longitude)); |
+ } |
+ |
+ // For one marker, don't alter zoom, just center it. |
+ if (this.markers.length > 1) { |
+ this.map.fitBounds(latLngBounds); |
+ } |
+ |
+ this.map.setCenter(latLngBounds.getCenter()); |
+ } |
+ }, |
+ |
+ _addMapListeners: function() { |
+ google.maps.event.addListener(this.map, 'center_changed', function() { |
+ var center = this.map.getCenter(); |
+ this.latitude = center.lat(); |
+ this.longitude = center.lng(); |
+ }.bind(this)); |
+ |
+ google.maps.event.addListener(this.map, 'zoom_changed', function() { |
+ this.zoom = this.map.getZoom(); |
+ }.bind(this)); |
+ |
+ this._clickEventsChanged(); |
+ this._dragEventsChanged(); |
+ this._mouseEventsChanged(); |
+ }, |
+ |
+ _clearListener: function(name) { |
+ if (this._listeners[name]) { |
+ google.maps.event.removeListener(this._listeners[name]); |
+ this._listeners[name] = null; |
+ } |
+ }, |
+ |
+ _forwardEvent: function(name) { |
+ this._listeners[name] = google.maps.event.addListener(this.map, name, function(event) { |
+ this.fire('google-map-' + name, event); |
+ }.bind(this)); |
+ } |
+ |
+ }); |
+ |
+</script> |