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.