1/* 2Monthly 2.1.0 by Kevin Thornbloom is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. 3*/ 4 5(function($) { 6 $.fn.extend({ 7 monthly: function(options) { 8 // These are overridden by options declared in footer 9 var defaults = { 10 weekStart: 'Sun', 11 mode: '', 12 xmlUrl: '', 13 jsonUrl: '', 14 dataType: 'json', 15 target: '', 16 eventList: true, 17 maxWidth: false, 18 setWidth: false, 19 startHidden: false, 20 showTrigger: '', 21 stylePast: false, 22 disablePast: false 23 } 24 25 var options = $.extend(defaults, options), 26 that = this, 27 uniqueId = $(this).attr('id'), 28 d = new Date(), 29 currentMonth = d.getMonth() + 1, 30 currentYear = d.getFullYear(), 31 currentDay = d.getDate(), 32 monthNames = options.monthNames || ["Jan", "Feb", "Mar", "Apr", "May", "June", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], 33 dayNames = options.dayNames || ['SUN','MON','TUE','WED','THU','FRI','SAT']; 34 35 if (options.maxWidth != false){ 36 $('#'+uniqueId).css('maxWidth',options.maxWidth); 37 } 38 if (options.setWidth != false){ 39 $('#'+uniqueId).css('width',options.setWidth); 40 } 41 42 if (options.startHidden == true){ 43 $('#'+uniqueId).addClass('monthly-pop').css({ 44 'position' : 'absolute', 45 'display' : 'none' 46 }); 47 $(document).on('focus', ''+options.showTrigger+'', function (e) { 48 $('#'+uniqueId).show(); 49 e.preventDefault(); 50 }); 51 $(document).on('click', ''+options.showTrigger+', .monthly-pop', function (e) { 52 e.stopPropagation(); 53 e.preventDefault(); 54 }); 55 $(document).on('click', function (e) { 56 $('#'+uniqueId).hide(); 57 }); 58 } 59 60 // Add Day Of Week Titles 61 if (options.weekStart == 'Sun') { 62 $('#' + uniqueId).append('<div class="monthly-day-title-wrap"><div>'+dayNames[0]+'</div><div>'+dayNames[1]+'</div><div>'+dayNames[2]+'</div><div>'+dayNames[3]+'</div><div>'+dayNames[4]+'</div><div>'+dayNames[5]+'</div><div>'+dayNames[6]+'</div></div><div class="monthly-day-wrap"></div>'); 63 } else if (options.weekStart == 'Mon') { 64 $('#' + uniqueId).append('<div class="monthly-day-title-wrap"><div>'+dayNames[1]+'</div><div>'+dayNames[2]+'</div><div>'+dayNames[3]+'</div><div>'+dayNames[4]+'</div><div>'+dayNames[5]+'</div><div>'+dayNames[6]+'</div><div>'+dayNames[0]+'</div></div><div class="monthly-day-wrap"></div>'); 65 } else { 66 console.error('Monthly.js has an incorrect entry for the weekStart variable'); 67 } 68 69 // Add Header & event list markup 70 $('#' + uniqueId).prepend('<div class="monthly-header"><div class="monthly-header-title"><a href="#" class="monthly-header-title-date" onclick="return false"></a></div><a href="#" class="monthly-prev"></a><a href="#" class="monthly-next"></a></div>').append('<div class="monthly-event-list"></div>'); 71 72 // How many days are in this month? 73 function daysInMonth(m, y){ 74 return m===2?y&3||!(y%25)&&y&15?28:29:30+(m+(m>>3)&1); 75 } 76 77 // Massive function to build the month 78 function setMonthly(m, y){ 79 $('#' + uniqueId).data('setMonth', m).data('setYear', y); 80 81 // Get number of days 82 var dayQty = daysInMonth(m, y), 83 // Get day of the week the first day is 84 mZeroed = m -1, 85 firstDay = new Date(y, mZeroed, 1, 0, 0, 0, 0).getDay(); 86 87 // Remove old days 88 $('#' + uniqueId + ' .monthly-day, #' + uniqueId + ' .monthly-day-blank').remove(); 89 $('#'+uniqueId+' .monthly-event-list').empty(); 90 $('#'+uniqueId+' .monthly-day-wrap').empty(); 91 // Print out the days 92 if (options.mode == 'event') { 93 for(var i = 0; i < dayQty; i++) { 94 95 var day = i + 1; // Fix 0 indexed days 96 var dayNamenum = new Date(y, mZeroed, day, 0, 0, 0, 0).getDay() 97 98 $('#' + uniqueId + ' .monthly-day-wrap').append('<a href="#" class="m-d monthly-day monthly-day-event" data-number="'+day+'"><div class="monthly-day-number">'+day+'</div><div class="monthly-indicator-wrap"></div></a>'); 99 $('#' + uniqueId + ' .monthly-event-list').append('<div class="monthly-list-item" id="'+uniqueId+'day'+day+'" data-number="'+day+'"><div class="monthly-event-list-date">'+dayNames[dayNamenum]+'<br>'+day+'</div></div>'); 100 } 101 } else { 102 for(var i = 0; i < dayQty; i++) { 103 // Fix 0 indexed days 104 var day = i + 1; 105 106 // Check if it's a day in the past 107 if(((day < currentDay && m === currentMonth) || y < currentYear || (m < currentMonth && y == currentYear)) && options.stylePast == true){ 108 $('#' + uniqueId + ' .monthly-day-wrap').append('<a href="#" class="m-d monthly-day monthly-day-pick monthly-past-day" data-number="'+day+'"><div class="monthly-day-number">'+day+'</div><div class="monthly-indicator-wrap"></div></a>'); 109 } else { 110 $('#' + uniqueId + ' .monthly-day-wrap').append('<a href="#" class="m-d monthly-day monthly-day-pick" data-number="'+day+'"><div class="monthly-day-number">'+day+'</div><div class="monthly-indicator-wrap"></div></a>'); 111 } 112 } 113 } 114 115 116 // Set Today 117 var setMonth = $('#' + uniqueId).data('setMonth'),
118 setYear = $('#' + uniqueId).data('setYear'); 119 if (setMonth == currentMonth && setYear == currentYear) { 120 $('#' + uniqueId + ' *[data-number="'+currentDay+'"]').addClass('monthly-today'); 121 } 122 123 // Reset button 124 if (setMonth == currentMonth && setYear == currentYear) { 125 $('#' + uniqueId + ' .monthly-header-title-date').html(monthNames[m - 1] +' '+ y); 126 } else { 127 $('#' + uniqueId + ' .monthly-header-title').html('<a href="#" class="monthly-header-title-date" onclick="return false">'+monthNames[m - 1] +' '+ y +'</a><a href="#" class="monthly-reset" title="Set to today">â» TODAY</a> '); 128 } 129 130 // Account for empty days at start 131 if(options.weekStart == 'Sun' && firstDay != 7) { 132 for(var i = 0; i < firstDay; i++) { 133 $('#' + uniqueId + ' .monthly-day-wrap').prepend('<div class="m-d monthly-day-blank"><div class="monthly-day-number"></div></div>'); 134 } 135 } else if (options.weekStart == 'Mon' && firstDay == 0) { 136 for(var i = 0; i < 6; i++) { 137 $('#' + uniqueId + ' .monthly-day-wrap').prepend('<div class="m-d monthly-day-blank" ><div class="monthly-day-number"></div></div>'); 138 } 139 } else if (options.weekStart == 'Mon' && firstDay != 1) { 140 for(var i = 0; i < (firstDay - 1); i++) { 141 $('#' + uniqueId + ' .monthly-day-wrap').prepend('<div class="m-d monthly-day-blank" ><div class="monthly-day-number"></div></div>'); 142 } 143 } 144 145 //Account for empty days at end 146 var numdays = $('#' + uniqueId + ' .monthly-day').length, 147 numempty = $('#' + uniqueId + ' .monthly-day-blank').length, 148 totaldays = numdays + numempty, 149 roundup = Math.ceil(totaldays/7) * 7, 150 daysdiff = roundup - totaldays; 151 if(totaldays % 7 != 0) { 152 for(var i = 0; i < daysdiff; i++) { 153 $('#' + uniqueId + ' .monthly-day-wrap').append('<div class="m-d monthly-day-blank"><div class="monthly-day-number"></div></div>'); 154 } 155 } 156 157 // Events 158 if (options.mode == 'event') { 159 // Remove previous events 160 161 // Add Events 162 var addEvents = function(event) { 163 // Year [0] Month [1] Day [2] 164 var fullstartDate = options.dataType == 'xml' ? $(event).find('startdate').text() : event.startdate, 165 startArr = fullstartDate.split("-"), 166 startYear = startArr[0], 167 startMonth = parseInt(startArr[1], 10), 168 startDay = parseInt(startArr[2], 10), 169 fullendDate = options.dataType == 'xml' ? $(event).find('enddate').text() : event.enddate, 170 endArr = fullendDate.split("-"), 171 endYear = endArr[0], 172 endMonth = parseInt(endArr[1], 10), 173 endDay = parseInt(endArr[2], 10), 174 eventURL = options.dataType == 'xml' ? $(event).find('url').text() : event.url, 175 eventTitle = options.dataType == 'xml' ? $(event).find('name').text() : event.name, 176 eventColor = options.dataType == 'xml' ? $(event).find('color').text() : event.color, 177 eventId = options.dataType == 'xml' ? $(event).find('id').text() : event.id, 178 startTime = options.dataType == 'xml' ? $(event).find('starttime').text() : event.starttime, 179 startSplit = startTime.split(":"), 180 endTime = options.dataType == 'xml' ? $(event).find('endtime').text() : event.endtime, 181 endSplit = endTime.split(":"), 182 eventLink = '', 183 startPeriod = 'AM', 184 endPeriod = 'PM'; 185 186 /* Convert times to 12 hour & determine AM or PM */ 187 if(parseInt(startSplit[0]) >= 12) { 188 var startTime = (startSplit[0] - 12)+':'+startSplit[1]+''; 189 var startPeriod = 'PM' 190 } 191 192 if(parseInt(startTime) == 0) { 193 var startTime = '12:'+startSplit[1]+''; 194 } 195 196 if(parseInt(endSplit[0]) >= 12) { 197 var endTime = (endSplit[0] - 12)+':'+endSplit[1]+''; 198 var endPeriod = 'PM' 199 } 200 if(parseInt(endTime) == 0) { 201 var endTime = '12:'+endSplit[1]+''; 202 } 203 if (eventURL){ 204 var eventLink = 'href="'+eventURL+'"'; 205 } 206 207 // function to print out list for multi day events 208 function multidaylist(){ 209 var timeHtml = ''; 210 if (startTime){ 211 var startTimehtml = '<div><div class="monthly-list-time-start">'+startTime+' '+startPeriod+'</div>'; 212 var endTimehtml = ''; 213 if (endTime){ 214 var endTimehtml = '<div class="monthly-list-time-end">'+endTime+' '+endPeriod+'</div>'; 215 } 216 var timeHtml = startTimehtml + endTimehtml + '</div>'; 217 } 218 $('#'+uniqueId+' .monthly-list-item[data-number="'+i+'"]').addClass('item-has-event').append('<a href="'+eventURL+'" class="listed-event" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'">'+eventTitle+' '+timeHtml+'</a>'); 219 } 220 221 222 // If event is one day & within month 223 if (!fullendDate && startMonth == setMonth && startYear == setYear) { 224 // Add Indicators 225 $('#'+uniqueId+' *[data-number="'+startDay+'"] .monthly-indicator-wrap').append('<div class="monthly-event-indicator" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'">'+eventTitle+'</div>'); 226 // Print out event list for single day event 227 var timeHtml = ''; 228 if (startTime){ 229 var startTimehtml = '<div><div class="monthly-list-time-start">'+startTime+' '+startPeriod+'</div>'; 230 var endTimehtml = ''; 231 if (endTime){ 232 var endTimehtml = '<div class="monthly-list-time-end">'+endTime+' '+endPeriod+'</div>'; 233 } 234 var timeHtml = startTimehtml + endTimehtml + '</div>'; 235 } 236 $('#'+uniqueId+' .monthly-list-item[data-number="'+startDay+'"]').addClass('item-has-event').append('<a href="'+eventURL+'" class="listed-event" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'">'+eventTitle+' '+timeHtml+'</a>'); 237 238 239 // If event is multi day & within month 240 } else if (startMonth == setMonth && startYear == setYear && endMonth == setMonth && endYear == setYear){ 241 for(var i = parseInt(startDay); i <= parseInt(endDay); i++) { 242 // If first day, add title 243 if (i == parseInt(startDay)) { 244 $('#'+uniqueId+' *[data-number="'+i+'"] .monthly-indicator-wrap').append('<div class="monthly-event-indicator" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'">'+eventTitle+'</div>'); 245 } else { 246 $('#'+uniqueId+' *[data-number="'+i+'"] .monthly-indicator-wrap').append('<div class="monthly-event-indicator" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'"></div>'); 247 } 248 multidaylist(); 249 } 250 251 // If event is multi day, starts in prev month, and ends in current month 252 } else if ((endMonth == setMonth && endYear == setYear) && ((startMonth < setMonth && startYear == setYear) || (startYear < setYear))) { 253 for(var i = 0; i <= parseInt(endDay); i++) { 254 // If first day, add title 255 if (i==1){ 256 $('#'+uniqueId+' *[data-number="'+i+'"] .monthly-indicator-wrap').append('<div class="monthly-event-indicator" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'">'+eventTitle+'</div>'); 257 } else { 258 $('#'+uniqueId+' *[data-number="'+i+'"] .monthly-indicator-wrap').append('<div class="monthly-event-indicator" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'"></div>'); 259 } 260 multidaylist(); 261 } 262 263 // If event is multi day, starts in this month, but ends in next 264 } else if ((startMonth == setMonth && startYear == setYear) && ((endMonth > setMonth && endYear == setYear) || (endYear > setYear))){ 265 for(var i = parseInt(startDay); i <= dayQty; i++) { 266 // If first day, add title 267 if (i == parseInt(startDay)) { 268 $('#'+uniqueId+' *[data-number="'+i+'"] .monthly-indicator-wrap').append('<div class="monthly-event-indicator" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'">'+eventTitle+'</div>'); 269 } else { 270 $('#'+uniqueId+' *[data-number="'+i+'"] .monthly-indicator-wrap').append('<div class="monthly-event-indicator" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'"></div>'); 271 } 272 multidaylist(); 273 } 274 275 // If event is multi day, starts in a prev month, ends in a future month 276 } else if (((startMonth < setMonth && startYear == setYear) || (startYear < setYear)) && ((e
276ndMonth > setMonth && endYear == setYear) || (endYear > setYear))){ 277 for(var i = 0; i <= dayQty; i++) { 278 // If first day, add title 279 if (i == 1){ 280 $('#'+uniqueId+' *[data-number="'+i+'"] .monthly-indicator-wrap').append('<div class="monthly-event-indicator" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'">'+eventTitle+'</div>'); 281 } else { 282 $('#'+uniqueId+' *[data-number="'+i+'"] .monthly-indicator-wrap').append('<div class="monthly-event-indicator" data-eventid="'+ eventId +'" style="background:'+eventColor+'" title="'+eventTitle+'"></div>'); 283 } 284 multidaylist(); 285 } 286 287 } 288 }; 289 290 var eventsResource = (options.dataType == 'xml' ? options.xmlUrl : options.jsonUrl); 291 292 $.get(''+eventsResource+'', {now: jQuery.now()}, function(d){ 293 if (options.dataType == 'xml') { 294 $(d).find('event').each(function(index, event) { 295 addEvents(event); 296 }); 297 } else if (options.dataType == 'json') { 298 $.each(d.monthly, function(index, event) { 299 addEvents(event); 300 }); 301 } 302 }, options.dataType).fail(function() { 303 console.error('Monthly.js failed to import '+eventsResource+'. Please check for the correct path & '+options.dataType+' syntax.'); 304 }); 305 306 } 307 var divs = $("#"+uniqueId+" .m-d"); 308 for(var i = 0; i < divs.length; i+=7) { 309 divs.slice(i, i+7).wrapAll("<div class='monthly-week'></div>"); 310 } 311 } 312 313 // Set the calendar the first time 314 setMonthly(currentMonth, currentYear); 315 316 // Function to go back to the month view 317 function viewToggleButton(){ 318 if($('#'+uniqueId+' .monthly-event-list').is(":visible")) { 319 $('#'+uniqueId+' .monthly-cal').remove(); 320 $('#'+uniqueId+' .monthly-header-title').prepend('<a href="#" class="monthly-cal" title="Back To Month View">â· MONTH</a>'); 321 } 322 } 323 324 // Advance months 325 $(document.body).on('click', '#'+uniqueId+' .monthly-next', function (e) { 326 var setMonth = $('#' + uniqueId).data('setMonth'), 327 setYear = $('#' + uniqueId).data('setYear'); 328 if (setMonth == 12) { 329 var newMonth = 1, 330 newYear = setYear + 1; 331 setMonthly(newMonth, newYear); 332 } else { 333 var newMonth = setMonth + 1, 334 newYear = setYear; 335 setMonthly(newMonth, newYear); 336 } 337 viewToggleButton(); 338 e.preventDefault(); 339 }); 340 341 // Go back in months 342 $(document.body).on('click', '#'+uniqueId+' .monthly-prev', function (e) { 343 var setMonth = $('#' + uniqueId).data('setMonth'), 344 setYear = $('#' + uniqueId).data('setYear'); 345 if (setMonth == 1) { 346 var newMonth = 12, 347 newYear = setYear - 1; 348 setMonthly(newMonth, newYear); 349 } else { 350 var newMonth = setMonth - 1, 351 newYear = setYear; 352 setMonthly(newMonth, newYear); 353 } 354 viewToggleButton(); 355 e.preventDefault(); 356 }); 357 358 // Reset Month 359 $(document.body).on('click', '#'+uniqueId+' .monthly-reset', function (e) { 360 $(this).remove(); 361 setMonthly(currentMonth, currentYear); 362 viewToggleButton(); 363 e.preventDefault(); 364 e.stopPropagation(); 365 }); 366 367 // Back to month view 368 $(document.body).on('click', '#'+uniqueId+' .monthly-cal', function (e) { 369 $(this).remove(); 370 $('#' + uniqueId+' .monthly-event-list').css('transform','scale(0)'); 371 setTimeout(function(){ 372 $('#' + uniqueId+' .monthly-event-list').hide(); 373 }, 250); 374 e.preventDefault(); 375 }); 376 377 // Click A Day 378 $(document.body).on('click', '#'+uniqueId+' a.monthly-day', function (e) { 379 // If events, show events list 380 if(options.mode == 'event' && options.eventList == true) { 381 var whichDay = $(this).data('number'); 382 $('#' + uniqueId+' .monthly-event-list').show(); 383 $('#' + uniqueId+' .monthly-event-list').css('transform'); 384 $('#' + uniqueId+' .monthly-event-list').css('transform','scale(1)'); 385 $('#' + uniqueId+' .monthly-list-item[data-number="'+whichDay+'"]').show(); 386 387 var myElement = document.getElementById(uniqueId+'day'+whichDay); 388 var topPos = myElement.offsetTop; 389 $('#' + uniqueId+' .monthly-event-list').scrollTop(topPos); 390 viewToggleButton(); 391 // If picker, pick date 392 } else if (options.mode == 'picker') { 393 var whichDay = $(this).data('number'), 394 setMonth = $('#' + uniqueId).data('setMonth'),
395 setYear = $('#' + uniqueId).data('setYear'); 396 397 // Should days in the past be disabled? 398 if($(this).hasClass('monthly-past-day') && options.disablePast == true) { 399 // If so, don't do anything. 400 e.preventDefault(); 401 } else { 402 // Otherwise, select the date ... 403 $(''+options.target+'').val(setMonth+'/'+whichDay+'/'+setYear); 404 // ... and then hide the calendar if it started that way 405 if(options.startHidden == true) { 406 $('#'+uniqueId).hide(); 407 } 408 } 409 } 410 e.preventDefault(); 411 }); 412 413 // Clicking an event within the list 414 $(document.body).on('click', '#'+uniqueId+' .listed-event', function (e) { 415 var href = $(this).attr('href'); 416 // If there isn't a link, don't go anywhere 417 if(!href) { 418 e.preventDefault(); 419 } 420 }); 421 422 } 423 }); 424})(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.