slides.js 22 KB

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