1// Popup display script 2// Injects the first matching popup from global `mrwp_page_popups` if present. 3// Tracks displayed popups with a cookie per-popup id. 4 5(function ($) { 6 'use strict'; 7 8 if (typeof window === 'undefined' || typeof $ === 'undefined') return; 9 10 var raw = window.mrwp_page_popups || null; 11 if (!raw) return; 12 13 // Normalize to array 14 var popups = raw; 15 if (!Array.isArray(popups)) { 16 if (typeof popups === 'object' && popups !== null) { 17 try { 18 popups = Object.keys(popups).map(function (k) { return popups[k]; }); 19 } catch (e) { 20 popups = [popups]; 21 } 22 } else { 23 popups = [popups]; 24 } 25 } 26 27 // Cookie helpers 28 function getCookie(name) { 29 var m = document.cookie.match('(?:^|; )' + name.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1') + '=([^;]*)'); 30 return m ? decodeURIComponent(m[1]) : null; 31 } 32 function setCookie(name, value, hours) { 33 var s = name + '=' + encodeURIComponent(String(value)) + '; path=/'; 34 if (typeof hours === 'number' && hours > 0) { 35 var exp = new Date(); 36 exp.setTime(exp.getTime() + hours * 3600 * 1000); 37 s += '; expires=' + exp.toUTCString(); 38 } 39 document.cookie = s; 40 } 41 42 // Render modal using jQuery 43 function renderPopup(p) { 44 if (!p) return; 45 46 if ($('.mrwp-popup-overlay').length) return; // avoid duplicates 47
48 var $overlay = $('<div class="mrwp-popup-overlay" role="dialog" aria-modal="true">'); 49 var $close = $('<button type="button" class="mrwp-popup-close" aria-label="Close">×</button>'); 50 51 var $iframe = $('<iframe />').attr('src', p.iframe_url); 52 53 $overlay.append($close); 54 $overlay.append($iframe); 55 $('body').append($overlay); 56 57 // Track when this popup was displayed 58 if (p.id) { 59 var hours = parseInt(String(p.hide_hours_between_displays || 0), 10) || 0; 60 setCookie('mrwp_popup_' + p.id + '_ts', Date.now(), hours || 24 * 365); 61 } 62 63 // focus 64 $close.focus(); 65 66 function closePopup() { 67 $overlay.remove(); 68 $(document).off('keydown.rrpopup'); 69 $(window).off('scroll.rrpopup'); 70 } 71 72 $overlay.on('click', function (ev) { 73 if (ev.target === $overlay[0]) closePopup(); 74 }); 75 $close.on('click', closePopup); 76 $(document).on('keydown.rrpopup', function (e) { 77 if (e.key === 'Escape' || e.key === 'Esc') closePopup(); 78 }); 79 } 80 81 // Decide first popup to show considering hide_hours_between_displays cookie + wait/scroll rules 82 function showFirstEligible() { 83 for (var i = 0; i < popups.length; i++) { 84 (function (p) { 85 if (!p || typeof p !== 'object') return; 86 87 var id = p.id || p.ID || p.popup_id; 88 if (typeof id === 'undefined' || id === null) return; 89 90 var hideHours = parseInt(String(p.hide_hours_between_displays || 0), 10) || 0; 91 var cookieVal = getCookie('mrwp_popup_' + id + '_ts'); 92 if (cookieVal) { 93 var lastTs = parseInt(cookieVal, 10) || 0; 94 if (lastTs > 0 && hideHours > 0) { 95 var delta = Date.now() - lastTs; 96 if (delta < hideHours * 3600 * 1000) { 97 return; // skip this popup; still hidden 98 } 99 } 100 } 101 102 // Check hide_hours_utm_email param and utm_medium_email_ts cookie value 103 var hideUtmEmailHours = parseInt(String(p.hide_hours_utm_email || 0), 10) || 0; 104 if (hideUtmEmailHours > 0) { 105 var utmEmailCookie = getCookie('utm_medium_email_ts'); 106 if (utmEmailCookie) { 107 var utmEmailTs = parseInt(utmEmailCookie, 10) || 0; 108 if (utmEmailTs > 0) { 109 var deltaUtm = Date.now() - utmEmailTs; 110 if (deltaUtm < hideUtmEmailHours * 3600 * 1000) { 111 return; // skip this popup; still hidden due to recent email visit 112 } 113 } 114 } 115 } 116 117 // Now handle wait_seconds_before_displaying and scroll_distance_before_displaying 118 var waitSecs = parseInt(String(p.wait_seconds_before_displaying || p.wait_seconds || 0), 10) || 0; 119 var scrollPx = parseInt(String(p.scroll_distance_before_displaying || p.scroll_distance || 0), 10) || 0; 120 121 var waited = waitSecs <= 0; 122 var scrolled = scrollPx <= 0; 123 124 var timerId = null; 125 126 function attemptShow() { 127 if (waited && scrolled) { 128 // render and stop listeners 129 renderPopup(p); 130 if (timerId) clearTimeout(timerId); 131 $(window).off('scroll.rrpopup'); 132 } 133 } 134 135 if (!waited) { 136 timerId = setTimeout(function () { 137 waited = true; 138 attemptShow(); 139 }, waitSecs * 1000); 140 } 141 142 if (!scrolled) { 143 $(window).on('scroll.rrpopup', function () { 144 var top = $(window).scrollTop(); 145 if (top >= scrollPx) { 146 scrolled = true; 147 $(window).off('scroll.rrpopup'); 148 attemptShow(); 149 } 150 }); 151 // check current position immediately 152 if ($(window).scrollTop() >= scrollPx) { 153 scrolled = true; 154 $(window).off('scroll.rrpopup'); 155 } 156 } 157 158 // If both conditions already satisfied, show immediately 159 attemptShow(); 160 161 })(popups[i]); 162 163 // Only try the first popup available in the array (do not attempt next once we rendered) 164 if ($('.mrwp-popup-overlay').length) break; 165 } 166 } 167 168 jQuery(document).on('ready', showFirstEligible);
169 jQuery(window).on('statechangecomplete', showFirstEligible); 170 171})(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.