PageSourceSearch

https://www.mymoney.gov/js/init.js?v=27

js mymoney.gov collected 2026-10-02 04:03:51 UTC 15,682 bytes, 472 lines download raw bytes

1/**
2 * MyMoney.gov - JavaScript Initialization
3 */
4
5(function() {
6  'use strict';
7
8  function getSearchMenu() {
9    return document.getElementById('megamenu-search');
10  }
11
12  function getSearchButtons() {
13    return Array.prototype.slice.call(document.querySelectorAll('.treas-search-nav .search-btn'));
14  }
15
16  function getMobileNavElements() {
17    return {
18      button: document.querySelector('.usa-menu-btn, .treas-burger-menu'),
19      nav: document.getElementById('navbarSupportedContent'),
20      close: document.querySelector('#navbarSupportedContent .usa-nav__close'),
21      overlay: document.querySelector('.usa-overlay')
22    };
23  }
24
25  function isMobileNavigationViewport() {
26    return window.matchMedia && window.matchMedia('(max-width: 63.99em)').matches;
27  }
28
29  function focusableElements(container) {
30    if (!container) return [];
31
32    return Array.prototype.slice.call(container.querySelectorAll(
33      'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
34    )).filter(function(element) {
35      return element.offsetWidth || element.offsetHeight || element.getClientRects().length;
36    });
37  }
38
39  var mobileNavigationBackgroundStates = [];
40
41  function setMobileNavigationBackgroundHidden(hidden) {
42    var backgroundElements = Array.prototype.slice.call(document.querySelectorAll('main, footer'));
43
44    if (hidden) {
45      if (!mobileNavigationBackgroundStates.length) {
46        mobileNavigationBackgroundStates = backgroundElements.map(function(element) {
47          return { element: element, ariaHidden: element.getAttribute('aria-hidden') };
48        });
49      }
50      backgroundElements.forEach(function(element) {
51        element.setAttribute('aria-hidden', 'true');
52        element.setAttribute('inert', '');
53      });
54      return;
55    }
56
57    mobileNavigationBackgroundStates.forEach(function(state) {
58      state.element.removeAttribute('inert');
59      if (state.ariaHidden === null) {
60        state.element.removeAttribute('aria-hidden');
61      } else {
62        state.element.setAttribute('aria-hidden', state.ariaHidden);
63      }
64    });
65    mobileNavigationBackgroundStates = [];
66  }
67
68  function setMobileNavigationOpen(options) {
69    var elements = getMobileNavElements();
70    if (!elements.button || !elements.nav) return;
71
72    var open = options.open;
73    elements.button.setAttribute('aria-expanded', open ? 'true' : 'false');
74    elements.nav.setAttribute('aria-hidden', open || !isMobileNavigationViewport() ? 'false' : 'true');
75    elements.nav.classList.toggle('is-visible', open);
76    if (elements.overlay) elements.overlay.classList.toggle('is-visible', open);
77    document.body.classList.toggle('usa-js-mobile-nav--active', open);
78    setMobileNavigationBackgroundHidden(open);
79
80    if (open) {
81      var firstTarget = elements.close || focusableElements(elements.nav)[0];
82      if (firstTarget) window.setTimeout(function() { firstTarget.focus(); }, 0);
83    } else if (options.restoreFocus) {
84      elements.button.focus();
85    }
86  }
87
88  function syncMobileNavigationAccessibility() {
89    var elements = getMobileNavElements();
90    if (!elements.nav) return;
91
92    if (!isMobileNavigationViewport() && elements.button && elements.button.getAttribute('aria-expanded') === 'true') {
93      setMobileNavigationOpen({ open: false, restoreFocus: false });
94      return;
95    }
96
97    elements.nav.setAttribute('aria-hidden', elements.button && elements.button.getAttribute('aria-expanded') === 'true'
98      ? 'false'
99      : (isMobileNavigationViewport() ? 'true' : 'false'));
100  }
101
102  function closeTopicsMenu() {
103    var topicsMenu = document.getElementById('megamenu-5');
104    var topicsButtons = Array.prototype.slice.call(document.querySelectorAll('[aria-controls="megamenu-5"]'));
105
106    topicsButtons.forEach(function(button) {
107      button.setAttribute('aria-expanded', 'false');
108    });
109
110    if (topicsMenu) {
111      topicsMenu.setAttribute('hidden', '');
112      topicsMenu.style.display = 'none';
113    }
114  }
115
116  function isLocalHost() {
117    return /^localhost$|^127\.|^\[?::1\]?$/.test(window.location.hostname);
118  }
119
120  function isSlashlessPagePath(pathname) {
121    if (!pathname || pathname === '/' || pathname.endsWith('/')) return false;
122    return !/\.[a-z0-9]{2,8}$/i.test(pathname);
123  }
124
125  var localExactPathStorageKey = 'mymoneyLocalExactPathTarget';
126
127  function localExactPathDisplayURL(targetUrl) {
128    return targetUrl.pathname + targetUrl.search + targetUrl.hash;
129  }
130
131  function localExactPathNavigationURL(targetUrl) {
132    var pathname = targetUrl.pathname;
133    if (!pathname.endsWith('/')) {
134      pathname += '/';
135    }
136    return pathname + targetUrl.search + targetUrl.hash;
137  }
138
139  function sameLocalExactPath(currentUrl, targetUrl) {
140    var currentPath = currentUrl.pathname.replace(/\/+$/, '') || '/';
141    var targetPath = targetUrl.pathname.replace(/\/+$/, '') || '/';
142    return currentPath === targetPath && currentUrl.search === targetUrl.search && currentUrl.hash === targetUrl.hash;
143  }
144
145  function normalizeLocalExactPathAfterNavigation() {
146    if (!isLocalHost()) return;
147
148    var storedTarget;
149    try {
150      storedTarget = window.sessionStorage.getItem(localExactPathStorageKey);
151      if (!storedTarget) return;
152    } catch (error) {
153      return;
154    }
155
156    var targetUrl = new URL(storedTarget, window.location.origin);
157    var currentUrl = new URL(window.location.href);
158
159    try {
160      window.sessionStorage.removeItem(localExactPathStorageKey);
161    } catch (error) {
162      // Ignore storage cleanup failures; the URL is the important behavior.
163    }
164
165    if (sameLocalExactPath(currentUrl, targetUrl)) {
166      window.history.replaceState(window.history.state || {}, '', localExactPathDisplayURL(targetUrl));
167    }
168  }
169
170  function navigateLocalExactPath(href) {
171    var targetUrl = new URL(href, window.location.href);
172
173    try {
174      window.sessionStorage.setItem(localExactPathStorageKey, localExactPathDisplayURL(targetUrl));
175    } catch (error) {
176      // If storage is unavailable, direct slash navigation still avoids the redirect loop.
177    }
178
179    window.location.assign(localExactPathNavigationURL(targetUrl));
180  }
181
182  function isLocalExactPathClick(event, link) {
183    if (!isLocalHost()) return false;
184    if (!link) return false;
185    if (event.defaultPrevented || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || event.button !== 0) return false;
186    if (link.target || link.hasAttribute('download')) return false;
187
188    var href = link.getAttribute('href') || '';
189    if (!href || href.startsWith('#') || href.startsWith('mailto:') || href.startsWith('tel:') || href.startsWith('javascript:')) return false;
190
191    var targetUrl;
192    try {
193      targetUrl = new URL(href, window.location.href);
194    } catch (error) {
195      return false;
196    }
197
198    if (targetUrl.origin !== window.location.origin) return false;
199    return isSlashlessPagePath(targetUrl.pathname);
200  }
201
202  normalizeLocalExactPathAfterNavigation();
203
204  function setSearchOpen(open) {
205    var searchMenu = getSearchMenu();
206    var searchButtons = getSearchButtons();
207
208    searchButtons.forEach(function(button) {
209      button.setAttribute('aria-expanded', open ? 'true' : 'false');
210    });
211
212    if (!searchMenu) return;
213
214    searchMenu.removeAttribute('hidden');
215    searchMenu.style.display = open ? 'block' : 'none';
216
217    if (open) {
218      closeTopicsMenu();
219      window.setTimeout(function() {
220        var input = searchMenu.querySelector('input[name="query"]');
221        if (input) input.focus();
222      }, 0);
223    }
224  }
225
226  document.addEventListener('click', function(event) {
227    var target = event.target;
228    if (!target || !target.closest) return;
229
230    var exactPathLink = target.closest('a[href]');
231    if (isLocalExactPathClick(event, exactPathLink)) {
232      event.preventDefault();
233      event.stopPropagation();
234      event.stopImmediatePropagation();
235      navigateLocalExactPath(exactPathLink.getAttribute('href'));
236      return;
237    }
238
239    var searchButton = target.closest('.treas-search-nav .search-btn');
240    if (searchButton) {
241      event.preventDefault();
242      event.stopPropagation();
243      event.stopImmediatePropagation();
244      setSearchOpen(searchButton.getAttribute('aria-expanded') !== 'true');
245      return;
246    }
247
248    if (target.closest('.usa-menu-btn, .treas-burger-menu')) {
249      event.preventDefault();
250      event.stopPropagation();
251      event.stopImmediatePropagation();
252      setMobileNavigationOpen({ open: true, restoreFocus: false });
253      return;
254    }
255
256    if (target.closest('.usa-nav__close') || target.closest('.usa-overlay')) {
257      event.preventDefault();
258      event.stopPropagation();
259      event.stopImmediatePropagation();
260      setMobileNavigationOpen({ open: false, restoreFocus: true });
261      return;
262    }
263
264    if (!target.closest('#megamenu-search') && !target.closest('.treas-search-nav')) {
265      setSearchOpen(false);
266    }
267  }, true);
268
269  document.addEventListener('keydown', function(event) {
270    if (event.key === 'Escape') {
271      setSearchOpen(false);
272      var mobileElements = getMobileNavElements();
273      if (mobileElements.button && mobileElements.button.getAttribute('aria-expanded') === 'true') {
274        setMobileNavigationOpen({ open: false, restoreFocus: true });
275      }
276      return;
277    }
278
279    var elements = getMobileNavElements();
280    if (event.key !== 'Tab' || !elements.nav || elements.button?.getAttribute('aria-expanded') !== 'true') return;
281
282    var targets = focusableElements(elements.nav);
283    if (!targets.length) return;
284
285    var firstTarget = targets[0];
286    var lastTarget = targets[targets.length - 1];
287    if (event.shiftKey && document.activeElement === firstTarget) {
288      event.preventDefault();
289      lastTarget.focus();
290    } else if (!event.shiftKey && document.activeElement === lastTarget) {
291      event.preventDefault();
292      firstTarget.focus();
293    }
294  });
295
296  window.addEventListener('resize', syncMobileNavigationAccessibility);
297
298  document.addEventListener('DOMContentLoaded', function() {
299    var searchMenu = getSearchMenu();
300    syncMobileNavigationAccessibility();
301    if (!searchMenu) return;
302    searchMenu.removeAttribute('hidden');
303    searchMenu.style.display = 'none';
304    getSearchButtons().forEach(function(button) {
305      button.setAttribute('aria-expanded', 'false');
306    });
307  });
308})();
309
310(function($) {
311  'use strict';
312
313  // Run after a short delay to ensure all other scripts have loaded
314  $(window).on('load', function() {
315    // Delay to ensure we run AFTER site-scripts.js and USWDS handlers
316    setTimeout(initMyMoney, 100);
317  });
318
319  // Also run on document ready as fallback
320  $(document).ready(function() {
321    setTimeout(initMyMoney, 100);
322  });
323
324  var initialized = false;
325
326  function initMyMoney() {
327    if (initialized) return;
328    initialized = true;
329
330    // Accordions are initialized with hidden attribute - JS click handler toggles it
331
332    // Initialize Slick Slider for hero carousel
333    if ($('.slick__slider').length && !$('.slick__slider').hasClass('slick-initialized')) {
334      $('.slick__slider').slick({
335        autoplay: true,
336        autoplaySpeed: 10000,
337        arrows: false,
338        dots: true,
339        fade: true,
340        speed: 500,
341        cssEase: 'ease-in-out',
342        pauseOnHover: true,
343        pauseOnFocus: true,
344        infinite: true
345      });
346    }
347
348    // Remove any existing click handlers and add new ones
349    var $searchBtn = $('.search-btn');
350    var $searchMenu = $('#megamenu-search');
351    var $topicsBtn = $('button[aria-controls="megamenu-5"]');
352    var $topicsMenu = $('#megamenu-5');
353
354    // Ensure search menu starts hidden properly, unless the dependency-free
355    // click handler already opened it before jQuery finished initializing.
356    var searchIsExpanded = $searchBtn.filter('[aria-expanded="true"]').length > 0;
357    $searchMenu.removeAttr('hidden').css('display', searchIsExpanded ? 'block' : 'none');
358
359    // Search button toggle - remove ALL click handlers first (including USWDS)
360    $searchBtn.off('click').on('click', function(e) {
361      e.preventDefault();
362      e.stopPropagation();
363      e.stopImmediatePropagation();
364
365      var isExpanded = $(this).attr('aria-expanded') === 'true';
366
367      // Close topics menu if open
368      $topicsMenu.attr('hidden', '').css('display', 'none');
369      $topicsBtn.attr('aria-expanded', 'false');
370
371      // Toggle search menu
372      if (isExpanded) {
373        $(this).attr('aria-expanded', 'false');
374        $searchMenu.hide();
375      } else {
376        $(this).attr('aria-expanded', 'true');
377        $searchMenu.show();
378      }
379
380      return false;
381    });
382
383    // Topics dropdown toggle - match USWDS/live behavior by toggling aria and hidden.
384    $topicsBtn.off('click').on('click', function(e) {
385      e.preventDefault();
386      e.stopPropagation();
387      e.stopImmediatePropagation();
388
389      var isExpanded = $(this).attr('aria-expanded') === 'true';
390
391      // Close search menu if open
392      $searchMenu.css('display', 'none');
393      $searchBtn.attr('aria-expanded', 'false');
394
395      if (isExpanded) {
396        $(this).attr('aria-expanded', 'false');
397        $topicsMenu.attr('hidden', '').css('display', 'none');
398      } else {
399        $(this).attr('aria-expanded', 'true');
400        $topicsMenu.removeAttr('hidden').css('display', 'block');
401      }
402
403      return false;
404    });
405
406    // Mobile menu toggle
407    $('.usa-menu-btn, .treas-burger-menu').off('click').on('click.mymoney', function(e) {
408      e.preventDefault();
409      e.stopPropagation();
410      e.stopImmediatePropagation();
411      $('.usa-nav, .treas-main-nav').addClass('is-visible');
412      $('.usa-overlay').addClass('is-visible');
413      $('body').addClass('usa-js-mobile-nav--active');
414      this.blur();
415      return false;
416    });
417
418    $('.usa-nav__close').off('click').on('click.mymoney', function(e) {
419      e.preventDefault();
420      e.stopPropagation();
421      e.stopImmediatePropagation();
422      $('.usa-nav, .treas-main-nav').removeClass('is-visible');
423      $('.usa-overlay').removeClass('is-visible');
424      $('body').removeClass('usa-js-mobile-nav--active');
425      return false;
426    });
427
428    $('.usa-overlay').off('click.mymoney').on('click.mymoney', function(e) {
429      e.preventDefault();
430      e.stopPropagation();
431      $('.usa-nav, .treas-main-nav').removeClass('is-visible');
432      $(this).removeClass('is-visible');
433      $('body').removeClass('usa-js-mobile-nav--active');
434      return false;
435    });
436
437    // Government banner toggle - initialize and handle click
438    var $bannerContent = $('#gov-banner');
439    var $bannerButton = $('.usa-banner__button');
440
441    // Remove hidden attribute and set initial state via CSS
442    $bannerContent.removeAttr('hidden').css('display', 'none');
443
444    $bannerButton.off('click.mymoney').on('click.mymoney', function(e) {
445      e.preventDefault();
446      e.stopPropagation();
447      var isExpanded = $(this).attr('aria-expanded') === 'true';
448
449      $(this).attr('aria-expanded', !isExpanded);
450      if (isExpanded) {
451        $bannerContent.hide();
452      } else {
453        $bannerContent.show();
454      }
455    });
456
457    // Close menus when clicking outside
458    $(document).off('click.mymoney-outside').on('click.mymoney-outside', function(e) {
459      // Close search menu
460      if (!$(e.target).closest('.treas-search-nav, #megamenu-search, .search-btn').length) {
461        $searchMenu.hide();
462        $searchBtn.attr('aria-expanded', 'false');
463      }
464      // Close topics menu
465      if (!$(e.target).closest('[aria-controls="megamenu-5"], #megamenu-5').length) {
466        $topicsBtn.attr('aria-expanded', 'false');
467        $topicsMenu.attr('hidden', '').css('display', 'none');
468      }
469    });
470  }
471
472})(jQuery);

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.