1/** 2 * FAQs Block Frontend JavaScript 3 * Matches theme accordion structure exactly. 4 * 5 * Click handling is delegated from the `.accordions` container during the 6 * capture phase and propagation is stopped there, so the theme's own 7 * accordion script cannot also toggle the same item (two independent 8 * `classList.toggle('active')` calls cancel each other out and the 9 * accordion appears dead). 10 */ 11 12(function() { 13 'use strict'; 14 15 var INIT_FLAG = 'ssFaqsInit'; 16 17 function setOpen(accordion, isOpen) { 18 accordion.classList.toggle('active', isOpen); 19 20 var question = accordion.querySelector('.question'); 21 if (question) { 22 question.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); 23 } 24 } 25 26 function toggleAccordion(container, accordion) { 27 var willOpen = !accordion.classList.contains('active'); 28 29 // Close every sibling, then apply the new state to the clicked item. 30 container.querySelectorAll('.accordion').forEach(function(accord) { 31 if (accord !== accordion) { 32 setOpen(accord, false); 33 } 34 }); 35 36 setOpen(accordion, willOpen); 37 } 38 39 function handleContainerEvent(event) { 40 var container = event.currentTarget; 41 42 // Ignore clicks on links/buttons inside an open answer. 43 var question = event.target.closest ? event.target.closest('.question') : null; 44 if (!question || !container.contains(question)) { 45 return; 46 } 47 48 var accordion = question.closest('.accordion'); 49 if (!accordion || !container.contains(accordion)) { 50 return; 51 } 52 53 if (event.type === 'keydown') { 54 if (event.key !== 'Enter' && event.key !== ' ' && event.key !== 'Spacebar') { 55 return; 56 } 57 } 58 59 // Claim this event so no other handler double-toggles the item. 60 event.preventDefault(); 61 event.stopPropagation(); 62 63 toggleAccordion(container, accordion); 64 } 65 66 function initAccordions() { 67 document.querySelectorAll('.wp-block-shipstation-faqs .accordions').forEach(function(container) { 68 if (container.dataset[INIT_FLAG]) { 69 return; 70 } 71 container.dataset[INIT_FLAG] = '1'; 72 73 // Capture phase: runs before any listener bound on the question itself. 74 container.addEventListener('click', handleContainerEvent, true); 75 container.addEventListener('keydown', handleContainerEvent, true); 76 77 // Sync aria-expanded with the rendered markup. 78 container.querySelectorAll('.accordion').forEach(function(accord) { 79 setOpen(accord, accord.classList.contains('active')); 80 }); 81 }); 82 } 83 84 // Initialize when DOM is ready 85 if (document.readyState === 'loading') { 86 document.addEventListener('DOMContentLoaded', initAccordions); 87 } else { 88 initAccordions(); 89 } 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.