upskill-event-manager/assets/js/single-product-gallery.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

120 lines
No EOL
4.7 KiB
JavaScript

document.addEventListener("DOMContentLoaded", function () {
triggerFirstSlide();
triggerGalleryImageMutation();
});
function triggerFirstSlide() {
const sliderTrigger = document.querySelector(
".woocommerce-product-gallery-thumbnails__wrapper div"
);
const variationWrap = jQuery(".single_variation_wrap");
if (variationWrap && sliderTrigger) {
variationWrap.on("show_variation", function (event, variation) {
sliderTrigger.click();
});
}
}
/**
* Function to change the gallery's first image to current selected variation image
*/
function triggerGalleryImageMutation() {
const mainImageElement = document.querySelector(
".woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image img"
);
if (!mainImageElement) {
return;
}
const defaultImageAttributes =
mainImageElement
?.getAttributeNames()
.map((name) => ({ name, value: mainImageElement.getAttribute(name) })) ||
[];
defaultImageAttributes.push({ name: "srcset", value: "" });
const verticalGallery = document.querySelector("#ast-vertical-slider-inner");
const prevButton = document.querySelector("#ast-vertical-navigation-prev");
const nextButton = document.querySelector("#ast-vertical-navigation-next");
// Flag to prevent multiple observer processing.
let isObserverProcessing = false;
const observer = new MutationObserver((mutationsList) => {
for (let mutation of mutationsList) {
if (mutation.type === "attributes" && mutation.attributeName === "src") {
// Bail early if we're in the middle of observer processing.
if (isObserverProcessing) {
return;
}
// Start observer processing.
isObserverProcessing = true;
const selectedVariationImageSrc = mutation.target?.getAttribute("src");
const galleryImages = document.querySelectorAll(
".woocommerce-product-gallery-thumbnails__wrapper .ast-woocommerce-product-gallery__image"
);
const mutatedImgSrc = mutation.target?.getAttribute("data-src");
let foundInGallery = false;
// Skipping the first image as it's the featured image, and starting the loop from the second image from where gallery images starts.
for (let i = 1; i < galleryImages.length; i++) {
const imageWrapper = galleryImages[i];
const image = imageWrapper?.querySelector("img");
if (!image) continue;
const galleryImgSrc = image?.getAttribute("data-original-src");
const imageFound = mutatedImgSrc === galleryImgSrc;
if (imageFound) {
foundInGallery = true;
observer.disconnect();
defaultImageAttributes.forEach(({ name, value }) =>
mainImageElement?.setAttribute(name, value)
);
setTimeout(() => {
imageWrapper?.click();
if (verticalGallery && typeof MoveSlide === "function") {
const imageHeight = image.clientHeight + 10;
verticalGallery?.setAttribute(
"ast-translate",
(i - 4) * imageHeight
);
MoveSlide("next", prevButton, nextButton);
}
isObserverProcessing = false;
observer.observe(mainImageElement, { attributes: true });
}, 50);
break;
}
}
if (!foundInGallery) {
observer.disconnect();
if (galleryImages[0]) {
const img = galleryImages[0]
img?.querySelector("img")?.setAttribute("src", selectedVariationImageSrc);
img?.querySelector("img")?.setAttribute("data-original-src", mutatedImgSrc);
}
if (verticalGallery && typeof MoveSlide === "function") {
MoveSlide("prev", prevButton, nextButton);
}
setTimeout( () => ( isObserverProcessing = false ) );
observer.observe(mainImageElement, { attributes: true });
}
}
}
});
// Start observing changes to the 'src' attribute of the main image element.
mainImageElement && observer.observe(mainImageElement, { attributes: true });
}