/** * CommerceKit Floating Cart – frontend script * * Responsibilities: * 1. Open the CommerceKit / Shoptimizer minicart when the floating button is clicked. * 2. Automatically open the minicart after a successful add-to-cart (AJAX or standard). * 3. Play a small badge-bump animation when the item count changes. * * All selectors and feature flags come from the `cgkitFC` object localised by PHP. */ ( function ( $ ) { 'use strict'; /* ----------------------------------------------------------------------- * Module * --------------------------------------------------------------------- */ var FloatingCart = { $btn: null, $count: null, prevCount: 0, /** Bootstrap */ init: function () { if ( typeof cgkitFC === 'undefined' ) { return; } this.$btn = $( '#cgkit-floating-cart .cgkit-floating-cart__btn' ); this.$count = $( '#cgkit-fc-count' ); if ( ! this.$btn.length ) { return; } this.prevCount = parseInt( this.$count.text(), 10 ) || 0; this.bindEvents(); }, /** Attach event listeners */ bindEvents: function () { var self = this; // --- Floating button click → open minicart ----------------------- this.$btn.on( 'click', function ( e ) { e.preventDefault(); self.openMinicart(); } ); // --- Auto-open after AJAX add-to-cart ---------------------------- if ( cgkitFC.autoOpen === 'yes' ) { $( document.body ).on( 'added_to_cart', function () { setTimeout( function () { self.openMinicart(); self.pulseBtn(); }, parseInt( cgkitFC.autoOpenDelay, 10 ) || 400 ); } ); } // --- Badge bump when WooCommerce refreshes fragments ------------- $( document.body ).on( 'wc_fragments_refreshed wc_fragments_loaded', function () { self.maybeBumpBadge(); } ); }, /** * Trigger the theme's minicart open mechanism. * * Strategy (stops at the first approach that succeeds): * 1. Find the header cart button via the configured selector list and * fire ONE native click on it. Using native click (not jQuery trigger * + native) avoids the double-fire / toggle-closed bug. * 2. If no button is found, try to show the Shoptimizer cart panel * directly by toggling the body class the theme uses. * 3. Last resort: navigate to the cart URL. * * NOTE: never call both $el.trigger('click') AND el.click() — that * fires two events and the toggle cancels itself immediately. */ openMinicart: function () { // --- 1. Try clicking the configured header cart button ------------ var selectors = ( cgkitFC.minicartTrigger || '' ).split( ',' ); for ( var i = 0; i < selectors.length; i++ ) { var $el = $( $.trim( selectors[ i ] ) ).first(); if ( $el.length ) { // One native click – reaches both jQuery and native listeners. $el[ 0 ].click(); return; } } // --- 2. Shoptimizer direct panel toggle -------------------------- // Shoptimizer's cart anchor is a.cart-contents inside .shoptimizer-cart. // If the selector loop above somehow missed it, grab it directly. var $directBtn = $( '.shoptimizer-cart a.cart-contents' ); if ( $directBtn.length ) { $directBtn[ 0 ].click(); return; } // --- 3. Fall back to cart page ----------------------------------- if ( cgkitFC.cartUrl ) { window.location.href = cgkitFC.cartUrl; } }, /** * Add a pulse ring on the button after add-to-cart. */ pulseBtn: function () { var self = this; this.$btn.addClass( 'cgkit-fc--pulse' ); setTimeout( function () { self.$btn.removeClass( 'cgkit-fc--pulse' ); }, 600 ); }, /** * If the item count increased, animate the badge. */ maybeBumpBadge: function () { var $freshCount = $( '#cgkit-fc-count' ); // Re-query in case the fragment replaced the element. if ( ! $freshCount.length ) { return; } this.$count = $freshCount; var newCount = parseInt( this.$count.text(), 10 ) || 0; if ( newCount !== this.prevCount ) { this.prevCount = newCount; this.$count.removeClass( 'cgkit-floating-cart__count--bump' ); // Force reflow so removing + re-adding the class restarts the animation. void this.$count[ 0 ].offsetWidth; // eslint-disable-line no-unused-expressions this.$count.addClass( 'cgkit-floating-cart__count--bump' ); } } }; /* ----------------------------------------------------------------------- * Boot * --------------------------------------------------------------------- */ $( document ).ready( function () { FloatingCart.init(); } ); } )( jQuery );