PageSourceSearch

https://handbal.nl/app/mu-plugins/saas-contentblocks//contentblock…/script-saas-preview-block.js?ver=1.4.7

js handbal.nl collected 2026-09-24 20:39:05 UTC 3,606 bytes, 121 lines download raw bytes

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.