Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
33580 ranu 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
(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.12.0";
22
 
23
  // Set the default global options
24
  Toastify.defaults = {
25
    oldestFirst: true,
26
    text: "Toastify is awesome!",
27
    node: undefined,
28
    duration: 3000,
29
    selector: undefined,
30
    callback: function () {
31
    },
32
    destination: undefined,
33
    newWindow: false,
34
    close: false,
35
    gravity: "toastify-top",
36
    positionLeft: false,
37
    position: '',
38
    backgroundColor: '',
39
    avatar: "",
40
    className: "",
41
    stopOnFocus: true,
42
    onClick: function () {
43
    },
44
    offset: {x: 0, y: 0},
45
    escapeMarkup: true,
46
    ariaLive: 'polite',
47
    style: {background: ''}
48
  };
49
 
50
  // Defining the prototype of the object
51
  Toastify.lib = Toastify.prototype = {
52
    toastify: version,
53
 
54
    constructor: Toastify,
55
 
56
    // Initializing the object with required parameters
57
    init: function (options) {
58
      // Verifying and validating the input object
59
      if (!options) {
60
        options = {};
61
      }
62
 
63
      // Creating the options object
64
      this.options = {};
65
 
66
      this.toastElement = null;
67
 
68
      // Validating the options
69
      this.options.text = options.text || Toastify.defaults.text; // Display message
70
      this.options.node = options.node || Toastify.defaults.node;  // Display content as node
71
      this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
72
      this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
73
      this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
74
      this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
75
      this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
76
      this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
77
      this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
78
      this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
79
      this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
80
      this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
81
      this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
82
      this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
83
      this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
84
      this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
85
      this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
86
      this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
87
      this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
88
      this.options.style = options.style || Toastify.defaults.style;
89
      if (options.backgroundColor) {
90
        this.options.style.background = options.backgroundColor;
91
      }
92
 
93
      // Returning the current object for chaining functions
94
      return this;
95
    },
96
 
97
    // Building the DOM element
98
    buildToast: function () {
99
      // Validating if the options are defined
100
      if (!this.options) {
101
        throw "Toastify is not initialized";
102
      }
103
 
104
      // Creating the DOM object
105
      var divElement = document.createElement("div");
106
      divElement.className = "toastify on " + this.options.className;
107
 
108
      // Positioning toast to left or right or center
109
      if (!!this.options.position) {
110
        divElement.className += " toastify-" + this.options.position;
111
      } else {
112
        // To be depreciated in further versions
113
        if (this.options.positionLeft === true) {
114
          divElement.className += " toastify-left";
115
          console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
116
        } else {
117
          // Default position
118
          divElement.className += " toastify-right";
119
        }
120
      }
121
 
122
      // Assigning gravity of element
123
      divElement.className += " " + this.options.gravity;
124
 
125
      if (this.options.backgroundColor) {
126
        // This is being deprecated in favor of using the style HTML DOM property
127
        console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
128
      }
129
 
130
      // Loop through our style object and apply styles to divElement
131
      for (var property in this.options.style) {
132
        divElement.style[property] = this.options.style[property];
133
      }
134
 
135
      // Announce the toast to screen readers
136
      if (this.options.ariaLive) {
137
        divElement.setAttribute('aria-live', this.options.ariaLive)
138
      }
139
 
140
      // Adding the toast message/node
141
      if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
142
        // If we have a valid node, we insert it
143
        divElement.appendChild(this.options.node)
144
      } else {
145
        if (this.options.escapeMarkup) {
146
          divElement.innerText = this.options.text;
147
        } else {
148
          divElement.innerHTML = this.options.text;
149
        }
150
 
151
        if (this.options.avatar !== "") {
152
          var avatarElement = document.createElement("img");
153
          avatarElement.src = this.options.avatar;
154
 
155
          avatarElement.className = "toastify-avatar";
156
 
157
          if (this.options.position == "left" || this.options.positionLeft === true) {
158
            // Adding close icon on the left of content
159
            divElement.appendChild(avatarElement);
160
          } else {
161
            // Adding close icon on the right of content
162
            divElement.insertAdjacentElement("afterbegin", avatarElement);
163
          }
164
        }
165
      }
166
 
167
      // Adding a close icon to the toast
168
      if (this.options.close === true) {
169
        // Create a span for close element
170
        var closeElement = document.createElement("button");
171
        closeElement.type = "button";
172
        closeElement.setAttribute("aria-label", "Close");
173
        closeElement.className = "toast-close";
174
        closeElement.innerHTML = "✖";
175
 
176
        // Triggering the removal of toast from DOM on close click
177
        closeElement.addEventListener(
178
            "click",
179
            function (event) {
180
              event.stopPropagation();
181
              this.removeElement(this.toastElement);
182
              window.clearTimeout(this.toastElement.timeOutValue);
183
            }.bind(this)
184
        );
185
 
186
        //Calculating screen width
187
        var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
188
 
189
        // Adding the close icon to the toast element
190
        // Display on the right if screen width is less than or equal to 360px
191
        if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
192
          // Adding close icon on the left of content
193
          divElement.insertAdjacentElement("afterbegin", closeElement);
194
        } else {
195
          // Adding close icon on the right of content
196
          divElement.appendChild(closeElement);
197
        }
198
      }
199
 
200
      // Clear timeout while toast is focused
201
      if (this.options.stopOnFocus && this.options.duration > 0) {
202
        var self = this;
203
        // stop countdown
204
        divElement.addEventListener(
205
            "mouseover",
206
            function (event) {
207
              window.clearTimeout(divElement.timeOutValue);
208
            }
209
        )
210
        // add back the timeout
211
        divElement.addEventListener(
212
            "mouseleave",
213
            function () {
214
              divElement.timeOutValue = window.setTimeout(
215
                  function () {
216
                    // Remove the toast from DOM
217
                    self.removeElement(divElement);
218
                  },
219
                  self.options.duration
220
              )
221
            }
222
        )
223
      }
224
 
225
      // Adding an on-click destination path
226
      if (typeof this.options.destination !== "undefined") {
227
        divElement.addEventListener(
228
            "click",
229
            function (event) {
230
              event.stopPropagation();
231
              if (this.options.newWindow === true) {
232
                window.open(this.options.destination, "_blank");
233
              } else {
234
                window.location = this.options.destination;
235
              }
236
            }.bind(this)
237
        );
238
      }
239
 
240
      if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
241
        divElement.addEventListener(
242
            "click",
243
            function (event) {
244
              event.stopPropagation();
245
              this.options.onClick();
246
            }.bind(this)
247
        );
248
      }
