PageSourceSearch

https://www.zoerr.de/wp-content/themes/zoerr/v4core/blocks/Accordi…ude_v4core.accordion.functions.js?ver=1.0.3

js zoerr.de collected 2026-10-04 05:56:54 UTC 5,962 bytes, 144 lines download raw bytes

1(function($) {
2    /**
3     * v4Accordion
4     * Supports accessible, multiple, and nested accordions matching the WP block markup.
5     *
6     * @param {object} $inner The inner wrapper jQuery element (.wp-block-visual4-accordion-inner).
7     * @param {object} options Configuration options.
8     */
9    function initializeBlock($inner, options = {}) {
10        if ($inner.hasClass('is-initialized')) return;
11        $inner.addClass('is-initialized');
12
13        // Merge settings
14        const settings = {
15            allowMultipleOpen: false,   // one open per level by default
16            targetClass: '.wp-block-visual4-accordion-inner',
17            openClass: 'is-open-on-load',
18            closedClass: 'is-closed',
19            ...options
20        };
21
22        // Locate title and content within this inner wrapper
23        const $title   = $inner.children('.v4-accordion-title');
24        const $content = $inner.children('.v4-accordion-content');
25
26        // Ensure IDs for ARIA
27        const innerId = $inner.attr('id') || `v4-accordion-${Math.random().toString(36).substr(2,9)}`;
28        $inner.attr('id', innerId);
29        $title.attr({
30            'role': 'button',
31            'tabindex': '0',
32            'aria-expanded': 'false',
33            'aria-controls': `${innerId}-content`
34        });
35        $content.attr({
36            'id': `${innerId}-content`,
37            'role': 'region',
38            'aria-labelledby': $title.attr('id') || innerId
39        });
40
41        // Initial state: open if not closed or flagged open on load
42        const $block = $inner.closest('.v4-accordion');
43        const shouldOpen =
44            $block.hasClass(settings.openClass) ||            // outer block requests open-on-load
45            !$inner.hasClass(settings.closedClass);           // inner missing closed class
46
47        if (shouldOpen) {
48            $title.attr('aria-expanded', 'true');
49            $inner.addClass('is-open').removeClass(settings.closedClass);
50            $content.stop().slideDown(0);
51        } else {
52            $inner.removeClass('is-open').addClass(settings.closedClass);
53            $content.stop().slideUp(0);
54        }
55
56        // Toggle function for this level
57        function toggle($current) {
58            const $curTitle   = $current.children('.v4-accordion-title');
59            const $curContent = $current.children('.v4-accordion-content');
60            const isOpen      = $current.hasClass('is-open');
61
62            // Scope sibling closure to same-level .v4-accordion blocks
63            const $currentBlock = $current.closest('.v4-accordion');
64            const $siblings = settings.allowMultipleOpen
65                ? $() // no auto-close
66                : $currentBlock.siblings('.v4-accordion').children(settings.targetClass);
67
68            if (isOpen) {
69                // Close current
70                $curTitle.attr('aria-expanded', 'false');
71                $curContent.stop().slideUp();
72                $current.removeClass('is-open').addClass(settings.closedClass);
73            } else {
74                // Close siblings first
75                $siblings.each(function() {
76                    const $sib = $(this);
77                    $sib.children('.v4-accordion-title').attr('aria-expanded', 'false');
78                    $sib.children('.v4-accordion-content').stop().slideUp();
79                    $sib.removeClass('is-open').addClass(settings.closedClass);
80                });
81                // Open current
82                $curTitle.attr('aria-expanded', 'true');
83                $curContent.stop().slideDown();
84                $current.addClass('is-open').removeClass(settings.closedClass);
85            }
86        }
87
88        // Click handler (stop propagation so parent doesn't toggle)
89        $title.on('click', function(e) {
90            e.stopPropagation();
91            toggle($inner);
92        });
93
94        // Keyboard navigation: cycle through same-level accordion titles
95        $title.on('keydown', function(e) {
96            const $currentBlock = $inner.closest('.v4-accordion');
97            const $innersAtLevel = $currentBlock.parent().children('.v4-accordion').children(settings.targetClass);
98            const idx = $innersAtLevel.index($inner);
99            let $targetInner;
100
101            switch (e.key) {
102                case 'Enter':
103                case ' ':
104                    e.preventDefault(); e.stopPropagation(); toggle($inner);
105                    break;
106                case 'ArrowDown':
107                    e.preventDefault();
108                    $targetInner = $innersAtLevel.eq((idx + 1) % $innersAtLevel.length);
109                    $targetInner.children('.v4-accordion-title').focus();
110                    break;
111                case 'ArrowUp':
112                    e.preventDefault();
113                    $targetInner = $innersAtLevel.eq(idx - 1 >
113= 0 ? idx - 1 : $innersAtLevel.length - 1);
114                    $targetInner.children('.v4-accordion-title').focus();
115                    break;
116                case 'Home':
117                    e.preventDefault(); $innersAtLevel.first().children('.v4-accordion-title').focus();
118                    break;
119                case 'End':
120                    e.preventDefault(); $innersAtLevel.last().children('.v4-accordion-title').focus();
121                    break;
122            }
123        });
124
125        // Recursively init nested accordions inside this content
126        $content.find(settings.targetClass).each(function() {
127            initializeBlock($(this), settings);
128        });
129    }
130
131    // Global initializer
132    window.v4InitAccordions = function(options = {}) {
133        const defaults = { allowMultipleOpen: false, targetClass: '.wp-block-visual4-accordion-inner' };
134        const cfg = { ...defaults, ...options };
135        $(cfg.targetClass).each(function() {
136            initializeBlock($(this), cfg);
137        });
138    };
139
140    // Run on DOM ready
141    $(document).ready(function() {
142        window.v4InitAccordions();
143    });
144})(jQuery);

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.