1 /** Provides a managed notification/toast display area. 2 * @constructor Creates a new Notifier instance. 3 * @augments puredom.EventEmitter 4 * @param {Object} [options] Hashmap of options 5 * @param {puredom.NodeSelection} [options.parent] Construct the display area within a given element. 6 */ 7 puredom.Notifier = function(options) { 8 var self = this; 9 10 puredom.EventEmitter.call(this); 11 this._data = { 12 counter : 0, 13 list : {} 14 }; 15 16 this._notificationClickHandler = function(e) { 17 self._performAction(puredom.el(this).attr('data-notification-id'), 'notificationclick', e); 18 return puredom.cancelEvent(e); 19 }; 20 21 options = options || {}; 22 if (options.parent) { 23 this._createBase(options.parent); 24 } 25 }; 26 27 28 puredom.inherits(puredom.Notifier, puredom.EventEmitter); 29 30 31 puredom.extend(puredom.Notifier.prototype, /** @lends puredom.Notifier# */ { 32 33 /** Show a notification. 34 * @param {Object} config Describes what to display 35 * @param {Object} [config.message] The text to display 36 * @param {Object} [config.icon] Icon/image to show next to the text 37 * @param {Object} [config.image] Icon/image to show next to the text 38 * @param {Object} [config.timeout=Notifier.timeout] How many seconds to wait before auto-dismissing the notification 39 */ 40 show : function(config) { 41 var notify; 42 if (config) { 43 this._data.counter += 1; 44 notify = { 45 id : this._data.counter + '', 46 timeout : config.timeout || this.timeout 47 }; 48 this._data.list[notify.id] = notify; 49 50 notify.base = this._build(notify.id, config); 51 this._show(notify.id); 52 53 if (notify.timeout) { 54 this._resetTimeout(notify.id); 55 } 56 return notify; 57 } 58 return false; 59 }, 60 61 62 /** @private */ 63 _createBase : function(parent) { 64 if (this.notifications_base) { 65 this.notifications_base.remove(); 66 this.notifications_base.appendTo(parent); 67 } 68 else { 69 this.notifications_base = puredom.el({ 70 className : 'notifications_base' 71 }, parent); 72 } 73 }, 74 75 76 /** @private */ 77 _build : function(id, options) { 78 var base, iconSrc; 79 base = puredom.el({ 80 className : "notification", 81 css : 'height:0; opacity:0;', 82 attributes : { 83 'data-notification-id' : id 84 }, 85 children : [ 86 { className:'notification_top' }, 87 { 88 className : 'notification_inner', 89 children : [ 90 { className:'notification_inner_top' }, 91 { 92 className : 'notification_closeButton', 93 children : [ 94 { className:'label', innerHTML:this.closeButtonLabel || '×' } 95 ] 96 }, 97 { 98 className : 'notification_message', 99 children : [ 100 { className:'label', innerHTML:options.message || options.text } 101 ] 102 }, 103 { className:'notification_inner_bottom' } 104 ] 105 }, 106 { className:'notification_bottom' } 107 ], 108 onclick : this._notificationClickHandler 109 }, this.notifications_base); 110 111 // add an icon if specified 112 iconSrc = options.icon || options.image; 113 if (iconSrc!==false && this.defaultIcon) { 114 iconSrc = this.defaultIcon; 115 } 116 if (iconSrc) { 117 puredom.el({ 118 type : 'img', 119 className : 'notification_message', 120 attributes : { 121 src : options.icon || options.image || this.defaultIcon 122 } 123 }, base.query('.notification_inner')); 124 } 125 126 if (options.userDismiss===false) { 127 base.query('.notification_closeButton').hide(true); 128 } 129 130 return base; 131 }, 132 133 134 /** @private */ 135 _show : function(id) { 136 var notify = this.get(id); 137 if (notify) { 138 notify.base.css({ 139 opacity : 0 140 }).css({ 141 opacity : 1, 142 height : notify.base.children().height() 143 }, {tween:this.showTween || 'medium'}); 144 } 145 }, 146 147 148 /** @private*/ 149 _hide : function(id) { 150 var notify = this.get(id); 151 if (notify) { 152 notify.base.css({ 153 opacity : 0, 154 height : 0 155 }, {tween:this.hideTween || 'medium', callback:function() { 156 notify.base.remove(); 157 notify = null; 158 }}); 159 } 160 }, 161 162 163 /** @private */ 164 _resetTimeout : function(id) { 165 var notify = this.get(id), 166 self = this; 167 if (notify) { 168 if (notify._hideTimer) { 169 clearTimeout(notify._hideTimer); 170 } 171 if (notify.timeout) { 172 notify._hideTimer = setTimeout(function() { 173 self._hide(id); 174 self = id = null; 175 }, notify.timeout*1000); 176 } 177 notify = null; 178 } 179 }, 180 181 182 /** Get a notification by ID */ 183 get : function(id) { 184 return id && this._data.list.hasOwnProperty(id+'') && this._data.list[id+''] || false; 185 }, 186 187 188 /** @private */ 189 _performAction : function(id, action, args) { 190 var notify = this.get(id), 191 ret; 192 if (!puredom.isArray(args)) { 193 args = [args]; 194 } 195 if (action && notify) { 196 args = [id].concat(args); 197 ret = this.fireEvent(action, args); 198 if (ret!==false) { 199 switch (action.toLowerCase()) { 200 case 'notificationclick': 201 case 'notificationclicked': 202 this._hide(id); 203 break; 204 } 205 } 206 } 207 }, 208 209 210 /** @private */ 211 timeout : 15, 212 213 214 /** @private */ 215 _data : { 216 counter : 0, 217 list : {} 218 } 219 });