249
 
250
      // Adding offset
251
      if (typeof this.options.offset === "object") {
252
 
253
        var x = getAxisOffsetAValue("x", this.options);
254
        var y = getAxisOffsetAValue("y", this.options);
255
 
256
        var xOffset = this.options.position == "left" ? x : "-" + x;
257
        var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
258
 
259
        divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
260
 
261
      }
262
 
263
      // Returning the generated element
264
      return divElement;
265
    },
266
 
267
    // Displaying the toast
268
    showToast: function () {
269
      // Creating the DOM object for the toast
270
      this.toastElement = this.buildToast();
271
 
272
      // Getting the root element to with the toast needs to be added
273
      var rootElement;
274
      if (typeof this.options.selector === "string") {
275
        rootElement = document.getElementById(this.options.selector);
276
      } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
277
        rootElement = this.options.selector;
278
      } else {
279
        rootElement = document.body;
280
      }
281
 
282
      // Validating if root element is present in DOM
283
      if (!rootElement) {
284
        throw "Root element is not defined";
285
      }
286
 
287
      // Adding the DOM element
288
      var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
289
      rootElement.insertBefore(this.toastElement, elementToInsert);
290
 
291
      // Repositioning the toasts in case multiple toasts are present
292
      Toastify.reposition();
293
 
294
      if (this.options.duration > 0) {
295
        this.toastElement.timeOutValue = window.setTimeout(
296
            function () {
297
              // Remove the toast from DOM
298
              this.removeElement(this.toastElement);
299
            }.bind(this),
300
            this.options.duration
301
        ); // Binding `this` for function invocation
302
      }
