1// Alert box design by Igor Ferrão de Souza: https://www.linkedin.com/in/igor-ferr%C3%A3o-de-souza-4122407b/ 2 3const cuteAlert = ({ 4 url, 5 type, 6 title, 7 message, 8 img, 9 buttonText = 'OK', 10 confirmText = 'OK', 11 vibrate = [], 12 playSound = null, 13 cancelText = 'Cancel', 14 closeStyle, 15}) => { 16 return new Promise(resolve => { 17 const existingAlert = document.querySelector('.alert-wrapper'); 18 19 if (existingAlert) { 20 existingAlert.remove(); 21 } 22 23 const body = document.querySelector('body'); 24 25 const scripts = document.getElementsByTagName('script'); 26 27 let src = ''; 28 29 for (let script of scripts) { 30 if (script.src.includes('cute-alert.js')) { 31 src = script.src.substring(0, script.src.lastIndexOf('/')); 32 } 33 } 34 35 let btnTemplate = ` 36 <button class="alert-button ${type}-bg ${type}-btn">${buttonText}</button> 37 `; 38 39 if (type === 'question') { 40 btnTemplate = ` 41 <div class="question-buttons"> 42 <button class="confirm-button ${type}-bg ${type}-btn">${confirmText}</button> 43 <button class="cancel-button error-bg error-btn">${cancelText}</button> 44 </div> 45 `; 46 } 47 48 if (vibrate.length > 0) { 49 navigator.vibrate(vibrate); 50 } 51 52 if (playSound !== null) { 53 let sound = new Audio(playSound); 54 sound.play(); 55 } 56 57 const template = ` 58 <div class="alert-wrapper"> 59 <div class="alert-frame"> 60 ${ 61 img === undefined 62 ? '<div class="alert-header ' + type + '-bg">' 63 : '<div class="alert-header-base">' 64 } 65 <span class="alert-close ${ 66 closeStyle === 'circle' 67 ? 'alert-close-circle' 68 : 'alert-close-default' 69 }">X</span> 70 ${ 71 img === undefined 72 ? '<img class="alert-img" src="' + 73 src + 74 "/img/" + 75 type + 76 ".svg" + 77 '" />' 78 : '<div class="custom-img-wrapper">' + img + "</div>" 79 } 80 </div> 81 <div class="alert-body"> 82 <span class="alert-title">${title}</span> 83 <span class="alert-message">${message}</span> 84 ${btnTemplate} 85 </div> 86 </div> 87 </div> 88 `; 89 90 body.insertAdjacentHTML('afterend', template); 91 92 const alertWrapper = document.querySelector('.alert-wrapper'); 93 const alertFrame = document.querySelector('.alert-frame'); 94 const alertClose = document.querySelector('.alert-close'); 95 96 if (type === 'question') { 97 const confirmButton = document.querySelector('.confirm-button'); 98 const cancelButton = document.querySelector('.cancel-button'); 99 100 confirmButton.addEventListener('click', () => { 101 alertWrapper.remove(); 102 resolve('confirm'); 103 }); 104 105 cancelButton.addEventListener('click', () => { 106 alertWrapper.remove(); 107 resolve(); 108 }); 109 } else { 110 const alertButton = document.querySelector('.alert-button'); 111 112 alertButton.addEventListener('click', () => { 113 alertWrapper.remove(); 114 resolve('ok'); 115 }); 116 } 117 118 alertClose.addEventListener('click', () => { 119 alertWrapper.remove(); 120 resolve('close'); 121 }); 122 123/* alertWrapper.addEventListener('click', () => { 124 alertWrapper.remove(); 125 resolve(); 126 }); */ 127 128 alertFrame.addEventListener('click', e => { 129 e.stopPropagation(); 130 }); 131 }); 132}; 133 134const cuteToast = ({ type, title, message, timer = 5000, vibrate = [], playSound = null }) => { 135 return new Promise(resolve => { 136 const body = document.querySelector('body'); 137 138 const scripts = document.getElementsByTagName('script'); 139 140 let src = ''; 141 142 for (let script of scripts) { 143 if (script.src.includes('cute-alert.js')) { 144 src = script.src.substring(0, script.src.lastIndexOf('/')); 145 } 146 } 147 148 let templateContainer = document.querySelector('.toast-container'); 149 150 if (!templateContainer) { 151 body.insertAdjacentHTML( 152 'afterend', 153 '<div class="toast-container"></div>', 154 ); 155 templateContainer = document.querySelector('.toast-container'); 156 } 157 158 const toastId = mfCaoId(); 159 160 const templateContent = ` 161 <div class="toast-content ${type}-bg" id="${toastId}-toast-content"> 162 <div> 163 <div class="toast-frame"> 164 <div class="toast-body"> 165 <img class="toast-body-img" src="${src}/img/${type}.svg" />' 166 <div class="toast-body-content">
167 <span class="toast-title">${title}</span> 168 <span class="toast-message">${message}</span> 169 </div> 170 <div class="toast-close" id="${toastId}-toast-close">X</div> 171 </div> 172 </div> 173 <div class="toast-timer ${type}-timer" style="animation: timer${timer}ms linear;> 174 </div> 175 </div> 176 `; 177 178 const toasts = document.querySelectorAll('.toast-content'); 179 180 if (toasts.length) { 181 toasts[0].insertAdjacentHTML('beforebegin', templateContent); 182 } else { 183 templateContainer.innerHTML = templateContent; 184 } 185 186 const toastContent = document.getElementById(`${toastId}-toast-content`); 187 188 if (vibrate.length > 0) { 189 navigator.vibrate(vibrate); 190 } 191 192 if (playSound !== null) { 193 let sound = new Audio(playSound); 194 sound.play(); 195 } 196 197 setTimeout(() => { 198 toastContent.remove(); 199 resolve(); 200 }, timer); 201 202 const toastClose = document.getElementById(`${toastId}-toast-close`); 203 204 toastClose.addEventListener('click', () => { 205 toastContent.remove(); 206 resolve(); 207 }); 208 }); 209}; 210 211const mfCaId = () => { 212 return '_' + Math.random().toString(36).substr(2, 9); 213}; 214 215
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.