ulmul 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +4 -0
- data/README-en.xhtml +294 -0
- data/README-ja +162 -0
- data/README-ja.xhtml +307 -0
- data/Rakefile +75 -0
- data/bin/ulmul.rb +561 -0
- data/favicon.ico +0 -0
- data/index.html +28 -0
- data/lib/ulmul.rb +561 -0
- data/ruby.jpg +0 -0
- data/setup.rb +1585 -0
- data/slidy.js +2778 -0
- data/style.css +65 -0
- data/tests/ulmul_test.rb +14 -0
- data/ulmul-slidy.css +112 -0
- data/ulmul.gemspec +33 -0
- metadata +76 -0
data/slidy.js
ADDED
@@ -0,0 +1,2778 @@
|
|
1
|
+
/* slidy.js
|
2
|
+
|
3
|
+
Copyright (c) 2005 W3C (MIT, ERCIM, Keio), All Rights Reserved.
|
4
|
+
W3C liability, trademark, document use and software licensing
|
5
|
+
rules apply, see:
|
6
|
+
|
7
|
+
http://www.w3.org/Consortium/Legal/copyright-documents
|
8
|
+
http://www.w3.org/Consortium/Legal/copyright-software
|
9
|
+
|
10
|
+
|
11
|
+
Slightly modified by Takeshi Nishimatsu in 2007-09-21:
|
12
|
+
Original: if (node.nodeName == "H1" || node.nodeName == "h1")
|
13
|
+
This one: if (node.nodeName == "H1" || node.nodeName == "h1" || node.nodeName == "H2" || node.nodeName == "h2")
|
14
|
+
|
15
|
+
*/
|
16
|
+
|
17
|
+
var ns_pos = (typeof window.pageYOffset!='undefined');
|
18
|
+
var khtml = ((navigator.userAgent).indexOf("KHTML") >= 0 ? true : false);
|
19
|
+
var opera = ((navigator.userAgent).indexOf("Opera") >= 0 ? true : false);
|
20
|
+
var ie7 = (!ns_pos && navigator.userAgent.indexOf("MSIE 7") != -1);
|
21
|
+
|
22
|
+
window.onload = startup; // equivalent to onload on body element
|
23
|
+
|
24
|
+
// IE only event handlers to ensure all slides are printed
|
25
|
+
// I don't yet know how to emulate these for other browsers
|
26
|
+
window.onbeforeprint = beforePrint;
|
27
|
+
window.onafterprint = afterPrint;
|
28
|
+
|
29
|
+
// hack to hide slides while loading
|
30
|
+
setTimeout(hideAll, 50);
|
31
|
+
|
32
|
+
function hideAll()
|
33
|
+
{
|
34
|
+
if (document.body)
|
35
|
+
document.body.style.visibility = "hidden";
|
36
|
+
else
|
37
|
+
setTimeout(hideAll, 50);
|
38
|
+
}
|
39
|
+
|
40
|
+
var slidenum = 0; // integer slide count: 0, 1, 2, ...
|
41
|
+
var slides; // set to array of slide div's
|
42
|
+
var slideNumElement; // element containing slide number
|
43
|
+
var notes; // set to array of handout div's
|
44
|
+
var backgrounds; // set to array of background div's
|
45
|
+
var toolbar; // element containing toolbar
|
46
|
+
var title; // document title
|
47
|
+
var lastShown = null; // last incrementally shown item
|
48
|
+
var eos = null; // span element for end of slide indicator
|
49
|
+
var toc = null; // table of contents
|
50
|
+
var outline = null; // outline element with the focus
|
51
|
+
var selectedTextLen; // length of drag selection on document
|
52
|
+
|
53
|
+
var viewAll = 0; // 1 to view all slides + handouts
|
54
|
+
var wantToolbar = 1; // 0 if toolbar isn't wanted
|
55
|
+
var mouseClickEnabled = true; // enables left click for next slide
|
56
|
+
var scrollhack = 0; // IE work around for position: fixed
|
57
|
+
|
58
|
+
var helpAnchor; // used for keyboard focus hack in showToolbar()
|
59
|
+
var helpPage = "http://www.w3.org/Talks/Tools/Slidy/help.html";
|
60
|
+
var helpText = "Navigate with mouse click, space bar, Cursor Left/Right, " +
|
61
|
+
"or Pg Up and Pg Dn. Use S and B to change font size.";
|
62
|
+
|
63
|
+
var sizeIndex = 0;
|
64
|
+
var sizeAdjustment = 0;
|
65
|
+
var sizes = new Array("10pt", "12pt", "14pt", "16pt", "18pt", "20pt",
|
66
|
+
"22pt", "24pt", "26pt", "28pt", "30pt", "32pt");
|
67
|
+
|
68
|
+
var okayForIncremental = incrementalElementList();
|
69
|
+
|
70
|
+
// needed for efficient resizing
|
71
|
+
var lastWidth = 0;
|
72
|
+
var lastHeight = 0;
|
73
|
+
|
74
|
+
// Needed for cross browser support for relative width/height on
|
75
|
+
// object elements. The work around is to save width/height attributes
|
76
|
+
// and then to recompute absolute width/height dimensions on resizing
|
77
|
+
var objects;
|
78
|
+
|
79
|
+
// updated to language specified by html file
|
80
|
+
var lang = "en";
|
81
|
+
|
82
|
+
//var localize = {};
|
83
|
+
|
84
|
+
// for each language there is an associative array
|
85
|
+
var strings_es = {
|
86
|
+
"slide":"pág.",
|
87
|
+
"help?":"Ayuda",
|
88
|
+
"contents?":"Índice",
|
89
|
+
"table of contents":"tabla de contenidos",
|
90
|
+
"Table of Contents":"Tabla de Contenidos",
|
91
|
+
"restart presentation":"Reiniciar presentación",
|
92
|
+
"restart?":"Inicio"
|
93
|
+
};
|
94
|
+
|
95
|
+
strings_es[helpText] =
|
96
|
+
"Utilice el ratón, barra espaciadora, teclas Izda/Dhca, " +
|
97
|
+
"o Re pág y Av pág. Use S y B para cambiar el tamaño de fuente.";
|
98
|
+
|
99
|
+
var strings_nl = {
|
100
|
+
"slide":"pagina",
|
101
|
+
"help?":"Help?",
|
102
|
+
"contents?":"Inhoud?",
|
103
|
+
"table of contents":"inhoudsopgave",
|
104
|
+
"Table of Contents":"Inhoudsopgave",
|
105
|
+
"restart presentation":"herstart presentatie",
|
106
|
+
"restart?":"Herstart?"
|
107
|
+
};
|
108
|
+
|
109
|
+
strings_nl[helpText] =
|
110
|
+
"Navigeer d.m.v. het muis, spatiebar, Links/Rechts toetsen, " +
|
111
|
+
"of PgUp en PgDn. Gebruik S en B om de karaktergrootte te veranderen.";
|
112
|
+
|
113
|
+
var strings_de = {
|
114
|
+
"slide":"Seite",
|
115
|
+
"help?":"Hilfe",
|
116
|
+
"contents?":"Übersicht",
|
117
|
+
"table of contents":"Inhaltsverzeichnis",
|
118
|
+
"Table of Contents":"Inhaltsverzeichnis",
|
119
|
+
"restart presentation":"Präsentation neu starten",
|
120
|
+
"restart?":"Neustart"
|
121
|
+
};
|
122
|
+
|
123
|
+
strings_de[helpText] =
|
124
|
+
"Benutzen Sie die Maus, Leerschlag, die Cursortasten links/rechts" +
|
125
|
+
"oder Page up/Page Down zum Wechseln der Seiten und S und B für die Schriftgrösse.";
|
126
|
+
|
127
|
+
var strings_pl = {
|
128
|
+
"slide":"slajd",
|
129
|
+
"help?":"pomoc?",
|
130
|
+
"contents?":"spis treści?",
|
131
|
+
"table of contents":"spis treści",
|
132
|
+
"Table of Contents":"Spis Treści",
|
133
|
+
"restart presentation":"Restartuj prezentację",
|
134
|
+
"restart?":"restart?"
|
135
|
+
};
|
136
|
+
|
137
|
+
strings_pl[helpText] =
|
138
|
+
"Zmieniaj slajdy klikając myszą, naciskając spację, strzałki lewo/prawo" +
|
139
|
+
"lub PgUp / PgDn. Użyj klawiszy S i B, aby zmienić rozmiar czczionki.";
|
140
|
+
|
141
|
+
var strings_fr = {
|
142
|
+
"slide":"page",
|
143
|
+
"help?":"Aide",
|
144
|
+
"contents?":"Index",
|
145
|
+
"table of contents":"table des matières",
|
146
|
+
"Table of Contents":"Table des matières",
|
147
|
+
"restart presentation":"Recommencer l'exposé",
|
148
|
+
"restart?":"Début"
|
149
|
+
};
|
150
|
+
|
151
|
+
strings_fr[helpText] =
|
152
|
+
"Naviguez avec la souris, la barre d'espace, les flèches" +
|
153
|
+
"gauche/droite ou les touches Pg Up, Pg Dn. Utilisez " +
|
154
|
+
"les touches S et B pour modifier la taille de la police.";
|
155
|
+
|
156
|
+
var strings_hu = {
|
157
|
+
"slide":"oldal",
|
158
|
+
"help?":"segítség",
|
159
|
+
"contents?":"tartalom",
|
160
|
+
"table of contents":"tartalomjegyzék",
|
161
|
+
"Table of Contents":"Tartalomjegyzék",
|
162
|
+
"restart presentation":"bemutató újraindítása",
|
163
|
+
"restart?":"újraindítás"
|
164
|
+
};
|
165
|
+
|
166
|
+
strings_hu[helpText] =
|
167
|
+
"Az oldalak közti lépkedéshez kattintson az egérrel, vagy használja a szóköz, a bal, vagy a jobb nyíl, " +
|
168
|
+
"illetve a Page Down, Page Up billentyűket. Az S és a B billentyűkkel változtathatja a szöveg méretét.";
|
169
|
+
|
170
|
+
var strings_it = {
|
171
|
+
"slide":"pag.",
|
172
|
+
"help?":"Aiuto",
|
173
|
+
"contents?":"Indice",
|
174
|
+
"table of contents":"indice",
|
175
|
+
"Table of Contents":"Indice",
|
176
|
+
"restart presentation":"Ricominciare la presentazione",
|
177
|
+
"restart?":"Inizio"
|
178
|
+
};
|
179
|
+
|
180
|
+
strings_it[helpText] =
|
181
|
+
"Navigare con mouse, barra spazio, frecce sinistra/destra o " +
|
182
|
+
"PgUp e PgDn. Usare S e B per cambiare la dimensione dei caratteri.";
|
183
|
+
|
184
|
+
var strings_el = {
|
185
|
+
"slide":"σελίδα",
|
186
|
+
"help?":"βοήθεια;",
|
187
|
+
"contents?":"περιεχόμενα;",
|
188
|
+
"table of contents":"πίνακας περιεχομένων",
|
189
|
+
"Table of Contents":"Πίνακας Περιεχομένων",
|
190
|
+
"restart presentation":"επανεκκίνηση παρουσίασης",
|
191
|
+
"restart?":"επανεκκίνηση;"
|
192
|
+
};
|
193
|
+
|
194
|
+
strings_el[helpText] =
|
195
|
+
"Πλοηγηθείτε με το κλίκ του ποντικιού, το space, τα βέλη αριστερά/δεξιά, " +
|
196
|
+
"ή Page Up και Page Down. Χρησιμοποιήστε τα πλήκτρα S και B για να αλλάξετε " +
|
197
|
+
"το μέγεθος της γραμματοσειράς.";
|
198
|
+
|
199
|
+
var strings_ja = {
|
200
|
+
"slide":"スライド",
|
201
|
+
"help?":"ヘルプ",
|
202
|
+
"contents?":"目次",
|
203
|
+
"table of contents":"目次を表示",
|
204
|
+
"Table of Contents":"目次",
|
205
|
+
"restart presentation":"最初から再生",
|
206
|
+
"restart?":"最初から"
|
207
|
+
};
|
208
|
+
|
209
|
+
strings_ja[helpText] =
|
210
|
+
"マウス左クリック ・ スペース ・ 左右キー " +
|
211
|
+
"または Page Up ・ Page Downで操作, S ・ Bでフォントサイズ変更";
|
212
|
+
|
213
|
+
|
214
|
+
// each such language array is declared in the localize array
|
215
|
+
// used indirectly as in help.innerHTML = "help".localize();
|
216
|
+
var localize = {
|
217
|
+
"es":strings_es,
|
218
|
+
"nl":strings_nl,
|
219
|
+
"de":strings_de,
|
220
|
+
"pl":strings_pl,
|
221
|
+
"fr":strings_fr,
|
222
|
+
"hu":strings_hu,
|
223
|
+
"it":strings_it,
|
224
|
+
"el":strings_el,
|
225
|
+
"jp":strings_ja
|
226
|
+
};
|
227
|
+
|
228
|
+
/* general initialization */
|
229
|
+
function startup()
|
230
|
+
{
|
231
|
+
// find human language from html element
|
232
|
+
// for use in localizing strings
|
233
|
+
lang = document.body.parentNode.getAttribute("lang");
|
234
|
+
|
235
|
+
if (!lang)
|
236
|
+
lang = document.body.parentNode.getAttribute("xml:lang");
|
237
|
+
|
238
|
+
if (!lang)
|
239
|
+
lang = "en";
|
240
|
+
|
241
|
+
document.body.style.visibility = "visible";
|
242
|
+
title = document.title;
|
243
|
+
toolbar = addToolbar();
|
244
|
+
wrapImplicitSlides();
|
245
|
+
slides = collectSlides();
|
246
|
+
notes = collectNotes();
|
247
|
+
objects = document.body.getElementsByTagName("object");
|
248
|
+
backgrounds = collectBackgrounds();
|
249
|
+
patchAnchors();
|
250
|
+
|
251
|
+
slidenum = findSlideNumber(location.href);
|
252
|
+
window.offscreenbuffering = true;
|
253
|
+
sizeAdjustment = findSizeAdjust();
|
254
|
+
hideImageToolbar(); // suppress IE image toolbar popup
|
255
|
+
initOutliner(); // activate fold/unfold support
|
256
|
+
|
257
|
+
if (slides.length > 0)
|
258
|
+
{
|
259
|
+
var slide = slides[slidenum];
|
260
|
+
slide.style.position = "absolute";
|
261
|
+
|
262
|
+
if (slidenum > 0)
|
263
|
+
{
|
264
|
+
setVisibilityAllIncremental("visible");
|
265
|
+
lastShown = previousIncrementalItem(null);
|
266
|
+
setEosStatus(true);
|
267
|
+
}
|
268
|
+
else
|
269
|
+
{
|
270
|
+
lastShown = null;
|
271
|
+
setVisibilityAllIncremental("hidden");
|
272
|
+
setEosStatus(!nextIncrementalItem(lastShown));
|
273
|
+
}
|
274
|
+
|
275
|
+
setLocation();
|
276
|
+
}
|
277
|
+
|
278
|
+
toc = tableOfContents();
|
279
|
+
hideTableOfContents();
|
280
|
+
|
281
|
+
// bind event handlers
|
282
|
+
document.onclick = mouseButtonClick;
|
283
|
+
document.onmouseup = mouseButtonUp;
|
284
|
+
document.onkeydown = keyDown;
|
285
|
+
window.onresize = resized;
|
286
|
+
window.onscroll = scrolled;
|
287
|
+
singleSlideView();
|
288
|
+
|
289
|
+
setLocation();
|
290
|
+
resized();
|
291
|
+
|
292
|
+
if (ie7)
|
293
|
+
setTimeout("ieHack()", 100);
|
294
|
+
|
295
|
+
showToolbar();
|
296
|
+
}
|
297
|
+
|
298
|
+
// add localize method to all strings for use
|
299
|
+
// as in help.innerHTML = "help".localize();
|
300
|
+
String.prototype.localize = function()
|
301
|
+
{
|
302
|
+
if (this == "")
|
303
|
+
return this;
|
304
|
+
|
305
|
+
// try full language code, e.g. en-US
|
306
|
+
var s, lookup = localize[lang];
|
307
|
+
|
308
|
+
if (lookup)
|
309
|
+
{
|
310
|
+
s = lookup[this];
|
311
|
+
|
312
|
+
if (s)
|
313
|
+
return s;
|
314
|
+
}
|
315
|
+
|
316
|
+
// try en if undefined for en-US
|
317
|
+
var lg = lang.split("-");
|
318
|
+
|
319
|
+
if (lg.length > 1)
|
320
|
+
{
|
321
|
+
lookup = localize[lg[0]];
|
322
|
+
|
323
|
+
if (lookup)
|
324
|
+
{
|
325
|
+
s = lookup[this];
|
326
|
+
|
327
|
+
if (s)
|
328
|
+
return s;
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
// otherwise string as is
|
333
|
+
return this;
|
334
|
+
}
|
335
|
+
|
336
|
+
// suppress IE's image toolbar pop up
|
337
|
+
function hideImageToolbar()
|
338
|
+
{
|
339
|
+
if (!ns_pos)
|
340
|
+
{
|
341
|
+
var images = document.getElementsByTagName("IMG");
|
342
|
+
|
343
|
+
for (var i = 0; i < images.length; ++i)
|
344
|
+
images[i].setAttribute("galleryimg", "no");
|
345
|
+
}
|
346
|
+
}
|
347
|
+
|
348
|
+
// hack to persuade IE to compute correct document height
|
349
|
+
// as needed for simulating fixed positioning of toolbar
|
350
|
+
function ieHack()
|
351
|
+
{
|
352
|
+
window.resizeBy(0,-1);
|
353
|
+
window.resizeBy(0, 1);
|
354
|
+
}
|
355
|
+
|
356
|
+
// Firefox reload SVG bug work around
|
357
|
+
function reload(e)
|
358
|
+
{
|
359
|
+
if (!e)
|
360
|
+
var e = window.event;
|
361
|
+
|
362
|
+
hideBackgrounds();
|
363
|
+
setTimeout("document.reload();", 100);
|
364
|
+
|
365
|
+
stopPropagation(e);
|
366
|
+
e.cancel = true;
|
367
|
+
e.returnValue = false;
|
368
|
+
|
369
|
+
return false;
|
370
|
+
}
|
371
|
+
|
372
|
+
// Safari and Konqueror don't yet support getComputedStyle()
|
373
|
+
// and they always reload page when location.href is updated
|
374
|
+
function isKHTML()
|
375
|
+
{
|
376
|
+
var agent = navigator.userAgent;
|
377
|
+
return (agent.indexOf("KHTML") >= 0 ? true : false);
|
378
|
+
}
|
379
|
+
|
380
|
+
function resized()
|
381
|
+
{
|
382
|
+
var width = 0;
|
383
|
+
|
384
|
+
if ( typeof( window.innerWidth ) == 'number' )
|
385
|
+
width = window.innerWidth; // Non IE browser
|
386
|
+
else if (document.documentElement && document.documentElement.clientWidth)
|
387
|
+
width = document.documentElement.clientWidth; // IE6
|
388
|
+
else if (document.body && document.body.clientWidth)
|
389
|
+
width = document.body.clientWidth; // IE4
|
390
|
+
|
391
|
+
var height = 0;
|
392
|
+
|
393
|
+
if ( typeof( window.innerHeight ) == 'number' )
|
394
|
+
height = window.innerHeight; // Non IE browser
|
395
|
+
else if (document.documentElement && document.documentElement.clientHeight)
|
396
|
+
height = document.documentElement.clientHeight; // IE6
|
397
|
+
else if (document.body && document.body.clientHeight)
|
398
|
+
height = document.body.clientHeight; // IE4
|
399
|
+
|
400
|
+
if (height && (width/height > 1.05*1024/768))
|
401
|
+
{
|
402
|
+
width = height * 1024.0/768;
|
403
|
+
}
|
404
|
+
|
405
|
+
// IE fires onresize even when only font size is changed!
|
406
|
+
// so we do a check to avoid blocking < and > actions
|
407
|
+
if (width != lastWidth || height != lastHeight)
|
408
|
+
{
|
409
|
+
if (width >= 1100)
|
410
|
+
sizeIndex = 5; // 4
|
411
|
+
else if (width >= 1000)
|
412
|
+
sizeIndex = 4; // 3
|
413
|
+
else if (width >= 800)
|
414
|
+
sizeIndex = 3; // 2
|
415
|
+
else if (width >= 600)
|
416
|
+
sizeIndex = 2; // 1
|
417
|
+
else if (width)
|
418
|
+
sizeIndex = 0;
|
419
|
+
|
420
|
+
// add in font size adjustment from meta element e.g.
|
421
|
+
// <meta name="font-size-adjustment" content="-2" />
|
422
|
+
// useful when slides have too much content ;-)
|
423
|
+
|
424
|
+
if (0 <= sizeIndex + sizeAdjustment &&
|
425
|
+
sizeIndex + sizeAdjustment < sizes.length)
|
426
|
+
sizeIndex = sizeIndex + sizeAdjustment;
|
427
|
+
|
428
|
+
// enables cross browser use of relative width/height
|
429
|
+
// on object elements for use with SVG and Flash media
|
430
|
+
adjustObjectDimensions(width, height);
|
431
|
+
|
432
|
+
document.body.style.fontSize = sizes[sizeIndex];
|
433
|
+
|
434
|
+
lastWidth = width;
|
435
|
+
lastHeight = height;
|
436
|
+
|
437
|
+
// force reflow to work around Mozilla bug
|
438
|
+
//if (ns_pos)
|
439
|
+
{
|
440
|
+
var slide = slides[slidenum];
|
441
|
+
hideSlide(slide);
|
442
|
+
showSlide(slide);
|
443
|
+
}
|
444
|
+
|
445
|
+
// force correct positioning of toolbar
|
446
|
+
refreshToolbar(200);
|
447
|
+
}
|
448
|
+
}
|
449
|
+
|
450
|
+
function scrolled()
|
451
|
+
{
|
452
|
+
if (toolbar && !ns_pos && !ie7)
|
453
|
+
{
|
454
|
+
hackoffset = scrollXOffset();
|
455
|
+
// hide toolbar
|
456
|
+
toolbar.style.display = "none";
|
457
|
+
|
458
|
+
// make it reappear later
|
459
|
+
if (scrollhack == 0 && !viewAll)
|
460
|
+
{
|
461
|
+
setTimeout(showToolbar, 1000);
|
462
|
+
scrollhack = 1;
|
463
|
+
}
|
464
|
+
}
|
465
|
+
}
|
466
|
+
|
467
|
+
// used to ensure IE refreshes toolbar in correct position
|
468
|
+
function refreshToolbar(interval)
|
469
|
+
{
|
470
|
+
if (!ns_pos && !ie7)
|
471
|
+
{
|
472
|
+
hideToolbar();
|
473
|
+
setTimeout(showToolbar, interval);
|
474
|
+
}
|
475
|
+
}
|
476
|
+
|
477
|
+
// restores toolbar after short delay
|
478
|
+
function showToolbar()
|
479
|
+
{
|
480
|
+
if (wantToolbar)
|
481
|
+
{
|
482
|
+
if (!ns_pos)
|
483
|
+
{
|
484
|
+
// adjust position to allow for scrolling
|
485
|
+
var xoffset = scrollXOffset();
|
486
|
+
toolbar.style.left = xoffset;
|
487
|
+
toolbar.style.right = xoffset;
|
488
|
+
|
489
|
+
// determine vertical scroll offset
|
490
|
+
//var yoffset = scrollYOffset();
|
491
|
+
|
492
|
+
// bottom is doc height - window height - scroll offset
|
493
|
+
//var bottom = documentHeight() - lastHeight - yoffset
|
494
|
+
|
495
|
+
//if (yoffset > 0 || documentHeight() > lastHeight)
|
496
|
+
// bottom += 16; // allow for height of scrollbar
|
497
|
+
|
498
|
+
toolbar.style.bottom = 0; //bottom;
|
499
|
+
}
|
500
|
+
|
501
|
+
toolbar.style.display = "block";
|
502
|
+
toolbar.style.visibility = "visible";
|
503
|
+
}
|
504
|
+
|
505
|
+
scrollhack = 0;
|
506
|
+
|
507
|
+
|
508
|
+
// set the keyboard focus to the help link on the
|
509
|
+
// toolbar to ensure that document has the focus
|
510
|
+
// IE doesn't always work with window.focus()
|
511
|
+
// and this hack has benefit of Enter for help
|
512
|
+
|
513
|
+
try
|
514
|
+
{
|
515
|
+
if (!opera)
|
516
|
+
helpAnchor.focus();
|
517
|
+
}
|
518
|
+
catch (e)
|
519
|
+
{
|
520
|
+
}
|
521
|
+
}
|
522
|
+
|
523
|
+
function test()
|
524
|
+
{
|
525
|
+
var s = "docH: " + documentHeight() +
|
526
|
+
" winH: " + lastHeight +
|
527
|
+
" yoffset: " + scrollYOffset() +
|
528
|
+
" toolbot: " + (documentHeight() - lastHeight - scrollYOffset());
|
529
|
+
|
530
|
+
//alert(s);
|
531
|
+
|
532
|
+
var slide = slides[slidenum];
|
533
|
+
// IE getAttribute requires "class" to be "className"
|
534
|
+
var name = ns_pos ? "class" : "className";
|
535
|
+
var style = (slide.currentStyle ? slide.currentStyle["backgroundColor"] :
|
536
|
+
document.defaultView.getComputedStyle(slide, '').getPropertyValue("background-color"));
|
537
|
+
alert("class='" + slide.getAttribute(name) + "' backgroundColor: " + style);
|
538
|
+
}
|
539
|
+
|
540
|
+
function hideToolbar()
|
541
|
+
{
|
542
|
+
toolbar.style.display = "none";
|
543
|
+
toolbar.style.visibility = "hidden";
|
544
|
+
window.focus();
|
545
|
+
}
|
546
|
+
|
547
|
+
// invoked via F key
|
548
|
+
function toggleToolbar()
|
549
|
+
{
|
550
|
+
if (!viewAll)
|
551
|
+
{
|
552
|
+
if (toolbar.style.display == "none")
|
553
|
+
{
|
554
|
+
toolbar.style.display = "block";
|
555
|
+
toolbar.style.visibility = "visible";
|
556
|
+
wantToolbar = 1;
|
557
|
+
}
|
558
|
+
else
|
559
|
+
{
|
560
|
+
toolbar.style.display = "none";
|
561
|
+
toolbar.style.visibility = "hidden";
|
562
|
+
wantToolbar = 0;
|
563
|
+
}
|
564
|
+
}
|
565
|
+
}
|
566
|
+
|
567
|
+
function scrollXOffset()
|
568
|
+
{
|
569
|
+
if (window.pageXOffset)
|
570
|
+
return self.pageXOffset;
|
571
|
+
|
572
|
+
if (document.documentElement &&
|
573
|
+
document.documentElement.scrollLeft)
|
574
|
+
return document.documentElement.scrollLeft;
|
575
|
+
|
576
|
+
if (document.body)
|
577
|
+
return document.body.scrollLeft;
|
578
|
+
|
579
|
+
return 0;
|
580
|
+
}
|
581
|
+
|
582
|
+
|
583
|
+
function scrollYOffset()
|
584
|
+
{
|
585
|
+
if (window.pageYOffset)
|
586
|
+
return self.pageYOffset;
|
587
|
+
|
588
|
+
if (document.documentElement &&
|
589
|
+
document.documentElement.scrollTop)
|
590
|
+
return document.documentElement.scrollTop;
|
591
|
+
|
592
|
+
if (document.body)
|
593
|
+
return document.body.scrollTop;
|
594
|
+
|
595
|
+
return 0;
|
596
|
+
}
|
597
|
+
|
598
|
+
// looking for a way to determine height of slide content
|
599
|
+
// the slide itself is set to the height of the window
|
600
|
+
function optimizeFontSize()
|
601
|
+
{
|
602
|
+
var slide = slides[slidenum];
|
603
|
+
|
604
|
+
//var dh = documentHeight(); //getDocHeight(document);
|
605
|
+
var dh = slide.scrollHeight;
|
606
|
+
var wh = getWindowHeight();
|
607
|
+
var u = 100 * dh / wh;
|
608
|
+
|
609
|
+
alert("window utilization = " + u + "% (doc "
|
610
|
+
+ dh + " win " + wh + ")");
|
611
|
+
}
|
612
|
+
|
613
|
+
function getDocHeight(doc) // from document object
|
614
|
+
{
|
615
|
+
if (!doc)
|
616
|
+
doc = document;
|
617
|
+
|
618
|
+
if (doc && doc.body && doc.body.offsetHeight)
|
619
|
+
return doc.body.offsetHeight; // ns/gecko syntax
|
620
|
+
|
621
|
+
if (doc && doc.body && doc.body.scrollHeight)
|
622
|
+
return doc.body.scrollHeight;
|
623
|
+
|
624
|
+
alert("couldn't determine document height");
|
625
|
+
}
|
626
|
+
|
627
|
+
function getWindowHeight()
|
628
|
+
{
|
629
|
+
if ( typeof( window.innerHeight ) == 'number' )
|
630
|
+
return window.innerHeight; // Non IE browser
|
631
|
+
|
632
|
+
if (document.documentElement && document.documentElement.clientHeight)
|
633
|
+
return document.documentElement.clientHeight; // IE6
|
634
|
+
|
635
|
+
if (document.body && document.body.clientHeight)
|
636
|
+
return document.body.clientHeight; // IE4
|
637
|
+
}
|
638
|
+
|
639
|
+
|
640
|
+
|
641
|
+
function documentHeight()
|
642
|
+
{
|
643
|
+
var sh, oh;
|
644
|
+
|
645
|
+
sh = document.body.scrollHeight;
|
646
|
+
oh = document.body.offsetHeight;
|
647
|
+
|
648
|
+
if (sh && oh)
|
649
|
+
{
|
650
|
+
return (sh > oh ? sh : oh);
|
651
|
+
}
|
652
|
+
|
653
|
+
// no idea!
|
654
|
+
return 0;
|
655
|
+
}
|
656
|
+
|
657
|
+
function smaller()
|
658
|
+
{
|
659
|
+
if (sizeIndex > 0)
|
660
|
+
{
|
661
|
+
--sizeIndex;
|
662
|
+
}
|
663
|
+
|
664
|
+
toolbar.style.display = "none";
|
665
|
+
document.body.style.fontSize = sizes[sizeIndex];
|
666
|
+
var slide = slides[slidenum];
|
667
|
+
hideSlide(slide);
|
668
|
+
showSlide(slide);
|
669
|
+
setTimeout(showToolbar, 300);
|
670
|
+
}
|
671
|
+
|
672
|
+
function bigger()
|
673
|
+
{
|
674
|
+
if (sizeIndex < sizes.length - 1)
|
675
|
+
{
|
676
|
+
++sizeIndex;
|
677
|
+
}
|
678
|
+
|
679
|
+
toolbar.style.display = "none";
|
680
|
+
document.body.style.fontSize = sizes[sizeIndex];
|
681
|
+
var slide = slides[slidenum];
|
682
|
+
hideSlide(slide);
|
683
|
+
showSlide(slide);
|
684
|
+
setTimeout(showToolbar, 300);
|
685
|
+
}
|
686
|
+
|
687
|
+
// enables cross browser use of relative width/height
|
688
|
+
// on object elements for use with SVG and Flash media
|
689
|
+
// with thanks to Ivan Herman for the suggestion
|
690
|
+
function adjustObjectDimensions(width, height)
|
691
|
+
{
|
692
|
+
for( var i = 0; i < objects.length; i++ )
|
693
|
+
{
|
694
|
+
var obj = objects[i];
|
695
|
+
var mimeType = obj.getAttribute("type");
|
696
|
+
|
697
|
+
if (mimeType == "image/svg+xml" || mimeType == "application/x-shockwave-flash")
|
698
|
+
{
|
699
|
+
if ( !obj.initialWidth )
|
700
|
+
obj.initialWidth = obj.getAttribute("width");
|
701
|
+
|
702
|
+
if ( !obj.initialHeight )
|
703
|
+
obj.initialHeight = obj.getAttribute("height");
|
704
|
+
|
705
|
+
if ( obj.initialWidth && obj.initialWidth.charAt(obj.initialWidth.length-1) == "%" )
|
706
|
+
{
|
707
|
+
var w = parseInt(obj.initialWidth.slice(0, obj.initialWidth.length-1));
|
708
|
+
var newW = width * (w/100.0);
|
709
|
+
obj.setAttribute("width",newW);
|
710
|
+
}
|
711
|
+
|
712
|
+
if ( obj.initialHeight && obj.initialHeight.charAt(obj.initialHeight.length-1) == "%" )
|
713
|
+
{
|
714
|
+
var h = parseInt(obj.initialHeight.slice(0, obj.initialHeight.length-1));
|
715
|
+
var newH = height * (h/100.0);
|
716
|
+
obj.setAttribute("height", newH);
|
717
|
+
}
|
718
|
+
}
|
719
|
+
}
|
720
|
+
}
|
721
|
+
|
722
|
+
function cancel(event)
|
723
|
+
{
|
724
|
+
if (event)
|
725
|
+
{
|
726
|
+
event.cancel = true;
|
727
|
+
event.returnValue = false;
|
728
|
+
|
729
|
+
if (event.preventDefault)
|
730
|
+
event.preventDefault();
|
731
|
+
}
|
732
|
+
|
733
|
+
return false;
|
734
|
+
}
|
735
|
+
|
736
|
+
// See e.g. http://www.quirksmode.org/js/events/keys.html for keycodes
|
737
|
+
function keyDown(event)
|
738
|
+
{
|
739
|
+
var key;
|
740
|
+
|
741
|
+
if (!event)
|
742
|
+
var event = window.event;
|
743
|
+
|
744
|
+
// kludge around NS/IE differences
|
745
|
+
if (window.event)
|
746
|
+
key = window.event.keyCode;
|
747
|
+
else if (event.which)
|
748
|
+
key = event.which;
|
749
|
+
else
|
750
|
+
return true; // Yikes! unknown browser
|
751
|
+
|
752
|
+
// ignore event if key value is zero
|
753
|
+
// as for alt on Opera and Konqueror
|
754
|
+
if (!key)
|
755
|
+
return true;
|
756
|
+
|
757
|
+
// check for concurrent control/command/alt key
|
758
|
+
// but are these only present on mouse events?
|
759
|
+
|
760
|
+
if (event.ctrlKey || event.altKey || event.metaKey)
|
761
|
+
return true;
|
762
|
+
|
763
|
+
// dismiss table of contents if visible
|
764
|
+
if (isShownToc() && key != 9 && key != 16 && key != 38 && key != 40)
|
765
|
+
{
|
766
|
+
hideTableOfContents();
|
767
|
+
|
768
|
+
if (key == 27 || key == 84 || key == 67)
|
769
|
+
return cancel(event);
|
770
|
+
}
|
771
|
+
|
772
|
+
if (key == 34) // Page Down
|
773
|
+
{
|
774
|
+
nextSlide(false);
|
775
|
+
return cancel(event);
|
776
|
+
}
|
777
|
+
else if (key == 33) // Page Up
|
778
|
+
{
|
779
|
+
previousSlide(false);
|
780
|
+
return cancel(event);
|
781
|
+
}
|
782
|
+
else if (key == 32) // space bar
|
783
|
+
{
|
784
|
+
nextSlide(true);
|
785
|
+
return cancel(event);
|
786
|
+
}
|
787
|
+
else if (key == 37) // Left arrow
|
788
|
+
{
|
789
|
+
previousSlide(!event.shiftKey);
|
790
|
+
return cancel(event);
|
791
|
+
}
|
792
|
+
else if (key == 36) // Home
|
793
|
+
{
|
794
|
+
firstSlide();
|
795
|
+
return cancel(event);
|
796
|
+
}
|
797
|
+
else if (key == 35) // End
|
798
|
+
{
|
799
|
+
lastSlide();
|
800
|
+
return cancel(event);
|
801
|
+
}
|
802
|
+
else if (key == 39) // Right arrow
|
803
|
+
{
|
804
|
+
nextSlide(!event.shiftKey);
|
805
|
+
return cancel(event);
|
806
|
+
}
|
807
|
+
else if (key == 13) // Enter
|
808
|
+
{
|
809
|
+
if (outline)
|
810
|
+
{
|
811
|
+
if (outline.visible)
|
812
|
+
fold(outline);
|
813
|
+
else
|
814
|
+
unfold(outline);
|
815
|
+
|
816
|
+
return cancel(event);
|
817
|
+
}
|
818
|
+
}
|
819
|
+
else if (key == 188) // < for smaller fonts
|
820
|
+
{
|
821
|
+
smaller();
|
822
|
+
return cancel(event);
|
823
|
+
}
|
824
|
+
else if (key == 190) // > for larger fonts
|
825
|
+
{
|
826
|
+
bigger();
|
827
|
+
return cancel(event);
|
828
|
+
}
|
829
|
+
else if (key == 189 || key == 109) // - for smaller fonts
|
830
|
+
{
|
831
|
+
smaller();
|
832
|
+
return cancel(event);
|
833
|
+
}
|
834
|
+
else if (key == 187 || key == 191 || key == 107) // = + for larger fonts
|
835
|
+
{
|
836
|
+
bigger();
|
837
|
+
return cancel(event);
|
838
|
+
}
|
839
|
+
else if (key == 83) // S for smaller fonts
|
840
|
+
{
|
841
|
+
smaller();
|
842
|
+
return cancel(event);
|
843
|
+
}
|
844
|
+
else if (key == 66) // B for larger fonts
|
845
|
+
{
|
846
|
+
bigger();
|
847
|
+
return cancel(event);
|
848
|
+
}
|
849
|
+
else if (key == 90) // Z for last slide
|
850
|
+
{
|
851
|
+
lastSlide();
|
852
|
+
return cancel(event);
|
853
|
+
}
|
854
|
+
else if (key == 70) // F for toggle toolbar
|
855
|
+
{
|
856
|
+
toggleToolbar();
|
857
|
+
return cancel(event);
|
858
|
+
}
|
859
|
+
else if (key == 65) // A for toggle view single/all slides
|
860
|
+
{
|
861
|
+
toggleView();
|
862
|
+
return cancel(event);
|
863
|
+
}
|
864
|
+
else if (key == 75) // toggle action of left click for next page
|
865
|
+
{
|
866
|
+
mouseClickEnabled = !mouseClickEnabled;
|
867
|
+
alert((mouseClickEnabled ? "enabled" : "disabled") + " mouse click advance");
|
868
|
+
return cancel(event);
|
869
|
+
}
|
870
|
+
else if (key == 84 || key == 67) // T or C for table of contents
|
871
|
+
{
|
872
|
+
if (toc)
|
873
|
+
showTableOfContents();
|
874
|
+
|
875
|
+
return cancel(event);
|
876
|
+
}
|
877
|
+
else if (key == 72) // H for help
|
878
|
+
{
|
879
|
+
window.location = helpPage;
|
880
|
+
return cancel(event);
|
881
|
+
}
|
882
|
+
|
883
|
+
//else if (key == 93) // Windows menu key
|
884
|
+
//alert("lastShown is " + lastShown);
|
885
|
+
//else alert("key code is "+ key);
|
886
|
+
|
887
|
+
|
888
|
+
return true;
|
889
|
+
}
|
890
|
+
|
891
|
+
// make note of length of selected text
|
892
|
+
// as this evaluates to zero in click event
|
893
|
+
function mouseButtonUp(e)
|
894
|
+
{
|
895
|
+
selectedTextLen = getSelectedText().length;
|
896
|
+
}
|
897
|
+
|
898
|
+
// right mouse button click is reserved for context menus
|
899
|
+
// it is more reliable to detect rightclick than leftclick
|
900
|
+
function mouseButtonClick(e)
|
901
|
+
{
|
902
|
+
var rightclick = false;
|
903
|
+
var leftclick = false;
|
904
|
+
var middleclick = false;
|
905
|
+
var target;
|
906
|
+
|
907
|
+
if (!e)
|
908
|
+
var e = window.event;
|
909
|
+
|
910
|
+
if (e.target)
|
911
|
+
target = e.target;
|
912
|
+
else if (e.srcElement)
|
913
|
+
target = e.srcElement;
|
914
|
+
|
915
|
+
// work around Safari bug
|
916
|
+
if (target.nodeType == 3)
|
917
|
+
target = target.parentNode;
|
918
|
+
|
919
|
+
if (e.which) // all browsers except IE
|
920
|
+
{
|
921
|
+
leftclick = (e.which == 1);
|
922
|
+
middleclick = (e.which == 2);
|
923
|
+
rightclick = (e.which == 3);
|
924
|
+
}
|
925
|
+
else if (e.button)
|
926
|
+
{
|
927
|
+
// Konqueror gives 1 for left, 4 for middle
|
928
|
+
// IE6 gives 0 for left and not 1 as I expected
|
929
|
+
|
930
|
+
if (e.button == 4)
|
931
|
+
middleclick = true;
|
932
|
+
|
933
|
+
// all browsers agree on 2 for right button
|
934
|
+
rightclick = (e.button == 2);
|
935
|
+
}
|
936
|
+
else leftclick = true;
|
937
|
+
|
938
|
+
// dismiss table of contents
|
939
|
+
hideTableOfContents();
|
940
|
+
|
941
|
+
if (selectedTextLen > 0)
|
942
|
+
{
|
943
|
+
stopPropagation(e);
|
944
|
+
e.cancel = true;
|
945
|
+
e.returnValue = false;
|
946
|
+
return false;
|
947
|
+
}
|
948
|
+
|
949
|
+
// check if target is something that probably want's clicks
|
950
|
+
// e.g. embed, object, input, textarea, select, option
|
951
|
+
|
952
|
+
if (mouseClickEnabled && leftclick &&
|
953
|
+
target.nodeName != "EMBED" &&
|
954
|
+
target.nodeName != "OBJECT" &&
|
955
|
+
target.nodeName != "INPUT" &&
|
956
|
+
target.nodeName != "TEXTAREA" &&
|
957
|
+
target.nodeName != "SELECT" &&
|
958
|
+
target.nodeName != "OPTION")
|
959
|
+
{
|
960
|
+
nextSlide(true);
|
961
|
+
stopPropagation(e);
|
962
|
+
e.cancel = true;
|
963
|
+
e.returnValue = false;
|
964
|
+
}
|
965
|
+
}
|
966
|
+
|
967
|
+
function previousSlide(incremental)
|
968
|
+
{
|
969
|
+
if (!viewAll)
|
970
|
+
{
|
971
|
+
var slide;
|
972
|
+
|
973
|
+
if ((incremental || slidenum == 0) && lastShown != null)
|
974
|
+
{
|
975
|
+
lastShown = hidePreviousItem(lastShown);
|
976
|
+
setEosStatus(false);
|
977
|
+
}
|
978
|
+
else if (slidenum > 0)
|
979
|
+
{
|
980
|
+
slide = slides[slidenum];
|
981
|
+
hideSlide(slide);
|
982
|
+
|
983
|
+
slidenum = slidenum - 1;
|
984
|
+
slide = slides[slidenum];
|
985
|
+
setVisibilityAllIncremental("visible");
|
986
|
+
lastShown = previousIncrementalItem(null);
|
987
|
+
setEosStatus(true);
|
988
|
+
showSlide(slide);
|
989
|
+
}
|
990
|
+
|
991
|
+
setLocation();
|
992
|
+
|
993
|
+
if (!ns_pos)
|
994
|
+
refreshToolbar(200);
|
995
|
+
}
|
996
|
+
}
|
997
|
+
|
998
|
+
function nextSlide(incremental)
|
999
|
+
{
|
1000
|
+
if (!viewAll)
|
1001
|
+
{
|
1002
|
+
var slide, last = lastShown;
|
1003
|
+
|
1004
|
+
if (incremental || slidenum == slides.length - 1)
|
1005
|
+
lastShown = revealNextItem(lastShown);
|
1006
|
+
|
1007
|
+
if ((!incremental || lastShown == null) && slidenum < slides.length - 1)
|
1008
|
+
{
|
1009
|
+
slide = slides[slidenum];
|
1010
|
+
hideSlide(slide);
|
1011
|
+
|
1012
|
+
slidenum = slidenum + 1;
|
1013
|
+
slide = slides[slidenum];
|
1014
|
+
lastShown = null;
|
1015
|
+
setVisibilityAllIncremental("hidden");
|
1016
|
+
showSlide(slide);
|
1017
|
+
}
|
1018
|
+
else if (!lastShown)
|
1019
|
+
{
|
1020
|
+
if (last && incremental)
|
1021
|
+
lastShown = last;
|
1022
|
+
}
|
1023
|
+
|
1024
|
+
setLocation();
|
1025
|
+
|
1026
|
+
setEosStatus(!nextIncrementalItem(lastShown));
|
1027
|
+
|
1028
|
+
if (!ns_pos)
|
1029
|
+
refreshToolbar(200);
|
1030
|
+
}
|
1031
|
+
}
|
1032
|
+
|
1033
|
+
// to first slide with nothing revealed
|
1034
|
+
// i.e. state at start of presentation
|
1035
|
+
function firstSlide()
|
1036
|
+
{
|
1037
|
+
if (!viewAll)
|
1038
|
+
{
|
1039
|
+
var slide;
|
1040
|
+
|
1041
|
+
if (slidenum != 0)
|
1042
|
+
{
|
1043
|
+
slide = slides[slidenum];
|
1044
|
+
hideSlide(slide);
|
1045
|
+
|
1046
|
+
slidenum = 0;
|
1047
|
+
slide = slides[slidenum];
|
1048
|
+
lastShown = null;
|
1049
|
+
setVisibilityAllIncremental("hidden");
|
1050
|
+
showSlide(slide);
|
1051
|
+
}
|
1052
|
+
|
1053
|
+
setEosStatus(!nextIncrementalItem(lastShown));
|
1054
|
+
setLocation();
|
1055
|
+
}
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
|
1059
|
+
// to last slide with everything revealed
|
1060
|
+
// i.e. state at end of presentation
|
1061
|
+
function lastSlide()
|
1062
|
+
{
|
1063
|
+
if (!viewAll)
|
1064
|
+
{
|
1065
|
+
var slide;
|
1066
|
+
|
1067
|
+
lastShown = null; //revealNextItem(lastShown);
|
1068
|
+
|
1069
|
+
if (lastShown == null && slidenum < slides.length - 1)
|
1070
|
+
{
|
1071
|
+
slide = slides[slidenum];
|
1072
|
+
hideSlide(slide);
|
1073
|
+
slidenum = slides.length - 1;
|
1074
|
+
slide = slides[slidenum];
|
1075
|
+
setVisibilityAllIncremental("visible");
|
1076
|
+
lastShown = previousIncrementalItem(null);
|
1077
|
+
|
1078
|
+
showSlide(slide);
|
1079
|
+
}
|
1080
|
+
else
|
1081
|
+
{
|
1082
|
+
setVisibilityAllIncremental("visible");
|
1083
|
+
lastShown = previousIncrementalItem(null);
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
setEosStatus(true);
|
1087
|
+
setLocation();
|
1088
|
+
}
|
1089
|
+
}
|
1090
|
+
|
1091
|
+
function setEosStatus(state)
|
1092
|
+
{
|
1093
|
+
if (eos)
|
1094
|
+
eos.style.color = (state ? "rgb(240,240,240)" : "red");
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
function showSlide(slide)
|
1098
|
+
{
|
1099
|
+
syncBackground(slide);
|
1100
|
+
window.scrollTo(0,0);
|
1101
|
+
slide.style.visibility = "visible";
|
1102
|
+
slide.style.display = "block";
|
1103
|
+
}
|
1104
|
+
|
1105
|
+
function hideSlide(slide)
|
1106
|
+
{
|
1107
|
+
slide.style.visibility = "hidden";
|
1108
|
+
slide.style.display = "none";
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
function beforePrint()
|
1112
|
+
{
|
1113
|
+
showAllSlides();
|
1114
|
+
hideToolbar();
|
1115
|
+
}
|
1116
|
+
|
1117
|
+
function afterPrint()
|
1118
|
+
{
|
1119
|
+
if (!viewAll)
|
1120
|
+
{
|
1121
|
+
singleSlideView();
|
1122
|
+
showToolbar();
|
1123
|
+
}
|
1124
|
+
}
|
1125
|
+
|
1126
|
+
function printSlides()
|
1127
|
+
{
|
1128
|
+
beforePrint();
|
1129
|
+
window.print();
|
1130
|
+
afterPrint();
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
function toggleView()
|
1134
|
+
{
|
1135
|
+
if (viewAll)
|
1136
|
+
{
|
1137
|
+
singleSlideView();
|
1138
|
+
showToolbar();
|
1139
|
+
viewAll = 0;
|
1140
|
+
}
|
1141
|
+
else
|
1142
|
+
{
|
1143
|
+
showAllSlides();
|
1144
|
+
hideToolbar();
|
1145
|
+
viewAll = 1;
|
1146
|
+
}
|
1147
|
+
}
|
1148
|
+
|
1149
|
+
// prepare for printing
|
1150
|
+
function showAllSlides()
|
1151
|
+
{
|
1152
|
+
var slide;
|
1153
|
+
|
1154
|
+
for (var i = 0; i < slides.length; ++i)
|
1155
|
+
{
|
1156
|
+
slide = slides[i];
|
1157
|
+
|
1158
|
+
slide.style.position = "relative";
|
1159
|
+
slide.style.borderTopStyle = "solid";
|
1160
|
+
slide.style.borderTopWidth = "thin";
|
1161
|
+
slide.style.borderTopColor = "black";
|
1162
|
+
|
1163
|
+
try {
|
1164
|
+
if (i == 0)
|
1165
|
+
slide.style.pageBreakBefore = "avoid";
|
1166
|
+
else
|
1167
|
+
slide.style.pageBreakBefore = "always";
|
1168
|
+
}
|
1169
|
+
catch (e)
|
1170
|
+
{
|
1171
|
+
//do nothing
|
1172
|
+
}
|
1173
|
+
|
1174
|
+
setVisibilityAllIncremental("visible");
|
1175
|
+
showSlide(slide);
|
1176
|
+
}
|
1177
|
+
|
1178
|
+
var note;
|
1179
|
+
|
1180
|
+
for (var i = 0; i < notes.length; ++i)
|
1181
|
+
{
|
1182
|
+
showSlide(notes[i]);
|
1183
|
+
}
|
1184
|
+
|
1185
|
+
// no easy way to render background under each slide
|
1186
|
+
// without duplicating the background divs for each slide
|
1187
|
+
// therefore hide backgrounds to avoid messing up slides
|
1188
|
+
hideBackgrounds();
|
1189
|
+
}
|
1190
|
+
|
1191
|
+
// restore after printing
|
1192
|
+
function singleSlideView()
|
1193
|
+
{
|
1194
|
+
var slide;
|
1195
|
+
|
1196
|
+
for (var i = 0; i < slides.length; ++i)
|
1197
|
+
{
|
1198
|
+
slide = slides[i];
|
1199
|
+
|
1200
|
+
slide.style.position = "absolute";
|
1201
|
+
|
1202
|
+
if (i == slidenum)
|
1203
|
+
{
|
1204
|
+
slide.style.borderStyle = "none";
|
1205
|
+
showSlide(slide);
|
1206
|
+
}
|
1207
|
+
else
|
1208
|
+
{
|
1209
|
+
slide.style.borderStyle = "none";
|
1210
|
+
hideSlide(slide);
|
1211
|
+
}
|
1212
|
+
}
|
1213
|
+
|
1214
|
+
setVisibilityAllIncremental("visible");
|
1215
|
+
lastShown = previousIncrementalItem(null);
|
1216
|
+
|
1217
|
+
var note;
|
1218
|
+
|
1219
|
+
for (var i = 0; i < notes.length; ++i)
|
1220
|
+
{
|
1221
|
+
hideSlide(notes[i]);
|
1222
|
+
}
|
1223
|
+
}
|
1224
|
+
|
1225
|
+
// the string str is a whitespace separated list of tokens
|
1226
|
+
// test if str contains a particular token, e.g. "slide"
|
1227
|
+
function hasToken(str, token)
|
1228
|
+
{
|
1229
|
+
if (str)
|
1230
|
+
{
|
1231
|
+
// define pattern as regular expression
|
1232
|
+
var pattern = /\w+/g;
|
1233
|
+
|
1234
|
+
// check for matches
|
1235
|
+
// place result in array
|
1236
|
+
var result = str.match(pattern);
|
1237
|
+
|
1238
|
+
// now check if desired token is present
|
1239
|
+
for (var i = 0; i < result.length; i++)
|
1240
|
+
{
|
1241
|
+
if (result[i] == token)
|
1242
|
+
return true;
|
1243
|
+
}
|
1244
|
+
}
|
1245
|
+
|
1246
|
+
return false;
|
1247
|
+
}
|
1248
|
+
|
1249
|
+
function getClassList(element)
|
1250
|
+
{
|
1251
|
+
if (typeof window.pageYOffset =='undefined')
|
1252
|
+
return element.getAttribute("className");
|
1253
|
+
|
1254
|
+
return element.getAttribute("class");
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
function hasClass(element, name)
|
1258
|
+
{
|
1259
|
+
var regexp = new RegExp("(^| )" + name + "\W*");
|
1260
|
+
|
1261
|
+
if (regexp.test(getClassList(element)))
|
1262
|
+
return true;
|
1263
|
+
|
1264
|
+
return false;
|
1265
|
+
|
1266
|
+
}
|
1267
|
+
|
1268
|
+
function removeClass(element, name)
|
1269
|
+
{
|
1270
|
+
// IE getAttribute requires "class" to be "className"
|
1271
|
+
var clsname = ns_pos ? "class" : "className";
|
1272
|
+
var clsval = element.getAttribute(clsname);
|
1273
|
+
|
1274
|
+
var regexp = new RegExp("(^| )" + name + "\W*");
|
1275
|
+
|
1276
|
+
if (clsval)
|
1277
|
+
{
|
1278
|
+
clsval = clsval.replace(regexp, "");
|
1279
|
+
element.setAttribute(clsname, clsval);
|
1280
|
+
}
|
1281
|
+
}
|
1282
|
+
|
1283
|
+
function addClass(element, name)
|
1284
|
+
{
|
1285
|
+
if (!hasClass(element, name))
|
1286
|
+
{
|
1287
|
+
// IE getAttribute requires "class" to be "className"
|
1288
|
+
var clsname = ns_pos ? "class" : "className";
|
1289
|
+
var clsval = element.getAttribute(clsname);
|
1290
|
+
element.setAttribute(clsname, (clsval ? clsval + " " + name : name));
|
1291
|
+
}
|
1292
|
+
}
|
1293
|
+
|
1294
|
+
// wysiwyg editors make it hard to use div elements
|
1295
|
+
// e.g. amaya loses the div when you copy and paste
|
1296
|
+
// this function wraps div elements around implicit
|
1297
|
+
// slides which start with an h1 element and continue
|
1298
|
+
// up to the next heading or div element
|
1299
|
+
function wrapImplicitSlides()
|
1300
|
+
{
|
1301
|
+
var i, heading, node, next, div;
|
1302
|
+
var headings = document.getElementsByTagName("h1");
|
1303
|
+
|
1304
|
+
if (!headings)
|
1305
|
+
return;
|
1306
|
+
|
1307
|
+
for (i = 0; i < headings.length; ++i)
|
1308
|
+
{
|
1309
|
+
heading = headings[i];
|
1310
|
+
|
1311
|
+
if (heading.parentNode != document.body)
|
1312
|
+
continue;
|
1313
|
+
|
1314
|
+
node = heading.nextSibling;
|
1315
|
+
|
1316
|
+
div = document.createElement("div");
|
1317
|
+
div.setAttribute((ns_pos ? "class" : "className"), "slide");
|
1318
|
+
document.body.replaceChild(div, heading);
|
1319
|
+
div.appendChild(heading);
|
1320
|
+
|
1321
|
+
while (node)
|
1322
|
+
{
|
1323
|
+
if (node.nodeType == 1 && // an element
|
1324
|
+
(node.nodeName == "H1" ||
|
1325
|
+
node.nodeName == "h1" ||
|
1326
|
+
node.nodeName == "DIV" ||
|
1327
|
+
node.nodeName == "div"))
|
1328
|
+
break;
|
1329
|
+
|
1330
|
+
next = node.nextSibling;
|
1331
|
+
node = document.body.removeChild(node);
|
1332
|
+
div.appendChild(node);
|
1333
|
+
node = next;
|
1334
|
+
}
|
1335
|
+
}
|
1336
|
+
}
|
1337
|
+
|
1338
|
+
// return new array of all slides
|
1339
|
+
function collectSlides()
|
1340
|
+
{
|
1341
|
+
var slides = new Array();
|
1342
|
+
var divs = document.body.getElementsByTagName("div");
|
1343
|
+
|
1344
|
+
for (var i = 0; i < divs.length; ++i)
|
1345
|
+
{
|
1346
|
+
div = divs.item(i);
|
1347
|
+
|
1348
|
+
if (hasClass(div, "slide"))
|
1349
|
+
{
|
1350
|
+
// add slide to collection
|
1351
|
+
slides[slides.length] = div;
|
1352
|
+
|
1353
|
+
// hide each slide as it is found
|
1354
|
+
div.style.display = "none";
|
1355
|
+
div.style.visibility = "hidden";
|
1356
|
+
|
1357
|
+
// add dummy <br/> at end for scrolling hack
|
1358
|
+
var node1 = document.createElement("br");
|
1359
|
+
div.appendChild(node1);
|
1360
|
+
var node2 = document.createElement("br");
|
1361
|
+
div.appendChild(node2);
|
1362
|
+
}
|
1363
|
+
else if (hasClass(div, "background"))
|
1364
|
+
{ // work around for Firefox SVG reload bug
|
1365
|
+
// which otherwise replaces 1st SVG graphic with 2nd
|
1366
|
+
div.style.display = "block";
|
1367
|
+
}
|
1368
|
+
}
|
1369
|
+
|
1370
|
+
return slides;
|
1371
|
+
}
|
1372
|
+
|
1373
|
+
// return new array of all <div class="handout">
|
1374
|
+
function collectNotes()
|
1375
|
+
{
|
1376
|
+
var notes = new Array();
|
1377
|
+
var divs = document.body.getElementsByTagName("div");
|
1378
|
+
|
1379
|
+
for (var i = 0; i < divs.length; ++i)
|
1380
|
+
{
|
1381
|
+
div = divs.item(i);
|
1382
|
+
|
1383
|
+
if (hasClass(div, "handout"))
|
1384
|
+
{
|
1385
|
+
// add slide to collection
|
1386
|
+
notes[notes.length] = div;
|
1387
|
+
|
1388
|
+
// hide handout notes as they are found
|
1389
|
+
div.style.display = "none";
|
1390
|
+
div.style.visibility = "hidden";
|
1391
|
+
}
|
1392
|
+
}
|
1393
|
+
|
1394
|
+
return notes;
|
1395
|
+
}
|
1396
|
+
|
1397
|
+
// return new array of all <div class="background">
|
1398
|
+
// including named backgrounds e.g. class="background titlepage"
|
1399
|
+
function collectBackgrounds()
|
1400
|
+
{
|
1401
|
+
var backgrounds = new Array();
|
1402
|
+
var divs = document.body.getElementsByTagName("div");
|
1403
|
+
|
1404
|
+
for (var i = 0; i < divs.length; ++i)
|
1405
|
+
{
|
1406
|
+
div = divs.item(i);
|
1407
|
+
|
1408
|
+
if (hasClass(div, "background"))
|
1409
|
+
{
|
1410
|
+
// add slide to collection
|
1411
|
+
backgrounds[backgrounds.length] = div;
|
1412
|
+
|
1413
|
+
// hide named backgrounds as they are found
|
1414
|
+
// e.g. class="background epilog"
|
1415
|
+
if (getClassList(div) != "background")
|
1416
|
+
{
|
1417
|
+
div.style.display = "none";
|
1418
|
+
div.style.visibility = "hidden";
|
1419
|
+
}
|
1420
|
+
}
|
1421
|
+
}
|
1422
|
+
|
1423
|
+
return backgrounds;
|
1424
|
+
}
|
1425
|
+
|
1426
|
+
// show just the backgrounds pertinent to this slide
|
1427
|
+
function syncBackground(slide)
|
1428
|
+
{
|
1429
|
+
var background;
|
1430
|
+
var bgColor;
|
1431
|
+
|
1432
|
+
if (slide.currentStyle)
|
1433
|
+
bgColor = slide.currentStyle["backgroundColor"];
|
1434
|
+
else if (document.defaultView)
|
1435
|
+
{
|
1436
|
+
var styles = document.defaultView.getComputedStyle(slide,null);
|
1437
|
+
|
1438
|
+
if (styles)
|
1439
|
+
bgColor = styles.getPropertyValue("background-color");
|
1440
|
+
else // broken implementation probably due Safari or Konqueror
|
1441
|
+
{
|
1442
|
+
//alert("defective implementation of getComputedStyle()");
|
1443
|
+
bgColor = "transparent";
|
1444
|
+
}
|
1445
|
+
}
|
1446
|
+
else
|
1447
|
+
bgColor == "transparent";
|
1448
|
+
|
1449
|
+
if (bgColor == "transparent")
|
1450
|
+
{
|
1451
|
+
var slideClass = getClassList(slide);
|
1452
|
+
|
1453
|
+
for (var i = 0; i < backgrounds.length; i++)
|
1454
|
+
{
|
1455
|
+
background = backgrounds[i];
|
1456
|
+
|
1457
|
+
var bgClass = getClassList(background);
|
1458
|
+
|
1459
|
+
if (matchingBackground(slideClass, bgClass))
|
1460
|
+
{
|
1461
|
+
background.style.display = "block";
|
1462
|
+
background.style.visibility = "visible";
|
1463
|
+
}
|
1464
|
+
else
|
1465
|
+
{
|
1466
|
+
background.style.display = "none";
|
1467
|
+
background.style.visibility = "hidden";
|
1468
|
+
}
|
1469
|
+
}
|
1470
|
+
}
|
1471
|
+
else // forcibly hide all backgrounds
|
1472
|
+
hideBackgrounds();
|
1473
|
+
}
|
1474
|
+
|
1475
|
+
function hideBackgrounds()
|
1476
|
+
{
|
1477
|
+
for (var i = 0; i < backgrounds.length; i++)
|
1478
|
+
{
|
1479
|
+
background = backgrounds[i];
|
1480
|
+
background.style.display = "none";
|
1481
|
+
background.style.visibility = "hidden";
|
1482
|
+
}
|
1483
|
+
}
|
1484
|
+
|
1485
|
+
// compare classes for slide and background
|
1486
|
+
function matchingBackground(slideClass, bgClass)
|
1487
|
+
{
|
1488
|
+
if (bgClass == "background")
|
1489
|
+
return true;
|
1490
|
+
|
1491
|
+
// define pattern as regular expression
|
1492
|
+
var pattern = /\w+/g;
|
1493
|
+
|
1494
|
+
// check for matches and place result in array
|
1495
|
+
var result = slideClass.match(pattern);
|
1496
|
+
|
1497
|
+
// now check if desired name is present for background
|
1498
|
+
for (var i = 0; i < result.length; i++)
|
1499
|
+
{
|
1500
|
+
if (hasToken(bgClass, result[i]))
|
1501
|
+
return true;
|
1502
|
+
}
|
1503
|
+
|
1504
|
+
return false;
|
1505
|
+
}
|
1506
|
+
|
1507
|
+
// left to right traversal of root's content
|
1508
|
+
function nextNode(root, node)
|
1509
|
+
{
|
1510
|
+
if (node == null)
|
1511
|
+
return root.firstChild;
|
1512
|
+
|
1513
|
+
if (node.firstChild)
|
1514
|
+
return node.firstChild;
|
1515
|
+
|
1516
|
+
if (node.nextSibling)
|
1517
|
+
return node.nextSibling;
|
1518
|
+
|
1519
|
+
for (;;)
|
1520
|
+
{
|
1521
|
+
node = node.parentNode;
|
1522
|
+
|
1523
|
+
if (!node || node == root)
|
1524
|
+
break;
|
1525
|
+
|
1526
|
+
if (node && node.nextSibling)
|
1527
|
+
return node.nextSibling;
|
1528
|
+
}
|
1529
|
+
|
1530
|
+
return null;
|
1531
|
+
}
|
1532
|
+
|
1533
|
+
// right to left traversal of root's content
|
1534
|
+
function previousNode(root, node)
|
1535
|
+
{
|
1536
|
+
if (node == null)
|
1537
|
+
{
|
1538
|
+
node = root.lastChild;
|
1539
|
+
|
1540
|
+
if (node)
|
1541
|
+
{
|
1542
|
+
while (node.lastChild)
|
1543
|
+
node = node.lastChild;
|
1544
|
+
}
|
1545
|
+
|
1546
|
+
return node;
|
1547
|
+
}
|
1548
|
+
|
1549
|
+
if (node.previousSibling)
|
1550
|
+
{
|
1551
|
+
node = node.previousSibling;
|
1552
|
+
|
1553
|
+
while (node.lastChild)
|
1554
|
+
node = node.lastChild;
|
1555
|
+
|
1556
|
+
return node;
|
1557
|
+
}
|
1558
|
+
|
1559
|
+
if (node.parentNode != root)
|
1560
|
+
return node.parentNode;
|
1561
|
+
|
1562
|
+
return null;
|
1563
|
+
}
|
1564
|
+
|
1565
|
+
// HTML elements that can be used with class="incremental"
|
1566
|
+
// note that you can also put the class on containers like
|
1567
|
+
// up, ol, dl, and div to make their contents appear
|
1568
|
+
// incrementally. Upper case is used since this is what
|
1569
|
+
// browsers report for HTML node names (text/html).
|
1570
|
+
function incrementalElementList()
|
1571
|
+
{
|
1572
|
+
var inclist = new Array();
|
1573
|
+
inclist["P"] = true;
|
1574
|
+
inclist["PRE"] = true;
|
1575
|
+
inclist["LI"] = true;
|
1576
|
+
inclist["BLOCKQUOTE"] = true;
|
1577
|
+
inclist["DT"] = true;
|
1578
|
+
inclist["DD"] = true;
|
1579
|
+
inclist["H2"] = true;
|
1580
|
+
inclist["H3"] = true;
|
1581
|
+
inclist["H4"] = true;
|
1582
|
+
inclist["H5"] = true;
|
1583
|
+
inclist["H6"] = true;
|
1584
|
+
inclist["SPAN"] = true;
|
1585
|
+
inclist["ADDRESS"] = true;
|
1586
|
+
inclist["TABLE"] = true;
|
1587
|
+
inclist["TR"] = true;
|
1588
|
+
inclist["TH"] = true;
|
1589
|
+
inclist["TD"] = true;
|
1590
|
+
inclist["IMG"] = true;
|
1591
|
+
inclist["OBJECT"] = true;
|
1592
|
+
return inclist;
|
1593
|
+
}
|
1594
|
+
|
1595
|
+
function nextIncrementalItem(node)
|
1596
|
+
{
|
1597
|
+
var slide = slides[slidenum];
|
1598
|
+
|
1599
|
+
for (;;)
|
1600
|
+
{
|
1601
|
+
node = nextNode(slide, node);
|
1602
|
+
|
1603
|
+
if (node == null || node.parentNode == null)
|
1604
|
+
break;
|
1605
|
+
|
1606
|
+
if (node.nodeType == 1) // ELEMENT
|
1607
|
+
{
|
1608
|
+
if (node.nodeName == "BR")
|
1609
|
+
continue;
|
1610
|
+
|
1611
|
+
if (hasClass(node, "incremental")
|
1612
|
+
&& okayForIncremental[node.nodeName])
|
1613
|
+
return node;
|
1614
|
+
|
1615
|
+
if (hasClass(node.parentNode, "incremental")
|
1616
|
+
&& !hasClass(node, "non-incremental"))
|
1617
|
+
return node;
|
1618
|
+
}
|
1619
|
+
}
|
1620
|
+
|
1621
|
+
return node;
|
1622
|
+
}
|
1623
|
+
|
1624
|
+
function previousIncrementalItem(node)
|
1625
|
+
{
|
1626
|
+
var slide = slides[slidenum];
|
1627
|
+
|
1628
|
+
for (;;)
|
1629
|
+
{
|
1630
|
+
node = previousNode(slide, node);
|
1631
|
+
|
1632
|
+
if (node == null || node.parentNode == null)
|
1633
|
+
break;
|
1634
|
+
|
1635
|
+
if (node.nodeType == 1)
|
1636
|
+
{
|
1637
|
+
if (node.nodeName == "BR")
|
1638
|
+
continue;
|
1639
|
+
|
1640
|
+
if (hasClass(node, "incremental")
|
1641
|
+
&& okayForIncremental[node.nodeName])
|
1642
|
+
return node;
|
1643
|
+
|
1644
|
+
if (hasClass(node.parentNode, "incremental")
|
1645
|
+
&& !hasClass(node, "non-incremental"))
|
1646
|
+
return node;
|
1647
|
+
}
|
1648
|
+
}
|
1649
|
+
|
1650
|
+
return node;
|
1651
|
+
}
|
1652
|
+
|
1653
|
+
// set visibility for all elements on current slide with
|
1654
|
+
// a parent element with attribute class="incremental"
|
1655
|
+
function setVisibilityAllIncremental(value)
|
1656
|
+
{
|
1657
|
+
var node = nextIncrementalItem(null);
|
1658
|
+
|
1659
|
+
while (node)
|
1660
|
+
{
|
1661
|
+
node.style.visibility = value;
|
1662
|
+
node = nextIncrementalItem(node);
|
1663
|
+
}
|
1664
|
+
}
|
1665
|
+
|
1666
|
+
// reveal the next hidden item on the slide
|
1667
|
+
// node is null or the node that was last revealed
|
1668
|
+
function revealNextItem(node)
|
1669
|
+
{
|
1670
|
+
node = nextIncrementalItem(node);
|
1671
|
+
|
1672
|
+
if (node && node.nodeType == 1) // an element
|
1673
|
+
node.style.visibility = "visible";
|
1674
|
+
|
1675
|
+
return node;
|
1676
|
+
}
|
1677
|
+
|
1678
|
+
|
1679
|
+
// exact inverse of revealNextItem(node)
|
1680
|
+
function hidePreviousItem(node)
|
1681
|
+
{
|
1682
|
+
if (node && node.nodeType == 1) // an element
|
1683
|
+
node.style.visibility = "hidden";
|
1684
|
+
|
1685
|
+
return previousIncrementalItem(node);
|
1686
|
+
}
|
1687
|
+
|
1688
|
+
|
1689
|
+
/* set click handlers on all anchors */
|
1690
|
+
function patchAnchors()
|
1691
|
+
{
|
1692
|
+
var anchors = document.body.getElementsByTagName("a");
|
1693
|
+
|
1694
|
+
for (var i = 0; i < anchors.length; ++i)
|
1695
|
+
{
|
1696
|
+
anchors[i].onclick = clickedAnchor;
|
1697
|
+
}
|
1698
|
+
}
|
1699
|
+
|
1700
|
+
function clickedAnchor(e)
|
1701
|
+
{
|
1702
|
+
if (!e)
|
1703
|
+
var e = window.event;
|
1704
|
+
|
1705
|
+
// compare this.href with location.href
|
1706
|
+
// for link to another slide in this doc
|
1707
|
+
|
1708
|
+
if (pageAddress(this.href) == pageAddress(location.href))
|
1709
|
+
{
|
1710
|
+
// yes, so find new slide number
|
1711
|
+
var newslidenum = findSlideNumber(this.href);
|
1712
|
+
|
1713
|
+
if (newslidenum != slidenum)
|
1714
|
+
{
|
1715
|
+
slide = slides[slidenum];
|
1716
|
+
hideSlide(slide);
|
1717
|
+
slidenum = newslidenum;
|
1718
|
+
slide = slides[slidenum];
|
1719
|
+
showSlide(slide);
|
1720
|
+
setLocation();
|
1721
|
+
}
|
1722
|
+
}
|
1723
|
+
else if (this.target == null)
|
1724
|
+
location.href = this.href;
|
1725
|
+
|
1726
|
+
this.blur();
|
1727
|
+
stopPropagation(e);
|
1728
|
+
}
|
1729
|
+
|
1730
|
+
function pageAddress(uri)
|
1731
|
+
{
|
1732
|
+
var i = uri.indexOf("#");
|
1733
|
+
|
1734
|
+
// check if anchor is entire page
|
1735
|
+
|
1736
|
+
if (i < 0)
|
1737
|
+
return uri; // yes
|
1738
|
+
|
1739
|
+
return uri.substr(0, i);
|
1740
|
+
}
|
1741
|
+
|
1742
|
+
function showSlideNumber()
|
1743
|
+
{
|
1744
|
+
slideNumElement.innerHTML = "slide".localize() + " " +
|
1745
|
+
(slidenum + 1) + "/" + slides.length;
|
1746
|
+
}
|
1747
|
+
|
1748
|
+
function setLocation()
|
1749
|
+
{
|
1750
|
+
var uri = pageAddress(location.href);
|
1751
|
+
|
1752
|
+
//if (slidenum > 0)
|
1753
|
+
uri = uri + "#(" + (slidenum+1) + ")";
|
1754
|
+
|
1755
|
+
if (uri != location.href && !khtml)
|
1756
|
+
location.href = uri;
|
1757
|
+
|
1758
|
+
document.title = title + " (" + (slidenum+1) + ")";
|
1759
|
+
//document.title = (slidenum+1) + ") " + slideName(slidenum);
|
1760
|
+
|
1761
|
+
showSlideNumber();
|
1762
|
+
}
|
1763
|
+
|
1764
|
+
// find current slide based upon location
|
1765
|
+
// first find target anchor and then look
|
1766
|
+
// for associated div element enclosing it
|
1767
|
+
// finally map that to slide number
|
1768
|
+
function findSlideNumber(uri)
|
1769
|
+
{
|
1770
|
+
// first get anchor from page location
|
1771
|
+
|
1772
|
+
var i = uri.indexOf("#");
|
1773
|
+
|
1774
|
+
// check if anchor is entire page
|
1775
|
+
|
1776
|
+
if (i < 0)
|
1777
|
+
return 0; // yes
|
1778
|
+
|
1779
|
+
var anchor = unescape(uri.substr(i+1));
|
1780
|
+
|
1781
|
+
// now use anchor as XML ID to find target
|
1782
|
+
var target = document.getElementById(anchor);
|
1783
|
+
|
1784
|
+
if (!target)
|
1785
|
+
{
|
1786
|
+
// does anchor look like "(2)" for slide 2 ??
|
1787
|
+
// where first slide is (1)
|
1788
|
+
var re = /\((\d)+\)/;
|
1789
|
+
|
1790
|
+
if (anchor.match(re))
|
1791
|
+
{
|
1792
|
+
var num = parseInt(anchor.substring(1, anchor.length-1));
|
1793
|
+
|
1794
|
+
if (num > slides.length)
|
1795
|
+
num = 1;
|
1796
|
+
|
1797
|
+
if (--num < 0)
|
1798
|
+
num = 0;
|
1799
|
+
|
1800
|
+
return num;
|
1801
|
+
}
|
1802
|
+
|
1803
|
+
// accept [2] for backwards compatibility
|
1804
|
+
re = /\[(\d)+\]/;
|
1805
|
+
|
1806
|
+
if (anchor.match(re))
|
1807
|
+
{
|
1808
|
+
var num = parseInt(anchor.substring(1, anchor.length-1));
|
1809
|
+
|
1810
|
+
if (num > slides.length)
|
1811
|
+
num = 1;
|
1812
|
+
|
1813
|
+
if (--num < 0)
|
1814
|
+
num = 0;
|
1815
|
+
|
1816
|
+
return num;
|
1817
|
+
}
|
1818
|
+
|
1819
|
+
// oh dear unknown anchor
|
1820
|
+
return 0;
|
1821
|
+
}
|
1822
|
+
|
1823
|
+
// search for enclosing slide
|
1824
|
+
|
1825
|
+
while (true)
|
1826
|
+
{
|
1827
|
+
// browser coerces html elements to uppercase!
|
1828
|
+
if (target.nodeName.toLowerCase() == "div" &&
|
1829
|
+
hasClass(target, "slide"))
|
1830
|
+
{
|
1831
|
+
// found the slide element
|
1832
|
+
break;
|
1833
|
+
}
|
1834
|
+
|
1835
|
+
// otherwise try parent element if any
|
1836
|
+
|
1837
|
+
target = target.parentNode;
|
1838
|
+
|
1839
|
+
if (!target)
|
1840
|
+
{
|
1841
|
+
return 0; // no luck!
|
1842
|
+
}
|
1843
|
+
};
|
1844
|
+
|
1845
|
+
for (i = 0; i < slides.length; ++i)
|
1846
|
+
{
|
1847
|
+
if (slides[i] == target)
|
1848
|
+
return i; // success
|
1849
|
+
}
|
1850
|
+
|
1851
|
+
// oh dear still no luck
|
1852
|
+
return 0;
|
1853
|
+
}
|
1854
|
+
|
1855
|
+
// find slide name from first h1 element
|
1856
|
+
// default to document title + slide number
|
1857
|
+
function slideName(index)
|
1858
|
+
{
|
1859
|
+
var name = null;
|
1860
|
+
var slide = slides[index];
|
1861
|
+
|
1862
|
+
var heading = findHeading(slide);
|
1863
|
+
|
1864
|
+
if (heading)
|
1865
|
+
name = extractText(heading);
|
1866
|
+
|
1867
|
+
if (!name)
|
1868
|
+
name = title + "(" + (index + 1) + ")";
|
1869
|
+
|
1870
|
+
name.replace(/\&/g, "&");
|
1871
|
+
name.replace(/\</g, "<");
|
1872
|
+
name.replace(/\>/g, ">");
|
1873
|
+
|
1874
|
+
return name;
|
1875
|
+
}
|
1876
|
+
|
1877
|
+
// find first h1 element in DOM tree
|
1878
|
+
function findHeading(node)
|
1879
|
+
{
|
1880
|
+
if (!node || node.nodeType != 1)
|
1881
|
+
return null;
|
1882
|
+
|
1883
|
+
if (node.nodeName == "H1" || node.nodeName == "h1" || node.nodeName == "H2" || node.nodeName == "h2")
|
1884
|
+
return node;
|
1885
|
+
|
1886
|
+
var child = node.firstChild;
|
1887
|
+
|
1888
|
+
while (child)
|
1889
|
+
{
|
1890
|
+
node = findHeading(child);
|
1891
|
+
|
1892
|
+
if (node)
|
1893
|
+
return node;
|
1894
|
+
|
1895
|
+
child = child.nextSibling;
|
1896
|
+
}
|
1897
|
+
|
1898
|
+
return null;
|
1899
|
+
}
|
1900
|
+
|
1901
|
+
// recursively extract text from DOM tree
|
1902
|
+
function extractText(node)
|
1903
|
+
{
|
1904
|
+
if (!node)
|
1905
|
+
return "";
|
1906
|
+
|
1907
|
+
// text nodes
|
1908
|
+
if (node.nodeType == 3)
|
1909
|
+
return node.nodeValue;
|
1910
|
+
|
1911
|
+
// elements
|
1912
|
+
if (node.nodeType == 1)
|
1913
|
+
{
|
1914
|
+
node = node.firstChild;
|
1915
|
+
var text = "";
|
1916
|
+
|
1917
|
+
while (node)
|
1918
|
+
{
|
1919
|
+
text = text + extractText(node);
|
1920
|
+
node = node.nextSibling;
|
1921
|
+
}
|
1922
|
+
|
1923
|
+
return text;
|
1924
|
+
}
|
1925
|
+
|
1926
|
+
return "";
|
1927
|
+
}
|
1928
|
+
|
1929
|
+
|
1930
|
+
// find copyright text from meta element
|
1931
|
+
function findCopyright()
|
1932
|
+
{
|
1933
|
+
var name, content;
|
1934
|
+
var meta = document.getElementsByTagName("meta");
|
1935
|
+
|
1936
|
+
for (var i = 0; i < meta.length; ++i)
|
1937
|
+
{
|
1938
|
+
name = meta[i].getAttribute("name");
|
1939
|
+
content = meta[i].getAttribute("content");
|
1940
|
+
|
1941
|
+
if (name == "copyright")
|
1942
|
+
return content;
|
1943
|
+
}
|
1944
|
+
|
1945
|
+
return null;
|
1946
|
+
}
|
1947
|
+
|
1948
|
+
function findSizeAdjust()
|
1949
|
+
{
|
1950
|
+
var name, content, offset;
|
1951
|
+
var meta = document.getElementsByTagName("meta");
|
1952
|
+
|
1953
|
+
for (var i = 0; i < meta.length; ++i)
|
1954
|
+
{
|
1955
|
+
name = meta[i].getAttribute("name");
|
1956
|
+
content = meta[i].getAttribute("content");
|
1957
|
+
|
1958
|
+
if (name == "font-size-adjustment")
|
1959
|
+
return 1 * content;
|
1960
|
+
}
|
1961
|
+
|
1962
|
+
return 0;
|
1963
|
+
}
|
1964
|
+
|
1965
|
+
function addToolbar()
|
1966
|
+
{
|
1967
|
+
var slideCounter, page;
|
1968
|
+
|
1969
|
+
var toolbar = createElement("div");
|
1970
|
+
toolbar.setAttribute("class", "toolbar");
|
1971
|
+
|
1972
|
+
if (ns_pos) // a reasonably behaved browser
|
1973
|
+
{
|
1974
|
+
var right = document.createElement("div");
|
1975
|
+
right.setAttribute("style", "float: right; text-align: right");
|
1976
|
+
|
1977
|
+
slideCounter = document.createElement("div")
|
1978
|
+
slideCounter.innerHTML = "slide".localize() + " n/m";
|
1979
|
+
right.appendChild(slideCounter);
|
1980
|
+
toolbar.appendChild(right);
|
1981
|
+
|
1982
|
+
var left = document.createElement("div");
|
1983
|
+
left.setAttribute("style", "text-align: left");
|
1984
|
+
|
1985
|
+
// global end of slide indicator
|
1986
|
+
eos = document.createElement("span");
|
1987
|
+
eos.innerHTML = "* ";
|
1988
|
+
left.appendChild(eos);
|
1989
|
+
|
1990
|
+
var help = document.createElement("a");
|
1991
|
+
help.setAttribute("href", helpPage);
|
1992
|
+
help.setAttribute("title", helpText.localize());
|
1993
|
+
help.innerHTML = "help?".localize();
|
1994
|
+
left.appendChild(help);
|
1995
|
+
helpAnchor = help; // save for focus hack
|
1996
|
+
|
1997
|
+
var gap1 = document.createTextNode(" ");
|
1998
|
+
left.appendChild(gap1);
|
1999
|
+
|
2000
|
+
var contents = document.createElement("a");
|
2001
|
+
contents.setAttribute("href", "javascript:toggleTableOfContents()");
|
2002
|
+
contents.setAttribute("title", "table of contents".localize());
|
2003
|
+
contents.innerHTML = "contents?".localize();
|
2004
|
+
left.appendChild(contents);
|
2005
|
+
|
2006
|
+
var gap2 = document.createTextNode(" ");
|
2007
|
+
left.appendChild(gap2);
|
2008
|
+
|
2009
|
+
var i = location.href.indexOf("#");
|
2010
|
+
|
2011
|
+
// check if anchor is entire page
|
2012
|
+
|
2013
|
+
if (i > 0)
|
2014
|
+
page = location.href.substr(0, i);
|
2015
|
+
else
|
2016
|
+
page = location.href;
|
2017
|
+
|
2018
|
+
var start = document.createElement("a");
|
2019
|
+
start.setAttribute("href", page);
|
2020
|
+
start.setAttribute("title", "restart presentation".localize());
|
2021
|
+
start.innerHTML = "restart?".localize();
|
2022
|
+
// start.setAttribute("href", "javascript:printSlides()");
|
2023
|
+
// start.setAttribute("title", "print all slides".localize());
|
2024
|
+
// start.innerHTML = "print!".localize();
|
2025
|
+
left.appendChild(start);
|
2026
|
+
|
2027
|
+
var copyright = findCopyright();
|
2028
|
+
|
2029
|
+
if (copyright)
|
2030
|
+
{
|
2031
|
+
var span = document.createElement("span");
|
2032
|
+
span.innerHTML = copyright;
|
2033
|
+
span.style.color = "black";
|
2034
|
+
span.style.marginLeft = "4em";
|
2035
|
+
left.appendChild(span);
|
2036
|
+
}
|
2037
|
+
|
2038
|
+
toolbar.appendChild(left);
|
2039
|
+
}
|
2040
|
+
else // IE so need to work around its poor CSS support
|
2041
|
+
{
|
2042
|
+
toolbar.style.position = (ie7 ? "fixed" : "absolute");
|
2043
|
+
toolbar.style.zIndex = "200";
|
2044
|
+
toolbar.style.width = "99.9%";
|
2045
|
+
toolbar.style.height = "1.2em";
|
2046
|
+
toolbar.style.top = "auto";
|
2047
|
+
toolbar.style.bottom = "0";
|
2048
|
+
toolbar.style.left = "0";
|
2049
|
+
toolbar.style.right = "0";
|
2050
|
+
toolbar.style.textAlign = "left";
|
2051
|
+
toolbar.style.fontSize = "60%";
|
2052
|
+
toolbar.style.color = "red";
|
2053
|
+
toolbar.borderWidth = 0;
|
2054
|
+
toolbar.style.background = "rgb(240,240,240)";
|
2055
|
+
|
2056
|
+
// would like to have help text left aligned
|
2057
|
+
// and page counter right aligned, floating
|
2058
|
+
// div's don't work, so instead use nested
|
2059
|
+
// absolutely positioned div's.
|
2060
|
+
|
2061
|
+
var sp = document.createElement("span");
|
2062
|
+
sp.innerHTML = " * ";
|
2063
|
+
toolbar.appendChild(sp);
|
2064
|
+
eos = sp; // end of slide indicator
|
2065
|
+
|
2066
|
+
var help = document.createElement("a");
|
2067
|
+
help.setAttribute("href", helpPage);
|
2068
|
+
help.setAttribute("title", helpText.localize());
|
2069
|
+
help.innerHTML = "help?".localize();
|
2070
|
+
toolbar.appendChild(help);
|
2071
|
+
helpAnchor = help; // save for focus hack
|
2072
|
+
|
2073
|
+
var gap1 = document.createTextNode(" ");
|
2074
|
+
toolbar.appendChild(gap1);
|
2075
|
+
|
2076
|
+
var contents = document.createElement("a");
|
2077
|
+
contents.setAttribute("href", "javascript:toggleTableOfContents()");
|
2078
|
+
contents.setAttribute("title", "table of contents".localize());
|
2079
|
+
contents.innerHTML = "contents?".localize();
|
2080
|
+
toolbar.appendChild(contents);
|
2081
|
+
|
2082
|
+
var gap2 = document.createTextNode(" ");
|
2083
|
+
toolbar.appendChild(gap2);
|
2084
|
+
|
2085
|
+
var i = location.href.indexOf("#");
|
2086
|
+
|
2087
|
+
// check if anchor is entire page
|
2088
|
+
|
2089
|
+
if (i > 0)
|
2090
|
+
page = location.href.substr(0, i);
|
2091
|
+
else
|
2092
|
+
page = location.href;
|
2093
|
+
|
2094
|
+
var start = document.createElement("a");
|
2095
|
+
start.setAttribute("href", page);
|
2096
|
+
start.setAttribute("title", "restart presentation".localize());
|
2097
|
+
start.innerHTML = "restart?".localize();
|
2098
|
+
// start.setAttribute("href", "javascript:printSlides()");
|
2099
|
+
// start.setAttribute("title", "print all slides".localize());
|
2100
|
+
// start.innerHTML = "print!".localize();
|
2101
|
+
toolbar.appendChild(start);
|
2102
|
+
|
2103
|
+
var copyright = findCopyright();
|
2104
|
+
|
2105
|
+
if (copyright)
|
2106
|
+
{
|
2107
|
+
var span = document.createElement("span");
|
2108
|
+
span.innerHTML = copyright;
|
2109
|
+
span.style.color = "black";
|
2110
|
+
span.style.marginLeft = "2em";
|
2111
|
+
toolbar.appendChild(span);
|
2112
|
+
}
|
2113
|
+
|
2114
|
+
slideCounter = document.createElement("div")
|
2115
|
+
slideCounter.style.position = "absolute";
|
2116
|
+
slideCounter.style.width = "auto"; //"20%";
|
2117
|
+
slideCounter.style.height = "1.2em";
|
2118
|
+
slideCounter.style.top = "auto";
|
2119
|
+
slideCounter.style.bottom = 0;
|
2120
|
+
slideCounter.style.right = "0";
|
2121
|
+
slideCounter.style.textAlign = "right";
|
2122
|
+
slideCounter.style.color = "red";
|
2123
|
+
slideCounter.style.background = "rgb(240,240,240)";
|
2124
|
+
|
2125
|
+
slideCounter.innerHTML = "slide".localize() + " n/m";
|
2126
|
+
toolbar.appendChild(slideCounter);
|
2127
|
+
}
|
2128
|
+
|
2129
|
+
// ensure that click isn't passed through to the page
|
2130
|
+
toolbar.onclick = stopPropagation;
|
2131
|
+
document.body.appendChild(toolbar);
|
2132
|
+
slideNumElement = slideCounter;
|
2133
|
+
setEosStatus(false);
|
2134
|
+
|
2135
|
+
return toolbar;
|
2136
|
+
}
|
2137
|
+
|
2138
|
+
function isShownToc()
|
2139
|
+
{
|
2140
|
+
if (toc && toc.style.visible == "visible")
|
2141
|
+
return true;
|
2142
|
+
|
2143
|
+
return false;
|
2144
|
+
}
|
2145
|
+
|
2146
|
+
function showTableOfContents()
|
2147
|
+
{
|
2148
|
+
if (toc)
|
2149
|
+
{
|
2150
|
+
if (toc.style.visibility != "visible")
|
2151
|
+
{
|
2152
|
+
toc.style.visibility = "visible";
|
2153
|
+
toc.style.display = "block";
|
2154
|
+
toc.focus();
|
2155
|
+
|
2156
|
+
if (ie7 && slidenum == 0)
|
2157
|
+
setTimeout("ieHack()", 100);
|
2158
|
+
}
|
2159
|
+
else
|
2160
|
+
hideTableOfContents();
|
2161
|
+
}
|
2162
|
+
}
|
2163
|
+
|
2164
|
+
function hideTableOfContents()
|
2165
|
+
{
|
2166
|
+
if (toc && toc.style.visibility != "hidden")
|
2167
|
+
{
|
2168
|
+
toc.style.visibility = "hidden";
|
2169
|
+
toc.style.display = "none";
|
2170
|
+
|
2171
|
+
try
|
2172
|
+
{
|
2173
|
+
if (!opera)
|
2174
|
+
helpAnchor.focus();
|
2175
|
+
}
|
2176
|
+
catch (e)
|
2177
|
+
{
|
2178
|
+
}
|
2179
|
+
}
|
2180
|
+
}
|
2181
|
+
|
2182
|
+
function toggleTableOfContents()
|
2183
|
+
{
|
2184
|
+
if (toc)
|
2185
|
+
{
|
2186
|
+
if (toc.style.visible != "visible")
|
2187
|
+
showTableOfContents();
|
2188
|
+
else
|
2189
|
+
hideTableOfContents();
|
2190
|
+
}
|
2191
|
+
}
|
2192
|
+
|
2193
|
+
// called on clicking toc entry
|
2194
|
+
function gotoEntry(e)
|
2195
|
+
{
|
2196
|
+
var target;
|
2197
|
+
|
2198
|
+
if (!e)
|
2199
|
+
var e = window.event;
|
2200
|
+
|
2201
|
+
if (e.target)
|
2202
|
+
target = e.target;
|
2203
|
+
else if (e.srcElement)
|
2204
|
+
target = e.srcElement;
|
2205
|
+
|
2206
|
+
// work around Safari bug
|
2207
|
+
if (target.nodeType == 3)
|
2208
|
+
target = target.parentNode;
|
2209
|
+
|
2210
|
+
if (target && target.nodeType == 1)
|
2211
|
+
{
|
2212
|
+
var uri = target.getAttribute("href");
|
2213
|
+
|
2214
|
+
if (uri)
|
2215
|
+
{
|
2216
|
+
//alert("going to " + uri);
|
2217
|
+
var slide = slides[slidenum];
|
2218
|
+
hideSlide(slide);
|
2219
|
+
slidenum = findSlideNumber(uri);
|
2220
|
+
slide = slides[slidenum];
|
2221
|
+
lastShown = null;
|
2222
|
+
setLocation();
|
2223
|
+
setVisibilityAllIncremental("hidden");
|
2224
|
+
setEosStatus(!nextIncrementalItem(lastShown));
|
2225
|
+
showSlide(slide);
|
2226
|
+
//target.focus();
|
2227
|
+
|
2228
|
+
try
|
2229
|
+
{
|
2230
|
+
if (!opera)
|
2231
|
+
helpAnchor.focus();
|
2232
|
+
}
|
2233
|
+
catch (e)
|
2234
|
+
{
|
2235
|
+
}
|
2236
|
+
}
|
2237
|
+
}
|
2238
|
+
|
2239
|
+
hideTableOfContents(e);
|
2240
|
+
if (ie7) ieHack();
|
2241
|
+
stopPropagation(e);
|
2242
|
+
return cancel(e);
|
2243
|
+
}
|
2244
|
+
|
2245
|
+
// called onkeydown for toc entry
|
2246
|
+
function gotoTocEntry(event)
|
2247
|
+
{
|
2248
|
+
var key;
|
2249
|
+
|
2250
|
+
if (!event)
|
2251
|
+
var event = window.event;
|
2252
|
+
|
2253
|
+
// kludge around NS/IE differences
|
2254
|
+
if (window.event)
|
2255
|
+
key = window.event.keyCode;
|
2256
|
+
else if (event.which)
|
2257
|
+
key = event.which;
|
2258
|
+
else
|
2259
|
+
return true; // Yikes! unknown browser
|
2260
|
+
|
2261
|
+
// ignore event if key value is zero
|
2262
|
+
// as for alt on Opera and Konqueror
|
2263
|
+
if (!key)
|
2264
|
+
return true;
|
2265
|
+
|
2266
|
+
// check for concurrent control/command/alt key
|
2267
|
+
// but are these only present on mouse events?
|
2268
|
+
|
2269
|
+
if (event.ctrlKey || event.altKey)
|
2270
|
+
return true;
|
2271
|
+
|
2272
|
+
if (key == 13)
|
2273
|
+
{
|
2274
|
+
var uri = this.getAttribute("href");
|
2275
|
+
|
2276
|
+
if (uri)
|
2277
|
+
{
|
2278
|
+
//alert("going to " + uri);
|
2279
|
+
var slide = slides[slidenum];
|
2280
|
+
hideSlide(slide);
|
2281
|
+
slidenum = findSlideNumber(uri);
|
2282
|
+
slide = slides[slidenum];
|
2283
|
+
lastShown = null;
|
2284
|
+
setLocation();
|
2285
|
+
setVisibilityAllIncremental("hidden");
|
2286
|
+
setEosStatus(!nextIncrementalItem(lastShown));
|
2287
|
+
showSlide(slide);
|
2288
|
+
//target.focus();
|
2289
|
+
|
2290
|
+
try
|
2291
|
+
{
|
2292
|
+
if (!opera)
|
2293
|
+
helpAnchor.focus();
|
2294
|
+
}
|
2295
|
+
catch (e)
|
2296
|
+
{
|
2297
|
+
}
|
2298
|
+
}
|
2299
|
+
|
2300
|
+
hideTableOfContents();
|
2301
|
+
if (ie7) ieHack();
|
2302
|
+
return cancel(event);
|
2303
|
+
}
|
2304
|
+
|
2305
|
+
if (key == 40 && this.next)
|
2306
|
+
{
|
2307
|
+
this.next.focus();
|
2308
|
+
return cancel(event);
|
2309
|
+
}
|
2310
|
+
|
2311
|
+
if (key == 38 && this.previous)
|
2312
|
+
{
|
2313
|
+
this.previous.focus();
|
2314
|
+
return cancel(event);
|
2315
|
+
}
|
2316
|
+
|
2317
|
+
return true;
|
2318
|
+
}
|
2319
|
+
|
2320
|
+
function isTitleSlide(slide)
|
2321
|
+
{
|
2322
|
+
return hasClass(slide, "title");
|
2323
|
+
}
|
2324
|
+
|
2325
|
+
// create div element with links to each slide
|
2326
|
+
function tableOfContents()
|
2327
|
+
{
|
2328
|
+
var toc = document.createElement("div");
|
2329
|
+
addClass(toc, "toc");
|
2330
|
+
//toc.setAttribute("tabindex", "0");
|
2331
|
+
|
2332
|
+
var heading = document.createElement("div");
|
2333
|
+
addClass(heading, "toc-heading");
|
2334
|
+
heading.innerHTML = "Table of Contents".localize();
|
2335
|
+
|
2336
|
+
heading.style.textAlign = "center";
|
2337
|
+
heading.style.width = "100%";
|
2338
|
+
heading.style.margin = "0";
|
2339
|
+
heading.style.marginBottom = "1em";
|
2340
|
+
heading.style.borderBottomStyle = "solid";
|
2341
|
+
heading.style.borderBottomColor = "rgb(180,180,180)";
|
2342
|
+
heading.style.borderBottomWidth = "1px";
|
2343
|
+
|
2344
|
+
toc.appendChild(heading);
|
2345
|
+
var previous = null;
|
2346
|
+
|
2347
|
+
for (var i = 0; i < slides.length; ++i)
|
2348
|
+
{
|
2349
|
+
var title = hasClass(slides[i], "title");
|
2350
|
+
var num = document.createTextNode((i + 1) + ". ");
|
2351
|
+
|
2352
|
+
toc.appendChild(num);
|
2353
|
+
|
2354
|
+
var a = document.createElement("a");
|
2355
|
+
a.setAttribute("href", "#(" + (i+1) + ")");
|
2356
|
+
|
2357
|
+
if (title)
|
2358
|
+
addClass(a, "titleslide");
|
2359
|
+
|
2360
|
+
var name = document.createTextNode(slideName(i));
|
2361
|
+
a.appendChild(name);
|
2362
|
+
a.onclick = gotoEntry;
|
2363
|
+
a.onkeydown = gotoTocEntry;
|
2364
|
+
a.previous = previous;
|
2365
|
+
|
2366
|
+
if (previous)
|
2367
|
+
previous.next = a;
|
2368
|
+
|
2369
|
+
toc.appendChild(a);
|
2370
|
+
|
2371
|
+
if (i == 0)
|
2372
|
+
toc.first = a;
|
2373
|
+
|
2374
|
+
if (i < slides.length - 1)
|
2375
|
+
{
|
2376
|
+
var br = document.createElement("br");
|
2377
|
+
toc.appendChild(br);
|
2378
|
+
}
|
2379
|
+
|
2380
|
+
previous = a;
|
2381
|
+
}
|
2382
|
+
|
2383
|
+
toc.focus = function () {
|
2384
|
+
if (this.first)
|
2385
|
+
this.first.focus();
|
2386
|
+
}
|
2387
|
+
|
2388
|
+
toc.onclick = function (e) {
|
2389
|
+
e||(e=window.event);
|
2390
|
+
hideTableOfContents();
|
2391
|
+
stopPropagation(e);
|
2392
|
+
|
2393
|
+
if (e.cancel != undefined)
|
2394
|
+
e.cancel = true;
|
2395
|
+
|
2396
|
+
if (e.returnValue != undefined)
|
2397
|
+
e.returnValue = false;
|
2398
|
+
|
2399
|
+
return false;
|
2400
|
+
};
|
2401
|
+
|
2402
|
+
toc.style.position = "absolute";
|
2403
|
+
toc.style.zIndex = "300";
|
2404
|
+
toc.style.width = "60%";
|
2405
|
+
toc.style.maxWidth = "30em";
|
2406
|
+
toc.style.height = "30em";
|
2407
|
+
toc.style.overflow = "auto";
|
2408
|
+
toc.style.top = "auto";
|
2409
|
+
toc.style.right = "auto";
|
2410
|
+
toc.style.left = "4em";
|
2411
|
+
toc.style.bottom = "4em";
|
2412
|
+
toc.style.padding = "1em";
|
2413
|
+
toc.style.background = "rgb(240,240,240)";
|
2414
|
+
toc.style.borderStyle = "solid";
|
2415
|
+
toc.style.borderWidth = "2px";
|
2416
|
+
toc.style.fontSize = "60%";
|
2417
|
+
|
2418
|
+
document.body.insertBefore(toc, document.body.firstChild);
|
2419
|
+
return toc;
|
2420
|
+
}
|
2421
|
+
|
2422
|
+
function replaceByNonBreakingSpace(str)
|
2423
|
+
{
|
2424
|
+
for (var i = 0; i < str.length; ++i)
|
2425
|
+
str[i] = 160;
|
2426
|
+
}
|
2427
|
+
|
2428
|
+
|
2429
|
+
function initOutliner()
|
2430
|
+
{
|
2431
|
+
var items = document.getElementsByTagName("LI");
|
2432
|
+
|
2433
|
+
for (var i = 0; i < items.length; ++i)
|
2434
|
+
{
|
2435
|
+
var target = items[i];
|
2436
|
+
|
2437
|
+
if (!hasClass(target.parentNode, "outline"))
|
2438
|
+
continue;
|
2439
|
+
|
2440
|
+
target.onclick = outlineClick;
|
2441
|
+
|
2442
|
+
if (!ns_pos)
|
2443
|
+
{
|
2444
|
+
target.onmouseover = hoverOutline;
|
2445
|
+
target.onmouseout = unhoverOutline;
|
2446
|
+
}
|
2447
|
+
|
2448
|
+
if (foldable(target))
|
2449
|
+
{
|
2450
|
+
target.foldable = true;
|
2451
|
+
target.onfocus = function () {outline = this;};
|
2452
|
+
target.onblur = function () {outline = null;};
|
2453
|
+
|
2454
|
+
if (!target.getAttribute("tabindex"))
|
2455
|
+
target.setAttribute("tabindex", "0");
|
2456
|
+
|
2457
|
+
if (hasClass(target, "expand"))
|
2458
|
+
unfold(target);
|
2459
|
+
else
|
2460
|
+
fold(target);
|
2461
|
+
}
|
2462
|
+
else
|
2463
|
+
{
|
2464
|
+
addClass(target, "nofold");
|
2465
|
+
target.visible = true;
|
2466
|
+
target.foldable = false;
|
2467
|
+
}
|
2468
|
+
}
|
2469
|
+
}
|
2470
|
+
|
2471
|
+
function foldable(item)
|
2472
|
+
{
|
2473
|
+
if (!item || item.nodeType != 1)
|
2474
|
+
return false;
|
2475
|
+
|
2476
|
+
var node = item.firstChild;
|
2477
|
+
|
2478
|
+
while (node)
|
2479
|
+
{
|
2480
|
+
if (node.nodeType == 1 && isBlock(node))
|
2481
|
+
return true;
|
2482
|
+
|
2483
|
+
node = node.nextSibling;
|
2484
|
+
}
|
2485
|
+
|
2486
|
+
return false;
|
2487
|
+
}
|
2488
|
+
|
2489
|
+
function fold(item)
|
2490
|
+
{
|
2491
|
+
if (item)
|
2492
|
+
{
|
2493
|
+
removeClass(item, "unfolded");
|
2494
|
+
addClass(item, "folded");
|
2495
|
+
}
|
2496
|
+
|
2497
|
+
var node = item ? item.firstChild : null;
|
2498
|
+
|
2499
|
+
while (node)
|
2500
|
+
{
|
2501
|
+
if (node.nodeType == 1 && isBlock(node)) // element
|
2502
|
+
{
|
2503
|
+
// note that getElementStyle won't work for Safari 1.3
|
2504
|
+
node.display = getElementStyle(node, "display", "display");
|
2505
|
+
node.style.display = "none";
|
2506
|
+
node.style.visibility = "hidden";
|
2507
|
+
}
|
2508
|
+
|
2509
|
+
node = node.nextSibling;
|
2510
|
+
}
|
2511
|
+
|
2512
|
+
item.visible = false;
|
2513
|
+
}
|
2514
|
+
|
2515
|
+
function unfold(item)
|
2516
|
+
{
|
2517
|
+
if (item)
|
2518
|
+
{
|
2519
|
+
addClass(item, "unfolded");
|
2520
|
+
removeClass(item, "folded");
|
2521
|
+
}
|
2522
|
+
|
2523
|
+
var node = item ? item.firstChild : null;
|
2524
|
+
|
2525
|
+
while (node)
|
2526
|
+
{
|
2527
|
+
if (node.nodeType == 1 && isBlock(node)) // element
|
2528
|
+
{
|
2529
|
+
// with fallback for Safari, see above
|
2530
|
+
node.style.display = (node.display ? node.display : "block");
|
2531
|
+
node.style.visibility = "visible";
|
2532
|
+
}
|
2533
|
+
|
2534
|
+
node = node.nextSibling;
|
2535
|
+
}
|
2536
|
+
|
2537
|
+
item.visible = true;
|
2538
|
+
}
|
2539
|
+
|
2540
|
+
function outlineClick(e)
|
2541
|
+
{
|
2542
|
+
var rightclick = false;
|
2543
|
+
var target;
|
2544
|
+
|
2545
|
+
if (!e)
|
2546
|
+
var e = window.event;
|
2547
|
+
|
2548
|
+
if (e.target)
|
2549
|
+
target = e.target;
|
2550
|
+
else if (e.srcElement)
|
2551
|
+
target = e.srcElement;
|
2552
|
+
|
2553
|
+
// work around Safari bug
|
2554
|
+
if (target.nodeType == 3)
|
2555
|
+
target = target.parentNode;
|
2556
|
+
|
2557
|
+
while (target && target.visible == undefined)
|
2558
|
+
target = target.parentNode;
|
2559
|
+
|
2560
|
+
if (!target)
|
2561
|
+
return true;
|
2562
|
+
|
2563
|
+
if (e.which)
|
2564
|
+
rightclick = (e.which == 3);
|
2565
|
+
else if (e.button)
|
2566
|
+
rightclick = (e.button == 2);
|
2567
|
+
|
2568
|
+
if (!rightclick && target.visible != undefined)
|
2569
|
+
{
|
2570
|
+
if (target.foldable)
|
2571
|
+
{
|
2572
|
+
if (target.visible)
|
2573
|
+
fold(target);
|
2574
|
+
else
|
2575
|
+
unfold(target);
|
2576
|
+
}
|
2577
|
+
|
2578
|
+
stopPropagation(e);
|
2579
|
+
e.cancel = true;
|
2580
|
+
e.returnValue = false;
|
2581
|
+
}
|
2582
|
+
|
2583
|
+
return false;
|
2584
|
+
}
|
2585
|
+
|
2586
|
+
function hoverOutline(e)
|
2587
|
+
{
|
2588
|
+
var target;
|
2589
|
+
|
2590
|
+
if (!e)
|
2591
|
+
var e = window.event;
|
2592
|
+
|
2593
|
+
if (e.target)
|
2594
|
+
target = e.target;
|
2595
|
+
else if (e.srcElement)
|
2596
|
+
target = e.srcElement;
|
2597
|
+
|
2598
|
+
// work around Safari bug
|
2599
|
+
if (target.nodeType == 3)
|
2600
|
+
target = target.parentNode;
|
2601
|
+
|
2602
|
+
while (target && target.visible == undefined)
|
2603
|
+
target = target.parentNode;
|
2604
|
+
|
2605
|
+
if (target && target.foldable)
|
2606
|
+
target.style.cursor = "pointer";
|
2607
|
+
|
2608
|
+
return true;
|
2609
|
+
}
|
2610
|
+
|
2611
|
+
function unhoverOutline(e)
|
2612
|
+
{
|
2613
|
+
var target;
|
2614
|
+
|
2615
|
+
if (!e)
|
2616
|
+
var e = window.event;
|
2617
|
+
|
2618
|
+
if (e.target)
|
2619
|
+
target = e.target;
|
2620
|
+
else if (e.srcElement)
|
2621
|
+
target = e.srcElement;
|
2622
|
+
|
2623
|
+
// work around Safari bug
|
2624
|
+
if (target.nodeType == 3)
|
2625
|
+
target = target.parentNode;
|
2626
|
+
|
2627
|
+
while (target && target.visible == undefined)
|
2628
|
+
target = target.parentNode;
|
2629
|
+
|
2630
|
+
if (target)
|
2631
|
+
target.style.cursor = "default";
|
2632
|
+
|
2633
|
+
return true;
|
2634
|
+
}
|
2635
|
+
|
2636
|
+
|
2637
|
+
function stopPropagation(e)
|
2638
|
+
{
|
2639
|
+
if (window.event)
|
2640
|
+
{
|
2641
|
+
window.event.cancelBubble = true;
|
2642
|
+
//window.event.returnValue = false;
|
2643
|
+
}
|
2644
|
+
else if (e)
|
2645
|
+
{
|
2646
|
+
e.cancelBubble = true;
|
2647
|
+
e.stopPropagation();
|
2648
|
+
//e.preventDefault();
|
2649
|
+
}
|
2650
|
+
}
|
2651
|
+
|
2652
|
+
/* can't rely on display since we set that to none to hide things */
|
2653
|
+
function isBlock(elem)
|
2654
|
+
{
|
2655
|
+
var tag = elem.nodeName;
|
2656
|
+
|
2657
|
+
return tag == "OL" || tag == "UL" || tag == "P" ||
|
2658
|
+
tag == "LI" || tag == "TABLE" || tag == "PRE" ||
|
2659
|
+
tag == "H1" || tag == "H2" || tag == "H3" ||
|
2660
|
+
tag == "H4" || tag == "H5" || tag == "H6" ||
|
2661
|
+
tag == "BLOCKQUOTE" || tag == "ADDRESS";
|
2662
|
+
}
|
2663
|
+
|
2664
|
+
function getElementStyle(elem, IEStyleProp, CSSStyleProp)
|
2665
|
+
{
|
2666
|
+
if (elem.currentStyle)
|
2667
|
+
{
|
2668
|
+
return elem.currentStyle[IEStyleProp];
|
2669
|
+
}
|
2670
|
+
else if (window.getComputedStyle)
|
2671
|
+
{
|
2672
|
+
var compStyle = window.getComputedStyle(elem, "");
|
2673
|
+
return compStyle.getPropertyValue(CSSStyleProp);
|
2674
|
+
}
|
2675
|
+
return "";
|
2676
|
+
}
|
2677
|
+
|
2678
|
+
// works with text/html and text/xhtml+xml with thanks to Simon Willison
|
2679
|
+
function createElement(element)
|
2680
|
+
{
|
2681
|
+
if (typeof document.createElementNS != 'undefined')
|
2682
|
+
{
|
2683
|
+
return document.createElementNS('http://www.w3.org/1999/xhtml', element);
|
2684
|
+
}
|
2685
|
+
|
2686
|
+
if (typeof document.createElement != 'undefined')
|
2687
|
+
{
|
2688
|
+
return document.createElement(element);
|
2689
|
+
}
|
2690
|
+
|
2691
|
+
return false;
|
2692
|
+
}
|
2693
|
+
|
2694
|
+
// designed to work with both text/html and text/xhtml+xml
|
2695
|
+
function getElementsByTagName(name)
|
2696
|
+
{
|
2697
|
+
if (typeof document.getElementsByTagNameNS != 'undefined')
|
2698
|
+
{
|
2699
|
+
return document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', name);
|
2700
|
+
}
|
2701
|
+
|
2702
|
+
if (typeof document.getElementsByTagName != 'undefined')
|
2703
|
+
{
|
2704
|
+
return document.getElementsByTagName(name);
|
2705
|
+
}
|
2706
|
+
|
2707
|
+
return null;
|
2708
|
+
}
|
2709
|
+
|
2710
|
+
/*
|
2711
|
+
// clean alternative to innerHTML method, but on IE6
|
2712
|
+
// it doesn't work with named entities like
|
2713
|
+
// which need to be replaced by numeric entities
|
2714
|
+
function insertText(element, text)
|
2715
|
+
{
|
2716
|
+
try
|
2717
|
+
{
|
2718
|
+
element.textContent = text; // DOM3 only
|
2719
|
+
}
|
2720
|
+
catch (e)
|
2721
|
+
{
|
2722
|
+
if (element.firstChild)
|
2723
|
+
{
|
2724
|
+
// remove current children
|
2725
|
+
while (element.firstChild)
|
2726
|
+
element.removeChild(element.firstChild);
|
2727
|
+
}
|
2728
|
+
|
2729
|
+
element.appendChild(document.createTextNode(text));
|
2730
|
+
}
|
2731
|
+
}
|
2732
|
+
|
2733
|
+
// as above, but as method of all element nodes
|
2734
|
+
// doesn't work in IE6 which doesn't allow you to
|
2735
|
+
// add methods to the HTMLElement prototype
|
2736
|
+
if (HTMLElement != undefined)
|
2737
|
+
{
|
2738
|
+
HTMLElement.prototype.insertText = function(text) {
|
2739
|
+
var element = this;
|
2740
|
+
|
2741
|
+
try
|
2742
|
+
{
|
2743
|
+
element.textContent = text; // DOM3 only
|
2744
|
+
}
|
2745
|
+
catch (e)
|
2746
|
+
{
|
2747
|
+
if (element.firstChild)
|
2748
|
+
{
|
2749
|
+
// remove current children
|
2750
|
+
while (element.firstChild)
|
2751
|
+
element.removeChild(element.firstChild);
|
2752
|
+
}
|
2753
|
+
|
2754
|
+
element.appendChild(document.createTextNode(text));
|
2755
|
+
}
|
2756
|
+
};
|
2757
|
+
}
|
2758
|
+
*/
|
2759
|
+
|
2760
|
+
function getSelectedText()
|
2761
|
+
{
|
2762
|
+
try
|
2763
|
+
{
|
2764
|
+
if (window.getSelection)
|
2765
|
+
return window.getSelection().toString();
|
2766
|
+
|
2767
|
+
if (document.getSelection)
|
2768
|
+
return document.getSelection().toString();
|
2769
|
+
|
2770
|
+
if (document.selection)
|
2771
|
+
return document.selection.createRange().text;
|
2772
|
+
}
|
2773
|
+
catch (e)
|
2774
|
+
{
|
2775
|
+
return "";
|
2776
|
+
}
|
2777
|
+
return "";
|
2778
|
+
}
|