PageSourceSearch

https://whitehousestours.com/wp-content/plugins/wht-about-us/assets/js/wht-about-us.js?ver=3.3.5.1785139213

js whitehousestours.com collected 2026-09-25 23:06:04 UTC 7,752 bytes, 261 lines download raw bytes

1(() => {
2  "use strict";
3
4  const page = document.querySelector(".wht-about-page");
5  if (!page) return;
6
7  const header = page.querySelector("[data-wht-about-header]");
8  const menuToggle = header?.querySelector("[data-wht-about-menu-toggle]");
9  const menuPanel = header?.querySelector("[data-wht-about-mobile-panel]");
10  const menuClose = header?.querySelector("[data-wht-about-menu-close]");
11  let lastMenuTrigger = null;
12
13  if (header?.dataset.whtAboutHeaderBound === "true") return;
14  if (header) header.dataset.whtAboutHeaderBound = "true";
15
16  function updateMobilePanelTop() {
17    if (!header) return;
18    const rect = header.getBoundingClientRect();
19    document.documentElement.style.setProperty(
20      "--wht-vineyard-mobile-panel-top",
21      `${Math.max(0, Math.round(rect.bottom))}px`,
22    );
23  }
24
25  function positionSubmenus() {
26    if (!header) return;
27    const padding = 16;
28
29    header
30      .querySelectorAll(".wht-vineyard-header__submenu")
31      .forEach((submenu) => {
32        submenu.style.setProperty("--wht-submenu-shift", "0px");
33        const rect = submenu.getBoundingClientRect();
34        let shift = 0;
35
36        if (rect.left < padding) shift += padding - rect.left;
37        if (rect.right + shift > window.innerWidth - padding) {
38          shift -= rect.right + shift - (window.innerWidth - padding);
39        }
40
41        submenu.style.setProperty(
42          "--wht-submenu-shift",
43          `${Math.round(shift)}px`,
44        );
45      });
46  }
47
48  function setMobileMenu(open, restoreFocus = false) {
49    if (!menuToggle || !menuPanel) return;
50
51    if (open && window.innerWidth > 1199) open = false;
52
53    if (open) {
54      lastMenuTrigger = document.activeElement;
55      updateMobilePanelTop();
56      menuPanel.hidden = false;
57      menuPanel.setAttribute("aria-hidden", "false");
58      menuToggle.setAttribute("aria-expanded", "true");
59      menuToggle.setAttribute("aria-label", "Close menu");
60      document.body.classList.add("wht-vineyard-mobile-menu-open");
61      window.requestAnimationFrame(() =>
62        menuClose?.focus({ preventScroll: true }),
63      );
64      return;
65    }
66
67    menuPanel.hidden = true;
68    menuPanel.setAttribute("aria-hidden", "true");
69    menuToggle.setAttribute("aria-expanded", "false");
70    menuToggle.setAttribute("aria-label", "Open menu");
71    document.body.classList.remove("wht-vineyard-mobile-menu-open");
72
73    if (restoreFocus && lastMenuTrigger instanceof HTMLElement) {
74      lastMenuTrigger.focus({ preventScroll: true });
75    }
76  }
77
78  if (header) {
79    const menuGroups = Array.from(
80      header.querySelectorAll(".wht-vineyard-header__menu-group"),
81    );
82    const finePointer = window.matchMedia(
83      "(hover: hover) and (pointer: fine)",
84    );
85    let activeGroup = null;
86
87    updateMobilePanelTop();
88    positionSubmenus();
89
90    const getGroupButton = (group) =>
91      group?.querySelector(".wht-vineyard-header__menu-button") || null;
92
93    const setExpanded = (group, expanded, forceClosed = false) => {
94      const button = getGroupButton(group);
95      if (!group || !button) return;
96
97      group.classList.toggle("is-open", expanded);
98      group.classList.toggle(
99        "is-force-closed",
100        !expanded && forceClosed === true,
101      );
102      button.setAttribute("aria-expanded", expanded ? "true" : "false");
103
104      if (expanded) activeGroup = group;
105      else if (activeGroup === group) activeGroup = null;
106    };
107
108    const closeOtherGroups = (except) => {
109      menuGroups.forEach((group) => {
110        if (group !== except) setExpanded(group, false, true);
111      });
112    };
113
114    const openGroup = (group) => {
115      closeOtherGroups(group);
116      group.classList.remove("is-force-closed");
117      setExpanded(group, true);
118    };
119
120    const closeGroup = (group, restoreFocus = false) => {
121      const button = getGroupButton(group);
122      setExpanded(group, false, true);
123      if (restoreFocus) button?.focus({ preventScroll: true });
124    };
125
126    menuGroups.forEach((group) => {
127      const button = getGroupButton(group);
128      const firstLink = group.querySelector(
129        ".wht-vineyard-header__submenu a",
130      );
131      let suppressNextKeyboardClick = false;
132      if (!button) return;
133
134      group.addEventListener("pointerenter", () => {
135        if (finePointer.matches) openGroup(group);
136      });
137
138      button.addEventListener("click", (event) => {
139        event.preventDefault();
140        if (suppressNextKeyboardClick && event.detail === 0) {
141          suppressNextKeyboardClick = false;
142          return;
143        }
144        suppressNextKeyboardClick = false;
145        if (button.getAttribute("aria-expanded") === "true") {
146          closeGroup(group);
147        } else {
148          openGroup(group);
149        }
150      });
151
152      button.addEventListener("keydown", (event) => {
153        if (event.key === "Enter" || event.key === " ") {
154          event.preventDefault();
155          suppressNextKeyboardClick = true;
156          if (button.getAttribute("aria-expanded") === "true") {
157            closeGroup(group);
158          } else {
159            openGroup(group);
160          }
161          return;
162        }
163
164        if (event.key === "ArrowDown") {
165          event.preventDefault();
166          openGroup(group);
167          firstLink?.focus({ preventScroll: true });
168        }
169      });
170
171      group.addEventListener("focusout", (event) => {
172        if (!event.relatedTarget || !group.contains(event.relatedTarget)) {
173          closeGroup(group);
174        }
175      });
176
177      group
178        .querySelectorAll(".wht-vineyard-header__submenu a")
179        .forEach((link) =>
180          link.addEventListener("click", () => closeGroup(group)),
181        );
182    });
183
184    document.addEventListener("pointerdown", (event) => {
185      if (activeGroup && !activeGroup.contains(event.target)) {
186        closeGroup(activeGroup);
187      }
188      if (
189        menuToggle?.getAttribute("aria-expanded") === "true" &&
190        !header.contains(event.target) &&
191        (!menuPanel || !menuPanel.contains(event.target))
192      ) {
193        setMobileMenu(false);
194      }
195    });
196
197    document.addEventListener("keydown", (event) => {
198      if (event.key === "Escape" && activeGroup) {
199        event.preventDefault();
200        event.stopPropagation();
201        closeGroup(activeGroup, true);
202      }
203    });
204  }
205
206  menuToggle?.addEventListener("click", () => {
207    setMobileMenu(menuToggle.getAttribute("aria-expanded") !== "true");
208  });
209
210  menuClose?.addEventListener("click", () => setMobileMenu(false, true));
211
212  menuPanel?.addEventListener("click", (event) => {
213    if (event.target.closest("a")) setMobileMenu(false);
214  });
215
216  menuPanel?.addEventListener("keydown", (event) => {
217    if (event.key === "Escape") {
218      event.preventDefault();
219      setMobileMenu(false, true);
220      return;
221    }
222
223    if (event.key !== "Tab" || menuPanel.hidden) return;
224
225    const focusable = Array.from(
226      menuPanel.querySelectorAll(
227        'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])',
228      ),
229    ).filter(
230      (element) =>
231        !element.hidden && element.getAttribute("aria-hidden") !== "true",
232    );
233
234    if (!focusable.length) {
235      event.preventDefault();
236      return;
237    }
238
239    const first = focusable[0];
240    const last = focusable[focusable.length - 1];
241
242    if (event.shiftKey && document.activeElement === first) {
243      event.preventDefault();
244      last.focus({ preventScroll: true });
245    } else if (!event.shiftKey && document.activeElement === last) {
246      event.preventDefault();
247      first.focus({ preventScroll: true });
248    }
249  });
250
251  window.addEventListener(
252    "resize",
253    () => {
254      updateMobilePanelTop();
255      positionSubmenus();
256      if (window.innerWidth > 1199) setMobileMenu(false);
257    },
258    { passive: true },
259  );
260
261})();

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.