PageSourceSearch

https://www.a-lab.name/vendor/noty/jquery.noty.js?v=131

js a-lab.name collected 2026-10-05 21:53:59 UTC 22,611 bytes, 688 lines download raw bytes

1/*!
2 @package noty - jQuery Notification Plugin
3 @version version: 2.3.4
4 @contributors https://github.com/needim/noty/graphs/contributors
5
6 @documentation Examples and Documentation - http://needim.github.com/noty/
7
8 @license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php
9 */
10
11    if(typeof Object.create !== 'function') {
12        Object.create = function(o) {
13            function F() {
14            }
15
16            F.prototype = o;
17            return new F();
18        };
19    }
20
21    var NotyObject = {
22
23        init: function(options) {
24
25            // Mix in the passed in options with the default options
26            this.options = $.extend({}, $.noty.defaults, options);
27
28            this.options.layout = (this.options.custom) ? $.noty.layouts['inline'] : $.noty.layouts[this.options.layout];
29
30            if($.noty.themes[this.options.theme])
31                this.options.theme = $.noty.themes[this.options.theme];
32            else
33                options.themeClassName = this.options.theme;
34
35            delete options.layout;
36            delete options.theme;
37
38            this.options = $.extend({}, this.options, this.options.layout.options);
39            this.options.id = 'noty_' + (new Date().getTime() * Math.floor(Math.random() * 1000000));
40
41            this.options = $.extend({}, this.options, options);
42
43            // Build the noty dom initial structure
44            this._build();
45
46            // return this so we can chain/use the bridge with less code.
47            return this;
48        }, // end init
49
50        _build: function() {
51
52            // Generating noty bar
53            var $bar = $('<div class="noty_bar noty_type_' + this.options.type + '"></div>').attr('id', this.options.id);
54            $bar.append(this.options.template).find('.noty_text').html(this.options.text);
55
56            this.$bar = (this.options.layout.parent.object !== null) ? $(this.options.layout.parent.object).css(this.options.layout.parent.css).append($bar) : $bar;
57
58            if(this.options.themeClassName)
59                this.$bar.addClass(this.options.themeClassName).addClass('noty_container_type_' + this.options.type);
60
61            // Set buttons if available
62            if(this.options.buttons) {
63
64                // If we have button disable closeWith & timeout options
65                this.options.closeWith = [];
66                this.options.timeout = false;
67
68                var $buttons = $('<div/>').addClass('noty_buttons');
69
70                (this.options.layout.parent.object !== null) ? this.$bar.find('.noty_bar').append($buttons) : this.$bar.append($buttons);
71
72                var self = this;
73
74                $.each(this.options.buttons, function(i, button) {
75                    var $button = $('<button/>').addClass((button.addClass) ? button.addClass : 'gray').html(button.text).attr('id', button.id ? button.id : 'button-' + i)
76                        .appendTo(self.$bar.find('.noty_buttons'))
77                        .on('click', function(event) {
78                            if($.isFunction(button.onClick)) {
79                                button.onClick.call($button, self, event);
80                            }
81                        });
82                });
83            }
84
85            // For easy access
86            this.$message = this.$bar.find('.noty_message');
87            this.$closeButton = this.$bar.find('.noty_close');
88            this.$buttons = this.$bar.find('.noty_buttons');
89
90            $.noty.store[this.options.id] = this; // store noty for api
91
92        }, // end _build
93
94        show: function() {
95
96            var self = this;
97
98            (self.options.custom) ? self.options.custom.find(self.options.layout.container.selector).append(self.$bar) : $(self.options.layout.container.selector).append(self.$bar);
99
100            if(self.options.theme && self.options.theme.style)
101                self.options.theme.style.apply(self);
102
103            ($.type(self.options.layout.css) === 'function') ? this.options.layout.css.apply(self.$bar) : self.$bar.css(this.options.layout.css || {});
104
105            self.$bar.addClass(self.options.layout.addClass);
106
107            self.options.layout.container.style.apply($(self.options.layout.container.selector));
108
109            self.showing = true;
110
111            if(self.options.theme && self.options.theme.style)
112                self.options.theme.callback.onShow.apply(this);
113
114            if($.inArray('click', self.options.closeWith) > -1)
115                self.$bar.css('cursor', 'pointer').one('click', function(evt) {
116                    self.stopPropagation(evt);
117                    if(self.options.callback.onCloseClick) {
118                        self.options.callback.onCloseClick.apply(self);
119                    }
120                    self.close();
121                });
122
123            if($.inArray('hover', self.options.closeWith) > -1)
124                self.$bar.one('mouseenter', function() {
125                    self.close();
126                });
127
128            if($.inArray('button', self.options.closeWith) > -1)
129                self.$closeButton.one('click', function(evt) {
130                    self.stopPropagation(evt);
131                    self.close();
132                });
133
134            if($.inArray('button', self.options.closeWith) == -1)
135                self.$closeButton.remove();
136
137            if(self.options.callback.onShow)
138                self.options.callback.onShow.apply(self);
139
140            if (typeof self.options.animation.open == 'string') {
141                self.$bar.css('height', self.$bar.innerHeight());
142                self.$bar.show().addClass(self.options.animation.open).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
143                    if(self.options.callback.afterShow) self.options.callback.afterShow.apply(self);
144                    self.showing = false;
145                    self.shown = true;
146                });
147
148            } else {
149                self.$bar.animate(
150                    self.options.animation.open,
151                    self.options.animation.speed,
152                    self.options.animation.easing,
153                    function() {
154                        if(self.options.callback.afterShow) self.options.callback.afterShow.apply(self);
155                        self.showing = false;
156                        self.shown = true;
157                    });
158            }
159
160            // If noty is have a timeout option
161            if(self.options.timeout)
162                self.$bar.delay(self.options.timeout).promise().done(function() {
163                    self.close();
164                });
165
166            return this;
167
168        }, // end show
169
170        close: function() {
171
172            if(this.closed) return;
173            if(this.$bar && this.$bar.hasClass('i-am-closing-now')) return;
174
175            var self = this;
176
177            if(this.showing) {
178                self.$bar.queue(
179                    function() {
180                        self.close.apply(self);
181                    }
182                );
183                return;
184            }
185
186            if(!this.shown && !this.showing) { // If we are still waiting in the queue just delete from queue
187                var queue = [];
188                $.each($.noty.queue, function(i, n) {
189                    if(n.options.id != self.options.id) {
190                        queue.push(n);
191                    }
192                });
193                $.noty.queue = queue;
194                return;
195            }
196
197            self.$bar.addClass('i-am-closing-now');
198
199            if(self.options.callback.onClose) {
200                self.options.callback.onClose.apply(self);
201            }
202
203            if (typeof self.options.animation.close == 'string') {
204                self.$bar.addClass(self.options.animation.close).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
205                    if(self.options.callback.afterClose) self.options.callback.afterClose.apply(self);
206                    self.closeCleanUp();
207                });
208            } else {
209                self.$bar.clearQueue().stop().animate(
210                    self.options.animation.close,
211                    self.options.animation.speed,
212                    self.options.animation.easing,
213                    function() {
214                        if(self.options.callback.afterClose) self.options.callback.afterClose.apply(self);
215                    })
216                    .promise().done(function() {
217                        self.closeCleanUp();
218                    });
219            }
220
221        }, // end close
222
223        closeCleanUp: function() {
224
225            var self = this;
226
227            // Modal Cleaning
228            if(self.options.modal) {
229                $.notyRenderer.setModalCount(-1);
230                if($.notyRenderer.getModalCount() == 0) $('.noty_modal').fadeOut('fast', function() {
231                    $(this).remove();
232                });
233            }
234
235            // Layout Cleaning
236            $.notyRenderer.setLayoutCountFor(self, -1);
237            if($.notyRenderer.getLayoutCountFor(self) == 0) $(self.options.layout.container.selector).remove();
238
239            // Make sure self.$bar has not been removed before attempting to remove it
240            if(typeof self.$bar !== 'undefined' && self.$bar !== null) {
241
242                if (typeof self.options.animation.close == 'string') {
243                    self.$bar.css('transition', 'all 100ms ease').css('border', 0).css('margin', 0).height(0);
244                    self.$bar.one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function() {
245                        self.$bar.remove();
246                        self.$bar = null;
247                        self.closed = true;
248
249                        if(self.options.theme.callback && self.options.theme.callback.onClose) {
250                            self.options.theme.callback.onClose.apply(self);
251                        }
252                    });
253                } else {
254                    self.$bar.remove();
255                    self.$bar = null;
256                    self.closed = true;
257                }
258            }
259
260            delete $.noty.store[self.options.id]; // deleting noty from store
261
262            if(self.options.theme.callback && self.options.theme.callback.onClose) {
263                self.options.theme.callback.onClose.apply(self);
264            }
265
266            if(!self.options.dismissQueue) {
267                // Queue render
268                $.noty.ontap = true;
269
270                $.notyRenderer.render();
271            }
272
273            if(self.options.maxVisible > 0 && self.options.dismissQueue) {
274                $.notyRenderer.render();
275            }
276
277        }, // end close clean up
278
279        setText: function(text) {
280            if(!this.closed) {
281                this.options.text = text;
282                this.$bar.find('.noty_text').html(text);
283            }
284            return this;
285        },
286
287        setType: function(type) {
288            if(!this.closed) {
289                this.options.type = type;
290                this.options.theme.style.apply(this);
291                this.options.theme.callback.onShow.apply(this);
292            }
293            return this;
294        },
295
296        setTimeout: function(time) {
297            if(!this.closed) {
298                var self = this;
299                this.options.timeout = time;
300                self.$bar.delay(self.options.timeout).promise().done(function() {
301                    self.close();
302                });
303            }
304            return this;
305        },
306
307        stopPropagation: function(evt) {
308            evt = evt || window.event;
309            if(typeof evt.stopPropagation !== "undefined") {
310                evt.stopPropagation();
311            }
312            else {
313                evt.cancelBubble = true;
314            }
315        },
316
317        closed : false,
318        showing: false,
319        shown  : false
320
321    }; // end NotyObject
322
323    $.notyRenderer = {};
324
325    $.notyRenderer.init = function(options) {
326
327        // Renderer creates a new noty
328        var notification = Object.create(NotyObject).init(options);
329
330        if(notification.options.killer)
331            $.noty.closeAll();
332
333        (notification.options.force) ? $.noty.queue.unshift(notification) : $.noty.queue.push(notification);
334
335        $.notyRenderer.render();
336
337        return ($.noty.returns == 'object') ? notification : notification.options.id;
338    };
339
340    $.notyRenderer.render = function() {
341
342        var instance = $.noty.queue[0];
343
344        if($.type(instance) === 'object') {
345            if(instance.options.dismissQueue) {
346                if(instance.options.maxVisible > 0) {
347                    if($(instance.options.layout.container.selector + ' li').length < instance.options.maxVisible) {
348                        $.notyRenderer.show($.noty.queue.shift());
349                    }
350                    else {
351
352                    }
353                }
354                else {
355                    $.notyRenderer.show($.noty.queue.shift());
356                }
357            }
358            else {
359                if($.noty.ontap) {
360                    $.notyRenderer.show($.noty.queue.shift());
361                    $.noty.ontap = false;
362                }
363            }
364        }
365        else {
366            $.noty.ontap = true; // Queue is over
367        }
368
369    };
370
371    $.notyRenderer.show = function(notification) {
372
373        if(notification.options.modal) {
374            $.notyRenderer.createModalFor(notification);
375            $.notyRenderer.setModalCount(+1);
376        }
377
378        // Where is the container?
379        if(notification.options.custom) {
380            if(notification.options.custom.find(notification.options.layout.container.selector).length == 0) {
381                notification.options.custom.append($(notification.options.layout.container.object).addClass('i-am-new'));
382            }
383            else {
384                notification.options.custom.find(notification.options.layout.container.selector).removeClass('i-am-new');
385            }
386        }
387        else {
388            if($(notification.options.layout.container.selector).length == 0) {
389                $('body').append($(notification.options.layout.container.object).addClass('i-am-new'));
390            }
391            else {
392                $(notification.options.layout.container.selector).removeClass('i-am-new');
393            }
394        }
395
396        $.notyRenderer.setLayoutCountFor(notification, +1);
397
398        notification.show();
399    };
400
401    $.notyRenderer.createModalFor = function(notification) {
402        if($('.noty_modal').length == 0) {
403            var modal = $('<div/>').addClass('noty_modal').addClass(notification.options.theme).data('noty_modal_count', 0);
404
405            if(notification.options.theme.modal && notification.options.theme.modal.css)
406                modal.css(notification.options.theme.modal.css);
407
408            modal.prependTo($('body')).fadeIn('fast');
409
410            if($.inArray('backdrop', notification.options.closeWith) > -1)
411                modal.on('click', function(e) {
412                    $.noty.closeAll();
413                });
414        }
415    };
416
417    $.notyRenderer.getLayoutCountFor = function(notification) {
418        return $(notification.options.layout.container.selector).data('noty_layout_count') || 0;
419    };
420
421    $.notyRenderer.setLayoutCountFor = function(notification, arg) {
422        return $(notification.options.layout.container.selector).data('noty_layout_count', $.notyRenderer.getLayoutCountFor(notification) + arg);
423    };
424
425    $.notyRenderer.getModalCount = function() {
426        return $('.noty_modal').data('noty_modal_count') || 0;
427    };
428
429    $.notyRenderer.setModalCount = function(arg) {
430        return $('.noty_modal').data('noty_modal_count', $.notyRenderer.getModalCount() + arg);
431    };
432
433    // This is for custom container
434    $.fn.noty = function(options) {
435        options.custom = $(this);
436        return $.notyRenderer.init(options);
437    };
438
439    $.noty = {};
440    $.noty.queue = [];
441    $.noty.ontap = true;
442    $.noty.layouts = {};
443    $.noty.themes = {};
444    $.noty.returns = 'object';
445    $.noty.store = {};
446
447    $.noty.get = function(id) {
448        return $.noty.store.hasOwnProperty(id) ? $.noty.store[id] : false;
449    };
450
451    $.noty.close = function(id) {
452        return $.noty.get(id) ? $.noty.get(id).close() : false;
453    };
454
455    $.noty.setText = function(id, text) {
456        return $.noty.get(id) ? $.noty.get(id).setText(text) : false;
457    };
458
459    $.noty.setType = function(id, type) {
460        return $.noty.get(id) ? $.noty.get(id).setType(type) : false;
461    };
462
463    $.noty.clearQueue = function() {
464        $.noty.queue = [];
465    };
466
467    $.noty.closeAll = function() {
468        $.noty.clearQueue();
469        $.each($.noty.store, function(id, noty) {
470            noty.close();
471        });
472    };
473
474    var windowAlert = window.alert;
475
476    $.noty.consumeAlert = function(options) {
477        window.alert = function(text) {
478            if(options)
479                options.text = text;
480            else
481                options = {text: text};
482
483            $.notyRenderer.init(options);
484        };
485    };
486
487    $.noty.stopConsumeAlert = function() {
488        window.alert = windowAlert;
489    };
490
491    $.noty.defaults = {
492        layout      : 'bottomRight',
493        theme       : 'relax',
494        type        : 'alert',
495        text        : '',
496        dismissQueue: true,
497        template    : '<div class="noty_message"><span class="noty_text"></span><div class="noty_close"></div></div>',
498        animation   : {
499            open  : {height: 'toggle'},
500            close : {height: 'toggle'},
501            easing: 'swing',
502            speed : 500
503        },
504        timeout     : false,
505        force       : false,
506        modal       : false,
507        maxVisible  : 5,
508        killer      : false,
509        closeWith   : ['click'],
510        callback    : {
511            onShow      : function() {
512            },
513            afterShow   : function() {
514            },
515            onClose     : function() {
516            },
517            afterClose  : function() {
518            },
519            onCloseClick: function() {
520            }
521        },
522        buttons     : false
523    };
524
525    $(window).on('resize', function() {
526        $.each($.noty.layouts, function(index, layout) {
527            layout.container.style.apply($(layout.container.selector));
528        });
529    });
530
531    // Helpers
532    window.noty = function noty(options) {
533        return jQuery.notyRenderer.init(options);
534    };
535$.noty.layouts.topCenter = {
536    name     : 'topCenter',
537    options  : { // overrides options
538
539    },
540    container: {
541        object  : '<ul id="toast-container" />',
542        selector: 'ul#toast-container',
543        style   : function() {
544            $(this).css({
545                top          : 20,
546                left         : 0,
547                position     : 'fixed',
548                width        : '310px',
549                height       : 'auto',
550                margin       : 0,
551                padding      : 0,
552                listStyleType: 'none',
553                zIndex       : 10000000
554            });
555
556            $(this).css({
557                left: ($(window).width() - $(this).outerWidth(false)) / 2 + 'px'
558            });
559        }
560    },
561    parent   : {
562        object  : '<li />',
563        selector: 'li',
564        css     : {}
565    },
566    css      : {
567        display: 'none',
568        width  : '310px'
569    },
570    addClass : ''
571};
572
573$.noty.layouts.bottomRight = {
574    name     : 'bottomRight',
575    options  : { // overrides options
576
577    },
578    container: {
579        object  : '<ul id="toast-container" />',
580        selector: 'ul#toast-container',
581        style   : function() {
582            $(this).css({
583                bottom       : 20,
584                right        : 20,
585                position     : 'fixed',
586                width        : '310px',
587                height       : 'auto',
588                margin       : 0,
589                padding      : 0,
590                listStyleType: 'none',
591                zIndex       : 10000000
592            });
593
594            if(window.innerWidth < 600) {
595                $(this).css({
596                    right: 5
597                });
598            }
599        }
600    },
601    parent   : {
602        object  : '<li />',
603        selector: 'li',
604        css     : {}
605    },
606    css      : {
607        display: 'none',
608        width  : '310px'
609    },
610    addClass : ''
611};
612
613$.noty.themes.relax = {
614    name    : 'relax',
615    helpers : {},
616    modal   : {
617        css: {
618            position       : 'fixed',
619            width          : '100%',
620            height         : '100%',
621            backgroundColor: '#000',
622            zIndex         : 10000,
623            opacity        : 0.6,
624            display        : 'none',
625            left           : 0,
626            top            : 0
627        }
628    },
629    style   : function() {
630
631        this.$bar.css({
632            overflow    : 'hidden',
633            margin      : '4px 0',
634            borderRadius: '3px'
635        });
636
637        this.$message.css({
638            lineHeight: '16px',
639            padding   : '10px',
640            width     : 'auto',
641            position  : 'relative',
642        });
643
644        this.$closeButton.css({
645            position  : 'absolute',
646            top       : 4, right: 4,
647            width     : 10, height: 10,
648            background: "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAxUlEQVR4AR3MPUoDURSA0e++uSkkOxC3IAOWNtaCIDaChfgXBMEZbQRByxCwk+BasgQRZLSYoLgDQbARxry8nyumPcVRKDfd0Aa8AsgDv1zp6pYd5jWOwhvebRTbzNNEw5BSsIpsj/kurQBnmk7sIFcCF5yyZPDRG6trQhujXYosaFoc+2f1MJ89uc76IND6F9BvlXUdpb6xwD2+4q3me3bysiHvtLYrUJto7PD/ve7LNHxSg/woN2kSz4txasBdhyiz3ugPGetTjm3XRokAAAAASUVORK5CYII=)",
649            display   : 'none',
650            cursor    : 'pointer'
651        });
652
653        this.$buttons.css({
654            padding        : 5,
655            textAlign      : 'right',
656            borderTop      : '1px solid #ccc',
657            backgroundColor: '#fff'
658        });
659
660        this.$buttons.find('button').css({
661            marginLeft: 5
662        });
663
664        this.$buttons.find('button:first').css({
665            marginLeft: 0
666        });
667
668        this.$bar.on({
669            mouseenter: function() {
670                $(this).find('.noty_close').stop().fadeTo('normal', 1);
671            },
672            mouseleave: function() {
673                $(this).find('.noty_close').stop().fadeTo('normal', 0);
674            }
675        });
676
677        this.$bar.addClass('toast toast-' + this.options.type);
678        
679    },
680    callback: {
681        onShow : function() {
682
683        },
684        onClose: function() {
685
686        }
687    }
688};

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.