1( function() { 2 'use strict'; 3 4 /** 5 * Distribute cards over the carousel pages: append the next (page size - 1) 6 * cards into each slide, wrapping around at the end. 7 * 8 * @param {Element} carousel 9 */ 10 function saas_preview_block_fill_carousel( carousel ) { 11 12 if ( carousel.getAttribute( 'data-carousel-filled' ) ) { 13 return; 14 } 15 carousel.setAttribute( 'data-carousel-filled', '1' ); 16 17 var items = carousel.querySelectorAll( '.carousel-inner > .carousel-item' ); 18 items.forEach( ( el ) => { 19 20 const minPerSlide = carousel.getAttribute( 'data-page-size' ) || 3; 21 let next = el.nextElementSibling; 22 23 for ( var i = 1; i < minPerSlide; i++ ) { 24 25 // Wrap carousel by using first child 26 if ( ! next ) { 27 next = items[0]; 28 } 29 30 let cloneChild = next.cloneNode( true ); 31 el.appendChild( cloneChild.children[ 0 ] ); 32 next = next.nextElementSibling; 33 34 } 35 36 } ); 37 38 } 39 40 /** 41 * Post-process an ajax-populated preview block: activate the first slide, 42 * hide the controls when everything fits on one page and fill the carousel pages. 43 * 44 * @param {Element} $target The block's ajax wrapper element. 45 */ 46 function saas_preview_block_process_response( $target ) { 47 48 var carousel = $target.querySelector( '.post-preview-carousel' ); 49 if ( ! carousel ) { 50 return; 51 } 52 53 var items = carousel.querySelectorAll( '.carousel-inner > .carousel-item' ); 54 if ( ! items.length ) { 55 return; 56 } 57 58 // Activate the first slide 59 if ( ! carousel.querySelector( '.carousel-inner > .carousel-item.active' ) ) { 60 items[0].classList.add( 'active' ); 61 } 62 63 // Hide the controls when all cards fit on one page 64 var page_size = parseInt( carousel.getAttribute( 'data-page-size' ) || 3, 10 ); 65 if ( items.length <= page_size ) { 66 carousel.querySelectorAll( '.carousel-control-prev, .carousel-control-next' ).forEach( ( el ) => { 67 el.classList.add( 'd-none' ); 68 } ); 69 } 70 71 saas_preview_block_fill_carousel( carousel ); 72 73 } 74 75 /** 76 * Bind the response handler to a preview block's ajax wrapper (once). 77 * 78 * @param {Element} $target 79 */ 80 function saas_preview_block_init( $target ) { 81 82 if ( $target.getAttribute( 'data-preview-block-initialized' ) ) { 83 return false; 84 } 85 $target.setAttribute( 'data-preview-block-initialized', '1' ); 86 87 $target.addEventListener( 'saas_ajax_get_template_data--complete', function() { 88 saas_preview_block_process_response( $target ); 89 } ); 90 91 return true; 92 93 } 94 95 // Blocks present on page load. Their data request is fired by the 96 // ajax-template-parts auto-loader ([data-get-template-data][data-get-data-asap]). 97 document.addEventListener( 'DOMContentLoaded', function() { 98 99 document.querySelectorAll( '.saas-preview-block-ajax' ).forEach( saas_preview_block_init ); 100 101 // Legacy server-rendered carousels (non-ajax fallback) 102 document.querySelectorAll( '.post-preview-carousel' ).forEach( ( carousel ) => { 103 if ( ! carousel.closest( '.saas-preview-block-ajax' ) ) { 104 saas_preview_block_fill_carousel( carousel ); 105 } 106 } ); 107 108 } ); 109 110 // Blocks inserted through an ajax template part (e.g. on conditional-content pages) 111 // arrive after DOMContentLoaded and the auto-loader does not rescan, so fire their 112 // data request manually. The initialized flag makes this fire exactly once per block. 113 document.body.addEventListener( 'ajax-template-loaded', function() { 114 document.querySelectorAll( '.saas-preview-block-ajax' ).forEach( ( $target ) => { 115 if ( saas_preview_block_init( $target ) && typeof saas_ajax_get_template_data === 'function' ) { 116 saas_ajax_get_template_data( $target, $target ); 117 } 118 } ); 119 } ); 120 121} )();
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.