PageSourceSearch

https://rehampson.com/wp-content/themes/modfarm-theme/assets/js/navigation-toggle.js?ver=1789344205

js rehampson.com collected 2026-10-06 05:17:00 UTC 8,792 bytes, 169 lines download raw bytes

1(function () {
2  'use strict';
3  var serial = 0;
4  var controllers = new Set();
5  function init(root) {
6    root.querySelectorAll('.mfs-nav').forEach(function (nav) {
7      if (nav.dataset.mfsReady) { if (nav.mfsEnhance) nav.mfsEnhance(); return; }
8      nav.dataset.mfsReady = 'true';
9      var toggle = nav.querySelector('.mfs-nav-toggle');
10      var overlay = nav.querySelector('.mfs-nav-overlay');
11      var panel = nav.querySelector('.mfs-nav-panel');
12      var below = nav.classList.contains('mfs-nav--below');
13      var placeholder = overlay ? document.createComment('mobile navigation') : null;
14      var isOpen = false, inertNodes = [], oldOverflow = '';
15      var search = nav.querySelector('.mfs-nav-search');
16      if (search) {
17        search.addEventListener('toggle', function () {
18          if (search.open) search.querySelector('input').focus();
19        });
20        search.addEventListener('keydown', function (event) {
21          if (event.key === 'Escape') {
22            event.stopPropagation(); search.open = false; search.querySelector('summary').focus();
23          }
24        });
25        document.addEventListener('click', function (event) {
26          if (!search.contains(event.target)) search.open = false;
27        });
28      }
29      function direct(item, selector) {
30        return Array.from(item.children).find(function (child) { return child.matches(selector); });
31      }
32      function setExpanded(item, expanded) {
33        item.classList.toggle('open', expanded);
34        var button = direct(item, '.mfs-submenu-toggle');
35        if (button) button.setAttribute('aria-expanded', String(expanded));
36        if (!expanded) item.querySelectorAll('li.open').forEach(function (child) { setExpanded(child, false); });
37      }
38      function reset() {
39        nav.querySelectorAll('li.open').forEach(function (item) { setExpanded(item, false); });
40        if (overlay) overlay.querySelectorAll('li.open').forEach(function (item) { setExpanded(item, false); });
41      }
42      function close(restoreFocus) {
43        if (!isOpen) return;
44        isOpen = false;
45        overlay.hidden = true;
46        overlay.classList.remove('active');
47        toggle.setAttribute('aria-expanded', 'false');
48        toggle.setAttribute('aria-label', 'Open menu');
49        if (!below) {
50          inertNodes.forEach(function (entry) { entry[0].inert = entry[1]; });
51          inertNodes = [];
52          document.body.style.overflow = oldOverflow;
53          if (placeholder.parentNode) placeholder.replaceWith(overlay);
54        }
55        reset();
56        if (restoreFocus !== false && toggle.isConnected) toggle.focus();
57      }
58      function open() {
59        if (search) search.open = false;
60        controllers.forEach(function (controller) { if (controller !== close) controller(false); });
61        if (!below) {
62          // Escape transformed/clipped theme containers while preserving resolved styles.
63          var computed = getComputedStyle(nav);
64          overlay.style.fontFamily = computed.fontFamily;
65          overlay.style.fontSize = computed.fontSize;
66          ['--mfs-mobile-bg','--mfs-mobile-color','--submenu-bg','--submenu-color','--mf-nav-hover-color','--mf-nav-font','--mf-nav-font-size','--mfs-menu-icon-size','--mfs-menu-image-gap'].forEach(function (key) {
67            overlay.style.setProperty(key, computed.getPropertyValue(key));
68          });
69          overlay.classList.toggle('mfs-mobile-drawer', nav.classList.contains('mfs-nav--drawer'));
70          overlay.classList.toggle('mfs-mobile-left', nav.classList.contains('mfs-nav--drawer-left'));
71          overlay.replaceWith(placeholder);
72          document.body.appendChild(overlay);
73          oldOverflow = document.body.style.overflow;
74          document.body.style.overflow = 'hidden';
75          Array.from(document.body.children).forEach(function (element) {
76            if (element !== overlay && !['SCRIPT','STYLE','LINK'].includes(element.tagName)) {
77              inertNodes.push([element, element.inert]); element.inert = true;
78            }
79          });
80        }
81        isOpen = true;
82        overlay.hidden = false;
83        overlay.classList.add('active');
84        toggle.setAttribute('aria-expanded', 'true');
85        toggle.setAttribute('aria-label', 'Close menu');
86        if (!below) panel.querySelector('.mfs-nav-close').focus();
87      }
88      if (toggle && overlay && panel) {
89        controllers.add(close);
90        toggle.addEventListener('click', function () { if (isOpen) close(); else open(); });
91        overlay.querySelector('.mfs-nav-close').addEventListener('click', function () { close(); });
92        overlay.addEventListener('click', function (event) {
93          if (event.target === overlay || event.target.closest('a')) close();
94        });
95        overlay.addEventListener('keydown', function (event) {
96          if (!isOpen || below || event.key !== 'Tab') return;
97          var focusable = Array.from(panel.querySelectorAll('a[href],button,input,select,textarea,[tabindex="0"]')).filter(function (el) { return !el.disabled && el.getClientRects().length; });
98          var first = focusable[0], last = focusable[focusable.length - 1];
99          if (event.shiftKey && (document.activeElement === first || document.activeElement === panel)) { event.preventDefault(); last.focus(); }
100          else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); }
101        });
102      }
103      nav.mfsEnhance = function () {
104      var items = Array.from(nav.querySelectorAll('li.menu-item-has-children'));
105      if (overlay && !nav.contains(overlay)) items = items.concat(Array.from(overlay.querySelectorAll('li.menu-item-has-children')));
106      items.forEach(function (item) {
107        if (item.dataset.mfsSubmenuReady) return;
108        item.dataset.mfsSubmenuReady = 'true';
109        var submenu = direct(item, '.sub-menu'), anchor = direct(item, 'a');
110        if (!submenu || !anchor) return;
111        var mobile = !!item.closest('.mfs-nav-overlay');
112        // wp_nav_menu is rendered twice: give every generated submenu a unique ID.
113        submenu.id = 'mfs-submenu-' + (++serial);
114        var button = document.createElement('button');
115        button.type = 'button'; button.className = 'mfs-submenu-toggle';
116        button.setAttribute('aria-expanded', 'false');
117        button.setAttribute('aria-controls', submenu.id);
118        button.setAttribute('aria-label', 'Toggle submenu: ' + (anchor.querySelector('.mfs-menu-label') || anchor).textContent.trim());
119        button.innerHTML = '<span aria-hidden="true"></span>';
120        anchor.after(button);
121        function position() {
122          if (mobile) return;
123          item.classList.remove('submenu-align-right');
124          if (submenu.getBoundingClientRect().right > window.innerWidth - 8) item.classList.add('submenu-align-right');
125        }
126        button.addEventListener('click', function () {
127          var next = !item.classList.contains('open');
128          Array.from(item.parentElement.children).forEach(function (sibling) { if (sibling !== item) setExpanded(sibling, false); });
129          setExpanded(item, next); position();
130        });
131        if (!mobile) {
132          item.addEventListener('mouseenter', function () {
133            if (window.matchMedia('(hover: hover)').matches) { setExpanded(item, true); position(); }
134          });
135          item.addEventListener('mouseleave', function () {
136            if (!item.contains(document.activeElement)) setExpanded(item, false);
137          });
138          item.addEventListener('focusout', function (event) {
139            if (!item.contains(event.relatedTarget)) setExpanded(item, false);
140          });
141        }
142        submenu.addEventListener('keydown', function (event) {
143          if (event.key === 'Escape') { event.stopPropagation(); setExpanded(item, false); button.focus(); }
144        });
145      });
146      };
147      nav.mfsEnhance();
148      document.addEventListener('keydown', function (event) {
149        if (event.key !== 'Escape') return;
150        if (isOpen) close(); else reset();
151      });
152      document.addEventListener('click', function (event) {
153        if (!nav.contains(event.target) && !(overlay && overlay.contains(event.target))) {
154          if (below && isOpen) close(false);
155          reset();
156        }
157      });
158      window.addEventListener('resize', function () {
159        if (window.innerWidth > 1024) close(false);
160      });
161    });
162  }
163  function boot() { init(document); }
164  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot); else boot();
165  // Customizer selective refresh replaces block markup without a page load.
166  if (window.wp && wp.customize && wp.customize.selectiveRefresh) {
167    wp.customize.selectiveRefresh.bind('partial-content-rendered', boot);
168  }
169})();

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.