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.