­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ /** * Element Pack Permission Manager * * This script handles permission manager functionality and role-based filtering * of Element Pack widgets in the Elementor editor and admin pages. */ (function($) { 'use strict'; // Permission Manager Functionality if ($('.ep-permission-manager-content').length > 0) { // Ensure required variables are defined if (typeof epRoleElementsData === 'undefined') { window.epRoleElementsData = {}; } if (typeof epRoleElementsNonce === 'undefined') { window.epRoleElementsNonce = ''; } // Add custom CSS styles if ($('#ep-permission-manager-styles').length === 0) { let customCSS = ` `; $('head').append(customCSS); } initPermissionManager(); } function initPermissionManager() { let currentRole = ''; let currentTab = 'core-widgets'; let currentTypeFilter = 'all'; let allWidgets = []; let allowedWidgets = []; let roleElements = {}; let originalWidgetsHTML = ''; let storedAllowedMap = {}; // Initialize the interface setupEventListeners(); function setupEventListeners() { // Role selector change (for single site) $('#ep-role-selector').on('change', function() { currentRole = $(this).val(); if (currentRole && currentRole !== '') { // Hide helper message when role is selected $('#ep-role-selector-helper').hide(); // Save selected role to localStorage localStorage.setItem('ep_selected_role', currentRole); loadRoleElements(currentRole); } else { // Default option selected - show helper message $('#ep-role-selector-helper').show(); // Clear saved role if none selected localStorage.removeItem('ep_selected_role'); showNoRoleSelected(); } }); // Subsite selector change (for multisite) $('#ep-subsite-selector').on('change', function() { currentRole = $(this).val(); if (currentRole) { // Save selected subsite to localStorage localStorage.setItem('ep_selected_subsite', currentRole); loadRoleElements(currentRole); } else { // Clear saved subsite if none selected localStorage.removeItem('ep_selected_subsite'); showNoRoleSelected(); } }); // Restore previously selected role/subsite on page load setTimeout(function() { // Check for role selector (single site) if ($('#ep-role-selector').length > 0) { const savedRole = localStorage.getItem('ep_selected_role'); const roleSelector = $('#ep-role-selector'); const currentValue = roleSelector.val(); if (savedRole) { const optionExists = roleSelector.find('option[value="' + savedRole + '"]').length > 0; if (optionExists) { roleSelector.val(savedRole); currentRole = savedRole; // Hide helper message since role is selected $('#ep-role-selector-helper').hide(); loadRoleElements(savedRole); } else { localStorage.removeItem('ep_selected_role'); // Show helper message if no valid role showNoRoleSelected(); } } else { // No saved role - check if default option is selected if (!currentValue || currentValue === '' || currentValue === null) { // Show helper message if default option is selected showNoRoleSelected(); } else { // A role is selected, hide helper message $('#ep-role-selector-helper').hide(); } } } // Check for subsite selector (multisite) if ($('#ep-subsite-selector').length > 0) { const savedSubsite = localStorage.getItem('ep_selected_subsite'); if (savedSubsite) { const subsiteSelector = $('#ep-subsite-selector'); const optionExists = subsiteSelector.find('option[value="' + savedSubsite + '"]').length > 0; if (optionExists) { subsiteSelector.val(savedSubsite); currentRole = savedSubsite; loadRoleElements(savedSubsite); } else { localStorage.removeItem('ep_selected_subsite'); } } } }, 200); // Tab button handlers $('.ep-tab-button').on('click', function() { const previousTab = currentTab; currentTab = $(this).data('category'); // Update active tab $('.ep-tab-button').removeClass('active'); $(this).addClass('active'); // Update tab styles updateTabStyles(); // Handle tab switching logic if (currentTab === 'settings') { // Switching TO settings tab showSettingsItems(); } else { // Switching FROM settings tab or between widget tabs if (previousTab === 'settings') { // Restore widgets first, then filter restoreWidgets(); } // Show all widgets first, then apply category filter if (currentTab === 'all') { $('.ep-widget-item').show(); } else { // Filter widgets by category filterWidgetsByCategory(currentTab); } } }); // Category filter buttons (legacy - keeping for compatibility) $(document).on('click', '.ep-category-filter-btn', function() { var category = $(this).data('category'); // Highlight active button $('.ep-category-filter-btn').removeClass('bdt-button-primary-active bdt-button-default-active'); if ($(this).hasClass('bdt-button-primary')) { $(this).addClass('bdt-button-primary-active'); } else { $(this).addClass('bdt-button-default-active'); } }); // Quick actions - Fixed selectors to match actual HTML IDs $('#ep-select-all-role-elements').on('click', function() { selectAllWidgets(); }); $('#ep-deselect-all-role-elements').on('click', function() { deselectAllWidgets(); }); // Search functionality $('#ep-widgets-search').on('input', function() { var searchTerm = $(this).val().toLowerCase().trim(); filterWidgetsBySearch(searchTerm); }); // Type filter buttons (Pro/Free/All) $(document).on('click', '.ep-type-filter-btn', function() { var filterType = $(this).data('filter'); // Update active state $('.ep-type-filter-btn').removeClass('active').css({ 'background': '#f0f0f1', 'color': '#3c434a', 'border': '1px solid #c3c4c7' }); $(this).addClass('active'); // Set button-specific colors when active if (filterType === 'all') { $(this).css({ 'background': '#0073aa', 'color': '#fff', 'border': '1px solid #0073aa' }); } else if (filterType === 'free') { $(this).css({ 'background': '#00a32a', 'color': '#fff', 'border': '1px solid #00a32a' }); } else if (filterType === 'pro') { $(this).css({ 'background': '#d63638', 'color': '#fff', 'border': '1px solid #d63638' }); } currentTypeFilter = filterType; applyAllFilters(); }); // Save and reset buttons $('.ep-save-role-elements').on('click', function() { saveRoleElements(); }); $('.ep-reset-role-elements').on('click', function() { resetRoleElements(); }); // Widget item click $(document).on('click', '.ep-widget-item:not(.disabled)', function() { const widgetName = $(this).data('widget'); const isSelected = $(this).hasClass('selected'); $(this).toggleClass('selected'); // Update stored allowed map to keep state in sync if (storedAllowedMap) { if (!isSelected) { // Widget was just selected storedAllowedMap[widgetName] = 'on'; } else { // Widget was just deselected delete storedAllowedMap[widgetName]; } } }); } function updateTabStyles() { $('.ep-tab-button').each(function() { if ($(this).hasClass('active')) { $(this).css({ 'background': '#0073aa', 'color': '#fff', 'border-bottom': '2px solid #0073aa' }); } else { $(this).css({ 'background': '#f0f0f1', 'color': '#3c434a', 'border-bottom': '1px solid #c3c4c7' }); } }); } function showSettingsItems() { // Check if allWidgets is available if (typeof allWidgets === 'undefined' || !allWidgets) { $('#ep-widgets-grid').html('

No widgets data available. Please select a role first.

'); $('#ep-widgets-grid').show(); $('#ep-role-elements-loading').hide(); return; } // Get current role's allowed settings from stored data let allowedSettings = {}; if (typeof epRoleElementsData !== 'undefined' && epRoleElementsData[currentRole]) { allowedSettings = epRoleElementsData[currentRole]; } // Filter widgets to show only settings items const settingsWidgets = allWidgets.filter(function(widget) { return widget.module_type === 'settings'; }); // Generate HTML for settings items let html = ''; settingsWidgets.forEach(function(widget) { // Use storedAllowedMap for consistent selection state let isSelected = storedAllowedMap && storedAllowedMap[widget.name] === 'on'; html += '
'; html += '
'; html += '

' + widget.label + '

'; html += 'SETTING'; html += '
'; html += '
'; }); // Update the widgets grid $('#ep-widgets-grid').html(html); $('#ep-widgets-grid').show(); $('#ep-role-elements-loading').hide(); $('#ep-role-selector-helper').hide(); // Ensure helper message is hidden when settings are shown // Update tab styles updateTabStyles(); } function categorizeWidget(widgetName, widgetElement) { // Use the module_type from widget data instead of guessing from names if (widgetElement && $(widgetElement).data('module-type')) { const moduleType = $(widgetElement).data('module-type'); return moduleType; } // 3rd Party Widgets if (widgetName.includes('woocommerce') || widgetName.includes('wc-') || widgetName.includes('contact-form-7') || widgetName.includes('cf7') || widgetName.includes('bbpress') || widgetName.includes('buddypress') || widgetName.includes('edd-') || widgetName.includes('charitable') || widgetName.includes('events-calendar') || widgetName.includes('everest-forms')) { return '3rd-party-widgets'; } // Extensions if (widgetName.includes('background-') || widgetName.includes('backdrop-filter') || widgetName.includes('cursor-effects') || widgetName.includes('confetti-effects') || widgetName.includes('animated-gradient-background') || widgetName.includes('animated-link') || widgetName.includes('animated-heading') || widgetName.includes('parallax') || widgetName.includes('overlay') || widgetName.includes('expand') || widgetName.includes('smooth-scroller') || widgetName.includes('live-copy') || widgetName.includes('duplicator') || widgetName.includes('custom-js') || widgetName.includes('custom-css') || widgetName.includes('-effects') || widgetName === 'equal-height' || widgetName === 'visibility-controls' || widgetName === 'content-protector' || widgetName === 'elementor') { return 'extensions'; } // Special Features if (widgetName.includes('dark-mode') || widgetName.includes('age-gate') || widgetName.includes('cookie-consent') || widgetName.includes('adblock-detector') || widgetName.includes('mega-menu')) { return 'special-features'; } // Default to Core Widgets return 'core-widgets'; } function filterWidgetsByCategory(category) { currentTab = category; // Handle settings tab if (currentTab === 'settings') { showSettingsItems(); return; } applyAllFilters(); } function filterWidgetsBySearch(searchTerm) { applyAllFilters(); } function applyAllFilters() { const searchTerm = $('#ep-widgets-search').val().toLowerCase().trim(); let visibleCount = 0; let hiddenCount = 0; // Filter widgets based on all criteria $('.ep-widget-item').each(function() { const widgetTitle = $(this).find('.ep-widget-title').text().toLowerCase(); const widgetDescription = $(this).find('.ep-widget-description').text().toLowerCase(); const widgetName = $(this).data('widget') || ''; const widgetType = $(this).find('.ep-widget-badge').text().toLowerCase(); const widgetSelected = $(this).hasClass('selected'); let shouldShow = true; // Apply search filter if (searchTerm) { const searchMatches = widgetTitle.includes(searchTerm) || widgetDescription.includes(searchTerm) || widgetName.toLowerCase().includes(searchTerm); if (!searchMatches) { shouldShow = false; } } // Apply category filter if (shouldShow && currentTab !== 'all' && currentTab !== 'settings') { const widgetCategory = categorizeWidget(widgetName, this); if (widgetCategory !== currentTab) { shouldShow = false; } } // Apply type filter (Pro/Free/All) if (shouldShow && currentTypeFilter !== 'all') { // Check if widget type matches filter if (currentTypeFilter === 'pro' && !widgetType.includes('pro')) { shouldShow = false; } else if (currentTypeFilter === 'free' && !widgetType.includes('free')) { shouldShow = false; } else if (currentTypeFilter === 'selected' && !widgetSelected) { shouldShow = false; } } // Apply visibility if (shouldShow) { $(this).show(); visibleCount++; } else { $(this).hide(); hiddenCount++; } }); } function restoreWidgets() { if (originalWidgetsHTML) { // Restore the original widgets HTML $('#ep-widgets-grid').html(originalWidgetsHTML); $('#ep-widgets-grid').show(); // Reapply selections based on stored allowed map $('.ep-widget-item').each(function() { const widgetName = $(this).data('widget'); if (storedAllowedMap && storedAllowedMap[widgetName]) { $(this).addClass('selected'); } else { $(this).removeClass('selected'); } }); } } function debugWidgetCategories() { let categoryCounts = { 'core-widgets': 0, '3rd-party-widgets': 0, 'extensions': 0, 'special-features': 0, 'settings': 0 }; let extensionWidgets = []; let allWidgetNames = []; $('.ep-widget-item').each(function() { const widgetName = $(this).data('widget') || ''; const widgetLabel = $(this).find('.ep-widget-title').text() || ''; const moduleType = $(this).data('module-type') || ''; const widgetCategory = $(this).hasClass('ep-setting-item') ? 'settings' : categorizeWidget(widgetName, this); allWidgetNames.push(widgetName); if (widgetCategory === 'extensions') { extensionWidgets.push({name: widgetName, label: widgetLabel, moduleType: moduleType}); } if (categoryCounts.hasOwnProperty(widgetCategory)) { categoryCounts[widgetCategory]++; } else { categoryCounts[widgetCategory] = 1; } }); } function loadRoleElements(role) { // Hide helper message and show the container when loading role elements $('#ep-role-selector-helper').hide(); // Show the container and loading state $('#ep-role-elements-container').show(); showLoading(); $.ajax({ url: ajaxurl, type: 'POST', data: { action: 'ep_get_role_elements', role: role, nonce: epRoleElementsNonce, ep_permission_manager_bypass: true // <--- added for backend bypass }, success: function(response) { if (response.success) { var widgets = response.data.all_widgets; var allowed = response.data.allowed_widgets; var allowedMap = {}; // Convert array of widget names to map with 'on' status if (Array.isArray(allowed)) { allowed.forEach(function(name) { allowedMap[name] = 'on'; }); } else if (typeof allowed === 'object') { // If it's already a map, use it directly allowedMap = allowed; } // Store widgets globally for settings tab allWidgets = widgets; allowedWidgets = allowed; renderWidgets(widgets, allowedMap); } else { showNotice('Error loading widgets: ' + response.data, 'error'); } }, error: function(xhr, status, error) { showNotice('Error loading widgets. Please try again.', 'error'); } }); } function renderWidgets(widgets, allowedMap) { let html = ''; if (widgets && widgets.length > 0) { widgets.forEach(function(widget) { let isSelected = allowedMap && (allowedMap[widget.name] === 'on' || allowedMap[widget.name] === true); html += '
'; html += '
'; html += '

' + widget.label + '

'; html += '' + widget.widget_type + ''; html += '
'; // Only render description if it exists if (widget.description) { html += '

' + widget.description + '

'; } // Do NOT render .ep-widget-category (content_type) anymore html += '
'; }); } else { html = '

No widgets available

'; } $('#ep-widgets-grid').html(html); $('#ep-widgets-grid').show(); // Make sure it's visible $('#ep-role-elements-loading').hide(); // Hide loading indicator $('#ep-role-selector-helper').hide(); // Ensure helper message is hidden when widgets are shown // Store original widgets HTML and allowed map for later restoration originalWidgetsHTML = html; storedAllowedMap = allowedMap || {}; // Initialize tab filtering and update styles updateTabStyles(); // Show all widgets initially (no filtering) currentTab = 'all'; // Debug widget categories debugWidgetCategories(); } // Add search field above widget grid on init if ($('.ep-permission-manager-content').length > 0) { if ($('#ep-widget-search').length === 0) { $('.ep-permission-manager-controls').append('
'); } } let currentCategory = ''; let currentSearch = ''; // Add secondary filter group tracking let currentPrimary = ''; let currentSecondary = ''; // Update filter button event handlers $(document).on('click', '.ep-category-filter-btn', function() { var category = $(this).data('category'); var isPrimary = $(this).hasClass('bdt-button-primary'); var isAll = (category === ""); if (isAll) { // Deselect all filter buttons in both groups $('.ep-category-filter-btn.bdt-button-primary').removeClass('bdt-button-primary-active'); $('.ep-category-filter-btn.bdt-button-default').removeClass('bdt-button-default-active'); // Set both filter states to "" currentPrimary = ""; currentSecondary = ""; // Highlight both "All" buttons $('.ep-category-filter-btn.bdt-button-primary[data-category=""]').addClass('bdt-button-primary-active'); $('.ep-category-filter-btn.bdt-button-default[data-category=""]').addClass('bdt-button-default-active'); } else if (isPrimary) { currentPrimary = category; $('.ep-category-filter-btn.bdt-button-primary').removeClass('bdt-button-primary-active'); $(this).addClass('bdt-button-primary-active'); } else { currentSecondary = category; $('.ep-category-filter-btn.bdt-button-default').removeClass('bdt-button-default-active'); $(this).addClass('bdt-button-default-active'); } applyWidgetFilters(); }); // Set initial filter states (All for both) currentPrimary = ''; currentSecondary = ''; // Highlight 'All' buttons on load $('.ep-category-filter-btn.bdt-button-primary[data-category=""]').addClass('bdt-button-primary-active'); $('.ep-category-filter-btn.bdt-button-default[data-category=""]').addClass('bdt-button-default-active'); // Update applyWidgetFilters to AND both filters function applyWidgetFilters() { $('.ep-widget-item').each(function() { var $item = $(this); var matchesPrimary = false; var matchesSecondary = false; // --- Primary filter logic --- if (!currentPrimary) { matchesPrimary = true; } else if (currentPrimary === 'pro') { matchesPrimary = $item.find('.ep-widget-badge').hasClass('pro'); } else if (currentPrimary === 'free') { matchesPrimary = $item.find('.ep-widget-badge').hasClass('free'); } else { matchesPrimary = true; } // --- Secondary filter logic --- if (!currentSecondary) { matchesSecondary = true; } else if (currentSecondary === 'forms') { matchesSecondary = ($item.data('category')+"").toLowerCase().indexOf('form') !== -1; } else if (currentSecondary === 'third-party') { matchesSecondary = ($item.data('category')+"").toLowerCase().indexOf('third') !== -1; } else if ([ 'new', 'post', 'custom', 'gallery', 'slider', 'carousel', 'template-builder', 'others', 'woocommerce', 'basic' ].includes(currentSecondary)) { var cat = ($item.data('category')+"").toLowerCase().replace(/[_\s-]+/g, '-'); var keyword = currentSecondary.replace(/[_\s-]+/g, '-'); matchesSecondary = cat.indexOf(keyword) !== -1; } else { matchesSecondary = $item.data('category') === currentSecondary; } // --- Search logic (unchanged) --- var label = $item.find('.ep-widget-title').text().toLowerCase(); var desc = $item.find('.ep-widget-description').text().toLowerCase(); var matchesSearch = (!currentSearch || label.indexOf(currentSearch) !== -1 || desc.indexOf(currentSearch) !== -1); // Show/hide if (matchesPrimary && matchesSecondary && matchesSearch) { $item.show(); } else { $item.hide(); } }); } function selectAllWidgets() { var widgets = $('.ep-widget-item:visible:not(.disabled)'); widgets.addClass('selected'); // Update stored allowed map if (storedAllowedMap) { widgets.each(function() { const widgetName = $(this).data('widget'); if (widgetName) { storedAllowedMap[widgetName] = 'on'; } }); } } function deselectAllWidgets() { var widgets = $('.ep-widget-item:visible'); widgets.removeClass('selected'); // Update stored allowed map if (storedAllowedMap) { widgets.each(function() { const widgetName = $(this).data('widget'); if (widgetName) { delete storedAllowedMap[widgetName]; } }); } } function showLoading() { $('#ep-widgets-grid').html('

Loading elements...

'); } function showNoRoleSelected() { // Show helper message and hide the container when no role is selected $('#ep-role-selector-helper').show(); $('#ep-role-elements-container').hide(); if (typeof epIsMultisite !== 'undefined' && epIsMultisite) { $('#ep-widgets-grid').html('

Please select a subsite to manage its element access

'); $('.ep-status-text').text('Select a subsite to manage its element access'); } else { $('#ep-widgets-grid').html('

Please select a user role to manage its element access

'); $('.ep-status-text').text('Select a role to manage its element access'); } } function saveRoleElements() { if (!currentRole) { let message = 'Please select a ' + (typeof epIsMultisite !== 'undefined' && epIsMultisite ? 'subsite' : 'role') + ' first.'; showNotice(message, 'warning'); return; } // Show saving state $('.ep-save-role-elements').prop('disabled', true).html(' Saving...'); let selectedWidgets = {}; // Get all widgets from allWidgets array to ensure we save all widgets if (allWidgets && allWidgets.length > 0) { allWidgets.forEach(function(widget) { // Check if this widget is selected in the DOM let widgetElement = $('.ep-widget-item[data-widget="' + widget.name + '"]'); if (widgetElement.length > 0 && widgetElement.hasClass('selected')) { selectedWidgets[widget.name] = 'on'; } else { // If widget element doesn't exist in DOM (e.g., settings items when on other tabs), // check if it was previously selected if (storedAllowedMap && storedAllowedMap[widget.name] === 'on') { selectedWidgets[widget.name] = 'on'; } } }); } $.ajax({ url: ajaxurl, type: 'POST', data: { action: 'ep_save_role_elements', role: currentRole, elements: selectedWidgets, nonce: epRoleElementsNonce }, success: function(response) { if (response.success) { if (typeof epRoleElementsData === 'undefined') { epRoleElementsData = {}; } epRoleElementsData[currentRole] = selectedWidgets; // Update stored allowed map to keep selections in sync storedAllowedMap = selectedWidgets; // Also update epRoleElementsData for consistency if (typeof epRoleElementsData === 'undefined') { epRoleElementsData = {}; } epRoleElementsData[currentRole] = selectedWidgets; showNotice('Permission saved successfully! ' + Object.keys(selectedWidgets).length + ' elements configured for ' + currentRole + ' role.', 'success'); // Temporary success button state $('.ep-save-role-elements').html(' Saved!').removeClass('bdt-button-primary').addClass('bdt-button-success'); setTimeout(function() { $('.ep-save-role-elements').html('Save Settings').removeClass('bdt-button-success').addClass('bdt-button-primary'); }, 2000); } else { showNotice('Error saving settings: ' + response.data, 'error'); } }, error: function(xhr, status, error) { showNotice('Error saving settings. Please try again.', 'error'); }, complete: function() { $('.ep-save-role-elements').prop('disabled', false); } }); } function resetRoleElements() { if (!currentRole) { let message = 'Please select a ' + (typeof epIsMultisite !== 'undefined' && epIsMultisite ? 'subsite' : 'role') + ' first.'; showNotice(message, 'error'); return; } let confirmMessage = 'Are you sure you want to reset all elements for this ' + (typeof epIsMultisite !== 'undefined' && epIsMultisite ? 'subsite' : 'role') + ' to default settings?'; if (!confirm(confirmMessage)) { return; } $.ajax({ url: ajaxurl, type: 'POST', data: { action: 'ep_reset_role_elements', role: currentRole, nonce: epRoleElementsNonce }, success: function(response) { if (response.success) { if (typeof epRoleElementsData !== 'undefined') { delete epRoleElementsData[currentRole]; } loadRoleElements(currentRole); // Select the first tab after reset setTimeout(function() { // Remove active class from all tabs $('.ep-tab-button').removeClass('active'); // Add active class to first tab (core-widgets) $('.ep-tab-button[data-category="core-widgets"]').addClass('active'); // Update current tab variable currentTab = 'core-widgets'; // Update tab styles updateTabStyles(); // Apply filters to show core widgets applyAllFilters(); }, 100); let successMessage = (typeof epIsMultisite !== 'undefined' && epIsMultisite ? 'Subsite' : 'Role') + ' elements reset to default successfully!'; showNotice(successMessage, 'success'); } else { showNotice('Error resetting settings: ' + response.data, 'error'); } }, error: function() { showNotice('Error resetting settings. Please try again.', 'error'); } }); } function showNotice(message, type) { // Try UIKit notification first if (typeof bdtUIkit !== 'undefined' && bdtUIkit.notification) { let status = 'primary'; if (type === 'success') status = 'success'; else if (type === 'error') status = 'danger'; else if (type === 'warning') status = 'warning'; bdtUIkit.notification({ message: message, status: status, pos: 'top-center', timeout: 3000 }); } // Fallback to WordPress admin notice style else { // Create a temporary notice element let noticeClass = 'notice notice-info'; if (type === 'success') noticeClass = 'notice notice-success'; else if (type === 'error') noticeClass = 'notice notice-error'; else if (type === 'warning') noticeClass = 'notice notice-warning'; let noticeHtml = '
'; noticeHtml += '

' + message + '

'; noticeHtml += ''; noticeHtml += '
'; // Add to body $('body').append(noticeHtml); // Auto-remove after 3 seconds setTimeout(function() { $('.ep-temp-notice').fadeOut(function() { $(this).remove(); }); }, 3000); } } // Show initial state showNoRoleSelected(); // Auto-select subsite for subsite admins (if only one option available) if (typeof epIsMultisite !== 'undefined' && epIsMultisite && typeof epIsMainSiteAdmin !== 'undefined' && !epIsMainSiteAdmin && typeof epCurrentSubsiteId !== 'undefined' && epCurrentSubsiteId) { // Auto-select the current subsite for subsite admins if ($('#ep-subsite-selector').length > 0) { $('#ep-subsite-selector').val(epCurrentSubsiteId).trigger('change'); } else if ($('#ep-role-selector').length > 0) { $('#ep-role-selector').val(epCurrentSubsiteId).trigger('change'); } } // Toggle Permission Manager Save Button Section function togglePermissionManagerSaveSection() { var hash = window.location.hash; var showBtns = (hash.indexOf('element_pack_permission_manager') !== -1); if (showBtns) { $('.ep-permission-manager-save-section').show(); } else { $('.ep-permission-manager-save-section').hide(); } } // Run on load togglePermissionManagerSaveSection(); // Run on hash change $(window).on('hashchange', togglePermissionManagerSaveSection); // Search input event handler (fix) $(document).on('input', '#ep-widget-search', function() { currentSearch = $(this).val().toLowerCase(); applyWidgetFilters(); }); } // Role Filters functionality (from ep-role-filters.js) var RoleFilters = { init: function() { this.bindEvents(); this.applyRoleFilters(); this.applyAdminSettingsFilters(); }, bindEvents: function() { // Listen for Elementor editor ready $(document).on('elementor/editor/init', function() { RoleFilters.applyRoleFilters(); }); // Listen for widget panel updates $(document).on('elementor/panel/widgets/loaded', function() { RoleFilters.hideRestrictedWidgets(); }); // Listen for new widgets added $(document).on('elementor/widgets/register', function() { RoleFilters.hideRestrictedWidgets(); }); }, applyRoleFilters: function() { // Only apply in Elementor editor if (typeof elementorFrontend === 'undefined') { return; } var settings = elementorFrontend.config; if (settings.ep_role_filters && settings.ep_role_filters.has_restrictions) { this.hideRestrictedWidgets(); this.showRestrictionNotice(); } }, hideRestrictedWidgets: function() { // Only apply in Elementor editor if (typeof elementorFrontend === 'undefined') { return; } var settings = elementorFrontend.config; if (!settings.ep_role_filters || !settings.ep_role_filters.restricted_widgets) { return; } var restrictedWidgets = settings.ep_role_filters.restricted_widgets; // Hide restricted widgets from the widgets panel restrictedWidgets.forEach(function(widgetName) { // Hide from the widgets list in the panel var panelWidget = $('.elementor-element-wrapper[data-widget-type="' + widgetName + '"]'); if (panelWidget.length) { panelWidget.hide(); panelWidget.addClass('ep-restricted'); } // Also hide from any other widget elements var widgetElement = $('[data-widget-type="' + widgetName + '"]'); if (widgetElement.length) { widgetElement.hide(); widgetElement.addClass('ep-restricted'); } }); // Hide restricted widgets from search results $(document).on('input', '.elementor-panel-search-input', function() { setTimeout(function() { restrictedWidgets.forEach(function(widgetName) { var searchResult = $('.elementor-element-wrapper[data-widget-type="' + widgetName + '"]'); if (searchResult.length) { searchResult.hide(); searchResult.addClass('ep-restricted'); } }); }, 100); }); // Also hide from category tabs $(document).on('click', '.elementor-panel-category', function() { setTimeout(function() { restrictedWidgets.forEach(function(widgetName) { var categoryWidget = $('.elementor-element-wrapper[data-widget-type="' + widgetName + '"]'); if (categoryWidget.length) { categoryWidget.hide(); categoryWidget.addClass('ep-restricted'); } }); }, 100); }); }, showRestrictionNotice: function() { // Only apply in Elementor editor if (typeof elementorFrontend === 'undefined') { return; } var settings = elementorFrontend.config; if (!settings.ep_role_filters || !settings.ep_role_filters.has_restrictions) { return; } // Check if notice already exists if ($('.ep-role-restriction-notice').length) { return; } var notice = $('
' + '

Element Pack: Some widgets are restricted based on your user role. ' + 'Contact an administrator if you need access to additional widgets.

' + '
'); // Add notice to the editor $('.elementor-panel-header').after(notice); // Make notice dismissible notice.find('.notice-dismiss').on('click', function() { notice.fadeOut(); }); }, getRestrictedWidgets: function() { // For admin pages, we'll get this from PHP via global variable if (typeof window.epRestrictedWidgets !== 'undefined') { return window.epRestrictedWidgets; } // For Elementor editor if (typeof elementorFrontend !== 'undefined' && elementorFrontend.config.ep_role_filters) { return elementorFrontend.config.ep_role_filters.restricted_widgets || []; } // Default fallback return []; }, isWidgetRestricted: function(widgetName) { var restrictedWidgets = this.getRestrictedWidgets(); return restrictedWidgets.indexOf(widgetName) !== -1; }, applyAdminSettingsFilters: function() { // Only apply on Element Pack admin pages if (!window.location.href.includes('element-pack')) { return; } // Get restricted widgets from PHP var restrictedWidgets = this.getRestrictedWidgets(); if (restrictedWidgets.length === 0) { return; } // Hide restricted widgets in admin settings restrictedWidgets.forEach(function(widgetName) { var cleanWidgetName = widgetName.replace('bdt-', ''); // Hide widget options in admin settings $('.ep-option-item-inner').each(function() { var $item = $(this); var $input = $item.find('input[name*="' + cleanWidgetName + '"], input[id*="' + cleanWidgetName + '"]'); if ($input.length > 0) { $item.hide(); $item.addClass('ep-restricted'); } }); }); // Update widget counts after hiding restricted widgets setTimeout(function() { // Trigger any existing count update functions if (typeof updateTotalStatus === 'function') { updateTotalStatus(); } // Update used/unused counts RoleFilters.updateAdminCounts(); }, 500); }, updateAdminCounts: function() { // Update used widget counts $('.ep-used-widget').each(function() { var $container = $(this).closest('.ep-options-parent'); var usedCount = $container.find('.ep-options .ep-used:visible').length; $(this).text(usedCount); }); // Update unused widget counts $('.ep-unused-widget').each(function() { var $container = $(this).closest('.ep-options-parent'); var unusedCount = $container.find('.ep-options .ep-unused:visible').length; $(this).text(unusedCount); }); } }; // Initialize when document is ready $(document).ready(function() { RoleFilters.init(); }); // Make RoleFilters available globally window.ElementPackRoleFilters = RoleFilters; // Elementor Editor Restricted Widget Management var ElementorRestrictedWidgets = { init: function() { this.waitForDependencies(); }, waitForDependencies: function() { if (typeof $ !== 'undefined' && typeof elementor !== 'undefined') { this.setupRestrictedWidgetManagement(); } else { setTimeout(this.waitForDependencies.bind(this), 100); } }, setupRestrictedWidgetManagement: function() { this.hideRestrictedWidgets(); this.setupEventListeners(); this.setupSearchMonitoring(); this.addCSSRules(); this.hideExtensionControlSections(); }, hideRestrictedWidgets: function() { // Check if $ is available if (typeof $ === 'undefined') { setTimeout(this.hideRestrictedWidgets.bind(this), 100); return; } // Hide from main panel this.hideRestrictedWidgetsFromPanel(); // Hide from search results this.hideRestrictedWidgetsFromSearch(); }, hideRestrictedWidgetsFromPanel: function() { var restrictedWidgets = this.getRestrictedWidgets(); if (restrictedWidgets && restrictedWidgets.length > 0) { // Count how many widgets we find var foundWidgets = 0; var hiddenWidgets = 0; // Find all widget elements in the Element Pack category var $elementPackCategory = $('#elementor-panel-category-element-pack'); if ($elementPackCategory.length) { // Find all elementor-element-wrapper elements that contain bdt-wi- classes $elementPackCategory.find('.elementor-element-wrapper').each(function () { var $widget = $(this); var $icon = $widget.find('[class*="bdt-wi-"]'); if ($icon.length) { foundWidgets++; // Primary method: Extract from icon class var widgetName = null; $icon.each(function () { var iconClass = $(this).attr('class'); if (iconClass) { var iconMatch = iconClass.match(/bdt-wi-([^\s]+)/); if (iconMatch) { widgetName = 'bdt-' + iconMatch[1]; } } }); if (widgetName) { // Check if this widget is in the restricted list var isRestricted = restrictedWidgets.includes(widgetName); if (isRestricted) { // Hide the restricted widget $widget.remove(); hiddenWidgets++; } } } }); } } }, hideRestrictedWidgetsFromSearch: function() { var restrictedWidgets = this.getRestrictedWidgets(); if (restrictedWidgets && restrictedWidgets.length > 0) { // Hide from search results - target the specific search panel var $searchResults = $('#elementor-panel-elements .elementor-element-wrapper'); var hiddenFromSearch = 0; // Also check if search is active var $searchInput = $('#elementor-panel-elements-search-input'); var searchValue = $searchInput.val(); if (searchValue && searchValue.length > 0) { $searchResults.each(function () { var $widget = $(this); var $icon = $widget.find('[class*="bdt-wi-"]'); if ($icon.length) { // Extract widget name from icon class var widgetName = null; $icon.each(function () { var iconClass = $(this).attr('class'); if (iconClass) { var iconMatch = iconClass.match(/bdt-wi-([^\s]+)/); if (iconMatch) { widgetName = 'bdt-' + iconMatch[1]; } } }); if (widgetName) { // Check if this widget is in the restricted list var isRestricted = restrictedWidgets.includes(widgetName); if (isRestricted) { // Remove the restricted widget from search completely $widget.remove(); hiddenFromSearch++; } } } }); } } }, setupEventListeners: function() { // Hide restricted widgets immediately this.hideRestrictedWidgets(); // Try to use elementor channels if available if (typeof elementor !== 'undefined' && elementor.channels && elementor.channels.panel) { // Also hide when panel is refreshed or widgets are updated elementor.channels.panel.on('change', function () { setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgets.bind(ElementorRestrictedWidgets), 100); }); // Hide when switching between categories elementor.channels.panel.on('category:activated', function () { setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgets.bind(ElementorRestrictedWidgets), 100); }); // Hide when panel is opened elementor.channels.panel.on('open', function () { setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgets.bind(ElementorRestrictedWidgets), 100); }); // Hide when widgets are loaded elementor.channels.panel.on('widgets:loaded', function () { setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgets.bind(ElementorRestrictedWidgets), 200); }); // Hide when elements are loaded elementor.channels.panel.on('elements:loaded', function () { setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgets.bind(ElementorRestrictedWidgets), 200); }); } // Use MutationObserver to watch for DOM changes (fallback method) if (typeof MutationObserver !== 'undefined') { var observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgets.bind(ElementorRestrictedWidgets), 100); } }); }); // Start observing the panel var panelElement = document.querySelector('#elementor-panel-category-element-pack'); if (panelElement) { observer.observe(panelElement, { childList: true, subtree: true }); } // Also observe the entire panel area for changes var panelArea = document.querySelector('#elementor-panel-elements'); if (panelArea) { observer.observe(panelArea, { childList: true, subtree: true }); } } // Set up periodic checking as a fallback setInterval(this.hideRestrictedWidgets.bind(this), 2000); // Periodic check for control sections (more frequent to handle timing issues) setInterval(this.hideExtensionControlSections.bind(this), 500); // Monitor for control sections being added $(document).on('DOMNodeInserted', '#elementor-control-section_element_pack_confetti_controls', function() { ElementorRestrictedWidgets.hideExtensionControlSections(); }); // Also monitor the entire control panel for any new sections $(document).on('DOMNodeInserted', '.elementor-controls', function() { setTimeout(ElementorRestrictedWidgets.hideExtensionControlSections.bind(ElementorRestrictedWidgets), 100); }); // More aggressive monitoring for any control section with confetti $(document).on('DOMNodeInserted', '[id*="confetti"], [class*="confetti"]', function() { setTimeout(ElementorRestrictedWidgets.hideExtensionControlSections.bind(ElementorRestrictedWidgets), 50); }); // Monitor when any control is added $(document).on('DOMNodeInserted', '.elementor-control', function() { var $control = $(this); var controlClass = $control.attr('class') || ''; // Check if this control is for a restricted widget var restrictedWidgets = ElementorRestrictedWidgets.getRestrictedWidgets(); if (restrictedWidgets && restrictedWidgets.length > 0) { restrictedWidgets.forEach(function(widgetName) { var widgetShortName = widgetName.replace('bdt-', ''); // Look for controls with both patterns - account for the elementor-control prefix if (controlClass.includes('elementor-control-section_element_pack_'+widgetShortName+'_controls') || controlClass.includes('elementor-control-element_pack_'+widgetShortName+'_section') || controlClass.includes('section_element_pack_'+widgetShortName+'_controls') || controlClass.includes('element_pack_'+widgetShortName+'_section') || controlClass.includes('elementor-control elementor-control-section_element_pack_'+widgetShortName+'_controls') || controlClass.includes('elementor-control elementor-control-element_pack_'+widgetShortName+'_section')) { $control.remove(); } }); } }); // Monitor when Elementor editor is ready $(document).on('elementor/editor/init', function() { setTimeout(ElementorRestrictedWidgets.hideExtensionControlSections.bind(ElementorRestrictedWidgets), 500); }); // Monitor when widgets are selected/activated $(document).on('elementor/editor/widget/activated', function() { setTimeout(ElementorRestrictedWidgets.hideExtensionControlSections.bind(ElementorRestrictedWidgets), 100); }); // Monitor when any element is selected $(document).on('elementor/editor/element/activated', function() { setTimeout(ElementorRestrictedWidgets.hideExtensionControlSections.bind(ElementorRestrictedWidgets), 100); }); // Monitor when a widget is selected (this is when controls are loaded) $(document).on('elementor/editor/widget/activated', function(event, widget) { // Wait a bit longer for controls to load setTimeout(ElementorRestrictedWidgets.hideExtensionControlSections.bind(ElementorRestrictedWidgets), 300); }); // Monitor when control panel is updated $(document).on('elementor/panel/control/loaded', function() { setTimeout(ElementorRestrictedWidgets.hideExtensionControlSections.bind(ElementorRestrictedWidgets), 100); }); // Monitor when control panel is opened $(document).on('elementor/panel/control/opened', function() { setTimeout(ElementorRestrictedWidgets.hideExtensionControlSections.bind(ElementorRestrictedWidgets), 100); }); // Add MutationObserver specifically for control panel if (typeof MutationObserver !== 'undefined') { var controlObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { // Check if any of the added nodes are control sections mutation.addedNodes.forEach(function(node) { if (node.nodeType === 1) { // Element node var $node = $(node); if ($node.hasClass('elementor-control') || $node.find('.elementor-control').length > 0) { setTimeout(ElementorRestrictedWidgets.hideExtensionControlSections.bind(ElementorRestrictedWidgets), 50); } } }); } }); }); // Start observing the control panel var controlPanel = document.querySelector('#elementor-controls'); if (controlPanel) { controlObserver.observe(controlPanel, { childList: true, subtree: true }); } // Also add a more aggressive observer that continuously removes restricted controls var aggressiveControlObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach(function(node) { if (node.nodeType === 1) { // Element node var $node = $(node); if ($node.hasClass('elementor-control')) { var controlClass = $node.attr('class') || ''; // Check if this is a restricted control var restrictedWidgets = ElementorRestrictedWidgets.getRestrictedWidgets(); if (restrictedWidgets && restrictedWidgets.length > 0) { for (var i = 0; i < restrictedWidgets.length; i++) { var widgetName = restrictedWidgets[i]; var widgetShortName = widgetName.replace('bdt-', ''); // Check for restricted control patterns if (controlClass.includes('elementor-control-section_element_pack_'+widgetShortName+'_controls') || controlClass.includes('elementor-control-element_pack_'+widgetShortName+'_section') || controlClass.includes('elementor-control elementor-control-section_element_pack_'+widgetShortName+'_controls') || controlClass.includes('elementor-control elementor-control-element_pack_'+widgetShortName+'_section')) { $node.remove(); // Add CSS to prevent re-appearance var cssRule = '.' + $node.attr('class').replace(/\s+/g, '.') + ' { display: none !important; }'; if (!$('#ep-aggressive-control-hide').length) { $('head').append(''); } $('#ep-aggressive-control-hide').append(cssRule); break; } } } } } }); } }); }); // Start the aggressive observer if (controlPanel) { aggressiveControlObserver.observe(controlPanel, { childList: true, subtree: true }); } } // Handle search input events - target the correct search field $(document).on('input', '#elementor-panel-elements-search-input', function() { // Prevent restricted widgets from appearing in search var searchValue = $(this).val().toLowerCase(); var restrictedWidgets = ElementorRestrictedWidgets.getRestrictedWidgets(); if (restrictedWidgets && restrictedWidgets.length > 0) { // Check if search term matches any restricted widget var isSearchingForRestricted = restrictedWidgets.some(function(widget) { return searchValue.includes(widget.replace('bdt-', '').toLowerCase()); }); if (isSearchingForRestricted) { // Clear the search to prevent restricted widgets from showing $(this).val(''); return; } } // Use a more aggressive approach - remove widgets immediately and continuously function aggressiveRemove() { var $searchResults = $('#elementor-panel-elements .elementor-element-wrapper'); $searchResults.each(function() { var $widget = $(this); var $icon = $widget.find('[class*="bdt-wi-"]'); if ($icon.length) { var widgetName = null; $icon.each(function () { var iconClass = $(this).attr('class'); if (iconClass) { var iconMatch = iconClass.match(/bdt-wi-([^\s]+)/); if (iconMatch) { widgetName = 'bdt-' + iconMatch[1]; } } }); if (widgetName && restrictedWidgets.indexOf(widgetName) !== -1) { $widget.remove(); } } }); } // Remove immediately and then continuously aggressiveRemove(); setTimeout(aggressiveRemove, 10); setTimeout(aggressiveRemove, 50); setTimeout(aggressiveRemove, 100); setTimeout(aggressiveRemove, 200); }); // Handle search results when they appear $(document).on('DOMNodeInserted', '.elementor-panel-elements-search-wrapper', function() { ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch(); // Immediate removal setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch.bind(ElementorRestrictedWidgets), 50); // Quick follow-up }); // Handle when search is cleared $(document).on('click', '.elementor-panel-elements-search-wrapper .elementor-panel-elements-search-input-clear', function() { ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch(); // Immediate removal setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch.bind(ElementorRestrictedWidgets), 50); // Quick follow-up }); // Also handle keyup events for search $(document).on('keyup', '#elementor-panel-elements-search-input', function() { ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch(); // Immediate removal setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch.bind(ElementorRestrictedWidgets), 50); // Quick follow-up }); // Handle search focus events $(document).on('focus', '#elementor-panel-elements-search-input', function() { ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch(); // Immediate removal setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch.bind(ElementorRestrictedWidgets), 50); // Quick follow-up }); // Handle changes in the search panel specifically $(document).on('DOMNodeInserted', '#elementor-panel-elements', function() { ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch(); // Immediate removal setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch.bind(ElementorRestrictedWidgets), 50); // Quick follow-up }); // Also handle when the search panel is updated $(document).on('DOMSubtreeModified', '#elementor-panel-elements', function() { ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch(); // Immediate removal setTimeout(ElementorRestrictedWidgets.hideRestrictedWidgetsFromSearch.bind(ElementorRestrictedWidgets), 50); // Quick follow-up }); // More aggressive approach - remove widgets immediately when they appear in search panel $(document).on('DOMNodeInserted', '#elementor-panel-elements .elementor-element-wrapper', function() { var $widget = $(this); var $icon = $widget.find('[class*="bdt-wi-"]'); if ($icon.length) { // Extract widget name from icon class var widgetName = null; $icon.each(function () { var iconClass = $(this).attr('class'); if (iconClass) { var iconMatch = iconClass.match(/bdt-wi-([^\s]+)/); if (iconMatch) { widgetName = 'bdt-' + iconMatch[1]; } } }); if (widgetName) { var restrictedWidgets = ElementorRestrictedWidgets.getRestrictedWidgets(); var isRestricted = restrictedWidgets && restrictedWidgets.indexOf(widgetName) !== -1; if (isRestricted) { $widget.remove(); } } } }); // Even more aggressive - monitor all DOM changes in search panel var searchObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach(function(node) { if (node.nodeType === 1) { // Element node var $node = $(node); if ($node.hasClass('elementor-element-wrapper')) { var $icon = $node.find('[class*="bdt-wi-"]'); if ($icon.length) { var widgetName = null; $icon.each(function () { var iconClass = $(this).attr('class'); if (iconClass) { var iconMatch = iconClass.match(/bdt-wi-([^\s]+)/); if (iconMatch) { widgetName = 'bdt-' + iconMatch[1]; } } }); if (widgetName) { var restrictedWidgets = ElementorRestrictedWidgets.getRestrictedWidgets(); var isRestricted = restrictedWidgets && restrictedWidgets.indexOf(widgetName) !== -1; if (isRestricted) { $node.remove(); } } } } } }); } }); }); // Start observing the search panel var searchPanel = document.querySelector('#elementor-panel-elements'); if (searchPanel) { searchObserver.observe(searchPanel, { childList: true, subtree: true }); } // Also observe the search wrapper var searchWrapper = document.querySelector('.elementor-panel-elements-search-wrapper'); if (searchWrapper) { searchObserver.observe(searchWrapper, { childList: true, subtree: true }); } }, setupSearchMonitoring: function() { // Monitor the search panel for any changes var searchPanel = document.querySelector('#elementor-panel-elements'); if (searchPanel) { var searchObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.type === 'childList') { mutation.addedNodes.forEach(function(node) { if (node.nodeType === 1) { // Element node var $node = $(node); if ($node.hasClass('elementor-element-wrapper')) { // Check if this is a restricted widget var $icon = $node.find('[class*="bdt-wi-"]'); if ($icon.length) { var widgetName = null; $icon.each(function () { var iconClass = $(this).attr('class'); if (iconClass) { var iconMatch = iconClass.match(/bdt-wi-([^\s]+)/); if (iconMatch) { widgetName = 'bdt-' + iconMatch[1]; } } }); if (widgetName) { var restrictedWidgets = ElementorRestrictedWidgets.getRestrictedWidgets(); var isRestricted = restrictedWidgets && restrictedWidgets.indexOf(widgetName) !== -1; if (isRestricted) { $node.remove(); } } } } } }); } }); }); searchObserver.observe(searchPanel, { childList: true, subtree: true }); } }, addCSSRules: function() { // Add CSS to hide restricted widgets immediately var style = document.createElement('style'); style.textContent = ` #elementor-panel-elements .elementor-element-wrapper[data-widget_type*="bdt-"] { transition: none !important; } #elementor-panel-elements .elementor-element-wrapper[data-widget_type*="bdt-"]:has([class*="bdt-wi-"]) { display: none !important; } `; document.head.appendChild(style); // Also add a more aggressive CSS rule for restricted widgets var restrictedWidgets = ElementorRestrictedWidgets.getRestrictedWidgets(); if (restrictedWidgets && restrictedWidgets.length > 0) { var restrictedWidgetsArray = Array.isArray(restrictedWidgets) ? restrictedWidgets : Object.values(restrictedWidgets); var cssRules = ''; restrictedWidgetsArray.forEach(function(widget) { cssRules += `#elementor-panel-elements .elementor-element-wrapper[data-widget_type="${widget}"] { display: none !important; }\n`; }); var restrictedStyle = document.createElement('style'); restrictedStyle.textContent = cssRules; document.head.appendChild(restrictedStyle); } // Add CSS to hide restricted control sections var restrictedWidgets = ElementorRestrictedWidgets.getRestrictedWidgets(); if (restrictedWidgets && restrictedWidgets.length > 0) { var restrictedWidgetsArray = Array.isArray(restrictedWidgets) ? restrictedWidgets : Object.values(restrictedWidgets); var controlCSSRules = ''; restrictedWidgetsArray.forEach(function(widget) { var widgetShortName = widget.replace('bdt-', ''); controlCSSRules += ` .elementor-control.elementor-control-section_element_pack_${widgetShortName}_controls, .elementor-control.elementor-control-element_pack_${widgetShortName}_section, .elementor-control[class*="elementor-control-section_element_pack_${widgetShortName}_controls"], .elementor-control[class*="elementor-control-element_pack_${widgetShortName}_section"] { display: none !important; visibility: hidden !important; opacity: 0 !important; height: 0 !important; overflow: hidden !important; } `; }); var controlStyle = document.createElement('style'); controlStyle.textContent = controlCSSRules; controlStyle.id = 'ep-restricted-controls-css'; document.head.appendChild(controlStyle); } }, hideExtensionControlSections: function() { $('.bdt-ep-restricted-badge').closest('.elementor-control').remove(); }, getRestrictedWidgets: function() { // For admin pages, we'll get this from PHP via global variable if (typeof window.epRestrictedWidgets !== 'undefined') { var widgets = window.epRestrictedWidgets; // Ensure we return an array if (widgets && widgets.restricted_widgets) { return Array.isArray(widgets.restricted_widgets) ? widgets.restricted_widgets : Object.values(widgets.restricted_widgets); } return []; } // For Elementor editor if (typeof elementorFrontend !== 'undefined' && elementorFrontend.config.ep_role_filters) { var widgets = elementorFrontend.config.ep_role_filters.restricted_widgets; return Array.isArray(widgets) ? widgets : []; } // Default fallback return []; }, }; // Initialize Elementor Restricted Widgets when document is ready $(document).ready(function() { ElementorRestrictedWidgets.init(); }); // Make ElementorRestrictedWidgets available globally window.ElementorRestrictedWidgets = ElementorRestrictedWidgets; })(jQuery);