PageSourceSearch

https://msjc.edu/_resources/js/emergency-alerts.js

js msjc.edu collected 2026-10-01 11:54:00 UTC 16,551 bytes, 580 lines download raw bytes

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 = '&nbsp;<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.