1/** 2 * Daily / Session-based Responsive Popup Banner Handler 3 * Shows banner at most once per day across all tabs/windows. 4 */ 5document.addEventListener('DOMContentLoaded', () => { 6 const modal = document.getElementById('popupBannerModal'); 7 const closeBtn = document.getElementById('closePopupBanner'); 8 const bannerLink = document.getElementById('popupBannerLink'); 9 10 if (!modal) return; 11 12 const STORAGE_KEY = 'popup_banner_last_shown_date'; 13 14 // Get current local date string (YYYY-MM-DD) 15 const getTodayDateString = () => { 16 const today = new Date(); 17 return `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`; 18 }; 19 20 const todayStr = getTodayDateString(); 21 22 // Function to save today's date in localStorage 23 const markAsShown = () => { 24 try { 25 localStorage.setItem(STORAGE_KEY, todayStr); 26 } catch (e) { 27 try { 28 sessionStorage.setItem(STORAGE_KEY, todayStr); 29 } catch (err) { 30 // Storage not accessible 31 } 32 } 33 }; 34 35 // Function to show modal 36 const showBanner = () => { 37 modal.classList.remove('hidden'); 38 modal.classList.add('flex'); 39 document.body.style.overflow = 'hidden'; // Prevent background scrolling 40 markAsShown(); 41 }; 42 43 // Function to hide modal 44 const hideBanner = () => { 45 modal.classList.add('hidden'); 46 modal.classList.remove('flex'); 47 document.body.style.overflow = ''; 48 markAsShown(); 49 }; 50 51 // Check if banner was already shown today 52 let lastShownDate = null; 53 try { 54 lastShownDate = localStorage.getItem(STORAGE_KEY) || sessionStorage.getItem(STORAGE_KEY); 55 } catch (e) { 56 try { 57 lastShownDate = sessionStorage.getItem(STORAGE_KEY); 58 } catch (err) { 59 lastShownDate = null; 60 } 61 } 62 63 if (lastShownDate !== todayStr) { 64 // Show banner after brief delay for smooth entrance 65 //setTimeout(showBanner, 400); 66 } 67 68 // Event Listeners 69 if (closeBtn) { 70 closeBtn.addEventListener('click', (e) => { 71 e.stopPropagation(); 72 hideBanner(); 73 }); 74 } 75 76 if (bannerLink) { 77 bannerLink.addEventListener('click', () => { 78 hideBanner(); 79 }); 80 } 81 82 // Dismiss when clicking background backdrop 83 modal.addEventListener('click', (e) => { 84 if (e.target === modal) { 85 hideBanner(); 86 } 87 }); 88 89 // ESC key to close modal 90 document.addEventListener('keydown', (e) => { 91 if (e.key === 'Escape' && !modal.classList.contains('hidden')) { 92 hideBanner(); 93 } 94 }); 95});
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.