1const BannerNotification = (function () { 2 let bannerSettingsContainer; 3 const bannerSettingsContainerKey = 'bannersettings'; 4 const defaultOptions = { 5 displayTimeMs: 5000, // options.displayTimeMs 6 checkFn: () => true, // options.checkFn = function that returns a bool for whether or not to show the banner 7 titleText: 'titleText', // options.titleText 8 cancelText: 'x', // options.cancelText 9 cancelType: 'text', // options.cancelType = 'button' or 'text' 10 cancelCssClass: '', // options.cancelCssClass 11 cancelFn: 'BannerNotification.ExplicitHide(this);', // options.cancelFn 12 acceptText: 'acceptText', // options.acceptText 13 acceptType: 'button', // options.acceptType = 'button' or 'text' 14 acceptFormat: 'onclick', // options.acceptFormat = 'onclick' or 'href' 15 acceptCssClass: 'btn btn-secondary', // options.acceptCssClass 16 acceptFn: 'BannerNotification.Hide(this);', // options.acceptFn 17 settingsKey: 'bannernotification', // options.settingsKey 18 maxRetries: 3, // options.settingsRetries 19 retryDelayHours: 6 // options.settingsRetryDelayHours 20 } 21 22 const defaultStorageSettings = { 23 lastHiddenUTC: '01-01-2000', 24 retries: 0, 25 maxRetries: -1, 26 retryDelayHours: -1 27 } 28 29 const bannerContainerSelector = '.banner-cont'; 30 const bannerCancelSelector = '[banner="cancel"]'; 31 const bannerAcceptSelector = '[banner="accept"]'; 32 let currentBannerTimeout = -1; 33 let bannerDelayTimeout = -1; 34 function Show(options) { 35 for (let option in defaultOptions) 36 options[option] = options[option] || defaultOptions[option] 37 38 if (!shouldShowBanner(options)) 39 return; 40 41 if (!options.checkFn()) 42 return; 43 44 let banner = createBanner(options); 45 renderBanner(banner, options.displayTimeMs); 46 } 47 48 function renderBanner(banner, displayTimeMs) { 49 let addNewDelay = 0; 50 clearTimeout(bannerDelayTimeout); 51 if (currentBannerTimeout >= 0) { 52 removeBanner($(bannerContainerSelector)) 53 addNewDelay = 1000; 54 } 55 56 bannerDelayTimeout = setTimeout(function () { 57 $('body').append(banner); 58 let newBanner = $($(bannerContainerSelector).slice(-1)) 59 newBanner.slideDown(); 60 currentBannerTimeout = setTimeout(function () { 61 removeBanner(newBanner); 62 }, displayTimeMs) 63 }, addNewDelay); 64 } 65 66 function shouldShowBanner(options) { 67 let bannerSettings = getBannerSettings(options.settingsKey, options); 68 69 let lastHiddenDateUTC = new Date(bannerSettings.lastHiddenUTC) 70 lastHiddenDateUTC.setTime(lastHiddenDateUTC.getTime() + (bannerSettings.retryDelayHours * 60 * 60 * 1000)); 71 72 if (lastHiddenDateUTC > new Date()) 73 return false; 74 75 if (lastHiddenDateUTC == 'Invalid Date') 76 return true; 77 78 lastHiddenDateUTC.setTime(lastHiddenDateUTC.getTime() + (30 * 24 * 60 * 60 * 1000)) 79 if (lastHiddenDateUTC < new Date()) { 80 bannerSettings.retries = 0; 81 bannerSettingsContainer.Update(options.settingsKey, bannerSettings); 82 return true; 83 } 84 85 if (bannerSettings.retries >= bannerSettings.maxRetries) 86 return false; 87 88 return true; 89 } 90 91 function ExplicitHide(element) { 92 Hide(element); 93 let bannerKey = $(element).attr('banner-key') 94 let bannerSettings = getBannerSettings(bannerKey) 95 96 bannerSettings.retries++; 97 bannerSettings.lastHiddenUTC = new Date().toUTCString(); 98 bannerSettingsContainer.Update(bannerKey, bannerSettings); 99 } 100 101 function getBannerSettings(key, options) { 102 bannerSettingsContainer = StorageProvider.GetOrCreateLocalContainer(bannerSettingsContainerKey); 103 let bannerSettings = bannerSettingsContainer.GetLatest(key); 104 let hasSettings = true; 105 if (!bannerSettings) { 106 hasSettings = false; 107 bannerSettings = {}; 108 } 109 for (let setting in defaultStorageSettings) { 110 bannerSettings[setting] = bannerSettings[setting] || defaultStorageSettings[setting] 111 if (options && options[setting] != undefined && bannerSettings[setting] === -1) 112 bannerSettings[setting] = options[setting]; 113 } 114 115 if (!hasSettings) 116 bannerSettingsContainer.Update(key, bannerSettings); 117 118 return bannerSettings; 119 } 120 121 function Hide(element) { 122 removeBanner($(element).closest(bannerContainerSelector)); 123 } 124 125 function removeBanner(banner) { 126 clearTimeout(currentBannerTimeout); 127 currentBannerTimeout = -1; 128 banner.slideUp(); 129 setTimeout(function () { 130 banner.remove(); 131 }, 500); 132 } 133 134 function createBanner(options) { 135 return `<div class="banner-cont req-cont shadow" style="display: none;"> 136 <div class="banner-title-cont"> 137 <div> 138 <i class="far fa-bell banner-icon"></i>
139 <span class="banner-title-text">${options.titleText}</span> 140 </div> 141 <div> 142 ${getCancelAction(options)} 143 </div> 144 </div> 145 <div class="banner-actions"> 146 ${getAcceptAction(options)} 147 </div> 148 </div>` 149 } 150 151 function getCancelAction(options) { 152 if (options.cancelType === 'button') 153 return getButtonAction(options.cancelCssClass, options.cancelText, 'cancel', options.cancelFn, options.settingsKey, 'onclick') 154 155 return getTextAction(options.cancelCssClass, options.cancelText, 'cancel', options.cancelFn, options.settingsKey, 'onclick') 156 } 157 158 function getAcceptAction(options) { 159 if (options.acceptFormat !== 'href' && options.acceptFormat !== 'onclick') 160 options.acceptFormat = 'onclick'; 161 162 if (options.acceptType === 'button' && options.acceptFormat !== 'href') 163 return getButtonAction(options.acceptCssClass, options.acceptText, 'accept', options.acceptFn, options.settingsKey, options.acceptFormat) 164 165 return getTextAction(options.acceptCssClass, options.acceptText, 'accept', options.acceptFn, options.settingsKey, options.acceptFormat) 166 } 167 168 function getButtonAction(cssClass, text, actionType, fn, bannerKey, acceptFormat) { 169 return `<button type="button" banner="${actionType}" banner-key="${bannerKey}" class="${cssClass}" ${acceptFormat}="${fn}">${text}</button>` 170 } 171 172 function getTextAction(cssClass, text, actionType, fn, bannerKey, acceptFormat) { 173 return `<a banner="${actionType}" banner-key="${bannerKey}" class="${cssClass}" ${acceptFormat}="${fn}">${text}</a>` 174 } 175 176 return { 177 Show, 178 Hide, 179 ExplicitHide 180 } 181})();
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.