PageSourceSearch

https://www.sindelfingen.de/fileadmin/templates/extensions/hw_menu/js/hw_mainmenu.js

js sindelfingen.de collected 2026-10-02 04:37:36 UTC 7,482 bytes, 215 lines download raw bytes

1import * as hwMenu from './hw_menu__shared.js';
2
3export function generateMainMenuData(currentId) {
4	const hwMenuContainer = document.querySelector('.hw_menu');
5	let hw_menu__data__main = hwMenu.getData(hwMenuContainer);
6	let activeElement = hwMenu.buildMenuData(hw_menu__data__main, currentId);
7
8	if (Object.keys(activeElement).length === 0) {
9
10        const url = hwMenu.findMatchingBaseUrl(window.location.href, hw_menu__data__main);
11
12		activeElement = hwMenu.getElementWithUrl(hw_menu__data__main, url);
13		activeElement.active = true;
14		activeElement.parentOfActive = true;
15		hwMenu.getParents(activeElement).forEach(parent => {
16			parent.parentOfActive = true;
17		});
18	}
19
20	hw_menu__data__main[0].activeElement = activeElement;
21
22	return hw_menu__data__main;
23}
24
25export function generateMainMenu(container, data, maxDepth, logoElement, footerElement) {
26	const activeElement = data[0].activeElement;
27
28	container.append(buildMainMenu(data, 1, maxDepth, activeElement, logoElement, footerElement));
29	hwMenu.initializeMenu(data, 'mainMenu', 0);
30
31	hwMenu.initGlobalArrowKeyScroll();
32}
33
34// Funktion um das Hauptmenü zu generieren
35function buildMainMenu(data, depth, maxDepth, activeElement, logoElement, footerElement) {
36	const menuList = `
37				<nav class="hw_menu__primary">
38					<button class="hw_menu__mobile_button__search" type="button" aria-pressed="false">
39						<span class="sr-only">Suche öffnen</span>
40						<hw-menu-button-icon-wrap>
41							<i class="fa-regular fa-magnifying-glass" aria-hidden="true"></i> 
42							<!-- <i class="fa-duotone fa-horizontal-rule" aria-hidden="true" style="&#45;&#45;fa-secondary-opacity: 1;"></i> -->  
43							<!-- <i class="fa-duotone fa-horizontal-rule" aria-hidden="true" style="&#45;&#45;fa-secondary-opacity: .5;"></i> -->
44						</hw-menu-button-icon-wrap>
45					</button>
46					
47					<button class="hw_menu__desktop_button hw_menu__main_button__menu" type="button" aria-pressed="false">
48						<hw-menu-button-icon-wrap>
49							<i class="fa-regular fa-sharp fa-flip-horizontal fa-bars" style="--fa-secondary-opacity: 0.5;"></i>
50							<i class="fa-solid fa-horizontal-rule" style="--fa-secondary-opacity: .75;"></i>
51							<i class="fa-solid fa-horizontal-rule" style="--fa-secondary-opacity: .5;"></i>
52						</hw-menu-button-icon-wrap>
53						<span>Menü <span class="sr-only">öffnen</span></span>
54					</button>
55		
56					<div class="hw_menu__page" data-depth="0"  aria-expanded="false">
57						${logoElement.outerHTML}					
58						<ul class="hw_menu__list" data-depth="0"></ul>			
59						${footerElement.outerHTML}		
60					</div>
61				</nav>
62			`;
63
64	const menuListHtmlFragment = document.createRange().createContextualFragment(menuList);
65
66	data[0].node = menuListHtmlFragment.querySelector('.hw_menu__main_button__menu');
67
68	data[0].node.addEventListener('click', (event) => {
69		event.stopImmediatePropagation();
70
71		const state = !data[0].expanded;
72
73		data[0].setExpanded(state);
74		data[0].setChildrenVisible(state);
75
76		document.body.classList.toggle('hw_menu__open', state);
77
78		document.querySelectorAll('.hw_menu__list[data-depth="0"], .hw_menu__list[data-depth="1"]').forEach(node => {
79			const menu_page = node.closest('.hw_menu__page');
80
81			if (node.scrollHeight > node.clientHeight) {
82				menu_page.setAttribute('data-scrollable', 'true');
83			} else {
84				menu_page.setAttribute('data-scrollable', 'false');
85			}
86
87			// Pfeiltasten-Navigation initialisieren
88			hwMenu.initArrowKeyScroll(node);
89		});
90	});
91
92	window.addEventListener('resize', () => {
93
94		const open = data[0].expanded;
95
96		if (open) {
97			document.querySelectorAll('.hw_menu__list[data-depth="0"], .hw_menu__list[data-depth="1"]').forEach(node => {
98				const menu_page = node.closest('.hw_menu__page');
99
100				if (node.scrollHeight > node.clientHeight) {
101					menu_page.setAttribute('data-scrollable', 'true');
102				} else {
103					menu_page.setAttribute('data-scrollable', 'false');
104				}
105
106				// Pfeiltasten-Navigation initialisieren
107				hwMenu.initArrowKeyScroll(node);
108			});
109		}
110	});
111
112	const dataAtDepth = hwMenu.getElementsAtDepth(data, depth);
113  
114	const searchButton = menuListHtmlFragment.querySelector('.hw_menu__mobile_button__search');
115
116	if(searchButton) {
117		searchButton.addEventListener('click', (event) => {
118			event.stopImmediatePropagation();
119
120			document.querySelector('hw-solr-main')._solrMain.openDialog('');
121
122			if (!document.body.classList.contains('hw_search__open') && document.body.classList.contains('hw_menu__open')) {
123
124				document.querySelector('.hw_menu__button[data-depth="1"][aria-pressed="true"]').click();
125			}
126		});
127	}
128
129	dataAtDepth.map(itemData => {
130		let menuListElementHtmlFragment;
131
132		if (itemData.children.length > 0) {
133			const mainMenuListElement = `
134						<li class="hw_menu__list_element">
135							<button type="button" class="hw_menu__button" data-depth="${itemData.depth}" aria-pressed="${itemData.expanded}" data-parent-of-active="${itemData.parentOfActive}">
136								<span class="hw_menu__button__inner_text">
137									<span>${itemData.title}</span>
138									${itemData.subtitle ? `<span>${itemData.subtitle}</span>` : ''}
139								</span>
140							</button>
141						</li>
142					`;
143
144			menuListElementHtmlFragment = document.createRange().createContextualFragment(mainMenuListElement);
145			const button = menuListElementHtmlFragment.querySelector('.hw_menu__button');
146
147			itemData.node = button;
148
149			button.addEventListener('click', event => {
150				event.stopImmediatePropagation();
151
152				const state = !itemData.expanded;
153
154				hwMenu.closeOpenMenu(itemData);
155				itemData.setExpanded(state);
156				itemData.setChildrenVisible(state);
157
158
159
160				// if (itemData.parent.children.filter(child => child.expanded === true).length === 0) {
161				// 	document.body.classList.remove('hw_menu__open');
162				// } else {
163				// 	document.body.classList.add('hw_menu__open');
164				//
165				// 	if (document.body.classList.contains('hw_search__open')) {
166				// 		document.querySelector('.hw_menu__mobile_button__search').click();
167				// 	}
168				// }
169			});
170
171			menuListElementHtmlFragment.querySelector('.hw_menu__list_element').append(buildMenuPage(itemData, maxDepth, activeElement, footerElement));
172		} else {
173			const mainMenuListElement = `
174						<li class="hw_menu__list_element">
175						</li>
176					`;
177
178			menuListElementHtmlFragment = document.createRange().createContextualFragment(mainMenuListElement);
179
180			menuListElementHtmlFragment.querySelector('.hw_menu__list_element').append(hwMenu.buildMenuLink(itemData, maxDepth, activeElement));
181		}
182
183		menuListHtmlFragment.querySelector('.hw_menu__list').append(menuListElementHtmlFragment);
184	});
185
186	return menuListHtmlFragment;
187}
188
189function buildMenuPage(data, maxDepth, activeElement, footerElement) {
190	const menuPage = `
191				<div class="hw_menu__page" data-depth="${data.depth}"  aria-expanded="${data.expanded}">
192					<ul class="hw_menu__list" data-depth="${data.depth}">
193					</ul>
194					${footerElement.outerHTML}		
195				</div>
196			`;
197
198	const htmlFragment = document.createRange().createContextualFragment(menuPage);
199	// const closeButton = htmlFragment.querySelector('.hw_menu__close_button');
200	//
201	// closeButton.addEventListener('click', event => {
202	// 	event.stopImmediatePropagation();
203	//
204	// 	data.setChildrenVisible(false);
205	// 	data.setExpanded(false);
206	//
207	// 	document.body.classList.remove('hw_menu__open');
208	// });
209
210	data.children.map(itemData => {
211		htmlFragment.querySelector('.hw_menu__list').append(hwMenu.buildMenuListElement(itemData, true, maxDepth, activeElement));
212	});
213
214	return htmlFragment;
215}

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.