1 2class Notice { 3 constructor() { 4 this.list = []; 5 this.container = null; 6 this.defaults = { 7 icon: 'notice', 8 html: 'ÐодÑвеÑдиÑе дейÑÑвие', 9 className: '', 10 buttons: [ 11 { 12 text: 'Ðк', 13 onClick: (modal) => this.close(modal) 14 } 15 ] 16 }; 17 18 this.init(); 19 } 20 21 init() { 22 // Создаем конÑÐµÐ¹Ð½ÐµÑ 23 this.container = document.createElement('div'); 24 this.container.className = 'notice'; 25 document.body.appendChild(this.container); 26 27 // ÐобавлÑем глобалÑнÑе меÑÐ¾Ð´Ñ 28 window.addNotice = this.add.bind(this); 29 window.clearAllNotice = this.clearAll.bind(this); 30 } 31 32 add(options) { 33 const modal = { ...this.defaults, ...options }; 34 this.list.push(modal); 35 this.render(); 36 37 if (options.timeout) { 38 setTimeout(() => this.close(modal), options.timeout); 39 } 40 } 41 42 close(modal) { 43 const index = this.list.indexOf(modal); 44 if (index !== -1) { 45 this.list.splice(index, 1); 46 this.render(); 47 } 48 } 49 50 clearAll() { 51 this.list = []; 52 this.render(); 53 } 54 55 render() { 56 if (!this.container) return; 57 58 if (this.list.length === 0) { 59 this.container.innerHTML = ''; 60 return; 61 } 62 63 const item = this.list[this.list.length - 1]; 64 const iconHtml = this.getIcon(item.icon); 65 66 let buttonsHtml = ''; 67 if (item.buttons && item.buttons.length) { 68 buttonsHtml = item.buttons.map(btn => ` 69 <button class="btn ${btn.classList || ''}" data-index="${item.buttons.indexOf(btn)}"> 70 ${btn.text} 71 </button> 72 `).join(''); 73 } else { 74 buttonsHtml = ` 75 <button class="notice__item-controlls-close"> 76 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 77 <line x1="18" y1="6" x2="6" y2="18"></line> 78 <line x1="6" y1="6" x2="18" y2="18"></line> 79 </svg> 80 </button> 81 `; 82 } 83 84 this.container.innerHTML = ` 85 <div class="notice__item ${item.className}"> 86 <div class="notice__item-row"> 87 <div class="notice__item-icon">${iconHtml}</div> 88 <div class="notice__item-text"> 89 ${item.title ? `<div class="notice__item-text-title">${item.title}</div>` : ''} 90 <div class="notice__item-text-text">${item.html}</div> 91 </div> 92 <div class="notice__item-controlls">${buttonsHtml}</div> 93 </div> 94 </div> 95 `; 96 97 // ÐавеÑиваем обÑабоÑÑики на кнопки 98 const modal = item; 99 const buttons = this.container.querySelectorAll('.btn'); 100 buttons.forEach((btn, index) => { 101 btn.addEventListener('click', () => { 102 if (modal.buttons && modal.buttons[index] && modal.buttons[index].onClick) { 103 modal.buttons[index].onClick(modal); 104 } 105 }); 106 }); 107 108 const closeBtn = this.container.querySelector('.notice__item-controlls-close'); 109 if (closeBtn) { 110 closeBtn.addEventListener('click', () => this.close(modal)); 111 } 112 } 113 114 getIcon(type) { 115 const icons = { 116 notice: ` 117 <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path> 118 <path d="M13.73 21a2 2 0 0 1-3.46 0"></path> 119 `, 120 success: `<polyline points="20 6 9 17 4 12"></polyline>`, 121 error: ` 122 <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path> 123 <line x1="12" y1="9" x2="12" y2="13"></line>
124 <line x1="12" y1="17" x2="12.01" y2="17"></line> 125 `, 126 info: ` 127 <circle cx="12" cy="12" r="10"></circle> 128 <line x1="12" y1="8" x2="12" y2="12"></line> 129 <line x1="12" y1="16" x2="12.01" y2="16"></line> 130 ` 131 }; 132 return `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${icons[type] || icons.notice}</svg>`; 133 } 134}
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.