1(function() { 2 3"use strict"; 4 5BX.namespace("BX.UI.Notification"); 6 7/** 8 * 9 * @enum {string} 10 */ 11BX.UI.Notification.Position = { 12 TOP_LEFT: "top-left", 13 TOP_CENTER: "top-center", 14 TOP_RIGHT: "top-right", 15 BOTTOM_LEFT: "bottom-left", 16 BOTTOM_CENTER: "bottom-center", 17 BOTTOM_RIGHT: "bottom-right" 18}; 19 20/** 21 * @typedef {object} BX.UI.Notification.StackOptions 22 * @property {BX.UI.Notification.Position} [position] 23 * @property {number} [spacing=20] 24 * @property {number} [offsetX=25] 25 * @property {number} [offsetY=25] 26 * @property {boolean} [newestOnTop=false] 27 * @property {string} [balloonType] 28 * @property {string} [id] 29 */ 30 31/** 32 * 33 * @param {BX.UI.Notification.StackOptions} options 34 * @constructor 35 */ 36BX.UI.Notification.Stack = function(options) 37{ 38 options = BX.type.isPlainObject(options) ? options : Object.create(null); 39 40 /** 41 * 42 * @type {BX.UI.Notification.Balloon[]} 43 */ 44 this.balloons = []; 45 46 /** 47 * 48 * @type {BX.UI.Notification.Balloon[]} 49 */ 50 this.queueStack = []; 51 52 this.id = BX.type.isNotEmptyString(options.id) ? options.id : BX.util.getRandomString(8).toLowerCase(); 53 this.position = BX.UI.Notification.Stack.getPositionCode(options.position) ? options.position : "top-right"; 54 55 this.spacing = 20; 56 this.offsetX = 25; 57 this.offsetY = 25; 58 this.newestOnTop = false; 59 this.balloonType = BX.UI.Notification.Balloon; 60 61 this.setOptions(options); 62 63 BX.addCustomEvent(BX.UI.Notification.Event.getFullName("onClose"), this.handleBalloonClose.bind(this)); 64}; 65 66BX.UI.Notification.Stack.getPositionCode = function(position) 67{ 68 for (var code in BX.UI.Notification.Position) 69 { 70 if (BX.UI.Notification.Position[code] === position) 71 { 72 return code; 73 } 74 } 75 76 return null; 77}; 78 79BX.UI.Notification.Stack.prototype = 80{ 81 /** 82 * @public 83 * @param {BX.UI.Notification.Balloon} [balloon] 84 */ 85 adjustPosition: function(balloon) 86 { 87 var offset = 0; 88 this.getBalloons().forEach(function(currentBalloon) { 89 90 if (!balloon || balloon === currentBalloon) 91 { 92 if (currentBalloon.doNotAdjustPosition) 93 { 94 return; 95 } 96 97 switch (this.getPosition()) 98 { 99 case BX.UI.Notification.Position.TOP_LEFT: 100 currentBalloon.getContainer().style.left = this.getOffsetX() + "px"; 101 currentBalloon.getContainer().style.top = offset + this.getOffsetY() + "px"; 102 break; 103 case BX.UI.Notification.Position.TOP_CENTER: 104 currentBalloon.getContainer().style.left = "50%"; 105 currentBalloon.getContainer().style.transform = "translateX(-50%)"; 106 currentBalloon.getContainer().style.top = offset + this.getOffsetY() + "px"; 107 break; 108 case BX.UI.Notification.Position.TOP_RIGHT: 109 currentBalloon.getContainer().style.right = this.getOffsetX() + "px"; 110 currentBalloon.getContainer().style.top = offset + this.getOffsetY() + "px"; 111 break; 112 case BX.UI.Notification.Position.BOTTOM_LEFT: 113 currentBalloon.getContainer().style.left = this.getOffsetX() + "px"; 114 currentBalloon.getContainer().style.bottom = offset + this.getOffsetY() + "px"; 115 break; 116 case BX.UI.Notification.Position.BOTTOM_CENTER: 117 currentBalloon.getContainer().style.left = "50%"; 118 currentBalloon.getContainer().style.transform = "translateX(-50%)"; 119 currentBalloon.getContainer().style.bottom = offset + this.getOffsetY() + "px"; 120 break; 121 case BX.UI.Notification.Position.BOTTOM_RIGHT: 122 currentBalloon.getContainer().style.right = this.getOffsetX() + "px"; 123 currentBalloon.getContainer().style.bottom = offset + this.getOffsetY() + "px"; 124 break; 125 } 126 } 127 128 offset += this.getSpacing() + currentBalloon.getHeight(); 129 130 }, this); 131 132 }, 133 134 /** 135 * @public 136 * @param {BX.UI.Notification.Balloon} balloon 137 */ 138 add: function(balloon) 139 { 140 if (this.getBalloons().length > 0 && (this.getQueue().length > 0 || !this.isBalloonFitToViewport(balloon))) 141 { 142 this.queue(balloon); 143 } 144 else 145 { 146 this.push(balloon); 147 } 148 }, 149 150 clear() 151 { 152 const balloons = [...this.balloons, ...this.queueStack]; 153 this.queueStack = []; 154 this.balloons = []; 155 156 balloons.forEach((balloon) => { 157 return balloon.close(); 158 }); 159 }, 160 161 /** 162 * @private 163 * @param {BX.UI.Notification.Balloon} balloon 164 */ 165 push: function(balloon) 166 { 167 if (!(balloon instanceof BX.UI.Notification.Balloon)) 168 { 169 throw new Error("'balloon' must be an instance of BX.UI.Notification.Balloon."); 170 } 171 172 if (this.balloons.indexOf(balloon) === -1) 173 { 174 if (this.isNewestOnTop()) 175 { 176 this.balloons.splice(0, 0, balloon); 177 } 178 else 179 {
180 this.balloons.push(balloon); 181 } 182 } 183 }, 184 185 /** 186 * @private 187 * @param {BX.UI.Notification.Balloon} balloon 188 */ 189 queue: function(balloon) 190 { 191 if (!(balloon instanceof BX.UI.Notification.Balloon)) 192 { 193 throw new Error("'balloon' must be an instance of BX.UI.Notification.Balloon."); 194 } 195 196 if (this.queueStack.indexOf(balloon) === -1) 197 { 198 balloon.setState(BX.UI.Notification.State.QUEUED); 199 this.queueStack.push(balloon); 200 } 201 }, 202 203 /** 204 * @private 205 */ 206 checkQueue: function() 207 { 208 var queue = this.queueStack.slice(); 209 for (var i = 0; i < queue.length; i++) 210 { 211 var balloon = queue[i]; 212 if (!this.isBalloonFitToViewport(balloon) && this.getBalloons().length > 0) 213 { 214 break; 215 } 216 217 balloon.setState(BX.UI.Notification.State.INIT); 218 this.queueStack.shift(); 219 this.push(balloon); 220 221 balloon.show(); 222 } 223 }, 224 225 /** 226 * @private 227 * @return {BX.UI.Notification.Balloon[]} 228 */ 229 getQueue: function() 230 { 231 return this.queueStack; 232 }, 233 234 /** 235 * @private 236 * @param {BX.UI.Notification.Balloon} balloon 237 * @return {boolean} 238 */ 239 isBalloonFitToViewport: function(balloon) 240 { 241 var viewportHeight = document.documentElement.clientHeight; 242 var balloonHeight = this.getSpacing() + balloon.getHeight(); 243 244 return this.getHeight() + balloonHeight <= viewportHeight; 245 }, 246 247 /** 248 * @private 249 * @param {BX.UI.Notification.Event} event 250 */ 251 handleBalloonClose: function(event) 252 { 253 const closingBalloon = event.getBalloon(); 254 if (closingBalloon.getStack() !== this) 255 { 256 return; 257 } 258 259 this.balloons = this.balloons.filter((balloon) => { 260 return closingBalloon !== balloon; 261 }); 262 263 this.adjustPosition(); 264 this.checkQueue(); 265 }, 266 267 /** 268 * @package 269 * @param {BX.UI.Notification.StackOptions} options 270 */ 271 setOptions: function(options) 272 { 273 options = options || {}; 274 275 this.setSpacing(options.spacing); 276 this.setOffsetX(options.offsetX); 277 this.setOffsetY(options.offsetY); 278 this.setNewestOnTop(options.newestOnTop); 279 this.setBalloonType(options.balloonType); 280 }, 281 282 /** 283 * 284 * @return {string} 285 */ 286 getId: function() 287 { 288 return this.id; 289 }, 290 291 /** 292 * @public 293 * @return {BX.UI.Notification.Balloon[]} 294 */ 295 getBalloons: function() 296 { 297 return this.balloons; 298 }, 299 300 /** 301 * @public 302 * @return {BX.UI.Notification.Position} 303 */ 304 getPosition: function() 305 { 306 return this.position; 307 }, 308 309 /** 310 * @public 311 * @return {number} 312 */ 313 getSpacing: function() 314 { 315 return this.spacing; 316 }, 317 318 /** 319 * @public 320 * @param {number} spacing 321 */ 322 setSpacing: function(spacing) 323 { 324 if (BX.type.isNumber(spacing)) 325 { 326 this.spacing = spacing; 327 } 328 }, 329 330 /** 331 * @public 332 * @return {number} 333 */ 334 getOffsetX: function() 335 { 336 return this.offsetX; 337 }, 338 339 /** 340 * @public 341 * @param {number} offsetX 342 */ 343 setOffsetX: function(offsetX) 344 { 345 if (BX.type.isNumber(offsetX)) 346 { 347 this.offsetX = offsetX; 348 } 349 }, 350 351 /** 352 * @public 353 * @return {number} 354 */ 355 getOffsetY: function() 356 { 357 return this.offsetY; 358 }, 359 360 /** 361 * @public 362 * @param {number} offsetY 363 */ 364 setOffsetY: function(offsetY) 365 { 366 if (BX.type.isNumber(offsetY)) 367 { 368 this.offsetY = offsetY; 369 } 370 }, 371 372 /** 373 * @public 374 * @return {number} 375 */ 376 getHeight: function() 377 { 378 return this.getBalloons().reduce(function(height, balloon) { 379 return height + balloon.getHeight() + this.getSpacing(); 380 }.bind(this), this.getOffsetY()); 381 }, 382 383 /** 384 * 385 * @param {string} [className] 386 * @return {BX.UI.Notification.Balloon} 387 */ 388 getBalloonType: function(className) 389 { 390 if (BX.type.isFunction(className)) 391 { 392 return className; 393 } 394 395 var classFn = BX.getClass(className); 396 397 if (BX.type.isFunction(classFn)) 398 { 399 return classFn; 400 } 401 402 return this.balloonType || BX.UI.Notification.Balloon; 403 }, 404 405 setBalloonType: function(balloonType) 406 { 407 if (BX.type.isFunction(balloonType)) 408 { 409 this.balloonType = balloonType; 410 } 411 else if (BX.type.isNotEmptyString(balloonType)) 412 { 413 var classFn = BX.getClass(balloonType); 414 if (BX.type.isFunction(classFn)) 415 { 416 this.balloonType = classFn; 417 } 418 } 419 }, 420 421 /** 422 * @public 423 * @return {boolean} 424 */ 425 isNewestOnTop: function() 426 { 427 return this.newestOnTop; 428 }, 429 430 /** 431 * @public 432 * @param {boolean} onTop 433 */ 434 setNewestOnTop: function(onTop) 435 { 436 if (BX.type.isBoolean(onTop)) 437 { 438 this.newestOnTop = onTop; 439 } 440 } 441}; 442 443}
vendor: 5 bytes, line 443
443)();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.