|
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. */ |
|
15 function WindowOnload(f) |
|
16 { |
|
17 var prev=window.onload; |
|
18 window.onload=function(){ if(prev)prev(); f(); } |
|
19 } |
|
20 |
|
21 // namespace |
|
22 function 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. |
|
422 ec3(); |
|
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! |
|
428 ec3.today=new Date(); |
|
429 ec3.today_day_num=ec3.today.getDate(); |
|
430 ec3.today_month_num=1+ec3.today.getMonth(); |
|
431 ec3.today_year_num=ec3.today.getFullYear(); |
|
432 |
|
433 // Holds ongoing XmlHttp requests. |
|
434 ec3.reqs=new Array(); |
|
435 |
|
436 ec3.ELEMENT_NODE=1; |
|
437 ec3.TEXT_NODE=3; |
|
438 |
|
439 ec3.version='3.1.4'; |