UNPKG

@deatog/react-google-maps-infobox

Version:
576 lines (573 loc) 24.3 kB
'use strict'; // This handler prevents an event in the InfoBox from being passed on to the map. function cancelHandler(event) { event.cancelBubble = true; if (event.stopPropagation) { event.stopPropagation(); } } var InfoBox = /** @class */ (function () { function InfoBox(options) { if (options === void 0) { options = {}; } this.getCloseClickHandler = this.getCloseClickHandler.bind(this); this.closeClickHandler = this.closeClickHandler.bind(this); this.createInfoBoxDiv = this.createInfoBoxDiv.bind(this); this.addClickHandler = this.addClickHandler.bind(this); this.getCloseBoxImg = this.getCloseBoxImg.bind(this); this.getBoxWidths = this.getBoxWidths.bind(this); this.setBoxStyle = this.setBoxStyle.bind(this); this.setPosition = this.setPosition.bind(this); this.getPosition = this.getPosition.bind(this); this.setOptions = this.setOptions.bind(this); this.setContent = this.setContent.bind(this); this.setVisible = this.setVisible.bind(this); this.getContent = this.getContent.bind(this); this.getVisible = this.getVisible.bind(this); this.setZIndex = this.setZIndex.bind(this); this.getZIndex = this.getZIndex.bind(this); this.onRemove = this.onRemove.bind(this); this.panBox = this.panBox.bind(this); this.extend = this.extend.bind(this); this.close = this.close.bind(this); this.draw = this.draw.bind(this); this.show = this.show.bind(this); this.hide = this.hide.bind(this); this.open = this.open.bind(this); this.extend(InfoBox, google.maps.OverlayView); // Standard options (in common with google.maps.InfoWindow): this.content = options.content || ''; this.disableAutoPan = options.disableAutoPan || false; this.maxWidth = options.maxWidth || 0; this.pixelOffset = options.pixelOffset || new google.maps.Size(0, 0); this.position = options.position || new google.maps.LatLng(0, 0); this.zIndex = options.zIndex || null; // Additional options (unique to InfoBox): this.boxClass = options.boxClass || 'infoBox'; this.boxStyle = options.boxStyle || {}; this.closeBoxMargin = options.closeBoxMargin || '2px'; this.closeBoxURL = options.closeBoxURL || 'http://www.google.com/intl/en_us/mapfiles/close.gif'; if (options.closeBoxURL === '') { this.closeBoxURL = ''; } this.infoBoxClearance = options.infoBoxClearance || new google.maps.Size(1, 1); if (typeof options.visible === 'undefined') { if (typeof options.isHidden === 'undefined') { options.visible = true; } else { options.visible = !options.isHidden; } } this.isHidden = !options.visible; this.alignBottom = options.alignBottom || false; this.pane = options.pane || 'floatPane'; this.enableEventPropagation = options.enableEventPropagation || false; this.div = null; this.closeListener = null; this.moveListener = null; this.mapListener = null; this.contextListener = null; this.eventListeners = null; this.fixedWidthSet = null; } InfoBox.prototype.createInfoBoxDiv = function () { var _this = this; // This handler ignores the current event in the InfoBox and conditionally prevents // the event from being passed on to the map. It is used for the contextmenu event. var ignoreHandler = function (event) { event.returnValue = false; if (event.preventDefault) { event.preventDefault(); } if (!_this.enableEventPropagation) { cancelHandler(event); } }; if (!this.div) { this.div = document.createElement('div'); this.setBoxStyle(); if (typeof this.content === 'string') { this.div.innerHTML = this.getCloseBoxImg() + this.content; } else { this.div.innerHTML = this.getCloseBoxImg(); this.div.appendChild(this.content); } var panes = this.getPanes(); if (panes !== null) { panes[this.pane].appendChild(this.div); // Add the InfoBox div to the DOM } this.addClickHandler(); if (this.div.style.width) { this.fixedWidthSet = true; } else { if (this.maxWidth !== 0 && this.div.offsetWidth > this.maxWidth) { this.div.style.width = this.maxWidth + 'px'; this.fixedWidthSet = true; } else { // The following code is needed to overcome problems with MSIE var bw = this.getBoxWidths(); this.div.style.width = this.div.offsetWidth - bw.left - bw.right + 'px'; this.fixedWidthSet = false; } } this.panBox(this.disableAutoPan); if (!this.enableEventPropagation) { this.eventListeners = []; // Cancel event propagation. // Note: mousemove not included (to resolve Issue 152) var events = [ 'mousedown', 'mouseover', 'mouseout', 'mouseup', 'click', 'dblclick', 'touchstart', 'touchend', 'touchmove', ]; for (var _i = 0, events_1 = events; _i < events_1.length; _i++) { var event_1 = events_1[_i]; this.eventListeners.push(google.maps.event.addListener(this.div, event_1, cancelHandler)); } // Workaround for Google bug that causes the cursor to change to a pointer // when the mouse moves over a marker underneath InfoBox. this.eventListeners.push(google.maps.event.addListener(this.div, 'mouseover', function () { if (_this.div) { _this.div.style.cursor = 'default'; } })); } this.contextListener = google.maps.event.addListener(this.div, 'contextmenu', ignoreHandler); /** * This event is fired when the DIV containing the InfoBox's content is attached to the DOM. * @name InfoBox#domready * @event */ google.maps.event.trigger(this, 'domready'); } }; InfoBox.prototype.getCloseBoxImg = function () { var img = ''; if (this.closeBoxURL !== '') { img = '<img alt=""'; img += ' aria-hidden="true"'; img += " src='" + this.closeBoxURL + "'"; img += ' align=right'; // Do this because Opera chokes on style='float: right;' img += " style='"; img += ' position: relative;'; // Required by MSIE img += ' cursor: pointer;'; img += ' margin: ' + this.closeBoxMargin + ';'; img += "'>"; } return img; }; InfoBox.prototype.addClickHandler = function () { this.closeListener = this.div && this.div.firstChild && this.closeBoxURL !== '' ? google.maps.event.addListener(this.div.firstChild, 'click', this.getCloseClickHandler()) : null; }; InfoBox.prototype.closeClickHandler = function (event) { // 1.0.3 fix: Always prevent propagation of a close box click to the map: event.cancelBubble = true; if (event.stopPropagation) { event.stopPropagation(); } /** * This event is fired when the InfoBox's close box is clicked. * @name InfoBox#closeclick * @event */ google.maps.event.trigger(this, 'closeclick'); this.close(); }; InfoBox.prototype.getCloseClickHandler = function () { return this.closeClickHandler; }; InfoBox.prototype.panBox = function (disablePan) { if (this.div && !disablePan) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore var map = this.getMap(); // Only pan if attached to map, not panorama if (map instanceof google.maps.Map) { var xOffset = 0; var yOffset = 0; var bounds = map.getBounds(); if (bounds && !bounds.contains(this.position)) { // Marker not in visible area of map, so set center // of map to the marker position first. map.setCenter(this.position); } var mapDiv = map.getDiv(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore var mapWidth = mapDiv.offsetWidth; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore var mapHeight = mapDiv.offsetHeight; var iwOffsetX = this.pixelOffset.width; var iwOffsetY = this.pixelOffset.height; var iwWidth = this.div.offsetWidth; var iwHeight = this.div.offsetHeight; var padX = this.infoBoxClearance.width; var padY = this.infoBoxClearance.height; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore var projection = this.getProjection(); var pixPosition = projection.fromLatLngToContainerPixel(this.position); if (pixPosition !== null) { if (pixPosition.x < -iwOffsetX + padX) { xOffset = pixPosition.x + iwOffsetX - padX; } else if (pixPosition.x + iwWidth + iwOffsetX + padX > mapWidth) { xOffset = pixPosition.x + iwWidth + iwOffsetX + padX - mapWidth; } if (this.alignBottom) { if (pixPosition.y < -iwOffsetY + padY + iwHeight) { yOffset = pixPosition.y + iwOffsetY - padY - iwHeight; } else if (pixPosition.y + iwOffsetY + padY > mapHeight) { yOffset = pixPosition.y + iwOffsetY + padY - mapHeight; } } else { if (pixPosition.y < -iwOffsetY + padY) { yOffset = pixPosition.y + iwOffsetY - padY; } else if (pixPosition.y + iwHeight + iwOffsetY + padY > mapHeight) { yOffset = pixPosition.y + iwHeight + iwOffsetY + padY - mapHeight; } } } if (!(xOffset === 0 && yOffset === 0)) { // Move the map to the shifted center. map.panBy(xOffset, yOffset); } } } }; InfoBox.prototype.setBoxStyle = function () { if (this.div) { // Apply style values from the style sheet defined in the boxClass parameter: this.div.className = this.boxClass; // Clear existing inline style values: this.div.style.cssText = ''; // Apply style values defined in the boxStyle parameter: var boxStyle = this.boxStyle; for (var i in boxStyle) { if (Object.prototype.hasOwnProperty.call(boxStyle, i)) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.div.style[i] = boxStyle[i]; } } // Fix for iOS disappearing InfoBox problem // See http://stackoverflow.com/questions/9229535/google-maps-markers-disappear-at-certain-zoom-level-only-on-iphone-ipad this.div.style.webkitTransform = 'translateZ(0)'; // Fix up opacity style for benefit of MSIE if (typeof this.div.style.opacity !== 'undefined' && this.div.style.opacity !== '') { // See http://www.quirksmode.org/css/opacity.html var opacity = parseFloat(this.div.style.opacity || ''); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.div.style.msFilter = '"progid:DXImageTransform.Microsoft.Alpha(Opacity=' + opacity * 100 + ')"'; this.div.style.filter = 'alpha(opacity=' + opacity * 100 + ')'; } // Apply required styles this.div.style.position = 'absolute'; this.div.style.visibility = 'hidden'; if (this.zIndex !== null) { this.div.style.zIndex = this.zIndex + ''; } if (!this.div.style.overflow) { this.div.style.overflow = 'auto'; } } }; InfoBox.prototype.getBoxWidths = function () { var bw = { top: 0, bottom: 0, left: 0, right: 0 }; if (!this.div) { return bw; } if (document.defaultView) { var ownerDocument = this.div.ownerDocument; var computedStyle = ownerDocument && ownerDocument.defaultView ? ownerDocument.defaultView.getComputedStyle(this.div, '') : null; if (computedStyle) { // The computed styles are always in pixel units (good!) bw.top = parseInt(computedStyle.borderTopWidth || '', 10) || 0; bw.bottom = parseInt(computedStyle.borderBottomWidth || '', 10) || 0; bw.left = parseInt(computedStyle.borderLeftWidth || '', 10) || 0; bw.right = parseInt(computedStyle.borderRightWidth || '', 10) || 0; } } else if ( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore document.documentElement.currentStyle // MSIE ) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore var currentStyle = this.div.currentStyle; if (currentStyle) { // The current styles may not be in pixel units, but assume they are (bad!) bw.top = parseInt(currentStyle.borderTopWidth || '', 10) || 0; bw.bottom = parseInt(currentStyle.borderBottomWidth || '', 10) || 0; bw.left = parseInt(currentStyle.borderLeftWidth || '', 10) || 0; bw.right = parseInt(currentStyle.borderRightWidth || '', 10) || 0; } } return bw; }; InfoBox.prototype.onRemove = function () { if (this.div && this.div.parentNode) { this.div.parentNode.removeChild(this.div); this.div = null; } }; InfoBox.prototype.draw = function () { this.createInfoBoxDiv(); if (this.div) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore var projection = this.getProjection(); var pixPosition = projection.fromLatLngToDivPixel(this.position); if (pixPosition !== null) { this.div.style.left = pixPosition.x + this.pixelOffset.width + 'px'; if (this.alignBottom) { this.div.style.bottom = -(pixPosition.y + this.pixelOffset.height) + 'px'; } else { this.div.style.top = pixPosition.y + this.pixelOffset.height + 'px'; } } if (this.isHidden) { this.div.style.visibility = 'hidden'; } else { this.div.style.visibility = 'visible'; } } }; InfoBox.prototype.setOptions = function (options) { if (options === void 0) { options = {}; } if (typeof options.boxClass !== 'undefined') { // Must be first this.boxClass = options.boxClass; this.setBoxStyle(); } if (typeof options.boxStyle !== 'undefined') { // Must be second this.boxStyle = options.boxStyle; this.setBoxStyle(); } if (typeof options.content !== 'undefined') { this.setContent(options.content); } if (typeof options.disableAutoPan !== 'undefined') { this.disableAutoPan = options.disableAutoPan; } if (typeof options.maxWidth !== 'undefined') { this.maxWidth = options.maxWidth; } if (typeof options.pixelOffset !== 'undefined') { this.pixelOffset = options.pixelOffset; } if (typeof options.alignBottom !== 'undefined') { this.alignBottom = options.alignBottom; } if (typeof options.position !== 'undefined') { this.setPosition(options.position); } if (typeof options.zIndex !== 'undefined') { this.setZIndex(options.zIndex); } if (typeof options.closeBoxMargin !== 'undefined') { this.closeBoxMargin = options.closeBoxMargin; } if (typeof options.closeBoxURL !== 'undefined') { this.closeBoxURL = options.closeBoxURL; } if (typeof options.infoBoxClearance !== 'undefined') { this.infoBoxClearance = options.infoBoxClearance; } if (typeof options.isHidden !== 'undefined') { this.isHidden = options.isHidden; } if (typeof options.visible !== 'undefined') { this.isHidden = !options.visible; } if (typeof options.enableEventPropagation !== 'undefined') { this.enableEventPropagation = options.enableEventPropagation; } if (this.div) { this.draw(); } }; InfoBox.prototype.setContent = function (content) { this.content = content; if (this.div) { if (this.closeListener) { google.maps.event.removeListener(this.closeListener); this.closeListener = null; } // Odd code required to make things work with MSIE. if (!this.fixedWidthSet) { this.div.style.width = ''; } if (typeof content === 'string') { this.div.innerHTML = this.getCloseBoxImg() + content; } else { this.div.innerHTML = this.getCloseBoxImg(); this.div.appendChild(content); } // Perverse code required to make things work with MSIE. // (Ensures the close box does, in fact, float to the right.) if (!this.fixedWidthSet) { this.div.style.width = this.div.offsetWidth + 'px'; if (typeof content === 'string') { this.div.innerHTML = this.getCloseBoxImg() + content; } else { this.div.innerHTML = this.getCloseBoxImg(); this.div.appendChild(content); } } this.addClickHandler(); } /** * This event is fired when the content of the InfoBox changes. * @name InfoBox#content_changed * @event */ google.maps.event.trigger(this, 'content_changed'); }; InfoBox.prototype.setPosition = function (latLng) { this.position = latLng; if (this.div) { this.draw(); } /** * This event is fired when the position of the InfoBox changes. * @name InfoBox#position_changed * @event */ google.maps.event.trigger(this, 'position_changed'); }; InfoBox.prototype.setVisible = function (isVisible) { this.isHidden = !isVisible; if (this.div) { this.div.style.visibility = this.isHidden ? 'hidden' : 'visible'; } }; InfoBox.prototype.setZIndex = function (index) { this.zIndex = index; if (this.div) { this.div.style.zIndex = index + ''; } /** * This event is fired when the zIndex of the InfoBox changes. * @name InfoBox#zindex_changed * @event */ google.maps.event.trigger(this, 'zindex_changed'); }; InfoBox.prototype.getContent = function () { return this.content; }; InfoBox.prototype.getPosition = function () { return this.position; }; InfoBox.prototype.getZIndex = function () { return this.zIndex; }; InfoBox.prototype.getVisible = function () { var map = this.getMap(); return typeof map === 'undefined' || map === null ? false : !this.isHidden; }; InfoBox.prototype.show = function () { this.isHidden = false; if (this.div) { this.div.style.visibility = 'visible'; } }; InfoBox.prototype.hide = function () { this.isHidden = true; if (this.div) { this.div.style.visibility = 'hidden'; } }; InfoBox.prototype.open = function (map, anchor) { var _this = this; if (anchor) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.position = anchor.getPosition(); this.moveListener = google.maps.event.addListener(anchor, 'position_changed', function () { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore var position = anchor.getPosition(); _this.setPosition(position); }); this.mapListener = google.maps.event.addListener(anchor, 'map_changed', function () { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore _this.setMap(anchor.map); }); } this.setMap(map); if (this.div) { this.panBox(); } }; InfoBox.prototype.close = function () { if (this.closeListener) { google.maps.event.removeListener(this.closeListener); this.closeListener = null; } if (this.eventListeners) { for (var _i = 0, _a = this.eventListeners; _i < _a.length; _i++) { var eventListener = _a[_i]; google.maps.event.removeListener(eventListener); } this.eventListeners = null; } if (this.moveListener) { google.maps.event.removeListener(this.moveListener); this.moveListener = null; } if (this.mapListener) { google.maps.event.removeListener(this.mapListener); this.mapListener = null; } if (this.contextListener) { google.maps.event.removeListener(this.contextListener); this.contextListener = null; } // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.setMap(null); }; InfoBox.prototype.extend = function (obj1, obj2) { return function applyExtend(object) { for (var property in object.prototype) { if (!Object.prototype.hasOwnProperty.call(this, property)) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this.prototype[property] = object.prototype[property]; } } return this; }.apply(obj1, [obj2]); }; return InfoBox; }()); exports.InfoBox = InfoBox; //# sourceMappingURL=cjs.js.map