UNPKG

alertifyjs

Version:

AlertifyJS is a javascript framework for developing pretty browser dialogs and notifications.

327 lines (312 loc) 13.8 kB
var notifier = (function () { var reflow, element, openInstances = [], classes = defaults.notifier.classes, baseClass = classes.base; /** * Helper: initializes the notifier instance * */ function initialize(instance) { if (!instance.__internal) { instance.__internal = { position: alertify.defaults.notifier.position, delay: alertify.defaults.notifier.delay, }; element = document.createElement('DIV'); var transitionOff = 'transitionOff' in defaults.notifier ? defaults.notifier.transitionOff : defaults.transitionOff; if(transitionOff){ baseClass = classes.base + ' ajs-no-transition'; } updatePosition(instance); } //add to DOM tree. if (element.parentNode !== document.body) { document.body.appendChild(element); } } function pushInstance(instance) { instance.__internal.pushed = true; openInstances.push(instance); } function popInstance(instance) { openInstances.splice(openInstances.indexOf(instance), 1); instance.__internal.pushed = false; } /** * Helper: update the notifier instance position * */ function updatePosition(instance) { element.className = baseClass; switch (instance.__internal.position) { case 'top-right': addClass(element, classes.top + ' ' + classes.right); break; case 'top-left': addClass(element, classes.top + ' ' + classes.left); break; case 'top-center': addClass(element, classes.top + ' ' + classes.center); break; case 'bottom-left': addClass(element, classes.bottom + ' ' + classes.left); break; case 'bottom-center': addClass(element, classes.bottom + ' ' + classes.center); break; default: case 'bottom-right': addClass(element, classes.bottom + ' ' + classes.right); break; } } /** * creates a new notification message * * @param {DOMElement} message The notifier message element * @param {Number} wait Time (in ms) to wait before the message is dismissed, a value of 0 means keep open till clicked. * @param {Function} callback A callback function to be invoked when the message is dismissed. * * @return {undefined} */ function create(div, callback) { function clickDelegate(event, instance) { if(!instance.__internal.closeButton || event.target.getAttribute('data-close') === 'true'){ instance.dismiss(true); } } function transitionDone(event, instance) { // unbind event off(instance.element, transition.type, transitionDone); // remove the message element.removeChild(instance.element); } function initialize(instance) { if (!instance.__internal) { instance.__internal = { pushed: false, delay : undefined, timer: undefined, clickHandler: undefined, transitionEndHandler: undefined, transitionTimeout: undefined }; instance.__internal.clickHandler = delegate(instance, clickDelegate); instance.__internal.transitionEndHandler = delegate(instance, transitionDone); } return instance; } function clearTimers(instance) { clearTimeout(instance.__internal.timer); clearTimeout(instance.__internal.transitionTimeout); } return initialize({ /* notification DOM element*/ element: div, /* * Pushes a notification message * @param {string or DOMElement} content The notification message content * @param {Number} wait The time (in seconds) to wait before the message is dismissed, a value of 0 means keep open till clicked. * */ push: function (_content, _wait) { if (!this.__internal.pushed) { pushInstance(this); clearTimers(this); var content, wait; switch (arguments.length) { case 0: wait = this.__internal.delay; break; case 1: if (typeof (_content) === 'number') { wait = _content; } else { content = _content; wait = this.__internal.delay; } break; case 2: content = _content; wait = _wait; break; } this.__internal.closeButton = alertify.defaults.notifier.closeButton; // set contents if (typeof content !== 'undefined') { this.setContent(content); } // append or insert if (notifier.__internal.position.indexOf('top') < 0) { element.appendChild(this.element); } else { element.insertBefore(this.element, element.firstChild); } reflow = this.element.offsetWidth; addClass(this.element, classes.visible); // attach click event on(this.element, 'click', this.__internal.clickHandler); return this.delay(wait); } return this; }, /* * {Function} callback function to be invoked before dismissing the notification message. * Remarks: A return value === 'false' will cancel the dismissal * */ ondismiss: function () { }, /* * {Function} callback function to be invoked when the message is dismissed. * */ callback: callback, /* * Dismisses the notification message * @param {Boolean} clicked A flag indicating if the dismissal was caused by a click. * */ dismiss: function (clicked) { if (this.__internal.pushed) { clearTimers(this); if (!(typeof this.ondismiss === 'function' && this.ondismiss.call(this) === false)) { //detach click event off(this.element, 'click', this.__internal.clickHandler); // ensure element exists if (typeof this.element !== 'undefined' && this.element.parentNode === element) { //transition end or fallback this.__internal.transitionTimeout = setTimeout(this.__internal.transitionEndHandler, transition.supported ? 1000 : 100); removeClass(this.element, classes.visible); // custom callback on dismiss if (typeof this.callback === 'function') { this.callback.call(this, clicked); } } popInstance(this); } } return this; }, /* * Delays the notification message dismissal * @param {Number} wait The time (in seconds) to wait before the message is dismissed, a value of 0 means keep open till clicked. * */ delay: function (wait) { clearTimers(this); this.__internal.delay = typeof wait !== 'undefined' && !isNaN(+wait) ? +wait : notifier.__internal.delay; if (this.__internal.delay > 0) { var self = this; this.__internal.timer = setTimeout(function () { self.dismiss(); }, this.__internal.delay * 1000); } return this; }, /* * Sets the notification message contents * @param {string or DOMElement} content The notification message content * */ setContent: function (content) { if (isString(content)) { clearContents(this.element); this.element.innerHTML = content; } else if (content instanceof window.HTMLElement && this.element.firstChild !== content) { clearContents(this.element); this.element.appendChild(content); } if(this.__internal.closeButton){ var close = document.createElement('span'); addClass(close, classes.close); close.setAttribute('data-close', true); this.element.appendChild(close); } return this; }, /* * Dismisses all open notifications except this. * */ dismissOthers: function () { notifier.dismissAll(this); return this; } }); } //notifier api return { /** * Gets or Sets notifier settings. * * @param {string} key The setting name * @param {Variant} value The setting value. * * @return {Object} if the called as a setter, return the notifier instance. */ setting: function (key, value) { //ensure init initialize(this); if (typeof value === 'undefined') { //get return this.__internal[key]; } else { //set switch (key) { case 'position': this.__internal.position = value; updatePosition(this); break; case 'delay': this.__internal.delay = value; break; } } return this; }, /** * [Alias] Sets dialog settings/options */ set:function(key,value){ this.setting(key,value); return this; }, /** * [Alias] Gets dialog settings/options */ get:function(key){ return this.setting(key); }, /** * Creates a new notification message * * @param {string} type The type of notification message (simply a CSS class name 'ajs-{type}' to be added). * @param {Function} callback A callback function to be invoked when the message is dismissed. * * @return {undefined} */ create: function (type, callback) { //ensure notifier init initialize(this); //create new notification message var div = document.createElement('div'); div.className = classes.message + ((typeof type === 'string' && type !== '') ? ' ' + classes.prefix + type : ''); return create(div, callback); }, /** * Dismisses all open notifications. * * @param {Object} excpet [optional] The notification object to exclude from dismissal. * */ dismissAll: function (except) { var clone = openInstances.slice(0); for (var x = 0; x < clone.length; x += 1) { var instance = clone[x]; if (except === undefined || except !== instance) { instance.dismiss(); } } } }; })();