PageSourceSearch

https://mindhelper.dk/wp-content/themes/mindhelper-2025/blocks/blocks/card-grid/script.js?ver=1790945744

js mindhelper.dk collected 2026-10-06 00:29:19 UTC 5,016 bytes, 158 lines download raw bytes

1/* global Swiper */
2/**
3 * Card Grid – Swiper initialisation
4 *
5 * Frontend works already. This update ensures the editor (iframe) also loads
6 * Swiper CSS/JS inside the iframe and initialises the carousels there, which
7 * prevents huge slide heights and accidental link wrapping in the editor.
8 */
9(() => {
10	const SWIPER_CDN = 'https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js';
11	const SWIPER_CSS_CDN = 'https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css';
12
13	/**
14	 * Ensure Swiper CSS is loaded into a specific document (defaults to window.document).
15	 * @param {Document} targetDoc
16	 */
17	const ensureSwiperCSS = (targetDoc = document) => {
18		if (!targetDoc.querySelector(`link[href="${SWIPER_CSS_CDN}"]`)) {
19			const link = targetDoc.createElement('link');
20			link.rel = 'stylesheet';
21			link.href = SWIPER_CSS_CDN;
22			(targetDoc.head || targetDoc.documentElement).appendChild(link);
23		}
24	};
25
26	/**
27	 * Dynamically load Swiper in a specific document context (frontend or editor iframe).
28	 * Resolves when Swiper is available on that document's defaultView.
29	 * @param {Document} targetDoc
30	 */
31	const loadSwiperInDocument = (targetDoc = document) =>
32		new Promise((resolve, reject) => {
33			const win = targetDoc.defaultView || window;
34			if (win.Swiper) {
35				resolve();
36				return;
37			}
38
39			const script = targetDoc.createElement('script');
40			script.src = SWIPER_CDN;
41			script.async = true;
42			script.onload = () => resolve();
43			script.onerror = () => reject(new Error('Failed to load Swiper library'));
44			(targetDoc.head || targetDoc.documentElement).appendChild(script);
45		});
46
47	/**
48	 * Initialise all card-grid swipers within a provided document.
49	 * @param {Document} rootDoc
50	 */
51	const initCardGridInDocument = (rootDoc = document) => {
52		const win = rootDoc.defaultView || window;
53		const swipers = rootDoc.querySelectorAll('.card-grid-swiper');
54
55		swipers.forEach((el) => {
56			// Avoid double init
57			if (el.swiper) return;
58
59			const swiperContainer = el; // .card-grid-swiper
60			const parentContainer = swiperContainer.closest('.card-grid');
61			if (!parentContainer) return;
62
63			const nextButton = parentContainer.querySelector('.card-grid__nav--next');
64			const prevButton = parentContainer.querySelector('.card-grid__nav--prev');
65			const pagination = parentContainer.querySelector('.card-grid-pagination');
66
67			// eslint-disable-next-line no-undef
68			new win.Swiper(el, {
69				slidesPerView: 1,
70				spaceBetween: 28,
71				loop: false,
72				breakpoints: {
73					// Below 769px: 1 slide per view
74					480: {
75						slidesPerView: 2,
76						spaceBetween: 28,
77					},
78					// 1280px and above: 3 slides per view
79					1280: {
80						slidesPerView: 3,
81						spaceBetween: 28,
82					},
83				},
84				navigation: {
85					nextEl: nextButton,
86					prevEl: prevButton,
87				},
88				pagination: {
89					el: pagination,
90					clickable: false,
91					bulletClass: 'swiper-pagination-bullet',
92					bulletActiveClass: 'swiper-pagination-bullet-active',
93				},
94			});
95		});
96	};
97
98	/**
99	 * Try to get the block editor iframe document (WP 6.x names/classes).
100	 * @returns {Document|null}
101	 */
102	const getEditorIframeDocument = () => {
103		const iframe = document.querySelector('.block-editor-iframe__iframe') || document.querySelector('iframe[name="editor-canvas"]');
104		if (iframe && iframe.contentDocument) return iframe.contentDocument;
105		return null;
106	};
107
108	/**
109	 * Boot in a given document: ensure CSS/JS, then init.
110	 * @param {Document} doc
111	 */
112	const bootForDocument = (doc) => {
113		ensureSwiperCSS(doc);
114		return loadSwiperInDocument(doc)
115			.then(() => {
116				initCardGridInDocument(doc);
117			})
118			.catch(() => {});
119	};
120
121	// Frontend (Swiper + CSS enqueued via WordPress)
122	initCardGridInDocument(document);
123
124	// Editor: run immediately if iframe is ready; also attach listeners for when it (re)loads
125	const maybeBootEditor = () => {
126		const editorDoc = getEditorIframeDocument();
127		if (editorDoc) {
128			bootForDocument(editorDoc);
129		}
130	};
131
132	// Try now and after DOM ready
133	if (document.readyState === 'complete' || document.readyState === 'interactive') {
134		maybeBootEditor();
135	} else {
136		document.addEventListener('DOMContentLoaded', maybeBootEditor, { once: true });
137	}
138
139	// When the iframe reloads due to template/style changes
140	const observeEditorIframe = () => {
141		const iframe = document.querySelector('.block-editor-iframe__iframe') || document.querySelector('iframe[name="editor-canvas"]');
142		if (!iframe) return;
143		iframe.addEventListener('load', () => {
144			const doc = iframe.contentDocument;
145			if (doc) bootForDocument(doc);
146		});
147	};
148	observeEditorIframe();
149
150	// Fallback: when blocks render/update in editor
151	if (window.wp && window.wp.hooks) {
152		window.wp.hooks.addAction('dom_ready', 'mh/card-grid-swiper', () => {
153			// Frontend fallback (Swiper loaded by WP)
154			initCardGridInDocument(document);
155			maybeBootEditor();
156		});
157	}
158})();

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.