toastr.js
435 lines
| 16.0 KiB
| application/javascript
|
JavascriptLexer
r526 | /* | |||
* Toastr | ||||
* Copyright 2012-2015 | ||||
* Authors: John Papa, Hans FjÀllemark, and Tim Ferrell. | ||||
* All Rights Reserved. | ||||
* Use, reproduction, distribution, and modification of this code is subject to the terms and | ||||
* conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php | ||||
* | ||||
* ARIA Support: Greta Krafsig | ||||
* | ||||
* Project: https://github.com/CodeSeven/toastr | ||||
*/ | ||||
/* global define */ | ||||
(function (define) { | ||||
define(['jquery'], function ($) { | ||||
return (function () { | ||||
var $container; | ||||
var listener; | ||||
var toastId = 0; | ||||
var toastType = { | ||||
error: 'error', | ||||
info: 'info', | ||||
success: 'success', | ||||
warning: 'warning' | ||||
}; | ||||
var toastr = { | ||||
clear: clear, | ||||
remove: remove, | ||||
error: error, | ||||
getContainer: getContainer, | ||||
info: info, | ||||
options: {}, | ||||
subscribe: subscribe, | ||||
success: success, | ||||
version: '2.1.2', | ||||
warning: warning | ||||
}; | ||||
var previousToast; | ||||
return toastr; | ||||
//////////////// | ||||
function error(message, title, optionsOverride) { | ||||
return notify({ | ||||
type: toastType.error, | ||||
iconClass: getOptions().iconClasses.error, | ||||
message: message, | ||||
optionsOverride: optionsOverride, | ||||
title: title | ||||
}); | ||||
} | ||||
function getContainer(options, create) { | ||||
if (!options) { options = getOptions(); } | ||||
$container = $('#' + options.containerId); | ||||
if ($container.length) { | ||||
return $container; | ||||
} | ||||
if (create) { | ||||
$container = createContainer(options); | ||||
} | ||||
return $container; | ||||
} | ||||
function info(message, title, optionsOverride) { | ||||
return notify({ | ||||
type: toastType.info, | ||||
iconClass: getOptions().iconClasses.info, | ||||
message: message, | ||||
optionsOverride: optionsOverride, | ||||
title: title | ||||
}); | ||||
} | ||||
function subscribe(callback) { | ||||
listener = callback; | ||||
} | ||||
function success(message, title, optionsOverride) { | ||||
return notify({ | ||||
type: toastType.success, | ||||
iconClass: getOptions().iconClasses.success, | ||||
message: message, | ||||
optionsOverride: optionsOverride, | ||||
title: title | ||||
}); | ||||
} | ||||
function warning(message, title, optionsOverride) { | ||||
return notify({ | ||||
type: toastType.warning, | ||||
iconClass: getOptions().iconClasses.warning, | ||||
message: message, | ||||
optionsOverride: optionsOverride, | ||||
title: title | ||||
}); | ||||
} | ||||
function clear($toastElement, clearOptions) { | ||||
var options = getOptions(); | ||||
if (!$container) { getContainer(options); } | ||||
if (!clearToast($toastElement, options, clearOptions)) { | ||||
clearContainer(options); | ||||
} | ||||
} | ||||
function remove($toastElement) { | ||||
var options = getOptions(); | ||||
if (!$container) { getContainer(options); } | ||||
if ($toastElement && $(':focus', $toastElement).length === 0) { | ||||
removeToast($toastElement); | ||||
return; | ||||
} | ||||
if ($container.children().length) { | ||||
$container.remove(); | ||||
} | ||||
} | ||||
// internal functions | ||||
function clearContainer (options) { | ||||
var toastsToClear = $container.children(); | ||||
for (var i = toastsToClear.length - 1; i >= 0; i--) { | ||||
clearToast($(toastsToClear[i]), options); | ||||
} | ||||
} | ||||
function clearToast ($toastElement, options, clearOptions) { | ||||
var force = clearOptions && clearOptions.force ? clearOptions.force : false; | ||||
if ($toastElement && (force || $(':focus', $toastElement).length === 0)) { | ||||
$toastElement[options.hideMethod]({ | ||||
duration: options.hideDuration, | ||||
easing: options.hideEasing, | ||||
complete: function () { removeToast($toastElement); } | ||||
}); | ||||
return true; | ||||
} | ||||
return false; | ||||
} | ||||
function createContainer(options) { | ||||
$container = $('<div/>') | ||||
.attr('id', options.containerId) | ||||
.addClass(options.positionClass) | ||||
.attr('aria-live', 'polite') | ||||
.attr('role', 'alert'); | ||||
$container.appendTo($(options.target)); | ||||
return $container; | ||||
} | ||||
function getDefaults() { | ||||
return { | ||||
tapToDismiss: true, | ||||
toastClass: 'toast', | ||||
containerId: 'toast-container', | ||||
debug: false, | ||||
showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery | ||||
showDuration: 300, | ||||
showEasing: 'swing', //swing and linear are built into jQuery | ||||
onShown: undefined, | ||||
hideMethod: 'fadeOut', | ||||
hideDuration: 1000, | ||||
hideEasing: 'swing', | ||||
onHidden: undefined, | ||||
closeMethod: false, | ||||
closeDuration: false, | ||||
closeEasing: false, | ||||
extendedTimeOut: 1000, | ||||
iconClasses: { | ||||
error: 'toast-error', | ||||
info: 'toast-info', | ||||
success: 'toast-success', | ||||
warning: 'toast-warning' | ||||
}, | ||||
iconClass: 'toast-info', | ||||
positionClass: 'toast-top-right', | ||||
timeOut: 5000, // Set timeOut and extendedTimeOut to 0 to make it sticky | ||||
titleClass: 'toast-title', | ||||
messageClass: 'toast-message', | ||||
escapeHtml: false, | ||||
target: 'body', | ||||
closeHtml: '<button type="button">×</button>', | ||||
newestOnTop: true, | ||||
preventDuplicates: false, | ||||
progressBar: false | ||||
}; | ||||
} | ||||
function publish(args) { | ||||
if (!listener) { return; } | ||||
listener(args); | ||||
} | ||||
function notify(map) { | ||||
var options = getOptions(); | ||||
var iconClass = map.iconClass || options.iconClass; | ||||
if (typeof (map.optionsOverride) !== 'undefined') { | ||||
options = $.extend(options, map.optionsOverride); | ||||
iconClass = map.optionsOverride.iconClass || iconClass; | ||||
} | ||||
if (shouldExit(options, map)) { return; } | ||||
toastId++; | ||||
$container = getContainer(options, true); | ||||
var intervalId = null; | ||||
var $toastElement = $('<div/>'); | ||||
var $titleElement = $('<div/>'); | ||||
var $messageElement = $('<div/>'); | ||||
var $progressElement = $('<div/>'); | ||||
var $closeElement = $(options.closeHtml); | ||||
var progressBar = { | ||||
intervalId: null, | ||||
hideEta: null, | ||||
maxHideTime: null | ||||
}; | ||||
var response = { | ||||
toastId: toastId, | ||||
state: 'visible', | ||||
startTime: new Date(), | ||||
options: options, | ||||
map: map | ||||
}; | ||||
personalizeToast(); | ||||
displayToast(); | ||||
handleEvents(); | ||||
publish(response); | ||||
if (options.debug && console) { | ||||
console.log(response); | ||||
} | ||||
return $toastElement; | ||||
function escapeHtml(source) { | ||||
if (source == null) | ||||
source = ""; | ||||
return new String(source) | ||||
.replace(/&/g, '&') | ||||
.replace(/"/g, '"') | ||||
.replace(/'/g, ''') | ||||
.replace(/</g, '<') | ||||
.replace(/>/g, '>'); | ||||
} | ||||
function personalizeToast() { | ||||
setIcon(); | ||||
setTitle(); | ||||
setMessage(); | ||||
setCloseButton(); | ||||
setProgressBar(); | ||||
setSequence(); | ||||
} | ||||
function handleEvents() { | ||||
$toastElement.hover(stickAround, delayedHideToast); | ||||
if (!options.onclick && options.tapToDismiss) { | ||||
$toastElement.click(hideToast); | ||||
} | ||||
if (options.closeButton && $closeElement) { | ||||
$closeElement.click(function (event) { | ||||
if (event.stopPropagation) { | ||||
event.stopPropagation(); | ||||
} else if (event.cancelBubble !== undefined && event.cancelBubble !== true) { | ||||
event.cancelBubble = true; | ||||
} | ||||
hideToast(true); | ||||
}); | ||||
} | ||||
if (options.onclick) { | ||||
$toastElement.click(function (event) { | ||||
options.onclick(event); | ||||
hideToast(); | ||||
}); | ||||
} | ||||
} | ||||
function displayToast() { | ||||
$toastElement.hide(); | ||||
$toastElement[options.showMethod]( | ||||
{duration: options.showDuration, easing: options.showEasing, complete: options.onShown} | ||||
); | ||||
if (options.timeOut > 0) { | ||||
intervalId = setTimeout(hideToast, options.timeOut); | ||||
progressBar.maxHideTime = parseFloat(options.timeOut); | ||||
progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime; | ||||
if (options.progressBar) { | ||||
progressBar.intervalId = setInterval(updateProgress, 10); | ||||
} | ||||
} | ||||
} | ||||
function setIcon() { | ||||
if (map.iconClass) { | ||||
$toastElement.addClass(options.toastClass).addClass(iconClass); | ||||
} | ||||
} | ||||
function setSequence() { | ||||
if (options.newestOnTop) { | ||||
$container.prepend($toastElement); | ||||
} else { | ||||
$container.append($toastElement); | ||||
} | ||||
} | ||||
function setTitle() { | ||||
if (map.title) { | ||||
$titleElement.append(!options.escapeHtml ? map.title : escapeHtml(map.title)).addClass(options.titleClass); | ||||
$toastElement.append($titleElement); | ||||
} | ||||
} | ||||
function setMessage() { | ||||
if (map.message) { | ||||
$messageElement.append(!options.escapeHtml ? map.message : escapeHtml(map.message)).addClass(options.messageClass); | ||||
$toastElement.append($messageElement); | ||||
} | ||||
} | ||||
function setCloseButton() { | ||||
if (options.closeButton) { | ||||
$closeElement.addClass('toast-close-button').attr('role', 'button'); | ||||
$toastElement.prepend($closeElement); | ||||
} | ||||
} | ||||
function setProgressBar() { | ||||
if (options.progressBar) { | ||||
$progressElement.addClass('toast-progress'); | ||||
$toastElement.prepend($progressElement); | ||||
} | ||||
} | ||||
function shouldExit(options, map) { | ||||
if (options.preventDuplicates) { | ||||
if (map.message === previousToast) { | ||||
return true; | ||||
} else { | ||||
previousToast = map.message; | ||||
} | ||||
} | ||||
return false; | ||||
} | ||||
function hideToast(override) { | ||||
var method = override && options.closeMethod !== false ? options.closeMethod : options.hideMethod; | ||||
var duration = override && options.closeDuration !== false ? | ||||
options.closeDuration : options.hideDuration; | ||||
var easing = override && options.closeEasing !== false ? options.closeEasing : options.hideEasing; | ||||
if ($(':focus', $toastElement).length && !override) { | ||||
return; | ||||
} | ||||
clearTimeout(progressBar.intervalId); | ||||
return $toastElement[method]({ | ||||
duration: duration, | ||||
easing: easing, | ||||
complete: function () { | ||||
removeToast($toastElement); | ||||
if (options.onHidden && response.state !== 'hidden') { | ||||
options.onHidden(); | ||||
} | ||||
response.state = 'hidden'; | ||||
response.endTime = new Date(); | ||||
publish(response); | ||||
} | ||||
}); | ||||
} | ||||
function delayedHideToast() { | ||||
if (options.timeOut > 0 || options.extendedTimeOut > 0) { | ||||
intervalId = setTimeout(hideToast, options.extendedTimeOut); | ||||
progressBar.maxHideTime = parseFloat(options.extendedTimeOut); | ||||
progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime; | ||||
} | ||||
} | ||||
function stickAround() { | ||||
clearTimeout(intervalId); | ||||
progressBar.hideEta = 0; | ||||
$toastElement.stop(true, true)[options.showMethod]( | ||||
{duration: options.showDuration, easing: options.showEasing} | ||||
); | ||||
} | ||||
function updateProgress() { | ||||
var percentage = ((progressBar.hideEta - (new Date().getTime())) / progressBar.maxHideTime) * 100; | ||||
$progressElement.width(percentage + '%'); | ||||
} | ||||
} | ||||
function getOptions() { | ||||
return $.extend({}, getDefaults(), toastr.options); | ||||
} | ||||
function removeToast($toastElement) { | ||||
if (!$container) { $container = getContainer(); } | ||||
if ($toastElement.is(':visible')) { | ||||
return; | ||||
} | ||||
$toastElement.remove(); | ||||
$toastElement = null; | ||||
if ($container.children().length === 0) { | ||||
$container.remove(); | ||||
previousToast = undefined; | ||||
} | ||||
} | ||||
})(); | ||||
}); | ||||
}(typeof define === 'function' && define.amd ? define : function (deps, factory) { | ||||
if (typeof module !== 'undefined' && module.exports) { //Node | ||||
module.exports = factory(require('jquery')); | ||||
} else { | ||||
window.toastr = factory(window.jQuery); | ||||
} | ||||
})); | ||||