Mercurial > hg > Applications > o2s5
comparison ui/core/slides.js @ 1:450bcedf4ed4
multiple theme
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 23 Sep 2011 23:05:08 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:b0c6281822f5 | 1:450bcedf4ed4 |
---|---|
1 // S5 v1.2a2 slides.js -- released into the Public Domain | |
2 // Many modifications by Jacques Distler to allow operation as real XHTML. | |
3 // | |
4 // Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information | |
5 // about all the wonderful and talented contributors to this code! | |
6 | |
7 var undef; | |
8 var slideCSS = ''; | |
9 var snum = 0; | |
10 var smax = 1; | |
11 var incpos = 0; | |
12 var number = undef; | |
13 var s5mode = true; | |
14 var defaultView = 'slideshow'; | |
15 var controlVis = 'visible'; | |
16 | |
17 var s5NotesWindow; | |
18 var s5NotesWindowLoaded = false; | |
19 var previousSlide = 0; | |
20 var presentationStart = new Date(); | |
21 var slideStart = new Date(); | |
22 | |
23 var countdown = { | |
24 timer: 0, | |
25 state: 'pause', | |
26 start: new Date(), | |
27 end: 0, | |
28 remaining: 0 | |
29 }; | |
30 | |
31 | |
32 var isIE = navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.indexOf('Opera') < 1 ? 1 : 0; | |
33 var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0; | |
34 var isSa = navigator.userAgent.indexOf('Safari') > -1 ? 1 : 0; | |
35 var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0; | |
36 | |
37 function hasClass(object, className) { | |
38 if (!object.className ||!object.getAttribute('class')) return false; | |
39 return (object.getAttribute('class').search('(^|\\s)' + className + '(\\s|$)') != -1); | |
40 } | |
41 | |
42 function hasValue(object, value) { | |
43 if (!object) return false; | |
44 return (object.search('(^|\\s)' + value + '(\\s|$)') != -1); | |
45 } | |
46 | |
47 function removeClass(object,className) { | |
48 if (!object || !hasClass(object,className)) return; | |
49 object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2); | |
50 } | |
51 | |
52 function addClass(object,className) { | |
53 if (!object || hasClass(object, className)) return; | |
54 if (object.className) { | |
55 object.className += ' '+className; | |
56 } else { | |
57 object.className = className; | |
58 } | |
59 } | |
60 | |
61 function GetElementsWithClassName(elementName,className) { | |
62 var allElements = document.getElementsByTagName(elementName); | |
63 var elemColl = new Array(); | |
64 for (var i = 0; i< allElements.length; i++) { | |
65 if (hasClass(allElements[i], className)) { | |
66 elemColl[elemColl.length] = allElements[i]; | |
67 } | |
68 } | |
69 return elemColl; | |
70 } | |
71 | |
72 function isParentOrSelf(element, id) { | |
73 if (element == null || element.nodeName=='body') return false; | |
74 else if (element.id == id) return true; | |
75 else return isParentOrSelf(element.parentNode, id); | |
76 } | |
77 | |
78 function nodeValue(node) { | |
79 var result = ""; | |
80 if (node.nodeType == 1) { | |
81 var children = node.childNodes; | |
82 for (var i = 0; i < children.length; ++i) { | |
83 result += nodeValue(children[i]); | |
84 } | |
85 } | |
86 else if (node.nodeType == 3) { | |
87 result = node.nodeValue; | |
88 } | |
89 return(result); | |
90 } | |
91 | |
92 function slideLabel() { | |
93 var slideColl = GetElementsWithClassName('*','slide'); | |
94 var list = document.getElementById('jumplist'); | |
95 smax = slideColl.length; | |
96 for (var n = 0; n < smax; n++) { | |
97 var obj = slideColl[n]; | |
98 | |
99 var did = 'slide' + n.toString(); | |
100 obj.setAttribute('id',did); | |
101 | |
102 // if (isOp) continue; // Opera fix (hallvord) | |
103 | |
104 var otext = ''; | |
105 var menu = obj.firstChild; | |
106 if (!menu) continue; // to cope with empty slides | |
107 while (menu && menu.nodeType == 3) { | |
108 menu = menu.nextSibling; | |
109 } | |
110 if (!menu) continue; // to cope with slides with only text nodes | |
111 | |
112 var menunodes = menu.childNodes; | |
113 for (var o = 0; o < menunodes.length; o++) { | |
114 otext += nodeValue(menunodes[o]); | |
115 } | |
116 if (isSa) { | |
117 var option = createElement('option'); | |
118 option.setAttribute('value', n); | |
119 option.appendChild(document.createTextNode(n + ' : ' + otext) ); | |
120 list.appendChild(option); | |
121 } else { | |
122 list.options[list.length] = new Option(n + ' : ' + otext, n); | |
123 } | |
124 } | |
125 } | |
126 | |
127 function currentSlide() { | |
128 var cs; | |
129 if (document.getElementById) { | |
130 cs = document.getElementById('currentSlide'); | |
131 } else { | |
132 cs = document.currentSlide; | |
133 } | |
134 var plink = createElement('a'); | |
135 plink.id = 'plink'; | |
136 plink.setAttribute('href', ''); | |
137 var csHere = createElement('span'); | |
138 var csSep = createElement('span'); | |
139 var csTotal = createElement('span'); | |
140 csHere.id = 'csHere'; | |
141 csSep.id = 'csSep'; | |
142 csTotal.id = 'csTotal'; | |
143 csHere.appendChild(document.createTextNode(this.snum)); | |
144 csSep.appendChild(document.createTextNode('/')); | |
145 csTotal.appendChild(document.createTextNode(this.smax-1)); | |
146 plink.appendChild(csHere); | |
147 plink.appendChild(csSep); | |
148 plink.appendChild(csTotal); | |
149 cs.removeChild(cs.firstChild); | |
150 cs.appendChild(plink); | |
151 if (snum == 0) { | |
152 cs.style.visibility = 'hidden'; | |
153 } else { | |
154 cs.style.visibility = 'visible'; | |
155 } | |
156 } | |
157 | |
158 function go(step) { | |
159 if (document.getElementById('slideProj').disabled || step == 0) return; | |
160 var jl = document.getElementById('jumplist'); | |
161 var cid = 'slide' + snum; | |
162 var ce = document.getElementById(cid); | |
163 if (incrementals[snum].length > 0) { | |
164 for (var i = 0; i < incrementals[snum].length; i++) { | |
165 removeClass(incrementals[snum][i], 'current'); | |
166 removeClass(incrementals[snum][i], 'incremental'); | |
167 } | |
168 } | |
169 if (step != 'j') { | |
170 snum += step; | |
171 lmax = smax - 1; | |
172 if (snum > lmax) snum = lmax; | |
173 if (snum < 0) snum = 0; | |
174 } else | |
175 snum = parseInt(jl.value); | |
176 var nid = 'slide' + snum; | |
177 var ne = document.getElementById(nid); | |
178 if (!ne) { | |
179 ne = document.getElementById('slide0'); | |
180 snum = 0; | |
181 } | |
182 if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;} | |
183 if (incrementals[snum].length > 0 && incpos == 0) { | |
184 for (var i = 0; i < incrementals[snum].length; i++) { | |
185 if (hasClass(incrementals[snum][i], 'current')) | |
186 incpos = i + 1; | |
187 else | |
188 addClass(incrementals[snum][i], 'incremental'); | |
189 } | |
190 } | |
191 if (incrementals[snum].length > 0 && incpos > 0) | |
192 addClass(incrementals[snum][incpos - 1], 'current'); | |
193 if (isOp) { //hallvord | |
194 location.hash = nid; | |
195 } else { | |
196 ce.style.visibility = 'hidden'; | |
197 ne.style.visibility = 'visible'; | |
198 } // /hallvord | |
199 jl.selectedIndex = snum; | |
200 currentSlide(); | |
201 loadNote(); | |
202 permaLink(); | |
203 number = undef; | |
204 } | |
205 | |
206 function goTo(target) { | |
207 if (target >= smax || target == snum) return; | |
208 go(target - snum); | |
209 } | |
210 | |
211 function subgo(step) { | |
212 if (step > 0) { | |
213 removeClass(incrementals[snum][incpos - 1],'current'); | |
214 removeClass(incrementals[snum][incpos], 'incremental'); | |
215 addClass(incrementals[snum][incpos],'current'); | |
216 incpos++; | |
217 } else { | |
218 incpos--; | |
219 removeClass(incrementals[snum][incpos],'current'); | |
220 addClass(incrementals[snum][incpos], 'incremental'); | |
221 addClass(incrementals[snum][incpos - 1],'current'); | |
222 } | |
223 loadNote(); | |
224 } | |
225 | |
226 function toggle() { | |
227 var slideColl = GetElementsWithClassName('*','slide'); | |
228 var slides = document.getElementById('slideProj'); | |
229 var outline = document.getElementById('outlineStyle'); | |
230 if (!slides.disabled) { | |
231 slides.disabled = true; | |
232 outline.disabled = false; | |
233 s5mode = false; | |
234 fontSize('1em'); | |
235 for (var n = 0; n < smax; n++) { | |
236 var slide = slideColl[n]; | |
237 slide.style.visibility = 'visible'; | |
238 } | |
239 } else { | |
240 slides.disabled = false; | |
241 outline.disabled = true; | |
242 s5mode = true; | |
243 fontScale(); | |
244 for (var n = 0; n < smax; n++) { | |
245 var slide = slideColl[n]; | |
246 slide.style.visibility = 'hidden'; | |
247 } | |
248 slideColl[snum].style.visibility = 'visible'; | |
249 } | |
250 } | |
251 | |
252 function showHide(action) { | |
253 var obj = GetElementsWithClassName('*','hideme')[0]; | |
254 switch (action) { | |
255 case 's': obj.style.visibility = 'visible'; break; | |
256 case 'h': obj.style.visibility = 'hidden'; break; | |
257 case 'k': | |
258 if (obj.style.visibility != 'visible') { | |
259 obj.style.visibility = 'visible'; | |
260 } else { | |
261 obj.style.visibility = 'hidden'; | |
262 } | |
263 break; | |
264 } | |
265 } | |
266 | |
267 // 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/) | |
268 function keys(key) { | |
269 if (!key) { | |
270 key = event; | |
271 key.which = key.keyCode; | |
272 } | |
273 if (key.which == 84) { | |
274 toggle(); | |
275 return; | |
276 } | |
277 if (s5mode) { | |
278 switch (key.which) { | |
279 case 10: // return | |
280 case 13: // enter | |
281 if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; | |
282 if (key.target && isParentOrSelf(key.target, 'controls')) return; | |
283 if(number != undef) { | |
284 goTo(number); | |
285 break; | |
286 } | |
287 case 32: // spacebar | |
288 case 34: // page down | |
289 case 39: // rightkey | |
290 case 40: // downkey | |
291 if(number != undef) { | |
292 go(number); | |
293 } else if (!incrementals[snum] || incpos >= incrementals[snum].length) { | |
294 go(1); | |
295 } else { | |
296 subgo(1); | |
297 } | |
298 break; | |
299 case 33: // page up | |
300 case 37: // leftkey | |
301 case 38: // upkey | |
302 if(number != undef) { | |
303 go(-1 * number); | |
304 } else if (!incrementals[snum] || incpos <= 0) { | |
305 go(-1); | |
306 } else { | |
307 subgo(-1); | |
308 } | |
309 break; | |
310 case 36: // home | |
311 goTo(0); | |
312 break; | |
313 case 35: // end | |
314 goTo(smax-1); | |
315 break; | |
316 case 67: // c | |
317 showHide('k'); | |
318 break; | |
319 case 78: // n | |
320 createNotesWindow(); | |
321 break; | |
322 } | |
323 if (key.which < 48 || key.which > 57) { | |
324 number = undef; | |
325 } else { | |
326 if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; | |
327 if (key.target && isParentOrSelf(key.target, 'controls')) return; | |
328 number = (((number != undef) ? number : 0) * 10) + (key.which - 48); | |
329 } | |
330 } | |
331 return false; | |
332 } | |
333 | |
334 function clicker(e) { | |
335 number = undef; | |
336 var target; | |
337 if (window.event) { | |
338 target = window.event.srcElement; | |
339 e = window.event; | |
340 } else target = e.target; | |
341 if (target.href != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true; | |
342 if (!e.which || e.which == 1) { | |
343 if (!incrementals[snum] || incpos >= incrementals[snum].length) { | |
344 go(1); | |
345 } else { | |
346 subgo(1); | |
347 } | |
348 } | |
349 } | |
350 | |
351 function findSlide(hash) { | |
352 var target = null; | |
353 var slides = GetElementsWithClassName('*','slide'); | |
354 for (var i = 0; i < slides.length; i++) { | |
355 var targetSlide = slides[i]; | |
356 if ( (targetSlide.name && targetSlide.name == hash) | |
357 || (targetSlide.id && targetSlide.id == hash) ) { | |
358 target = targetSlide; | |
359 break; | |
360 } | |
361 } | |
362 while(target != null && target.nodeName != 'body') { | |
363 if (hasClass(target, 'slide')) { | |
364 return parseInt(target.id.slice(5)); | |
365 } | |
366 target = target.parentNode; | |
367 } | |
368 return null; | |
369 } | |
370 | |
371 function slideJump() { | |
372 if (window.location.hash == null) return; | |
373 var sregex = /^#slide(\d+)$/; | |
374 var matches = sregex.exec(window.location.hash); | |
375 var dest = null; | |
376 if (matches != null) { | |
377 dest = parseInt(matches[1]); | |
378 } else { | |
379 dest = findSlide(window.location.hash.slice(1)); | |
380 } | |
381 if (dest != null) | |
382 go(dest - snum); | |
383 } | |
384 | |
385 function fixLinks() { | |
386 var thisUri = window.location.href; | |
387 thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length); | |
388 var aelements = document.getElementsByTagName('a'); | |
389 for (var i = 0; i < aelements.length; i++) { | |
390 var a = aelements[i].href; | |
391 var slideID = a.match('\#slide[0-9]{1,2}'); | |
392 if ((slideID) && (slideID[0].slice(0,1) == '#')) { | |
393 var dest = findSlide(slideID[0].slice(1)); | |
394 if (dest != null) { | |
395 if (aelements[i].addEventListener) { | |
396 aelements[i].addEventListener("click", new Function("e", | |
397 "if (document.getElementById('slideProj').disabled) return;" + | |
398 "go("+dest+" - snum); " + | |
399 "if (e.preventDefault) e.preventDefault();"), true); | |
400 } else if (aelements[i].attachEvent) { | |
401 aelements[i].attachEvent("onclick", new Function("", | |
402 "if (document.getElementById('slideProj').disabled) return;" + | |
403 "go("+dest+" - snum); " + | |
404 "event.returnValue = false;")); | |
405 } | |
406 } | |
407 } | |
408 } | |
409 } | |
410 | |
411 function externalLinks() { | |
412 if (!document.getElementsByTagName) return; | |
413 var anchors = document.getElementsByTagName('a'); | |
414 for (var i=0; i<anchors.length; i++) { | |
415 var anchor = anchors[i]; | |
416 if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) { | |
417 anchor.target = '_blank'; | |
418 addClass(anchor,'external'); | |
419 } | |
420 } | |
421 } | |
422 | |
423 function permaLink() { | |
424 document.getElementById('plink').href = window.location.pathname + '#slide' + snum; | |
425 } | |
426 | |
427 function createControls() { | |
428 var controlsDiv = document.getElementById("controls"); | |
429 if (!controlsDiv) return; | |
430 var controlForm = createElement('form'); | |
431 controlForm.id = 'controlForm'; | |
432 controlForm.setAttribute('action', '#'); | |
433 if (controlVis == 'hidden') { | |
434 controlForm.setAttribute('onmouseover', 'showHide(\'s\');'); | |
435 controlForm.setAttribute('onmouseout', 'showHide(\'h\');'); | |
436 } | |
437 var navLinks = createElement('div'); | |
438 navLinks.id = 'navLinks'; | |
439 var showNotes = createElement('a'); | |
440 showNotes.id = 'show-notes'; | |
441 showNotes.setAttribute('accesskey', 'n'); | |
442 showNotes.setAttribute('href', 'javascript:createNotesWindow();'); | |
443 showNotes.setAttribute('title', 'Show Notes'); | |
444 showNotes.appendChild(document.createTextNode('\u2261')); | |
445 var toggle = createElement('a'); | |
446 toggle.id = 'toggle'; | |
447 toggle.setAttribute('accesskey', 't'); | |
448 toggle.setAttribute('href', 'javascript:toggle();'); | |
449 toggle.appendChild(document.createTextNode('\u00D8')); | |
450 var prev = createElement('a'); | |
451 prev.id = 'prev'; | |
452 prev.setAttribute('accesskey', 'z'); | |
453 prev.setAttribute('href', 'javascript:go(-1);'); | |
454 prev.appendChild(document.createTextNode('\u00AB')); | |
455 var next = createElement('a'); | |
456 next.id = 'next'; | |
457 next.setAttribute('accesskey', 'x'); | |
458 next.setAttribute('href', 'javascript:go(1);'); | |
459 next.appendChild(document.createTextNode('\u00BB')); | |
460 var navList = createElement('div'); | |
461 navList.id = 'navList'; | |
462 if (controlVis != 'hidden') { | |
463 navList.setAttribute('onmouseover', 'showHide(\'s\');'); | |
464 navList.setAttribute('onmouseout', 'showHide(\'h\');'); | |
465 } | |
466 var jumplist = createElement('select'); | |
467 jumplist.id = 'jumplist'; | |
468 jumplist.setAttribute('onchange', 'go(\'j\');'); | |
469 navList.appendChild(jumplist); | |
470 navLinks.appendChild(showNotes); | |
471 navLinks.appendChild(toggle); | |
472 navLinks.appendChild(prev); | |
473 navLinks.appendChild(next); | |
474 navLinks.appendChild(navList); | |
475 controlForm.appendChild(navLinks); | |
476 controlsDiv.appendChild(controlForm); | |
477 | |
478 if (controlVis == 'hidden') { | |
479 var hidden = document.getElementById('navLinks'); | |
480 } else { | |
481 var hidden = document.getElementById('jumplist'); | |
482 } | |
483 addClass(hidden,'hideme'); | |
484 } | |
485 | |
486 function fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers | |
487 if (!s5mode) return false; | |
488 var vScale = 48; // both yield 16 (the usual browser default) at 1024x768 | |
489 var hScale = 64; // perhaps should auto-calculate based on theme's declared value? | |
490 if (window.innerHeight) { | |
491 var vSize = window.innerHeight; | |
492 var hSize = window.innerWidth; | |
493 } else if (document.documentElement.clientHeight) { | |
494 var vSize = document.documentElement.clientHeight; | |
495 var hSize = document.documentElement.clientWidth; | |
496 } else if (document.body.clientHeight) { | |
497 var vSize = document.body.clientHeight; | |
498 var hSize = document.body.clientWidth; | |
499 } else { | |
500 var vSize = 700; // assuming 1024x768, minus chrome and such | |
501 var hSize = 1024; // these do not account for kiosk mode or Opera Show | |
502 } | |
503 var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale)); | |
504 fontSize(newSize + 'px'); | |
505 if (isGe) { // hack to counter incremental reflow bugs | |
506 var obj = document.getElementsByTagName('body')[0]; | |
507 obj.style.display = 'none'; | |
508 obj.style.display = 'block'; | |
509 } | |
510 } | |
511 | |
512 function fontSize(value) { | |
513 if (!(s5ss = document.getElementById('s5ss'))) { | |
514 if (!document.createStyleSheet) { | |
515 document.getElementsByTagName('head')[0].appendChild(s5ss = createElement('style')); | |
516 s5ss.setAttribute('media','screen, projection'); | |
517 s5ss.setAttribute('id','s5ss'); | |
518 } else { | |
519 document.createStyleSheet(); | |
520 document.s5ss = document.styleSheets[document.styleSheets.length - 1]; | |
521 } | |
522 } | |
523 if (!(document.s5ss && document.s5ss.addRule)) { | |
524 while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild); | |
525 s5ss.appendChild(document.createTextNode('html {font-size: ' + value + ' !important;}')); | |
526 } else { | |
527 document.s5ss.addRule('html','font-size: ' + value + ' !important;'); | |
528 } | |
529 } | |
530 | |
531 function notOperaFix() { | |
532 slideCSS = document.getElementById('slideProj').href; | |
533 var slides = document.getElementById('slideProj'); | |
534 var outline = document.getElementById('outlineStyle'); | |
535 slides.setAttribute('media','screen'); | |
536 outline.disabled = true; | |
537 if (isGe) { | |
538 slides.setAttribute('href',slideCSS); // Gecko fix | |
539 } | |
540 if (isIE && document.styleSheets && document.styleSheets[0]) { | |
541 document.styleSheets[0].addRule('img', 'behavior: url(../../s5/ui/default/iepngfix.htc)'); | |
542 document.styleSheets[0].addRule('div', 'behavior: url(../../s5/ui/default/iepngfix.htc)'); | |
543 document.styleSheets[0].addRule('.slide', 'behavior: url(../../s5/ui/default/iepngfix.htc)'); | |
544 } | |
545 } | |
546 | |
547 function getIncrementals(obj) { | |
548 var incrementals = new Array(); | |
549 if (!obj) | |
550 return incrementals; | |
551 var children = obj.childNodes; | |
552 for (var i = 0; i < children.length; i++) { | |
553 var child = children[i]; | |
554 if (hasClass(child, 'incremental')) { | |
555 if (child.nodeName == 'ol' || child.nodeName == 'ul' || child.nodeName == 'dl') { | |
556 removeClass(child, 'incremental'); | |
557 for (var j = 0; j < child.childNodes.length; j++) { | |
558 if (child.childNodes[j].nodeType == 1) { | |
559 addClass(child.childNodes[j], 'incremental'); | |
560 } | |
561 } | |
562 } else { | |
563 incrementals[incrementals.length] = child; | |
564 removeClass(child,'incremental'); | |
565 } | |
566 } | |
567 if (hasClass(child, 'show-first')) { | |
568 if (child.nodeName == 'ol' || child.nodeName == 'ul' || child.nodeName == 'dl') { | |
569 removeClass(child, 'show-first'); | |
570 if (child.childNodes[isGe].nodeType == 1) { | |
571 removeClass(child.childNodes[isGe], 'incremental'); | |
572 } | |
573 } else { | |
574 incrementals[incrementals.length] = child; | |
575 } | |
576 } | |
577 incrementals = incrementals.concat(getIncrementals(child)); | |
578 } | |
579 return incrementals; | |
580 } | |
581 | |
582 function createIncrementals() { | |
583 var incrementals = new Array(); | |
584 for (var i = 0; i < smax; i++) { | |
585 incrementals[i] = getIncrementals(document.getElementById('slide'+i)); | |
586 } | |
587 return incrementals; | |
588 } | |
589 | |
590 function defaultCheck() { | |
591 var allMetas = document.getElementsByTagName('meta'); | |
592 for (var i = 0; i< allMetas.length; i++) { | |
593 if (allMetas[i].name == 'defaultView') { | |
594 defaultView = allMetas[i].content; | |
595 } | |
596 if (allMetas[i].name == 'controlVis') { | |
597 controlVis = allMetas[i].content; | |
598 } | |
599 } | |
600 } | |
601 | |
602 // Key trap fix, new function body for trap() | |
603 function trap(e) { | |
604 if (!e) { | |
605 e = event; | |
606 e.which = e.keyCode; | |
607 } | |
608 try { | |
609 modifierKey = e.ctrlKey || e.altKey || e.metaKey; | |
610 } | |
611 catch(e) { | |
612 modifierKey = false; | |
613 } | |
614 return modifierKey || e.which == 0; | |
615 } | |
616 | |
617 function noteLabel() { // Gives notes id's to match parent slides | |
618 var notes = GetElementsWithClassName('div','notes'); | |
619 for (var i = 0; i < notes.length; i++) { | |
620 var note = notes[i]; | |
621 var id = 'note' + note.parentNode.id.substring(5); | |
622 note.setAttribute('id',id); | |
623 } | |
624 resetElapsedSlide(); | |
625 resetRemainingTime(); | |
626 window.setInterval('updateElaspedTime()', 1000); | |
627 } | |
628 | |
629 function createNotesWindow() { // creates a window for our notes | |
630 if (!s5NotesWindow || s5NotesWindow.closed) { // Create the window if it doesn't exist | |
631 s5NotesWindowLoaded = false; | |
632 // Note: Safari has a tendency to ignore window options preferring to default to the settings of the parent window, grr. | |
633 if (isIE) { | |
634 s5NotesWindow = window.open('../../s5/ui/s5-notes.html', 's5NotesWindow', 'top=0,left=0,resizable=yes,scrollbars=auto'); | |
635 } else { | |
636 s5NotesWindow = window.open('../../s5/ui/s5-notes.xhtml', 's5NotesWindow', 'top=0,left=0,resizable=yes,scrollbars=auto'); | |
637 } | |
638 } | |
639 if (s5NotesWindowLoaded) { // Load the current note if the Note HTML has loaded | |
640 loadNote(); | |
641 } else { // Keep trying... | |
642 window.setTimeout('createNotesWindow()', 50); | |
643 } | |
644 } | |
645 | |
646 function loadNote() { | |
647 // Loads a note into the note window | |
648 var notes = nextNotes = '<em class="disclaimer">There are no notes for this slide.</em>'; | |
649 if (document.getElementById('note' + snum)) { | |
650 notes = document.getElementById('note' + snum).innerHTML; | |
651 } | |
652 if (document.getElementById('note' + (snum + 1))) { | |
653 nextNotes = document.getElementById('note' + (snum + 1)).innerHTML; | |
654 } | |
655 | |
656 var jl = document.getElementById('jumplist'); | |
657 var slideTitle = jl.options[jl.selectedIndex].text.replace(/^\d+\s+:\s+/, '') + ((jl.selectedIndex) ? ' (' + jl.selectedIndex + '/' + (smax - 1) + ')' : ''); | |
658 if (incrementals[snum].length > 0) { | |
659 // alert('howdy'); | |
660 slideTitle += ' <small>[' + incpos + '/' + incrementals[snum].length + ']</small>'; | |
661 } | |
662 if (jl.selectedIndex < smax - 1) { | |
663 var nextTitle = jl.options[jl.selectedIndex + 1].text.replace(/^\d+\s+:\s+/, '') + ((jl.selectedIndex + 1) ? ' (' + (jl.selectedIndex + 1) + '/' + (smax - 1) + ')' : ''); | |
664 } else { | |
665 var nextTitle = '[end of slide show]'; | |
666 } | |
667 | |
668 if (s5NotesWindow && !s5NotesWindow.closed && s5NotesWindow.document) { | |
669 s5NotesWindow.document.getElementById('slide').innerHTML = slideTitle; | |
670 s5NotesWindow.document.getElementById('notes').innerHTML = notes; | |
671 s5NotesWindow.document.getElementById('next').innerHTML = nextTitle; | |
672 s5NotesWindow.document.getElementById('nextnotes').innerHTML = nextNotes; | |
673 } | |
674 resetElapsedSlide(); | |
675 } | |
676 | |
677 function minimizeTimer(id) { | |
678 var obj = s5NotesWindow.document.getElementById(id); | |
679 if (hasClass(obj,'collapsed')) { | |
680 removeClass(obj,'collapsed'); | |
681 } else { | |
682 addClass(obj,'collapsed'); | |
683 } | |
684 } | |
685 | |
686 function resetElapsedTime() { | |
687 presentationStart = new Date(); | |
688 slideStart = new Date(); | |
689 updateElaspedTime(); | |
690 } | |
691 | |
692 function resetElapsedSlide() { | |
693 if (snum != previousSlide) { | |
694 slideStart = new Date(); | |
695 previousSlide = snum; | |
696 updateElaspedTime(); | |
697 } | |
698 } | |
699 | |
700 function updateElaspedTime() { | |
701 if (!s5NotesWindowLoaded || !s5NotesWindow || s5NotesWindow.closed) return; | |
702 var now = new Date(); | |
703 var ep = s5NotesWindow.document.getElementById('elapsed-presentation'); | |
704 var es = s5NotesWindow.document.getElementById('elapsed-slide'); | |
705 ep.removeChild(ep.firstChild); | |
706 ep.appendChild(document.createTextNode(formatTime(now.valueOf() - presentationStart.valueOf()))); | |
707 es.removeChild(es.firstChild); | |
708 es.appendChild(document.createTextNode(formatTime(now.valueOf() - slideStart.valueOf()))); | |
709 } | |
710 | |
711 function resetRemainingTime() { | |
712 if (!s5NotesWindowLoaded || !s5NotesWindow || s5NotesWindow.closed) return; | |
713 var startField = s5NotesWindow.document.getElementById('startFrom'); | |
714 startFrom = readTime(startField.value); | |
715 countdown.remaining = startFrom * 60000; // convert to msecs | |
716 countdown.start = new Date().valueOf(); | |
717 countdown.end = countdown.start + countdown.remaining; | |
718 var tl = s5NotesWindow.document.getElementById('timeLeft'); | |
719 var timeLeft = formatTime(countdown.remaining); | |
720 tl.removeChild(tl.firstChild); | |
721 tl.appendChild(document.createTextNode(timeLeft)); | |
722 } | |
723 | |
724 function updateRemainingTime() { | |
725 if (!s5NotesWindowLoaded || !s5NotesWindow || s5NotesWindow.closed) return; | |
726 var tl = s5NotesWindow.document.getElementById('timeLeft'); | |
727 var now = new Date(); | |
728 if (countdown.state == 'run') { | |
729 countdown.remaining = countdown.end - now; | |
730 } | |
731 tl.style.color = ''; | |
732 tl.style.backgroundColor = ''; | |
733 if (countdown.remaining >= 0) { | |
734 var timeLeft = formatTime(countdown.remaining); | |
735 removeClass(tl,'overtime'); | |
736 if (countdown.remaining < 300000) { | |
737 tl.style.color = 'rgb(' + (255-Math.round(countdown.remaining/2000)) + ',0,0)'; | |
738 tl.style.backgroundColor = 'rgb(255,255,' + (Math.round(countdown.remaining/2000)) + ')'; | |
739 } | |
740 } else { | |
741 var timeLeft = '-' + formatTime(-countdown.remaining); | |
742 addClass(tl,'overtime'); | |
743 } | |
744 tl.removeChild(tl.firstChild); | |
745 tl.appendChild(document.createTextNode(timeLeft)); | |
746 } | |
747 | |
748 function toggleRemainingTime() { | |
749 if (countdown.state == 'pause') countdown.state = 'run'; else countdown.state = 'pause'; | |
750 if (countdown.state == 'pause') { | |
751 window.clearInterval(countdown.timer); | |
752 } | |
753 if (countdown.state == 'run') { | |
754 countdown.start = new Date().valueOf(); | |
755 countdown.end = countdown.start + countdown.remaining; | |
756 countdown.timer = window.setInterval('updateRemainingTime()', 1000); | |
757 } | |
758 } | |
759 | |
760 function alterRemainingTime(amt) { | |
761 var change = amt * 60000; // convert to msecs | |
762 countdown.end += change; | |
763 countdown.remaining += change; | |
764 updateRemainingTime(); | |
765 } | |
766 | |
767 function formatTime(msecs) { | |
768 var time = new Date(msecs); | |
769 | |
770 var hrs = time.getUTCHours() + ((time.getUTCDate() -1) * 24); // I doubt anyone will spend more than 24 hours on a presentation or single slide but just in case... | |
771 hrs = (hrs < 10) ? '0'+hrs : hrs; | |
772 if (hrs == 'NaN' || isNaN(hrs)) hrs = '--'; | |
773 | |
774 var min = time.getUTCMinutes(); | |
775 min = (min < 10) ? '0'+min : min; | |
776 if (min == 'NaN' || isNaN(min)) min = '--'; | |
777 | |
778 var sec = time.getUTCSeconds(); | |
779 sec = (sec < 10) ? '0'+sec : sec; | |
780 if (sec == 'NaN' || isNaN(sec)) sec = '--'; | |
781 | |
782 return hrs + ':' + min + ':' + sec; | |
783 } | |
784 | |
785 function readTime(val) { | |
786 var sregex = /:/; | |
787 var matches = sregex.exec(val); | |
788 if (matches == null) { | |
789 return val; | |
790 } else { | |
791 var times = val.split(':'); | |
792 var hours = parseInt(times[0]); | |
793 var mins = parseInt(times[1]); | |
794 var total = (hours * 60) + mins; | |
795 return total; | |
796 } | |
797 } | |
798 | |
799 function createElement(element) { | |
800 if (typeof document.createElementNS != 'undefined') { | |
801 return document.createElementNS('http://www.w3.org/1999/xhtml', element); | |
802 } else { | |
803 return document.createElement(element); | |
804 } | |
805 } | |
806 | |
807 function windowChange() { | |
808 fontScale(); | |
809 } | |
810 | |
811 function fixRunIn() { | |
812 // work around lack of gecko support for display:run-in | |
813 var re = /^num_|\s+num_|^un_|\s+un_|proof/; | |
814 $$('div > h6').each(function(element) { | |
815 if(re.test($(element.parentNode).className)) { | |
816 var new_span = new Element('span').update(element.textContent); | |
817 new_span.addClassName('theorem_label'); | |
818 var next_el = element.next().firstChild; | |
819 next_el.parentNode.insertBefore(new_span, next_el); | |
820 var period = new Element('span').update('. '); | |
821 next_el.parentNode.insertBefore(period, next_el); | |
822 element.remove(); | |
823 } | |
824 }); | |
825 // add tombstone to proof, since gecko doesn't support :last-child properly | |
826 | |
827 $$('div.proof').each(function(element) { | |
828 var l = element.childElements().length -1; | |
829 var span = new Element('span').update('\u00a0\u00a0\u25ae'); | |
830 element.childElements()[l].insert(span); | |
831 }) | |
832 } | |
833 | |
834 function startup() { | |
835 defaultCheck(); | |
836 createControls(); // hallvord | |
837 slideLabel(); | |
838 incrementals = createIncrementals(); | |
839 noteLabel(); // [SI:060104] must follow slideLabel() | |
840 loadNote(); | |
841 fixLinks(); | |
842 externalLinks(); | |
843 fontScale(); | |
844 fixRunIn(); | |
845 if (!isOp) notOperaFix(); | |
846 slideJump(); | |
847 if (defaultView == 'outline') { | |
848 toggle(); | |
849 } | |
850 document.onkeyup = keys; | |
851 document.onkeypress = trap; | |
852 document.onclick = clicker; | |
853 } | |
854 | |
855 window.onload = startup; | |
856 window.onresize = function(){setTimeout('windowChange()',5);} |