1function JetGMInfoBox(opt_opts) { 2 3 opt_opts = opt_opts || {}; 4 5 google.maps.OverlayView.apply(this, arguments); 6 7 // Standard options (in common with google.maps.InfoWindow): 8 this.content_ = opt_opts.content || ""; 9 this.disableAutoPan_ = opt_opts.disableAutoPan || false; 10 this.maxWidth_ = opt_opts.maxWidth || 0; 11 this.pixelOffset_ = opt_opts.pixelOffset || new google.maps.Size(0, 0); 12 this.position_ = opt_opts.position || new google.maps.LatLng(0, 0); 13 this.zIndex_ = opt_opts.zIndex || null; 14 15 // Additional options (unique to JetGMInfoBox): 16 this.boxClass_ = opt_opts.boxClass || "infoBox"; 17 this.boxStyle_ = opt_opts.boxStyle || {}; 18 this.closeBoxMargin_ = opt_opts.closeBoxMargin || "2px"; 19 this.closeBoxURL_ = opt_opts.closeBoxURL || "//www.google.com/intl/en_us/mapfiles/close.gif"; 20 if (opt_opts.closeBoxURL === "") { 21 this.closeBoxURL_ = ""; 22 } 23 this.closeBoxTitle_ = opt_opts.closeBoxTitle || " Close "; 24 this.infoBoxClearance_ = opt_opts.infoBoxClearance || new google.maps.Size(1, 1); 25 26 if (typeof opt_opts.visible === "undefined") { 27 if (typeof opt_opts.isHidden === "undefined") { 28 opt_opts.visible = true; 29 } else { 30 opt_opts.visible = !opt_opts.isHidden; 31 } 32 } 33 this.isHidden_ = !opt_opts.visible; 34 35 this.alignBottom_ = opt_opts.alignBottom || false; 36 this.pane_ = opt_opts.pane || "floatPane"; 37 this.enableEventPropagation_ = opt_opts.enableEventPropagation || false; 38 39 this.div_ = null; 40 this.closeListener_ = null; 41 this.moveListener_ = null; 42 this.contextListener_ = null; 43 this.eventListeners_ = null; 44 this.fixedWidthSet_ = null; 45 46} 47 48/* JetGMInfoBox extends OverlayView in the Google Maps API v3. 49 */ 50JetGMInfoBox.prototype = new google.maps.OverlayView(); 51 52JetGMInfoBox.prototype.addEventListener = function ( target, type, handler, useCapture ) { 53 54 useCapture = useCapture || false; 55 56 target.addEventListener( type, handler, useCapture ); 57 58 return { 59 target: target, 60 type: type, 61 handler: handler, 62 useCapture: useCapture, 63 } 64} 65 66JetGMInfoBox.prototype.removeEventListener = function ( listener ) { 67 listener.target.removeEventListener( listener.type, listener.handler, listener.useCapture ); 68} 69 70/** 71 * Creates the DIV representing the JetGMInfoBox. 72 * @private 73 */ 74JetGMInfoBox.prototype.createJetGMInfoBoxDiv_ = function () { 75 76 var i; 77 var events; 78 var bw; 79 var me = this; 80 var clickableElements = [ 81 'A', 82 'BUTTON', 83 'INPUT', 84 'TEXTAREA' 85 ]; 86 87 // This handler prevents an event in the JetGMInfoBox from being passed on to the map. 88 // 89 var cancelHandler = function (e) { 90 var hasListingOverlay = 'click' === e.type && e.currentTarget.querySelector('.jet-engine-listing-overlay-wrap'); 91 92 if ( hasListingOverlay ) { 93 return; 94 } 95 96 /** 97 * @see https://github.com/Crocoblock/issues-tracker/issues/15546 98 * 99 * do not stop event propagation for clickable elements 100 */ 101 102 if ( 'click' === e.type && clickableElements.includes( e.target.tagName ) ) { 103 return; 104 } 105 106 e.cancelBubble = true; 107 if (e.stopPropagation) { 108 e.stopPropagation(); 109 } 110 }; 111 112 // This handler ignores the current event in the JetGMInfoBox and conditionally prevents 113 // the event from being passed on to the map. It is used for the contextmenu event. 114 // 115 var ignoreHandler = function (e) { 116 117 e.returnValue = false; 118 119 if (e.preventDefault) { 120 121 e.preventDefault(); 122 } 123 124 if (!me.enableEventPropagation_) { 125 126 cancelHandler(e); 127 } 128 }; 129 130 if (!this.div_) { 131 132 this.div_ = document.createElement("div"); 133 134 this.setBoxStyle_(); 135 136 if (typeof this.content_.nodeType === "undefined") { 137 this.div_.innerHTML = this.getCloseBoxImg_() + this.content_; 138 } else { 139 this.div_.innerHTML = this.getCloseBoxImg_(); 140 this.div_.appendChild(this.content_); 141 } 142 143 // Add the JetGMInfoBox DIV to the DOM 144 this.getPanes()[this.pane_].appendChild(this.div_); 145 146 this.addClickHandler_(); 147 148 if (this.div_.style.width) { 149 150 this.fixedWidthSet_ = true; 151 152 } else { 153 154 155 if ( this.maxWidth_ !== 0 ) { 156 157 this.div_.style.width = this.maxWidth_ + 'px'; 158 this.fixedWidthSet_ = true; 159 160 } else { // The following code is needed to overcome problems with MSIE 161 162 bw = this.getBoxWidths_(); 163 164 this.div_.style.width = (this.div_.offsetWidth - bw.left - bw.right) + "px"; 165 this.fixedWidthSet_ = false;
vendor: 3,743 bytes, lines 166-309
166 } 167 } 168 169 this.panBox_(this.disableAutoPan_); 170 171 if (!this.enableEventPropagation_) { 172 173 this.eventListeners_ = []; 174 175 // Cancel event propagation. 176 // 177 // Note: mousemove not included (to resolve Issue 152) 178 events = ["mousedown", "mouseover", "mouseout", "mouseup", 179 "click", "dblclick", "touchstart", "touchend", "touchmove"]; 180 181 for (i = 0; i < events.length; i++) { 182 183 this.eventListeners_.push(this.addEventListener(this.div_, events[i], cancelHandler)); 184 } 185 186 // Workaround for Google bug that causes the cursor to change to a pointer 187 // when the mouse moves over a marker underneath JetGMInfoBox. 188 this.eventListeners_.push(this.addEventListener(this.div_, "mouseover", function (e) { 189 this.style.cursor = "default"; 190 })); 191 } 192 193 this.contextListener_ = this.addEventListener(this.div_, "contextmenu", ignoreHandler); 194 195 /** 196 * This event is fired when the DIV containing the JetGMInfoBox's content is attached to the DOM. 197 * @name JetGMInfoBox#domready 198 * @event 199 */ 200 google.maps.event.trigger(this, "domready"); 201 } 202}; 203 204/** 205 * Returns the HTML <IMG> tag for the close box. 206 * @private 207 */ 208JetGMInfoBox.prototype.getCloseBoxImg_ = function () { 209 210 var img = ""; 211 212 if (this.closeBoxURL_ !== "") { 213 214 img = "<img"; 215 img += " src='" + this.closeBoxURL_ + "'"; 216 img += " align=right"; // Do this because Opera chokes on style='float: right;' 217 img += " title='" + this.closeBoxTitle_ + "'"; 218 img += " class='jet-map-close'"; 219 img += " style='"; 220 img += " margin: " + this.closeBoxMargin_ + ";"; 221 img += "'>"; 222 } 223 224 return img; 225}; 226 227/** 228 * Adds the click handler to the JetGMInfoBox close box. 229 * @private 230 */ 231JetGMInfoBox.prototype.addClickHandler_ = function () { 232 233 var closeBox; 234 235 if (this.closeBoxURL_ !== "") { 236 237 closeBox = this.div_.firstChild; 238 this.closeListener_ = this.addEventListener(closeBox, "click", this.getCloseClickHandler_()); 239 240 } else { 241 242 this.closeListener_ = null; 243 } 244}; 245 246/** 247 * Returns the function to call when the user clicks the close box of an JetGMInfoBox. 248 * @private 249 */ 250JetGMInfoBox.prototype.getCloseClickHandler_ = function () { 251 252 var me = this; 253 254 return function (e) { 255 256 // 1.0.3 fix: Always prevent propagation of a close box click to the map: 257 e.cancelBubble = true; 258 259 if (e.stopPropagation) { 260 261 e.stopPropagation(); 262 } 263 264 /** 265 * This event is fired when the JetGMInfoBox's close box is clicked. 266 * @name JetGMInfoBox#closeclick 267 * @event 268 */ 269 google.maps.event.trigger(me, "closeclick"); 270 271 me.close(); 272 }; 273}; 274 275/** 276 * Pans the map so that the JetGMInfoBox appears entirely within the map's visible area. 277 * @private 278 */ 279JetGMInfoBox.prototype.panBox_ = function (disablePan) { 280 281 var map; 282 var bounds; 283 var xOffset = 0, yOffset = 0; 284 285 if (!disablePan) { 286 287 map = this.getMap(); 288 289 if (map instanceof google.maps.Map) { // Only pan if attached to map, not panorama 290 291 if (!map.getBounds().contains(this.position_)) { 292 // Marker not in visible area of map, so set center 293 // of map to the marker position first. 294 map.setCenter(this.position_); 295 } 296 297 var iwOffsetX = this.pixelOffset_.width; 298 var iwOffsetY = this.pixelOffset_.height; 299 var iwWidth = this.div_.offsetWidth; 300 var iwHeight = this.div_.offsetHeight; 301 var padX = this.infoBoxClearance_.width; 302 var padY = this.infoBoxClearance_.height; 303 304 if (map.panToBounds.length == 2) { 305 // Using projection.fromLatLngToContainerPixel to compute the infowindow position 306 // does not work correctly anymore for JS Maps API v3.32 and above if there is a 307 // previous synchronous call that causes the map to animate (e.g. setCenter when 308 // the position is not within bounds). Hence, we are using panToBounds with 309 // padding instead, which works synchronously.
310 var padding = {left: 0, right: 0, top: 0, bottom: 0}; 311 padding.left = -iwOffsetX + padX; 312 padding.right = iwOffsetX + iwWidth + padX; 313 if (this.alignBottom_) { 314 padding.top = -iwOffsetY + padY + iwHeight; 315 padding.bottom = iwOffsetY + padY; 316 } else { 317 padding.top = -iwOffsetY + padY; 318 padding.bottom = iwOffsetY + iwHeight + padY; 319 } 320 map.panToBounds(new google.maps.LatLngBounds(this.position_), padding); 321 } else { 322 var mapDiv = map.getDiv(); 323 var mapWidth = mapDiv.offsetWidth; 324 var mapHeight = mapDiv.offsetHeight; 325 var pixPosition = this.getProjection().fromLatLngToContainerPixel(this.position_); 326 327 if (pixPosition.x < (-iwOffsetX + padX)) { 328 xOffset = pixPosition.x + iwOffsetX - padX; 329 } else if ((pixPosition.x + iwWidth + iwOffsetX + padX) > mapWidth) { 330 xOffset = pixPosition.x + iwWidth + iwOffsetX + padX - mapWidth; 331 } 332 if (this.alignBottom_) { 333 if (pixPosition.y < (-iwOffsetY + padY + iwHeight)) { 334 yOffset = pixPosition.y + iwOffsetY - padY - iwHeight; 335 } else if ((pixPosition.y + iwOffsetY + padY) > mapHeight) { 336 yOffset = pixPosition.y + iwOffsetY + padY - mapHeight; 337 } 338 } else { 339 if (pixPosition.y < (-iwOffsetY + padY)) { 340 yOffset = pixPosition.y + iwOffsetY - padY; 341 } else if ((pixPosition.y + iwHeight + iwOffsetY + padY) > mapHeight) { 342 yOffset = pixPosition.y + iwHeight + iwOffsetY + padY - mapHeight; 343 } 344 } 345 346 if (!(xOffset === 0 && yOffset === 0)) { 347 348 // Move the map to the shifted center. 349 // 350 var c = map.getCenter(); 351 map.panBy(xOffset, yOffset); 352 } 353 } 354 } 355 } 356}; 357 358/** 359 * Sets the style of the JetGMInfoBox by setting the style sheet and applying 360 * other specific styles requested. 361 * @private 362 */ 363JetGMInfoBox.prototype.setBoxStyle_ = function () { 364 365 var i, boxStyle; 366 367 if (this.div_) { 368 369 // Apply style values from the style sheet defined in the boxClass parameter: 370 this.div_.className = this.boxClass_; 371 372 // Clear existing inline style values: 373 this.div_.style.cssText = ""; 374 375 // Apply style values defined in the boxStyle parameter: 376 boxStyle = this.boxStyle_; 377 for (i in boxStyle) { 378 379 if (boxStyle.hasOwnProperty(i)) { 380 381 this.div_.style[i] = boxStyle[i]; 382 } 383 } 384 385 // Fix for iOS disappearing JetGMInfoBox problem. 386 // See http://stackoverflow.com/questions/9229535/google-maps-markers-disappear-at-certain-zoom-level-only-on-iphone-ipad 387 // Required: use "matrix" technique to specify transforms in order to avoid this bug. 388 if ((typeof this.div_.style.WebkitTransform === "undefined") || (this.div_.style.WebkitTransform.indexOf("translateZ") === -1 && this.div_.style.WebkitTransform.indexOf("matrix") === -1)) { 389 390 this.div_.style.WebkitTransform = "translateZ(0)"; 391 } 392 393 // Fix up opacity style for benefit of MSIE: 394 // 395 if (typeof this.div_.style.opacity !== "undefined" && this.div_.style.opacity !== "") { 396 // See http://www.quirksmode.org/css/opacity.html 397 this.div_.style.MsFilter = "\"progid:DXImageTransform.Microsoft.Alpha(Opacity=" + (this.div_.style.opacity * 100) + ")\""; 398 this.div_.style.filter = "alpha(opacity=" + (this.div_.style.opacity * 100) + ")"; 399 } 400 401 // Apply required styles: 402 // 403 this.div_.style.position = "absolute"; 404 this.div_.style.visibility = 'hidden'; 405 if (this.zIndex_ !== null) { 406 407 this.div_.style.zIndex = this.zIndex_; 408 } 409 } 410}; 411 412/** 413 * Get the widths of the borders of the JetGMInfoBox. 414 * @private 415 * @return {Object} widths object (top, bottom left, right) 416 */ 417JetGMInfoBox.prototype.getBoxWidths_ = function () { 418 419 var computedStyle; 420 var bw = {top: 0, bottom: 0, left: 0, right: 0}; 421 var box = this.div_; 422 423 if (document.defaultView && document.defaultView.getComputedStyle) { 424 425 computedStyle = box.ownerDocument.defaultView.getComputedStyle(box, ""); 426 427 if (computedStyle) { 428 429 // The computed styles are always in pixel units (good!) 430 bw.top = parseInt(computedStyle.borderTopWidth, 10) || 0; 431 bw.bottom = parseInt(computedStyle.borderBottomWidth, 10) || 0; 432 bw.left = parseInt(computedStyle.borderLeftWidth, 10) || 0; 433 bw.right = parseInt(computedStyle.borderRightWidth, 10) || 0; 434 } 435 436 } else if (document.documentElement.currentStyle) { // MSIE 437 438 if (box.currentStyle) { 439 440 // The current styles may not be in pixel units, but assume they are (bad!) 441 bw.top = parseInt(box.currentStyle.borderTopWidth, 10) || 0; 442 bw.bottom = parseInt(box.currentStyle.borderBottomWidth, 10) || 0; 443 bw.left = parseInt(box.currentStyle.borderLeftWidth, 10) || 0; 444 bw.right = parseInt(box.currentStyle.borderRightWidth, 10) || 0; 445 } 446 } 447 448 return bw; 449}; 450 451/** 452 * Invoked when <tt>close</tt> is called. Do not call it directly. 453 */ 454JetGMInfoBox.prototype.onRemove = function () { 455 456 if (this.div_) { 457 458 this.div_.parentNode.removeChild(this.div_); 459 this.div_ = null; 460 } 461}; 462 463/** 464 * Draws the JetGMInfoBox based on the current map projection and zoom level. 465 */ 466JetGMInfoBox.prototype.draw = function () { 467 468 this.createJetGMInfoBoxDiv_(); 469 470 var pixPosition = this.getProjection().fromLatLngToDivPixel(this.position_); 471 472 this.div_.style.left = (pixPosition.x + this.pixelOffset_.width) + "px"; 473 474 if (this.alignBottom_) { 475 this.div_.style.bottom = -(pixPosition.y + this.pixelOffset_.height) + "px"; 476 } else { 477 this.div_.style.top = (pixPosition.y + this.pixelOffset_.height) + "px"; 478 } 479 480 if (this.isHidden_) { 481 482 this.div_.style.visibility = "hidden"; 483 484 } else { 485 486 this.div_.style.visibility = "visible"; 487 } 488}; 489 490/** 491 * Sets the options for the JetGMInfoBox. Note that changes to the <tt>maxWidth</tt>, 492 * <tt>closeBoxMargin</tt>, <tt>closeBoxTitle</tt>, <tt>closeBoxURL</tt>, and 493 * <tt>enableEventPropagation</tt> properties have no affect until the current 494 * JetGMInfoBox is <tt>close</tt>d and a new one is <tt>open</tt>ed. 495 * @param {JetGMInfoBoxOptions} opt_opts 496 */ 497JetGMInfoBox.prototype.setOptions = function (opt_opts) { 498 if (typeof opt_opts.boxClass !== "undefined") { // Must be first 499 500 this.boxClass_ = opt_opts.boxClass; 501 this.setBoxStyle_(); 502 } 503 if (typeof opt_opts.boxStyle !== "undefined") { // Must be second 504 505 this.boxStyle_ = opt_opts.boxStyle; 506 this.setBoxStyle_(); 507 } 508 if (typeof opt_opts.content !== "undefined") { 509 510 this.setContent(opt_opts.content); 511 } 512 if (typeof opt_opts.disableAutoPan !== "undefined") { 513 514 this.disableAutoPan_ = opt_opts.disableAutoPan; 515 } 516 if (typeof opt_opts.maxWidth !== "undefined") { 517 518 this.maxWidth_ = opt_opts.maxWidth; 519 } 520 if (typeof opt_opts.pixelOffset !== "undefined") { 521 522 this.pixelOffset_ = opt_opts.pixelOffset; 523 } 524 if (typeof opt_opts.alignBottom !== "undefined") { 525 526 this.alignBottom_ = opt_opts.alignBottom; 527 } 528 if (typeof opt_opts.position !== "undefined") { 529 530 this.setPosition(opt_opts.position); 531 } 532 if (typeof opt_opts.zIndex !== "undefined") { 533 534 this.setZIndex(opt_opts.zIndex); 535 } 536 if (typeof opt_opts.closeBoxMargin !== "undefined") { 537 538 this.closeBoxMargin_ = opt_opts.closeBoxMargin; 539 } 540 if (typeof opt_opts.closeBoxURL !== "undefined") { 541 542 this.closeBoxURL_ = opt_opts.closeBoxURL; 543 } 544 if (typeof opt_opts.closeBoxTitle !== "undefined") { 545 546 this.closeBoxTitle_ = opt_opts.closeBoxTitle; 547 } 548 if (typeof opt_opts.infoBoxClearance !== "undefined") { 549 550 this.infoBoxClearance_ = opt_opts.infoBoxClearance; 551 } 552 if (typeof opt_opts.isHidden !== "undefined") { 553 554 this.isHidden_ = opt_opts.isHidden; 555 } 556 if (typeof opt_opts.visible !== "undefined") { 557 558 this.isHidden_ = !opt_opts.visible; 559 } 560 if (typeof opt_opts.enableEventPropagation !== "undefined") { 561 562 this.enableEventPropagation_ = opt_opts.enableEventPropagation; 563 } 564 565 if (this.div_) { 566 567 this.draw(); 568 } 569}; 570 571JetGMInfoBox.prototype.contentIsSet = function () { 572 return "" !== this.content_; 573}; 574 575/** 576 * Sets the content of the JetGMInfoBox. 577 * The content can be plain text or an HTML DOM node. 578 * @param {string|Node} content 579 */ 580JetGMInfoBox.prototype.setContent = function (content) { 581 // Convert a content to an HTMLElement to store the HTML manipulation in a popup 582 if ( typeof content.nodeType === 'undefined' ) { 583 let contentHtml = document.createElement( 'div' ); 584 contentHtml.innerHTML = content; 585 content = contentHtml; 586 } 587 588 this.content_ = content; 589 590 if (this.div_) { 591 592 if (this.closeListener_) { 593 594 this.removeEventListener(this.closeListener_); 595 this.closeListener_ = null; 596 } 597 598 // Odd code required to make things work with MSIE. 599 // 600 if (!this.fixedWidthSet_) { 601 602 this.div_.style.width = ""; 603 } 604 605 if (typeof content.nodeType === "undefined") { 606 this.div_.innerHTML = this.getCloseBoxImg_() + content; 607 } else { 608 this.div_.innerHTML = this.getCloseBoxImg_(); 609 this.div_.appendChild(content); 610 } 611
vendor: 4,104 bytes, lines 612-802
612 // Perverse code required to make things work with MSIE. 613 // (Ensures the close box does, in fact, float to the right.) 614 // 615 if (!this.fixedWidthSet_) { 616 this.div_.style.width = this.div_.offsetWidth + "px"; 617 if (typeof content.nodeType === "undefined") { 618 this.div_.innerHTML = this.getCloseBoxImg_() + content; 619 } else { 620 this.div_.innerHTML = this.getCloseBoxImg_(); 621 this.div_.appendChild(content); 622 } 623 } 624 625 this.addClickHandler_(); 626 } 627 628 /** 629 * This event is fired when the content of the JetGMInfoBox changes. 630 * @name JetGMInfoBox#content_changed 631 * @event 632 */ 633 google.maps.event.trigger(this, "content_changed"); 634}; 635 636/** 637 * Sets the geographic location of the JetGMInfoBox. 638 * @param {LatLng} latlng 639 */ 640JetGMInfoBox.prototype.setPosition = function (latlng) { 641 642 this.position_ = latlng; 643 644 if (this.div_) { 645 646 this.draw(); 647 } 648 649 /** 650 * This event is fired when the position of the JetGMInfoBox changes. 651 * @name JetGMInfoBox#position_changed 652 * @event 653 */ 654 google.maps.event.trigger(this, "position_changed"); 655}; 656 657/** 658 * Sets the zIndex style for the JetGMInfoBox. 659 * @param {number} index 660 */ 661JetGMInfoBox.prototype.setZIndex = function (index) { 662 663 this.zIndex_ = index; 664 665 if (this.div_) { 666 667 this.div_.style.zIndex = index; 668 } 669 670 /** 671 * This event is fired when the zIndex of the JetGMInfoBox changes. 672 * @name JetGMInfoBox#zindex_changed 673 * @event 674 */ 675 google.maps.event.trigger(this, "zindex_changed"); 676}; 677 678/** 679 * Sets the visibility of the JetGMInfoBox. 680 * @param {boolean} isVisible 681 */ 682JetGMInfoBox.prototype.setVisible = function (isVisible) { 683 684 this.isHidden_ = !isVisible; 685 if (this.div_) { 686 this.div_.style.visibility = (this.isHidden_ ? "hidden" : "visible"); 687 } 688}; 689 690/** 691 * Returns the content of the JetGMInfoBox. 692 * @returns {string} 693 */ 694JetGMInfoBox.prototype.getContent = function () { 695 696 return this.content_; 697}; 698 699/** 700 * Returns the geographic location of the JetGMInfoBox. 701 * @returns {LatLng} 702 */ 703JetGMInfoBox.prototype.getPosition = function () { 704 705 return this.position_; 706}; 707 708/** 709 * Returns the zIndex for the JetGMInfoBox. 710 * @returns {number} 711 */ 712JetGMInfoBox.prototype.getZIndex = function () { 713 714 return this.zIndex_; 715}; 716 717/** 718 * Returns a flag indicating whether the JetGMInfoBox is visible. 719 * @returns {boolean} 720 */ 721JetGMInfoBox.prototype.getVisible = function () { 722 723 var isVisible; 724 725 if ((typeof this.getMap() === "undefined") || (this.getMap() === null)) { 726 isVisible = false; 727 } else { 728 isVisible = !this.isHidden_; 729 } 730 return isVisible; 731}; 732 733/** 734 * Returns the width of the JetGMInfoBox in pixels. 735 * @returns {number} 736 */ 737JetGMInfoBox.prototype.getWidth = function () { 738 var width = null; 739 740 if (this.div_) { 741 width = this.div_.offsetWidth; 742 } 743 744 return width; 745}; 746 747/** 748 * Returns the height of the JetGMInfoBox in pixels. 749 * @returns {number} 750 */ 751JetGMInfoBox.prototype.getHeight = function () { 752 var height = null; 753 754 if (this.div_) { 755 height = this.div_.offsetHeight; 756 } 757 758 return height; 759}; 760 761/** 762 * Shows the JetGMInfoBox. [Deprecated; use <tt>setVisible</tt> instead.] 763 */ 764JetGMInfoBox.prototype.show = function () { 765 766 this.isHidden_ = false; 767 if (this.div_) { 768 this.div_.style.visibility = "visible"; 769 } 770}; 771 772/** 773 * Hides the JetGMInfoBox. [Deprecated; use <tt>setVisible</tt> instead.] 774 */ 775JetGMInfoBox.prototype.hide = function () { 776 777 this.isHidden_ = true; 778 if (this.div_) { 779 this.div_.style.visibility = "hidden"; 780 } 781}; 782 783/** 784 * Adds the JetGMInfoBox to the specified map or Street View panorama. If <tt>anchor</tt> 785 * (usually a <tt>google.maps.Marker</tt>) is specified, the position 786 * of the JetGMInfoBox is set to the position of the <tt>anchor</tt>. If the 787 * anchor is dragged to a new location, the JetGMInfoBox moves as well. 788 * @param {Map|StreetViewPanorama} map 789 * @param {MVCObject} [anchor] 790 */ 791JetGMInfoBox.prototype.open = function (map, anchor) { 792 793 var me = this; 794 795 if (anchor) { 796 797 this.setPosition(anchor.getPosition()); // BUG FIX 2/17/2018: needed for v3.32 798 this.moveListener_ = google.maps.event.addListener(anchor, "position_changed", function () { 799 me.setPosition(this.getPosition()); 800 }); 801 } 802
803 this.setMap(map); 804 805 map.jeActiveInfoWindow = this; 806 807 if ( this.div_ ) { 808 809 window.dispatchEvent( 810 new CustomEvent( 811 'jet-engine/maps/google/info-box-open', 812 { 813 detail: { 814 container: this.div_, 815 }, 816 } 817 ) 818 ); 819 820 this.panBox_(this.disableAutoPan_); // BUG FIX 2/17/2018: add missing parameter 821 822 } 823}; 824 825/** 826 * Removes the JetGMInfoBox from the map. 827 */ 828JetGMInfoBox.prototype.close = function () { 829 830 var i; 831 832 if (this.closeListener_) { 833 834 this.removeEventListener(this.closeListener_); 835 this.closeListener_ = null; 836 } 837 838 if (this.eventListeners_) { 839 840 for (i = 0; i < this.eventListeners_.length; i++) { 841 842 this.removeEventListener(this.eventListeners_[i]); 843 } 844 this.eventListeners_ = null; 845 } 846 847 if (this.moveListener_) { 848 849 google.maps.event.removeListener(this.moveListener_); 850 this.moveListener_ = null; 851 } 852 853 if (this.contextListener_) { 854 855 this.removeEventListener(this.contextListener_); 856 this.contextListener_ = null; 857 } 858 859 if ( this.map?.jeActiveInfoWindow ) { 860 this.map.jeActiveInfoWindow = false; 861 } 862 863 this.setMap(null); 864}; 865 866// richmarker.js 867// initial version - https://github.com/googlearchive/js-rich-marker 868// new version - https://github.com/kaskad88/js-rich-marker // fixed deprecated notices 869(function(){function t(t){var r=t||{};this.ready_=!1,this.dragging_=!1,null==t.visible&&(t.visible=!0),null==t.shadow&&(t.shadow="7px -3px 5px rgba(88,88,88,0.7)"),null==t.anchor&&(t.anchor=e.BOTTOM),this.setValues(r)}t.prototype=new google.maps.OverlayView,window.RichMarker=t,t.prototype.getVisible=function(){return this.get("visible")},t.prototype.getVisible=t.prototype.getVisible,t.prototype.setVisible=function(t){this.set("visible",t)},t.prototype.setVisible=t.prototype.setVisible,t.prototype.visible_changed=function(){this.ready_&&(this.markerWrapper_.style.display=this.getVisible()?"":"none",this.draw())},t.prototype.visible_changed=t.prototype.visible_changed,t.prototype.setFlat=function(t){this.set("flat",!!t)},t.prototype.setFlat=t.prototype.setFlat,t.prototype.getFlat=function(){return this.get("flat")},t.prototype.getFlat=t.prototype.getFlat,t.prototype.getWidth=function(){return this.get("width")},t.prototype.getWidth=t.prototype.getWidth,t.prototype.getHeight=function(){return this.get("height")},t.prototype.getHeight=t.prototype.getHeight,t.prototype.setShadow=function(t){this.set("shadow",t),this.flat_changed()},t.prototype.setShadow=t.prototype.setShadow,t.prototype.getShadow=function(){return this.get("shadow")},t.prototype.getShadow=t.prototype.getShadow,t.prototype.flat_changed=function(){this.ready_&&(this.markerWrapper_.style.boxShadow=this.markerWrapper_.style.webkitBoxShadow=this.markerWrapper_.style.MozBoxShadow=this.getFlat()?"":this.getShadow())},t.prototype.flat_changed=t.prototype.flat_changed,t.prototype.setZIndex=function(t){this.set("zIndex",t)},t.prototype.setZIndex=t.prototype.setZIndex,t.prototype.getZIndex=function(){return this.get("zIndex")},t.prototype.getZIndex=t.prototype.getZIndex,t.prototype.zIndex_changed=function(){this.getZIndex()&&this.ready_&&(this.markerWrapper_.style.zIndex=this.getZIndex())},t.prototype.zIndex_changed=t.prototype.zIndex_changed,t.prototype.getDraggable=function(){return this.get("draggable")},t.prototype.getDraggable=t.prototype.getDraggable,t.prototype.setDraggable=function(t){this.set("draggable",!!t)},t.prototype.setDraggable=t.prototype.setDraggable,t.prototype.draggable_changed=function(){this.ready_&&(this.getDraggable()?this.addDragging_(this.markerWrapper_):this.removeDragListeners_())},t.prototype.draggable_changed=t.prototype.draggable_changed,t.prototype.getPosition=function(){return this.get("position")},t.prototype.getPosition=t.prototype.getPosition,t.prototype.setPosition=function(t){this.set("position",t)},t.prototype.setPosition=t.prototype.setPosition,t.prototype.position_changed=function(){this.draw()},t.prototype.position_changed=t.prototype.position_changed,t.prototype.getAnchor=function(){return this.get("anchor")},t.prototype.getAnchor=t.prototype.getAnchor,t.prototype.setAnchor=function(t){this.set("anchor",t)},t.prototype.setAnchor=t.prototype.setAnchor,t.prototype.anchor_changed=function(){this.draw()},t.prototype.anchor_changed=t.prototype.anchor_changed,t.prototype.htmlToDocumentFragment_=function(t){var e=document.createElement("DIV");if(e.innerHTML=t,1==e.childNodes.length)return e.removeChild(e.firstChild);for(var r=document.createDocumentFragment();e.firstChild;)r.appendChild(e.firstChild);return r},t.prototype.removeChildren_=function(t){if(t)for(var e;e=t.firstChild;)t.removeChild(e)},t.prototype.setContent=function(t){this.set("content",t)},t.prototype.setContent=t.prototype.setContent,t.prototype.getContent=function(){return this.get("content")},t.prototype.getContent=t.prototype.getContent,t.prototype.addEventListener=function(t,e,r,o){return o=o||!1,t.addEventListener(e,r,o),{target:t,type:e,handler:r,useCapture:o}},t.prototype.removeEventListener=function(t){t.target.removeEventListener(t.type,t.handler,t.useCapture)},t.prototype.content_changed=function(){if(this.markerContent_){this.removeChildren_(this.markerContent_);var t=this.getContent();if(t){"string"==typeof t&&(t=t.replace(/^\s*([\S\s]*)\b\s*$/,"$1"),t=this.htmlToDocumentFragment_(t)),this.markerContent_.appendChild(t);for(var e,r=this,o=this.markerContent_.getElementsByTagName("IMG"),i=0;e=o[i];i++)this.addEventListener(e,"mousedown",(function(t){r.getDraggable()&&(t.preventDefault&&t.preventDefault(),t.returnValue=!1,console.log("image mousedown"))})),this.addEventListener(e,"load",(function(){r.draw(),console.log("image load")}));google.maps.event.trigger(this,"domready")}this.ready_&&this.draw()}},t.prototype.content_changed=t.prototype.content_changed,t.prototype.setCursor_=function(t){if(this.ready_){var e="";-1!==navigator.userAgent.indexOf("Gecko/")?("dragging"==t&&(e="-moz-grabbing"),"dragready"==t&&(e="-moz-grab"),"draggable"==t&&(e="pointer")):("dragging"!=t&&"dragready"!=t||(e="move"),"draggable"==t&&(e="pointer")),this.markerWrapper_.style.cursor!=e&&(this.markerWrapper_.style.cursor=e)}},t.prototype.startDrag=function(t){if(this.getDraggable()&&!this.dragging_){this.dragging_=!0;var e=this.getMap();this.mapDraggable_=e.get("draggable"),e.set("draggable",!1),this.mouseX_=t.clientX,this.mouseY_=t.clientY,this.setCursor_("dragready"),this.markerWrapper_.style.MozUserSelect="none",this.markerWrapper_.style.KhtmlUserSelect="none",this.markerWrapper_.style.WebkitUserSelect="none",this.markerWrapper_.unselectable="on",this.markerWrapper_.onselectstart=function(){return!1},this.addDraggingListeners_(),google.maps.event.trigger(this,"dragstart")}},t.prototype.stopDrag=function(){this.getDraggable()&&this.dragging_&&(this.dragging_=!1,this.getMap().set("draggable",this.mapDraggable_),this.mouseX_=this.mouseY_=this.mapDraggable_=null,this.markerWrapper_.style.MozUserSelect="",this.markerWrapper_.style.KhtmlUserSelect="",this.markerWrapper_.style.WebkitUserSelect="",this.markerWrapper_.unselectable="off",this.markerWrapper_.onselectstart=function(){},this.removeDraggingListeners_(),this.setCursor_("draggable"),google.maps.event.trigger(this,"dragend"),this.draw())},t.prototype.drag=function(t){if(this.getDraggable()&&this.dragging_){var e=this.mouseX_-t.clientX,r=this.mouseY_-t.clientY;this.mouseX_=t.clientX,this.mouseY_=t.clientY;var o=parseInt(this.markerWrapper_.style.left,10)-e,i=parseInt(this.markerWrapper_.style.top,10)-r;this.markerWrapper_.style.left=o+"px",this.markerWrapper_.style.top=i+"px";var s=this.getOffset_(),n=new google.maps.Point(o-s.width,i-s.height),a=this.getProjection();this.setPosition(a.fromDivPixelToLatLng(n)),this.setCursor_("dragging"),google.maps.event.trigger(this,"drag")}
869else this.stopDrag()},t.prototype.removeDragListeners_=function(){this.draggableListener_&&(this.removeEventListener(this.draggableListener_),delete this.draggableListener_),this.setCursor_("")},t.prototype.addDragging_=function(t){if(t){var e=this;this.draggableListener_=this.addEventListener(t,"mousedown",(function(t){e.startDrag(t),console.log("node mousedown")})),this.setCursor_("draggable")}},t.prototype.addDraggingListeners_=function(){var t=this;this.markerWrapper_.setCapture?(this.markerWrapper_.setCapture(!0),this.draggingListeners_=[this.addEventListener(this.markerWrapper_,"mousemove",(function(e){t.drag(e)}),!0),this.addEventListener(this.markerWrapper_,"mouseup",(function(){t.stopDrag(),t.markerWrapper_.releaseCapture()}),!0)]):this.draggingListeners_=[this.addEventListener(window,"mousemove",(function(e){t.drag(e)}),!0),this.addEventListener(window,"mouseup",(function(){t.stopDrag()}),!0)]},t.prototype.removeDraggingListeners_=function(){if(this.draggingListeners_){for(var t,e=0;t=this.draggingListeners_[e];e++)this.removeEventListener(t);this.draggingListeners_.length=0}},t.prototype.getOffset_=function(){var t=this.getAnchor();if("object"==typeof t)return t;var r=new google.maps.Size(0,0);if(!this.markerContent_)return r;var o=this.markerContent_.offsetWidth,i=this.markerContent_.offsetHeight;switch(t){case e.TOP_LEFT:break;case e.TOP:r.width=-o/2;break;case e.TOP_RIGHT:r.width=-o;break;case e.LEFT:r.height=-i/2;break;case e.MIDDLE:r.width=-o/2,r.height=-i/2;break;case e.RIGHT:r.width=-o,r.height=-i/2;break;case e.BOTTOM_LEFT:r.height=-i;break;case e.BOTTOM:r.width=-o/2,r.height=-i;break;case e.BOTTOM_RIGHT:r.width=-o,r.height=-i}return r},t.prototype.onAdd=function(){if(this.markerWrapper_||(this.markerWrapper_=document.createElement("DIV"),this.markerWrapper_.style.position="absolute"),this.getZIndex()&&(this.markerWrapper_.style.zIndex=this.getZIndex()),this.markerWrapper_.style.display=this.getVisible()?"":"none",!this.markerContent_){this.markerContent_=document.createElement("DIV"),this.markerWrapper_.appendChild(this.markerContent_);var t=this;this.addEventListener(this.markerContent_,"click",(function(e){google.maps.event.trigger(t,"click",e)})),this.addEventListener(this.markerContent_,"mouseover",(function(e){google.maps.event.trigger(t,"mouseover",e)})),this.addEventListener(this.markerContent_,"mouseout",(function(e){google.maps.event.trigger(t,"mouseout",e)}))}this.ready_=!0,this.content_changed(),this.flat_changed(),this.draggable_changed();var e=this.getPanes();e&&e.overlayMouseTarget.appendChild(this.markerWrapper_),google.maps.event.trigger(this,"ready")},t.prototype.onAdd=t.prototype.onAdd,t.prototype.draw=function(){if(this.ready_&&!this.dragging_){var t=this.getProjection();if(t){var e=this.get("position"),r=t.fromLatLngToDivPixel(e),o=this.getOffset_();this.markerWrapper_.style.top=r.y+o.height+"px",this.markerWrapper_.style.left=r.x+o.width+"px";var i=this.markerContent_.offsetHeight,s=this.markerContent_.offsetWidth;s!=this.get("width")&&this.set("width",s),i!=this.get("height")&&this.set("height",i)}}},t.prototype.draw=t.prototype.draw,t.prototype.onRemove=function(){this.markerWrapper_&&this.markerWrapper_.parentNode&&this.markerWrapper_.parentNode.removeChild(this.markerWrapper_),this.removeDragListeners_()},t.prototype.onRemove=t.prototype.onRemove;var e={TOP_LEFT:1,TOP:2,TOP_RIGHT:3,LEFT:4,MIDDLE:5,RIGHT:6,BOTTOM_LEFT:7,BOTTOM:8,BOTTOM_RIGHT:9};window.RichMarkerPosition=e;})(); 870 871window.JetEngineMapsProvider = function() { 872 873 this.getId = function() { 874 return 'google'; 875 } 876 877 this.getContainer = function( map ) { 878 return map.getDiv(); 879 } 880 881 this.getBoundsJSON = function( map ) { 882 const bounds = map.getBounds(); 883 884 if ( ! bounds ) { 885 return; 886 } 887 888 return bounds.toJSON(); 889 } 890 891 this.updateSyncBounds = function() { 892 const map = this; 893 894 const bounds = map.getBounds(); 895 896 if ( ! bounds ) { 897 return; 898 } 899 900 window.JetEngineMaps.dispatchMapSyncEvent( map, bounds.toJSON() ); 901 } 902 903 this.initSync = function( map ) { 904 if ( map?.isJetEngineSyncInited || ! window.JetEngineMaps || ! window.JetSmartFilters ) { 905 return; 906 } 907 908 map.addListener( 'dragend', this.updateSyncBounds );
909 map.addListener( 'bounds_changed', this.updateSyncBounds ); 910 911 google.maps.event.addListenerOnce( 912 map, 913 'idle', 914 () => { 915 window.JetEngineMaps.dispatchMapSyncInitEvent( map ) 916 } 917 ); 918 919 map.isJetEngineSyncInited = true; 920 } 921 922 this.initMap = function( container, settings ) { 923 924 settings = settings || {}; 925 926 if ( ! settings.mapTypeId ) { 927 settings.mapTypeId = google.maps.MapTypeId.ROADMAP; 928 } 929 930 let map = new google.maps.Map( container, settings ); 931 932 this.initSync( map ); 933 934 /** 935 * @see https://github.com/Crocoblock/issues-tracker/issues/15546 936 * 937 * stop map click event if clicked POI is behind map popup 938 */ 939 map.addListener( 'click', function( e ) { 940 if ( e.placeId && map.jeActiveInfoWindow ) { 941 const poiScreenX = e.domEvent?.screenX; 942 const poiScreenY = e.domEvent?.screenY; 943 944 if ( ! poiScreenX || ! poiScreenY ) { 945 return; 946 } 947 948 const infoBoxDivRect = map.jeActiveInfoWindow.div_.getBoundingClientRect(); 949 950 if ( 951 poiScreenX >= infoBoxDivRect.left && 952 poiScreenX <= infoBoxDivRect.right && 953 poiScreenY >= infoBoxDivRect.top && 954 poiScreenY <= infoBoxDivRect.bottom 955 ) { 956 e.stop(); 957 } 958 } 959 } ); 960 961 return map; 962 } 963 964 this.initBounds = function() { 965 return new google.maps.LatLngBounds(); 966 } 967 968 this.fitMapBounds = function( data, callback ) { 969 var self = this; 970 971 data.map.fitBounds( data.bounds ); 972 973 var listener = google.maps.event.addListener( data.map, 'idle', function() { 974 if ( ! data.marker.getMap() ) { 975 self.fitMapToMarker( data.marker, data.markersClusterer ); 976 } else if ( callback ) { 977 callback(); 978 } 979 google.maps.event.removeListener( listener ); 980 } ); 981 } 982 983 this.addMarker = function( data ) { 984 data.position = new google.maps.LatLng( data.position.lat, data.position.lng ); 985 return new RichMarker( data ); 986 } 987 988 this.removeMarker = function( marker ) { 989 marker.setMap( null ); 990 } 991 992 this.addPopup = function( data ) { 993 return new JetGMInfoBox( { 994 position: new google.maps.LatLng( data.position.lat, data.position.lng ), 995 maxWidth: data.width, 996 boxClass: "jet-map-box", 997 zIndex: null, 998 pixelOffset: new google.maps.Size( 0 - data.width / 2, 0 - data.offset ), 999 alignBottom: true, 1000 infoBoxClearance: new google.maps.Size( 10, 10 ), 1001 pane: "floatPane", 1002 enableEventPropagation: false, 1003 } ); 1004 } 1005 1006 this.markerOnClick = function( map, data, callback ) { 1007 1008 data = data || {}; 1009 1010 data.map = map; 1011 data.shadow = false; 1012 1013 google.maps.event.addListener( map, "click", ( event ) => { 1014 1015 data.position = { 1016 lat: event.latLng.lat(), 1017 lng: event.latLng.lng(), 1018 }; 1019 1020 if ( callback ) { 1021 callback( this.addMarker( data ) ); 1022 } 1023 1024 } ); 1025 } 1026 1027 this.closePopup = function( infoBox, callback ) { 1028 google.maps.event.addListener( infoBox, 'closeclick', function( e ) { 1029 callback( e ); 1030 } ); 1031 } 1032 1033 this.openPopup = function( trigger, callback, infobox, map, openOn ) { 1034 google.maps.event.addListener( trigger, 'click', function( e ) { 1035 map.isInternalInteraction = true; 1036 callback( e ); 1037 } ); 1038 1039 if ( 'hover' === openOn ) { 1040 google.maps.event.addListener( trigger, 'mouseover', function( e ) { 1041 map.isInternalInteraction = true; 1042 callback( e ); 1043 } ); 1044 } 1045 } 1046 1047 this.triggerOpenPopup = function( trigger ) { 1048 google.maps.event.trigger( trigger, 'click' ); 1049 } 1050 1051 this.getMarkerPosition = function( marker, toJSON ) { 1052 toJSON = toJSON || false; 1053 1054 if ( toJSON ) { 1055 return marker.position.toJSON(); 1056 } else { 1057 return marker.position; 1058 } 1059 1060 } 1061 1062 this.getMarkerCluster = function( data ) { 1063 let options = { 1064 imagePath: data.clustererImg, 1065 }; 1066 1067 const optionsMap = { 1068 maxZoom: 'clusterMaxZoom', 1069 gridSize: 'clusterRadius', 1070 }; 1071 1072 for ( const [ optionKey, settingsKey ] of Object.entries( optionsMap ) ) { 1073 if ( undefined !== data[ settingsKey ] && '' !== data[ settingsKey ] ) { 1074 options[ optionKey ] = data[ settingsKey ]; 1075 } 1076 } 1077 1078 return new MarkerClusterer( 1079 data.map, 1080 data.markers, 1081 options 1082 ); 1083 } 1084 1085 this.addMarkers = function( markerCluster, markers ) { 1086 markerCluster.addMarkers( markers ); 1087 } 1088 1089 this.removeMarkers = function( markerCluster, markers ) { 1090 markerCluster.removeMarkers( markers ); 1091 } 1092 1093 this.setCenterByPosition = function( data ) { 1094 data.map.setCenter( data.position ); 1095 data.map.setZoom( data.zoom ); 1096 } 1097 1098 this.setAutoCenter = function( data ) { 1099 data.map.isInternalInteraction = true; 1100 1101 data.map.fitBounds( data.bounds ); 1102 1103 if ( data.settings.maxZoom ) { 1104 1105 var listener = google.maps.event.addListener( data.map, 'idle', function() { 1106 1107 if ( data.map.getZoom() > data.settings.maxZoom ) { 1108 data.map.setZoom( data.settings.maxZoom ); 1109 } 1110 1111 google.maps.event.removeListener( listener ); 1112 1113 } ); 1114 } 1115 } 1116 1117 this.getMarkerMap = function( marker ) { 1118 return marker.getMap(); 1119 } 1120 1121 this.fitMapToMarker = function( marker, markersClusterer, zoom ) { 1122 var cluster = this._findClusterByMarker( markersClusterer, marker ), 1123 bounds, 1124 map; 1125 1126 if ( ! cluster ) { 1127 return; 1128 } 1129 1130 map = markersClusterer.getMap(); 1131 bounds = cluster.getBounds(); 1132 1133 this.fitMapBounds( { 1134 map: map,
1135 bounds: bounds, 1136 marker: marker, 1137 markersClusterer: markersClusterer, 1138 }, () => { 1139 this.panTo( { 1140 map: map, 1141 position: this.getMarkerPosition( marker ), 1142 zoom: zoom 1143 } ); 1144 } ); 1145 }; 1146 1147 this.panTo = function( data, forceZoom = false ) { 1148 data.map.panTo( data.position ); 1149 1150 if ( forceZoom || data.zoom && data.zoom > data.map.getZoom() ) { 1151 data.map.setZoom( data.zoom ); 1152 } 1153 } 1154 1155 this._findClusterByMarker = function( markersClusterer, marker ) { 1156 var clusters = markersClusterer.getClusters(), 1157 result; 1158 1159 if ( !clusters.length ) { 1160 return; 1161 } 1162 1163 for ( var i = 0; i < clusters.length; i++ ) { 1164 var markers = clusters[i].getMarkers(); 1165 1166 for ( var j = 0; j < markers.length; j++ ) { 1167 1168 if ( markers[j] === marker && markers.length > 1) { 1169 result = clusters[i]; 1170 break; 1171 } 1172 } 1173 } 1174 1175 return result; 1176 } 1177 1178}
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.