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
288 lines
No EOL
9.3 KiB
JavaScript
288 lines
No EOL
9.3 KiB
JavaScript
/**
|
|
* HVAC Menu System JavaScript - Safari Compatible Version
|
|
* Handle dropdown interactions and mobile menu behavior
|
|
*/
|
|
|
|
(function($) {
|
|
'use strict';
|
|
|
|
/**
|
|
* Initialize menu system
|
|
*/
|
|
function initHVACMenu() {
|
|
var $menu = $('.hvac-trainer-menu');
|
|
|
|
if (!$menu.length) {
|
|
return;
|
|
}
|
|
|
|
// Handle dropdown toggles
|
|
handleDropdownToggles($menu);
|
|
|
|
// Handle mobile menu
|
|
handleMobileMenu($menu);
|
|
|
|
// Handle keyboard navigation
|
|
handleKeyboardNavigation($menu);
|
|
|
|
// Close dropdowns when clicking outside
|
|
handleOutsideClick($menu);
|
|
|
|
// Set active menu items
|
|
setActiveMenuItem($menu);
|
|
}
|
|
|
|
/**
|
|
* Handle dropdown toggle functionality
|
|
*/
|
|
function handleDropdownToggles($menu) {
|
|
$menu.on('click', '.hvac-menu-item.has-submenu > a', function(e) {
|
|
e.preventDefault();
|
|
|
|
var $menuItem = $(this).parent();
|
|
var $submenu = $menuItem.find('.hvac-submenu');
|
|
var isOpen = $menuItem.hasClass('open');
|
|
|
|
// Close all other open dropdowns
|
|
$menu.find('.hvac-menu-item.open').removeClass('open');
|
|
$menu.find('.hvac-submenu').slideUp(200);
|
|
|
|
// Toggle current dropdown
|
|
if (!isOpen) {
|
|
$menuItem.addClass('open');
|
|
$submenu.slideDown(200);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle mobile menu functionality
|
|
*/
|
|
function handleMobileMenu($menu) {
|
|
var $mobileToggle = $('.hvac-mobile-menu-toggle');
|
|
var $mobileMenu = $('.hvac-mobile-menu');
|
|
|
|
if (!$mobileToggle.length || !$mobileMenu.length) {
|
|
return;
|
|
}
|
|
|
|
$mobileToggle.on('click', function(e) {
|
|
e.preventDefault();
|
|
|
|
var isOpen = $mobileMenu.hasClass('open');
|
|
|
|
if (isOpen) {
|
|
$mobileMenu.removeClass('open');
|
|
$mobileToggle.removeClass('active');
|
|
$('body').removeClass('mobile-menu-open');
|
|
} else {
|
|
$mobileMenu.addClass('open');
|
|
$mobileToggle.addClass('active');
|
|
$('body').addClass('mobile-menu-open');
|
|
}
|
|
});
|
|
|
|
// Close mobile menu when clicking on overlay
|
|
$mobileMenu.on('click', '.hvac-mobile-overlay', function() {
|
|
$mobileMenu.removeClass('open');
|
|
$mobileToggle.removeClass('active');
|
|
$('body').removeClass('mobile-menu-open');
|
|
});
|
|
|
|
// Handle mobile submenu toggles
|
|
$mobileMenu.on('click', '.hvac-menu-item.has-submenu > a', function(e) {
|
|
var $menuItem = $(this).parent();
|
|
var $submenu = $menuItem.find('.hvac-submenu');
|
|
var isOpen = $menuItem.hasClass('open');
|
|
|
|
// Only prevent default for items with submenus
|
|
if ($submenu.length > 0) {
|
|
e.preventDefault();
|
|
|
|
if (isOpen) {
|
|
$menuItem.removeClass('open');
|
|
$submenu.slideUp(200);
|
|
} else {
|
|
$menuItem.addClass('open');
|
|
$submenu.slideDown(200);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle keyboard navigation
|
|
*/
|
|
function handleKeyboardNavigation($menu) {
|
|
$menu.on('keydown', 'a', function(e) {
|
|
var $currentLink = $(this);
|
|
var $currentItem = $currentLink.parent();
|
|
var $allLinks = $menu.find('a');
|
|
var currentIndex = $allLinks.index($currentLink);
|
|
var $targetLink;
|
|
|
|
switch (e.keyCode) {
|
|
case 27: // Escape key
|
|
// Close dropdown and return to parent
|
|
if ($currentItem.hasClass('hvac-submenu-item')) {
|
|
var $parentItem = $currentItem.closest('.hvac-menu-item.has-submenu');
|
|
$parentItem.removeClass('open');
|
|
$parentItem.find('.hvac-submenu').slideUp(200);
|
|
$parentItem.find('> a').focus();
|
|
}
|
|
break;
|
|
|
|
case 38: // Up arrow
|
|
e.preventDefault();
|
|
if (currentIndex > 0) {
|
|
$targetLink = $allLinks.eq(currentIndex - 1);
|
|
$targetLink.focus();
|
|
}
|
|
break;
|
|
|
|
case 40: // Down arrow
|
|
e.preventDefault();
|
|
if (currentIndex < $allLinks.length - 1) {
|
|
$targetLink = $allLinks.eq(currentIndex + 1);
|
|
$targetLink.focus();
|
|
}
|
|
break;
|
|
|
|
case 13: // Enter key
|
|
case 32: // Space key
|
|
if ($currentItem.hasClass('has-submenu')) {
|
|
e.preventDefault();
|
|
$currentLink.click();
|
|
}
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Close dropdowns when clicking outside
|
|
*/
|
|
function handleOutsideClick($menu) {
|
|
$(document).on('click', function(e) {
|
|
if (!$menu.is(e.target) && $menu.has(e.target).length === 0) {
|
|
$menu.find('.hvac-menu-item.open').removeClass('open');
|
|
$menu.find('.hvac-submenu').slideUp(200);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Set active menu item based on current URL
|
|
*/
|
|
function setActiveMenuItem($menu) {
|
|
var currentPath = window.location.pathname;
|
|
|
|
$menu.find('a').each(function() {
|
|
var $link = $(this);
|
|
var linkHref = $link.attr('href');
|
|
|
|
if (linkHref && currentPath.indexOf(linkHref.replace(window.location.origin, '')) !== -1) {
|
|
$link.addClass('current-page');
|
|
|
|
// Also mark parent menu item as active if this is a submenu item
|
|
var $parentMenuItem = $link.closest('.hvac-menu-item.has-submenu');
|
|
if ($parentMenuItem.length) {
|
|
$parentMenuItem.find('> a').addClass('current-parent');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle responsive menu behavior
|
|
*/
|
|
function handleResponsiveMenu() {
|
|
var $window = $(window);
|
|
var $menu = $('.hvac-trainer-menu');
|
|
var breakpoint = 768;
|
|
|
|
function checkMenuLayout() {
|
|
var windowWidth = $window.width();
|
|
|
|
if (windowWidth < breakpoint) {
|
|
$menu.addClass('mobile-layout');
|
|
// Close any open desktop dropdowns
|
|
$menu.find('.hvac-menu-item.open').removeClass('open');
|
|
$menu.find('.hvac-submenu').hide();
|
|
} else {
|
|
$menu.removeClass('mobile-layout');
|
|
// Close mobile menu if open
|
|
$('.hvac-mobile-menu').removeClass('open');
|
|
$('.hvac-mobile-menu-toggle').removeClass('active');
|
|
$('body').removeClass('mobile-menu-open');
|
|
}
|
|
}
|
|
|
|
// Check on resize
|
|
$window.on('resize', debounce(checkMenuLayout, 250));
|
|
|
|
// Check initially
|
|
checkMenuLayout();
|
|
}
|
|
|
|
/**
|
|
* Debounce function for performance
|
|
*/
|
|
function debounce(func, wait) {
|
|
var timeout;
|
|
return function() {
|
|
var context = this;
|
|
var args = arguments;
|
|
var later = function() {
|
|
timeout = null;
|
|
func.apply(context, args);
|
|
};
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(later, wait);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Handle help menu positioning
|
|
*/
|
|
function handleHelpMenuPositioning() {
|
|
var $helpMenu = $('.hvac-help-menu');
|
|
|
|
if (!$helpMenu.length) {
|
|
return;
|
|
}
|
|
|
|
$helpMenu.on('click', '.hvac-menu-item.has-submenu > a', function() {
|
|
var $submenu = $(this).siblings('.hvac-submenu');
|
|
var $menuContainer = $(this).closest('.hvac-trainer-menu');
|
|
|
|
if ($submenu.length && $menuContainer.length) {
|
|
// Adjust position if submenu would go off-screen
|
|
setTimeout(function() {
|
|
var submenuOffset = $submenu.offset();
|
|
var submenuWidth = $submenu.outerWidth();
|
|
var windowWidth = $(window).width();
|
|
|
|
if (submenuOffset.left + submenuWidth > windowWidth) {
|
|
$submenu.addClass('align-right');
|
|
} else {
|
|
$submenu.removeClass('align-right');
|
|
}
|
|
}, 10);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Initialize when DOM is ready
|
|
$(document).ready(function() {
|
|
initHVACMenu();
|
|
handleResponsiveMenu();
|
|
handleHelpMenuPositioning();
|
|
});
|
|
|
|
// Re-initialize if content is dynamically loaded
|
|
$(document).on('hvac-menu-refresh', function() {
|
|
initHVACMenu();
|
|
});
|
|
|
|
})(jQuery); |