PageSourceSearch

https://www.kunsthauswien.com/assets/js/utilities/collapseTextHandler.js

js kunsthauswien.com collected 2026-10-02 07:35:45 UTC 3,029 bytes, 84 lines download raw bytes

1
2if (!crypto.randomUUID) {
3    crypto.randomUUID = function () {
4        return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
5            (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
6        );
7    };
8}
9
10export class TextCollapsible {
11    constructor(element) {
12        this.element = element;
13        this.section = element.closest('.section-body-text-narrow');
14        this.button = this.section.querySelector('.text-collapsible__button')
15        this.isCollapsed = element.classList.contains('collapsed');
16
17        // Setup accessibility
18        this.id = element.id || crypto.randomUUID();
19        element.id = this.id;
20
21        this.button.setAttribute('role', 'button');
22        this.button.setAttribute('tabindex', '0');
23        this.button.setAttribute('aria-controls', this.id + '-content');
24        this.element.id = this.id + '-content';
25        this.element.setAttribute('aria-hidden', this.isOpen ? 'false' : 'true');
26        this.button.setAttribute('aria-expanded', this.isOpen ? 'true' : 'false');
27
28        // Set initial styles
29        this.element.style.height = this.isCollapsed ? '500px' : `${this.content.scrollHeight}px`;
30
31        // Bind events
32        this.button.addEventListener('click', () => this.toggle());
33    }
34
35    toggle() {
36        this.isCollapsed ? this.expand() : this.collapse();
37    }
38
39    expand() {
40        if (!this.element) return;
41
42        const fullHeight = this.element.scrollHeight + 'px';
43        this.element.style.height = fullHeight;
44        this.element.classList.remove('collapsed');
45        this.button.innerText = this.button.dataset.expanded;
46
47        this.element.setAttribute('aria-hidden', 'false');
48        this.button.setAttribute('aria-expanded', 'true');
49        this.isCollapsed = false;
50
51        // Reset height after transition to allow dynamic content
52        const transitionDuration = parseFloat(
53            getComputedStyle(document.documentElement).getPropertyValue('--dropdown-transition-duration')
54        ) || 0.3;
55        setTimeout(() => {
56            if (!this.isCollapsed) this.element.style.height = 'auto';
57        }, transitionDuration * 1000);
58    }
59
60    collapse() {
61        if (!this.element) return;
62
63        const currentHeight = this.element.scrollHeight + 'px';
64        this.element.style.height = currentHeight;
65
66        this.button.innerText = this.button.dataset.collapsed;
67
68        // Force reflow to trigger transition
69        void this.element.offsetHeight;
70
71        this.element.style.height = '500px';
72        this.element.classList.add('collapsed');
73        this.element.setAttribute('aria-hidden', 'true');
74        this.button.setAttribute('aria-expanded', 'false');
75        this.isCollapsed = true;
76    }
77}
78
79export function initCollapseText() {
80    if (!document.querySelectorAll('.text-collapsible').length) return;
81
82    const collapsibles = Array.from(document.querySelectorAll('.text-collapsible'));
83    collapsibles.forEach((collapsible) => new TextCollapsible(collapsible));
84}

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.