1/** 2 * Corporate Pubs Carousel JavaScript 3 * 4 * Handles Splide.js initialization and carousel functionality 5 * 6 * @package Corporate Events Plugin 7 * @since 1.0.0 8 */ 9 10(function () { 11 "use strict"; 12 13 /** 14 * Initialize a single carousel 15 */ 16 function initializeCarousel(carouselElement) { 17 console.log("Initializing corporate pubs carousel:", carouselElement); 18 19 // Check if already initialized 20 if (carouselElement.classList.contains("splide-initialized")) { 21 console.log("Carousel already initialized, skipping"); 22 return; 23 } 24 25 // Get configuration from data attribute 26 let config = {}; 27 try { 28 const configData = carouselElement.getAttribute("data-splide"); 29 if (configData) { 30 config = JSON.parse(configData); 31 console.log("Loaded configuration from data attribute:", config); 32 } 33 } catch (error) { 34 console.warn("Error parsing carousel configuration:", error); 35 } 36 37 // Default configuration (fallback) 38 const defaultConfig = { 39 type: config.enableLoop !== false ? "loop" : "slide", 40 perPage: 3, 41 perMove: 1, 42 pagination: true, 43 arrows: true, 44 autoplay: false, 45 pauseOnHover: true, 46 breakpoints: { 47 768: { perPage: 2 }, 48 480: { perPage: 1 }, 49 }, 50 }; 51 52 // Merge configurations (config from data attribute takes priority) 53 const finalConfig = { ...defaultConfig, ...config }; 54 55 // Calculate responsive padding/peek values if padding is set 56 if (finalConfig.padding && finalConfig.padding !== "0") { 57 const originalPadding = finalConfig.padding; 58 59 // Try to extract numeric value for responsive calculations 60 let paddingValue = 0; 61 if (typeof originalPadding === "string") { 62 paddingValue = parseInt(originalPadding) || 0; 63 } else { 64 paddingValue = originalPadding || 0; 65 } 66 67 // Calculate responsive padding 68 const tabletPadding = 69 paddingValue > 0 ? Math.max(paddingValue * 0.6, 10) + "px" : 0; 70 const mobilePadding = 71 paddingValue > 0 ? Math.max(paddingValue * 0.3, 5) + "px" : 0; 72 73 // Update breakpoints with responsive padding 74 finalConfig.breakpoints = { 75 ...finalConfig.breakpoints, 76 768: { 77 ...finalConfig.breakpoints[768], 78 padding: tabletPadding, 79 }, 80 480: { 81 ...finalConfig.breakpoints[480], 82 padding: mobilePadding, 83 }, 84 }; 85 } 86 87 console.log("Final carousel configuration:", finalConfig); 88 89 // Wait for Splide.js to be available 90 function waitForSplide() { 91 if (typeof window.Splide !== "undefined") { 92 console.log("Splide.js is available, creating carousel instance"); 93 try { 94 // Create and mount the Splide instance 95 const splide = new window.Splide(carouselElement, finalConfig); 96 97 // Add accessibility features 98 splide.on("mounted", function () { 99 // Add ARIA labels to navigation controls 100 const prevButton = carouselElement.querySelector( 101 ".splide__arrow--prev" 102 ); 103 const nextButton = carouselElement.querySelector( 104 ".splide__arrow--next" 105 ); 106 107 if (prevButton) { 108 prevButton.setAttribute("aria-label", "Previous pubs"); 109 } 110 111 if (nextButton) { 112 nextButton.setAttribute("aria-label", "Next pubs"); 113 } 114 115 // Add keyboard support announcement 116 const track = carouselElement.querySelector(".splide__track"); 117 if (track) { 118 track.setAttribute("aria-live", "polite"); 119 track.setAttribute("aria-atomic", "true"); 120 } 121 }); 122 123 // Handle keyboard navigation 124 splide.on("arrows:mounted", function () { 125 const arrows = carouselElement.querySelectorAll(".splide__arrow"); 126 arrows.forEach(function (arrow) { 127 arrow.setAttribute("tabindex", "0"); 128 }); 129 }); 130 131 // Respect reduced motion preferences 132 const prefersReducedMotion = window.matchMedia( 133 "(prefers-reduced-motion: reduce)" 134 ).matches; 135 if (prefersReducedMotion) { 136 finalConfig.speed = Math.max(finalConfig.speed || 400, 400);
137 finalConfig.autoplay = false; 138 } 139 140 splide.mount(); 141 142 // Mark as initialized 143 carouselElement.classList.add("splide-initialized"); 144 console.log("Corporate pubs carousel initialized successfully"); 145 } catch (error) { 146 console.error("Error initializing Splide carousel:", error); 147 } 148 } else { 149 console.log("Splide.js not yet available, retrying..."); 150 setTimeout(waitForSplide, 100); 151 } 152 } 153 154 waitForSplide(); 155 } 156 157 /** 158 * Initialize all corporate pubs carousels on the page 159 */ 160 function initCarousels() { 161 const carousels = document.querySelectorAll( 162 ".corporate-pubs-carousel__splide" 163 ); 164 console.log( 165 `Found ${carousels.length} corporate pubs carousel(s) to initialize` 166 ); 167 168 carousels.forEach(function (carousel, index) { 169 console.log(`Initializing carousel ${index + 1}/${carousels.length}`); 170 initializeCarousel(carousel); 171 }); 172 } 173 174 /** 175 * Initialize when DOM is ready 176 */ 177 if (document.readyState === "loading") { 178 document.addEventListener("DOMContentLoaded", initCarousels); 179 } else {
180 initCarousels(); 181 } 182 183 /** 184 * Reinitialize carousels when new content is loaded (e.g., via AJAX) 185 */ 186 window.corporatePubsInitCarousels = initCarousels; 187 188 // Handle ACF block preview updates 189 if (typeof window.acf !== "undefined") { 190 window.acf.addAction("render_block_preview", function () { 191 setTimeout(function () { 192 const carousels = document.querySelectorAll( 193 ".corporate-pubs-carousel__splide" 194 ); 195 carousels.forEach(function (carousel) { 196 if (!carousel.classList.contains("splide-initialized")) { 197 initializeCarousel(carousel); 198 } 199 }); 200 }, 100); 201 }); 202 } 203 204 // MutationObserver to handle dynamically added content 205 const observer = new MutationObserver(function (mutations) { 206 mutations.forEach(function (mutation) { 207 if (mutation.type === "childList") { 208 mutation.addedNodes.forEach(function (node) { 209 if (node.nodeType === Node.ELEMENT_NODE) { 210 // Check if the added node is a carousel or contains carousels 211 const carousels = node.classList?.contains( 212 "corporate-pubs-carousel__splide" 213 ) 214 ? [node] 215 : node.querySelectorAll?.(".corporate-pubs-carousel__splide") || 216 []; 217 218 if (carousels.length > 0) { 219 console.log( 220 `Found ${carousels.length} new corporate pubs carousel(s), initializing...` 221 ); 222 carousels.forEach(initializeCarousel); 223 } 224 } 225 }); 226 } 227 }); 228 }); 229 230 // Start observing 231 observer.observe(document.body, { 232 childList: true, 233 subtree: true, 234 }); 235 236 console.log("Corporate Pubs Carousel: Initialization complete"); 237})();
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.