put up FOSDEM 2022 on main page
[slides.git] / fosdem2017 / slides.js
CommitLineData
df2f979f
RK
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// Slide timer - color variation of headerText
eeb0ec0c 20// Up to 2/3 of that time, use "ontime" styling, then "neartime" until this is reached, "overtime" after that.
df2f979f
RK
21var slideSeconds = 2 * 60;
22
23// Called when the document has been loaded.
24function docLoaded() {
25 pageTitle = document.getElementsByTagName("title")[0];
26 headerText = document.getElementById("header-text");
27 subHeaderText = document.getElementById("subheader-text");
28 navPrev = document.getElementById("nav-prev");
29 navNext = document.getElementById("nav-next");
30 navPrevNolink = document.getElementById("nav-prev-nolink");
31 navNextNolink = document.getElementById("nav-next-nolink");
32 articleNodes = document.getElementsByTagName("article");
33
34 if (!firstIdx)
35 firstIdx = 0;
36 if (!lastIdx)
37 lastIdx = articleNodes.length - 1;
38
39 // Get a list of all slides (articles).
40 subHeaderText.textContent = articleNodes.length + " slides...";
41 for (var i = 0; i < articleNodes.length; ++i) {
42 subHeaderText.textContent = "Indexing slide " + i + " / " + articleNodes.length;
43 if (!articleNodes[i].id)
44 articleNodes[i].id = "slide_" + i;
45
46 slides[articleNodes[i].id] =
47 {"idx": i,
48 "name": articleNodes[i].id,
49 "title": articleNodes[i].title ? articleNodes[i].title : articleNodes[i].id,
50 "obj": articleNodes[i]};
51
52 if (location.hash.length &&
53 (location.hash == "#" + articleNodes[i].id || location.hash == "#" + i)) {
54 articleNodes[i].setAttribute("aria-selected", "true");
55 currentSlide = slides[articleNodes[i].id];
56 currentIdx = i;
57 }
58 }
59
60 if (!currentSlide) {
61 currentIdx = defaultIdx;
62 currentSlide = slides[articleNodes[currentIdx].id];
63 currentSlide.obj.setAttribute("aria-selected", "true");
64 location.hash = "#" + currentSlide.name;
65 }
66 updateDisplay();
67}
68
69// Called when the hash part of the location changes.
70function locationHashChanged() {
71 if (location.hash.length > 1) {
72 var hashtag = location.hash.substring(1);
73 // If not a number, treat as ID
74 if (isNaN(hashtag) && slides[hashtag]) {
75 currentSlide.obj.removeAttribute("aria-selected");
76 currentSlide = slides[hashtag];
77 currentIdx = currentSlide.idx;
78 currentSlide.obj.setAttribute("aria-selected", "true");
79 updateDisplay();
80 }
81 else if (articleNodes[hashtag]) {
82 currentSlide.obj.removeAttribute("aria-selected");
83 currentIdx = hashtag;
84 currentSlide = slides[articleNodes[currentIdx].id];
85 currentSlide.obj.setAttribute("aria-selected", "true");
86 updateDisplay();
87 }
88 }
89}
90window.onhashchange = locationHashChanged;
91
92// Update the display after we updated what slide is shown.
93function updateDisplay() {
94 if (currentIdx >= firstIdx && currentIdx <= lastIdx &&
95 currentSlide.name != "toc")
96 subHeaderText.textContent = (currentIdx - firstIdx + 1) + "/" +
97 (lastIdx - firstIdx + 1) + " - " +
98 currentSlide.title;
99 else
100 subHeaderText.textContent = currentSlide.title;
101 pageTitle.textContent = headerText.textContent + ": " + currentSlide.title;
102 if (currentIdx > firstIdx && currentSlide.name != "toc") {
103 navPrev.hidden = false;
104 navPrev.href = "#" + articleNodes[currentIdx - 1].id;
105 navPrevNolink.hidden = true;
106 }
107 else {
108 navPrev.hidden = true;
109 navPrevNolink.hidden = false;
110 }
111 if (currentIdx < lastIdx && currentSlide.name != "toc") {
112 navNext.hidden = false;
113 navNext.href = "#" + articleNodes[currentIdx + 1].id;
114 navNextNolink.hidden = true;
115 }
116 else {
117 navNext.hidden = true;
118 navNextNolink.hidden = false;
119 }
120 headerText.className = "";
121 slideStart = new Date();
122 if (currentSlide.name == "toc")
123 createTOC();
124 else
125 setTimeout("timerFired()", timerMSec);
126}
127
128// Create TOC list.
129function createTOC() {
130 var list = document.getElementById("toc-list");
131 if (!list.getElementsByTagName("li").length) {
132 for (var slide in slides) {
133 if (slide != "toc") {
134 var item = document.createElement("li");
135 var link = document.createElement("a");
136 var slideHeaders = slides[slide].obj.getElementsByTagName("h1");
137 if (slideHeaders.length)
138 link.textContent = slideHeaders[0].textContent;
139 else
140 link.textContent = slides[slide].title;
141 link.href = "#" + slides[slide].name;
142 item.appendChild(link);
143 list.appendChild(item);
144 }
145 }
146 }
147}
148
149// Do timed color variation on slides.
150function timerFired() {
151 var slideCurrent = new Date();
152 var secondsDiff = Math.round((slideCurrent.getTime() - slideStart.getTime()) / 1000);
153 if (secondsDiff >= slideSeconds) {
154 headerText.className = "overtime";
155 }
156 else if (secondsDiff >= Math.round(2 * slideSeconds / 3)) {
157 headerText.className = "ontime";
158 setTimeout("timerFired()", timerMSec);
159 }
160 else if (secondsDiff >= Math.round(slideSeconds / 3)) {
161 headerText.className = "neartime";
162 setTimeout("timerFired()", timerMSec);
163 }
164 else {
165 // We should never come here, but if we do, go into a 100ms loop until we get over the upcoming step.
166 setTimeout("timerFired()", 100);
167 }
168}
169var slideStart = new Date();
170var timerMSec = 1000 * (slideSeconds / 3);
171setTimeout("timerFired()", timerMSec);
172
173// Keyboard/click nav functionality, mostly inherited from FOSDEM 2007.
174(function() {
175 function go(where) {
176 where = where || "next";
177 var navElem = document.getElementById("nav-" + where);
178 if (!navElem.hidden)
179 window.location.href = navElem.href;
180 }
181
182 function handleClick(e) {
183 e = e || event;
184 var target = (window.event) ? e.srcElement : e.target;
185 if (e.which == 1 && target.nodeName != "A" && target.nodeName != "VIDEO")
186 go("next");
187 }
188
189 function handleKeyPress(e) {
190 e = e || event;
191 switch (e.keyCode) {
80b2a5a3 192 // See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Constants_for_keyCode_value
df2f979f 193 case e.DOM_VK_LEFT:
80b2a5a3
RK
194 case e.DOM_VK_DOWN:
195 case e.DOM_VK_PAGE_DOWN:
da7ec9b7 196 case e.DOM_VK_H: //8bitdo Zero "X"
df2f979f
RK
197 go("prev"); break;
198 case e.DOM_VK_RIGHT:
80b2a5a3
RK
199 case e.DOM_VK_UP:
200 case e.DOM_VK_PAGE_UP:
da7ec9b7 201 case e.DOM_VK_J: //8bitdo Zero "B"
df2f979f 202 go("next"); break;
80b2a5a3
RK
203 case e.DOM_VK_HOME:
204 go("start"); break;
205 case e.DOM_VK_END:
206 go("toc"); break;
df2f979f
RK
207 }
208 }
209
210 window.onclick = handleClick;
211 window.onkeypress = handleKeyPress;
212})();