UNPKG

tourgent-ember-g-map

Version:

An ember-cli addon for integration with google maps.

171 lines (138 loc) 4.4 kB
import Ember from 'ember'; import layout from '../templates/components/g-map-infowindow'; import GMapComponent from './g-map'; import GMapMarkerComponent from './g-map-marker'; const { isEmpty, isPresent, observer, computed, run, assert, typeOf } = Ember; const OPEN_CLOSE_EVENTS = Ember.A( [ 'click', 'dblclick', 'rightclick', 'mouseover', 'mouseout' ] ); const GMapInfowindowComponent = Ember.Component.extend({ layout: layout, classNames: ['g-map-marker'], map: computed.alias('mapContext.map'), marker: computed.alias('mapContext.marker'), init() { this._super(arguments); const mapContext = this.get('mapContext'); const hasMap = mapContext instanceof GMapComponent; const hasMarker = mapContext instanceof GMapMarkerComponent; assert('Must be inside {{#g-map}} or {{#g-map-marker}} components with context set', hasMarker || hasMap); this.set('hasMarker', hasMarker); }, didInsertElement() { this._super(); if (isEmpty(this.get('infowindow'))) { const infowindow = this.buildInfowindow(); this.set('infowindow', infowindow); } this.setPosition(); this.setMap(); this.setMarker(); this.setOptions(); }, willDestroyElement() { this.close(); if (this.get('hasMarker')) { this.get('mapContext').unregisterInfowindow(); } }, optionsChanged: observer('disableAutoPan', 'maxWidth', 'pixelOffset', function() { run.once(this, 'setOptions'); }), setOptions() { const infowindow = this.get('infowindow'); const options = ['disableAutoPan', 'maxWidth', 'pixelOffset']; const infoWindowOptions = {}; for (let i = 0; i < options.length; i++) { const value = this.get(options[i]); if (isPresent(value)) { infoWindowOptions[options[i]] = value; } } if (isPresent(infowindow) && Object.keys(infoWindowOptions).length !== 0) { infowindow.setOptions(infoWindowOptions); } }, buildInfowindow() { const infowindow = new google.maps.InfoWindow({ content: this.get('element') }); if (isPresent(this.get('attrs.onClose'))) { infowindow.addListener('closeclick', () => this.handleCloseClickEvent()); } return infowindow; }, handleCloseClickEvent() { const { onClose } = this.attrs; if (typeOf(onClose) === 'function') { onClose(); } else { this.sendAction('onClose'); } }, open() { const infowindow = this.get('infowindow'); const map = this.get('map'); const marker = this.get('marker'); this.set('isOpen', true); if (isPresent(map) && isPresent(marker)) { infowindow.open(map, marker); } else if (isPresent(map)) { infowindow.open(map); } }, close() { const infowindow = this.get('infowindow'); if (isPresent(infowindow)) { this.set('isOpen', false); infowindow.close(); } }, mapWasSet: observer('map', function() { run.once(this, 'setMap'); }), setMap() { if (this.get('hasMarker') === false) { this.open(); } }, markerWasSet: observer('marker', function() { run.once(this, 'setMarker'); }), setMarker() { const map = this.get('map'); const marker = this.get('marker'); const context = this.get('mapContext'); const infowindow = this.get('infowindow'); if (isPresent(infowindow) && isPresent(map) && isPresent(marker)) { const openEvent = this.retrieveOpenEvent(); const closeEvent = this.retrieveCloseEvent(); context.registerInfowindow(this, openEvent, closeEvent); } }, coordsChanged: observer('lat', 'lng', function() { run.once(this, 'setPosition'); }), setPosition() { const infowindow = this.get('infowindow'); const lat = this.get('lat'); const lng = this.get('lng'); if (isPresent(infowindow) && isPresent(lat) && isPresent(lng)) { const position = new google.maps.LatLng(lat, lng); infowindow.setPosition(position); } }, retrieveOpenEvent() { const openEvent = this.get('openOn'); return OPEN_CLOSE_EVENTS.contains(openEvent) ? openEvent : 'click'; }, retrieveCloseEvent() { const closeEvent = this.get('closeOn'); return OPEN_CLOSE_EVENTS.contains(closeEvent) ? closeEvent : null; } }); GMapInfowindowComponent.reopenClass({ positionalParams: ['mapContext'] }); export default GMapInfowindowComponent;