1/* EventCalendar. Copyright (C) 2005-2007, Alex Tingle. $Revision: 284 $ 2 * This file is licensed under the GNU GPL. See LICENSE file for details. 3 */ 4 5// Set in HTML file: 6// var ec3.start_of_week 7// var ec3.month_of_year 8// var ec3.month_abbrev 9// var ec3.myfiles 10// var ec3.home 11// var ec3.hide_logo 12// var ec3.viewpostsfor 13 14/** Register an onload function. */ 15function WindowOnload(f) 16{ 17 var prev=window.onload; 18 window.onload=function(){ if(prev)prev(); f(); } 19} 20 21// namespace 22function ec3() 23{ 24 WindowOnload( function() 25 { 26 // Overwrite the href links in ec3_prev & ec3_next to activate EC3. 27 var prev=document.getElementById('ec3_prev'); 28 var next=document.getElementById('ec3_next'); 29 if(prev && next) 30 { 31 // Check for cat limit in month link 32 var xCat=new RegExp('&cat=[0-9]+$'); 33 var match=xCat.exec(prev.href); 34 if(match) 35 ec3.catClause=match[0]; 36 // Replace links 37 prev.href='javascript:ec3.go_prev()'; 38 next.href='javascript:ec3.go_next()'; 39 // Pre-load image. 40 ec3.imgwait=new Image(14,14); 41 ec3.imgwait.src=ec3.myfiles+'/ec_load.gif'; 42 // Convert strings from PHP into Unicode 43 ec3.viewpostsfor=unencode(ec3.viewpostsfor); 44 for(var i=0; i<ec3.month_of_year.length; i++) 45 ec3.month_of_year[i]=unencode(ec3.month_of_year[i]); 46 for(var j=0; j<ec3.month_abbrev.length; j++) 47 ec3.month_abbrev[j]=unencode(ec3.month_abbrev[j]); 48 } 49 } ); 50 51 /** Converts HTML encoded text (e.g. "© Copyright") into Unicode. */ 52 function unencode(text) 53 { 54 if(!ec3.unencodeDiv) 55 ec3.unencodeDiv=document.createElement('div'); 56 ec3.unencodeDiv.innerHTML=text; 57 return (ec3.unencodeDiv.innerText || ec3.unencodeDiv.firstChild.nodeValue); 58 } 59 60 function get_child_by_tag_name(element,tag_name) 61 { 62 var results=element.getElementsByTagName(tag_name); 63 if(results) 64 for(var i=0; i<results.length; i++) 65 if(results[i].parentNode==element) 66 return results[i]; 67 return 0; 68 } 69 ec3.get_child_by_tag_name=get_child_by_tag_name; 70 71 72 function calc_day_id(day_num,month_num,year_num) 73 { 74 if(ec3.today_day_num==day_num && 75 ec3.today_month_num==month_num && 76 ec3.today_year_num==year_num) 77 { 78 return 'today'; 79 } 80 else 81 { 82 return 'ec3_'+year_num+'_'+month_num+'_'+day_num; 83 } 84 } 85 86 87 /** Replaces the caption and tbody in table to be the specified year/month. */ 88 function create_calendar(table_cal,month_num,year_num) 89 { 90 // Take a deep copy of the current calendar. 91 var table=table_cal.cloneNode(1); 92 93 // Calculate the zero-based month_num 94 var month_num0=month_num-1; 95 96 // Set the new caption 97 var caption=get_child_by_tag_name(table,'caption'); 98 if(caption) 99 { 100 var c=get_child_by_tag_name(caption,'a'); 101 var caption_text=ec3.month_of_year[month_num0] + ' ' + year_num; 102 if(c && c.firstChild && c.firstChild.nodeType==ec3.TEXT_NODE ) 103 { 104 if(month_num<10) 105 { 106 c.href=ec3.home+'/?m='+year_num+'0'+month_num; 107 } 108 else 109 { 110 c.href=ec3.home+'/?m='+year_num+month_num; 111 } 112 if(ec3.catClause) 113 c.href+=ec3.catClause; // Copy cat' limit from original month link. 114 c.title=ec3.viewpostsfor; 115 c.title=c.title.replace(/%1\$s/,ec3.month_of_year[month_num0]); 116 c.title=c.title.replace(/%2\$s/,year_num); 117 c.firstChild.data=caption_text; 118 } 119 } 120 121 if(caption && caption.firstChild && caption.firstChild.nodeType==ec3.TEXT_NODE) 122 caption.firstChild.data=ec3.month_of_year[month_num0] + ' ' + year_num; 123 124 var tbody=get_child_by_tag_name(table,'tbody'); 125 126 // Remove all children from the table body 127 while(tbody.lastChild) 128 tbody.removeChild(tbody.lastChild); 129 130 // Make a new calendar. 131 var date=new Date(year_num,month_num0,1, 12,00,00); 132 133 var tr=document.createElement('tr'); 134 var td,div; 135 tbody.appendChild(tr); 136 var day_count=0 137 var col=0; 138 while(date.getMonth()==month_num0 && day_count<40) 139 { 140 var day=(date.getDay()+7-ec3.start_of_week)%7; 141 if(col>6) 142 { 143 tr=document.createElement('tr'); 144 tbody.appendChild(tr); 145 col=0; 146 } 147 if(col<day) 148 { 149 // insert padding 150 td=document.createElement('td'); 151 td.colSpan=day-col; 152 td.className='pad'; 153 tr.appendChild(td); 154 col=day; 155 } 156 // insert day 157 td=document.createElement('td'); 158 td.appendChild(document.createTextNode(date.getDate())); 159 td.id=calc_day_id(date.getDate(),month_num,year_num); 160 tr.appendChild(td); 161 col++; 162 day_count++; 163 date.setDate(date.getDate()+1); 164 } 165 // insert padding 166 if(col<7) 167 { 168 td=document.createElement('td'); 169 td.colSpan=7-col; 170 td.className='pad'; 171 tr.appendChild(td); 172 } 173 174 // add the 'dog' 175 if((7-col)>1 && !ec3.hide_logo) 176 { 177 a=document.createElement('a'); 178 a.href='http://blog.firetree.net/?ec3_version='+ec3.version; 179 a.title='Event Calendar '+ec3.version; 180 td.style.verticalAlign='bottom'; 181 td.appendChild(a); 182 div=document.createElement('div'); 183 div.className='ec3_ec'; 184 div.align='right'; // keeps IE happy 185 a.appendChild(div); 186 } 187 188 // set table's element id
189 table.id='ec3_'+year_num+'_'+month_num; 190 191 return table; 192 } // end create_calendar() 193 194 195 /** Dispatch an XMLHttpRequest for a month of calendar entries. */ 196 function loadDates(month_num,year_num) 197 { 198 var req=new XMLHttpRequest(); 199 if(req) 200 { 201 ec3.reqs.push(req); 202 req.onreadystatechange=process_xml; 203 req.open("GET", 204 ec3.home+'/?ec3_xml='+year_num+'_'+month_num,true); 205 set_spinner(1); 206 req.send(null); 207 } 208 } 209 210 211 /** Obtain an array of all the calendar tables. */ 212 function get_calendars() 213 { 214 var div=document.getElementById('wp-calendar'); 215 var result=new Array(); 216 for(var i=0; i<div.childNodes.length; i++) 217 { 218 var c=div.childNodes[i]; 219 if(c.id && c.id.search('ec3_[0-9]')==0 && c.style.display!='none') 220 result.push(div.childNodes[i]); 221 } 222 if(result.length>0) 223 return result; 224 else 225 return 0; 226 } 227 ec3.get_calendars=get_calendars; 228 229 230 /** Changes the link text in the forward and backwards buttons. 231 * Parameters are the 0-based month numbers. */ 232 function rewrite_controls(prev_month0,next_month0) 233 { 234 var prev=document.getElementById('ec3_prev'); 235 if(prev && prev.firstChild && prev.firstChild.nodeType==ec3.TEXT_NODE) 236 prev.firstChild.data='\u00ab\u00a0'+ec3.month_abbrev[prev_month0%12]; 237 var next=document.getElementById('ec3_next'); 238 if(next && next.firstChild && next.firstChild.nodeType==ec3.TEXT_NODE) 239 next.firstChild.data=ec3.month_abbrev[next_month0%12]+'\u00a0\u00bb'; 240 } 241 242 243 /** Turn the busy spinner on or off. */ 244 function set_spinner(on) 245 { 246 var spinner=document.getElementById('ec3_spinner'); 247 var publish=document.getElementById('ec3_publish'); 248 if(spinner) 249 { 250 if(on) 251 { 252 spinner.style.display='inline'; 253 if(publish) 254 publish.style.display='none'; 255 } 256 else 257 { 258 spinner.style.display='none'; 259 if(publish) 260 publish.style.display='inline'; 261 } 262 } 263 } 264 265 266 /** Called when the user clicks the 'previous month' button. */ 267 function go_prev() 268 { 269 var calendars=get_calendars(); 270 if(!calendars) 271 return; 272 var pn=calendars[0].parentNode; 273 274 // calculate date of new calendar 275 var id_array=calendars[0].id.split('_'); 276 if(id_array.length<3) 277 return; 278 var year_num=parseInt(id_array[1]); 279 var month_num=parseInt(id_array[2])-1; 280 if(month_num==0) 281 { 282 month_num=12; 283 year_num--; 284 } 285 // Get new calendar 286 var newcal=document.getElementById('ec3_'+year_num+'_'+month_num); 287 if(newcal) 288 { 289 // Add in the new first calendar 290 newcal.style.display=ec3.calendar_display; 291 } 292 else 293 { 294 newcal=create_calendar(calendars[0],month_num,year_num); 295 pn.insertBefore( newcal, calendars[0] ); 296 loadDates(month_num,year_num); 297 } 298 // Hide the last calendar 299 ec3.calendar_display=calendars[calendars.length-1].style.display; 300 calendars[calendars.length-1].style.display='none'; 301 302 // Re-write the forward & back buttons. 303 rewrite_controls(month_num+10,month_num+calendars.length-1); 304 } 305 ec3.go_prev=go_prev; 306 307 308 /** Called when the user clicks the 'next month' button. */ 309 function go_next() 310 { 311 var calendars=get_calendars(); 312 if(!calendars) 313 return; 314 var pn=calendars[0].parentNode; 315 var last_cal=calendars[calendars.length-1]; 316 317 // calculate date of new calendar 318 var id_array=last_cal.id.split('_'); 319 if(id_array.length<3) 320 return; 321 var year_num=parseInt(id_array[1]); 322 var month_num=1+parseInt(id_array[2]); 323 if(month_num==13) 324 { 325 month_num=1; 326 year_num++; 327 } 328 // Get new calendar 329 var newcal=document.getElementById('ec3_'+year_num+'_'+month_num); 330 if(newcal) 331 { 332 // Add in the new last calendar 333 newcal.style.display=ec3.calendar_display; 334 } 335 else 336 { 337 newcal=create_calendar(calendars[0],month_num,year_num); 338 if(last_cal.nextSibling) 339 pn.insertBefore(newcal,last_cal.nextSibling); 340 else 341 pn.appendChild(newcal);
342 loadDates(month_num,year_num); 343 } 344 // Hide the first calendar 345 ec3.calendar_display=calendars[0].style.display; 346 calendars[0].style.display='none'; 347 348 // Re-write the forward & back buttons. 349 rewrite_controls(month_num-calendars.length+11,month_num); 350 } 351 ec3.go_next=go_next; 352 353 354 /** Triggered when the XML load is complete. Checks that load is OK, and then 355 * updates calendar days. */ 356 function process_xml() 357 { 358 var busy=0; 359 for(var i=0; i<ec3.reqs.length; i++) 360 { 361 var req=ec3.reqs[i]; 362 if(req) 363 { 364 if(req.readyState==4) 365 { 366 ec3.reqs[i]=0; 367 if(req.status==200) 368 update_days(req.responseXML.documentElement); 369 } 370 else 371 busy=1; 372 } 373 } 374 if(!busy) 375 { 376 // Remove old requests. 377 while(ec3.reqs.shift && ec3.reqs.length && !ec3.reqs[0]) 378 ec3.reqs.shift(); 379 set_spinner(0); 380 } 381 } 382 383 384 /** Adds links to the calendar for each day listed in the XML. */ 385 function update_days(month_xml) 386 { 387 var days=month_xml.getElementsByTagName('day'); 388 if(!days) 389 return; 390 for(var i=0; i<days.length; i++) 391 { 392 var td=document.getElementById(days[i].getAttribute('id')); 393 if(td && td.firstChild && td.firstChild.nodeType==ec3.TEXT_NODE) 394 { 395 td.className='ec3_postday'; 396 var txt=td.removeChild(td.firstChild); 397 var a=document.createElement('a'); 398 a.href=days[i].getAttribute('link'); 399 a.title=days[i].getAttribute('titles'); 400 if(days[i].getAttribute('is_event')) 401 { 402 td.className+=' ec3_eventday'; 403 a.className='eventday'; 404 } 405 a.appendChild(txt); 406 td.appendChild(a); 407 } 408 } 409 if(typeof ec3_Popup != 'undefined') 410 { 411 var month= 412 document.getElementById(month_xml.childNodes[0].getAttribute('id')); 413 if(month) 414 ec3_Popup.add_tbody( get_child_by_tag_name(month,'tbody') ); 415 } 416 } 417 418 419} // end namespace ec3 420 421// Export public functions from ec3 namespace. 422ec3(); 423 424// Set up static variables in namespace 'ec3'. 425 426// Get today's date. 427// Note - DO THIS ONCE, so that the value of today never changes! 428ec3.today=new Date(); 429ec3.today_day_num=ec3.today.getDate(); 430ec3.today_month_num=1+ec3.today.getMonth(); 431ec3.today_year_num=ec3.today.getFullYear(); 432 433// Holds ongoing XmlHttp requests. 434ec3.reqs=new Array(); 435 436ec3.ELEMENT_NODE=1; 437ec3.TEXT_NODE=3; 438 439ec3.version='3.1.4';
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.