1/* NewLife Email Popup â v1.3.0. Time-delayed slide-in + dismiss/subscribe memory. 2 * No animation library, no modal behaviour (see popup.css for why). 3 */ 4( function ( $ ) { 5 'use strict'; 6 7 function getCookie( name ) { 8 var match = document.cookie.match( new RegExp( '(^|; )' + name + '=([^;]*)' ) ); 9 return match ? decodeURIComponent( match[ 2 ] ) : null; 10 } 11 12 function setCookie( name, value, days ) { 13 var expires = new Date( Date.now() + days * 864e5 ).toUTCString(); 14 document.cookie = name + '=' + encodeURIComponent( value ) + '; expires=' + expires + '; path=/; SameSite=Lax'; 15 } 16 17 $( function () { 18 var cfg = window.nlPopupConfig || {}; 19 20 // All the "don't show this" checks happen here in JS, not in PHP before the 21 // assets were even enqueued â this page can be served from the LiteSpeed 22 // page cache, and a per-visitor decision baked into cached HTML would be 23 // wrong for every other visitor who gets that same cached copy. Same 24 // reasoning as the cart check below, applied to dismissed/subscribed too. 25 if ( getCookie( 'nl_popup_dismissed' ) || getCookie( 'nl_popup_subscribed' ) ) { 26 return; 27 } 28 29 // Logged-in customers get a second, permanent check: an account-level flag 30 // (set once, on either the popup or the checkout newsletter tick-box) that 31 // survives a cleared cookie or a different browser/device. This value is 32 // safe to read from a server-localized variable rather than a cookie 33 // because pages for logged-in visitors aren't served from the page cache. 34 if ( cfg.isLoggedIn && cfg.loggedInSubscribed ) { 35 return; 36 } 37 38 // Skip entirely if the visitor currently has items in their cart. Checked 39 // client-side for the same cache-safety reason as above â WooCommerce core 40 // itself sets/clears this cookie (class-wc-cart-session.php) specifically so 41 // things like this can check cart state without PHP or an AJAX call. 42 if ( getCookie( 'woocommerce_items_in_cart' ) ) { 43 return; 44 } 45 46 var $panel = $( '#nl-popup-panel' ); 47 if ( ! $panel.length ) { 48 return; 49 } 50 51 // The field labels/sub-labels are hidden visually by popup.css, so without a 52 // placeholder each box reads as blank. Fill in a sensible default here rather 53 // than requiring it to be set by hand in WPForms â but only on a field that 54 // doesn't already have one, so a manually-set WPForms placeholder is never 55 // overwritten. 56 ( function applyPlaceholders() { 57 var ph = cfg.placeholders || {}; 58 var map = [ 59 [ 'input.wpforms-field-name-first', ph.first ], 60 [ 'input.wpforms-field-name-last', ph.last ], 61 [ '.wpforms-field-email input[type="email"]', ph.email ], 62 ]; 63 map.forEach( function ( pair ) { 64 var $field = $panel.find( pair[ 0 ] ); 65 if ( $field.length && pair[ 1 ] && ! $field.attr( 'placeholder' ) ) { 66 $field.attr( 'placeholder', pair[ 1 ] ); 67 } 68 } ); 69 } )(); 70 71 var delayMs = ( cfg.delaySeconds || 10 ) * 1000; 72 var dismissDays = cfg.dismissDays || 7; 73 var timer = setTimeout( show, delayMs ); 74 75 function show() { 76 $panel.removeAttr( 'hidden' ).addClass( 'is-visible' ).attr( 'aria-hidden', 'false' ); 77 } 78 79 function hide( remember ) { 80 clearTimeout( timer ); 81 $panel.removeClass( 'is-visible' ).attr( 'aria-hidden', 'true' ); 82 if ( remember ) { 83 setCookie( 'nl_popup_dismissed', '1', dismissDays ); 84 } 85 } 86 87 $panel.on( 'click', '.nl-popup-close', function () { 88 hide( true ); 89 } ); 90 91 // Non-modal: Escape dismisses it like the close button, but there's no 92 // backdrop to click through and the rest of the page stays fully usable 93 // while it's showing. 94 $( document ).on( 'keydown', function ( e ) { 95 if ( 'Escape' === e.key && $panel.hasClass( 'is-visible' ) ) { 96 hide( true ); 97 } 98 } ); 99 100 // WPForms swaps the form markup for its confirmation message in place on success. 101 // Once that shows up, auto-close shortly after instead of leaving the card open â 102 // the actual "don't show again" cookie/account flag is set server-side in 103 // wpforms_process_complete. 104 var $content = $panel.find( '.nl-popup-body' ).first(); 105 if ( $content.length && window.MutationObserver ) { 106 var observer = new MutationObserver( function () { 107 if ( $content.find( '.wpforms-confirmation-container' ).length ) { 108 observer.disconnect(); 109 setTimeout( function () { 110 hide( false ); 111 }, 4000 ); 112 } 113 } ); 114 observer.observe( $content[ 0 ], { childList: true, subtree: true } ); 115 } 116 } ); 117} )( jQuery );
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.