add a development page to the slide set
[slides.git] / eumozcamp-berlin2011 / slides.js
... / ...
CommitLineData
1/******************************
2 * JavaScript for talk slides *
3 * by Robert Kaiser *
4 * <kairo@kairo.at> *
5 * (for FOSDEM 2011) *
6 ******************************/
7
8var slides = {};
9var articleNodes;
10var currentSlide;
11var currentIdx;
12var defaultIdx = 1; // set to slide index to show by default
13var firstIdx = 2; // set no value if to use first available
14var lastIdx; // set no value if to use first available
15
16var pageTitle, headerText, subHeaderText;
17var navPrev, navNext, navPrevNolink, navNextNolink;
18
19// Called when the document has been loaded.
20function docLoaded() {
21 pageTitle = document.getElementsByTagName("title")[0];
22 headerText = document.getElementById("header-text");
23 subHeaderText = document.getElementById("subheader-text");
24 navPrev = document.getElementById("nav-prev");
25 navNext = document.getElementById("nav-next");
26 navPrevNolink = document.getElementById("nav-prev-nolink");
27 navNextNolink = document.getElementById("nav-next-nolink");
28 articleNodes = document.getElementsByTagName("article");
29
30 if (!firstIdx)
31 firstIdx = 0;
32 if (!lastIdx)
33 lastIdx = articleNodes.length - 1;
34
35 // Get a list of all slides (articles).
36 subHeaderText.textContent = articleNodes.length + " slides...";
37 for (var i = 0; i < articleNodes.length; ++i) {
38 subHeaderText.textContent = "Indexing slide " + i + " / " + articleNodes.length;
39 if (!articleNodes[i].id)
40 articleNodes[i].id = "slide_" + i;
41
42 slides[articleNodes[i].id] =
43 {"idx": i,
44 "name": articleNodes[i].id,
45 "title": articleNodes[i].title ? articleNodes[i].title : articleNodes[i].id,
46 "obj": articleNodes[i]};
47
48 if (location.hash.length &&
49 (location.hash == "#" + articleNodes[i].id || location.hash == "#" + i)) {
50 articleNodes[i].setAttribute("aria-selected", "true");
51 currentSlide = slides[articleNodes[i].id];
52 currentIdx = i;
53 }
54 }
55
56 if (!currentSlide) {
57 currentIdx = defaultIdx;
58 currentSlide = slides[articleNodes[currentIdx].id];
59 currentSlide.obj.setAttribute("aria-selected", "true");
60 location.hash = "#" + currentSlide.name;
61 }
62 updateDisplay();
63}
64
65// Called when the hash part of the location changes.
66function locationHashChanged() {
67 if (location.hash.length > 1) {
68 var hashtag = location.hash.substring(1);
69 // If not a number, treat as ID
70 if (isNaN(hashtag) && slides[hashtag]) {
71 currentSlide.obj.removeAttribute("aria-selected");
72 currentSlide = slides[hashtag];
73 currentIdx = currentSlide.idx;
74 currentSlide.obj.setAttribute("aria-selected", "true");
75 updateDisplay();
76 }
77 else if (articleNodes[hashtag]) {
78 currentSlide.obj.removeAttribute("aria-selected");
79 currentIdx = hashtag;
80 currentSlide = slides[articleNodes[currentIdx].id];
81 currentSlide.obj.setAttribute("aria-selected", "true");
82 updateDisplay();
83 }
84 }
85}
86window.onhashchange = locationHashChanged;
87
88// Update the display after we updated what slide is shown.
89function updateDisplay() {
90 if (currentIdx >= firstIdx && currentIdx <= lastIdx &&
91 currentSlide.name != "toc")
92 subHeaderText.textContent = (currentIdx - firstIdx + 1) + "/" +
93 (lastIdx - firstIdx + 1) + " - " +
94 currentSlide.title;
95 else
96 subHeaderText.textContent = currentSlide.title;
97 pageTitle.textContent = headerText.textContent + ": " + currentSlide.title;
98 if (currentIdx > firstIdx && currentSlide.name != "toc") {
99 navPrev.hidden = false;
100 navPrev.href = "#" + articleNodes[currentIdx - 1].id;
101 navPrevNolink.hidden = true;
102 }
103 else {
104 navPrev.hidden = true;
105 navPrevNolink.hidden = false;
106 }
107 if (currentIdx < lastIdx && currentSlide.name != "toc") {
108 navNext.hidden = false;
109 navNext.href = "#" + articleNodes[currentIdx + 1].id;
110 navNextNolink.hidden = true;
111 }
112 else {
113 navNext.hidden = true;
114 navNextNolink.hidden = false;
115 }
116 headerText.className = "";
117 slide_start = new Date();
118 if (currentSlide.name == "toc")
119 createTOC();
120 else
121 setTimeout("timerFired()", 1000*(slide_seconds/3));
122}
123
124// Create TOC list.
125function createTOC() {
126 var list = document.getElementById("toc-list");
127 if (!list.getElementsByTagName("li").length) {
128 for (var slide in slides) {
129 if (slide != "toc") {
130 var item = document.createElement("li");
131 var link = document.createElement("a");
132 var slideHeaders = slides[slide].obj.getElementsByTagName("h1");
133 if (slideHeaders.length)
134 link.textContent = slideHeaders[0].textContent;
135 else
136 link.textContent = slides[slide].title;
137 link.href = "#" + slides[slide].name;
138 item.appendChild(link);
139 list.appendChild(item);
140 }
141 }
142 }
143}
144
145// Do timed color variation on slides.
146var slide_seconds = 3*60;
147var slide_start = new Date();
148
149function timerFired() {
150 var slide_current = new Date();
151 var seconds_diff = Math.round((slide_current.getTime() - slide_start.getTime()) / 1000);
152 if (seconds_diff >= slide_seconds) {
153 headerText.className = "overtime";
154 }
155 else if (seconds_diff >= Math.round(2*slide_seconds/3)) {
156 headerText.className = "ontime";
157 setTimeout("timerFired()", 1000*(slide_seconds/3));
158 }
159 else if (seconds_diff >= Math.round(slide_seconds/3)) {
160 headerText.className = "neartime";
161 setTimeout("timerFired()", 1000*(slide_seconds/3));
162 }
163 else {
164 // We should never come here, but if we do, go into a 1s loop until we get over the upcoming step.
165 setTimeout("timerFired()", 1000);
166 }
167}
168setTimeout("timerFired()", 1000*(slide_seconds/3));
169
170// Keyboard/click nav functionality, mostly inherited from FOSDEM 2007.
171(function() {
172 function go(where) {
173 where = where || "next";
174 var navElem = document.getElementById("nav-" + where);
175 if (!navElem.hidden)
176 window.location.href = navElem.href;
177 }
178
179 function handleClick(e) {
180 e = e || event;
181 var target = (window.event) ? e.srcElement : e.target;
182 if (e.which == 1 && target.nodeName != "A" && target.nodeName != "VIDEO")
183 go("next");
184 }
185
186 function handleKeyPress(e) {
187 e = e || event;
188 switch (e.keyCode) {
189 case e.DOM_VK_LEFT:
190 go("prev"); break;
191 case e.DOM_VK_RIGHT:
192 go("next"); break;
193 }
194 }
195
196 window.onclick = handleClick;
197 window.onkeypress = handleKeyPress;
198})();