Linux heracles.o2switch.net 4.18.0-553.62.1.lve.el8.x86_64 #1 SMP Mon Jul 21 17:50:35 UTC 2025 x86_64
/
home
/
ophq1335
/
www
/
wp-content
/
plugins
/
wp-seopress
/
assets
/
js
/
//home/ophq1335/www/wp-content/plugins/wp-seopress/assets/js/seopress-promotions.js
/** * SEOPress Promotions JavaScript * * Handles dismissal functionality and modal interactions for the promotions system. * * @package SEOPress * @since 9.6.0 */ (function($) { 'use strict'; /** * SEOPress Promotions module. */ var SEOPressPromotions = { /** * Initialize the module. */ init: function() { this.bindEvents(); this.initModal(); }, /** * Bind event handlers. */ bindEvents: function() { // Dismiss promotion buttons. $(document).on('click', '.promo-dismiss', this.handleDismiss); // Track CTA clicks. $(document).on('click', '.promo-cta', this.handleCtaClick); // Toggle all promotions. $(document).on('change', '#seopress-toggle-promotions', this.handleToggleAll); // Modal dismiss button. $(document).on('click', '[data-dismiss="license-modal"]', this.handleModalDismiss); // Close modal on overlay click. $(document).on('click', '.seopress-modal-overlay', this.handleOverlayClick); }, /** * Handle promotion dismissal. * * @param {Event} e Click event. */ handleDismiss: function(e) { e.preventDefault(); e.stopPropagation(); var $button = $(this); var $promo = $button.closest('.seopress-promo-banner, .seopress-promo-card, .seopress-metabox-promo-banner, .seopress-contextual-promo'); var promoId = $button.data('promo-id') || $promo.data('promo-id'); var duration = $button.data('dismiss-duration') || 30; if (!promoId) { console.warn('SEOPress Promotions: No promo ID found for dismissal.'); return; } // Disable button and show loading state. $button.prop('disabled', true).css('opacity', '0.5'); // Track dismissal stats (fire and forget). SEOPressPromotions.trackStat(promoId, 'dismiss'); // Send AJAX request to store dismissal locally. $.ajax({ url: ajaxurl, type: 'POST', data: { action: 'seopress_dismiss_promotion', promo_id: promoId, duration: duration, _ajax_nonce: seopressPromotions.dismiss_nonce }, success: function(response) { if (response.success) { // Check if this is the top banner. var isTopBanner = $promo.hasClass('seopress-promo-banner'); // Animate out and remove. $promo.slideUp(300, function() { $(this).remove(); // Remove body class if top banner was dismissed. if (isTopBanner) { $('body').removeClass('has-promo-banner'); } // Check if promotions panel is now empty. var $panel = $('#seopress-promotions-panel'); if ($panel.length && $panel.find('.seopress-promo-card').length === 0 && $panel.find('.affiliate-card').length === 0) { $panel.slideUp(300, function() { $(this).remove(); }); } }); } else { // Re-enable button on error. $button.prop('disabled', false).css('opacity', '1'); console.error('SEOPress Promotions: Failed to dismiss promotion.', response); } }, error: function(xhr, status, error) { // Re-enable button on error. $button.prop('disabled', false).css('opacity', '1'); console.error('SEOPress Promotions: AJAX error.', error); } }); }, /** * Handle CTA button click - track before navigating. * * @param {Event} e Click event. */ handleCtaClick: function(e) { var $link = $(this); var $promo = $link.closest('.seopress-promo-banner, .seopress-promo-card, .seopress-metabox-promo-banner, .seopress-contextual-promo'); var promoId = $promo.data('promo-id'); if (!promoId) { return; // Let click proceed normally. } // Track click stat (fire and forget - don't block navigation). SEOPressPromotions.trackStat(promoId, 'click'); }, /** * Send stat to remote API. * * @param {string} promoId Promotion ID. * @param {string} action Action type (click, dismiss). */ trackStat: function(promoId, action) { if (!seopressPromotions.stats_endpoint) { return; } // Use sendBeacon for reliable tracking that doesn't block navigation. if (navigator.sendBeacon) { var data = new FormData(); data.append('ad_id', promoId); data.append('action', action); navigator.sendBeacon(seopressPromotions.stats_endpoint, data); } else { // Fallback to async fetch. fetch(seopressPromotions.stats_endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ad_id: promoId, action: action }), keepalive: true }).catch(function() { // Silently fail - stats are non-critical. }); } }, /** * Handle toggling all promotions on/off. * * @param {Event} e Change event. */ handleToggleAll: function(e) { var $checkbox = $(this); var disableAll = $checkbox.is(':checked') ? '1' : '0'; $.ajax({ url: ajaxurl, type: 'POST', data: { action: 'seopress_toggle_promotions', disable_all: disableAll, _ajax_nonce: seopressPromotions.toggle_nonce }, success: function(response) { if (response.success) { // Reload page to reflect changes. if (disableAll === '1') { $('.seopress-promo-banner, .seopress-promotions, .seopress-contextual-promo').slideUp(300); } else { location.reload(); } } }, error: function(xhr, status, error) { console.error('SEOPress Promotions: AJAX error.', error); // Revert checkbox state. $checkbox.prop('checked', !$checkbox.is(':checked')); } }); }, /** * Initialize license renewal modal. */ initModal: function() { var $modal = $('#seopress-license-modal'); if (!$modal.length) { return; } // Check if modal was already dismissed today. var dismissedAt = localStorage.getItem('seopress_license_modal_dismissed'); if (dismissedAt) { var dismissedDate = new Date(parseInt(dismissedAt, 10)); var now = new Date(); var hoursDiff = (now - dismissedDate) / (1000 * 60 * 60); // Show again after 24 hours. if (hoursDiff < 24) { $modal.addClass('hidden'); return; } } // Show modal with slight delay for better UX. setTimeout(function() { $modal.removeClass('hidden'); }, 1000); }, /** * Handle modal dismiss button click. * * @param {Event} e Click event. */ handleModalDismiss: function(e) { e.preventDefault(); var $modal = $('#seopress-license-modal'); // Store dismissal timestamp. localStorage.setItem('seopress_license_modal_dismissed', Date.now().toString()); // Animate out. $modal.css({ 'opacity': '0', 'transition': 'opacity 0.3s ease' }); setTimeout(function() { $modal.addClass('hidden').css('opacity', '1'); }, 300); }, /** * Handle click on modal overlay. * * @param {Event} e Click event. */ handleOverlayClick: function(e) { // Only close if clicking directly on overlay, not modal content. if ($(e.target).hasClass('seopress-modal-overlay')) { $('[data-dismiss="license-modal"]').trigger('click'); } }, }; // Initialize on document ready. $(document).ready(function() { SEOPressPromotions.init(); }); })(jQuery);