PageSourceSearch

https://sbsstudent.se/wp-content/plugins/qase-blocks/js/qase-blocks-accordion.js?ver=0.3.5

js sbsstudent.se collected 2026-10-05 05:53:46 UTC 3,016 bytes, 90 lines download raw bytes

1const fixDuplicateAccordionIds = () => {
2    const items = document.querySelectorAll("[data-accordion='accordion-item']");
3    const usedIds = new Set();
4
5    items.forEach((item) => {
6        const trigger = item.querySelector("[data-accordion='accordion-trigger']");
7        const content = item.querySelector("[data-accordion='accordion-content']");
8
9        if (!trigger || !content) return;
10
11        let tId = trigger.id;
12        let cId = content.id;
13
14        // If IDs already exist and are unique, keep them
15        const triggerExists = tId && usedIds.has(tId);
16        const contentExists = cId && usedIds.has(cId);
17
18        // Generate new IDs only if missing or duplicate
19        if (!tId || triggerExists) {
20            tId = `trigger-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 5)}`;
21            trigger.id = tId;
22        }
23
24        if (!cId || contentExists) {
25            cId = `content-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 5)}`;
26            content.id = cId;
27        }
28
29        trigger.setAttribute('aria-controls', cId);
30        content.setAttribute('aria-labelledby', tId);
31
32        usedIds.add(tId);
33        usedIds.add(cId);
34    });
35};
36
37const accordionToggler = () => {
38    document.querySelectorAll("[data-accordion='accordion-trigger']").forEach((trigger) => {
39        trigger.addEventListener("click", () => {
40            handleToggle(trigger);
41        });
42    });
43
44    const handleToggle = (trigger) => {
45        const headingEl = trigger.parentElement;
46        const isOpen = headingEl.dataset.isOpen === 'true';
47        if (isOpen) {
48            closeAccordion(trigger);
49        } else {
50            openAccordion(trigger);
51        }
52    }
53
54    const openAccordion = (trigger) => {
55        const headingEl = trigger.parentElement;
56        const contentId = trigger.getAttribute("aria-controls");
57        const content = document.getElementById(contentId);
58
59        if (!content) return;
60
61        headingEl.dataset.isOpen = "true";
62        trigger.setAttribute("aria-expanded", "true");
63        content.removeAttribute("hidden");
64        content.style.maxHeight = content.scrollHeight + "px";
65    };
66
67    const closeAccordion = (trigger) => {
68        const headingEl = trigger.parentElement;
69        const contentId = trigger.getAttribute("aria-controls");
70        const content = document.getElementById(contentId);
71        if (!content) return;
72
73        headingEl.dataset.isOpen = "false";
74        trigger.setAttribute("aria-expanded", "false");
75        content.style.maxHeight = "0px";
76
77        const handleTransitionEnd = (e) => {
78            if (e.propertyName === 'max-height') {
79                content.setAttribute('hidden', '');
80                content.removeEventListener('transitionend', handleTransitionEnd);
81            }
82        };
83        content.addEventListener('transitionend', handleTransitionEnd);
84    };
85};
86
87document.addEventListener("DOMContentLoaded", () => {
88    fixDuplicateAccordionIds();
89    accordionToggler();
90});

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.