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.

337 lines
12 KiB

  1. /*
  2. * Toastr
  3. * Copyright 2012-2014 John Papa and Hans Fjällemark.
  4. * All Rights Reserved.
  5. * Use, reproduction, distribution, and modification of this code is subject to the terms and
  6. * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
  7. *
  8. * Author: John Papa and Hans Fjällemark
  9. * ARIA Support: Greta Krafsig
  10. * Project: https://github.com/CodeSeven/toastr
  11. */
  12. ; (function (define) {
  13. define(['jquery'], function ($) {
  14. return (function () {
  15. var $container;
  16. var listener;
  17. var toastId = 0;
  18. var toastType = {
  19. error: 'error',
  20. info: 'info',
  21. success: 'success',
  22. warning: 'warning'
  23. };
  24. var toastr = {
  25. clear: clear,
  26. remove: remove,
  27. error: error,
  28. getContainer: getContainer,
  29. info: info,
  30. options: {},
  31. subscribe: subscribe,
  32. success: success,
  33. version: '2.0.3',
  34. warning: warning
  35. };
  36. return toastr;
  37. //#region Accessible Methods
  38. function error(message, title, optionsOverride) {
  39. return notify({
  40. type: toastType.error,
  41. iconClass: getOptions().iconClasses.error,
  42. message: message,
  43. optionsOverride: optionsOverride,
  44. title: title
  45. });
  46. }
  47. function getContainer(options, create) {
  48. if (!options) { options = getOptions(); }
  49. $container = $('#' + options.containerId);
  50. if ($container.length) {
  51. return $container;
  52. }
  53. if(create) {
  54. $container = createContainer(options);
  55. }
  56. return $container;
  57. }
  58. function info(message, title, optionsOverride) {
  59. return notify({
  60. type: toastType.info,
  61. iconClass: getOptions().iconClasses.info,
  62. message: message,
  63. optionsOverride: optionsOverride,
  64. title: title
  65. });
  66. }
  67. function subscribe(callback) {
  68. listener = callback;
  69. }
  70. function success(message, title, optionsOverride) {
  71. return notify({
  72. type: toastType.success,
  73. iconClass: getOptions().iconClasses.success,
  74. message: message,
  75. optionsOverride: optionsOverride,
  76. title: title
  77. });
  78. }
  79. function warning(message, title, optionsOverride) {
  80. return notify({
  81. type: toastType.warning,
  82. iconClass: getOptions().iconClasses.warning,
  83. message: message,
  84. optionsOverride: optionsOverride,
  85. title: title
  86. });
  87. }
  88. function clear($toastElement) {
  89. var options = getOptions();
  90. if (!$container) { getContainer(options); }
  91. if (!clearToast($toastElement, options)) {
  92. clearContainer(options);
  93. }
  94. }
  95. function remove($toastElement) {
  96. var options = getOptions();
  97. if (!$container) { getContainer(options); }
  98. if ($toastElement && $(':focus', $toastElement).length === 0) {
  99. removeToast($toastElement);
  100. return;
  101. }
  102. if ($container.children().length) {
  103. $container.remove();
  104. }
  105. }
  106. //#endregion
  107. //#region Internal Methods
  108. function clearContainer(options){
  109. var toastsToClear = $container.children();
  110. for (var i = toastsToClear.length - 1; i >= 0; i--) {
  111. clearToast($(toastsToClear[i]), options);
  112. };
  113. }
  114. function clearToast($toastElement, options){
  115. if ($toastElement && $(':focus', $toastElement).length === 0) {
  116. $toastElement[options.hideMethod]({
  117. duration: options.hideDuration,
  118. easing: options.hideEasing,
  119. complete: function () { removeToast($toastElement); }
  120. });
  121. return true;
  122. }
  123. return false;
  124. }
  125. function createContainer(options) {
  126. $container = $('<div/>')
  127. .attr('id', options.containerId)
  128. .addClass(options.positionClass)
  129. .attr('aria-live', 'polite')
  130. .attr('role', 'alert');
  131. $container.appendTo($(options.target));
  132. return $container;
  133. }
  134. function getDefaults() {
  135. return {
  136. tapToDismiss: true,
  137. toastClass: 'toast',
  138. containerId: 'toast-container',
  139. debug: false,
  140. showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery
  141. showDuration: 300,
  142. showEasing: 'swing', //swing and linear are built into jQuery
  143. onShown: undefined,
  144. hideMethod: 'fadeOut',
  145. hideDuration: 1000,
  146. hideEasing: 'swing',
  147. onHidden: undefined,
  148. extendedTimeOut: 1000,
  149. iconClasses: {
  150. error: 'toast-error',
  151. info: 'toast-info',
  152. success: 'toast-success',
  153. warning: 'toast-warning'
  154. },
  155. iconClass: 'toast-info',
  156. positionClass: 'toast-top-right',
  157. timeOut: 5000, // Set timeOut and extendedTimeout to 0 to make it sticky
  158. titleClass: 'toast-title',
  159. messageClass: 'toast-message',
  160. target: 'body',
  161. closeHtml: '<button>&times;</button>',
  162. newestOnTop: true
  163. };
  164. }
  165. function publish(args) {
  166. if (!listener) { return; }
  167. listener(args);
  168. }
  169. function notify(map) {
  170. var options = getOptions(),
  171. iconClass = map.iconClass || options.iconClass;
  172. if (typeof (map.optionsOverride) !== 'undefined') {
  173. options = $.extend(options, map.optionsOverride);
  174. iconClass = map.optionsOverride.iconClass || iconClass;
  175. }
  176. toastId++;
  177. $container = getContainer(options, true);
  178. var intervalId = null,
  179. $toastElement = $('<div/>'),
  180. $titleElement = $('<div/>'),
  181. $messageElement = $('<div/>'),
  182. $closeElement = $(options.closeHtml),
  183. response = {
  184. toastId: toastId,
  185. state: 'visible',
  186. startTime: new Date(),
  187. options: options,
  188. map: map
  189. };
  190. if (map.iconClass) {
  191. $toastElement.addClass(options.toastClass).addClass(iconClass);
  192. }
  193. if (map.title) {
  194. $titleElement.append(map.title).addClass(options.titleClass);
  195. $toastElement.append($titleElement);
  196. }
  197. if (map.message) {
  198. $messageElement.append(map.message).addClass(options.messageClass);
  199. $toastElement.append($messageElement);
  200. }
  201. if (options.closeButton) {
  202. $closeElement.addClass('toast-close-button').attr("role", "button");
  203. $toastElement.prepend($closeElement);
  204. }
  205. $toastElement.hide();
  206. if (options.newestOnTop) {
  207. $container.prepend($toastElement);
  208. } else {
  209. $container.append($toastElement);
  210. }
  211. $toastElement[options.showMethod](
  212. { duration: options.showDuration, easing: options.showEasing, complete: options.onShown }
  213. );
  214. if (options.timeOut > 0) {
  215. intervalId = setTimeout(hideToast, options.timeOut);
  216. }
  217. $toastElement.hover(stickAround, delayedHideToast);
  218. if (!options.onclick && options.tapToDismiss) {
  219. $toastElement.click(hideToast);
  220. }
  221. if (options.closeButton && $closeElement) {
  222. $closeElement.click(function (event) {
  223. if( event.stopPropagation ) {
  224. event.stopPropagation();
  225. } else if( event.cancelBubble !== undefined && event.cancelBubble !== true ) {
  226. event.cancelBubble = true;
  227. }
  228. hideToast(true);
  229. });
  230. }
  231. if (options.onclick) {
  232. $toastElement.click(function () {
  233. options.onclick();
  234. hideToast();
  235. });
  236. }
  237. publish(response);
  238. if (options.debug && console) {
  239. console.log(response);
  240. }
  241. return $toastElement;
  242. function hideToast(override) {
  243. if ($(':focus', $toastElement).length && !override) {
  244. return;
  245. }
  246. return $toastElement[options.hideMethod]({
  247. duration: options.hideDuration,
  248. easing: options.hideEasing,
  249. complete: function () {
  250. removeToast($toastElement);
  251. if (options.onHidden && response.state !== 'hidden') {
  252. options.onHidden();
  253. }
  254. response.state = 'hidden';
  255. response.endTime = new Date();
  256. publish(response);
  257. }
  258. });
  259. }
  260. function delayedHideToast() {
  261. if (options.timeOut > 0 || options.extendedTimeOut > 0) {
  262. intervalId = setTimeout(hideToast, options.extendedTimeOut);
  263. }
  264. }
  265. function stickAround() {
  266. clearTimeout(intervalId);
  267. $toastElement.stop(true, true)[options.showMethod](
  268. { duration: options.showDuration, easing: options.showEasing }
  269. );
  270. }
  271. }
  272. function getOptions() {
  273. return $.extend({}, getDefaults(), toastr.options);
  274. }
  275. function removeToast($toastElement) {
  276. if (!$container) { $container = getContainer(); }
  277. if ($toastElement.is(':visible')) {
  278. return;
  279. }
  280. $toastElement.remove();
  281. $toastElement = null;
  282. if ($container.children().length === 0) {
  283. $container.remove();
  284. }
  285. }
  286. //#endregion
  287. })();
  288. });
  289. }(typeof define === 'function' && define.amd ? define : function (deps, factory) {
  290. if (typeof module !== 'undefined' && module.exports) { //Node
  291. module.exports = factory(require('jquery'));
  292. } else {
  293. window['toastr'] = factory(window['jQuery']);
  294. }
  295. }));