303
 
304
      // Supporting function chaining
305
      return this;
306
    },
307
 
308
    hideToast: function () {
309
      if (this.toastElement.timeOutValue) {
310
        clearTimeout(this.toastElement.timeOutValue);
311
      }
312
      this.removeElement(this.toastElement);
313
    },
314
 
315
    // Removing the element from the DOM
316
    removeElement: function (toastElement) {
317
      // Hiding the element
318
      // toastElement.classList.remove("on");
319
      toastElement.className = toastElement.className.replace(" on", "");
320
 
321
      // Removing the element from DOM after transition end
322
      window.setTimeout(
323
          function () {
324
            // remove options node if any
325
            if (this.options.node && this.options.node.parentNode) {
326
              this.options.node.parentNode.removeChild(this.options.node);
327
            }
328
 
329
            // Remove the element from the DOM, only when the parent node was not removed before.
330
            if (toastElement.parentNode) {
331
              toastElement.parentNode.removeChild(toastElement);
332
            }
333
 
334
            // Calling the callback function
335
            this.options.callback.call(toastElement);
336
 
337
            // Repositioning the toasts again
338
            Toastify.reposition();
339
          }.bind(this),
340
          400
341
      ); // Binding `this` for function invocation
342
    },
343
  };
344
 
345
  // Positioning the toasts on the DOM
346
  Toastify.reposition = function () {
347
 
348
    // Top margins with gravity
349
    var topLeftOffsetSize = {
350
      top: 15,
351
      bottom: 15,
352
    };
353
    var topRightOffsetSize = {
354
      top: 15,
355
      bottom: 15,
356
    };
357
    var offsetSize = {
358
      top: 15,
359
      bottom: 15,
360
    };
361
 
362
    // Get all toast messages on the DOM
363
    var allToasts = document.getElementsByClassName("toastify");
364
 
365
    var classUsed;
366
 
367
    // Modifying the position of each toast element
368
    for (var i = 0; i < allToasts.length; i++) {
369
      // Getting the applied gravity
370
      if (containsClass(allToasts[i], "toastify-top") === true) {
371
        classUsed = "toastify-top";
372
      } else {
373
        classUsed = "toastify-bottom";
374
      }
375
 
376
      var height = allToasts[i].offsetHeight;
377
      classUsed = classUsed.substr(9, classUsed.length - 1)
378
      // Spacing between toasts
379
      var offset = 15;
380
 
381
      var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
382
 
383
      // Show toast in center if screen with less than or equal to 360px
384
      if (width <= 360) {
385
        // Setting the position
386
        allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
387
 
388
        offsetSize[classUsed] += height + offset;
389
      } else {
390
        if (containsClass(allToasts[i], "toastify-left") === true) {
391
          // Setting the position
392
          allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
393
 
394
          topLeftOffsetSize[classUsed] += height + offset;
395
        } else {
396
          // Setting the position
397
          allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
398
 
399
          topRightOffsetSize[classUsed] += height + offset;
400
        }
401
      }
402
    }
403
 
404
    // Supporting function chaining
405
    return this;
406
  };
407
 
408
  // Helper function to get offset.
409
  function getAxisOffsetAValue(axis, options) {
410
 
411
    if (options.offset[axis]) {
412
      if (isNaN(options.offset[axis])) {
413
        return options.offset[axis];
414
      } else {
415
        return options.offset[axis] + 'px';
416
      }
417
    }
418
 
419
    return '0px';
420
 
421
  }
422
 
423
  function containsClass(elem, yourClass) {
424
    if (!elem || typeof yourClass !== "string") {
425
      return false;
426
    } else if (
427
        elem.className &&
428
        elem.className
429
            .trim()
430
            .split(/\s+/gi)
431
            .indexOf(yourClass) > -1
432
    ) {
433
      return true;
434
    } else {
435
      return false;
436
    }
437
  }
438
 
439
  // Setting up the prototype for the init object
440
  Toastify.lib.init.prototype = Toastify.lib;
441
 
442
  // Returning the Toastify function to be assigned to the window object/module
443
  return Toastify;
444
});