PageSourceSearch

https://transiti.net/wp-content/plugins/dynamic-content-for-elemen…/js/dynamic-posts-skin-grid.js?ver=3.4.16

js transiti.net collected 2026-10-06 05:26:05 UTC 12,623 bytes, 431 lines download raw bytes

1(function ($) {
2	// For Elementor >= 3.16:
3	const handleInfiniteScrollInsideTab = ($tabpanel, $grid) => {
4		var observer = new MutationObserver(function (_, observer) {
5			$grid.isotope("layout");
6			// only needed the first time the tab is activated:
7			observer.disconnect();
8		});
9		var observerConfig = {
10			attributes: true,
11			attributeFilter: ["class"],
12		};
13		// observe only needed if tab not active on loading:
14		if (!$tabpanel.hasClass("e-active")) {
15			observer.observe($tabpanel[0], observerConfig);
16		}
17	};
18
19	// For Elementor < 3.16:
20	const handleInfiniteScrollInsideTabLegacy = ($tablist, $grid) => {
21		var observer = new MutationObserver(function (_, observer) {
22			$grid.isotope("layout");
23			// only needed the first time the tab is activated:
24			observer.disconnect();
25		});
26		var observerConfig = {
27			attributes: true,
28			attributeFilter: ["class"],
29		};
30		// find our tab:
31		let $tab = $tablist.children().has($grid);
32		// observe only needed if tab not active on loading:
33		if (!$tab.hasClass("e-active")) {
34			observer.observe($tab[0], observerConfig);
35		}
36	};
37
38	window.dceDynamicPostsGrid = function ($scope, $) {
39		var elementSettings = dceGetElementSettings($scope);
40		var id_scope = $scope.attr("data-id");
41		var grid = $scope.find(
42			".dce-posts-container.dce-skin-grid .dce-posts-wrapper",
43		);
44		var masonryGrid = null;
45		var isMasonryEnabled = false;
46		// "Match Height by Row" is a switcher whose return_value is the string
47		// "true" and is absent when off. Coerce to a real boolean so "off"
48		// equalises every card across the whole grid instead of falling back to
49		// matchHeight's byRow:true default (which made the off state a no-op).
50		let byRow =
51			elementSettings.grid_match_height_by_row === "true" ||
52			elementSettings.grid_filters_match_height_by_row === "true";
53
54		const getMatchHeightElementsWithContainers = () => {
55			let $nestedContainers = $scope.find(".e-con .e-con");
56			let $articles = $scope.find(".dce-post-block");
57			let articleContainers = $articles.get().map((article) => {
58				return jQuery(article).find(".e-con").not($nestedContainers);
59			});
60			let matchHeightEls = [];
61			if (articleContainers.length) {
62				articleContainers[0].each((i) => {
63					let $els = $articles.map((index) => articleContainers[index][i]);
64					matchHeightEls.push($els);
65				});
66			}
67			return matchHeightEls;
68		};
69
70		const findMatchHeightSlices = () => {
71			let matchHeightEls;
72			if (elementSettings.style_items === "template") {
73				if ($scope.find(".dce-post-block .elementor-inner-section").length) {
74					matchHeightEls = [];
75					let $articles = $scope.find(".dce-post-block");
76					let articleSections = $articles.get().map((article) => {
77						return jQuery(article).find(".elementor-inner-section");
78					});
79					articleSections[0].each((i) => {
80						let $els = $articles.map((index) => articleSections[index][i]);
81						matchHeightEls.push($els);
82					});
83				} else {
84					let $topSections = $scope.find(".dce-post-block .elementor-top-section");
85					matchHeightEls = $topSections.length
86						? [$topSections]
87						: getMatchHeightElementsWithContainers();
88				}
89			} else {
90				matchHeightEls = [$scope.find(".dce-post-block")];
91			}
92			return matchHeightEls;
93		};
94
95		const findAndMatchHeight = () => {
96			slices = findMatchHeightSlices();
97			for (const $els of slices) {
98				$els.matchHeight({ byRow: byRow });
99			}
100		};
101
102		// MASONRY
103		function activeMasonry() {
104			masonryGrid = grid.masonry({
105				itemSelector: ".dce-post-item",
106				masonry: {
107					horizontalOrder: true,
108				},
109			});
110			isMasonryEnabled = true;
111		}
112		function layoutMasonry() {
113			if (
114				elementSettings[dceDynamicPostsSkinPrefix + "grid_type"] !=
115				"masonry"
116			) {
117				masonryGrid.masonry("destroy");
118				isMasonryEnabled = false;
119			} else {
120				masonryGrid.masonry();
121			}
122		}
123
124		// For the grid-filters skin, Match Height is handled by its own handler
125		// (dynamic-posts-skin-grid-filters.js) so initial load and filter
126		// changes stay consistent. Avoid double-applying it here.
127		if (
128			dceDynamicPostsSkin !== "grid_filters" &&
129			(elementSettings.grid_match_height ||
130				elementSettings.grid_filters_match_height)
131		) {
132			findAndMatchHeight();
133		}
134
135		// Skip plain masonry for grid-filters skin — Isotope handles it there
136		if (
137			dceDynamicPostsSkin !== "grid_filters" &&
138			elementSettings[dceDynamicPostsSkinPrefix + "grid_type"] ==
139				"masonry"
140		) {
141			activeMasonry();
142			masonryGrid.imagesLoaded().progress(function () {
143				layoutMasonry();
144			});
145		}
146
147		// When Search&Filter request is completed
148		$(document).on("sf:ajaxfinish", ".searchandfilter", function (e, data) {
149			// Add inline CSS for background url
150			var allArticles = document.querySelectorAll(
151				".dce-dynamic-posts-collection .elementor-section, .dce-dynamic-posts-collection .elementor-column, .dce-dynamic-posts-collection .elementor-widget, .dce-dynamic-posts-collection .e-container, .dce-dynamic-posts-collection .e-con",
152			);
153			allArticles.forEach(function (article) {
154				dce.applyDynamicStyles(article);
155			});
156		});
157
158		// InfiniteScroll
159		if (
160			!elementorFrontend.isEditMode() &&
161			elementSettings.infiniteScroll_enable
162		) {
163			var elementorElement = ".elementor-element-" + id_scope;
164			var is_history = Boolean(
165				elementSettings.infiniteScroll_enable_history,
166			)
167				? "replace"
168				: false;
169			var $gridContainer = $scope.find(
170				".dce-posts-container.dce-skin-grid .dce-posts-wrapper.dce-wrapper-grid",
171			);
172			var $layoutMode =
173				elementSettings[dceDynamicPostsSkinPrefix + "grid_type"];
174			var $grid = $gridContainer.isotope({
175				itemSelector: ".dce-post-item",
176				layoutMode: "masonry" === $layoutMode ? "masonry" : "fitRows",
177				sortBy: "original-order",
178				percentPosition: true,
179				masonry: {
180					columnWidth: ".dce-post-item",
181				},
182			});
183			$grid.imagesLoaded().progress(function () {
184				$grid.isotope("layout");
185			});
186
187			let $tabpanel = $grid.closest('[role="tabpanel"]');
188			if ($tabpanel.length) {
189				handleInfiniteScrollInsideTab($tabpanel, $grid);
190			} else {
191				// For Elementor < 3.16
192				let $tablist = $grid.closest('[role="tablist"]');
193				if ($tablist.length) {
194					handleInfiniteScrollInsideTabLegacy($tablist, $grid);
195				}
196			}
197
198			// Apply link to template when layout is complete
199			if (
200				false === elementorFrontend.isEditMode() &&
201				"yes" === elementSettings.templatemode_linkable
202			) {
203				$gridContainer.on(
204					"append.infiniteScroll",
205					function (event, title, path) {
206						$scope
207							.find(".dce-post.dce-post-item[data-post-link]")
208							.click(function () {
209								window.location.assign(
210									$(this).attr("data-post-link"),
211								);
212								return false;
213							});
214					},
215				);
216			}
217
218			// Match Height when layout is complete
219			if (
220				elementSettings.grid_match_height ||
221				elementSettings.grid_filters_match_height
222			) {
223				$gridContainer.on(
224					"append.infiniteScroll",
225					function (event, title, path) {
226						findAndMatchHeight();
227						$gridContainer.isotope("layout");
228					},
229				);
230			}
231
232			// Reload the template after using Infinite Scroll
233			if ("template" === elementSettings.style_items) {
234				$gridContainer.on(
235					"append.infiniteScroll",
236					function (event, title, path) {
237						if (elementorFrontend) {
238							if (
239								elementorFrontend.elementsHandler
240									.runReadyTrigger
241							) {
242								var widgets = $(
243									".dce-dynamic-posts-collection",
244								).find(".elementor-widget");
245								widgets.each(function (i) {
246									elementorFrontend.elementsHandler.runReadyTrigger(
247										jQuery(this),
248									);
249									elementorFrontend.hooks.doAction(
250										"frontend/element_ready/global",
251										jQuery(this),
252										jQuery,
253									);
254								});
255							}
256						}
257
258						// Add inline CSS for background
259						var allArticles = document.querySelectorAll(
260							".dce-dynamic-posts-collection .elementor-section, .dce-dynamic-posts-collection .elementor-column, .dce-dynamic-posts-collection .elementor-widget, .dce-dynamic-posts-collection .e-container, .dce-dynamic-posts-collection .e-con",
261						);
262						allArticles.forEach(function (article) {
263							dce.applyDynamicStyles(article);
264						});
265					},
266				);
267
268				// When Search&Filter request is completed
269				$(document).on(
270					"sf:ajaxfinish",
271					".searchandfilter",
272					function (e, data) {
273						if (elementorFrontend) {
274							if (
275								elementSettings.grid_match_height ||
276								elementSettings.grid_filters_match_height
277							) {
278								findAndMatchHeight();
279							}
280							// Template Linkable
281							$scope
282								.find(".dce-post.dce-post-item[data-post-link]")
283								.click(function () {
284									window.location.assign(
285										$(this).attr("data-post-link"),
286									);
287									return false;
288								});
289						}
290					},
291				);
292			}
293
294			var iso = $grid.data("isotope");
295
296			if (jQuery(elementorElement + " .pagination__next").length) {
297				var infiniteScroll_options = {
298					path: elementorElement + " .pagination__next",
299					history: is_history,
300					append: elementorElement + " .dce-post.dce-post-item",
301					outlayer: iso,
302					status: elementorElement + " .page-load-status",
303					hideNav: elementorElement + ".pagination",
304					scrollThreshold:
305						"scroll" === elementSettings.infiniteScroll_trigger
306							? true
307							: false,
308					loadOnScroll:
309						"scroll" === elementSettings.infiniteScroll_trigger
310							? true
311							: false,
312					onInit: function () {
313						this.on("load", function () {});
314					},
315				};
316				if (elementSettings.infiniteScroll_trigger == "button") {
317					// load pages on button click
318					infiniteScroll_options["button"] =
319						elementorElement + " .view-more-button";
320				}
321				infScroll = $gridContainer.infiniteScroll(
322					infiniteScroll_options,
323				);
324
325				// fix for infinitescroll + masonry
326				var nElements = jQuery(
327					elementorElement + " .dce-post-item:visible",
328				).length; // initial length
329
330				$gridContainer.on(
331					"append.infiniteScroll",
332					function (event, response, path, items) {
333						setTimeout(function () {
334							var nElementsVisible = jQuery(
335								elementorElement + " .dce-post-item:visible",
336							).length;
337							if (nElementsVisible <= nElements) {
338								// force another load
339								$gridContainer.infiniteScroll("loadNextPage");
340							}
341						}, 1000);
342					},
343				);
344			}
345		}
346
347		// Scroll Reveal
348		var on_scrollReveal = function () {
349			var runRevAnim = function (entries, observer) {
350				entries.forEach(function (entry) {
351					var el = $(entry.target);
352					if (entry.isIntersecting) {
353						el.addClass("animate");
354						observer.unobserve(entry.target);
355					} else {
356						el.removeClass("animate");
357					}
358				});
359			};
360
361			var observerOptions = {
362				root: null,
363				rootMargin: "0px",
364				threshold: 0.1,
365			};
366
367			var observer = new IntersectionObserver(
368				runRevAnim,
369				observerOptions,
370			);
371			var elements = $scope.find(".dce-post-item");
372
373			elements.each(function () {
374				observer.observe(this);
375			});
376		};
377
378		on_scrollReveal();
379
380		// Callback function executed when mutations occur
381		var handleClassAttributeChange = function (mutationsList, observer) {
382			for (var mutation of mutationsList) {
383				if (
384					mutation.type === "attributes" &&
385					mutation.attributeName === "class" &&
386					isMasonryEnabled
387				) {
388					layoutMasonry();
389				}
390			}
391		};
392		dceObserveElement($scope[0], handleClassAttributeChange);
393	};
394
395	jQuery(window).on("elementor/frontend/init", function () {
396		const widgets = [
397			"dce-dynamicposts-v2.grid",
398			"dce-dynamicposts-v2.grid-filters",
399			"dce-woo-products-cart.grid",
400			"dce-woo-products-cart.grid-filters",
401			"dce-woo-products-cart-on-sale.grid",
402			"dce-woo-products-cart-on-sale.grid-filters",
403			"dce-woo-product-upsells.grid",
404			"dce-woo-product-upsells.grid-filters",
405			"dce-woo-product-crosssells.grid",
406			"dce-woo-product-crosssells.grid-filters",
407			"dce-dynamic-woo-products.grid",
408			"dce-dynamic-woo-products.grid-filters",
409			"dce-dynamic-show-favorites.grid",
410			"dce-dynamic-show-favorites.grid-filters",
411			"dce-dynamic-archives.grid",
412			"dce-my-posts.grid",
413			"dce-my-posts.grid-filters",
414			"dce-sticky-posts.grid",
415			"dce-sticky-posts.grid-filters",
416			"dce-search-results.grid",
417			"dce-search-results.grid-filters",
418			"dce-metabox-relationship.grid",
419			"dce-metabox-relationship.grid-filters",
420			"dce-acf-relationship.grid",
421			"dce-acf-relationship.grid-filters",
422		];
423
424		widgets.forEach(function (widget) {
425			elementorFrontend.hooks.addAction(
426				"frontend/element_ready/" + widget,
427				dceDynamicPostsGrid,
428			);
429		});
430	});
431})(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.