upskill-event-manager/assets/js/megamenu-options.js
Ben Reed cdc5ea85f4 feat: Add comprehensive CSS, JavaScript and theme asset infrastructure
Add massive collection of CSS, JavaScript and theme assets that were previously excluded:

**CSS Files (681 total):**
- HVAC plugin-specific styles (hvac-*.css): 34 files including dashboard, certificates, registration, mobile nav, accessibility fixes, animations, and welcome popup
- Theme framework files (Astra, builder systems, layouts): 200+ files
- Plugin compatibility styles (WooCommerce, WPForms, Elementor, Contact Form 7): 150+ files
- WordPress core and editor styles: 50+ files
- Responsive and RTL language support: 200+ files

**JavaScript Files (400+ total):**
- HVAC plugin functionality (hvac-*.js): 27 files including menu systems, dashboard enhancements, profile sharing, mobile responsive features, accessibility, and animations
- Framework and library files: jQuery plugins, GSAP, AOS, Swiper, Chart.js, Lottie, Isotope
- Plugin compatibility scripts: WPForms, WooCommerce, Elementor, Contact Form 7, LifterLMS
- WordPress core functionality: customizer, admin, block editor compatibility
- Third-party integrations: Stripe, SMTP, analytics, search functionality

**Assets:**
- Certificate background images and logos
- Comprehensive theme styling infrastructure
- Mobile-responsive design systems
- Cross-browser compatibility assets
- Performance-optimized minified versions

**Updated .gitignore:**
- Fixed asset directory whitelisting patterns to properly include CSS/JS/images
- Added proper directory structure recognition (!/assets/css/, !/assets/js/, etc.)
- Maintains security by excluding sensitive files while including essential assets

This commit provides the complete frontend infrastructure needed for:
- Full theme functionality and styling
- Plugin feature implementations
- Mobile responsiveness and accessibility
- Cross-browser compatibility
- Performance optimization
- Developer workflow support
2025-08-11 16:20:31 -03:00

286 lines
7.8 KiB
JavaScript

