1 /******************************
 
   2  * JavaScript for talk slides *
 
   6  ******************************/
 
  12 var defaultIdx = 1; // set to slide index to show by default
 
  13 var firstIdx = 2; // set no value if to use first available
 
  14 var lastIdx; // set no value if to use first available
 
  16 var pageTitle, headerText, subHeaderText;
 
  17 var navPrev, navNext, navPrevNolink, navNextNolink;
 
  19 // Slide timer - color variation of headerText
 
  20 var slideSeconds = 2 * 60;
 
  22 // Called when the document has been loaded.
 
  23 function docLoaded() {
 
  24   pageTitle = document.getElementsByTagName("title")[0];
 
  25   headerText = document.getElementById("header-text");
 
  26   subHeaderText = document.getElementById("subheader-text");
 
  27   navPrev = document.getElementById("nav-prev");
 
  28   navNext = document.getElementById("nav-next");
 
  29   navPrevNolink = document.getElementById("nav-prev-nolink");
 
  30   navNextNolink = document.getElementById("nav-next-nolink");
 
  31   articleNodes = document.getElementsByTagName("article");
 
  36     lastIdx = articleNodes.length - 1;
 
  38   // Get a list of all slides (articles).
 
  39   subHeaderText.textContent = articleNodes.length + " slides...";
 
  40   for (var i = 0; i < articleNodes.length; ++i) {
 
  41     subHeaderText.textContent = "Indexing slide " + i + " / " + articleNodes.length;
 
  42     if (!articleNodes[i].id)
 
  43       articleNodes[i].id = "slide_" + i;
 
  45     slides[articleNodes[i].id] =
 
  47         "name": articleNodes[i].id,
 
  48         "title": articleNodes[i].title ? articleNodes[i].title : articleNodes[i].id,
 
  49         "obj": articleNodes[i]};
 
  51     if (location.hash.length &&
 
  52         (location.hash == "#" + articleNodes[i].id || location.hash == "#" + i)) {
 
  53       articleNodes[i].setAttribute("aria-selected", "true");
 
  54       currentSlide = slides[articleNodes[i].id];
 
  60     currentIdx = defaultIdx;
 
  61     currentSlide = slides[articleNodes[currentIdx].id];
 
  62     currentSlide.obj.setAttribute("aria-selected", "true");
 
  63     location.hash = "#" + currentSlide.name;
 
  68 // Called when the hash part of the location changes.
 
  69 function locationHashChanged() {
 
  70   if (location.hash.length > 1) {
 
  71     var hashtag = location.hash.substring(1);
 
  72     // If not a number, treat as ID
 
  73     if (isNaN(hashtag) && slides[hashtag]) {
 
  74       currentSlide.obj.removeAttribute("aria-selected");
 
  75       currentSlide = slides[hashtag];
 
  76       currentIdx = currentSlide.idx;
 
  77       currentSlide.obj.setAttribute("aria-selected", "true");
 
  80     else if (articleNodes[hashtag]) {
 
  81       currentSlide.obj.removeAttribute("aria-selected");
 
  83       currentSlide = slides[articleNodes[currentIdx].id];
 
  84       currentSlide.obj.setAttribute("aria-selected", "true");
 
  89 window.onhashchange = locationHashChanged;
 
  91 // Update the display after we updated what slide is shown.
 
  92 function updateDisplay() {
 
  93   if (currentIdx >= firstIdx && currentIdx <= lastIdx &&
 
  94       currentSlide.name != "toc")
 
  95     subHeaderText.textContent = (currentIdx - firstIdx + 1) + "/" +
 
  96                                 (lastIdx - firstIdx + 1) + " - " +
 
  99     subHeaderText.textContent = currentSlide.title;
 
 100   pageTitle.textContent = headerText.textContent + ": " + currentSlide.title;
 
 101   if (currentIdx > firstIdx && currentSlide.name != "toc") {
 
 102     navPrev.hidden = false;
 
 103     navPrev.href = "#" + articleNodes[currentIdx - 1].id;
 
 104     navPrevNolink.hidden = true;
 
 107     navPrev.hidden = true;
 
 108     navPrevNolink.hidden = false;
 
 110   if (currentIdx < lastIdx && currentSlide.name != "toc") {
 
 111     navNext.hidden = false;
 
 112     navNext.href = "#" + articleNodes[currentIdx + 1].id;
 
 113     navNextNolink.hidden = true;
 
 116     navNext.hidden = true;
 
 117     navNextNolink.hidden = false;
 
 119   headerText.className = "";
 
 120   slideStart = new Date();
 
 121   if (currentSlide.name == "toc")
 
 124     setTimeout("timerFired()", timerMSec);
 
 128 function createTOC() {
 
 129  var list = document.getElementById("toc-list");
 
 130  if (!list.getElementsByTagName("li").length) {
 
 131    for (var slide in slides) {
 
 132      if (slide != "toc") {
 
 133        var item = document.createElement("li");
 
 134        var link = document.createElement("a");
 
 135        var slideHeaders = slides[slide].obj.getElementsByTagName("h1");
 
 136        if (slideHeaders.length)
 
 137          link.textContent = slideHeaders[0].textContent;
 
 139          link.textContent = slides[slide].title;
 
 140        link.href = "#" + slides[slide].name;
 
 141        item.appendChild(link);
 
 142        list.appendChild(item);
 
 148 // Do timed color variation on slides.
 
 149 function timerFired() {
 
 150   var slideCurrent = new Date();
 
 151   var secondsDiff = Math.round((slideCurrent.getTime() - slideStart.getTime()) / 1000);
 
 152   if (secondsDiff >= slideSeconds) {
 
 153     headerText.className = "overtime";
 
 155   else if (secondsDiff >= Math.round(2 * slideSeconds / 3)) {
 
 156     headerText.className = "ontime";
 
 157     setTimeout("timerFired()", timerMSec);
 
 159   else if (secondsDiff >= Math.round(slideSeconds / 3)) {
 
 160     headerText.className = "neartime";
 
 161     setTimeout("timerFired()", timerMSec);
 
 164     // We should never come here, but if we do, go into a 100ms loop until we get over the upcoming step.
 
 165     setTimeout("timerFired()", 100);
 
 168 var slideStart = new Date();
 
 169 var timerMSec = 1000 * (slideSeconds / 3);
 
 170 setTimeout("timerFired()", timerMSec);
 
 172 // Keyboard/click nav functionality, mostly inherited from FOSDEM 2007.
 
 175     where = where || "next";
 
 176     var navElem = document.getElementById("nav-" + where);
 
 178       window.location.href = navElem.href;
 
 181   function handleClick(e) {
 
 183     var target = (window.event) ? e.srcElement : e.target;
 
 184     if (e.which == 1 && target.nodeName != "A" && target.nodeName != "VIDEO")
 
 188   function handleKeyPress(e) {
 
 198   window.onclick = handleClick;
 
 199   window.onkeypress = handleKeyPress;