PageSourceSearch

https://www.cox-pta.org/wp-content/themes/rallytrain-theme/assets/nav.js?ver=2.26.15

js cox-pta.org collected 2026-10-02 01:06:59 UTC 4,838 bytes, 145 lines download raw bytes

1/**
2 * RallyTrain theme: mobile navigation drawer.
3 *
4 * Turns the primary nav into an off-canvas drawer (slides in from the right)
5 * with a full-screen backdrop. Closes on the ✕ button, an overlay/outside
6 * click, Escape, or a nav-link click. Progressive enhancement: if this script
7 * doesn't load the toggle simply does nothing.
8 */
9(function () {
10	'use strict';
11
12	document.addEventListener('DOMContentLoaded', function () {
13		var toggle = document.querySelector('.rt-menu-toggle');
14		var nav = document.getElementById('rt-primary-nav');
15		var overlay = document.querySelector('.rt-nav-overlay');
16		var closeBtn = nav ? nav.querySelector('.rt-nav-close') : null;
17
18		if (!toggle || !nav) {
19			return;
20		}
21
22		function isOpen() {
23			return nav.classList.contains('is-open');
24		}
25
26		function open() {
27			nav.classList.add('is-open');
28			if (overlay) {
29				overlay.classList.add('is-open');
30			}
31			document.body.classList.add('rt-nav-open');
32			toggle.setAttribute('aria-expanded', 'true');
33			if (closeBtn) {
34				closeBtn.focus({ preventScroll: true });
35			}
36		}
37
38		function close() {
39			nav.classList.remove('is-open');
40			if (overlay) {
41				overlay.classList.remove('is-open');
42			}
43			document.body.classList.remove('rt-nav-open');
44			toggle.setAttribute('aria-expanded', 'false');
45			toggle.focus({ preventScroll: true });
46			// Collapsed-submenu mode: a reopened drawer starts tidy.
47			nav.querySelectorAll('.rt-submenu-open').forEach(function (li) {
48				li.classList.remove('rt-submenu-open');
49				var btn = li.querySelector(':scope > .rt-submenu-toggle');
50				if (btn) {
51					btn.setAttribute('aria-expanded', 'false');
52				}
53			});
54		}
55
56		toggle.addEventListener('click', function () {
57			if (isOpen()) {
58				close();
59			} else {
60				open();
61			}
62		});
63
64		if (overlay) {
65			overlay.addEventListener('click', close);
66		}
67		if (closeBtn) {
68			closeBtn.addEventListener('click', close);
69		}
70
71		document.addEventListener('keydown', function (e) {
72			if (e.key === 'Escape' && isOpen()) {
73				close();
74			}
75		});
76
77		// Clicks inside the drawer. A parent that owns a submenu is a TOGGLE
78		// there, never a link: every parent has a child that goes where the
79		// parent used to, and a mis-tap navigating away mid-browse was the
80		// complaint. Ordinary links still navigate and close the drawer.
81		nav.addEventListener('click', function (e) {
82			var a = e.target && e.target.closest ? e.target.closest('a') : null;
83			if (!a) {
84				return;
85			}
86			var li = a.parentElement;
87			if (isOpen() && li && li.classList.contains('menu-item-has-children')) {
88				e.preventDefault();
89				if (document.body.classList.contains('rt-mobile-submenus-closed')) {
90					var open = li.classList.toggle('rt-submenu-open');
91					var btn = li.querySelector(':scope > .rt-submenu-toggle');
92					if (btn) {
93						btn.setAttribute('aria-expanded', open ? 'true' : 'false');
94					}
95				}
96				return;
97			}
98			close();
99		});
100
101		// Collapsed-submenu mode (body class printed by the plugin when the
102		// site's Mobile menu setting is "closed"): give every parent item a
103		// real toggle button. The parent link keeps navigating; only the
104		// button expands. Buttons are display:none outside the drawer.
105		if (document.body.classList.contains('rt-mobile-submenus-closed')) {
106			nav.querySelectorAll('.menu-item-has-children').forEach(function (li) {
107				var btn = document.createElement('button');
108				btn.type = 'button';
109				btn.className = 'rt-submenu-toggle';
110				btn.setAttribute('aria-expanded', 'false');
111				btn.setAttribute('aria-label', 'Toggle submenu');
112				btn.addEventListener('click', function (e) {
113					e.stopPropagation();
114					var open = li.classList.toggle('rt-submenu-open');
115					btn.setAttribute('aria-expanded', open ? 'true' : 'false');
116				});
117				li.insertBefore(btn, li.querySelector(':scope > ul'));
118			});
119		}
120
121		// Suppress drawer transitions while the window is resizing, so the drawer
122		// doesn't animate into view when crossing the mobile breakpoint.
123		var resizeTimer;
124		window.addEventListener('resize', function () {
125			document.documentElement.classList.add('rt-resizing');
126			clearTimeout(resizeTimer);
127			resizeTimer = setTimeout(function () {
128				document.documentElement.classList.remove('rt-resizing');
129			}, 200);
130		});
131	});
132})();
133
134/* External links open in a new tab, site-wide. Content authors never have to
135   remember target="_blank"; internal links are untouched. */
136document.addEventListener('DOMContentLoaded', function () {
137	document.querySelectorAll('a[href^="http"]').forEach(function (a) {
138		if (a.host && a.host !== window.location.host) {
139			a.target = '_blank';
140			if (!/\bnoopener\b/.test(a.rel)) {
141				a.rel = (a.rel ? a.rel + ' ' : '') + 'noopener';
142			}
143		}
144	});
145});

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.