__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php

namespace MasterAddons\Inc\Templates\Classes;

use MasterAddons\Inc\Templates;

/**
 * Author Name: Liton Arefin
 * Author URL: https://jeweltheme.com
 * Date: 9/8/19
 */

if (!defined('ABSPATH')) exit; // No access of directly access

if (!class_exists('Master_Addons_Templates_Assets')) {


	class Master_Addons_Templates_Assets
	{


		private static $instance = null;

		public function __construct()
		{

			add_action('elementor/preview/enqueue_styles', array($this, 'enqueue_preview_styles'));

			add_action('elementor/editor/before_enqueue_scripts', array($this, 'editor_scripts'), -1);

			add_action('elementor/editor/after_enqueue_styles', array($this, 'editor_styles'));

			add_action('elementor/editor/footer', array($this, 'load_footer_scripts'));
		}


		public function editor_styles()
		{
			wp_enqueue_style('master-editor-only', JLTMA_URL . '/assets/templates/css/editor.css', [], JLTMA_VER);
		}


		public function enqueue_preview_styles()
		{
			wp_enqueue_style('master-addons-editor-preview', JLTMA_URL . '/assets/templates/css/preview.css', array(), JLTMA_VER, 'all');
		}


		public function editor_scripts()
		{
			wp_enqueue_script('master-addons-editor-js', JLTMA_URL . '/assets/templates/js/editor.js', array('jquery', 'underscore'), JLTMA_VER, true);

			$button = Templates\master_addons_templates()->config->get('master_addons_templates');

			wp_localize_script(
				'master-addons-editor-js',
				'MasterAddonsData',
				apply_filters(
					'master-addons-core/assets/editor/localize',
					array(
						'master_image_dir'      => JLTMA_IMAGE_DIR . 'ma-editor-icon.svg',
						'MasterAddonsEditorBtn' => $button,
						'get_templates_nonce'   => wp_create_nonce('jltma_get_templates_nonce_action'),
						'insert_template_nonce' => wp_create_nonce('jltma_insert_templates_nonce_action'),
						'refresh_cache_nonce'   => wp_create_nonce('master_addons_nonce'),
						'modalRegions'          => $this->get_modal_region(),
						'license'               => array(
							'status'       => Templates\master_addons_templates()->config->get('status'),
							'activateLink' => Templates\master_addons_templates()->config->get('license_page'),
							'proMessage'   => Templates\master_addons_templates()->config->get('pro_message')
						),
					)
				)
			);
		}


		public function get_modal_region()
		{

			return array(
				'modalHeader'  => '.dialog-header',
				'modalContent' => '.dialog-message',
			);
		}


		public function load_footer_scripts()
		{
			

			$scripts = glob(JLTMA_PATH . 'inc/templates/editor/*.php');

			array_map(function ($file) {

				$name = basename($file, '.php');

				ob_start();

				include $file;

				printf('<script type="text/html" id="views-ma-el-%1$s">%2$s</script>', $name, ob_get_clean());
			}, $scripts);
			
			// Add cache refresh functionality for template modal
			$this->add_cache_refresh_script();
		}
		
		
		public function add_cache_refresh_script()
		{
			?>
			<script type="text/javascript">
			jQuery(document).ready(function($) {
				// Global Macy instance
				var macyInstance = null;

				// Wait for Elementor to be available and add cache refresh functionality
				function initCacheRefresh() {
					if (typeof window.elementor === 'undefined') {
						setTimeout(initCacheRefresh, 100);
						return;
					}

					// Initialize Macy.js for template grid
					initMacyLayout();

					// Add tab switching preloader functionality
					initTabPreloader();

					// Add template search functionality
					initTemplateSearch();

					// Initialize filters and keywords
					initFiltersAndKeywords();
					
					// Add banner click tracking
					$(document).on('click', '.ma-el-template-library--banner', function(e) {
						// Track banner click for analytics (optional)
						if (typeof gtag !== 'undefined') {
							gtag('event', 'banner_click', {
								'event_category': 'template_library',
								'event_label': 'template_banner',
								'transport_type': 'beacon'
							});
						}
						
					});
					
					// Add event handler using delegation for dynamically loaded modal content
					$(document).on('click', '#ma-el-template-cache-refresh', function(e) {
						e.preventDefault();
						
						var $button = $(this);
						var $icon = $button.find('i');
						
						// Add updating state
						$button.addClass('updating');
						$icon.removeClass('eicon-sync').addClass('eicon-loading eicon-animation-spin');
						
						// Perform cache refresh
						$.ajax({
							type: 'POST',
							url: ajaxurl,
							data: {
								action: 'jltma_refresh_templates_cache',
								_wpnonce: MasterAddonsData.refresh_cache_nonce
							},
							success: function(response) {
								if (response.success) {
									
									// Update cache count if cache status element exists
									var $cacheStatus = $('#ma-el-template-cache-status');
									if ($cacheStatus.length && response.data.total_templates) {
										var newCount = response.data.total_templates;
										$cacheStatus.find('.cache-count').text(newCount);
										$cacheStatus.attr('title', 'Cache Status: ' + newCount + ' templates cached');
										if (newCount > 0) {
											$cacheStatus.show();
										} else {
											$cacheStatus.hide();
										}
									}
									
									// Reset button state
									$button.removeClass('updating');
									$icon.removeClass('eicon-loading eicon-animation-spin').addClass('eicon-sync');
									
									// Force refresh of current tab content by reloading the modal
									setTimeout(function() {
										// Find the currently active tab to refresh
										var $activeTab = $('#ma-el-template-modal-header-tabs input:checked');
										if ($activeTab.length > 0) {
											// Trigger click on active tab to reload content
											$activeTab.trigger('change');
										} else {
											// Fallback: reload entire modal content if possible
											var $modalContent = $('#ma-el-template-library-content');
											if ($modalContent.length > 0) {
												$modalContent.trigger('refresh');
											}
										}
									}, 500);
									
									// Show success feedback
									$button.attr('title', 'Cache refreshed successfully!');
									setTimeout(function() {
										$button.attr('title', 'Refresh Cache');
									}, 3000);
									
								} else {
									console.error('Failed to refresh template cache:', response.data ? response.data.message : 'Unknown error');
									$button.removeClass('updating');
									$icon.removeClass('eicon-loading eicon-animation-spin').addClass('eicon-sync');
								}
							},
							error: function(xhr, status, error) {
								console.error('AJAX error refreshing template cache:', error);
								$button.removeClass('updating');
								$icon.removeClass('eicon-loading eicon-animation-spin').addClass('eicon-sync');
							}
						});
					});
				}

				// Initialize Macy.js masonry layout for template grid
				function initMacyLayout() {
					var $container = $('#ma-el-modal-templates-container, .ma-el-templates-list');

					if ($container.length === 0) {
						return;
					}

					// Destroy existing instance if any
					if (macyInstance) {
						macyInstance.remove();
						macyInstance = null;
					}

					// Check if Macy is available
					if (typeof Macy === 'undefined') {
						return;
					}

					// Initialize new Macy instance
					macyInstance = Macy({
						container: $container[0],
						trueOrder: false,
						waitForImages: true,
						margin: 20,
						columns: 3,
						breakAt: {
							1200: 3,
							940: 2,
							520: 1
						}
					});

					// Recalculate after images load
					setTimeout(function() {
						if (macyInstance) {
							macyInstance.recalculate(true);
						}
					}, 500);
				}

				// Tab preloader functionality
				function initTabPreloader() {
					// Add preloader for tab switching
					$(document).on('click', '#ma-el-template-modal-header-tabs label', function(e) {
						var $clickedLabel = $(this);
						var $input = $clickedLabel.find('input');
						
						// Don't show loader if this tab is already active
						if ($input.is(':checked')) {
							return;
						}
						
						// Show loading state
						showTabLoader();
						
						// Set a timeout to ensure loader is shown
						setTimeout(function() {
							$input.prop('checked', true).trigger('change');
						}, 50);
					});
					
					// Monitor for tab content loading completion
					$(document).on('DOMSubtreeModified', '#ma-el-template-library-content', function() {
						hideTabLoader();
					});
					
					// Fallback: Hide loader after reasonable time
					var loaderTimeout;
					$(document).on('change', '#ma-el-template-modal-header-tabs input[type="radio"]', function() {
						clearTimeout(loaderTimeout);
						loaderTimeout = setTimeout(function() {
							hideTabLoader();
						}, 3000); // Hide after 3 seconds max
					});
					
					// Modern browsers: Use MutationObserver instead of deprecated DOMSubtreeModified
					if (typeof MutationObserver !== 'undefined') {
						var observer = new MutationObserver(function(mutations) {
							mutations.forEach(function(mutation) {
								if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
									// Check if template content was added
									var hasTemplateContent = false;
									for (var i = 0; i < mutation.addedNodes.length; i++) {
										var node = mutation.addedNodes[i];
										if (node.nodeType === 1) { // Element node
											if ($(node).find('#ma-el-modal-templates-container').length > 0 ||
												$(node).is('#ma-el-modal-templates-container') ||
												$(node).find('.elementor-template-library-template').length > 0) {
												hasTemplateContent = true;
												break;
											}
										}
									}
									if (hasTemplateContent) {
										setTimeout(function() {
											hideTabLoader();
											// Reinitialize or refresh Macy when new content is loaded
											if (macyInstance) {
												macyInstance.recalculate(true);
											} else {
												initMacyLayout();
											}
										}, 200);
									}
								}
							});
						});
						
						// Start observing when modal is present
						$(document).on('DOMNodeInserted', '#ma-el-template-library-content', function() {
							observer.observe(this, {
								childList: true,
								subtree: true
							});
						});
					}
				}
				
				function showTabLoader() {
					var $modalContent = $('#ma-el-template-library-content');
					if ($modalContent.length > 0) {
						// Add loading overlay
						if ($modalContent.find('.ma-el-tab-loading-overlay').length === 0) {
							var loaderHtml = '<div class="ma-el-tab-loading-overlay">' +
								'<div class="elementor-loader-wrapper">' +
									'<div class="elementor-loader">' +
										'<div class="elementor-loader-box"></div>' +
										'<div class="elementor-loader-box"></div>' +
										'<div class="elementor-loader-box"></div>' +
										'<div class="elementor-loader-box"></div>' +
									'</div>' +
									'<div class="elementor-loading-title">Loading Templates...</div>' +
								'</div>' +
							'</div>';
							$modalContent.append(loaderHtml);
						}
						$modalContent.find('.ma-el-tab-loading-overlay').fadeIn(150);
					}
				}
				
				function hideTabLoader() {
					var $loadingOverlay = $('.ma-el-tab-loading-overlay');
					if ($loadingOverlay.length > 0) {
						$loadingOverlay.fadeOut(150, function() {
							$(this).remove();
						});
					}
				}
				
				// Template search functionality
				function initTemplateSearch() {
					var searchTimeout = null;
					
					// Handle search input
					$(document).on('keyup input', '#ma-el-template-search-input', function(e) {
						var $input = $(this);
						var searchTerm = $input.val().toLowerCase().trim();
						
						// Clear previous timeout
						if (searchTimeout) {
							clearTimeout(searchTimeout);
						}
						
						// Debounce search
						searchTimeout = setTimeout(function() {
							performTemplateSearch(searchTerm);
						}, 300);
					});
					
					// Clear search on escape
					$(document).on('keydown', '#ma-el-template-search-input', function(e) {
						if (e.keyCode === 27) { // Escape key
							$(this).val('');
							performTemplateSearch('');
						}
					});
					
				}
				
				function performTemplateSearch(searchTerm) {
					// Look for templates in both possible containers
					var $templates = $('#ma-el-modal-templates-container .elementor-template-library-template, .ma-el-templates-list .elementor-template-library-template');
					var $noResults = $('.ma-el-no-search-results');
					var $container = $('#ma-el-modal-templates-container');
					var $templatesContainer = $('.ma-el-templates-list');
					
					// Use templates list container if it exists, otherwise fall back to modal container
					if ($templatesContainer.length > 0) {
						$container = $templatesContainer;
					}
					
					if (searchTerm === '') {
						// Show all templates and respect any active keyword filter
						var selectedKeyword = $('.ma-el-keyword-filter.active').data('keyword');
						if (selectedKeyword) {
							performKeywordFilter(selectedKeyword);
						} else {
							$templates.show();
							$noResults.remove();
							refreshMasonryLayout();
						}
						return;
					}
					
					var visibleCount = 0;
					var selectedKeyword = $('.ma-el-keyword-filter.active').data('keyword');
					
					$templates.each(function() {
						var $template = $(this);
						var templateName = ($template.find('.elementor-template-library-template-name').text() || '').toLowerCase();
						var templateTitle = ($template.attr('data-title') || '').toLowerCase();
						var templateKeywords = ($template.attr('data-keywords') || '').toLowerCase();
						
						// Check search match
						var searchMatch = templateName.indexOf(searchTerm) !== -1 || 
							templateTitle.indexOf(searchTerm) !== -1 || 
							templateKeywords.indexOf(searchTerm) !== -1;
						
						// Check keyword filter match if one is selected
						var keywordMatch = !selectedKeyword || templateKeywords.indexOf(selectedKeyword.toLowerCase()) !== -1;
						
						// Show template if both search and keyword filter match
						if (searchMatch && keywordMatch) {
							$template.show();
							visibleCount++;
						} else {
							$template.hide();
						}
					});
					
					// Show no results message if needed
					if (visibleCount === 0) {
						if ($noResults.length === 0) {
							var noResultsHtml = '<div class="ma-el-no-search-results">' +
								'<div class="ma-el-no-results-content">' +
									'<i class="eicon-search"></i>' +
									'<h3>No templates found</h3>' +
									'<p>Try searching with different keywords or check other tabs.</p>' +
								'</div>' +
							'</div>';
							$container.append(noResultsHtml);
						}
					} else {
						$noResults.remove();
					}
					
					// Force masonry layout refresh
					refreshMasonryLayout();
				}
				
				function performKeywordFilter(keyword) {
					var $templates = $('#ma-el-modal-templates-container .elementor-template-library-template, .ma-el-templates-list .elementor-template-library-template');
					var $noResults = $('.ma-el-no-filter-results');
					var $container = $('.ma-el-templates-list').length > 0 ? $('.ma-el-templates-list') : $('#ma-el-modal-templates-container');
					var searchTerm = $('#ma-el-template-search-input').val().toLowerCase().trim();
					
					if (!keyword) {
						// Show all templates but respect search term
						if (searchTerm) {
							performTemplateSearch(searchTerm);
						} else {
							$templates.show();
							$noResults.remove();
							refreshMasonryLayout();
						}
						return;
					}
					
					var visibleCount = 0;
					
					$templates.each(function() {
						var $template = $(this);
						var templateKeywords = ($template.attr('data-keywords') || '').toLowerCase();
						var templateName = ($template.find('.elementor-template-library-template-name').text() || '').toLowerCase();
						var templateTitle = ($template.attr('data-title') || '').toLowerCase();
						
						// Check keyword filter match
						var keywordMatch = templateKeywords.indexOf(keyword.toLowerCase()) !== -1;
						
						// Check search match if there's a search term
						var searchMatch = !searchTerm || 
							templateName.indexOf(searchTerm) !== -1 || 
							templateTitle.indexOf(searchTerm) !== -1 || 
							templateKeywords.indexOf(searchTerm) !== -1;
						
						// Show template if both keyword and search match
						if (keywordMatch && searchMatch) {
							$template.show();
							visibleCount++;
						} else {
							$template.hide();
						}
					});
					
					// Show no results message if needed
					if (visibleCount === 0) {
						if ($noResults.length === 0) {
							var noResultsHtml = '<div class="ma-el-no-filter-results">' +
								'<div class="ma-el-no-results-content">' +
									'<i class="eicon-filter"></i>' +
									'<h3>No templates found</h3>' +
									'<p>Try selecting a different filter or clear the search.</p>' +
								'</div>' +
							'</div>';
							$container.append(noResultsHtml);
						}
					} else {
						$noResults.remove();
					}
					
					// Force masonry layout refresh
					refreshMasonryLayout();
				}
				
				// Initialize Macy.js layout
				(function () {
					if (window.__macyLayoutInit) return;
						window.__macyLayoutInit = true;

					
					const log = (...a) => console.log("[MacyFix]", ...a);
					const wait = (ms) => new Promise((r) => setTimeout(r, ms));

					const findContainer = () =>
						document.querySelector("#ma-el-modal-templates-container") ||
						document.querySelector(".ma-el-templates-list") ||
						document.querySelector(".ma-el-templates-grid");

					const getCols = (w) => (w < 480 ? 1 : w < 768 ? 2 : w < 1200 ? 3 : 5);

					async function waitImages(container) {
						if (!container) return;
						const imgs = Array.from(container.querySelectorAll("img"));
						if (!imgs.length) return;
						await Promise.allSettled(
							imgs.map(
								(img) =>
									new Promise((res) => {
										if (img.complete && img.naturalWidth) return res();
										img.addEventListener("load", res, { once: true });
										img.addEventListener("error", res, { once: true });
									})
							)
						);
					}

					let macyInstance = null;

					async function refreshMacy(delay = 150) {
						await wait(delay);
						const container = findContainer();
						if (!container || typeof Macy === "undefined") {
							console.warn("[MacyFix] Container or Macy missing");
							return;
						}

						await waitImages(container);

						if (macyInstance && typeof macyInstance.remove === "function") {
							macyInstance.remove();
							macyInstance = null;
						}

						const width =
							container.closest(".dialog-widget-content")?.offsetWidth ||
							container.offsetWidth;
						const cols = getCols(width);

						macyInstance = Macy({
							container,
							trueOrder: false,
							waitForImages: true,
							margin: 24,
							columns: cols,
						});

						jQuery(container).trigger("macy:refresh");
						log("Macy refreshed successfully.");
					}

					window.__refreshMacyLayout = refreshMacy;

					
					const tabSelector =
						"#views-ma-el-template-modal-tabs-items, " +
						"#ma-el-template-modal-header-tabs, " +
						".elementor-template-library-menu-item, " +
						".MuiTabs-root [role='tab']";

					jQuery(document)
						.off("click.MacyFix change.MacyFix")
						.on("click.MacyFix change.MacyFix", tabSelector, () => refreshMacy(250));

					jQuery(document).off("ajaxComplete.MacyFix").on("ajaxComplete.MacyFix", () => refreshMacy(300));

					let resizeTimer;
					window.addEventListener("resize", () => {
						clearTimeout(resizeTimer);
						resizeTimer = setTimeout(() => refreshMacy(100), 180);
					});

					if (window.MutationObserver) {
						const tabRoot =
							document.querySelector(".MuiTabs-root") ||
							document.querySelector("#views-ma-el-template-modal-tabs-items");
						if (tabRoot) {
							const obs = new MutationObserver(() => refreshMacy(200));
							obs.observe(tabRoot, { attributes: true, subtree: true });
							log("Tab observer active");
						}
					}

					(async () => {
						let tries = 0;
						const iv = setInterval(async () => {
							const container = findContainer();
							if (container || tries > 20) {
								clearInterval(iv);
								if (container) await refreshMacy(100);
								else console.warn("[MacyFix] Container not found after waiting.");
							}
							tries++;
						}, 200);
					})();
				})();

				function refreshMasonryLayout() {
					// Use Macy.js for layout refresh
					if (macyInstance) {
						// Recalculate the layout
						macyInstance.recalculate(true);

						// Also rerun the layout after images potentially load
						setTimeout(function() {
							macyInstance.recalculate(true);
						}, 500);
					} else {
						// Fallback: Try to initialize Macy if not already done
						initMacyLayout();
					}

					// Trigger window resize for compatibility
					setTimeout(function() {
						$(window).trigger('resize');
					}, 50);
				}
				
				function initFiltersAndKeywords() {
					// Wait for both DOM structure and Marionette views to be available
					function setupFiltersAndKeywords() {
						var $filtersList = $('.ma-el-filters-list');
						var $keywordsList = $('.ma-el-keywords-list');
						var $templatesWrap = $('.ma-el-modal-templates-wrap');
						
						if ($filtersList.length === 0 || $keywordsList.length === 0 || $templatesWrap.length === 0) {
							return false; // Not ready yet
						}
						
						// Check if Marionette has already populated these regions
						if ($filtersList.children().length > 0 || $keywordsList.children().length > 0) {
							return true; // Already populated by Marionette
						}
						
						// Only populate if Marionette hasn't done so already
						// Populate filters list (categories/tags)
						if ($filtersList.children().length === 0) {
							var filtersHtml = '<h4>Categories</h4>' +
								'<div class="ma-el-filter-items">' +
									'<div class="ma-el-filter-item ma-el-category-filter active" data-category="all">' +
										'<span>All Categories</span>' +
									'</div>' +
									'<div class="ma-el-filter-item ma-el-category-filter" data-category="blocks">' +
										'<span>Blocks</span>' +
									'</div>' +
									'<div class="ma-el-filter-item ma-el-category-filter" data-category="pages">' +
										'<span>Pages</span>' +
									'</div>' +
									'<div class="ma-el-filter-item ma-el-category-filter" data-category="sections">' +
										'<span>Sections</span>' +
									'</div>' +
								'</div>';
							$filtersList.html(filtersHtml);
						}
						
						// Populate keywords list (widget types)
						// if ($keywordsList.children().length === 0) {
						// 	var keywordsHtml = '<h4>Widgets</h4>' +
						// 		'<div class="ma-el-keyword-items">' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter active" data-keyword="">' +
						// 				'<span>All Widgets</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="call-to-action">' +
						// 				'<span>Call To Action</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="counter">' +
						// 				'<span>Counter</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="creative-button">' +
						// 				'<span>Creative Button</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="faq">' +
						// 				'<span>FAQ</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="flipbox">' +
						// 				'<span>Flipbox</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="heading">' +
						// 				'<span>Heading</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="hero-image">' +
						// 				'<span>Hero Image</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="hero-slideshow">' +
						// 				'<span>Hero Slideshow</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="infobox">' +
						// 				'<span>Infobox</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="progress-bar">' +
						// 				'<span>Progress Bar</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="team-members">' +
						// 				'<span>Team Members</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="testimonial">' +
						// 				'<span>Testimonial</span>' +
						// 			'</div>' +
						// 			'<div class="ma-el-filter-item ma-el-keyword-filter" data-keyword="text-editor">' +
						// 				'<span>Text Editor</span>' +
						// 			'</div>' +
						// 		'</div>';
						// 	$keywordsList.html(keywordsHtml);
						// }
						
						// Add event handlers for filters
						$(document).off('click', '.ma-el-category-filter').on('click', '.ma-el-category-filter', function(e) {
							e.preventDefault();
							var $this = $(this);
							var category = $this.data('category');
							
							// Update active state
							$('.ma-el-category-filter').removeClass('active');
							$this.addClass('active');
							
							// Apply category filter (placeholder for now)
							performCategoryFilter(category);
						});
						
						// $(document).off('click', '.ma-el-keyword-filter').on('click', '.ma-el-keyword-filter', function(e) {
						// 	e.preventDefault();
						// 	var $this = $(this);
						// 	var keyword = $this.data('keyword');
							
						// 	// Update active state
						// 	$('.ma-el-keyword-filter').removeClass('active');
						// 	$this.addClass('active');
							
						// 	// Apply keyword filter
						// 	performKeywordFilter(keyword);
						// });
						
						return true; // Successfully setup
					}
					
					// Wait longer before trying to setup to allow Marionette to initialize first
					setTimeout(function() {
						if (!setupFiltersAndKeywords()) {
							// If not ready, monitor for DOM changes
							var attempts = 0;
							var maxAttempts = 30;
							
							var setupInterval = setInterval(function() {
								attempts++;
								
								if (setupFiltersAndKeywords() || attempts >= maxAttempts) {
									clearInterval(setupInterval);
								}
							}, 200);
						}
					}, 1000); // Wait 1 second for Marionette to initialize
				}
				
				function performCategoryFilter(category) {
					// Placeholder for category filtering
					// This would filter templates by category (blocks, pages, sections, etc.)
					console.log('Category filter:', category);
					
					// For now, just trigger a layout refresh
					refreshMasonryLayout();
				}
				
				// Initialize when document is ready
				initCacheRefresh();
				
				// Initialize Template Importer lazy loading
				initTemplateImporterLazyLoad();
				
				function initTemplateImporterLazyLoad() {
					var currentPage = 1;
					var isLoading = false;
					var hasMoreTemplates = true;
					var perPage = 10;
					
					// Initialize pagination and lazy loading for template modal
					function initTemplatePagination() {
						// Wait for modal content to be available
						function waitForModalContent() {
							var $modalContainer = $('#ma-el-modal-templates-container');
							var $templatesList = $('.ma-el-templates-list');
							
							if ($modalContainer.length > 0 || $templatesList.length > 0) {
								setupScrollPagination();
								return true;
							}
							return false;
						}
						
						// Try immediately and fallback to polling
						if (!waitForModalContent()) {
							var pollCount = 0;
							var pollInterval = setInterval(function() {
								pollCount++;
								if (waitForModalContent() || pollCount > 20) {
									clearInterval(pollInterval);
								}
							}, 500);
						}
					}
					
					function setupScrollPagination() {
						var $container = $('.ma-el-templates-list').length > 0 ? $('.ma-el-templates-list') : $('#ma-el-modal-templates-container');
						
						// Add loading indicator
						if (!$('.ma-el-template-loading-more').length) {
							var $loadingIndicator = $('<div class="ma-el-template-loading-more" style="display: none; text-align: center; padding: 20px;"><p>Loading More Templates...</p></div>');
							$container.after($loadingIndicator);
						}
						
						// Monitor scroll on modal
						var $modalElement = $('#elementor-template-library-modal');
						if ($modalElement.length === 0) {
							$modalElement = $('.dialog-widget');
						}
						
						if ($modalElement.length > 0) {
							$modalElement.off('scroll.template-lazy').on('scroll.template-lazy', function() {
								if (isLoading || !hasMoreTemplates) {
									return;
								}
								
								var scrollTop = $(this).scrollTop();
								var scrollHeight = this.scrollHeight;
								var clientHeight = $(this).height();
								
								// Load more when 200px from bottom
								if (scrollTop + clientHeight >= scrollHeight - 200) {
									loadMoreTemplates();
								}
							});
						}
					}
					
					function loadMoreTemplates() {
						if (isLoading || !hasMoreTemplates) {
							return;
						}
						
						isLoading = true;
						currentPage++;
						
						$('.ma-el-template-loading-more').show();
						
						// Get current active tab
						var activeTab = getActiveTemplateTab();
						
						$.ajax({
							type: 'POST',
							url: ajaxurl,
							data: {
								action: 'ma_el_get_templates',
								tab: activeTab,
								page: currentPage,
								per_page: perPage,
								_wpnonce: MasterAddonsData.get_templates_nonce
							},
							success: function(response) {
								isLoading = false;
								$('.ma-el-template-loading-more').hide();
								
								if (response.success && response.data && response.data.templates && response.data.templates.length > 0) {
									appendTemplates(response.data.templates);
									
									// Check if we have more templates
									if (response.data.templates.length < perPage) {
										hasMoreTemplates = false;
									}
								} else {
									hasMoreTemplates = false;
								}
							},
							error: function(xhr, status, error) {
								isLoading = false;
								$('.ma-el-template-loading-more').hide();
								console.error('Failed to load more templates:', error);
								
								// Reset page counter for retry
								currentPage--;
							}
						});
					}
					
					function getActiveTemplateTab() {
						var $activeTab = $('#ma-el-template-modal-header-tabs input:checked');
						if ($activeTab.length > 0) {
							return $activeTab.val();
						}
						return 'master_section'; // default tab
					}
					
					function appendTemplates(templates) {
						var $container = $('.ma-el-templates-list').length > 0 ? $('.ma-el-templates-list') : $('#ma-el-modal-templates-container');
						
						templates.forEach(function(template) {
							var templateHtml = generateTemplateHTML(template);
							$container.append(templateHtml);
						});
						
						// Refresh layout for new templates
						refreshMasonryLayout();
					}
					
					function generateTemplateHTML(template) {
						var placeholderImage = MasterAddonsData.master_image_dir ? MasterAddonsData.master_image_dir.replace('ma-editor-icon.svg', 'placeholder.png') : '';
						var thumbnailUrl = template.thumbnail || placeholderImage;
						
						return '<div class="elementor-template-library-template ma-el-template-item" data-template-id="' + template.template_id + '" data-title="' + template.title + '" data-keywords="' + (template.keywords || '') + '">' +
							'<div class="elementor-template-library-template-body">' +
								'<div class="elementor-template-library-template-screenshot">' +
									'<div class="elementor-template-library-template-preview">' +
										'<i class="fa fa-search-plus"></i>' +
									'</div>' +
									'<img src="' + thumbnailUrl + '" alt="' + template.title + '" class="ma-el-template-image" onerror="this.src=\'' + placeholderImage + '\'">' +
									'<div class="elementor-template-library-template-name">' + template.title + '</div>' +
								'</div>' +
							'</div>' +
							'<div class="elementor-template-library-template-controls">' +
								'<button class="elementor-template-library-template-action ma-el-template-insert elementor-button elementor-button-success" data-template-id="' + template.template_id + '">' +
									'<i class="eicon-file-download"></i>' +
									'<span class="elementor-button-title">Insert</span>' +
								'</button>' +
							'</div>' +
						'</div>';
					}
					
					// Reset pagination when tab changes
					$(document).on('change', '#ma-el-template-modal-header-tabs input[type="radio"]', function() {
						currentPage = 1;
						isLoading = false;
						hasMoreTemplates = true;
					});
					
					// Initialize when modal is opened
					$(document).on('DOMNodeInserted', '#elementor-template-library-modal', function() {
						setTimeout(initTemplatePagination, 100);
					});
					
					// Initialize immediately if modal is already open
					if ($('#elementor-template-library-modal').length > 0) {
						setTimeout(initTemplatePagination, 100);
					}
				}
			});
			</script>
			<?php
		}


		public static function get_instance()
		{

			if (self::$instance == null) {
				self::$instance = new self;
			}
			return self::$instance;
		}
	}
}

Filemanager

Name Type Size Permission Actions
api.php File 2.18 KB 0775
assets.php File 33.18 KB 0775
config.php File 3.19 KB 0775
get-templates-update.php File 6.66 KB 0775
manager.php File 21.57 KB 0775
rest-api.php File 8.72 KB 0775
template-kit-cache-manager.php File 117.91 KB 0775
template-library-cache-manager.php File 38.14 KB 0775
Filemanager