/** * Bloglendar, a class that generates a calendar navigation panel for Blogger, * which greatly help locating posts of a particular day. * @param dateSelector TagName+ClassName for the date entries, e.g. "div.blogDate" * @param panelId ID of the panel object, e.g. "bloglendar" * @param monthNames Names of months for displaying (optional) * @param weekdayNames Names of weekdays for displaying (optional) * @param dayNames Names of days for displaying (optional) */ function Bloglendar( dateSelector, panelId, monthNames, weekdayNames, dayNames ) { this.links = new Array(); this.panelHolder = document.getElementById( panelId ); this.monthNames = monthNames; this.weekdayNames = weekdayNames; this.dayNames = dayNames; this.firstFoundDate = new Date(); // Get the links var selector = dateSelector.split( "." ); var elements = document.getElementsByTagName( selector[0] ); var currentDate, currentId; for ( var i = 0, len = elements.length; i < len; i++ ) { if ( elements[i].className == selector[1] ) { currentDate = new Date( elements[i].title ); currentId = currentDate.valueOf(); elements[i].removeAttribute( "title" ); // Only do this once if ( this.links.length == 0 ) { this.firstFoundDate = currentDate; } // Only add links of the same month if ( this.firstFoundDate.getYear() == currentDate.getYear() && this.firstFoundDate.getMonth() == currentDate.getMonth() ) { elements[i].id = currentId; this.links[ currentDate.getDate() ] = "#" + currentId; } } } if ( monthNames == null || monthNames.length != 12 ) { this.monthNames = new Array( "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ); } if ( weekdayNames == null || weekdayNames.length != 7 ) { this.weekdayNames = new Array( "SUN", "MON", "TUE", "WED", "THR", "FRI", "SAT" ); } if ( dayNames == null || dayNames.length != 31 ) { this.dayNames = new Array( 31 ); for ( var j = 0; j < 31; j++ ) { this.dayNames[j] = j+1; } } } /** * Count the number of days in a given date * @param date The date to be counted * @return The number of days in that date */ Bloglendar.prototype.countDays = function( date ) { var monthCounts = new Array ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); var year = date.getFullYear(); if ( year % 4 == 0 ) { if ( year % 100 == 0 ) { if ( year % 400 == 0 ) monthCounts[1]++; } else monthCounts[1]++; } return monthCounts[date.getMonth()]; } /** * Stop propagation of event * @param e Event that triggers this handler */ Bloglendar.prototype.stopPropagation = function( e ) { if ( e.stopPropagation ) // W3C { e.stopPropagation(); } else // IE { window.event.cancelBubble = true; } } /** * Go to the URL inside the target element * @param e Event that triggers this handler */ Bloglendar.prototype.gotoUrl = function( e ) { var targetObj; if ( e.target ) // W3C { targetObj = e.target; } if ( e.srcElement ) // IE { targetObj = e.srcElement; } document.location.href = targetObj.firstChild.href; } /** * Draw the calendar into the place holder */ Bloglendar.prototype.draw = function() { var calendar; // Display the bloglendar if and only if there are blog entries if ( this.links.length == 0 ) { var notice = document.createTextNode( "This month: No blog entry yet" ); calendar = document.createElement( "p" ); calendar.appendChild( notice ); } else { // Times and dates var currDate = new Date(); var calMonth = this.firstFoundDate; var dayCount = this.countDays( calMonth ); var currDay = -1; // An impossible value if ( currDate.getYear() == calMonth.getYear() && currDate.getMonth() == calMonth.getMonth() ) { currDay = currDate.getDate(); } // Leading blanks calMonth.setDate( 1 ); var blankCount = calMonth.getDay(); // Bloglendar table var calTable = document.createElement( "table" ); calTable.createTHead(); var calTbody = document.createElement( "tbody" ); // Repetitive objects (frequently reused) var row = document.createElement( "tr" ); var headerCell = document.createElement( "th" ); var normalCell = document.createElement( "td" ); var text = document.createTextNode( "" ); var anchor = document.createElement( "a" ); // Create month var monthRow = row.cloneNode( false ); var monthCell = headerCell.cloneNode( false ); var monthText = text.cloneNode( false ); monthText.data = this.monthNames[calMonth.getMonth()] + " " + calMonth.getFullYear(); monthCell.colSpan = "7"; monthCell.className = "month"; monthCell.appendChild( monthText ); monthRow.appendChild( monthCell ); calTable.tHead.appendChild( monthRow ); // Create weekdays var weekdayRow = row.cloneNode( false ); var weekdayCell; var weekdayText; for ( var i = 0; i < 7; i++ ) { weekdayCell = headerCell.cloneNode( false ); weekdayCell.className = "weekday"; weekdayText = text.cloneNode( false ); weekdayText.data = this.weekdayNames[i]; weekdayCell.appendChild( weekdayText ); weekdayRow.appendChild( weekdayCell ); } calTable.tHead.appendChild( weekdayRow ); // Create days for ( var j = 1; j <= dayCount; ) { var dayRow = row.cloneNode( false ); var dayCell; var dayText; var dayAnchor; // Create empty days for ( var a = 0; a < blankCount; a++ ) { dayCell = normalCell.cloneNode( false ) dayText = text.cloneNode( false ); dayText.data = " "; dayCell.appendChild( dayText ); dayRow.appendChild( dayCell ); } // Create days for ( var b = blankCount; b < 7; b++ ) { dayCell = normalCell.cloneNode( false ); dayText = text.cloneNode( false ); dayText.data = this.dayNames[j-1]; // Create active days if ( this.links[j] ) { dayAnchor = anchor.cloneNode( false ); dayAnchor.href = this.links[j]; dayAnchor.appendChild( dayText ); dayCell.appendChild( dayAnchor ); dayCell.className = "activeday"; } // Create inactive days else if ( j <= dayCount ) { dayCell.appendChild( dayText ); } // Create empty days else { dayText.data = " "; dayCell.appendChild( dayText ); } // Set day's class if ( j < currDay || ( currDay < 0 && j <= dayCount ) ) { dayCell.className = dayCell.className + " pastday"; } else if ( j == currDay ) { dayCell.className = dayCell.className + " currentday"; } else if ( j <= dayCount ) { dayCell.className = dayCell.className + " futureday"; } dayRow.appendChild( dayCell ); calTbody.appendChild( dayRow ); j++; } blankCount = 0; } calTable.appendChild( calTbody ); calendar = calTable; } this.panelHolder.appendChild( calendar ); }