function ewGetTypePadsprop7() { var url = document.location + ''; var re = new RegExp( '\/comments\/page\/' ); var qsParamValue = tiiGetQueryParamValue( 'cid' ); if ( re.test(url) || qsParamValue != null ) { url = ''; } else { url = url.split( '#', 1 ); url = url + ''; url = url.split( '?', 1 ); url = url + ''; } return url; } function tiiQuigoSetEnabled(b) { _tiiQuigoEnabled = b; } function tiiQuigoIsEnabled() { if (typeof(_tiiQuigoEnabled) == "boolean") { return _tiiQuigoEnabled; } return true; } function tiiQuigoWriteAd(pid, placementId, zw, zh, ps) { if (tiiQuigoIsEnabled()) { qas_writeAd(placementId, pid, ps, zw, zh, 'ads.adsonar.com'); } } // ### Array Helper Functions ### function tiiArrayContains (array, value) { if (array != null) { var al = array.length; for (var i = 0; i < al; i++) { if (array[i] == value) return true; } } return false; } // ### Key=Value; Functions ### function tiiHashKeys(string) { var keys = null; if (string != null) { var hash = string.split(';'); var hl = hash.length - 1; if(hl > 0){ keys = new Array(); for(var i = 0; i < hl; i++){ var data = hash[i].split('='); keys[i] = data[0].replace(' ', ''); } } } return keys; } function tiiHashGet(string, key) { var value = null; if (string != null) { var keyStart = key + '='; var offset = string.indexOf(keyStart); if (offset != -1) { offset += keyStart.length; var end = string.indexOf(';', offset); if (end == -1) { end = string.length; } value = string.substring(offset, end); } } return value; } function tiiHashSet(string, key, value) { var string = tiiHashDelete(string, key); var newValue = key + '=' + value + ';'; if (string != null) newValue = newValue + string; return newValue; } function tiiHashDelete(string, key) { var oldValue = tiiHashGet(string, key); var newString = string; if (oldValue != null) { var search = key + '='; var start = string.indexOf(search); var offset = start + search.length; var end = string.indexOf(';', offset) + 1; if (end == -1) end = string.length; newString = string.slice(0,start) + string.slice(end,string.length); return newString; } return newString; } function tiiGetQueryParamValue(param) { var startIndex; var endIndex; var valueStart; var qs = document.location.search; var detectIndex = qs.indexOf( "?" + param + "=" ); var detectIndex2 = qs.indexOf( "&" + param + "=" ); var key = "&" + param + "="; var keylen = key.length; if (qs.length > 1) { if (detectIndex != -1) { startIndex = detectIndex; } else if (detectIndex2 != -1) { startIndex = detectIndex2; } else { return null; } valueStart = startIndex + keylen; if (qs.indexOf("&", valueStart) != -1) { endIndex = qs.indexOf("&", startIndex + 1) } else { endIndex = qs.length } return (qs.substring(qs.indexOf("=", startIndex) + 1, endIndex)); } return null; } // ### Date/Time Functions ### function tiiDateGetOffsetMinutes(minutes) { var today = new Date(); return today.getTime() + (60000) * minutes;} function tiiDateGetOffsetHours(hours) { var today = new Date(); return today.getTime() + (3600000) * hours; } function tiiDateGetOffsetDays(days) { var today = new Date(); return today.getTime() + (86400000) * days; } function tiiDateGetOffsetWeeks(weeks) { var today = new Date(); return today.getTime() + (604800000) * weeks; } function tiiDateGetOffsetMonths(months) { var today = new Date(); return today.getTime() + (259200000) * months; } function tiiDateGetOffsetYears(years) { var today = new Date(); return today.getTime() + (31536000000) * years; } var adConfig = new TiiAdConfig("3475.enw"); adConfig.setCmSitename("cm.enw"); adConfig.setRevSciTracking(true); function adSetTarget() {} function htmlAdWH() {} function adSetType() {} function openLink(url,target) { if (target) { new_window= window.open(url); } else { location.href = url; } } var daysArray = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"); var monthsArray = new Array("January","February","March","April","May","June","July","August","September","October","November","December"); function getDateCurrent() { var today = new Date(); var monthNumber = (today.getMonth()); var monthName = monthsArray[monthNumber].substr(0,3); var weekDayNumber = (today.getDay()); var weekDayName = daysArray[weekDayNumber]; var dayNumber=today.getDate(); if (dayNumber < 10){ dayNumber="0" + dayNumber; } var yearNumber = today.getYear(); if (yearNumber < 1000) { yearNumber+=1900; } document.write(weekDayName + ", " + monthName + ". " + dayNumber + ", " + yearNumber); } function getHeaderDateCurrent () { var today = new Date(); var monthNumber = (today.getMonth()); var monthName = monthsArray[monthNumber]; var weekDayNumber = (today.getDay()); var weekDayName = daysArray[weekDayNumber]; var dayNumber=today.getDate(); var yearNumber = today.getYear(); if (yearNumber < 1000) { yearNumber+=1900; } document.write(weekDayName + ", " + monthName + " " + dayNumber + ", " + yearNumber); } function getReleaseDateDiff(releaseDate,mtype) { var now = new Date(); var release = new Date(releaseDate); var difference = release.getTime() - now.getTime(); difference = Math.floor(difference / (1000 * 60 * 60 * 24)) + 1; if (difference > 0 && difference != 1) { document.write('
'+mtype+' Release'+difference+' Days
'); } else if (difference == 1) { document.write('
'+mtype+' Release'+difference+' Day
'); } else if (difference == 0) { document.write('
'+mtype+' Releasetoday
'); } } function getComingSoonReleaseDateDiff(releaseDate) { var now = new Date(); var release = new Date(releaseDate); var difference = release.getTime() - now.getTime(); difference = Math.floor(difference / (1000 * 60 * 60 * 24)) + 1; if (difference > 0 && difference != 1) { document.write('
'+difference+'
Days
'); } else if (difference == 1) { document.write('
'+difference+'
Day
'); } else if (difference == 0) { document.write('
'+difference+'
today
'); } } // used to send aol message var IM_global_title; var IM_global_url; var IM_default_text_IE = "Here's%20something%20that%20may%20interest%20you%20from%20EW.com:"; var IM_default_text_OT = "Here's something that may interest you from EW.com:"; function openPrintWin(which) { which.setAttribute('href', '?print'); return true; } function popMailWin() { var pageURL = document.URL; if (pageURL.substring(pageURL.length-1)=="#") { pageURL = pageURL.substring(0, pageURL.length-1); } var pageTitle = escape(self.document.title); var formURL = "https://cgi.timeinc.net/cgi-bin/mail/secure/mailurl2friend.cgi?path=/ew/static/cgi/mail/mailurl2friend/&url=" + pageURL + "&group=ew&title=" + pageTitle; showCenteredPopup('emailpop', formURL, 'scrollbars=1', 540, 450); return false; } function popGameMailWin(gameUrl, gameTitle) { var pageURL = gameUrl; if (pageURL.substring(pageURL.length-1)=="#") { pageURL = pageURL.substring(0, pageURL.length-1); } var pageTitle = gameTitle; var formURL = "https://cgi.timeinc.net/cgi-bin/mail/secure/mailurl2friend.cgi?path=/ew/static/cgi/mail/mailurl2friend/&url=" + pageURL + "&group=ew_games&title=" + pageTitle; showCenteredPopup('emailpop', formURL, 'scrollbars=1', 540, 450); return false; } function showCenteredPopup(name, url, features, width, height) { var top = (window.screen.height / 2) - height / 2; var left = (window.screen.width / 2) - width / 2; if (features == null || features == '') { features = "scrollbars=yes,toolbar=no,menubar=no,status=no,location=no"; } window.open (url, name.replace (' ', '_'), features + ",top=" + top + ",left=" + left + ",width=" + width + ",height=" + height); } function sendAIM() { var url = document.URL; if (url.substring(url.length-1)=="#") { url = url.substring(0, url.length-1); } var title_OT = self.document.title; var title = escape(self.document.title); title = title.replace(" ", "+") var uAgt = navigator.userAgent.toLowerCase(); var isIE = uAgt.indexOf(" msie ") != - 1; var isAOLBrowser = uAgt.indexOf(" america online browser ") != - 1; if (!isIE){ var message = IM_default_text_OT + '
' + title_OT + ''; } else if (isAOLBrowser){ var message = IM_default_text_OT + '
' + title + ''; } else { var message = escape(IM_default_text_IE) + "%3cbr%3e%3ca+href=%22" + escape(url) + "%22%3e" + escape(title) + "%3c%2fa%3e"; } try { location.replace("aim:goIM?message=" + message); } catch (e){ AIMExpress.start(); location.replace("aim:goIM?message=" + message); } return false; } function sendIM(title, url) { if (title == ''){ title = 'Click here to checkout'; } IM_global_title = title; IM_global_url = url; var uAgt = navigator.userAgent.toLowerCase(); var isAOL = uAgt.indexOf(" aol ") != - 1; var isIE = uAgt.indexOf(" msie ") != - 1; if (!isAOL) { if (!isIE) { sendAIM(); } else { if (!canRunAIM()) { AIMExpress.start(); } else { sendAIM(); } } } else { sendAOLCLNT(); } } // To launch the STAF User Console function openstaf(title, url, channel) { window.open("http://sendtoafriend.aol.com?type=disp&channelurl=" + url + "&title=" + title + "&channel=" + channel + "&url=" + url + "", null, "height=420,width=296,statusbar=0,toolbar=no,menubar=no,location=no") } // To send IM through AOL Client Messenger function sendAOLCLNT() { var title = IM_global_title; var url = IM_global_url; var uAgt = navigator.userAgent.toLowerCase(); var isAOL = uAgt.indexOf(" aol ") != - 1; var isIE = uAgt.indexOf("msie") != - 1; try { if (!isAOL){ if (!isIE){ document.location = "aol://9293::" + IM_default_text_OT + "
" + title + ""; } else { document.location = "aol://9293::" + IM_default_text_IE + "%3cbr%3e%3ca href='" + url + "'%3e" + title + "%3c%2fa%3e"; } } else { document.location = 'aol://9293::' + IM_default_text_OT + '
' + title + '' } } catch (e){ AIMExpress.start(); } } // To check AOL Client install in the local machine or not function canRunAOLClient() { var agt = navigator.userAgent.toLowerCase(); var isIE = (agt.indexOf("msie") != - 1); if (isIE){ var a = document.anchors; for (var i = 0; i < a.length; i++){ if (a[i].name == "aolclientnotfound"){ return false; } } } return true; } // To check AIM install in the local machine or not function canRunAIM() { var agt = navigator.userAgent.toLowerCase(); var isIE = (agt.indexOf("msie") != - 1); if (isIE){ var a = document.anchors; for (var i = 0; i < a.length; i++){ if (a[i].name == "aimnotfound"){ return false; } } } return true; } ewMagicNumberObject = function(adWidth,adHeight,magicNumber){ this.adWidth=adWidth; this.adHeight=adHeight; this.magicNumber=magicNumber; this.placementKey=adWidth + "x" + adHeight; this.placements=new Array(); this.placements[this.placementKey]=magicNumber; } ewMagicNumberObject.prototype.getMagicNumber = function(adWidth,adHeight) { return this.placements[this.placementKey]; } var ewMagicNumberObj = new ewMagicNumberObject('','',''); var ewHeaderMagicNumberObj = new ewMagicNumberObject(365,104,93223283); var printable = false; if (document.location.href.indexOf("?") != -1) { var params = document.location.href.split("?")[1]; printable = (params.indexOf("print") != -1); } if (printable) { document.writeln(''); } function ewGetThreadedCommentsPage () { var result = 1; if ( ew_queryVariableExists( 'page' ) == 1 ) { result = tiiGetQueryParamValue( 'page' ); } return result; } function ewGetSTIScribbleboardPage () { // Important to intialize to 1 var result = 1; if ( ew_queryVariableExists( 'commentsPage' ) == 1 ) { var temp = tiiGetQueryParamValue( 'commentsPage' ); temp = parseInt( temp ); if ( isNaN( temp ) == 0 && temp > 1 ) { result = temp; } } return result; } function ewWriteSTIScribbleboardPagination (articleCurl) { //kc: Navigation to comments on Gallery pages only var commentsAnchor = "" if (document.location.href.indexOf("/gallery/") != -1) { commentsAnchor = "&#pagecomments" } if ( sti_scribbleboardPages > 1 && commentsPage > 1 ) { var previousPage = commentsPage - 1; //document.write('[First] '); document.write ('Back to Main'); document.write(''); } if ( sti_scribbleboardPages > 0 && commentsPage >= 1 ) { document.write( ' Page ' + commentsPage + ' of ' + sti_scribbleboardPages + ' ' ); } if ( sti_scribbleboardPages > 1 && commentsPage < sti_scribbleboardPages ) { var nextPage = commentsPage + 1; document.write( '' ); } } function ewWriteSTIScribbleboardTopHeader (articleCurl) { if ( sti_scribbleboardPages > 0 ) { document.write('
'); ewWriteSTIScribbleboardPagination(articleCurl); document.write( '
' ); } } function ewWriteSTIScribbleboardBottomHeader (articleCurl) { if ( sti_scribbleboardPages > 0 ) { document.write('
'); ewWriteSTIScribbleboardPagination(articleCurl); document.write( '
' ); } } function ewNextRandomNumber() { var hi = this.seed / this.Q; var lo = this.seed % this.Q; var test = this.A * lo - this.R * hi; if (test > 0) this.seed = test; else this.seed = test + this.M; return (this.seed * this.oneOverM); } function ewRandomNumberGenerator() { var d = new Date(); this.seed = 2345678901 + (d.getSeconds() * 0xFFFFFF) + (d.getMinutes() * 0xFFFF); this.A = 48271; this.M = 2147483647; this.Q = this.M / this.A; this.R = this.M % this.A; this.oneOverM = 1.0 / this.M; this.next = ewNextRandomNumber; return this; } function ewCreateRandomNumber(Min, Max) { var rand = new ewRandomNumberGenerator(); return Math.round( (Max-Min) * rand.next() + Min ); } (function() { /** * DEPLOYMENT INSTRUCTIONS: * Before deploying, verify the JavaScript code using JSLint: http://jslint.com * Then compress using YUI Compressor: http://compressorrater.thruhere.net/ * NOTE: Packer compresses slightly further but requires eval to execute so * stick with YUI. */ /** * Declare EWPicks namespace */ var EWPicks = {}; /** * Add EWPicks to global namespace */ window.EWPicks = EWPicks; function getPeriodOffset( targetDate, pagePeriod ) { // Establish a reference date for first day of EW week. Happy B-Day! w var referenceDate = new Date( 'Mon Mar 30 2009' ); // Calculate the size of the period in ms var msPerDay = 1000 * 60 * 60 * 24; var msPerPeriod = msPerDay; if ( pagePeriod === 'week' ) { msPerPeriod = 7 * msPerDay; } // Remove any time component from day targetDate.setHours( 0, 0, 0, 0 ); // Compute the delta, rounding down var ms = targetDate.getTime() - referenceDate.getTime(); var mod = ms % msPerPeriod; ms = ms - mod; var perc = mod / msPerPeriod; var timePeriods = ms / msPerPeriod; // Floating point slop. This seems to only be a problem with MSIE6. if ( perc > 0.98 && perc < 1 ) { timePeriods = timePeriods + 1; } /* alert( 'getPeriodOffset: pagePeriod -> ' + pagePeriod + ', referenceDate -> ' + referenceDate.toDateString() + ' ' + referenceDate.getTime() + ', targetDate -> ' + targetDate.toDateString() + ' ' + targetDate.getTime() + ', timePeriods -> ' + timePeriods + ', ms -> ' + ms + ', mod -> ' + mod + ', perc -> ' + perc ); */ return timePeriods; } /** * Add getPeriodOffset to EWPicks namespace */ EWPicks.getPeriodOffset = getPeriodOffset; /** ==================================================================== **/ /** * Parses a query string into an associative array object * * @method parseQueryString * @param {String} q (optional) URL query string or value of location.search * if none provided * @return {returnType} Return description */ var parseQueryString = function(/* q */) { var params = {}; var q = arguments[0] || location.search; if (q.length > 0) { var pairs = q.substring(q.indexOf('?') + 1).split('&'); for (var i = pairs.length - 1; i >= 0; --i) { var pair = pairs[i].split('='); params[pair[0]] = (typeof pair[1] === 'string') ? unescape(pair[1]) : pair[1]; } } return params; }; /** * Add parseQueryString to EWPicks namespace */ EWPicks.parseQueryString = parseQueryString; /** * Creates a regular expression for finding/replacing a particular DOM class * in an element's className attribute. (Used in the hasClass and * removeClass methods.) * * @method getClassNameRegExp * @param {String} className Name of DOM class to find/replace * @return {RegExp} Regular expression used to find/replace DOM class */ var getClassNameRegExp = function(className) { return new RegExp('\\s+' + className + '\\s+'); }; /** * Removes white space (or specified characters) from the beginning and end * of a string * * @method trim * @param {String} str String to trim * @return {String} Trimmed string */ var trim = function(str) { var chr = arguments[1] || '\\s'; var re = new RegExp('^'+chr+'+|'+chr+'+$', 'g'); return str.replace(re, ''); }; /** * Evaluates if a DOM element is of a specified CSS class * * @method hasClass * @param {DOMElement} el DOM element to evaluate * @param {String} className CSS class name to look for * @return {Boolean} True if className of DOM element contains CSS class */ var hasClass = function(el, className) { if (el && className) { return getClassNameRegExp(className).test(' ' + el.className + ' '); } else { throw new Error('hasClass called with invalid arguments'); } }; /** * Adds a CSS class to a DOM element * * @method addClass * @param {DOMElement} el DOM element to modify * @param {String} className Name of CSS class to add to element * @return */ var addClass = function(el, className) { if (el && className) { if (!hasClass(el, className)) { var y = el.className + ' ' + className; el.className = y; /* //Gets rid of the S for some reason. el.className = trim(el.className + ' ' + className); */ } } else { throw new Error('addClass called with invalid arguments'); } }; /** * Removes a CSS class from a DOM element * * @method removeClass * @param {DOMElement} el DOM element to modify * @param {String} className Name of CSS class to remove from element * @return */ var removeClass = function( el, targetClassName ) { /* IE Is lame! */ var classes = ''; var cleaned_classes = ''; if (el.getAttribute('className') !== null) { classes = el.getAttribute('className'); cleaned_classes = classes.replace(targetClassName, ' '); el.setAttribute('className', cleaned_classes); } else { classes = el.getAttribute('class'); cleaned_classes = classes.replace(targetClassName, ' '); el.setAttribute('class', cleaned_classes); } }; /** * Converts a string to a CSS class name * * Example: * "Beans and Rice" converts to 'beans-and-rice' * * @method toCSSClassName * @param {String} str String to modify * @return {String} Hyphenated, lowercased string */ var toCSSClassName = function(str) { return trim(str.toLowerCase().replace(/W+/g, '-'), '-'); }; /** * Description of method * * @method extend * @param {Function} subclass Parameter description * @param {Function} superclass Parameter description * @param {Object} overrides Parameter description * @return {returnType} Return description */ var extend = function(subclass, superclass, overrides) { if (!superclass || !subclass) { throw new Error('extend failed, please check that all dependencies are included.'); } var F = function() {}; F.prototype = superclass.prototype; subclass.prototype = new F(); subclass.prototype.constructor = subclass; subclass.superclass = superclass.prototype; if (superclass.prototype.constructor == Object.prototype.constructor) { superclass.prototype.constructor = superclass; } if (overrides) { for (var i in overrides) { if (overrides.hasOwnProperty(i)) { subclass.prototype[i] = overrides[i]; } } // L._IEEnumFix(subclass.prototype, overrides); } }; /** ==================================================================== **/ /** * BaseCalendarApp class * * BaseCalendarApp is an abstract class. It is currently extended by * DailyCalendarApp, HomepageCalendarApp, ChannelCalendarApp, and * WeeklyCalendarApp. * * BaseCalendarApp contains many of the methods necessary for constructing * a Google Calendar widget. It uses the GData API for loading calendar * data. * * @method BaseCalendarApp * @param {String} elementId Name of container DOM element * @param {Array|Object} calendars Calendar configuration object or array of calendar configuration objects * @param {Date} startDate (optional) Parameter description * @param {Date} endDate (optional) description * @return {Object} Instance of BaseCalendarApp */ var BaseCalendarApp = function(elementId, calendars /*, startDate, endDate */) { /** * The DOM element which contains the EW Picks application */ this.element = document.getElementById(elementId); /** * BaseCalendarApp requires an existing DOM element */ if (this.element === null) { throw new Error('EWPicks.BaseCalendarApp: Unable to locate element ' + elementId); } /** * A calendar or array of calendars to populate the EW Picks application */ this.calendars = (calendars instanceof Array) ? calendars : [calendars]; /** * BaseCalendarApp requires one or multiple calendars. */ if (this.calendars.length === 0) { throw new Error('EWPicks.BaseCalendarApp: Requires calendars.'); } /** * BaseCalendarApp accepts an optional start date. Without a start date, the * Google Calendar API will retrieve all events from the end date back. */ if (arguments.length > 2 && arguments[2]) { this.startDate = arguments[2]; } /** * BaseCalendarApp accepts an optional end date, Without an end date, the Google * Calendar API will retrieve all events from the start date forward. */ if (arguments.length > 3 && arguments[3]) { this.endDate = arguments[3]; } /** * Memoize the scope for use in the Google API callback */ var scope = this; /** * Load the Google Data API */ google.load('gdata', '1'); google.setOnLoadCallback(function() { scope.calendarService = new google.gdata.calendar.CalendarService(scope.appName); scope._init.apply(scope); }); }; /** * Prototoype for the BaseCalendarApp class */ BaseCalendarApp.prototype = { appName: 'EWPicks-BaseCalendarApp', /** * Callback method for the gdata onload event. * * @method _init * @return {returnType} Return description */ _init: function() { }, /** * Parses event data from the Google Calendar Event object * * @method _parseCalendarEntry * @param {Object} entry Parameter description * @return {Object} Simplified event object */ _parseCalendarEntry: function(entry) { var linkData = entry.getLocations()[0].getValueString().split('#'); return { summary: entry.getTitle().getText(), description: entry.getContent().getText(), link: linkData[0], linkText: linkData[1] || BaseCalendarApp.DEFAULT_LINK_TEXT, date: entry.getTimes()[0].getStartTime().getDate() }; }, /** * Description of method * * @method _parseCalendarEventFeed * @param {Object} eventFeed Parameter description * @return {Array} Array of simplified event objects */ _parseCalendarEventFeed: function(eventFeed, moreLinkText, moreLinkUrl) { var entries = eventFeed.getEntries(); var events = []; for (var i = 0, len = entries.length; i < len; ++i) { var entry = this._parseCalendarEntry(entries[i]); entry.moreLink = moreLinkUrl; entry.moreLinkText = moreLinkText; events.push(entry); } return events; }, /** * Sets the time of a date object to 00:00:00.000. Along with the * setTimeToEndOfDay method, this method is used to bracket the date range * supplied to the Google Calendar API query. * * NOTE: This method modifies the original object. * * @method setTimeToStartOfDay * @param {Date} date Date object to modify */ setTimeToStartOfDay: function(date) { date.setHours(0); date.setMinutes(0); date.setSeconds(0); date.setMilliseconds(0); }, /** * Sets the time of a date object to 23:59:59.999. Along with the * setTimeToStartOfDay method, this method is used to bracket the date * range supplied to the Google Calendar API query. * * NOTE: This method modifies the original object. * * @method setTimeToEndOfDay * @param {Date} date Date object to modify */ setTimeToEndOfDay: function(date) { date.setHours(23); date.setMinutes(59); date.setSeconds(59); date.setMilliseconds(999); }, /** * Adds a leading zero to a numeric value less than 10. * * @method addLeadingZero * @param {String|Number} val A string or number object representing a * numerical value * @return {String} The original value preceded by a zero (if numeric * value is less than 10) */ addLeadingZero: function(val) { return (parseInt(val, 10) < 10) ? '0' + val : val; }, /** * Description of method * * @method _fetchEvents * @param {String} calendarId Parameter description * @param {Function} callback Parameter description * @param {Object} scope (optional) Parameter description * @param {Date} startDate (optional) Parameter description * @param {Date} endDate (optional) Parameter description * @return {returnType} Return description */ _fetchEvents: function(calendarId, callback /*, scope, startDate, endDate */) { var uri = BaseCalendarApp.URI_TEMPLATE.replace(BaseCalendarApp.URI_REG_EXP, calendarId); var query = new google.gdata.calendar.CalendarEventQuery(uri); /** * */ var scope = arguments[2] || window; /** * */ if (arguments.length > 3 && typeof arguments[3] !== 'undefined') { var startDate = arguments[3]; var startMin = new google.gdata.DateTime(startDate); query.setMinimumStartTime(startMin); /** * */ if (arguments.length > 4 && typeof arguments[4] !== 'undefined') { var endDate = arguments[4]; var startMax = new google.gdata.DateTime(endDate); query.setMaximumStartTime(startMax); } } query.setOrderBy('starttime'); query.setSortOrder('ascending'); query.setSingleEvents('true'); /** * */ var handleSuccess = function(result) { if (typeof callback !== 'undefined' && typeof callback.success === 'function') { callback.success.apply(scope, [result]); } }; /** * */ var handleFailure = function(error) { if (typeof callback !== 'undefined' && typeof callback.failure === 'function') { callback.failure.apply(scope, [error]); } }; this.calendarService.getEventsFeed(query, handleSuccess, handleFailure); }, /** * Description of method * * @method _renderErrorElement * @param {String} error Parameter description * @return {DOMElement} Return description */ _renderErrorElement: function(error) { var el = document.createElement('div'); el.className = 'error'; el.appendChild(document.createTextNode(error)); return el; }, /** * Description of method * * @method _renderHeaderElement * @param {String} text Parameter description * @param {String} url Parameter description * @return {DOMElement} Return description */ _renderHeaderElement: function(text, url) { var el = document.createElement('h3'); var a = document.createElement('a'); a.href = url; a.appendChild(document.createTextNode(text)); el.appendChild(a); return el; }, /** * Renders a DOM element representing an event's date * * @method _renderDtElement * @param {Date} date Parameter description * @param {String} className Parameter description * @return {DOMElement} Return description */ _renderDtElement: function(date, className) { var yyyy = date.getFullYear(); var m = date.getMonth(); var mm = this.addLeadingZero(m + 1); var d = date.getDate(); var dd = this.addLeadingZero(d); var el = document.createElement('div'); el.className = 'dtstart'; el.title = [yyyy, mm, dd].join('-'); var weekday = document.createElement('span'); weekday.className = 'weekday'; weekday.appendChild(document.createTextNode(BaseCalendarApp.WEEKDAYS[date.getDay()])); el.appendChild(weekday); el.appendChild(document.createTextNode(' ')); var month = document.createElement('abbr'); month.className = 'month'; month.title = BaseCalendarApp.MONTHS[m]; month.appendChild(document.createTextNode(BaseCalendarApp.MONTHS_ABBREVIATED[m])); el.appendChild(month); el.appendChild(document.createTextNode(' ')); var day = document.createElement('span'); day.className = 'day'; day.appendChild(document.createTextNode(d)); el.appendChild(day); return el; }, /** * Renders a DOM element representing an event's date for What's New * * @method _renderDtElement * @param {Date} date Parameter description * @param {String} className Parameter description * @return {DOMElement} Return description */ _renderWNDtElement: function(date, className) { var yyyy = date.getFullYear(); var m = date.getMonth(); var mm = this.addLeadingZero(m + 1); var d = date.getDate(); var dd = this.addLeadingZero(d); var el = document.createElement('div'); el.className = 'dateHolder'; el.title = [yyyy, mm, dd].join('-'); var weekday = document.createElement('span'); weekday.className = 'dayOfWeek'; weekday.appendChild(document.createTextNode(BaseCalendarApp.WNWEEKDAYS[date.getDay()])); el.appendChild(weekday); el.appendChild(document.createTextNode(' ')); el.appendChild(document.createTextNode(' ')); var day = document.createElement('span'); day.className = 'date'; day.appendChild(document.createTextNode(d)); el.appendChild(day); return el; }, /** * Renders a DOM element representing an event's date for Looking Ahead * * @method _renderLADtElement * @param {Date} date Parameter description * @param {String} className Parameter description * @return {DOMElement} Return description */ _renderLADtElement: function(date, className) { var yyyy = date.getFullYear(); var m = date.getMonth(); var mm = this.addLeadingZero(m + 1); var d = date.getDate(); var dd = this.addLeadingZero(d); var el = document.createElement('div'); el.className = 'dateHolder'; el.title = [yyyy, mm, dd].join('-'); var month = document.createElement('span'); month.className = 'month'; month.appendChild(document.createTextNode(BaseCalendarApp.MONTHS_ABBREVIATED[date.getMonth()])); el.appendChild(month); el.appendChild(document.createTextNode(' ')); el.appendChild(document.createTextNode(' ')); var day = document.createElement('span'); day.className = 'date'; day.appendChild(document.createTextNode(d)); el.appendChild(day); return el; }, /** * Renders a DOM element representing an event's summary (title) * * @method _renderSummaryElement * @param {String} summary Parameter description * @param {String} url (optional) Parameter description * @return {DOMElement} Return description */ _renderSummaryElement: function(summary /*, url*/) { var el = document.createElement('h4'); el.className = 'summary'; var tn = document.createTextNode(summary); if (arguments.length > 1 && arguments[1]) { var summaryLink = document.createElement('a'); summaryLink.href = arguments[1]; summaryLink.appendChild(tn); el.appendChild(summaryLink); } else { el.appendChild(tn); } return el; }, _renderHPSummaryElement: function(summary /*, url*/) { var el = document.createElement('h4'); el.className = 'summary'; var tn = document.createTextNode(summary); var image = document.createElement('img'); image.setAttribute('src', 'http://img2.timeinc.net/ew/i/icon_arrow06.gif'); image.setAttribute('alt', 'arrow'); if (arguments.length > 1 && arguments[1]) { var summaryLink = document.createElement('a'); summaryLink.href = arguments[1]; summaryLink.appendChild(tn); summaryLink.appendChild(image); el.appendChild(summaryLink); } else { el.appendChild(tn); } return el; }, _renderWNSummaryElement: function(summary /*, url*/) { var el = document.createElement('span'); el.className = 'summary'; var tn = document.createTextNode(summary); /* if (arguments.length > 1 && arguments[1]) { var summaryLink = document.createElement('a'); //summaryLink.href = arguments[1]; summaryLink.appendChild(tn); el.appendChild(summaryLink); } else { el.appendChild(tn); } */ el.appendChild(tn); return el; }, /** * Renders a DOM element representing an event's description * * @method _renderDescriptionElement * @param {String} description Parameter description * @return {DOMElement} Return description */ _renderDescriptionElement: function(description) { var el = document.createElement('p'); el.className = 'description'; el.appendChild(document.createTextNode(description)); return el; }, _renderWNDescriptionElement: function(description) { var el = document.createElement('p'); el.className = 'description'; el.appendChild(document.createTextNode(description)); return el; }, /** * Renders a DOM element containing a link to an event's article URL * * @method _renderLinkElement * @param {String} text Parameter description * @param {String} url Parameter description * @return {DOMElement} Return description */ _renderLinkElement: function(text, url) { var el = document.createElement('a'); el.href = url; var domain = url.split('/'); var split_url = domain[2].split('.'); if ((split_url[0] == 'ew') || (split_url[1] == 'ew')) { } else { el.setAttribute('target', '_NEW'); } el.className = 'url'; el.appendChild(document.createTextNode(text)); return el; }, _renderWNLinkElement: function(text, url) { var el = document.createElement('a'); el.href = url; //el.className = 'url'; var domain = url.split('/'); var split_url = domain[2].split('.'); if ((split_url[0] == 'ew') || (split_url[1] == 'ew')) { } else { el.setAttribute('target', '_NEW'); } el.appendChild(document.createTextNode(text)); var el2 = document.createElement('img'); el2.className = 'arrowImage'; el2.setAttribute('src', 'http://img2.timeinc.net/ew/i/icon_arrow05.gif'); el.className = 'arrow'; el.appendChild(el2); return el; }, /** * Renders a DOM element containing a link to a channel's weekly calendar * * @method _renderMoreLinkElement * @param {String} text Parameter description * @param {String} url Parameter description * @return {DOMElement} Return description */ _renderMoreLinkElement: function(text, url) { var el = document.createElement('a'); el.href = url; el.className = 'more'; el.appendChild(document.createTextNode(text)); return el; }, _renderMoreWNLinkElement: function(text, url) { var el = document.createElement('a'); el.href = url; el.className = 'more'; el.appendChild(document.createTextNode(text)); return el; }, /** * Renders a DOM element representing an event * * @method _renderEventElement * @param {Object} event Parameter description * @return {DOMElement} Return description */ _renderEventElement: function(event) { var el = document.createElement('div'); el.className = 'vevent'; el.appendChild(this._renderDtElement(event.date, 'dtstart')); el.appendChild(this._renderSummaryElement(event.summary, event.link)); el.appendChild(this._renderDescriptionElement(event.description)); if (event.link) { el.appendChild(this._renderLinkElement(event.linkText, event.link)); } return el; }, _renderWNEventElement: function(event) { var el = document.createElement('div'); el.className = 'item first-item'; //if (isFirst == TRUE) { // el.className = 'first-item'; //} var el2 = document.createElement('div'); el2.className = 'descHolder'; //el.appendChild(el2); el.appendChild(this._renderWNSummaryElement(event.summary, event.link)); if (event.description) { el.appendChild(this._renderWNDescriptionElement(event.description)); } if (event.link) { el.appendChild(this._renderWNLinkElement(event.linkText, event.link)); } return el; }, _renderWNEventElement2: function(event) { //alert('woo'); //alert(event.linkText); var el = document.createElement('div'); el.className = 'item'; var el2 = document.createElement('div'); el2.className = 'descHolder'; //el.appendChild(el2); //el.appendChild(this._renderWNDtElement(event.date, 'dtstart')); el.appendChild(this._renderWNSummaryElement(event.summary, event.link)); if (event.description) { el.appendChild(this._renderWNDescriptionElement(event.description)); } if (event.link) { el.appendChild(this._renderWNLinkElement(event.linkText, event.link)); } return el; }, _renderLAEventElement: function(event) { var el = document.createElement('div'); el.className = 'item'; el.appendChild(this._renderLADtElement(event.date, 'dtstart')); var el2 = document.createElement('div'); el2.className = 'item-description'; el2.appendChild(this._renderWNSummaryElement(event.summary, event.link)); if (event.description) { el2.appendChild(this._renderWNDescriptionElement(event.description)); } if (event.link) { el2.appendChild(this._renderWNLinkElement(event.linkText, event.link)); } el.appendChild(el2); return el; }, /** * Renders the "Previous" and "Next" links for a calendar widget (ie. * DailyCalendarApp and WeeklyCalendarApp) * * @method _renderPreviousNextLinksElement * @return {DOMElement} Return description */ _renderPreviousNextLinksElement: function() { var el = document.createElement('ul'); el.className = 'previousNextLinks'; var prev = document.createElement('li'); prev.appendChild(this._renderPreviousLink()); el.appendChild(prev); var next = document.createElement('li'); next.appendChild(this._renderNextLink()); el.appendChild(next); return el; }, /** * Retrieves the head element of a calendar widget having class "hd" * * @method getHeadElement * @return {returnType} Return description */ getHeadElement: function() { var hd, divs = this.element.getElementsByTagName('div'); var divFound = 0; for (var i = 0, len = divs.length; i < len; ++i) { var div = divs[i]; if (hasClass(div, 'hd')) { divFound = 1; return div; } } if (divFound != 1) { div = document.getElementById('hd-div'); return div; } }, _getHeadElement: function() { var hd, divs = this.element.getElementsByTagName('div'); for (var i = 0, len = divs.length; i < len; ++i) { var div = divs[i]; if (hasClass(div, 'hd')) { return div; } } }, /** * Retrieves the head element of a calendar widget having class "ft" * * @method getFootElement * @return {returnType} Return description */ getFootElement: function() { var ft, divs = this.element.getElementsByTagName('div'); var divFound = 0; for (var i = 0, len = divs.length; i < len; ++i) { var div = divs[i]; if (hasClass(div, 'ft')) { divFound = 1; return div; } } if (divFound != 1) { div = document.getElementById('ft-div'); return div; } }, _getFootElement: function() { var ft, divs = this.element.getElementsByTagName('div'); for (var i = 0, len = divs.length; i < len; ++i) { var div = divs[i]; if (hasClass(div, 'ft')) { return div; } } } }; /** * Add BaseCalendarApp to EWPicks namespace */ EWPicks.BaseCalendarApp = BaseCalendarApp; /** * BaseCalendarApp constants */ BaseCalendarApp.URI_REG_EXP = /#\{calendarId\}/; BaseCalendarApp.URI_TEMPLATE = 'http://www.google.com/calendar/feeds/#{calendarId}/public/full'; BaseCalendarApp.DEFAULT_LINK_TEXT = 'Read more'; BaseCalendarApp.DEFAULT_MORE_LINK_TEXT = 'See Weekly %s Picks'; BaseCalendarApp.WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; BaseCalendarApp.WNWEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; BaseCalendarApp.MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'Octover', 'November', 'December']; BaseCalendarApp.MONTHS_ABBREVIATED = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; BaseCalendarApp.ONE_DAY_IN_MILLISECONDS = 86400000; BaseCalendarApp.SIX_DAYS_IN_MILLISECONDS = 518400000; BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS = 604800000; /** ==================================================================== **/ /** * Description of method * * @method DailyCalendarApp * @param {String} elementId Parameter description * @param {Array|Object} calendars Parameter description * @param {Date} startDate (optional) Parameter description * @param {Boolean} displayNavigation Parameter description * @return {Object} Instance of DailyCalendarApp */ var DailyCalendarApp = function(elementId, calendars /*, startDate, displayNavigation */) { /** * Configure dates */ var startDate = (arguments.length > 2 && arguments[2]) ? new Date(arguments[2]) : new Date(); this.setTimeToStartOfDay(startDate); var endDate = new Date(startDate); this.setTimeToEndOfDay(endDate); /** * */ DailyCalendarApp.superclass.constructor.call(this, elementId, calendars, startDate, endDate); var displayNavigation = !!arguments[3]; var hd = this.getHeadElement(); if (displayNavigation) { // Add date to head element var ft = this.getFootElement(); var nav = document.createElement('div'); nav.className = 'nav'; nav.appendChild(this._renderDtElement(this.startDate, 'dtstart')); nav.appendChild(this._renderPreviousNextLinksElement()); var nav2 = nav.cloneNode(true); hd.appendChild(nav); ft.appendChild(nav2); } else { hd.appendChild(this._renderDtElement(this.startDate, 'dtstart')); } }; /** * Extend DailyCalendarApp from BaseCalendarApp and augment the * DailyCalendarApp prototype */ extend(DailyCalendarApp, BaseCalendarApp, { appName: 'EWPicks-DailyCalendarApp', /** * Callback method for the gdata onload event. Fetches calendar feed and * constructs the callback method for parsing feed and displaying entries. * * @method _init * @return {returnType} Return description */ _init: function() { // DailyCalendarApp.superclass._init.call(this); for (var i = 0, len = this.calendars.length; i < len; i++) { var calendar = this.calendars[i]; var calendar_name = calendar.el; var el = document.getElementById(calendar_name); var feed = calendar.feed; addClass(el, toCSSClassName(feed.name)); /* TODO: throw error or continue if element is undefined */ var handleSuccess = function(el, feed) { return function(result) { var h3 = this._renderHeaderElement(feed.name, feed.url); el.appendChild(h3); var moreLinkText = BaseCalendarApp.DEFAULT_MORE_LINK_TEXT.replace('%s', feed.name); var moreLinkUrl = feed.url; var events = this._parseCalendarEventFeed(result.feed, moreLinkText, moreLinkUrl); for (var i = 0, len = events.length; i <= len; ++i) { var event = events[i]; if ( event !== null && typeof(event) === 'object' && event.date !== null && typeof(event.date) === 'object' ) { if (event.date >= this.startDate && event.date <= this.endDate) { removeClass(el, 'loading'); el.appendChild(this._renderEventElement(event)); } } } }; }(el, feed); var handleFailure = function(el, feed) { return function() { removeClass(el, 'loading'); // el.appendChild(this._renderErrorElement('Server error.')); el.style.display = 'none'; }; }(el, feed); //addClass(el, 'loading'); this._fetchEvents(feed.id, { success: handleSuccess, failure: handleFailure }, this, this.startDate, this.endDate); } }, /** * Description of method * * @method _renderEventElement * @param {Object} event Parameter description * @return {DOMElement} Return description */ _renderEventElement: function(event) { var el = DailyCalendarApp.superclass._renderEventElement.call(this, event); if (event.moreLink) { el.appendChild(this._renderMoreLinkElement(event.moreLinkText, event.moreLink)); } return el; }, /** * Description of method * * @method _renderPreviousLink * @return {DOMElement} Return description */ _renderPreviousLink: function() { var date = new Date(this.startDate.getTime() - BaseCalendarApp.ONE_DAY_IN_MILLISECONDS); var now = new Date(); var second_diff = this.startDate.getTime() - now.getTime(); var el = document.createElement('a'); var periodOffsets = getPeriodOffset(this.startDate, 'day') - getPeriodOffset(now, 'day'); //alert( periodOffsets ); if ( periodOffsets >= 1 && periodOffsets <= 14 ) { el.className = 'previous'; el.href = '?date=' + date.toDateString(); } else { el.className = 'previous-disabled'; el.href = '#'; } el.appendChild(document.createTextNode('Previous Day')); return el; }, /** * Description of method * * @method _renderNextLink * @return {DOMElement} Return description */ _renderNextLink: function() { var date = new Date(this.startDate.getTime() + BaseCalendarApp.ONE_DAY_IN_MILLISECONDS); var now = new Date(); var second_diff = date.getTime() - now.getTime(); var two_weeks = BaseCalendarApp.ONE_DAY_IN_MILLISECONDS * 14; var el = document.createElement('a'); //alert('second diff: ' + second_diff + ' two weeks: ' + two_weeks); var periodOffsets = getPeriodOffset(this.startDate, 'day') - getPeriodOffset(now, 'day'); //alert( periodOffsets ); if ( periodOffsets >= 0 && periodOffsets <= 13 ) { el.className = 'next'; el.href = '?date=' + date.toDateString(); } else { el.className = 'next-disabled'; el.href = '#'; } el.appendChild(document.createTextNode('Next Day')); return el; } }); /** * Add DailyCalendarApp to EWPicks namespace */ EWPicks.DailyCalendarApp = DailyCalendarApp; /** ==================================================================== **/ /** * Description of method * * @method HomepageCalendarApp * @param {String} elementId Parameter description * @param {Array|Object} calendars Parameter description * @return {Object} Instance of HomepageCalendarApp */ var HomepageCalendarApp = function(elementId, calendars) { var startDate = EWPicks.parseQueryString().date; HomepageCalendarApp.superclass.constructor.call(this, elementId, calendars, startDate); }; /** * Extend HomepageCalendarApp from DailyCalendarApp and augment the * HomepageCalendarApp prototype */ extend(HomepageCalendarApp, DailyCalendarApp, { appName: 'EWPicks-HomepageCalendarApp', /** * Description of method * * @method _renderEventElement * @param {Object} event Parameter description * @return {DOMElement} Return description */ _renderEventElement: function(event) { var el = document.createElement('div'); el.className = 'vevent'; el.appendChild(this._renderHPSummaryElement(event.summary, EWPicks.DAILY_URL)); if (event.moreLink) { el.appendChild(this._renderMoreLinkElement(event.moreLinkText, event.moreLink)); } return el; } }); /** * Add HomepageCalendarApp to EWPicks namespace */ EWPicks.HomepageCalendarApp = HomepageCalendarApp; /** ==================================================================== **/ /** * Description of method * * @method ChannelCalendarApp * @param {String} elementId Parameter description * @param {Array|Object} calendars Parameter description * @return {Object} Instance of ChannelCalendarApp */ var ChannelCalendarApp = function(elementId, calendars) { var startDate = EWPicks.parseQueryString().date; ChannelCalendarApp.superclass.constructor.call(this, elementId, calendars, startDate); }; /** * Extend ChannelCalendarApp from DailyCalendarApp and augment the * ChannelCalendarApp prototype */ extend(ChannelCalendarApp, DailyCalendarApp, { appName: 'EWPicks-ChannelCalendarApp' }); /** * Add ChannelCalendarApp to EWPicks namespace */ EWPicks.ChannelCalendarApp = ChannelCalendarApp; /** ==================================================================== **/ /** * Description of method * * @method WeeklyCalendarApp * @param {String} elementId Parameter description * @param {Array|Object} calendars Parameter description * @param {Date} startDate Parameter description * @param {Boolean} displayNavigation Parameter description * @return {Object} Instance of WeeklyCalendarApp */ var WeeklyCalendarApp = function(elementId, calendars /*, startDate, displayNavigation */) { /** * Configure dates */ var date = (arguments.length > 2 && arguments[2]) ? new Date(arguments[2]) : new Date(); var millisecondsSinceMonday = (date.getDay() - 1) * BaseCalendarApp.ONE_DAY_IN_MILLISECONDS; var startDate = new Date(date.getTime() - millisecondsSinceMonday); /* 20090408. kwiechma. Hack so that users manually entering a date will not be displayed incorrect week data for the last days of the week. */ if ( date.getTime() < startDate.getTime() ) { startDate.setTime( startDate.getTime() - BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS); } /* 20090408. kwiechma */ this.setTimeToStartOfDay(startDate); var endDate = new Date(startDate.getTime() + BaseCalendarApp.SIX_DAYS_IN_MILLISECONDS); this.setTimeToEndOfDay(endDate); this.todayDateString = (new Date()).toDateString(); /** * */ WeeklyCalendarApp.superclass.constructor.call(this, elementId, calendars, startDate, endDate); var displayNavigation = !!arguments[3]; if (displayNavigation) { // Add date to head element var hd = this.getHeadElement(); var ft = this.getFootElement(); var nav = document.createElement('div'); nav.className = 'nav'; nav.appendChild(this._renderWeekOfElement()); nav.appendChild(this._renderPreviousNextLinksElement()); var nav2 = nav.cloneNode(true); hd.appendChild(nav); ft.appendChild(nav2); } }; /** * Extend WeeklyCalendarApp from BaseCalendarApp and augment the * WeeklyCalendarApp prototype */ extend(WeeklyCalendarApp, BaseCalendarApp, { appName: 'EWPicksWeeklyCalendarApp', /** * Callback method for the gdata onload event. Fetches calendar feed and * constructs the callback method for parsing feed and displaying entries. * * @method _init * @return {returnType} Return description */ _init: function() { // WeeklyCalendarApp.superclass._init.call(this); // Add date to head element var hd = this.getHeadElement(); var ft = this.getFootElement(); var handleFailure = function(error) { removeClass(el, 'loading'); // el.appendChild(this._renderErrorElement('Server error.')); el.style.display = 'none'; }; for (var i = 0, len = this.calendars.length; i < len; ++i) { var calendar = this.calendars[i]; var prefix = calendar.prefix; var feed = calendar.feed; var handleSuccess = function(prefix, feed) { return function(result) { var moreLinkText = BaseCalendarApp.DEFAULT_MORE_LINK_TEXT.replace('%s', feed.name); var moreLinkUrl = feed.url; var events = this._parseCalendarEventFeed(result.feed, moreLinkText, moreLinkUrl); for (var i = 0, len = events.length; i < len; ++i) { var event = events[i]; var date = event.date; if ( event !== null && typeof(event) === 'object' && event.date !== null && typeof(event.date) === 'object' ) { if (date >= this.startDate && date <= this.endDate) { var pos = (date.getDay() + 6) % 7; // Move Sunday to the end var el = document.getElementById(prefix + pos); if (el !== null) { removeClass(el, 'loading'); el.appendChild(this._renderEventElement(event)); } } } } }; }(prefix, feed); this._fetchEvents(calendar.feed.id, { success: handleSuccess, failure: handleFailure }, this, this.startDate, this.endDate); } }, /** * Description of method * * @method _renderEventElement * @param {Object} event Parameter description * @return {DOMElement} Return description */ _renderEventElement: function(event) { var el = WeeklyCalendarApp.superclass._renderEventElement.call(this, event); if (event.date.toDateString() === this.todayDateString) { el.className += ' today'; } return el; }, /** * Description of method * * @method _renderPreviousLink * @return {DOMElement} Return description */ _renderPreviousLink: function() { var date = new Date(this.startDate.getTime() - BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS); var el = document.createElement('a'); var now = new Date(); var second_diff = this.startDate.getTime() - now.getTime(); //alert( 'second_diff -> ' + second_diff + ', this.startDate.getTime() -> ' + this.startDate.getTime() + ', now.getTime() -> ' + now.getTime() ); var periodOffsets = getPeriodOffset(this.startDate, 'week') - getPeriodOffset(now, 'week'); //alert( periodOffsets ); if ( periodOffsets >= 1 && periodOffsets <= 1 ) { el.className = 'previous'; el.href = '?date=' + date.toDateString(); } else { el.className = 'previous-disabled'; el.href = '#'; } el.appendChild(document.createTextNode('Previous Week')); return el; }, /** * Description of method * * @method _renderNextLink * @return {DOMElement} Return description */ _renderNextLink: function() { var date = new Date(this.startDate.getTime() + BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS); var now = new Date(); var second_diff = date.getTime() - now.getTime(); var el = document.createElement('a'); //alert( 'second_diff -> ' + second_diff + ', BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS -> ' + BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS ); var periodOffsets = getPeriodOffset(this.startDate, 'week') - getPeriodOffset(now, 'week'); //alert( periodOffsets ); if ( periodOffsets >= 0 && periodOffsets <= 0 ) { el.className = 'next'; el.href = '?date=' + date.toDateString(); } else { el.className = 'next-disabled'; el.href = '#'; } el.appendChild(document.createTextNode('Next Week')); return el; }, /** * Description of method * * @method _renderWeekOfElement * @return {DOMElement} Return description */ _renderWeekOfElement: function() { var el = document.createElement('div'); el.className = 'dtrange vevent'; el.appendChild(document.createTextNode('Week of ')); el.appendChild(this._renderDtElement(this.startDate, 'dtstart')); el.appendChild(document.createTextNode(' - ')); el.appendChild(this._renderDtElement(this.endDate,'dtend')); return el; } }); /** * Add WeeklyCalendarApp to EWPicks namespace */ EWPicks.WeeklyCalendarApp = WeeklyCalendarApp; /* This is scary stuff built by Ned so if it doesn't work we are in trouble. */ var LookingAheadApp = function(elementId, calendars) { var startDate = new Date(); for (var i = 0, len = calendars.length; i < len; ++i) { var calendar = calendars[i]; var prefix = calendar.prefix; var feed = calendar.feed; var target = calendar.target; } LookingAheadApp.superclass.constructor.call(this, elementId, calendars, startDate); }; extend(LookingAheadApp, BaseCalendarApp, { appName: 'LookingAheadApp', _init: function() { //alert('init'); var handleFailure = function(error) { //alert('failure'); var loadingHolder = document.getElementById('looking-ahead-loading'); loadingHolder.className = ''; }; for (var i = 0, len = this.calendars.length; i < len; i++) { var calendar = this.calendars[i]; var feed = calendar.feed; //alert(feed.name + ' url:' + feed.url + ' id:' + feed.id); var handleSuccess = function(feed) { return function(result) { var el = document.getElementById('looking-ahead-results'); var events = this._parseCalendarEventFeed(result.feed); //alert(events.length); if (events.length > 8) { len = 8; } else { len = events.length; } for (var i = 0; i < len; i++) { var event = events[i]; var date = event.date; if (el !== null) { el.appendChild(this._renderLAEventElement(event)); } //alert(event.name); } var loadingHolder = document.getElementById('looking-ahead-loading'); loadingHolder.className = ''; var lookingResults = document.getElementById('looking-ahead-results'); var last = lookingResults.lastChild; last.className = 'item last'; }; }(feed); var startDate = new Date(); this._fetchEvents(feed.id, { success: handleSuccess, failure: handleFailure }, this, this.startDate); } } }); EWPicks.LookingAheadApp = LookingAheadApp; /** ==================================================================== **/ /** ==================================================================== **/ /** * Description of method * * @method WhatsNew-WeeklyCalendarApp * @param {String} elementId Parameter description * @param {Array|Object} calendars Parameter description * @param {Date} startDate Parameter description * @param {Boolean} displayNavigation Parameter description * @return {Object} Instance of WeeklyCalendarApp */ var WhatsNewWeeklyCalendarApp = function(elementId, calendars, startDate, displayNavigation ) { //alert('boo'); /** * Configure dates */ var date = (arguments.length > 2 && arguments[2]) ? new Date(arguments[2]) : new Date(); //alert(date); var millisecondsSinceMonday = (date.getDay() - 1) * BaseCalendarApp.ONE_DAY_IN_MILLISECONDS; startDate = new Date(date.getTime() - millisecondsSinceMonday); /* 20090408. kwiechma. Hack so that users manually entering a date will not be displayed incorrect week data for the last days of the week. */ if ( date.getTime() < startDate.getTime() ) { startDate.setTime( startDate.getTime() - BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS); } /* 20090408. kwiechma */ this.setTimeToStartOfDay(startDate); var endDate = new Date(startDate.getTime() + BaseCalendarApp.SIX_DAYS_IN_MILLISECONDS); this.setTimeToEndOfDay(endDate); this.todayDateString = (new Date()).toDateString(); /** * */ WhatsNewWeeklyCalendarApp.superclass.constructor.call(this, elementId, calendars, startDate, endDate); displayNavigation = !!arguments[3]; if (displayNavigation) { // Add date to head element var hd = document.getElementById('hd-div'); var ft = document.getElementById('ft-div'); var children = hd.getElementsByTagName('div'); // 20090417. kwiechma. 0 --> 1 Allows navigation on What's New // alert(children.length); if (children.length === 1) { var nav = document.createElement('div'); nav.className = 'nav'; nav.appendChild(this._renderWeekOfElement()); nav.appendChild(this._renderPreviousNextLinksElement()); var nav2 = nav.cloneNode(true); hd.appendChild(nav); ft.appendChild(nav2); } } }; /** * Extend WeeklyCalendarApp from BaseCalendarApp and augment the * WeeklyCalendarApp prototype */ extend(WhatsNewWeeklyCalendarApp, BaseCalendarApp, { appName: 'WhatsNewWeeklyCalendarApp', /** * Callback method for the gdata onload event. Fetches calendar feed and * constructs the callback method for parsing feed and displaying entries. * * @method _init * @return {returnType} Return description */ _init: function() { //WeeklyCalendarApp.superclass._init.call(this); // Add date to head element var hd = this.getHeadElement(); var ft = this.getFootElement(); var handleFailure = function(error) { removeClass(el, 'loading'); // el.appendChild(this._renderErrorElement('Server error.')); el.style.display = 'none'; }; for (var i = 0, len = this.calendars.length; i < len; ++i) { var calendar = this.calendars[i]; var prefix = calendar.prefix; var feed = calendar.feed; var target = calendar.target; var handleSuccess = function(prefix, feed) { return function(result) { var moreLinkText = BaseCalendarApp.DEFAULT_MORE_LINK_TEXT.replace('%s', feed.name); var moreLinkUrl = feed.url; var events = this._parseCalendarEventFeed(result.feed, moreLinkText, moreLinkUrl); var last_date = ''; //alert(events.length); var el = document.getElementById(target); var children = el.getElementsByTagName('div'); if (children.length !== 0) { for (var y = 0; y < children.length; y++) { if (children[y].className == 'loading') { //removeClass(children[y], 'loading'); el.removeChild(children[y]); } } } for (var i = 0, len = events.length; i < len; ++i) { var event = events[i]; var date = event.date; if (date >= this.startDate && date <= this.endDate) { var pos = (date.getDay() + 6) % 7; // Move Sunday to the end if (date + '' != last_date + '') { //alert('good'); //alert('date ' + date + ' last_date: ' + last_date); //Need to render a new day. //var close_day = TRUE; var subEl = document.createElement('div'); subEl.className = 'dayHolder'; //alert(pos); if (pos == len) { subEl.className = 'dayHolder lastDay'; } subEl.appendChild(this._renderWNDtElement(event.date, 'dtstart')); //var is_last = FALSE; //alert('sigh'); if (el !== null) { el.appendChild(subEl); subEl.appendChild(this._renderWNEventElement(event)); } } else { //alert('no good'); //var kiddo = document.createElement('div'); //kiddo.className = 'item'; //subEl.appendChild(kiddo); //alert(event); subEl.appendChild(this._renderWNEventElement2(event)); } last_date = date; } } var last_child = el.lastChild; last_child.className = 'dayHolder lastDay'; }; }(prefix, feed); this._fetchEvents(calendar.feed.id, { success: handleSuccess, failure: handleFailure }, this, this.startDate, this.endDate); } }, /** * Description of method * * @method _renderEventElement * @param {Object} event Parameter description * @return {DOMElement} Return description */ _renderWNEventElement: function(event) { var el = WeeklyCalendarApp.superclass._renderWNEventElement.call(this, event); if (event.date.toDateString() === this.todayDateString) { //el.className += ' today'; } return el; }, _renderWNEventElement2: function(event) { var el = WeeklyCalendarApp.superclass._renderWNEventElement2.call(this, event); return el; }, /** * Description of method * * @method _renderPreviousLink * @return {DOMElement} Return description */ _renderPreviousLink: function() { var date = new Date(this.startDate.getTime() - BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS); var now = new Date(); var second_diff = this.startDate.getTime() - now.getTime(); var el = document.createElement('a'); //alert( 'second_diff -> ' + second_diff + ', this.startDate.getTime() -> ' + this.startDate.getTime() + ', now.getTime() -> ' + now.getTime() ); var periodOffsets = getPeriodOffset(this.startDate, 'week') - getPeriodOffset(now, 'week'); //alert( periodOffsets ); if ( periodOffsets >= 1 && periodOffsets <= 2 ) { el.className = 'previous'; el.href = '?date=' + date.toDateString(); } else { el.className = 'previous-disabled'; el.href = '#'; } el.appendChild(document.createTextNode('Previous Week')); return el; }, /** * Description of method * * @method _renderNextLink * @return {DOMElement} Return description */ _renderNextLink: function() { var date = new Date(this.startDate.getTime() + BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS); var now = new Date(); var second_diff = date.getTime() - now.getTime(); var el = document.createElement('a'); //alert( 'second_diff -> ' + second_diff + ', BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS -> ' + BaseCalendarApp.ONE_WEEK_IN_MILLISECONDS ); var periodOffsets = getPeriodOffset(this.startDate, 'week') - getPeriodOffset(now, 'week'); //alert( periodOffsets ); if ( periodOffsets >= 0 && periodOffsets <= 1 ) { el.className = 'next'; el.href = '?date=' + date.toDateString(); } else { el.className = 'next-disabled'; el.href = '#'; } el.appendChild(document.createTextNode('Next Week')); return el; }, /** * Description of method * * @method _renderWeekOfElement * @return {DOMElement} Return description */ _renderWeekOfElement: function() { var el = document.createElement('div'); el.className = 'dtrange vevent'; el.appendChild(document.createTextNode('Week of ')); el.appendChild(this._renderDtElement(this.startDate, 'dtstart')); el.appendChild(document.createTextNode(' - ')); el.appendChild(this._renderDtElement(this.endDate,'dtend')); return el; } }); /** * Add WeeklyCalendarApp to EWPicks namespace */ EWPicks.WhatsNewWeeklyCalendarApp = WhatsNewWeeklyCalendarApp; /** ==================================================================== **/ /** * Description of method * * @method GoogleCalendarEventFeedConfig * @param {String} id Parameter description * @param {String} name Parameter description * @param {String} url Parameter description * @return {Object} Instance of GoogleCalendarEventFeedConfig */ var GoogleCalendarEventFeedConfig = function(id, name, url) { this.id = id; this.name = name; this.url = url; }; /** * Add GoogleCalendarEventFeedConfig to EWPicks namespace */ EWPicks.GoogleCalendarEventFeedConfig = GoogleCalendarEventFeedConfig; /** ==================================================================== **/ })(); EWPicks.DAILY_URL = '/ew/picks/0,,,00.html'; // alert( 'Picks JS PROD config loading...' ); var GoogleCalendarEventFeedConfig = EWPicks.GoogleCalendarEventFeedConfig; /* * EW Picks feed configurations */ EWPicks.MoviesCalendarFeed = new GoogleCalendarEventFeedConfig( 'dk7ni186hjl08opf9pv5673o78@group.calendar.google.com', 'Movies', '/ew/picks/movies/0,,,00.html' ); EWPicks.TVCalendarFeed = new GoogleCalendarEventFeedConfig( 'g25q1f38jj5au1ie7i72jqkqjk@group.calendar.google.com', 'TV', '/ew/picks/tv/0,,,00.html' ); EWPicks.MusicCalendarFeed = new GoogleCalendarEventFeedConfig( '399e1ajetvqfocpqta796fn3as@group.calendar.google.com', 'Music', '/ew/picks/music/0,,,00.html' ); EWPicks.BooksCalendarFeed = new GoogleCalendarEventFeedConfig( 'vq165ao5ta8vbvpeh22ta0ql5s@group.calendar.google.com', 'Books', '/ew/picks/books/0,,,00.html' ); EWPicks.TechCalendarFeed = new GoogleCalendarEventFeedConfig( '3l3l739du9ceins3ip56osun8g@group.calendar.google.com', 'Tech', '/ew/picks/tech/0,,,00.html' ); /* * EW What's New feed configurations */ EWPicks.WhatsNewBooks = new GoogleCalendarEventFeedConfig( 'l038ltlou57a72l43lmddpqn94@group.calendar.google.com', "What's New: Books", '/ew/picks/also-this-week/0,,,00.html#books' ); EWPicks.WhatsNewTech = new GoogleCalendarEventFeedConfig( '6mcof1kef01p6jp0mr37i8fth8@group.calendar.google.com', "What's New: Tech", '/ew/picks/also-this-week/0,,,00.html#tech' ); EWPicks.WhatsNewMovies = new GoogleCalendarEventFeedConfig( 'm1hrjnvm0i7d95ehipi0046h30@group.calendar.google.com', "What's New: Movies", '/ew/picks/also-this-week/0,,,00.html#movies' ); EWPicks.WhatsNewMusic = new GoogleCalendarEventFeedConfig( 'dq4emhgsg7e59r4h7h4023vm4g@group.calendar.google.com', "What's New: Music", '/ew/picks/also-this-week/0,,,00.html#music' ); EWPicks.WhatsNewTV = new GoogleCalendarEventFeedConfig( 'riaob2rvob17flselb8r2jt5rk@group.calendar.google.com', "What's New: TV", '/ew/picks/also-this-week/0,,,00.html#tv' ); EWPicks.WhatsNewDVD = new GoogleCalendarEventFeedConfig( '162fqmpr8num14mof0rir75bks@group.calendar.google.com', "What's New: DVD", '/ew/picks/also-this-week/0,,,00.html#dvd' ); /* * Looking Ahead configuration */ EWPicks.LookingAhead = new GoogleCalendarEventFeedConfig( '74n5gsne9fbjfo5coh9tr2gnok@group.calendar.google.com', "What's New: Looking Ahead", '' );