├── example
├── pattern.png
├── script.js
└── script.css
├── .prettierrc
├── .travis.yml
├── .gitattributes
├── package.json
├── .gitignore
├── LICENSE
├── src
├── toastify.css
└── toastify.js
├── CHANGELOG.md
├── index.html
└── README.md
/example/pattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/skjnldsv/toastify-js/master/example/pattern.png
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": false,
3 | "printWidth": 80,
4 | "tabWidth": 2,
5 | "singleQuote": false,
6 | "trailingComma": "es5",
7 | "parser": "babylon",
8 | "noSemi": false
9 | }
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "8"
4 | script:
5 | - echo "skipping tests"
6 | deploy:
7 | skip_cleanup: true
8 | provider: npm
9 | email: $NPM_USERNAME
10 | api_key: $NPM_TOKEN
11 | on:
12 | branch: master
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "toastify-js",
3 | "version": "1.7.0",
4 | "description":
5 | "Toastify is a lightweight, vanilla JS toast notification library.",
6 | "main": "./src/toastify.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "git+https://github.com/apvarun/toastify-js.git"
10 | },
11 | "keywords": ["toastify", "javascript", "notifications", "toast"],
12 | "author": "Varun A P",
13 | "license": "MIT",
14 | "bugs": {
15 | "url": "https://github.com/apvarun/toastify-js/issues"
16 | },
17 | "homepage": "https://github.com/apvarun/toastify-js#readme"
18 | }
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 apvarun
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/example/script.js:
--------------------------------------------------------------------------------
1 | var bgColors = [
2 | "linear-gradient(to right, #00b09b, #96c93d)",
3 | "linear-gradient(to right, #ff5f6d, #ffc371)",
4 | ],
5 | i = 0;
6 |
7 | Toastify({
8 | text: "Hi",
9 | duration: 4500,
10 | destination: "https://github.com/apvarun/toastify-js",
11 | newWindow: true,
12 | gravity: "top",
13 | position: 'left',
14 | }).showToast();
15 |
16 | setTimeout(function() {
17 | Toastify({
18 | text: "Simple JavaScript Toasts",
19 | gravity: "top",
20 | position: 'center',
21 | backgroundColor: "#0f3443",
22 | }).showToast();
23 | }, 1000);
24 |
25 | // Options for the toast
26 | var options = {
27 | text: "Happy toasting!",
28 | duration: 2500,
29 | callback: function() {
30 | console.log("Toast hidden");
31 | Toastify.reposition();
32 | },
33 | close: true,
34 | backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
35 | };
36 |
37 | // Initializing the toast
38 | var myToast = Toastify(options);
39 |
40 | // Toast after delay
41 | setTimeout(function() {
42 | myToast.showToast();
43 | }, 4500);
44 |
45 | setTimeout(function() {
46 | Toastify({
47 | text: "Highly customizable",
48 | gravity: "bottom",
49 | position: 'left',
50 | close: true,
51 | backgroundColor: "linear-gradient(to right, #ff5f6d, #ffc371)",
52 | }).showToast();
53 | }, 3000);
54 |
55 | // Displaying toast on manual action `Try`
56 | document.getElementById("new-toast").addEventListener("click", function() {
57 | Toastify({
58 | text: "I am a toast",
59 | duration: 3000,
60 | close: i % 3 ? true : false,
61 | backgroundColor: bgColors[i % 2],
62 | }).showToast();
63 | i++;
64 | });
65 |
--------------------------------------------------------------------------------
/src/toastify.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Toastify js 1.7.0
3 | * https://github.com/apvarun/toastify-js
4 | * @license MIT licensed
5 | *
6 | * Copyright (C) 2018 Varun A P
7 | */
8 |
9 | .toastify {
10 | padding: 12px 20px;
11 | color: #ffffff;
12 | display: inline-block;
13 | box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
14 | background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
15 | background: linear-gradient(135deg, #73a5ff, #5477f5);
16 | position: fixed;
17 | opacity: 0;
18 | transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
19 | border-radius: 2px;
20 | cursor: pointer;
21 | text-decoration: none;
22 | max-width: calc(50% - 20px);
23 | z-index: 2147483647;
24 | }
25 |
26 | .toastify.on {
27 | opacity: 1;
28 | }
29 |
30 | .toast-close {
31 | opacity: 0.4;
32 | padding: 0 5px;
33 | }
34 |
35 | .toastify-right {
36 | right: 15px;
37 | }
38 |
39 | .toastify-left {
40 | left: 15px;
41 | }
42 |
43 | .toastify-top {
44 | top: -150px;
45 | }
46 |
47 | .toastify-bottom {
48 | bottom: -150px;
49 | }
50 |
51 | .toastify-rounded {
52 | border-radius: 25px;
53 | }
54 |
55 | .toastify-avatar {
56 | width: 1.5em;
57 | height: 1.5em;
58 | margin: 0 5px;
59 | border-radius: 2px;
60 | }
61 |
62 | .toastify-center {
63 | margin-left: auto;
64 | margin-right: auto;
65 | left: 0;
66 | right: 0;
67 | max-width: fit-content;
68 | }
69 |
70 | @media only screen and (max-width: 360px) {
71 | .toastify-right, .toastify-left {
72 | margin-left: auto;
73 | margin-right: auto;
74 | left: 0;
75 | right: 0;
76 | max-width: fit-content;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/example/script.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | html, body {
6 | height: 100%;
7 | }
8 |
9 | body {
10 | font-family: Helvetica, Arial, sans-serif;
11 | background-size: 100%;
12 | margin: 0;
13 | padding: 0;
14 | color: #424242;
15 | }
16 |
17 | .container {
18 | overflow: hidden;
19 | display: flex;
20 | height: 100%;
21 | justify-content: center;
22 | flex-direction: column;
23 | align-items: center;
24 | background-color: whitesmoke;
25 | background-image: url("./pattern.png");
26 | }
27 |
28 | .hidden {
29 | display: none;
30 | }
31 |
32 | .docs {
33 | display: flex;
34 | justify-content: center;
35 | flex-direction: column;
36 | align-items: center;
37 | background-color: white;
38 | border: 1px solid #e3e3e3;
39 | padding: 20px 20px;
40 | width: 60%;
41 | border-radius: 4px;
42 | }
43 |
44 | .docs h2 {
45 | margin-top: 0px;
46 | }
47 |
48 | code p {
49 | margin: 2px;
50 | }
51 |
52 | .pad-left {
53 | padding-left: 20px;
54 | }
55 |
56 | .buttons {
57 | margin: 20px;
58 | display: flex;
59 | flex-wrap: wrap;
60 | justify-content: center;
61 | }
62 |
63 | .button {
64 | overflow: hidden;
65 | margin: 10px;
66 | padding: 12px 12px;
67 | cursor: pointer;
68 | -webkit-transition: all 200ms ease-in-out;
69 | transition: all 200ms ease-in-out;
70 | text-align: center;
71 | white-space: nowrap;
72 | text-decoration: none;
73 | text-transform: none;
74 | text-transform: capitalize;
75 | border-radius: 4px;
76 | font-size: 13px;
77 | font-weight: 500;
78 | line-height: 1.3;
79 | min-width: 100px;
80 | display: inline-block;
81 | box-shadow: 0 5px 20px rgba(22, 22, 22, 0.15);
82 | color: #5477f5;
83 | background-color: Snow;
84 | border: 1px solid #5477f5;
85 | }
86 |
87 | .button:hover {
88 | color: #FFFFFF;
89 | background: linear-gradient(135deg, #73a5ff, #5477f5);
90 | border: 1px solid transparent;
91 | }
92 |
93 | .repo {
94 | margin: 10px;
95 | }
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All the changes made to toastify-js library.
4 |
5 | ## [1.7.0] - 2020-03-01
6 |
7 | * To be able to set `stopOnFocus` for toasts without close icon
8 | * Bugfix: `duration` can be infinite by setting as `0`
9 | * Bugfix: Prevent errors when parent node is removed from DOM while using frameworks
10 | * Bugfix: IE 9/10 compatibility fix
11 |
12 | ## [1.6.2] - 2020-01-03
13 |
14 | * Bugfix: Closing the toast when custom close icon from icon fonts are used
15 |
16 | ## [1.6.1] - 2019-06-29
17 |
18 | * Bugfix: Disabling `stopOnFocus`
19 |
20 | ## [1.6.0] - 2019-06-29
21 |
22 | * **Deprecation Warning**: Migrating from `positionLeft` property to `position`
23 | * Property `position` to support `center` as a value along with `left` and `right` - Useful for centering toast messages in the page
24 |
25 | ## [1.5.0] - 2019-05-30
26 |
27 | * Added persistant toast option with ability to programatically close it
28 |
29 | ## [1.4.0] - 2019-05-12
30 |
31 | * **Breaking Change**: Manually import CSS while using as module in your modern JavaScript applications
32 | * Ability to pause the toast dismiss timer on hover (Using `stopOnFocus` property)
33 |
34 | ## [1.3.2] - 2018-12-6
35 |
36 | * Added z-index attribute
37 |
38 | ## [1.2.1] - 2018-05-31
39 |
40 | * Added support for Classes. Now custom classes can be added to the toast while creating it
41 |
42 | ## [1.2.0] - 2018-03-05
43 |
44 | * Fix issue when `destination` and `close` options is used at the same time
45 |
46 | ## [1.1.0] - 2018-02-18
47 |
48 | * Browser support extended to IE10+ without any polyfills
49 |
50 | ## [1.0.0] - 2018-02-17
51 |
52 | * Support for modules
53 |
54 | ## [0.0.6] - 2017-09-09
55 |
56 | * Support for changing background [Options]
57 | * Optimized toast positioning logic
58 | * Added changelog for library update tracking
59 |
60 | ## [0.0.5] - 2017-09-06
61 |
62 | * Support for toast messages on mobile screens
63 | * Tweaked close icon
64 |
65 | ## [0.0.4] - 2017-09-05
66 |
67 | * Support for positioning of toasts on the page
68 |
69 | ## [0.0.3] - 2017-09-05
70 |
71 | * Close buton for toasts [Options]
72 |
73 | ## [0.0.2] - 2017-09-04
74 |
75 | * Option to add on-click link for toasts
76 | * Updated comments for code readability
77 |
78 | ## [0.0.1] - 2017-09-02
79 |
80 | * Initial Release
81 | * Added Preview page
82 | * Optimized function structure
83 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Toastify JS - Pure JavaScript Toast Notificaton Library
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
Toastify JS
20 |
21 |
Better notification messages
22 |
28 |
29 |
Usage
30 |
31 | Toastify({
32 | text: "This is a toast",
33 | duration: 3000
34 | }).showToast();
35 |
36 |
37 |
38 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
58 |
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Toastify
2 |
3 | 
4 | 
5 |
6 | [](https://www.npmjs.com/package/toastify-js)
7 |
8 | Toastify is a lightweight, vanilla JS toast notification library.
9 |
10 | ## Demo
11 |
12 | [Click here](https://apvarun.github.io/toastify-js/)
13 |
14 | ## Features
15 |
16 | * Multiple stacked notifications
17 | * Customizable
18 | * No blocking of execution thread
19 |
20 | ### Customization options
21 |
22 | * Notification Text
23 | * Duration
24 | * Toast background color
25 | * Close icon display
26 | * Display position
27 |
28 | ## Installation
29 |
30 | #### Toastify now supports installation via NPM
31 |
32 | * Run the below command to add toastify-js to your exisitng or new project.
33 |
34 | ```
35 | npm install --save toastify-js
36 | ```
37 |
38 | or
39 |
40 | ```
41 | yarn add toastify-js -S
42 | ```
43 |
44 | * Import toastify-js into your module to start using it.
45 |
46 | ```
47 | import Toastify from 'toastify-js'
48 | ```
49 |
50 | You can use the default CSS from Toastify as below and later override it or choose to write your own CSS.
51 |
52 | ```
53 | import "toastify-js/src/toastify.css"
54 | ```
55 |
56 | #### Adding ToastifyJs to HTML page using the traditional method
57 |
58 | To start using **Toastify**, add the following CSS on to your page.
59 |
60 | ```html
61 |
62 | ```
63 |
64 | And the script at the bottom of the page
65 |
66 | ```html
67 |
68 | ```
69 |
70 | > Files are delivered via the CDN service provided by [jsdeliver](https://www.jsdelivr.com/)
71 |
72 | ## Documentation
73 |
74 | ```javascript
75 | Toastify({
76 | text: "This is a toast",
77 | duration: 3000,
78 | destination: "https://github.com/apvarun/toastify-js",
79 | newWindow: true,
80 | close: true,
81 | gravity: "top", // `top` or `bottom`
82 | position: 'left', // `left`, `center` or `right`
83 | backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
84 | stopOnFocus: true, // Prevents dismissing of toast on hover
85 | onClick: function(){} // Callback after click
86 | }).showToast();
87 | ```
88 |
89 | > Toast messages will be centered on devices with screen width less than 360px.
90 |
91 | * See the [changelog](https://github.com/apvarun/toastify-js/blob/master/CHANGELOG.md)
92 |
93 | ### Add own custom classes
94 |
95 | If you want to use custom classes on the toast for customizing (like info or warning for example), you can do that as follows:
96 |
97 | ```javascript
98 | Toastify({
99 | text: "This is a toast",
100 | backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
101 | className: "info",
102 | }).showToast();
103 | ```
104 |
105 | Multiple classes also can be assigned as a string, with spaces between class names.
106 |
107 | ## API
108 |
109 | | Option Key | type | Usage | Defaults |
110 | |-----------------|----------------------|----------------------------------------------------------------------------|-------------|
111 | | text | string | Message to be displayed in the toast | "Hi there!" |
112 | | duration | number | Duration for which the toast should be displayed. 0 for permanent toast | 3000 |
113 | | selector | string | CSS Selector on which the toast should be added | body |
114 | | destination | URL string | URL to which the browser should be navigated on click of the toast | |
115 | | newWindow | boolean | Decides whether the `destination` should be opened in a new window or not | false |
116 | | close | boolean | To show the close icon or not | false |
117 | | gravity | "top" or "bottom" | To show the toast from top or bottom | "top" |
118 | | position | "left" or "right" | To show the toast on left or right | "right" |
119 | | backgroundColor | CSS background value | Sets the background color of the toast | |
120 | | avatar | URL string | Image/icon to be shown before text | |
121 | | className | string | Ability to provide custom class name for further customization | |
122 | | stopOnFocus | boolean | To stop timer when hovered over the toast (Only if duration is set) | true |
123 | | callback | Function | Invoked when the toast is dismissed | |
124 | | onClick | Function | Invoked when the toast is clicked | |
125 |
126 | ## Browsers support
127 |
128 | | ![][ie] IE / Edge | ![][firefox] Firefox | ![][chrome] Chrome | ![][safari] Safari | ![][opera] Opera |
129 | | ---------------------- | ------------------------- | ----------------------- | ----------------------- | --------------------- |
130 | | IE10, IE11, Edge | last 10 versions | last 10 versions | last 10 versions | last 10 versions |
131 |
132 | ## Contributors
133 |
134 |
135 |
136 |
137 |
225 |
226 |
227 |
228 | ## License
229 |
230 | MIT © [Varun A P](https://github.com/apvarun)
231 |
232 | [ie]: https://raw.githubusercontent.com/godban/browsers-support-badges/master/src/images/edge.png
233 | [firefox]: https://raw.githubusercontent.com/godban/browsers-support-badges/master/src/images/firefox.png
234 | [chrome]: https://raw.githubusercontent.com/godban/browsers-support-badges/master/src/images/chrome.png
235 | [safari]: https://raw.githubusercontent.com/godban/browsers-support-badges/master/src/images/safari.png
236 | [opera]: https://raw.githubusercontent.com/godban/browsers-support-badges/master/src/images/opera.png
237 |
--------------------------------------------------------------------------------
/src/toastify.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Toastify js 1.7.0
3 | * https://github.com/apvarun/toastify-js
4 | * @license MIT licensed
5 | *
6 | * Copyright (C) 2018 Varun A P
7 | */
8 | (function(root, factory) {
9 | if (typeof module === "object" && module.exports) {
10 | module.exports = factory();
11 | } else {
12 | root.Toastify = factory();
13 | }
14 | })(this, function(global) {
15 | // Object initialization
16 | var Toastify = function(options) {
17 | // Returning a new init object
18 | return new Toastify.lib.init(options);
19 | },
20 | // Library version
21 | version = "1.7.0";
22 |
23 | // Defining the prototype of the object
24 | Toastify.lib = Toastify.prototype = {
25 | toastify: version,
26 |
27 | constructor: Toastify,
28 |
29 | // Initializing the object with required parameters
30 | init: function(options) {
31 | // Verifying and validating the input object
32 | if (!options) {
33 | options = {};
34 | }
35 |
36 | // Creating the options object
37 | this.options = {};
38 |
39 | this.toastElement = null;
40 |
41 | // Validating the options
42 | this.options.text = options.text || "Hi there!"; // Display message
43 | this.options.duration = options.duration === 0 ? 0 : options.duration || 3000; // Display duration
44 | this.options.selector = options.selector; // Parent selector
45 | this.options.callback = options.callback || function() {}; // Callback after display
46 | this.options.destination = options.destination; // On-click destination
47 | this.options.newWindow = options.newWindow || false; // Open destination in new window
48 | this.options.close = options.close || false; // Show toast close icon
49 | this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : "toastify-top"; // toast position - top or bottom
50 | this.options.positionLeft = options.positionLeft || false; // toast position - left or right
51 | this.options.position = options.position || ''; // toast position - left or right
52 | this.options.backgroundColor = options.backgroundColor; // toast background color
53 | this.options.avatar = options.avatar || ""; // img element src - url or a path
54 | this.options.className = options.className || ""; // additional class names for the toast
55 | this.options.stopOnFocus = options.stopOnFocus === undefined? true: options.stopOnFocus; // stop timeout on focus
56 | this.options.onClick = options.onClick; // Callback after click
57 |
58 | // Returning the current object for chaining functions
59 | return this;
60 | },
61 |
62 | // Building the DOM element
63 | buildToast: function() {
64 | // Validating if the options are defined
65 | if (!this.options) {
66 | throw "Toastify is not initialized";
67 | }
68 |
69 | // Creating the DOM object
70 | var divElement = document.createElement("div");
71 | divElement.className = "toastify on " + this.options.className;
72 |
73 | // Positioning toast to left or right or center
74 | if (!!this.options.position) {
75 | divElement.className += " toastify-" + this.options.position;
76 | } else {
77 | // To be depreciated in further versions
78 | if (this.options.positionLeft === true) {
79 | divElement.className += " toastify-left";
80 | console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
81 | } else {
82 | // Default position
83 | divElement.className += " toastify-right";
84 | }
85 | }
86 |
87 | // Assigning gravity of element
88 | divElement.className += " " + this.options.gravity;
89 |
90 | if (this.options.backgroundColor) {
91 | divElement.style.background = this.options.backgroundColor;
92 | }
93 |
94 | // Adding the toast message
95 | divElement.innerHTML = this.options.text;
96 |
97 | if (this.options.avatar !== "") {
98 | var avatarElement = document.createElement("img");
99 | avatarElement.src = this.options.avatar;
100 |
101 | avatarElement.className = "toastify-avatar";
102 |
103 | if (this.options.position == "left" || this.options.positionLeft === true) {
104 | // Adding close icon on the left of content
105 | divElement.appendChild(avatarElement);
106 | } else {
107 | // Adding close icon on the right of content
108 | divElement.insertAdjacentElement("beforeend", avatarElement);
109 | }
110 | }
111 |
112 | // Adding a close icon to the toast
113 | if (this.options.close === true) {
114 | // Create a span for close element
115 | var closeElement = document.createElement("span");
116 | closeElement.innerHTML = "✖";
117 |
118 | closeElement.className = "toast-close";
119 |
120 | // Triggering the removal of toast from DOM on close click
121 | closeElement.addEventListener(
122 | "click",
123 | function(event) {
124 | event.stopPropagation();
125 | this.removeElement(this.toastElement);
126 | window.clearTimeout(this.toastElement.timeOutValue);
127 | }.bind(this)
128 | );
129 |
130 | //Calculating screen width
131 | var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
132 |
133 | // Adding the close icon to the toast element
134 | // Display on the right if screen width is less than or equal to 360px
135 | if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
136 | // Adding close icon on the left of content
137 | divElement.insertAdjacentElement("afterbegin", closeElement);
138 | } else {
139 | // Adding close icon on the right of content
140 | divElement.appendChild(closeElement);
141 | }
142 | }
143 |
144 | // Clear timeout while toast is focused
145 | if (this.options.stopOnFocus && this.options.duration > 0) {
146 | const self = this;
147 | // stop countdown
148 | divElement.addEventListener(
149 | "mouseover",
150 | function(event) {
151 | window.clearTimeout(divElement.timeOutValue);
152 | }
153 | )
154 | // add back the timeout
155 | divElement.addEventListener(
156 | "mouseleave",
157 | function() {
158 | divElement.timeOutValue = window.setTimeout(
159 | function() {
160 | // Remove the toast from DOM
161 | self.removeElement(divElement);
162 | },
163 | self.options.duration
164 | )
165 | }
166 | )
167 | }
168 |
169 | // Adding an on-click destination path
170 | if (typeof this.options.destination !== "undefined") {
171 | divElement.addEventListener(
172 | "click",
173 | function(event) {
174 | event.stopPropagation();
175 | if (this.options.newWindow === true) {
176 | window.open(this.options.destination, "_blank");
177 | } else {
178 | window.location = this.options.destination;
179 | }
180 | }.bind(this)
181 | );
182 | }
183 |
184 | if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
185 | divElement.addEventListener(
186 | "click",
187 | function(event) {
188 | event.stopPropagation();
189 | this.options.onClick();
190 | }.bind(this)
191 | );
192 | }
193 |
194 | // Returning the generated element
195 | return divElement;
196 | },
197 |
198 | // Displaying the toast
199 | showToast: function() {
200 | // Creating the DOM object for the toast
201 | this.toastElement = this.buildToast();
202 |
203 | // Getting the root element to with the toast needs to be added
204 | var rootElement;
205 | if (typeof this.options.selector === "undefined") {
206 | rootElement = document.body;
207 | } else {
208 | rootElement = document.getElementById(this.options.selector);
209 | }
210 |
211 | // Validating if root element is present in DOM
212 | if (!rootElement) {
213 | throw "Root element is not defined";
214 | }
215 |
216 | // Adding the DOM element
217 | rootElement.insertBefore(this.toastElement, rootElement.firstChild);
218 |
219 | // Repositioning the toasts in case multiple toasts are present
220 | Toastify.reposition();
221 |
222 | if (this.options.duration > 0) {
223 | this.toastElement.timeOutValue = window.setTimeout(
224 | function() {
225 | // Remove the toast from DOM
226 | this.removeElement(this.toastElement);
227 | }.bind(this),
228 | this.options.duration
229 | ); // Binding `this` for function invocation
230 | }
231 |
232 | // Supporting function chaining
233 | return this;
234 | },
235 |
236 | hideToast: function() {
237 | if (this.toastElement.timeOutValue) {
238 | clearTimeout(this.toastElement.timeOutValue);
239 | }
240 | this.removeElement(this.toastElement);
241 | },
242 |
243 | // Removing the element from the DOM
244 | removeElement: function(toastElement) {
245 | // Hiding the element
246 | // toastElement.classList.remove("on");
247 | toastElement.className = toastElement.className.replace(" on", "");
248 |
249 | // Removing the element from DOM after transition end
250 | window.setTimeout(
251 | function() {
252 | // Remove the elemenf from the DOM, only when the parent node was not removed before.
253 | if (toastElement.parentNode) {
254 | toastElement.parentNode.removeChild(toastElement);
255 | }
256 |
257 | // Calling the callback function
258 | this.options.callback.call(toastElement);
259 |
260 | // Repositioning the toasts again
261 | Toastify.reposition();
262 | }.bind(this),
263 | 400
264 | ); // Binding `this` for function invocation
265 | },
266 | };
267 |
268 | // Positioning the toasts on the DOM
269 | Toastify.reposition = function() {
270 | // Top margins with gravity
271 | var topLeftOffsetSize = {
272 | top: 15,
273 | bottom: 15,
274 | };
275 | var topRightOffsetSize = {
276 | top: 15,
277 | bottom: 15,
278 | };
279 | var offsetSize = {
280 | top: 15,
281 | bottom: 15,
282 | };
283 |
284 | // Get all toast messages on the DOM
285 | var allToasts = document.getElementsByClassName("toastify");
286 |
287 | var classUsed;
288 |
289 | // Modifying the position of each toast element
290 | for (var i = 0; i < allToasts.length; i++) {
291 | // Getting the applied gravity
292 | if (containsClass(allToasts[i], "toastify-top") === true) {
293 | classUsed = "toastify-top";
294 | } else {
295 | classUsed = "toastify-bottom";
296 | }
297 |
298 | var height = allToasts[i].offsetHeight;
299 | classUsed = classUsed.substr(9, classUsed.length-1)
300 | // Spacing between toasts
301 | var offset = 15;
302 |
303 | var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
304 |
305 | // Show toast in center if screen with less than or qual to 360px
306 | if (width <= 360) {
307 | // Setting the position
308 | allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
309 |
310 | offsetSize[classUsed] += height + offset;
311 | } else {
312 | if (containsClass(allToasts[i], "toastify-left") === true) {
313 | // Setting the position
314 | allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
315 |
316 | topLeftOffsetSize[classUsed] += height + offset;
317 | } else {
318 | // Setting the position
319 | allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
320 |
321 | topRightOffsetSize[classUsed] += height + offset;
322 | }
323 | }
324 | }
325 |
326 | // Supporting function chaining
327 | return this;
328 | };
329 |
330 | function containsClass(elem, yourClass) {
331 | if (!elem || typeof yourClass !== "string") {
332 | return false;
333 | } else if (
334 | elem.className &&
335 | elem.className
336 | .trim()
337 | .split(/\s+/gi)
338 | .indexOf(yourClass) > -1
339 | ) {
340 | return true;
341 | } else {
342 | return false;
343 | }
344 | }
345 |
346 | // Setting up the prototype for the init object
347 | Toastify.lib.init.prototype = Toastify.lib;
348 |
349 | // Returning the Toastify function to be assigned to the window object/module
350 | return Toastify;
351 | });
352 |
--------------------------------------------------------------------------------