1/* ========================================================================== 2 ID Popup â Frontend JavaScript 3 Handles: Per-popup delay, auto-close, device detection, close button, 4 optional GTM/GA4 dataLayer tracking 5 ========================================================================== */ 6 7jQuery( document ).ready( function ( $ ) { 8 9 var viewportWidth = $( window ).width(); 10 11 // ----------------------------------------------------------------------- 12 // dataLayer push helper â no-op if tracking flag missing on the popup 13 // ----------------------------------------------------------------------- 14 function pushDataLayer( $popup, eventName, extra ) { 15 if ( $popup.data( 'track' ) != 1 ) return; 16 if ( ! eventName ) return; 17 18 window.dataLayer = window.dataLayer || []; 19 20 var payload = { 21 event: eventName, 22 popup_id: $popup.data( 'track-id' ) || '', 23 popup_title: $popup.data( 'track-title' ) || '', 24 }; 25 26 if ( extra && typeof extra === 'object' ) { 27 for ( var k in extra ) { 28 if ( Object.prototype.hasOwnProperty.call( extra, k ) ) { 29 payload[ k ] = extra[ k ]; 30 } 31 } 32 } 33 34 window.dataLayer.push( payload ); 35 } 36 37 // Iterate over every popup rendered in the footer 38 $( '.id-popup-container' ).each( function () { 39 var $popup = $( this ); 40 var $overlay = $popup.prev( '.id-popup-overlay' ); 41 42 // Read timing from data attributes (stored in ms by PHP) 43 var rawDelay = parseInt( $popup.data( 'delay' ), 10 ); 44 var rawAutoClose = parseInt( $popup.data( 'autoclose' ), 10 ); 45 var delay = isNaN( rawDelay ) ? 3000 : rawDelay; 46 var autoClose = isNaN( rawAutoClose ) ? 15000 : rawAutoClose; 47 48 // Device image flags 49 var hasDesktop = parseInt( $popup.data( 'has-desktop' ), 10 ); 50 var hasMobile = parseInt( $popup.data( 'has-mobile' ), 10 ); 51 var isMobile = viewportWidth <= 767; 52 53 // Skip if no image configured for the current device 54 if ( isMobile && hasMobile === 0 ) return; 55 if ( ! isMobile && hasDesktop === 0 ) return; 56 57 // Track when the popup actually appeared so close events can report duration 58 var shownAt = 0; 59 60 // Show popup after delay 61 setTimeout( function () { 62 $overlay.fadeIn( 400 ); 63 $popup.fadeIn( 400 ); 64 $( 'body' ).addClass( 'id-popup-open' ); 65 shownAt = Date.now(); 66 // Store on the DOM element so close handlers outside this closure 67 // can also compute time_shown_ms. 68 $popup.data( 'id-shown-at', shownAt ); 69 pushDataLayer( $popup, $popup.data( 'track-view-event' ) ); 70 }, delay ); 71 72 // Auto-close after delay + autoClose (0 means disabled) 73 if ( autoClose > 0 ) { 74 setTimeout( function () { 75 if ( $popup.is( ':visible' ) ) { 76 pushDataLayer( $popup, $popup.data( 'track-close-event' ), { 77 close_reason: 'auto', 78 time_shown_ms: shownAt ? ( Date.now() - shownAt ) : 0, 79 } ); 80 } 81 $popup.fadeOut( 300 ); 82 $overlay.fadeOut( 300, function () { 83 if ( ! $( '.id-popup-container:visible' ).length ) { 84 $( 'body' ).removeClass( 'id-popup-open' ); 85 } 86 } ); 87 }, delay + autoClose ); 88 } 89 90 // Click on the popup image/link â fire click event before default nav 91 $popup.find( 'a' ).on( 'click', function () {
92 pushDataLayer( $popup, $popup.data( 'track-click-event' ), { 93 link_url: $popup.data( 'track-link' ) || $( this ).attr( 'href' ) || '', 94 } ); 95 } ); 96 } ); 97 98 // ----------------------------------------------------------------------- 99 // Close Button 100 // ----------------------------------------------------------------------- 101 $( document ).on( 'click', '.id-popup-close-btn', function () { 102 var $popup = $( this ).closest( '.id-popup-container' ); 103 var $overlay = $popup.prev( '.id-popup-overlay' ); 104 var shownAt = $popup.data( 'id-shown-at' ) || 0; 105 pushDataLayer( $popup, $popup.data( 'track-close-event' ), { 106 close_reason: 'button', 107 time_shown_ms: shownAt ? ( Date.now() - shownAt ) : 0, 108 } ); 109 $popup.fadeOut( 300 ); 110 $overlay.fadeOut( 300, function () { 111 if ( ! $( '.id-popup-container:visible' ).length ) { 112 $( 'body' ).removeClass( 'id-popup-open' ); 113 } 114 } ); 115 } ); 116 117 // ----------------------------------------------------------------------- 118 // Overlay Click â also closes the popup 119 // ----------------------------------------------------------------------- 120 $( document ).on( 'click', '.id-popup-overlay', function () {
121 var $overlay = $( this ); 122 var $popup = $overlay.next( '.id-popup-container' ); 123 var shownAt = $popup.data( 'id-shown-at' ) || 0; 124 pushDataLayer( $popup, $popup.data( 'track-close-event' ), { 125 close_reason: 'overlay', 126 time_shown_ms: shownAt ? ( Date.now() - shownAt ) : 0, 127 } ); 128 $popup.fadeOut( 300 ); 129 $overlay.fadeOut( 300, function () { 130 if ( ! $( '.id-popup-container:visible' ).length ) { 131 $( 'body' ).removeClass( 'id-popup-open' ); 132 } 133 } ); 134 } ); 135 136} );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.