PageSourceSearch

https://onlineitcourses.co.za/blog/wp-content/plugins/magical-post…/assets/js/theme-builder.js?ver=1.3.0

js onlineitcourses.co.za collected 2026-10-04 20:05:40 UTC 5,523 bytes, 220 lines download raw bytes

1/**
2 * Magical Posts Display - Theme Builder frontend scripts.
3 *
4 * Powers AJAX Load More buttons and Infinite Scroll sentinels rendered by
5 * the Archive Posts and Post Pagination theme widgets. Appends freshly
6 * rendered post items into the `[data-mgpd-archive]` grid on the page.
7 *
8 * @package Magical_Posts_Display
9 */
10(function ($) {
11	'use strict';
12
13	if (typeof mgpdThemeBuilder === 'undefined') {
14		return;
15	}
16
17	var config = mgpdThemeBuilder;
18
19	/**
20	 * Fetch the next page of items for an archive container.
21	 *
22	 * @param {jQuery} $container Archive grid element ([data-mgpd-archive]).
23	 * @param {number} page       Page number to load.
24	 * @param {Function} done     Callback(success, data).
25	 */
26	function fetchPage($container, page, done) {
27		$.ajax({
28			url: config.ajaxurl,
29			type: 'POST',
30			dataType: 'json',
31			data: {
32				action: 'mgpd_theme_load_more',
33				nonce: config.nonce,
34				page: page,
35				query_args: $container.attr('data-query-args') || '{}',
36				widget_settings: $container.attr('data-widget-settings') || '{}'
37			},
38			success: function (response) {
39				if (response && response.success) {
40					done(true, response.data || {});
41				} else {
42					done(false, response);
43				}
44			},
45			error: function () {
46				done(false, null);
47			}
48		});
49	}
50
51	/**
52	 * Append rendered items with a soft entrance animation.
53	 *
54	 * @param {jQuery} $container Archive grid element.
55	 * @param {string} html       Item markup.
56	 */
57	function appendItems($container, html) {
58		var $items = $(html).filter(function () {
59			return this.nodeType === 1;
60		});
61
62		$items.addClass('mgpd-item-enter');
63		$container.append($items);
64
65		// Double rAF so the initial styles are committed before transitioning.
66		window.requestAnimationFrame(function () {
67			window.requestAnimationFrame(function () {
68				$items.removeClass('mgpd-item-enter');
69			});
70		});
71
72		$(document).trigger('mgpd:posts-appended', [$items]);
73	}
74
75	/**
76	 * Reveal the "end of list" message inside a pagination nav.
77	 *
78	 * @param {jQuery} $nav Pagination nav element.
79	 */
80	function showEndMessage($nav) {
81		var $end = $nav.find('.mgpd-end-message');
82		if ($end.length) {
83			$end.removeAttr('hidden');
84		}
85	}
86
87	/**
88	 * Load the next page for a trigger element (button or sentinel).
89	 *
90	 * @param {jQuery} $trigger Element carrying page/max/target data.
91	 */
92	function loadNext($trigger) {
93		if ($trigger.data('mgpdBusy')) {
94			return;
95		}
96
97		var $nav = $trigger.closest('.mgpd-archive-pagination, .mgpd-theme-pagination');
98		var $container = $($trigger.attr('data-target') || '[data-mgpd-archive]').first();
99
100		// Post Pagination widget without an Archive Posts widget on the
101		// page: fall back to a regular page load so links still work.
102		if (!$container.length) {
103			var page = parseInt($trigger.attr('data-page'), 10) + 1;
104			if (page >= 2) {
105				var url = new URL(window.location.href);
106				url.searchParams.set('paged', page);
107				window.location.href = url.toString();
108			}
109			return;
110		}
111
112		var page = parseInt($trigger.attr('data-page'), 10) || 1;
113		var max = parseInt($trigger.attr('data-max'), 10) || 1;
114		var next = page + 1;
115
116		if (next > max) {
117			$trigger.attr('data-exhausted', '1');
118			if ($nav.length) {
119				showEndMessage($nav);
120			}
121			return;
122		}
123
124		$trigger.data('mgpdBusy', true);
125
126		if ($trigger.is('button')) {
127			$trigger.addClass('loading').prop('disabled', true);
128		} else {
129			$nav.find('.mgpd-infinite-loader').addClass('active');
130		}
131
132		fetchPage($container, next, function (success, data) {
133			$trigger.data('mgpdBusy', false);
134
135			if ($trigger.is('button')) {
136				$trigger.removeClass('loading').prop('disabled', false);
137			} else {
138				$nav.find('.mgpd-infinite-loader').removeClass('active');
139			}
140
141			if (!success) {
142				window.console && console.warn('MGPD: load more request failed.', data);
143				return;
144			}
145
146			if (data.html) {
147				appendItems($container, data.html);
148			}
149
150			$trigger.attr('data-page', next);
151
152			var hasMore = typeof data.has_more !== 'undefined'
153				? !!data.has_more
154				: next < max;
155
156			if (!hasMore) {
157				$trigger.attr('data-exhausted', '1');
158				if ($trigger.is('button')) {
159					$trigger[0].hidden = true;
160				}
161				if ($nav.length) {
162					showEndMessage($nav);
163				}
164			}
165		});
166	}
167
168	// Load More buttons (Archive Posts widget + Post Pagination widget).
169	$(document).on('click', '[data-mgpd-loadmore]', function (e) {
170		e.preventDefault();
171		loadNext($(this));
172	});
173
174	// Infinite Scroll sentinels.
175	if ('IntersectionObserver' in window) {
176		var observer = new IntersectionObserver(function (entries) {
177			entries.forEach(function (entry) {
178				if (!entry.isIntersecting) {
179					return;
180				}
181
182				var $trigger = $(entry.target);
183				if ($trigger.attr('data-exhausted')) {
184					observer.unobserve(entry.target);
185					return;
186				}
187
188				loadNext($trigger);
189			});
190		}, {
191			rootMargin: '400px 0px',
192			threshold: 0
193		});
194
195		function observeSentinels() {
196			$('[data-mgpd-infinite]').each(function () {
197				if (!this.dataset.mgpdObserved) {
198					this.dataset.mgpdObserved = '1';
199					observer.observe(this);
200				}
201			});
202		}
203
204		observeSentinels();
205		$(document).on('mgpd:posts-appended', function () {
206			observeSentinels();
207
208			// Stop observing exhausted sentinels.
209			$('[data-mgpd-infinite][data-exhausted]').each(function () {
210				observer.unobserve(this);
211			});
212		});
213	} else {
214		// Legacy fallback: treat infinite scroll as a load more button.
215		$(document).on('click', '[data-mgpd-infinite]', function (e) {
216			e.preventDefault();
217			loadNext($(this));
218		});
219	}
220})(jQuery);

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.