1(function ($, window) { 2 'use strict'; 3 var OUAlerts = function (element, options) { 4 this.el = $(element); 5 this.$notification = null; 6 this.$widget = null; 7 this.orgPadding = null; 8 this.severity = null; 9 this.defaults = { 10 'archivedPath' : '/ou-alerts/archived-alerts.xml', 11 'activePath' : '/ou-alerts/active-alerts.xml', 12 //Alert details 13 'icon' : false, 14 'title' : true, 15 'subtitle' : true, 16 'description' : true, 17 'link' : true, 18 'date' : true, 19 'dateFormat' : '', 20 //behavior 21 'delay' : false, 22 'closeOnClick' : true, 23 'popup' : true, 24 'showRecent' : true, 25 //CSS classes 26 'showClass': 'fadeInDown', 27 'hideClass': 'zoomOut', 28 'animationType' : 'animated-fast', 29 'emergency': { 30 'class' : 'oualerts-notify-error', 31 'position' : 'modal', 32 'icon' : 'fa fa-exclamation-triangle', 33 'iconColor' : '#F44336', 34 'fontColor' : '', 35 'backgroundColor' : '#FFC5C0', 36 'template' : false 37 }, 38 'warning': { 39 'class' : 'oualerts-notify-warning', 40 'position' : 'top', 41 'icon' : 'fa fa-exclamation-circle', 42 'iconColor' : '#f08a24', 43 'fontColor' : '', 44 'backgroundColor' : '#FFE5C0', 45 'template' : false 46 }, 47 'announcement': { 48 'class' : 'oualerts-notify-info', 49 'position' : 'top', 50 'icon' : 'fa fa-bullhorn', 51 'iconColor' : '#6091ba', 52 'fontColor' : '', 53 'backgroundColor' : '#B3CFE8', 54 'template' : false 55 }, 56 'widgetTemplate' : false, 57 'archiveHeader' : true 58 }; 59 60 $.extend(true, this.defaults, options); 61 62 this.init(); 63 }; 64 65 OUAlerts.prototype.init = function () { 66 var self = this; 67 68 this.loading(); 69 70 if (this.defaults.type === 'active') { 71 //this is an active alert 72 this.fetch('active').then(function(data) { 73 if (!data || data.alert === undefined) { return; } 74 if (self.defaults.popup === true) { 75 self.notify(data, self.defaults); 76 } else { 77 self.loading(true); 78 //widget 79 self.widget(data, self.defaults); 80 } 81 }); 82 } else { 83 this.fetch('archived').then(function(data) { 84 if (!data || data.archive === undefined) { return; } 85 self.loading(true); 86 self.widget(data, self.defaults, true); 87 }); 88 } 89 }; 90 91 OUAlerts.prototype.fetch = function (type) { 92 var self = this, 93 def = $.Deferred(), 94 path = type === 'active' ? this.defaults.activePath : this.defaults.archivedPath; 95 96 $.ajax({ 97 type: "GET", 98 url: path, 99 cache: false, 100 dataType: "xml", 101 success: function(xml) { 102 //parse data/sort content 103 if (type === 'active') { 104 def.resolve(self.prepareData(xmlToJson(xml))); 105 } else { 106 def.resolve(self.prepareArchivedData(xmlToJson(xml))); 107 } 108 }, 109 error : function (err) { 110 def.reject(err); 111 } 112 }); 113 return def; 114 }; 115 116 OUAlerts.prototype.widget = function (data, options, archived) { 117 if (typeof options.widgetTemplate === 'function') { 118 this.$widget = options.widgetTemplate(data, options); 119 } else { 120 if (archived) { 121 this.$widget = _createArchivedTemplate(data, options); 122 } else { 123 this.$widget = _createWidgetTemplate(data, options); 124 } 125 } 126 this.el.html(this.$widget); 127 }; 128 129 OUAlerts.prototype.notify = function (data, options) { 130 //top, bottom, or modal view 131 var css, self = this; 132 this.severity = data.alert['ou:severity'].toLowerCase(); 133 134 if (typeof self.defaults[self.severity].template === 'function') { 135 this.$notification = self.defaults[self.severity].template(data, options); 136 } else { 137 if (options.showRecent) { 138 //get most recent update 139 var items = []; 140 items.push(data.alert); 141 items = items.concat(data.updates); 142 //sort 143 items.sort(function (a, b) { 144 return new Date(b.pubDate) - new Date(a.pubDate); 145 }); 146 147 items[0]['ou:severity'] = data.alert['ou:severity']; 148 149 this.$notification = this.createNotificationTemplate(items[0], options); 150 } else { 151 this.$notification = this.createNotificationTemplate(data.alert, options); 152 } 153 } 154 155 if (options.closeOnClick) { 156 $('body').click(function () { 157 self.remove(); 158 }); 159 } 160 161 if (options.delay) { 162 setTimeout(function() { 163 self.el.append(self.$notification); 164 if (self.defaults[self.severity].position === 'top') { 165 self.applyPadding(); 166 } 167 }, options.delay); 168 } else { 169 this.el.append(this.$notification); 170 if (self.defaults[self.severity].position === 'top') { 171 self.applyPadding(); 172 } 173 } 174 }; 175 176 OUAlerts.prototype.calcPadding = function (orgPadding){
177 var alert = this.$notification; 178 var newPadding = orgPadding + alert.height() + 'px'; 179 this.el.css('padding-top', newPadding); 180 }; 181 182 OUAlerts.prototype.applyPadding = function (){ 183 $("body").addClass("ou-alerts-active"); 184 this.orgPadding = parseInt(this.el.css('padding-top')); 185 this.calcPadding(this.orgPadding); 186 $(window).resize(this.calcPadding(this.orgPadding)); 187 }; 188 189 OUAlerts.prototype.remove = function () { 190 var self = this; 191 $("body").removeClass("ou-alerts-active"); 192 if (this.defaults[this.severity.toLowerCase()].position === 'top') { 193 this.el.css('padding-top', this.orgPadding); 194 } 195 196 this.$notification.removeClass(this.defaults.showClass) 197 .addClass(this.defaults.hideClass); 198 199 if (window.AnimationEvent) { 200 this.$notification.on('oanimationend animationend webkitAnimationEnd', function() { 201 self.$notification.remove(); 202 }); 203 } else { 204 self.$notification.remove(); 205 } 206 207 }; 208 209 OUAlerts.prototype.prepareArchivedData = function (data) { 210 var items, alerts = []; 211 212 // only grab data if there is an item, and that item has a valid title 213 if (!data.rss.channel.item) { return false; } 214 if (isArray(data.rss.channel.item)) { 215 if (!data.rss.channel.item || data.rss.channel.item["0"] === undefined || data.rss.channel.item["0"].title["#text"] === undefined) { return false; } 216 } else { 217 if (data.rss.channel.item.title === undefined) { return false; } 218 } 219 220 if (data.rss.channel.item && !data.rss.channel.item.length) { 221 items = [data.rss.channel.item]; 222 } else { 223 items = data.rss.channel.item; 224 } 225 226 $.each(items, function (i, item) { 227 if (item['dc:type']['#text'] === 'alert'){ 228 item.updates = []; 229 $.each(items, function (i, update) { 230 if (update['dc:type']['#text'] === 'update' && update['dc:identifier']['#text'] === item['dc:identifier']['#text']){ 231 item.updates.push(clean(update)); 232 } 233 }); 234 alerts.push(clean(item)); 235 } 236 }); 237 var feed = { 238 archive : alerts, 239 channel : { 240 description : data.rss.channel.description['#text'], 241 language : data.rss.channel.language['#text'], 242 lastBuildDate : data.rss.channel.lastBuildDate['#text'], 243 link : data.rss.channel.link['#text'], 244 title : data.rss.channel.title['#text'] 245 } 246 }; 247 return feed; 248 }; 249 250 function isArray(what) { 251 return Object.prototype.toString.call(what) === '[object Array]'; 252 } 253 254 OUAlerts.prototype.prepareData = function (data) { 255 var alert, items, updates = []; 256 257 // only grab data if there is an item, and that item has a valid title 258 if (!data.rss.channel.item) { return false; } 259 if (isArray(data.rss.channel.item)) { 260 if (!data.rss.channel.item || data.rss.channel.item["0"] === undefined || data.rss.channel.item["0"].title["#text"] === undefined) { return false; } 261 } else { 262 if (data.rss.channel.item.title === undefined) { return false; } 263 } 264 265 if (data.rss.channel.item && !data.rss.channel.item.length) { 266 items = [data.rss.channel.item]; 267 } else { 268 items = data.rss.channel.item; 269 } 270 $.each(items, function (i, item) { 271 if (item['dc:type']['#text'] === 'alert'){ 272 alert = clean(item); 273 } else 274 if (item['dc:type']['#text'] === 'update'){ 275 updates.push(clean(item)); 276 } 277 }); 278 279 if (updates.length){ 280 updates.sort(function (a, b) { 281 return new Date(b.pubDate) - new Date(a.pubDate); 282 }); 283 } 284 285 var feed = { 286 alert : alert, 287 updates : updates, 288 channel : { 289 description : data.rss.channel.description['#text'], 290 language : data.rss.channel.language['#text'], 291 lastBuildDate : data.rss.channel.lastBuildDate['#text'], 292 link : data.rss.channel.link['#text'], 293 title : data.rss.channel.title['#text'] 294 } 295 }; 296 297 return feed; 298 }; 299 300 //add loading class to container 301 OUAlerts.prototype.loading = function (done) { 302 if (!this.defaults.popup && !done) { 303 this.el.addClass('loading'); 304 } else 305 if (done) { 306 this.el.addClass('ready'); 307 this.el.removeClass('loading'); 308 } 309 }; 310 311 var _createArchivedTemplate = function (data, options) { 312 var $archiveCont = $('<div class="oualerts-archive-wrapper"></div>'); 313 var $archiveHeader = $('<h2>Archived Alerts</h2>'); 314 var $archiveList = $('<ul class="oualerts-archive-list"></ul>'); 315 316 $.each(data.archive, function(i, item) { 317 var $alert = _alertTemplate(item, options); 318 var $tmpl = $('<li class="oualerts-archive"></li>'); 319 var $updateCont = $('<ul class="oualerts-update-cont"/>'); 320 321 $tmpl.append($alert); 322 //updates 323 if (item.updates && item.updates.length) { 324 var $updateContHeader = $('<h4 class="oualerts-archive-update-header">UPDATES</h4>'); 325 $tmpl.append($updateContHeader); 326 $tmpl.append('<hr/>'); 327 $tmpl.append($updateCont); 328 $.each(item.updates, function(i, update) { 329 var $update = _updateTemplate(update, options, true); 330 var $updateTmpl = $('<li class="oualerts-archive-update"></li>'); 331 if (i === item.updates.length - 1) { 332 $updateTmpl.append($update); 333 } else { 334 $updateTmpl.append($update).append('<hr/>'); 335 } 336 $updateCont.append($updateTmpl); 337 }); 338 $tmpl.append($updateCont); 339 }
340 $archiveList.append($tmpl); 341 }); 342 343 if (options.archiveHeader) { 344 $archiveCont.append($archiveHeader); 345 } 346 347 $archiveCont.append($archiveList); 348 349 return $archiveCont; 350 }; 351 352 var _alertTemplate = function (data, options) { 353 var $alertContainer = $('<article/>'); 354 var $alertDate = $('<div class="oualerts-date">' + convertDateTime(data.pubDate) + '</div>'); 355 var $alertTitle = $('<h2 class="oualerts-title"></h2>'); 356 $alertTitle.text(data.title); 357 var $alertDescription = $('<p class="oualerts-msg"></p>'); 358 $alertDescription.text(data.description); 359 360 if (options.icon) { 361 var $icon, icon = options[data['ou:severity'].toLowerCase()].icon; 362 //image instead of icon 363 if (icon.indexOf('/') > -1) { 364 $icon = $('<img class="oualerts-title-icon" src="' + icon + '" alt="Alert Icon"/>'); 365 } else { 366 $icon = $('<i class="' + icon + '"></i>'); 367 var iconColor = options[data['ou:severity'].toLowerCase()].iconColor; 368 if (iconColor) { 369 $icon.css({ color : iconColor}); 370 } 371 } 372 373 $alertTitle.prepend($icon); 374 } 375 376 $alertContainer 377 .append($alertDate) 378 .append($alertTitle); 379 380 if (data['ou:subtitle']) { 381 var $subTitle = $('<h3 class="oualerts-subtitle"></h3>'); 382 $subTitle.text(data['ou:subtitle']); 383 384 $alertContainer 385 .append($subTitle); 386 } 387 388 $alertContainer 389 .append($alertDescription); 390 391 return $alertContainer; 392 }; 393 394 var _updateTemplate = function (data, options, archive) { 395 var $update = $('<article/>'); 396 var $date = $('<div class="oualerts-date oualerts-active-update-date">' + convertDateTime(data.pubDate) + '</div>'); 397 var $title = $('<h5 class="' + (archive ? '' : 'oualerts-active-update-title') + '"></h5>'); 398 var $description = $('<p class="oualerts-active-update-msg"></p>'); 399 400 $title.text(data.title); 401 $description.text(data.description); 402 403 $update 404 .append($date) 405 .append($title) 406 .append($description); 407 408 return $update; 409 }; 410 411 var _createWidgetTemplate = function (data, options) { 412 var $alertContainer = _alertTemplate(data.alert, options); 413 var $updateHeader = $('<h4 class="oualerts-active-update-title">UPDATES</h4>'); 414 var $updateCont = $('<ul class="oualerts-active-update-list"/>'); 415 416 $.each(data.updates, function(i, update) { 417 var $updateTmpl = $('<li class="oualerts-active-update"></li>'); 418 $updateTmpl.append(_updateTemplate(update, options)); 419 if (i === data.updates.length - 1) { 420 $updateCont.append($updateTmpl); 421 } else { 422 $updateCont.append($updateTmpl).append('<hr/>'); 423 } 424 }); 425 426 if (data.updates.length) { 427 $alertContainer 428 .append($updateHeader) 429 .append('<hr/>') 430 .append($updateCont); 431 } 432 433 return $alertContainer; 434 }; 435 436 OUAlerts.prototype.createNotificationTemplate = function (alert, options) { 437 var self = this, 438 $iconEl, 439 $innerIconEl, 440 $iconWrapper, 441 $body, 442 $footer, 443 alertType = options[alert['ou:severity'].toLowerCase()], 444 position = alertType.position, 445 $notify = $('<div></div>', { 446 'class': 'oualerts-notify ' + alertType['class'] + ' ' + options.animationType + ' ' + options.showClass 447 }); 448 449 $body = $('<div class="oualerts-notify-body"/>'); 450 451 if (options.date) { 452 var date = convertDateTime(alert.pubDate); 453 var $date = $('<div class="oualerts-notify-date">' + date + '</div>'); 454 $body.append($date); 455 } 456 if (options.title) { 457 var $title = $('<h3 class="oualerts-notify-title"></h3>'); 458 $title.text(alert.title); 459 if (options.icon) { 460 var $icon = $('<i class="' + alertType.icon + '"></i>'); 461 var iconColor = alertType.iconColor; 462 if (iconColor) { 463 $icon.css({ color : iconColor}); 464 } 465 $title.prepend($icon); 466 } 467 $body.append($title); 468 } 469 if (options.subtitle && alert['ou:subtitle']) { 470 var $subTitle = $('<h4 class="oualerts-notify-subtitle"></h4>'); 471 $subTitle.text(alert['ou:subtitle']); 472 $body.append($subTitle); 473 } 474 if (options.description) { 475 var $desc = $('<p class="oualerts-notify-msg"></p>'); 476 $desc.text(alert.description); 477 if (options.link && alert.guid && alert.guid.indexOf('.xml') < 0) { 478 var $link = ' <a href="' + alert.guid + '" target="_blank" class="oualerts-notify-link">Read More...</a>'; 479 $desc.append($link); 480 } 481 $body.append($desc); 482 } 483 $footer = $('<p class="oualerts-notify-footer"></p>'); 484 $('<button class="oualerts-close-button' + (alertType.buttonClass ? ' ' + alertType.buttonClass.trim() : '') + '">' + (alertType.buttonText ? alertType.buttonText.trim() : 'Close') + '</button>').on('click', function () { 485 self.remove(); 486 }).appendTo($footer); 487 488 $body.append($footer); 489 490 $notify.append($body); 491 492 var backgroundColor = alertType.backgroundColor; 493 if (backgroundColor) { 494 $notify.css({ backgroundColor : backgroundColor}); 495 } 496 var fontColor = alertType.fontColor; 497 if (fontColor) { 498 $notify.css({ color : fontColor}); 499 } 500 501 if (position === 'bottom') { 502 $notify.addClass('oualerts-bottom'); 503 } else 504 if (position === 'top') { 505 $notify.addClass('oualerts-top'); 506 } else 507 if (position === 'modal') { 508 $notify.addClass('oualerts-modal'); 509 510 if (alertType.modalSize) { 511 $notify.addClass(alertType.modalSize); 512 } else { 513 $notify.addClass('large'); 514 } 515 516 $notify = $('<div class="oualerts-notify-modal-overlay"/>').append($notify); 517 } 518 519 return $notify; 520 }; 521 522 function convertDateTime(timestamp){ 523 var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
523November", "December" ]; 524 var time = new Date(timestamp); 525 var ampm = (time.getHours() >= 12)?"PM":"AM"; 526 var minutes = (time.getMinutes()<10?'0':'') + time.getMinutes(); 527 var hours = time.getHours(); 528 if (hours > 12) { hours -= 12; } else if (hours === 0) { hours = 12; } 529 var fullTime = " "+hours+":"+minutes+" "+ampm; 530 return monthNames[time.getMonth()]+" "+time.getDate()+", "+time.getFullYear()+fullTime; 531 } 532 533 function clean (data) { 534 for( var key in data) { 535 if (data[key]['#text']) { 536 data[key] = data[key]['#text']; 537 } else if ($.isEmptyObject(data[key])) { 538 data[key] = ""; 539 } 540 } 541 return data; 542 } 543 544 function xmlToJson(xml) { 545 var obj = {}; 546 547 if (xml.nodeType == 3) { // text 548 obj = xml.nodeValue; 549 } 550 if (xml.hasChildNodes()) { 551 for(var i = 0; i < xml.childNodes.length; i++) { 552 var item = xml.childNodes.item(i); 553 var nodeName = item.nodeName; 554 if (typeof(obj[nodeName]) == "undefined") { 555 obj[nodeName] = xmlToJson(item); 556 } else { 557 if (typeof(obj[nodeName].push) == "undefined") { 558 var old = obj[nodeName]; 559 obj[nodeName] = []; 560 obj[nodeName].push(old); 561 } 562 obj[nodeName].push(xmlToJson(item)); 563 } 564 } 565 } 566 return obj; 567 } 568 569 $.fn.OUAlert = function() { 570 var _ = this, opt = arguments[0], l = _.length, i = 0; 571 572 for(i; i < l; i++) { 573 _[i].OUAlert = new OUAlerts(_[i], opt); 574 } 575 return _; 576 }; 577 578 window.OUAlerts = OUAlerts; 579 580})(jQuery, window);
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.