1/** 2 * @name InfoBox 3 * @version 1.1.19 [April 6, 2018] 4 * @author Gary Little (inspired by proof-of-concept code from Pamela Fox of Google) 5 * @copyright Copyright 2010 Gary Little [gary at luxcentral.com] 6 * @fileoverview InfoBox extends the Google Maps JavaScript API V3 <tt>OverlayView</tt> class. 7 * <p> 8 * An InfoBox behaves like a <tt>google.maps.InfoWindow</tt>, but it supports several 9 * additional properties for advanced styling. An InfoBox can also be used as a map label. 10 * <p> 11 * An InfoBox also fires the same events as a <tt>google.maps.InfoWindow</tt>. 12 */ 13 14/*! 15 * 16 * Licensed under the Apache License, Version 2.0 (the "License"); 17 * you may not use this file except in compliance with the License. 18 * You may obtain a copy of the License at 19 * 20 * http://www.apache.org/licenses/LICENSE-2.0 21 * 22 * Unless required by applicable law or agreed to in writing, software 23 * distributed under the License is distributed on an "AS IS" BASIS, 24 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 * See the License for the specific language governing permissions and 26 * limitations under the License. 27 */ 28 29/*jslint browser:true */ 30/*global google */ 31 32/** 33 * @name InfoBoxOptions 34 * @class This class represents the optional parameter passed to the {@link InfoBox} constructor. 35 * @property {string|Node} content The content of the InfoBox (plain text or an HTML DOM node). 36 * @property {boolean} [disableAutoPan=false] Disable auto-pan on <tt>open</tt>. 37 * @property {number} maxWidth The maximum width (in pixels) of the InfoBox. Set to 0 if no maximum. 38 * @property {Size} pixelOffset The offset (in pixels) from the top left corner of the InfoBox 39 * (or the bottom left corner if the <code>alignBottom</code> property is <code>true</code>) 40 * to the map pixel corresponding to <tt>position</tt>. 41 * @property {LatLng} position The geographic location at which to display the InfoBox. 42 * @property {number} zIndex The CSS z-index style value for the InfoBox. 43 * Note: This value overrides a zIndex setting specified in the <tt>boxStyle</tt> property. 44 * @property {string} [boxClass="infoBox"] The name of the CSS class defining the styles for the InfoBox container. 45 * @property {Object} [boxStyle] An object literal whose properties define specific CSS 46 * style values to be applied to the InfoBox. Style values defined here override those that may 47 * be defined in the <code>boxClass</code> style sheet. If this property is changed after the 48 * InfoBox has been created, all previously set styles (except those defined in the style sheet) 49 * are removed from the InfoBox before the new style values are applied. 50 * @property {string} closeBoxMargin The CSS margin style value for the close box. 51 * The default is "2px" (a 2-pixel margin on all sides). 52 * @property {string} closeBoxTitle The tool tip for the close box. The default is " Close ". 53 * @property {string} closeBoxURL The URL of the image representing the close box. 54 * Note: The default is the URL for Google's standard close box. 55 * Set this property to "" if no close box is required. 56 * @property {Size} infoBoxClearance Minimum offset (in pixels) from the InfoBox to the 57 * map edge after an auto-pan. 58 * @property {boolean} [isHidden=false] Hide the InfoBox on <tt>open</tt>. 59 * [Deprecated in favor of the <tt>visible</tt> property.] 60 * @property {boolean} [visible=true] Show the InfoBox on <tt>open</tt>. 61 * @property {boolean} alignBottom Align the bottom left corner of the InfoBox to the <code>position</code> 62 * location (default is <tt>false</tt> which means that the top left corner of the InfoBox is aligned). 63 * @property {string} pane The pane where the InfoBox is to appear (default is "floatPane"). 64 * Set the pane to "mapPane" if the InfoBox is being used as a map label. 65 * Valid pane names are the property names for the <tt>google.maps.MapPanes</tt> object. 66 * @property {boolean} enableEventPropagation Propagate mousedown, mousemove, mouseover, mouseout, 67 * mouseup, click, dblclick, touchstart, touchend, touchmove, and contextmenu events in the InfoBox
68 * (default is <tt>false</tt> to mimic the behavior of a <tt>google.maps.InfoWindow</tt>). Set 69 * this property to <tt>true</tt> if the InfoBox is being used as a map label. 70 */ 71 72/** 73 * Creates an InfoBox with the options specified in {@link InfoBoxOptions}. 74 * Call <tt>InfoBox.open</tt> to add the box to the map. 75 * @constructor 76 * @param {InfoBoxOptions} [opt_opts] 77 */ 78 79 const google = (window.top && window.top.google) || (window.google) || google; 80 81 function InfoBox(opt_opts) { 82 83 opt_opts = opt_opts || {}; 84 85 google.maps.OverlayView.apply(this, arguments); 86 87 // Standard options (in common with google.maps.InfoWindow): 88 // 89 this.content_ = opt_opts.content || ""; 90 this.disableAutoPan_ = opt_opts.disableAutoPan || false; 91 this.maxWidth_ = opt_opts.maxWidth || 0; 92 this.pixelOffset_ = opt_opts.pixelOffset || new google.maps.Size(0, 0); 93 this.position_ = opt_opts.position || new google.maps.LatLng(0, 0); 94 this.zIndex_ = opt_opts.zIndex || null; 95 96 // Additional options (unique to InfoBox): 97 // 98 this.boxClass_ = opt_opts.boxClass || "infoBox"; 99 this.boxStyle_ = opt_opts.boxStyle || {}; 100 this.closeBoxMargin_ = opt_opts.closeBoxMargin || "2px"; 101 this.closeBoxURL_ = opt_opts.closeBoxURL || "//www.google.com/intl/en_us/mapfiles/close.gif"; 102 if (opt_opts.closeBoxURL === "") { 103 this.closeBoxURL_ = ""; 104 } 105 this.closeBoxTitle_ = opt_opts.closeBoxTitle || " Close "; 106 this.infoBoxClearance_ = opt_opts.infoBoxClearance || new google.maps.Size(1, 1); 107 108 if (typeof opt_opts.visible === "undefined") { 109 if (typeof opt_opts.isHidden === "undefined") { 110 opt_opts.visible = true; 111 } else { 112 opt_opts.visible = !opt_opts.isHidden; 113 } 114 } 115 this.isHidden_ = !opt_opts.visible; 116 117 this.alignBottom_ = opt_opts.alignBottom || false; 118 this.pane_ = opt_opts.pane || "floatPane"; 119 this.enableEventPropagation_ = opt_opts.enableEventPropagation || false; 120 121 this.div_ = null; 122 this.closeListener_ = null; 123 this.moveListener_ = null; 124 this.contextListener_ = null; 125 this.eventListeners_ = null; 126 this.fixedWidthSet_ = null; 127 } 128 129 /* InfoBox extends OverlayView in the Google Maps API v3. 130 */ 131 InfoBox.prototype = new google.maps.OverlayView(); 132 133 /** 134 * Creates the DIV representing the InfoBox. 135 * @private 136 */ 137 InfoBox.prototype.createInfoBoxDiv_ = function () { 138 139 var i; 140 var events; 141 var bw; 142 var me = this; 143 144 // This handler prevents an event in the InfoBox from being passed on to the map. 145 // 146 var cancelHandler = function (e) { 147 e.cancelBubble = true; 148 if (e.stopPropagation) { 149 e.stopPropagation(); 150 } 151 }; 152 153 // This handler ignores the current event in the InfoBox and conditionally prevents 154 // the event from being passed on to the map. It is used for the contextmenu event. 155 // 156 var ignoreHandler = function (e) { 157 158 e.returnValue = false; 159 160 if (e.preventDefault) { 161 162 e.preventDefault(); 163 } 164 165 if (!me.enableEventPropagation_) { 166 167 cancelHandler(e); 168 } 169 }; 170 171 if (!this.div_) { 172 173 this.div_ = document.createElement("div"); 174 175 this.setBoxStyle_(); 176 177 if (typeof this.content_.nodeType === "undefined") { 178 this.div_.innerHTML = this.getCloseBoxImg_() + this.content_; 179 } else { 180 this.div_.innerHTML = this.getCloseBoxImg_(); 181 this.div_.appendChild(this.content_); 182 } 183 184 // Add the InfoBox DIV to the DOM 185 this.getPanes()[this.pane_].appendChild(this.div_); 186 187 this.addClickHandler_(); 188 189 if (this.div_.style.width) { 190 191 this.fixedWidthSet_ = true; 192 193 } else { 194 195 if (this.maxWidth_ !== 0 && this.div_.offsetWidth > this.maxWidth_) { 196 197 this.div_.style.width = this.maxWidth_; 198 this.div_.style.overflow = "auto"; 199 this.fixedWidthSet_ = true; 200 201 } else { // The following code is needed to overcome problems with MSIE 202 203 bw = this.getBoxWidths_(); 204 205 this.div_.style.width = (this.div_.offsetWidth - bw.left - bw.right) + "px"; 206 this.fixedWidthSet_ = false;
207 } 208 } 209 210 this.panBox_(this.disableAutoPan_); 211 212 if (!this.enableEventPropagation_) { 213 214 this.eventListeners_ = []; 215 216 // Cancel event propagation. 217 // 218 // Note: mousemove not included (to resolve Issue 152) 219 events = ["mousedown", "mouseover", "mouseout", "mouseup", 220 "click", "dblclick", "touchstart", "touchend", "touchmove"]; 221 222 for (i = 0; i < events.length; i++) { 223 224 this.eventListeners_.push(google.maps.event.addDomListener(this.div_, events[i], cancelHandler)); 225 } 226 227 // Workaround for Google bug that causes the cursor to change to a pointer 228 // when the mouse moves over a marker underneath InfoBox. 229 this.eventListeners_.push(google.maps.event.addDomListener(this.div_, "mouseover", function (e) { 230 this.style.cursor = "default"; 231 })); 232 } 233 234 this.contextListener_ = google.maps.event.addDomListener(this.div_, "contextmenu", ignoreHandler); 235 236 /** 237 * This event is fired when the DIV containing the InfoBox's content is attached to the DOM. 238 * @name InfoBox#domready 239 * @event 240 */ 241 google.maps.event.trigger(this, "domready"); 242 } 243 }; 244 245 /** 246 * Returns the HTML <IMG> tag for the close box. 247 * @private 248 */ 249 InfoBox.prototype.getCloseBoxImg_ = function () { 250 251 var img = ""; 252 253 if (this.closeBoxURL_ !== "") { 254 /* 255 img = "<img"; 256 img += " src='" + this.closeBoxURL_ + "'"; 257 img += " align=right"; // Do this because Opera chokes on style='float: right;' 258 img += " title='" + this.closeBoxTitle_ + "'"; 259 img += " style='"; 260 img += " position: relative;"; // Required by MSIE 261 img += " cursor: pointer;"; 262 img += " margin: " + this.closeBoxMargin_ + ";"; 263 img += "'>"; 264 */ 265 266 img = '<span class="supreme_google_map_infowindow_close" title="' + this.closeBoxTitle_ + '">×</span>'; 267 } 268 269 return img; 270 }; 271 272 /** 273 * Adds the click handler to the InfoBox close box. 274 * @private 275 */ 276 InfoBox.prototype.addClickHandler_ = function () { 277 278 var closeBox; 279 280 if (this.closeBoxURL_ !== "") { 281 282 closeBox = this.div_.firstChild; 283 this.closeListener_ = google.maps.event.addDomListener(closeBox, "click", this.getCloseClickHandler_()); 284 285 } else { 286 287 this.closeListener_ = null; 288 } 289 }; 290 291 /** 292 * Returns the function to call when the user clicks the close box of an InfoBox. 293 * @private 294 */ 295 InfoBox.prototype.getCloseClickHandler_ = function () { 296 297 var me = this; 298 299 return function (e) { 300 301 // 1.0.3 fix: Always prevent propagation of a close box click to the map: 302 e.cancelBubble = true; 303 304 if (e.stopPropagation) { 305 306 e.stopPropagation(); 307 } 308 309 /** 310 * This event is fired when the InfoBox's close box is clicked. 311 * @name InfoBox#closeclick 312 * @event 313 */ 314 google.maps.event.trigger(me, "closeclick"); 315 316 me.close(); 317 }; 318 }; 319 320 /** 321 * Pans the map so that the InfoBox appears entirely within the map's visible area. 322 * @private 323 */ 324 InfoBox.prototype.panBox_ = function (disablePan) { 325 326 var map; 327 var bounds; 328 var xOffset = 0, yOffset = 0; 329 330 if (!disablePan) { 331 332 map = this.getMap(); 333 334 if (map instanceof google.maps.Map) { // Only pan if attached to map, not panorama 335 336 if (!map.getBounds().contains(this.position_)) { 337 // Marker not in visible area of map, so set center 338 // of map to the marker position first. 339 map.setCenter(this.position_); 340 } 341 342 var iwOffsetX = this.pixelOffset_.width; 343 var iwOffsetY = this.pixelOffset_.height; 344 var iwWidth = this.div_.offsetWidth; 345 var iwHeight = this.div_.offsetHeight; 346 var padX = this.infoBoxClearance_.width; 347 var padY = this.infoBoxClearance_.height; 348 349 if (map.panToBounds.length === 2) { 350 // Using projection.fromLatLngToContainerPixel to compute the infowindow position 351 // does not work correctly anymore for JS Maps API v3.32 and above if there is a 352 // previous synchronous call that causes the map to animate (e.g. setCenter when 353 // the position is not within bounds). Hence, we are using panToBounds with 354 // padding instead, which works synchronously.
355 var padding = {left: 0, right: 0, top: 0, bottom: 0}; 356 padding.left = -iwOffsetX + padX; 357 padding.right = iwOffsetX + iwWidth + padX; 358 if (this.alignBottom_) { 359 padding.top = -iwOffsetY + padY + iwHeight; 360 padding.bottom = iwOffsetY + padY; 361 } else { 362 padding.top = -iwOffsetY + padY; 363 padding.bottom = iwOffsetY + iwHeight + padY; 364 } 365 map.panToBounds(new google.maps.LatLngBounds(this.position_), padding); 366 } else { 367 var mapDiv = map.getDiv(); 368 var mapWidth = mapDiv.offsetWidth; 369 var mapHeight = mapDiv.offsetHeight; 370 var pixPosition = this.getProjection().fromLatLngToContainerPixel(this.position_); 371 372 if (pixPosition.x < (-iwOffsetX + padX)) { 373 xOffset = pixPosition.x + iwOffsetX - padX; 374 } else if ((pixPosition.x + iwWidth + iwOffsetX + padX) > mapWidth) { 375 xOffset = pixPosition.x + iwWidth + iwOffsetX + padX - mapWidth; 376 } 377 if (this.alignBottom_) { 378 if (pixPosition.y < (-iwOffsetY + padY + iwHeight)) { 379 yOffset = pixPosition.y + iwOffsetY - padY - iwHeight; 380 } else if ((pixPosition.y + iwOffsetY + padY) > mapHeight) { 381 yOffset = pixPosition.y + iwOffsetY + padY - mapHeight; 382 } 383 } else { 384 if (pixPosition.y < (-iwOffsetY + padY)) { 385 yOffset = pixPosition.y + iwOffsetY - padY; 386 } else if ((pixPosition.y + iwHeight + iwOffsetY + padY) > mapHeight) { 387 yOffset = pixPosition.y + iwHeight + iwOffsetY + padY - mapHeight; 388 } 389 } 390 391 if (!(xOffset === 0 && yOffset === 0)) { 392 393 // Move the map to the shifted center. 394 // 395 var c = map.getCenter(); 396 map.panBy(xOffset, yOffset); 397 } 398 } 399 } 400 } 401 }; 402 403 /** 404 * Sets the style of the InfoBox by setting the style sheet and applying 405 * other specific styles requested. 406 * @private 407 */ 408 InfoBox.prototype.setBoxStyle_ = function () { 409 410 var i, boxStyle; 411 412 if (this.div_) { 413 414 // Apply style values from the style sheet defined in the boxClass parameter: 415 this.div_.className = this.boxClass_; 416 417 // Clear existing inline style values: 418 this.div_.style.cssText = ""; 419 420 // Apply style values defined in the boxStyle parameter: 421 boxStyle = this.boxStyle_; 422 for (i in boxStyle) { 423 424 if (boxStyle.hasOwnProperty(i)) { 425 426 this.div_.style[i] = boxStyle[i]; 427 } 428 } 429 430 // Fix for iOS disappearing InfoBox problem. 431 // See http://stackoverflow.com/questions/9229535/google-maps-markers-disappear-at-certain-zoom-level-only-on-iphone-ipad 432 // Required: use "matrix" technique to specify transforms in order to avoid this bug. 433 if ((typeof this.div_.style.WebkitTransform === "undefined") || (this.div_.style.WebkitTransform.indexOf("translateZ") === -1 && this.div_.style.WebkitTransform.indexOf("matrix") === -1)) { 434 435 this.div_.style.WebkitTransform = "translateZ(0)"; 436 } 437 438 // Fix up opacity style for benefit of MSIE: 439 // 440 if (typeof this.div_.style.opacity !== "undefined" && this.div_.style.opacity !== "") { 441 // See http://www.quirksmode.org/css/opacity.html 442 this.div_.style.MsFilter = "\"progid:DXImageTransform.Microsoft.Alpha(Opacity=" + (this.div_.style.opacity * 100) + ")\""; 443 this.div_.style.filter = "alpha(opacity=" + (this.div_.style.opacity * 100) + ")"; 444 } 445 446 // Apply required styles: 447 // 448 this.div_.style.position = "absolute"; 449 this.div_.style.visibility = 'hidden'; 450 if (this.zIndex_ !== null) { 451 452 this.div_.style.zIndex = this.zIndex_; 453 } 454 } 455 }; 456 457 /** 458 * Get the widths of the borders of the InfoBox. 459 * @private 460 * @return {Object} widths object (top, bottom left, right) 461 */ 462 InfoBox.prototype.getBoxWidths_ = function () { 463 464 var computedStyle; 465 var bw = {top: 0, bottom: 0, left: 0, right: 0}; 466 var box = this.div_; 467 468 if (document.defaultView && document.defaultView.getComputedStyle) { 469 470 computedStyle = box.ownerDocument.defaultView.getComputedStyle(box, ""); 471 472 if (computedStyle) { 473 474 // The computed styles are always in pixel units (good!) 475 bw.top = parseInt(computedStyle.borderTopWidth, 10) || 0; 476 bw.bottom = parseInt(computedStyle.borderBottomWidth, 10) || 0; 477 bw.left = parseInt(computedStyle.borderLeftWidth, 10) || 0; 478 bw.right = parseInt(computedStyle.borderRightWidth, 10) || 0; 479 } 480 481 } else if (document.documentElement.currentStyle) { // MSIE 482 483 if (box.currentStyle) { 484 485 // The current styles may not be in pixel units, but assume they are (bad!) 486 bw.top = parseInt(box.currentStyle.borderTopWidth, 10) || 0; 487 bw.bottom = parseInt(box.currentStyle.borderBottomWidth, 10) || 0; 488 bw.left = parseInt(box.currentStyle.borderLeftWidth, 10) || 0; 489 bw.right = parseInt(box.currentStyle.borderRightWidth, 10) || 0; 490 } 491 } 492 493 return bw; 494 }; 495 496 /** 497 * Invoked when <tt>close</tt> is called. Do not call it directly. 498 */ 499 InfoBox.prototype.onRemove = function () { 500 501 if (this.div_) { 502 503 this.div_.parentNode.removeChild(this.div_); 504 this.div_ = null; 505 } 506 }; 507 508 /** 509 * Draws the InfoBox based on the current map projection and zoom level. 510 */ 511 InfoBox.prototype.draw = function () { 512 513 this.createInfoBoxDiv_(); 514 515 var pixPosition = this.getProjection().fromLatLngToDivPixel(this.position_); 516 517 this.div_.style.left = (pixPosition.x + this.pixelOffset_.width) + "px"; 518 519 if (this.alignBottom_) { 520 this.div_.style.bottom = -(pixPosition.y + this.pixelOffset_.height) + "px"; 521 } else { 522 this.div_.style.top = (pixPosition.y + this.pixelOffset_.height) + "px"; 523 } 524 525 if (this.isHidden_) { 526 527 this.div_.style.visibility = "hidden"; 528 529 } else { 530
531 this.div_.style.visibility = "visible"; 532 } 533 }; 534 535 /** 536 * Sets the options for the InfoBox. Note that changes to the <tt>maxWidth</tt>, 537 * <tt>closeBoxMargin</tt>, <tt>closeBoxTitle</tt>, <tt>closeBoxURL</tt>, and 538 * <tt>enableEventPropagation</tt> properties have no affect until the current 539 * InfoBox is <tt>close</tt>d and a new one is <tt>open</tt>ed. 540 * @param {InfoBoxOptions} opt_opts 541 */ 542 InfoBox.prototype.setOptions = function (opt_opts) { 543 if (typeof opt_opts.boxClass !== "undefined") { // Must be first 544 545 this.boxClass_ = opt_opts.boxClass; 546 this.setBoxStyle_(); 547 } 548 if (typeof opt_opts.boxStyle !== "undefined") { // Must be second 549 550 this.boxStyle_ = opt_opts.boxStyle; 551 this.setBoxStyle_(); 552 } 553 if (typeof opt_opts.content !== "undefined") { 554 555 this.setContent(opt_opts.content); 556 } 557 if (typeof opt_opts.disableAutoPan !== "undefined") { 558 559 this.disableAutoPan_ = opt_opts.disableAutoPan; 560 } 561 if (typeof opt_opts.maxWidth !== "undefined") { 562 563 this.maxWidth_ = opt_opts.maxWidth; 564 } 565 if (typeof opt_opts.pixelOffset !== "undefined") { 566 567 this.pixelOffset_ = opt_opts.pixelOffset; 568 } 569 if (typeof opt_opts.alignBottom !== "undefined") { 570 571 this.alignBottom_ = opt_opts.alignBottom; 572 } 573 if (typeof opt_opts.position !== "undefined") { 574 575 this.setPosition(opt_opts.position); 576 } 577 if (typeof opt_opts.zIndex !== "undefined") { 578 579 this.setZIndex(opt_opts.zIndex); 580 } 581 if (typeof opt_opts.closeBoxMargin !== "undefined") { 582 583 this.closeBoxMargin_ = opt_opts.closeBoxMargin; 584 } 585 if (typeof opt_opts.closeBoxURL !== "undefined") { 586 587 this.closeBoxURL_ = opt_opts.closeBoxURL; 588 } 589 if (typeof opt_opts.closeBoxTitle !== "undefined") { 590 591 this.closeBoxTitle_ = opt_opts.closeBoxTitle; 592 } 593 if (typeof opt_opts.infoBoxClearance !== "undefined") { 594 595 this.infoBoxClearance_ = opt_opts.infoBoxClearance; 596 } 597 if (typeof opt_opts.isHidden !== "undefined") { 598 599 this.isHidden_ = opt_opts.isHidden; 600 } 601 if (typeof opt_opts.visible !== "undefined") { 602 603 this.isHidden_ = !opt_opts.visible; 604 } 605 if (typeof opt_opts.enableEventPropagation !== "undefined") { 606 607 this.enableEventPropagation_ = opt_opts.enableEventPropagation; 608 } 609 610 if (this.div_) { 611 612 this.draw(); 613 } 614 }; 615 616 /** 617 * Sets the content of the InfoBox. 618 * The content can be plain text or an HTML DOM node. 619 * @param {string|Node} content 620 */ 621 InfoBox.prototype.setContent = function (content) { 622 this.content_ = content; 623 624 if (this.div_) { 625 626 if (this.closeListener_) { 627 628 google.maps.event.removeListener(this.closeListener_); 629 this.closeListener_ = null; 630 } 631 632 // Odd code required to make things work with MSIE. 633 // 634 if (!this.fixedWidthSet_) { 635 636 this.div_.style.width = ""; 637 } 638 639 if (typeof content.nodeType === "undefined") { 640 this.div_.innerHTML = this.getCloseBoxImg_() + content; 641 } else { 642 this.div_.innerHTML = this.getCloseBoxImg_(); 643 this.div_.appendChild(content); 644 } 645 646 // Perverse code required to make things work with MSIE. 647 // (Ensures the close box does, in fact, float to the right.) 648 // 649 if (!this.fixedWidthSet_) { 650 this.div_.style.width = this.div_.offsetWidth + "px"; 651 if (typeof content.nodeType === "undefined") { 652 this.div_.innerHTML = this.getCloseBoxImg_() + content; 653 } else { 654 this.div_.innerHTML = this.getCloseBoxImg_(); 655 this.div_.appendChild(content); 656 } 657 } 658 659 this.addClickHandler_(); 660 } 661 662 /** 663 * This event is fired when the content of the InfoBox changes. 664 * @name InfoBox#content_changed 665 * @event 666 */ 667 google.maps.event.trigger(this, "content_changed"); 668 }; 669 670 /** 671 * Sets the geographic location of the InfoBox. 672 * @param {LatLng} latlng 673 */ 674 InfoBox.prototype.setPosition = function (latlng) { 675 676 this.position_ = latlng; 677 678 if (this.div_) { 679 680 this.draw(); 681 } 682 683 /**
684 * This event is fired when the position of the InfoBox changes. 685 * @name InfoBox#position_changed 686 * @event 687 */ 688 google.maps.event.trigger(this, "position_changed"); 689 }; 690 691 /** 692 * Sets the zIndex style for the InfoBox. 693 * @param {number} index 694 */ 695 InfoBox.prototype.setZIndex = function (index) { 696 697 this.zIndex_ = index; 698 699 if (this.div_) { 700 701 this.div_.style.zIndex = index; 702 } 703 704 /** 705 * This event is fired when the zIndex of the InfoBox changes. 706 * @name InfoBox#zindex_changed 707 * @event 708 */ 709 google.maps.event.trigger(this, "zindex_changed"); 710 }; 711 712 /** 713 * Sets the visibility of the InfoBox. 714 * @param {boolean} isVisible 715 */ 716 InfoBox.prototype.setVisible = function (isVisible) { 717 718 this.isHidden_ = !isVisible; 719 if (this.div_) { 720 this.div_.style.visibility = (this.isHidden_ ? "hidden" : "visible"); 721 } 722 }; 723 724 /** 725 * Returns the content of the InfoBox. 726 * @returns {string} 727 */ 728 InfoBox.prototype.getContent = function () { 729 730 return this.content_; 731 }; 732 733 /** 734 * Returns the geographic location of the InfoBox. 735 * @returns {LatLng} 736 */ 737 InfoBox.prototype.getPosition = function () { 738 739 return this.position_; 740 }; 741 742 /** 743 * Returns the zIndex for the InfoBox. 744 * @returns {number} 745 */ 746 InfoBox.prototype.getZIndex = function () { 747 748 return this.zIndex_; 749 }; 750 751 /** 752 * Returns a flag indicating whether the InfoBox is visible. 753 * @returns {boolean} 754 */ 755 InfoBox.prototype.getVisible = function () { 756 757 var isVisible; 758 759 if ((typeof this.getMap() === "undefined") || (this.getMap() === null)) { 760 isVisible = false; 761 } else { 762 isVisible = !this.isHidden_; 763 } 764 return isVisible; 765 }; 766 767 /** 768 * Returns the width of the InfoBox in pixels. 769 * @returns {number} 770 */ 771 InfoBox.prototype.getWidth = function () { 772 var width = null; 773 774 if (this.div_) { 775 width = this.div_.offsetWidth; 776 } 777 778 return width; 779 }; 780 781 /** 782 * Returns the height of the InfoBox in pixels. 783 * @returns {number} 784 */ 785 InfoBox.prototype.getHeight = function () { 786 var height = null; 787 788 if (this.div_) { 789 height = this.div_.offsetHeight; 790 } 791 792 return height; 793 }; 794 795 /** 796 * Shows the InfoBox. [Deprecated; use <tt>setVisible</tt> instead.] 797 */ 798 InfoBox.prototype.show = function () { 799 800 this.isHidden_ = false; 801 if (this.div_) { 802 this.div_.style.visibility = "visible"; 803 } 804 }; 805 806 /** 807 * Hides the InfoBox. [Deprecated; use <tt>setVisible</tt> instead.] 808 */ 809 InfoBox.prototype.hide = function () { 810 811 this.isHidden_ = true; 812 if (this.div_) { 813 this.div_.style.visibility = "hidden"; 814 } 815 }; 816 817 /** 818 * Adds the InfoBox to the specified map or Street View panorama. If <tt>anchor</tt> 819 * (usually a <tt>google.maps.Marker</tt>) is specified, the position 820 * of the InfoBox is set to the position of the <tt>anchor</tt>. If the 821 * anchor is dragged to a new location, the InfoBox moves as well. 822 * @param {Map|StreetViewPanorama} map 823 * @param {MVCObject} [anchor] 824 */ 825 InfoBox.prototype.open = function (map, anchor) { 826 827 var me = this; 828 829 if (anchor) { 830 831 this.setPosition(anchor.getPosition()); // BUG FIX 2/17/2018: needed for v3.32 832 this.moveListener_ = google.maps.event.addListener(anchor, "position_changed", function () { 833 me.setPosition(this.getPosition()); 834 }); 835 } 836 837 this.setMap(map); 838 839 if (this.div_) { 840 841 this.panBox_(this.disableAutoPan_); // BUG FIX 2/17/2018: add missing parameter 842 } 843 }; 844 845 /** 846 * Removes the InfoBox from the map. 847 */ 848 InfoBox.prototype.close = function () { 849 850 var i; 851 852 if (this.closeListener_) { 853 854 google.maps.event.removeListener(this.closeListener_); 855 this.closeListener_ = null; 856 } 857 858 if (this.eventListeners_) { 859 860 for (i = 0; i < this.eventListeners_.length; i++) { 861 862 google.maps.event.removeListener(this.eventListeners_[i]); 863 } 864 this.eventListeners_ = null; 865 } 866 867 if (this.moveListener_) { 868 869 google.maps.event.removeListener(this.moveListener_); 870 this.moveListener_ = null; 871 } 872 873 if (this.contextListener_) { 874 875 google.maps.event.removeListener(this.contextListener_); 876 this.contextListener_ = null; 877 } 878 879 this.setMap(null); 880 };
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.