vendor: 4,670 bytes, lines 1-129
1/*! 2 * Toastify js 1.12.0 3 * https://github.com/apvarun/toastify-js 4 * @license MIT licensed 5 * 6 * Copyright (C) 2018 Varun A P 7 */ 8 9/** 10 * Options used for Toastify 11 * @typedef {Object} ToastifyConfigurationObject 12 * @property {string} text - Message to be displayed in the toast 13 * @property {Element} node - Provide a node to be mounted inside the toast. node takes higher precedence over text 14 * @property {number} duration - Duration for which the toast should be displayed. -1 for permanent toast 15 * @property {string|Element} selector - CSS ID Selector on which the toast should be added 16 * @property {url} destination - URL to which the browser should be navigated on click of the toast 17 * @property {boolean} newWindow - Decides whether the destination should be opened in a new window or not 18 * @property {boolean} close - To show the close icon or not 19 * @property {string} gravity - To show the toast from top or bottom 20 * @property {string} position - To show the toast on left or right 21 * @property {string} backgroundColor - Deprecated: Sets the background color of the toast 22 * @property {url} avatar - Image/icon to be shown before text 23 * @property {string} className - Ability to provide custom class name for further customization 24 * @property {boolean} stopOnFocus - To stop timer when hovered over the toast (Only if duration is set) 25 * @property {Function} callback - Invoked when the toast is dismissed 26 * @property {Function} onClick - Invoked when the toast is clicked 27 * @property {Object} offset - Ability to add some offset to axis 28 * @property {boolean} escapeMarkup - Toggle the default behavior of escaping HTML markup 29 * @property {string} ariaLive - Use the HTML DOM style property to add styles to toast 30 * @property {Object} style - Use the HTML DOM style property to add styles to toast 31 */ 32 33 34export class Toastify { 35 36 defaults = { 37 oldestFirst: true, 38 text: "Toastify is awesome!", 39 node: undefined, 40 duration: 3000, 41 selector: undefined, 42 callback: function () { }, 43 destination: undefined, 44 newWindow: false, 45 close: false, 46 gravity: "toastify-top", 47 positionLeft: false, 48 position: "right", 49 backgroundColor: "", 50 avatar: "", 51 className: "", 52 stopOnFocus: true, 53 onClick: function () { }, 54 offset: { x: 0, y: 0 }, 55 escapeMarkup: true, 56 ariaLive: "polite", 57 style: { background: "" }, 58 }; 59 60 constructor(options) { 61 /** 62 * The version of Toastify 63 * @type {string} 64 * @public 65 */ 66 this.version = "1.12.0"; 67 68 /** 69 * The configuration object to configure Toastify 70 * @type {ToastifyConfigurationObject} 71 * @public 72 */ 73 this.options = {}; 74 75 /** 76 * The element that is the Toast 77 * @type {Element} 78 * @public 79 */ 80 this.toastElement = null; 81 82 /** 83 * The root element that contains all the toasts 84 * @type {Element} 85 * @private 86 */ 87 this._rootElement = document.body; 88 89 this._init(options); 90 } 91 92 /** 93 * Display the toast 94 * @public 95 */ 96 showToast() { 97 // Creating the DOM object for the toast 98 this.toastElement = this._buildToast(); 99 100 // Getting the root element to with the toast needs to be added 101 if (typeof this.options.selector === "string") { 102 this._rootElement = document.getElementById(this.options.selector); 103 } else if (this.options.selector instanceof HTMLElement || this.options.selector instanceof ShadowRoot) { 104 this._rootElement = this.options.selector; 105 } else { 106 this._rootElement = document.body; 107 } 108 109 // Validating if root element is present in DOM 110 if (!this._rootElement) { 111 throw "Root element is not defined"; 112 } 113 114 // Adding the DOM element 115 this._rootElement.insertBefore(this.toastElement, this._rootElement.firstChild); 116 117 // Repositioning the toasts in case multiple toasts are present 118 this._reposition(); 119 120 if (this.options.duration > 0) { 121 this.toastElement.timeOutValue = window.setTimeout( 122 () => { 123 // Remove the toast from DOM 124 this._removeElement(this.toastElement); 125 }, 126 this.options.duration 127 ); // Binding `this` for function invocation 128 } 129
130 // Supporting function chaining 131 return this; 132 } 133 134 /** 135 * Hide the toast 136 * @public 137 */ 138 hideToast() { 139 if (this.toastElement.timeOutValue) { 140 clearTimeout(this.toastElement.timeOutValue); 141 } 142 this._removeElement(this.toastElement); 143 } 144 145 /** 146 * Init the Toastify class 147 * @param {ToastifyConfigurationObject} options - The configuration object to configure Toastify 148 * @param {string} [options.text=Hi there!] - Message to be displayed in the toast 149 * @param {Element} [options.node] - Provide a node to be mounted inside the toast. node takes higher precedence over text 150 * @param {number} [options.duration=3000] - Duration for which the toast should be displayed. -1 for permanent toast 151 * @param {string} [options.selector] - CSS Selector on which the toast should be added 152 * @param {url} [options.destination] - URL to which the browser should be navigated on click of the toast 153 * @param {boolean} [options.newWindow=false] - Decides whether the destination should be opened in a new window or not 154 * @param {boolean} [options.close=false] - To show the close icon or not 155 * @param {string} [options.gravity=toastify-top] - To show the toast from top or bottom 156 * @param {string} [options.position=right] - To show the toast on left or right 157 * @param {string} [options.backgroundColor] - Sets the background color of the toast (To be deprecated) 158 * @param {url} [options.avatar] - Image/icon to be shown before text 159 * @param {string} [options.className] - Ability to provide custom class name for further customization 160 * @param {boolean} [options.stopOnFocus] - To stop timer when hovered over the toast (Only if duration is set) 161 * @param {Function} [options.callback] - Invoked when the toast is dismissed 162 * @param {Function} [options.onClick] - Invoked when the toast is clicked 163 * @param {Object} [options.offset] - Ability to add some offset to axis 164 * @param {boolean} [options.escapeMarkup=true] - Toggle the default behavior of escaping HTML markup 165 * @param {string} [options.ariaLive] - Announce the toast to screen readers 166 * @param {Object} [options.style] - Use the HTML DOM style property to add styles to toast 167 * @private 168 */ 169 _init(options) { 170 171 // Setting defaults 172 this.options = Object.assign(this.defaults, options); 173 174 if (this.options.backgroundColor) {
vendor: 10,559 bytes, lines 175-466
175 // This is being deprecated in favor of using the style HTML DOM property 176 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.'); 177 } 178 179 this.toastElement = null; 180 181 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : "toastify-top"; // toast position - top or bottom 182 this.options.stopOnFocus = options.stopOnFocus === undefined ? true : options.stopOnFocus; // stop timeout on focus 183 if (options.backgroundColor) { 184 this.options.style.background = options.backgroundColor; 185 } 186 } 187 188 /** 189 * Build the Toastify element 190 * @returns {Element} 191 * @private 192 */ 193 _buildToast() { 194 // Validating if the options are defined 195 if (!this.options) { 196 throw "Toastify is not initialized"; 197 } 198 199 // Creating the DOM object 200 let divElement = document.createElement("div"); 201 divElement.className = `toastify on ${this.options.className}`; 202 203 // Positioning toast to left or right or center (default right) 204 divElement.className += ` toastify-${this.options.position}`; 205 206 // Assigning gravity of element 207 divElement.className += ` ${this.options.gravity}`; 208 209 // Loop through our style object and apply styles to divElement 210 for (const property in this.options.style) { 211 divElement.style[property] = this.options.style[property]; 212 } 213 214 // Announce the toast to screen readers 215 if (this.options.ariaLive) { 216 divElement.setAttribute('aria-live', this.options.ariaLive) 217 } 218 219 // Adding the toast message/node 220 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) { 221 // If we have a valid node, we insert it 222 divElement.appendChild(this.options.node) 223 } else { 224 if (this.options.escapeMarkup) { 225 divElement.innerText = this.options.text; 226 } else { 227 divElement.innerHTML = this.options.text; 228 } 229 230 if (this.options.avatar !== "") { 231 let avatarElement = document.createElement("img"); 232 avatarElement.src = this.options.avatar; 233 234 avatarElement.className = "toastify-avatar"; 235 236 if (this.options.position == "left") { 237 // Adding close icon on the left of content 238 divElement.appendChild(avatarElement); 239 } else { 240 // Adding close icon on the right of content 241 divElement.insertAdjacentElement("afterbegin", avatarElement); 242 } 243 } 244 } 245 246 // Adding a close icon to the toast 247 if (this.options.close === true) { 248 // Create a span for close element 249 let closeElement = document.createElement("button"); 250 closeElement.type = "button"; 251 closeElement.setAttribute("aria-label", "Close"); 252 closeElement.className = "toast-close"; 253 closeElement.innerHTML = "✖"; 254 255 // Triggering the removal of toast from DOM on close click 256 closeElement.addEventListener( 257 "click", 258 (event) => { 259 event.stopPropagation(); 260 this._removeElement(this.toastElement); 261 window.clearTimeout(this.toastElement.timeOutValue); 262 } 263 ); 264 265 //Calculating screen width 266 const width = window.innerWidth > 0 ? window.innerWidth : screen.width; 267 268 // Adding the close icon to the toast element 269 // Display on the right if screen width is less than or equal to 360px 270 if ((this.options.position == "left") && width > 360) { 271 // Adding close icon on the left of content 272 divElement.insertAdjacentElement("afterbegin", closeElement); 273 } else { 274 // Adding close icon on the right of content 275 divElement.appendChild(closeElement); 276 } 277 } 278 279 // Clear timeout while toast is focused 280 if (this.options.stopOnFocus && this.options.duration > 0) { 281 // stop countdown 282 divElement.addEventListener( 283 "mouseover", 284 (event) => { 285 window.clearTimeout(divElement.timeOutValue); 286 } 287 ) 288 // add back the timeout 289 divElement.addEventListener( 290 "mouseleave", 291 () => { 292 divElement.timeOutValue = window.setTimeout( 293 () => { 294 // Remove the toast from DOM 295 this._removeElement(divElement); 296 }, 297 this.options.duration 298 ) 299 } 300 ) 301 } 302 303 // Adding an on-click destination path 304 if (typeof this.options.destination !== "undefined") { 305 divElement.addEventListener( 306 "click", 307 (event) => { 308 event.stopPropagation(); 309 if (this.options.newWindow === true) { 310 window.open(this.options.destination, "_blank"); 311 } else { 312 window.location = this.options.destination; 313 } 314 } 315 ); 316 } 317 318 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") { 319 divElement.addEventListener( 320 "click", 321 (event) => { 322 event.stopPropagation(); 323 this.options.onClick(); 324 } 325 ); 326 } 327 328 // Adding offset 329 if (typeof this.options.offset === "object") { 330 331 const x = this._getAxisOffsetAValue("x", this.options); 332 const y = this._getAxisOffsetAValue("y", this.options); 333 334 const xOffset = this.options.position == "left" ? x : `-${x}`; 335 const yOffset = this.options.gravity == "toastify-top" ? y : `-${y}`; 336 337 divElement.style.transform = `translate(${xOffset},${yOffset})`; 338 339 } 340 341 // Returning the generated element 342 return divElement; 343 } 344 345 /** 346 * Remove the toast from the DOM 347 * @param {Element} toastElement 348 */ 349 _removeElement(toastElement) { 350 // Hiding the element 351 toastElement.className = toastElement.className.replace(" on", ""); 352 353 // Removing the element from DOM after transition end 354 window.setTimeout( 355 () => { 356 // remove options node if any 357 if (this.options.node && this.options.node.parentNode) { 358 this.options.node.parentNode.removeChild(this.options.node); 359 } 360 361 // Remove the element from the DOM, only when the parent node was not removed before. 362 if (toastElement.parentNode) { 363 toastElement.parentNode.removeChild(toastElement); 364 } 365 366 // Calling the callback function 367 this.options.callback.call(toastElement); 368 369 // Repositioning the toasts again 370 this._reposition(); 371 }, 372 400 373 ); // Binding `this` for function invocation 374 } 375 376 /** 377 * Position the toast on the DOM 378 * @private 379 */ 380 _reposition() { 381 382 // Top margins with gravity 383 let topLeftOffsetSize = { 384 top: 15, 385 bottom: 15, 386 }; 387 let topRightOffsetSize = { 388 top: 15, 389 bottom: 15, 390 }; 391 let offsetSize = { 392 top: 15, 393 bottom: 15, 394 }; 395 396 // Get all toast messages that have been added to the container (selector) 397 let allToasts = this._rootElement.querySelectorAll(".toastify"); 398 399 let classUsed; 400 401 // Modifying the position of each toast element 402 for (let i = 0; i < allToasts.length; i++) { 403 // Getting the applied gravity 404 if (allToasts[i].classList.contains("toastify-top") === true) { 405 classUsed = "toastify-top"; 406 } else { 407 classUsed = "toastify-bottom"; 408 } 409 410 let height = allToasts[i].offsetHeight; 411 classUsed = classUsed.substr(9, classUsed.length - 1) 412 // Spacing between toasts 413 let offset = 15; 414 415 let width = window.innerWidth > 0 ? window.innerWidth : screen.width; 416 417 // Show toast in center if screen with less than or equal to 360px 418 if (width <= 360) { 419 // Setting the position 420 allToasts[i].style[classUsed] = `${offsetSize[classUsed]}px`; 421 422 offsetSize[classUsed] += height + offset; 423 } else { 424 if (allToasts[i].classList.contains("toastify-left") === true) { 425 // Setting the position 426 allToasts[i].style[classUsed] = `${topLeftOffsetSize[classUsed]}px`; 427 428 topLeftOffsetSize[classUsed] += height + offset; 429 } else { 430 // Setting the position 431 allToasts[i].style[classUsed] = `${topRightOffsetSize[classUsed]}px`; 432 433 topRightOffsetSize[classUsed] += height + offset; 434 } 435 } 436 } 437 } 438 439 /** 440 * Helper function to get offset 441 * @param {string} axis - 'x' or 'y' 442 * @param {ToastifyConfigurationObject} options - The options object containing the offset object 443 */ 444 _getAxisOffsetAValue(axis, options) { 445 446 if (options.offset[axis]) { 447 if (isNaN(options.offset[axis])) { 448 return options.offset[axis]; 449 } else { 450 return `${options.offset[axis]}px`; 451 } 452 } 453 454 return '0px'; 455 456 } 457 458} 459 460 461// Returning the Toastify function to be assigned to the window object/module 462function StartToastifyInstance(options) { 463 return new Toastify(options); 464} 465 466export default StartToastifyInstance;
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.