PageSourceSearch

https://events.middlesexcollege.edu/livewhale/plugins/jquery/jquery.lw-widget.js

js middlesexcollege.edu collected 2026-10-01 15:25:57 UTC 14,426 bytes, 476 lines download raw bytes

1/**
2 * jquery.lw-widget.js
3 *
4 * Usage:
5 *		 basic:		$(selector).lwWidget(options);
6 *		 methods: $(selector).lwWidget('method_name', arg1, arg2, etc);
7 *
8 * Description:
9 *		 This plugin inserts a widget on an external site
10 */
11
12(function($) {
13	var defaults = {
14		include_default_styles:  false,
15		group_by_date:					 false,
16		format:									 'json'
17	};
18
19	var disable_timezone = false;
20	var User = livewhale.lib.DateUser;
21	var Timezone = livewhale.lib.DateTimezone;
22
23	function getDefaultResults(opts, format_args, data) {
24		var result = '';
25
26		// for each widget result
27		$.each(data.data, function(key, val) {
28			var output = data.format,
29					has_image = false,
30					item;
31
32			// format each result
33			$.each(format_args, function(key2, val2) {
34				// make title a link if url exists
35				if (val2 === 'title' && val.title && val.url) {
36					val.title = '<a href="' + val.url + '">' + val.title + '</a>';
37				}
38
39				//
40				if (val2 === 'thumbnail' && val.thumbnail) {
41					var img_alt = (val.title) ? encodeURIComponent(val.title) : 'Thumbnail Image';
42					val.thumbnail = '<span class="lw_item_thumb">' + (val.url ? '<a href="' + val.url + '">' : '')
43						+ '<img src="' + val.thumbnail + '" alt="' + img_alt + '"/>' + (val.url ? '</a>' : '') + '</span>';
44					has_image = true;
45				}
46				output = output.replace('{' + val2 + '}', (val[val2] ? val[val2] : ''));
47			});
48			result += '<div class="lw_widget_item' + (has_image ? ' lw_has_image' : '') + '">' + output + '</div>';
49		});
50		return result;
51	}
52
53	function getEventsResults(opts, format_args, data) {
54		var results = {},
55				result = '';
56
57		// set default timezone and formats based on widget group
58		Timezone.time_format[data.group.timezone_format] = data.group.time_format;
59		Timezone.date_format[data.group.timezone_format] = data.group.date_format;
60		Timezone.setUserFormatZone(data.group.timezone_format);
61
62		// strip PHP % in datetime formats; reassign to TZ formats if present
63		$.each(['date_format', 'time_format'], function(i, format) {
64			if (typeof data[format] === 'string') {
65				data[format] = data[format].replace(/(^|[^%]{1})%/g, '$1');
66				if (data[format] && typeof Timezone[format][data.group.timezone_format] !== 'undefined') {
67					Timezone[format][data.group.timezone_format] = data[format];
68				}
69			}
70		});
71
72		function getItem(val) {
73			var output = ((val.is_starred === 1) ? data.format_starred : data.format),
74				has_image = false,
75				start_time = new Timezone(val.date_ts, val.tz_offset),
76				end_time = (val.date2_ts) ? new Timezone(val.date2_ts, val.tz_offset) : null,
77				event_url;
78
79			if (val.title) {
80				val.title_clean = val.title;
81			} else {
82				val.title_clean = '';
83			}
84
85			// handle different landing page url
86			if (val.url && val.url.length > 0) {
87				event_url = val.url;
88			} else {
89				event_url = null;
90			}
91			if (data.type === 'events' && val.id && data.group.directory && data.group.directory !== opts.host + '/') {
92				event_url = data.group.directory + '#!event_id/' + val.id + '/view/event';
93			}
94
95			// format each result
96			$.each(format_args, function(key2, val2) {
97				// show date range if multi-day event
98				if (val2 === 'date' && end_time && start_time.getShortDateString() !== end_time.getShortDateString()) {
99					if (start_time.getMonth() === end_time.getMonth()) {
100						val[val2] = val[val2] + '-' + end_time.getDate();
101					} else {
102						val[val2] = val[val2] + ' - ' + end_time.getFormattedDate('F d');
103					}
104				}
105
106				// make title a link if url exists
107				if (val2 === 'title' && val.title && event_url) {
108					val.title = '<a href="' + event_url + '" class="lw_events_title">' + val.title + '</a>';
109				}
110
111				// handle image, image_src
112				if (val2 === 'image' && val.image) {
113					val.image = val.image.replace(/(href|src)="(?!(http|\/\/))(.*?)"/ig, '$1="' + opts.host + '$3"');
114					if (val.image_src) {
115						val.image_src = opts.host + val.image_src;
116					}
117					has_image = true;
118				}
119
120				// handle thumbnail
121				if (val2 === 'thumbnail' && val.thumbnail) {
122					var img_alt = (val.title) ? encodeURIComponent(val.title) : 'Thumbnail Image';
123					val.thumbnail = '<span class="lw_item_thumb">' + (event_url ? '<a href="' + event_url + '">' : '') + '<img src="' + val.image_src + '" alt="' + img_alt + '"/>
123' + (event_url ? '</a>' : '') + '</span>';
124					has_image = true;
125				}
126
127				// handle links in summary/description
128				if ((val2 === 'summary' || val2 === 'description') && val[val2] && val[val2].match(/<[^>]+(href|src)=[^>]+>/i)) {
129					val[val2] = val[val2].replace(/(href|src)="(?!(http|\/\/))(.*?)"/ig, '$1="' + opts.host + '$3"');
130				}
131
132				// make time available, showing only original timezone value
133				if (val2 === 'time') { // change to 'time' when this is completed
134					if (val.is_all_day && (val.is_all_day === true || val.is_all_day === '1' || val.is_all_day === 1)) {
135						val[val2] = 'All Day';
136					} else if (val.date_ts) {
137						val[val2] = start_time.getTimeString(); // and output the formatted string
138						if (end_time) {
139							if (start_time.getShortDateString() === end_time.getShortDateString()) { // if same day
140								if (start_time.getTimeString() !== end_time.getTimeString()) { // append end time if different
141									val[val2] += '&nbsp;&ndash;&nbsp;' + end_time.getTimeString();
142								}
143							} else { // show date with end time
144								val[val2] += ' until ' + end_time.getShortDateString() + ', ' + end_time.getTimeString();
145							}
146						}
147					}
148				}
149				output = output.replace('{' + val2 + '}', (val[val2] ? val[val2] : ''));
150			});
151
152			return '<div class="lw_widget_item' + (has_image ? ' lw_has_image' : '') + (val.is_starred ? ' lw_is_starred' : '') + '">' + output + '</div>';
153		}
154
155		if (opts.group_by_date) {
156			$.each(data.data, function(index, item) {
157				var start_time = new Timezone(item.date_ts, item.tz_offset),
158					date = item.date,
159					end_time;
160
161				if (item.date2_ts) {
162					end_time = new Timezone(item.date2_ts, item.tz_offset);
163					// show date range if multi-day event
164					if (start_time.getShortDateString() !== end_time.getShortDateString()) {
165						if (start_time.getMonth() === end_time.getMonth()) {
166							date += '-' + end_time.getDate();
167						} else {
168							date += ' - ' + end_time.getFormattedDate('F d');
169						}
170					}
171				}
172				if (!$.isArray(results[date])) {
173					results[date] = [];
174				}
175				results[date].push(item);
176			});
177			$.each(results, function(date, date_results) {
178				result += '<h3>' + date + '</h3>';
179				$.each(date_results, function(i, item) {
180					result += getItem(item);
181				});
182			});
183		} else {
184				// add each widget result
185				$.each(data.data, function(index, item) {
186					result += getItem(item);
187				});
188			}
189			return result;
190	}
191
192	// public methods
193	var methods = {
194		init: function(options) {
195			var that = this,
196					plugin = this,
197					opts = $.extend({}, defaults, options),
198					$body = $('body'),
199					user = new User();
200
201			return this.each(function() {
202				var $widget = $(this),
203						liveurl, url, request_opts;
204
205				function replaceCalendarLinks() {
206					if (!opts.link_to_calendar) return;
207
208					$widget.find('a[href]').each(function() {
209						var $a = $(this),
210								href = $a.attr('href'),
211								id_match = href.match(/\/(\d+)[^\/]*$/),
212								widget_host = opts.host.replace(/^https?:\/\//, '').replace(/\/$/, ''),
213								link_host_match = href.match(/^.*:\/\/([A-Za-z0-9\-\.]+)/);
214
215						if (id_match && link_host_match && link_host_match.length === 2 && link_host_match[1] === widget_host) {
216							$a.attr('href', opts.link_to_calendar + '/#!view/event/event_id/' + id_match[1]);
217						}
218					});
219				}
220
221				function includeDefaultStyles(type, theme) {
222					var css_url;
223					theme = theme || 'core';
224
225					if (opts.theme) {
226						theme = opts.theme;
227					}
228
229					css_url = opts.host + liveurl + '/resource/css/%5Clivewhale%5Ctheme%5C' + theme
230									+ '%5Cstyles%5C' + type + '-embed-widget.css';
231
232					// href must be set last, and after appended to work in IE8
233					$('<link>').appendTo($('head')).attr({
234						type: 'text/css',
235						rel: 'stylesheet'
236					}).attr('href', css_url);
237				}
238
239				$widget.addClass('loading');
240
241				// return if no valid host
242				if (!opts.host || !opts.host.match(/[^\.]+\.[^\.]+/gi)) {
243					return this;
244				}
245
246				// return if no widget id
247				if (!opts.id) {
248					return this;
249				}
250
251				// trim trailing slash from host
252				opts.host = opts.host.replace(/\/$/, '');
253
254				if (!opts.host.match(/^http/)) {
255					opts.host = document.location.protocol + '//' + opts.host;
256				}
257
258				liveurl = opts.liveurl_dir || '/live';
259				url = opts.host + liveurl + '/widget/' + opts.id;
260
261				// correct argument syntax
262				// early clients used the plural form
263				if (opts.tags) {
264					opts.tag = opts.tags;
265					delete opts.tags;
266				}
267				if (opts.categories) {
268					opts.category = opts.categories;
269					delete opts.categories;
270				}
271				if (opts.groups) {
272					opts.group = opts.groups;
273					delete opts.groups;
274				}
275
276				// build table of option properties to exclude from the ajax request
277				var exclude_from_request = {
278					host: 1,
279					group_by_date: 1,
280					link_to_calendar: 1,
281					theme: 1,
282					id: 1,
283					liveurl_dir: 1,
284					include_default_styles: 1,
285					format: 1
286				};
287
288				// add all options not in the exclude table to the ajax request
289				$.each(opts, function(key, vals) {
290					// skip keys in exclude table
291					if (exclude_from_request[key]) {
292						return true;
293					}
294
295					// add everything else to the url
296			vals=(key!=='filter' ? vals.split('|') : [vals]);
297					$.each(vals, function(i, val) {
298						// replace slashes with dashes if this is a date field
299						if ('start_date' === key || 'end_date' === key) {
300							val = val.replace(/\//g, '-');
301						}
302						url += '/' + encodeURIComponent(key) + '/' + encodeURIComponent($.trim(val));
303					});
304				});
305
306				console.log('url', url);
307
308				request_opts = {
309					type: 'GET',
310					timeout: 30000,
311					crossDomain: true
312				};
313
314				if ('json' === opts.format) {
315					url += '@JSON';
316
317					request_opts.data = { external_widget: 1 };
318					request_opts.dataType = 'jsonp';
319					request_opts.success = function(data) {
320						var format_args = [],
321								results = {},
322								result, css_url, $wrapper;
323
324						$body.trigger('beforeWidgetLoad.lw');
325
326						// parse format args from format
327						$.each((data.format + data.format_starred).match(/\{[^\}]+\}/gi), function(key, val) {
328							// remove "{" and "}" chars from format args
329							val = val.replace('{', '').replace('}', '');
330							if ($.inArray(val, format_args)) {
331								format_args.push(val);
332							}
333						});
334
335						// add default styles if specified in options
336						if (opts.include_default_styles) {
337							includeDefaultStyles(data.type, data.theme);
338						}
339
340						// output results
341						$wrapper = $('<div class="lw_widget lw_widget_' + data.type + '"/>');
342
343						// add custom classes
344						if (!$.isArray(data['class'])) {
345							data['class'] = [];
346						}
347						if (opts.group_by_date) {
348							data['class'].push('lw_widget_group_by_date');
349						}
350						$.each(data['class'], function(i, class_name) {
351							$wrapper.addClass(class_name);
352						});
353
354						if (data.data.length) {
355							// we changed the names of a few data points to make them consistent with non-external data points
356							// this copies the new names to the old properties to preserve backwards compatibility
357							$.each(data.data, function(index, obj) {
358								if ($.isPlainObject(obj)) {
359									data.data[index].href = obj.url;
360									data.data[index].group_title = obj.group;
361								}
362							});
363
364							if (data.type === 'events') {
365								result = getEventsResults(opts, format_args, data);
366							} else {
367								result = getDefaultResults(opts, format_args, data);
368							}
369						} else {
370							result = data.no_results;
371						}
372						$wrapper.append(result);
373						$widget.html($wrapper);
374
375						if (opts.link_to_calendar) {
376							replaceCalendarLinks();
377						}
378
379						$widget.removeClass('loading');
380						$body.trigger('widgetLoad.lw');
381					};
382				} else {
383					request_opts.dataType = 'html';
384					request_opts.success = function(data) {
385						$body.trigger('beforeWidgetLoad.lw');
386
387						$widget.html(data);
388
389						// handler for opening a new window when widget link has target="_blank".  This fixes a bug
390						// in Safari that caused a cached versions of window.location.hash to override the actual
391						// hash in the url
392						$widget.on('click', 'a[target="_blank"]', function(e) {
393							e.preventDefault();
394							window.open($(this).attr('href'), 'lw_calendar_event');
395							return true;
396						});
397
398						if (opts.link_to_calendar) {
399							replaceCalendarLinks();
400						}
401
402						$widget.removeClass('loading');
403						$body.trigger('widgetLoad.lw');
404					};
405				}
406
407				// get format arg
408				$.ajax(url, request_opts);
409
410				$widget.on('click', '.lw_paginate a', function(e) {
411					e.preventDefault();
412					var href = $(this).attr('href');
413					var opts = {};
414					var page;
415
416					$widget.addClass('loading');
417
418					href = href.substring(href.lastIndexOf('?') + 1);
419					var pairs = href.split('&');
420					var all = false;
421
422					$.each(pairs, function(i, pair) {
423						var arg = pair.split('=');
424						if (arg.length !== 2) {
425							return true;
426						}
427						if (arg[0] === 'page') {
428							page = arg[1];
429						}
430						if (arg[0] === 'all' && arg[1]) {
431							all = true;
432						}
433					});
434
435					if (all) {
436						$.extend(true, opts, request_opts, {
437							data: {
438								'all': '1'
439							}
440						});
441					} else if (page) {
442						$.extend(true, opts, request_opts, {
443							data: {
444								'page': page
445							}
446						});
447					}
448					$.ajax(url, opts);
449					return true;
450				});
451
452				// make sure the element isn't hidden
453				$widget.show();
454
455				// we put this here to override code on U Calgary's site that
456				// was hiding the widget after load.	We decided to add it to
457				// the core code because it doesn't negatively impact widgets
458				// on other sites.
459				setTimeout(function() {
460					$widget.show();
461				}, 200);
462			});
463		}
464	};
465
466	$.fn.lwWidget = function(method) {
467		if (methods[method]) {
468			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
469		} else if (typeof method === 'object' || !method) {
470			return methods.init.apply(this, arguments);
471		} else {
472			console.log('Method ' + method + ' does not exist on jQuery.lwWidget');
473			return false;
474		}
475	};
476}(livewhale.jQuery || jQuery));

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.