source for sakino.kelbie.scot
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

520 lines
16 KiB

7 months ago
  1. /**
  2. * noty - jQuery Notification Plugin v2.0.3
  3. * Contributors: https://github.com/needim/noty/graphs/contributors
  4. *
  5. * Examples and Documentation - http://needim.github.com/noty/
  6. *
  7. * Licensed under the MIT licenses:
  8. * 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. F.prototype = o;
  16. return new F();
  17. };
  18. }
  19. (function ($) {
  20. var NotyObject = {
  21. init:function (options) {
  22. // Mix in the passed in options with the default options
  23. this.options = $.extend({}, $.noty.defaults, options);
  24. this.options.layout = (this.options.custom) ? $.noty.layouts['inline'] : $.noty.layouts[this.options.layout];
  25. this.options.theme = $.noty.themes[this.options.theme];
  26. delete options.layout;
  27. delete options.theme;
  28. this.options = $.extend({}, this.options, this.options.layout.options);
  29. this.options.id = 'noty_' + (new Date().getTime() * Math.floor(Math.random() * 1000000));
  30. this.options = $.extend({}, this.options, options);
  31. // Build the noty dom initial structure
  32. this._build();
  33. // return this so we can chain/use the bridge with less code.
  34. return this;
  35. }, // end init
  36. _build:function () {
  37. // Generating noty bar
  38. var $bar = $('<div class="noty_bar"></div>').attr('id', this.options.id);
  39. $bar.append(this.options.template).find('.noty_text').html(this.options.text);
  40. this.$bar = (this.options.layout.parent.object !== null) ? $(this.options.layout.parent.object).css(this.options.layout.parent.css).append($bar) : $bar;
  41. // Set buttons if available
  42. if (this.options.buttons) {
  43. // If we have button disable closeWith & timeout options
  44. this.options.closeWith = [];
  45. this.options.timeout = false;
  46. var $buttons = $('<div/>').addClass('noty_buttons');
  47. (this.options.layout.parent.object !== null) ? this.$bar.find('.noty_bar').append($buttons) : this.$bar.append($buttons);
  48. var self = this;
  49. $.each(this.options.buttons, function (i, button) {
  50. var $button = $('<button/>').addClass((button.addClass) ? button.addClass : 'gray').html(button.text)
  51. .appendTo(self.$bar.find('.noty_buttons'))
  52. .bind('click', function () {
  53. if ($.isFunction(button.onClick)) {
  54. button.onClick.call($button, self);
  55. }
  56. });
  57. });
  58. }
  59. // For easy access
  60. this.$message = this.$bar.find('.noty_message');
  61. this.$closeButton = this.$bar.find('.noty_close');
  62. this.$buttons = this.$bar.find('.noty_buttons');
  63. $.noty.store[this.options.id] = this; // store noty for api
  64. }, // end _build
  65. show:function () {
  66. var self = this;
  67. $(self.options.layout.container.selector).append(self.$bar);
  68. self.options.theme.style.apply(self);
  69. ($.type(self.options.layout.css) === 'function') ? this.options.layout.css.apply(self.$bar) : self.$bar.css(this.options.layout.css || {});
  70. self.$bar.addClass(self.options.layout.addClass);
  71. self.options.layout.container.style.apply($(self.options.layout.container.selector));
  72. self.options.theme.callback.onShow.apply(this);
  73. if ($.inArray('click', self.options.closeWith) > -1)
  74. self.$bar.css('cursor', 'pointer').one('click', function () {
  75. self.close();
  76. });
  77. if ($.inArray('hover', self.options.closeWith) > -1)
  78. self.$bar.one('mouseenter', function () {
  79. self.close();
  80. });
  81. if ($.inArray('button', self.options.closeWith) > -1)
  82. self.$closeButton.one('click', function () {
  83. self.close();
  84. });
  85. if ($.inArray('button', self.options.closeWith) == -1)
  86. self.$closeButton.remove();
  87. if (self.options.callback.onShow)
  88. self.options.callback.onShow.apply(self);
  89. self.$bar.animate(
  90. self.options.animation.open,
  91. self.options.animation.speed,
  92. self.options.animation.easing,
  93. function () {
  94. if (self.options.callback.afterShow) self.options.callback.afterShow.apply(self);
  95. self.shown = true;
  96. });
  97. // If noty is have a timeout option
  98. if (self.options.timeout)
  99. self.$bar.delay(self.options.timeout).promise().done(function () {
  100. self.close();
  101. });
  102. return this;
  103. }, // end show
  104. close:function () {
  105. if (this.closed) return;
  106. var self = this;
  107. if (!this.shown) { // If we are still waiting in the queue just delete from queue
  108. var queue = [];
  109. $.each($.noty.queue, function (i, n) {
  110. if (n.options.id != self.options.id) {
  111. queue.push(n);
  112. }
  113. });
  114. $.noty.queue = queue;
  115. return;
  116. }
  117. self.$bar.addClass('i-am-closing-now');
  118. if (self.options.callback.onClose) {
  119. self.options.callback.onClose.apply(self);
  120. }
  121. self.$bar.clearQueue().stop().animate(
  122. self.options.animation.close,
  123. self.options.animation.speed,
  124. self.options.animation.easing,
  125. function () {
  126. if (self.options.callback.afterClose) self.options.callback.afterClose.apply(self);
  127. })
  128. .promise().done(function () {
  129. // Modal Cleaning
  130. if (self.options.modal) {
  131. $.notyRenderer.setModalCount(-1);
  132. if ($.notyRenderer.getModalCount() == 0) $('.noty_modal').fadeOut('fast', function () {
  133. $(this).remove();
  134. });
  135. }
  136. // Layout Cleaning
  137. $.notyRenderer.setLayoutCountFor(self, -1);
  138. if ($.notyRenderer.getLayoutCountFor(self) == 0) $(self.options.layout.container.selector).remove();
  139. // Make sure self.$bar has not been removed before attempting to remove it
  140. if (typeof self.$bar !== 'undefined' && self.$bar !== null ) {
  141. self.$bar.remove();
  142. self.$bar = null;
  143. self.closed = true;
  144. }
  145. delete $.noty.store[self.options.id]; // deleting noty from store
  146. self.options.theme.callback.onClose.apply(self);
  147. if (!self.options.dismissQueue) {
  148. // Queue render
  149. $.noty.ontap = true;
  150. $.notyRenderer.render();
  151. }
  152. });
  153. }, // end close
  154. setText:function (text) {
  155. if (!this.closed) {
  156. this.options.text = text;
  157. this.$bar.find('.noty_text').html(text);
  158. }
  159. return this;
  160. },
  161. setType:function (type) {
  162. if (!this.closed) {
  163. this.options.type = type;
  164. this.options.theme.style.apply(this);
  165. this.options.theme.callback.onShow.apply(this);
  166. }
  167. return this;
  168. },
  169. setTimeout:function (time) {
  170. if (!this.closed) {
  171. var self = this;
  172. this.options.timeout = time;
  173. self.$bar.delay(self.options.timeout).promise().done(function () {
  174. self.close();
  175. });
  176. }
  177. return this;
  178. },
  179. closed:false,
  180. shown:false
  181. }; // end NotyObject
  182. $.notyRenderer = {};
  183. $.notyRenderer.init = function (options) {
  184. // Renderer creates a new noty
  185. var notification = Object.create(NotyObject).init(options);
  186. (notification.options.force) ? $.noty.queue.unshift(notification) : $.noty.queue.push(notification);
  187. $.notyRenderer.render();
  188. return ($.noty.returns == 'object') ? notification : notification.options.id;
  189. };
  190. $.notyRenderer.render = function () {
  191. var instance = $.noty.queue[0];
  192. if ($.type(instance) === 'object') {
  193. if (instance.options.dismissQueue) {
  194. $.notyRenderer.show($.noty.queue.shift());
  195. } else {
  196. if ($.noty.ontap) {
  197. $.notyRenderer.show($.noty.queue.shift());
  198. $.noty.ontap = false;
  199. }
  200. }
  201. } else {
  202. $.noty.ontap = true; // Queue is over
  203. }
  204. };
  205. $.notyRenderer.show = function (notification) {
  206. if (notification.options.modal) {
  207. $.notyRenderer.createModalFor(notification);
  208. $.notyRenderer.setModalCount(+1);
  209. }
  210. // Where is the container?
  211. if ($(notification.options.layout.container.selector).length == 0) {
  212. if (notification.options.custom) {
  213. notification.options.custom.append($(notification.options.layout.container.object).addClass('i-am-new'));
  214. } else {
  215. $('body').append($(notification.options.layout.container.object).addClass('i-am-new'));
  216. }
  217. } else {
  218. $(notification.options.layout.container.selector).removeClass('i-am-new');
  219. }
  220. $.notyRenderer.setLayoutCountFor(notification, +1);
  221. notification.show();
  222. };
  223. $.notyRenderer.createModalFor = function (notification) {
  224. if ($('.noty_modal').length == 0)
  225. $('<div/>').addClass('noty_modal').data('noty_modal_count', 0).css(notification.options.theme.modal.css).prependTo($('body')).fadeIn('fast');
  226. };
  227. $.notyRenderer.getLayoutCountFor = function (notification) {
  228. return $(notification.options.layout.container.selector).data('noty_layout_count') || 0;
  229. };
  230. $.notyRenderer.setLayoutCountFor = function (notification, arg) {
  231. return $(notification.options.layout.container.selector).data('noty_layout_count', $.notyRenderer.getLayoutCountFor(notification) + arg);
  232. };
  233. $.notyRenderer.getModalCount = function () {
  234. return $('.noty_modal').data('noty_modal_count') || 0;
  235. };
  236. $.notyRenderer.setModalCount = function (arg) {
  237. return $('.noty_modal').data('noty_modal_count', $.notyRenderer.getModalCount() + arg);
  238. };
  239. // This is for custom container
  240. $.fn.noty = function (options) {
  241. options.custom = $(this);
  242. return $.notyRenderer.init(options);
  243. };
  244. $.noty = {};
  245. $.noty.queue = [];
  246. $.noty.ontap = true;
  247. $.noty.layouts = {};
  248. $.noty.themes = {};
  249. $.noty.returns = 'object';
  250. $.noty.store = {};
  251. $.noty.get = function (id) {
  252. return $.noty.store.hasOwnProperty(id) ? $.noty.store[id] : false;
  253. };
  254. $.noty.close = function (id) {
  255. return $.noty.get(id) ? $.noty.get(id).close() : false;
  256. };
  257. $.noty.setText = function (id, text) {
  258. return $.noty.get(id) ? $.noty.get(id).setText(text) : false;
  259. };
  260. $.noty.setType = function (id, type) {
  261. return $.noty.get(id) ? $.noty.get(id).setType(type) : false;
  262. };
  263. $.noty.clearQueue = function () {
  264. $.noty.queue = [];
  265. };
  266. $.noty.closeAll = function () {
  267. $.noty.clearQueue();
  268. $.each($.noty.store, function (id, noty) {
  269. noty.close();
  270. });
  271. };
  272. var windowAlert = window.alert;
  273. $.noty.consumeAlert = function (options) {
  274. window.alert = function (text) {
  275. if (options)
  276. options.text = text;
  277. else
  278. options = {text:text};
  279. $.notyRenderer.init(options);
  280. };
  281. };
  282. $.noty.stopConsumeAlert = function () {
  283. window.alert = windowAlert;
  284. };
  285. $.noty.defaults = {
  286. layout:'top',
  287. theme:'defaultTheme',
  288. type:'alert',
  289. text:'',
  290. dismissQueue:true,
  291. template:'<div class="noty_message"><span class="noty_text"></span><div class="noty_close"></div></div>',
  292. animation:{
  293. open:{height:'toggle'},
  294. close:{height:'toggle'},
  295. easing:'swing',
  296. speed:500
  297. },
  298. timeout:false,
  299. force:false,
  300. modal:false,
  301. closeWith:['click'],
  302. callback:{
  303. onShow:function () {
  304. },
  305. afterShow:function () {
  306. },
  307. onClose:function () {
  308. },
  309. afterClose:function () {
  310. }
  311. },
  312. buttons:false
  313. };
  314. $(window).resize(function () {
  315. $.each($.noty.layouts, function (index, layout) {
  316. layout.container.style.apply($(layout.container.selector));
  317. });
  318. });
  319. })(jQuery);
  320. // Helpers
  321. function noty(options) {
  322. // This is for BC - Will be deleted on v2.2.0
  323. var using_old = 0
  324. , old_to_new = {
  325. 'animateOpen':'animation.open',
  326. 'animateClose':'animation.close',
  327. 'easing':'animation.easing',
  328. 'speed':'animation.speed',
  329. 'onShow':'callback.onShow',
  330. 'onShown':'callback.afterShow',
  331. 'onClose':'callback.onClose',
  332. 'onClosed':'callback.afterClose'
  333. };
  334. jQuery.each(options, function (key, value) {
  335. if (old_to_new[key]) {
  336. using_old++;
  337. var _new = old_to_new[key].split('.');
  338. if (!options[_new[0]]) options[_new[0]] = {};
  339. options[_new[0]][_new[1]] = (value) ? value : function () {
  340. };
  341. delete options[key];
  342. }
  343. });
  344. if (!options.closeWith) {
  345. options.closeWith = jQuery.noty.defaults.closeWith;
  346. }
  347. if (options.hasOwnProperty('closeButton')) {
  348. using_old++;
  349. if (options.closeButton) options.closeWith.push('button');
  350. delete options.closeButton;
  351. }
  352. if (options.hasOwnProperty('closeOnSelfClick')) {
  353. using_old++;
  354. if (options.closeOnSelfClick) options.closeWith.push('click');
  355. delete options.closeOnSelfClick;
  356. }
  357. if (options.hasOwnProperty('closeOnSelfOver')) {
  358. using_old++;
  359. if (options.closeOnSelfOver) options.closeWith.push('hover');
  360. delete options.closeOnSelfOver;
  361. }
  362. if (options.hasOwnProperty('custom')) {
  363. using_old++;
  364. if (options.custom.container != 'null') options.custom = options.custom.container;
  365. }
  366. if (options.hasOwnProperty('cssPrefix')) {
  367. using_old++;
  368. delete options.cssPrefix;
  369. }
  370. if (options.theme == 'noty_theme_default') {
  371. using_old++;
  372. options.theme = 'defaultTheme';
  373. }
  374. if (!options.hasOwnProperty('dismissQueue')) {
  375. if (options.layout == 'topLeft'
  376. || options.layout == 'topRight'
  377. || options.layout == 'bottomLeft'
  378. || options.layout == 'bottomRight') {
  379. options.dismissQueue = true;
  380. } else {
  381. options.dismissQueue = false;
  382. }
  383. }
  384. if (options.buttons) {
  385. jQuery.each(options.buttons, function (i, button) {
  386. if (button.click) {
  387. using_old++;
  388. button.onClick = button.click;
  389. delete button.click;
  390. }
  391. if (button.type) {
  392. using_old++;
  393. button.addClass = button.type;
  394. delete button.type;
  395. }
  396. });
  397. }
  398. if (using_old) {
  399. if (typeof console !== "undefined" && console.warn) {
  400. console.warn('You are using noty v2 with v1.x.x options. @deprecated until v2.2.0 - Please update your options.');
  401. }
  402. }
  403. // console.log(options);
  404. // End of the BC
  405. return jQuery.notyRenderer.init(options);
  406. }