PageSourceSearch

https://www.fema.gov/profiles/femad8_gov/themes/fema_uswds/js/fema_chosen_fix.js?v=1.x

js fema.gov collected 2026-10-01 07:44:20 UTC 3,491 bytes, 115 lines download raw bytes

1(function ($, Drupal, once) {
2  'use strict';
3
4  const fixChosenTabs = () => {
5    $("select[tabindex='-1']+.chosen-container").attr('tabindex', '0');
6  };
7
8  const watchChosenTabs = () => {
9    $('button.usa-accordion__button[aria-controls="edit-secondary-content"]').on('click', fixChosenTabs);
10  };
11
12  Drupal.behaviors.chosenTabFix = {
13    attach: function (context) {
14      fixChosenTabs();
15      watchChosenTabs();
16    },
17  };
18
19  const CHOSEN_EVENTS = [
20    'chosen:ready',
21    'chosen:showing_dropdown',
22    'chosen:hiding_dropdown',
23    'chosen:updated',
24    'chosen:search',
25  ];
26
27  /**
28   * Ensures Chosen no-results items satisfy listbox child requirements.
29   */
30  function ensureNoResultsOption(resultsEl) {
31    const noResults = resultsEl.querySelector('li.no-results');
32    if (noResults && !noResults.getAttribute('role')) {
33      noResults.setAttribute('role', 'option');
34    }
35  }
36
37  /**
38   * Determines whether a Chosen results list has valid listbox children.
39   */
40  function hasListboxOptions(resultsEl) {
41    ensureNoResultsOption(resultsEl);
42    return resultsEl.querySelectorAll('li[role="option"]').length > 0;
43  }
44
45  /**
46   * Syncs accessibility attributes on a Chosen results listbox.
47   *
48   * Empty listboxes are removed from the accessibility tree to satisfy
49   * SiteImprove SIA-R68 (#1546). Options are restored when results exist.
50   */
51  function syncChosenResultsAccessibility(resultsEl) {
52    if (!resultsEl || !resultsEl.classList.contains('chosen-results')) {
53      return;
54    }
55
56    if (hasListboxOptions(resultsEl)) {
57      resultsEl.removeAttribute('hidden');
58      resultsEl.removeAttribute('aria-hidden');
59      resultsEl.setAttribute('role', 'listbox');
60    }
61    else {
62      resultsEl.setAttribute('hidden', '');
63      resultsEl.setAttribute('aria-hidden', 'true');
64      resultsEl.setAttribute('role', 'presentation');
65    }
66  }
67
68  /**
69   * Binds Chosen lifecycle listeners for a select element.
70   */
71  function bindChosenAccessibilityEvents(selectEl) {
72    CHOSEN_EVENTS.forEach((eventName) => {
73      selectEl.addEventListener(eventName, () => {
74        const container = selectEl.nextElementSibling;
75        if (!container || !container.classList.contains('chosen-container')) {
76          return;
77        }
78        syncChosenResultsAccessibility(container.querySelector('.chosen-results'));
79      });
80    });
81  }
82
83  Drupal.behaviors.chosenEmptyListboxFix = {
84    attach(context) {
85      once('chosen-empty-listbox-fix', 'select', context).forEach((selectEl) => {
86        bindChosenAccessibilityEvents(selectEl);
87
88        const container = selectEl.nextElementSibling;
89        if (container && container.classList.contains('chosen-container')) {
90          syncChosenResultsAccessibility(container.querySelector('.chosen-results'));
91        }
92      });
93
94      once('chosen-empty-listbox-sync', '.chosen-results', context).forEach((resultsEl) => {
95        syncChosenResultsAccessibility(resultsEl);
96      });
97    },
98  };
99
100  $(document).on('ajaxComplete', function () {
101    document.querySelectorAll('.chosen-results').forEach(syncChosenResultsAccessibility);
102  });
103
104  // #1458: Remove aria-label from divs without role.
105  Drupal.behaviors.chosenAriaLabelFix = {
106    attach(context) {
107      once('chosen-aria-label-fix', '.chosen-container div[aria-label]', context).forEach((element) => {
108        if (!element.getAttribute('role')) {
109          element.removeAttribute('aria-label');
110        }
111      });
112    },
113  };
114
115})(jQuery, Drupal, once);

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.