/* EventCalendar. Copyright (C) 2005-2007, Alex Tingle. $Revision: 284 $
* This file is licensed under the GNU GPL. See LICENSE file for details.
*/
// Set in HTML file:
// var ec3.start_of_week
// var ec3.month_of_year
// var ec3.month_abbrev
// var ec3.myfiles
// var ec3.home
// var ec3.hide_logo
// var ec3.viewpostsfor
/** Register an onload function. */
function WindowOnload(f)
{
var prev=window.onload;
window.onload=function(){ if(prev)prev(); f(); }
}
// namespace
function ec3()
{
WindowOnload( function()
{
// Overwrite the href links in ec3_prev & ec3_next to activate EC3.
var prev=document.getElementById('ec3_prev');
var next=document.getElementById('ec3_next');
if(prev && next)
{
// Check for cat limit in month link
var xCat=new RegExp('&cat=[0-9]+$');
var match=xCat.exec(prev.href);
if(match)
ec3.catClause=match[0];
// Replace links
prev.href='javascript:ec3.go_prev()';
next.href='javascript:ec3.go_next()';
// Pre-load image.
ec3.imgwait=new Image(14,14);
ec3.imgwait.src=ec3.myfiles+'/ec_load.gif';
// Convert strings from PHP into Unicode
ec3.viewpostsfor=unencode(ec3.viewpostsfor);
for(var i=0; i<ec3.month_of_year.length; i++)
ec3.month_of_year[i]=unencode(ec3.month_of_year[i]);
for(var j=0; j<ec3.month_abbrev.length; j++)
ec3.month_abbrev[j]=unencode(ec3.month_abbrev[j]);
}
} );
/** Converts HTML encoded text (e.g. "© Copyright") into Unicode. */
function unencode(text)
{
if(!ec3.unencodeDiv)
ec3.unencodeDiv=document.createElement('div');
ec3.unencodeDiv.innerHTML=text;
return (ec3.unencodeDiv.innerText || ec3.unencodeDiv.firstChild.nodeValue);
}
function get_child_by_tag_name(element,tag_name)
{
var results=element.getElementsByTagName(tag_name);
if(results)
for(var i=0; i<results.length; i++)
if(results[i].parentNode==element)
return results[i];
return 0;
}
ec3.get_child_by_tag_name=get_child_by_tag_name;
function calc_day_id(day_num,month_num,year_num)
{
if(ec3.today_day_num==day_num &&
ec3.today_month_num==month_num &&
ec3.today_year_num==year_num)
{
return 'today';
}
else
{
return 'ec3_'+year_num+'_'+month_num+'_'+day_num;
}
}
/** Replaces the caption and tbody in table to be the specified year/month. */
function create_calendar(table_cal,month_num,year_num)
{
// Take a deep copy of the current calendar.
var table=table_cal.cloneNode(1);
// Calculate the zero-based month_num
var month_num0=month_num-1;
// Set the new caption
var caption=get_child_by_tag_name(table,'caption');
if(caption)
{
var c=get_child_by_tag_name(caption,'a');
var caption_text=ec3.month_of_year[month_num0] + ' ' + year_num;
if(c && c.firstChild && c.firstChild.nodeType==ec3.TEXT_NODE )
{
if(month_num<10)
{
c.href=ec3.home+'/?m='+year_num+'0'+month_num;
}
else
{
c.href=ec3.home+'/?m='+year_num+month_num;
}
if(ec3.catClause)
c.href+=ec3.catClause; // Copy cat' limit from original month link.
c.title=ec3.viewpostsfor;
c.title=c.title.replace(/%1\$s/,ec3.month_of_year[month_num0]);
c.title=c.title.replace(/%2\$s/,year_num);
c.firstChild.data=caption_text;
}
}
if(caption && caption.firstChild && caption.firstChild.nodeType==ec3.TEXT_NODE)
caption.firstChild.data=ec3.month_of_year[month_num0] + ' ' + year_num;
var tbody=get_child_by_tag_name(table,'tbody');
// Remove all children from the table body
while(tbody.lastChild)
tbody.removeChild(tbody.lastChild);
// Make a new calendar.
var date=new Date(year_num,month_num0,1, 12,00,00);
var tr=document.createElement('tr');
var td,div;
tbody.appendChild(tr);
var day_count=0
var col=0;
while(date.getMonth()==month_num0 && day_count<40)
{
var day=(date.getDay()+7-ec3.start_of_week)%7;
if(col>6)
{
tr=document.createElement('tr');
tbody.appendChild(tr);
col=0;
}
if(col<day)
{
// insert padding
td=document.createElement('td');
td.colSpan=day-col;
td.className='pad';
tr.appendChild(td);
col=day;
}
// insert day
td=document.createElement('td');
td.appendChild(document.createTextNode(date.getDate()));
td.id=calc_day_id(date.getDate(),month_num,year_num);
tr.appendChild(td);
col++;
day_count++;
date.setDate(date.getDate()+1);
}
// insert padding
if(col<7)
{
td=document.createElement('td');
td.colSpan=7-col;
td.className='pad';
tr.appendChild(td);
}
// add the 'dog'
if((7-col)>1 && !ec3.hide_logo)
{
a=document.createElement('a');
a.href='http://blog.firetree.net/?ec3_version='+ec3.version;
a.title='Event Calendar '+ec3.version;
td.style.verticalAlign='bottom';
td.appendChild(a);
div=document.createElement('div');
div.className='ec3_ec';
div.align='right'; // keeps IE happy
a.appendChild(div);
}
// set table's element id
table.id='ec3_'+year_num+'_'+month_num;
return table;
} // end create_calendar()
/** Dispatch an XMLHttpRequest for a month of calendar entries. */
function loadDates(month_num,year_num)
{
var req=new XMLHttpRequest();
if(req)
{
ec3.reqs.push(req);
req.onreadystatechange=process_xml;
req.open("GET",
ec3.home+'/?ec3_xml='+year_num+'_'+month_num,true);
set_spinner(1);
req.send(null);
}
}
/** Obtain an array of all the calendar tables. */
function get_calendars()
{
var div=document.getElementById('wp-calendar');
var result=new Array();
for(var i=0; i<div.childNodes.length; i++)
{
var c=div.childNodes[i];
if(c.id && c.id.search('ec3_[0-9]')==0 && c.style.display!='none')
result.push(div.childNodes[i]);
}
if(result.length>0)
return result;
else
return 0;
}
ec3.get_calendars=get_calendars;
/** Changes the link text in the forward and backwards buttons.
* Parameters are the 0-based month numbers. */
function rewrite_controls(prev_month0,next_month0)
{
var prev=document.getElementById('ec3_prev');
if(prev && prev.firstChild && prev.firstChild.nodeType==ec3.TEXT_NODE)
prev.firstChild.data='\u00ab\u00a0'+ec3.month_abbrev[prev_month0%12];
var next=document.getElementById('ec3_next');
if(next && next.firstChild && next.firstChild.nodeType==ec3.TEXT_NODE)
next.firstChild.data=ec3.month_abbrev[next_month0%12]+'\u00a0\u00bb';
}
/** Turn the busy spinner on or off. */
function set_spinner(on)
{
var spinner=document.getElementById('ec3_spinner');
var publish=document.getElementById('ec3_publish');
if(spinner)
{
if(on)
{
spinner.style.display='inline';
if(publish)
publish.style.display='none';
}
else
{
spinner.style.display='none';
if(publish)
publish.style.display='inline';
}
}
}
/** Called when the user clicks the 'previous month' button. */
function go_prev()
{
var calendars=get_calendars();
if(!calendars)
return;
var pn=calendars[0].parentNode;
// calculate date of new calendar
var id_array=calendars[0].id.split('_');
if(id_array.length<3)
return;
var year_num=parseInt(id_array[1]);
var month_num=parseInt(id_array[2])-1;
if(month_num==0)
{
month_num=12;
year_num--;
}
// Get new calendar
var newcal=document.getElementById('ec3_'+year_num+'_'+month_num);
if(newcal)
{
// Add in the new first calendar
newcal.style.display=ec3.calendar_display;
}
else
{
newcal=create_calendar(calendars[0],month_num,year_num);
pn.insertBefore( newcal, calendars[0] );
loadDates(month_num,year_num);
}
// Hide the last calendar
ec3.calendar_display=calendars[calendars.length-1].style.display;
calendars[calendars.length-1].style.display='none';
// Re-write the forward & back buttons.
rewrite_controls(month_num+10,month_num+calendars.length-1);
}
ec3.go_prev=go_prev;
/** Called when the user clicks the 'next month' button. */
function go_next()
{
var calendars=get_calendars();
if(!calendars)
return;
var pn=calendars[0].parentNode;
var last_cal=calendars[calendars.length-1];
// calculate date of new calendar
var id_array=last_cal.id.split('_');
if(id_array.length<3)
return;
var year_num=parseInt(id_array[1]);
var month_num=1+parseInt(id_array[2]);
if(month_num==13)
{
month_num=1;
year_num++;
}
// Get new calendar
var newcal=document.getElementById('ec3_'+year_num+'_'+month_num);
if(newcal)
{
// Add in the new last calendar
newcal.style.display=ec3.calendar_display;
}
else
{
newcal=create_calendar(calendars[0],month_num,year_num);
if(last_cal.nextSibling)
pn.insertBefore(newcal,last_cal.nextSibling);
else
pn.appendChild(newcal);
loadDates(month_num,year_num);
}
// Hide the first calendar
ec3.calendar_display=calendars[0].style.display;
calendars[0].style.display='none';
// Re-write the forward & back buttons.
rewrite_controls(month_num-calendars.length+11,month_num);
}
ec3.go_next=go_next;
/** Triggered when the XML load is complete. Checks that load is OK, and then
* updates calendar days. */
function process_xml()
{
var busy=0;
for(var i=0; i<ec3.reqs.length; i++)
{
var req=ec3.reqs[i];
if(req)
{
if(req.readyState==4)
{
ec3.reqs[i]=0;
if(req.status==200)
update_days(req.responseXML.documentElement);
}
else
busy=1;
}
}
if(!busy)
{
// Remove old requests.
while(ec3.reqs.shift && ec3.reqs.length && !ec3.reqs[0])
ec3.reqs.shift();
set_spinner(0);
}
}
/** Adds links to the calendar for each day listed in the XML. */
function update_days(month_xml)
{
var days=month_xml.getElementsByTagName('day');
if(!days)
return;
for(var i=0; i<days.length; i++)
{
var td=document.getElementById(days[i].getAttribute('id'));
if(td && td.firstChild && td.firstChild.nodeType==ec3.TEXT_NODE)
{
td.className='ec3_postday';
var txt=td.removeChild(td.firstChild);
var a=document.createElement('a');
a.href=days[i].getAttribute('link');
a.title=days[i].getAttribute('titles');
if(days[i].getAttribute('is_event'))
{
td.className+=' ec3_eventday';
a.className='eventday';
}
a.appendChild(txt);
td.appendChild(a);
}
}
if(typeof ec3_Popup != 'undefined')
{
var month=
document.getElementById(month_xml.childNodes[0].getAttribute('id'));
if(month)
ec3_Popup.add_tbody( get_child_by_tag_name(month,'tbody') );
}
}
} // end namespace ec3
// Export public functions from ec3 namespace.
ec3();
// Set up static variables in namespace 'ec3'.
// Get today's date.
// Note - DO THIS ONCE, so that the value of today never changes!
ec3.today=new Date();
ec3.today_day_num=ec3.today.getDate();
ec3.today_month_num=1+ec3.today.getMonth();
ec3.today_year_num=ec3.today.getFullYear();
// Holds ongoing XmlHttp requests.
ec3.reqs=new Array();
ec3.ELEMENT_NODE=1;
ec3.TEXT_NODE=3;
ec3.version='3.1.4';