PageSourceSearch

https://www.griesingen.de/_assets/68bd152eb8a807512de054076d8e1f2a…/Dist/panel-navigation.js?1702546506

js griesingen.de collected 2026-10-02 20:55:52 UTC 3,618 bytes, 120 lines download raw bytes

1
2const hasTransition = (element) => {
3    const {transition} = getComputedStyle(element);
4    return transition !== 'none 0s ease 0s';
5}
6
7const waitUntilTransitioned = async (element) => {
8
9    return new Promise((resolve) => {
10
11        if(!hasTransition(element)) {
12            resolve();
13        }
14
15        const cb = () => {
16            removeEventListener('transitionend', cb);
17            resolve();
18        }
19
20        element.addEventListener('transitionend', cb);
21    })
22
23}
24
25const trapFocus = (element) => {
26
27    const focusable = element.querySelectorAll('a[href]:not(.hidden a[href]), button:not(.hidden button)');
28    const firstFocusable = focusable[0];
29    const lastFocusable = focusable[focusable.length - 1];
30
31    element.addEventListener('keydown', (e) => {
32
33        if (e.key === 'Tab') {
34            if (e.shiftKey) {
35              if (document.activeElement === firstFocusable) {
36                e.preventDefault();
37                lastFocusable.focus();
38              }
39            } else {
40              if (document.activeElement === lastFocusable) {
41                e.preventDefault();
42                firstFocusable.focus();
43              }
44            }
45          }
46    });
47
48    firstFocusable.focus();
49}
50
51
52const openPanelMenu = async () => {
53    const popover = document.getElementById('panel-menu-popover');
54
55    const backdrop = document.querySelector('.panel-menu-backdrop');
56    const menu = document.querySelector('.panel-menu');
57
58    popover.classList.add('opening');
59    await Promise.all([waitUntilTransitioned(backdrop), waitUntilTransitioned(menu)]);
60    popover.classList.replace('opening', 'open');
61    trapFocus(menu);
62
63}
64
65const closePanelMenu = async () => {
66    const popover = document.getElementById('panel-menu-popover');
67
68    const backdrop = document.querySelector('.panel-menu-backdrop');
69    const menu = document.querySelector('.panel-menu');
70
71    popover.classList.replace('open', 'closing');
72    await Promise.all([waitUntilTransitioned(backdrop), waitUntilTransitioned(menu)]);
73    popover.classList.remove('closing');
74
75    document.querySelector('.panel-menu-toggle')?.focus();
76}
77
78const togglePanelMenu = () => isPanelMenuOpen() ? closePanelMenu() : openPanelMenu();
79
80const isPanelMenuOpen = () => {
81    return document.getElementById('panel-menu-popover')?.classList.contains('open') ?? false;
82}
83
84
85const registerPanelMenu = () => {
86
87    document.querySelectorAll('.panel-menu-toggle').forEach((toggler) => {
88        toggler.addEventListener('click', togglePanelMenu);
89    });
90
91    document.querySelector('.panel-menu-backdrop')?.addEventListener('click', closePanelMenu);
92
93    document.addEventListener('keyup', ({key}) => {
94
95        if(key === 'Escape') {
96            closePanelMenu();
97        }
98    })
99
100
101    document.querySelectorAll('[data-panel-menu-link-to]').forEach((menuLink) => {
102        
103        menuLink.addEventListener('click', async (event) => {
104            event.preventDefault();
105            event.stopPropagation();
106            const {panelMenuLinkTo} = menuLink.dataset;
107            const currentPanel = menuLink.closest('.menu-panel');
108            const nextPanel = document.getElementById(`menu-panel-${panelMenuLinkTo}`);
109            currentPanel.classList.add('hidden');
110            nextPanel.classList.remove('hidden');
111
112            await waitUntilTransitioned(nextPanel);
113            trapFocus(document.querySelector('.panel-menu'))
114        })
115
116    })
117}
118
119
120document.addEventListener('DOMContentLoaded', registerPanelMenu);

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.