document.addEventListener("DOMContentLoaded", () => {
//click event for menu settings button.
menuSettingsEventClick();
});
function menuSettingsEventClick() {
const offCanvasSection = document.querySelector(".ast-offcanvas-wrapper");
document.addEventListener("click", function (event) {
if (event.target.matches(".astra-megamenu-opts-btn")) {
const menuDepth = event.target.closest(".menu-item").classList.value;
if (menuDepth.includes('menu-item-depth-')) {
const menuDeptId = menuDepth.split('menu-item-depth-')[1].split('')[0];
const menuName = event.target.getAttribute("data-menu-title");
const menuId = event.target.getAttribute("data-menu-id");
const navId = document
.querySelector("#nav-menu-meta-object-id")
.getAttribute("value");
if (menuDeptId && menuName && menuId && navId) {
document.dispatchEvent(
new CustomEvent("astra_mega_menu_event", {
detail: {
menu_depth: menuDeptId,
menu_name: menuName,
menu_id: menuId,
navId: navId,
},
})
);
if (!offCanvasSection.classList.contains("active")) {
offCanvasSection.classList.add("active");
}
}
}
}
});
}
function onColorReady() {
jQuery(document).mouseup(function (e) {
var container = jQuery('.ast-color');
var colorWrap = container.find('.astra-color-picker-wrap');
var resetBtnWrap = container.find('.ast-color-btn-reset-wrap');
// If the target of the click isn't the container nor a descendant of the container.
if (!colorWrap.is(e.target) && !resetBtnWrap.is(e.target) && colorWrap.has(e.target).length === 0 && resetBtnWrap.has(e.target).length === 0) {
container.find('.components-button.astra-color-icon-indicate.open').click();
}
});
}
// Old code modified to work with current implementation.
(function ($) {
const abortController = { current: null };
document.addEventListener("astra_mega_menu_loaded", function (event) {
renderSavedWidgets(event.detail.menu_id);
select2Init();
onColorReady();
});
// This event listener is triggered when the mega menu is unmounted.
// It checks if there's an ongoing request and aborts it if found.
document.addEventListener( 'astra_mega_menu_unmounted', () => {
if ( abortController.current ) {
abortController.current?.abort();
}
} );
document.addEventListener("astra_mega_menu_widget_event", function (event) {
dropWidget(event.detail.menu_id);
});
function dropWidget(menuid) {
var widget_id = $(".ast-select-widget").val();
var container = $(".astra-mm-options-wrap");
var menu_item_id = menuid;
if ("" == widget_id) {
return;
}
$(".ast-widget-list").show();
var data = {
action: "ast_add_widget",
widget_id: widget_id,
menu_item_id: menu_item_id,
title: $(".ast-select-widget").find("option:selected").text(),
security_nonce: AstraBuilderMegaMenu.nonceWidget,
};
$.post(ajaxurl, data, function (response) {
var widget_html = $(response.data);
widget_html?.each((_, element) => container.find(".ast-widget-list").append(DOMPurify.sanitize(element)));
$(".widget-action").off();
$(".widget-action").on("click", editWidget);
$("#mega-menu-submit").removeClass('ast-disabled');
});
}
function renderSavedWidgets( menu_item_id ) {
const container = $( '.astra-mm-options-wrap' );
// Abort any ongoing request before starting a new one.
if ( abortController.current ) {
abortController.current?.abort();
}
// Create a new AbortController for this request.
abortController.current = new AbortController();
const data = {
action: 'ast_render_widgets',
menu_item_id: menu_item_id,
security_nonce: AstraBuilderMegaMenu.nonceWidget,
};
// Convert data to URL-encoded format
const params = new URLSearchParams( data ).toString();
// Using fetch instead of $.post() to make use of the AbortController.
fetch( ajaxurl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params,
signal: abortController.current?.signal,
} )
.then( ( response ) => {
if ( ! response.ok ) {
throw new Error( 'Network response was not ok!' );
}
return response.json();
} )
.then( ( response ) => {
const widgetHTML = response.data.html;
const hasWidgets = response.data.has_widgets;
if ( hasWidgets ) {
$( '.ast-widget-list' ).show();
}
container.find( '.ast-widget-list' ).html( DOMPurify.sanitize( widgetHTML ) );
$( '#ast-widget-sortable' ).sortable( {
change: function ( event, ui ) {
$( '#mega-menu-submit' ).removeClass( 'ast-disabled' );
},
} );
$( '#ast-widget-sortable' ).disableSelection();
$( '.widget-action' ).off();
$( '.widget-action' ).on( 'click', editWidget );
} )
.catch( ( error ) => {
if ( error.name === 'AbortError' ) {
return;
}
console.error( 'Fetch error: ', error );
} );
}
function editWidget() {
var widget = $(this).closest(".widget");
var widget_inner = widget.find(".widget-inner");
var id = widget.attr("id");
widget.toggleClass("menu-item-edit-active");
var data = {
action: "ast_edit_widget",
widget_id: id,
security_nonce: AstraBuilderMegaMenu.nonceWidget,
};
if (!widget.hasClass("open") && !widget.data("loaded")) {
$.post(ajaxurl, data, function (response) {
// Configure DOMPurify to allow the name="action" attribute on input elements.
DOMPurify.addHook('afterSanitizeAttributes', (node) => {
if (node.nodeName === 'INPUT' && node?.hasAttribute('value') && node?.getAttribute('value') === 'ast_save_widget') {
node?.setAttribute('name', 'action');
}
});
widget_inner.html(DOMPurify.sanitize(response.data));
widget.data("loaded", true).toggleClass("open");
// Init Black Studio TinyMCE
if (widget.is("[id*=black-studio-tinymce]")) {
bstw(widget).deactivate().activate();
}
setTimeout(function () {
$(document).trigger("widget-added", [widget]);
}, 100);
// bind delete button action
widget.find(".delete").on("click", function (e) {
e.preventDefault();
var data = {
action: "ast_delete_widget",
widget_id: id,
security_nonce: AstraBuilderMegaMenu.nonceWidget,
};
$.post(ajaxurl, data, function (delete_response) {
widget.remove();
$("#mega-menu-submit").removeClass('ast-disabled');
});
});
widget.find(".close").on("click", function (e) {
e.preventDefault();
widget.toggleClass("open");
});
widget.find(".ast-save-widget").on("click", function (e) {
e.preventDefault();
var data = widget.find("form").serialize();
var $button = $(this);
$button.attr("disabled", "disabled");
widget.find(".spinner").css("visibility", "visible");
$.post(ajaxurl, data, function (submit_response) {
widget.find(".spinner").css("visibility", "hidden");
$button.removeAttr("disabled");
$("#mega-menu-submit").removeClass('ast-disabled');
});
});
});
} else {
widget.toggleClass("open");
}
}
function select2Init() {
$(".astra-mm-options-wrap")
.find(".ast-select2-container")
.astselect2({
placeholder: astMegamenuVars.select2_placeholder,
ajax: {
url: ajaxurl,
dataType: "json",
method: "post",
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page,
action: "ast_get_posts_list",
nonce: astRules.ajax_nonce,
};
},
processResults: function (data) {
// parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to
// alter the remote JSON data
$("#mega-menu-submit").removeClass('ast-disabled');
return {
results: data,
};
},
cache: true,
},
minimumInputLength: 2,
language: astRules.ast_lang,
});
}
})(jQuery);