PageSourceSearch

https://www.visionsource-joplin.com/scripts/map-info-window-factory.js

js visionsource-joplin.com collected 2026-10-08 23:18:52 UTC 3,840 bytes, 78 lines download raw bytes

1export function createInfoWindowContent(location) {
2  return `<div class="relative map-info-box mb-5 max-w-lg">
3    <div class="textprimary-foreground bg-primary/80 w-full rounded-2xl p-4 backdrop-blur-sm">
4      <button
5        type="button"
6        class="absolute top-4 right-4 btn btn-sm btn-secondary btn-circle transition-all duration-100 transform hover:bg-secondary/80 hover:scale-110"
7        aria-label="Close info window"
8        onclick="this.closest('.gm-style-iw-a').querySelector('.gm-ui-hover-effect').click();"
9      >
10        <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
11          <path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8 2.146 2.854Z"/>
12        </svg>
13      </button>
14
15      <div class="mb-6 flex items-center justify-between">
16        <div class="flex items-stretch flex-1">
17          <span class="relative flex aspect-square items-center justify-center rounded-lg bg-secondary p-2 font-black text-secondary-foreground">
18            <span class="uppercase font-black text-5xl min-w-12 grid place-items-center">${location.name?.[0] || "L"}</span>
19          </span>
20          <div class="flex flex-col flex-1 pe-7">
21            <span class="text-primary-foreground text-lg mb-.5 ml-2 font-semibold">${location.name || "Location"}</span>
22            <span class="text-primary-foreground/80 ml-2 text-base">
23              ${location.addressLine1 || ""}<br />
24              ${location.addressCity || ""}, ${location.addressState || ""} ${location.addressZip || ""}
25            </span>
26          </div>
27        </div>
28      </div>
29      <div class="grid gap-2 xs:grid-cols-3">
30        <a href="sms:${location.message || ""}" class="flex-1 uppercase !font-semibold !text-xs btn btn-md btn-accent rounded-md">
31          Message Us
32        </a>
33        <a href="tel:${location.phone || ""}" class="flex-1 uppercase !font-semibold !text-xs btn btn-md btn-info rounded-md">
34          Call Us Now
35        </a>
36        <a href="https://www.google.com/maps/dir/?api=1&destination=${location.coordinates || ""}" target="_blank" class="flex-1 uppercase !font-semibold !text-xs btn btn-md btn-success rounded-md">
37          Get Directions
38        </a>
39      </div>
40    </div>
41  </div>`;
42}
43
44/**
45 * Sets up interactions for buttons inside an info window.
46 * @param {Object} location - The location data object.
47 */
48export function setupInfoWindowInteractions(location) {
49  try {
50    // This function is tricky because it operates on the DOM *after* the info window has been rendered by Google Maps.
51    // The logic inside seems to be trying to fix some event propagation issues.
52    const mapButtons = document.querySelectorAll(".map-info-box button, .map-info-box a");
53
54    mapButtons.forEach((button) => {
55      if (button.getAttribute("aria-hidden") === "true") {
56        button.removeAttribute("aria-hidden");
57      }
58      // Re-cloning the button to remove existing listeners is a bit of a hack,
59      // but we'll keep it as it might be there for a reason related to the Google Maps API.
60      const newButton = button.cloneNode(true);
61      button.parentNode.replaceChild(newButton, button);
62    });
63
64    const closeButtons = document.querySelectorAll(".map-info-box button[aria-label='Close info window']");
65    closeButtons.forEach((button) => {
66      button.addEventListener("click", (e) => {
67        e.preventDefault();
68        e.stopPropagation();
69        const closeElement = button.closest(".gm-style-iw-a")?.querySelector(".gm-ui-hover-effect");
70        if (closeElement) {
71          closeElement.click();
72        }
73      });
74    });
75  } catch (error) {
76    console.warn("Error setting up info window interactions:", error);
77  }
78}

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.