PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / accordion / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/accordion/frontend.js

132 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 function toArray(nl) {
3 return Array.prototype.slice.call(nl || []);
4 }
5
6 function initAccordion(wrap) {
7 var allowMultiple = wrap.getAttribute('data-allow-multiple') === '1';
8 var schemaEnabled = wrap.getAttribute('data-schema') === '1';
9 var headers = toArray(wrap.querySelectorAll('.bkbg-ac-header'));
10 var items = toArray(wrap.querySelectorAll('.bkbg-ac-item'));
11
12 // Generate unique IDs if not present
13 var blockId = 'bkbg-ac-' + Math.random().toString(36).substr(2, 9);
14 headers.forEach(function (header, index) {
15 if (!header.id) {
16 header.id = blockId + '-h-' + index;
17 }
18 var contentId = header.getAttribute('aria-controls');
19 if (!contentId) {
20 contentId = blockId + '-c-' + index;
21 header.setAttribute('aria-controls', contentId);
22 var content = header.nextElementSibling;
23 if (content && content.classList.contains('bkbg-ac-content')) {
24 content.id = contentId;
25 content.setAttribute('aria-labelledby', header.id);
26 }
27 }
28 });
29
30 headers.forEach(function (header) {
31 header.addEventListener('click', function () {
32 var expanded = header.getAttribute('aria-expanded') === 'true';
33 var contentId = header.getAttribute('aria-controls');
34 var content = document.getElementById(contentId);
35 var item = header.closest('.bkbg-ac-item');
36
37 if (!allowMultiple && !expanded) {
38 // Close other panels
39 headers.forEach(function (otherHeader) {
40 if (otherHeader !== header && otherHeader.getAttribute('aria-expanded') === 'true') {
41 var otherId = otherHeader.getAttribute('aria-controls');
42 var otherContent = document.getElementById(otherId);
43 var otherItem = otherHeader.closest('.bkbg-ac-item');
44 otherHeader.setAttribute('aria-expanded', 'false');
45 if (otherContent) {
46 otherContent.setAttribute('aria-hidden', 'true');
47 }
48 if (otherItem) {
49 otherItem.classList.remove('is-active');
50 }
51 }
52 });
53 }
54
55 // Toggle current panel
56 var newState = !expanded;
57 header.setAttribute('aria-expanded', newState ? 'true' : 'false');
58 if (content) {
59 content.setAttribute('aria-hidden', newState ? 'false' : 'true');
60 }
61 if (item) {
62 item.classList.toggle('is-active', newState);
63 }
64 });
65
66 // Keyboard navigation
67 header.addEventListener('keydown', function (e) {
68 var index = headers.indexOf(header);
69 var nextIndex = -1;
70
71 switch (e.key) {
72 case 'ArrowDown':
73 nextIndex = (index + 1) % headers.length;
74 e.preventDefault();
75 break;
76 case 'ArrowUp':
77 nextIndex = (index - 1 + headers.length) % headers.length;
78 e.preventDefault();
79 break;
80 case 'Home':
81 nextIndex = 0;
82 e.preventDefault();
83 break;
84 case 'End':
85 nextIndex = headers.length - 1;
86 e.preventDefault();
87 break;
88 }
89
90 if (nextIndex >= 0) {
91 headers[nextIndex].focus();
92 }
93 });
94 });
95
96 // FAQ Schema injection
97 if (schemaEnabled && items.length > 0) {
98 var faqData = {
99 '@context': 'https://schema.org',
100 '@type': 'FAQPage',
101 'mainEntity': []
102 };
103
104 items.forEach(function (item) {
105 var titleEl = item.querySelector('.bkbg-ac-title');
106 var bodyEl = item.querySelector('.bkbg-ac-body');
107 if (titleEl && bodyEl) {
108 faqData.mainEntity.push({
109 '@type': 'Question',
110 'name': titleEl.textContent.trim(),
111 'acceptedAnswer': {
112 '@type': 'Answer',
113 'text': bodyEl.textContent.trim()
114 }
115 });
116 }
117 });
118
119 if (faqData.mainEntity.length > 0) {
120 var script = document.createElement('script');
121 script.type = 'application/ld+json';
122 script.textContent = JSON.stringify(faqData);
123 document.head.appendChild(script);
124 }
125 }
126 }
127
128 document.addEventListener('DOMContentLoaded', function () {
129 toArray(document.querySelectorAll('.bkbg-ac-wrap')).forEach(initAccordion);
130 });
131 })();
132