showoff 0.7.0 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.rdoc +53 -475
- data/Rakefile +17 -18
- data/bin/showoff +29 -7
- data/lib/commandline_parser.rb +1 -1
- data/lib/showoff/version.rb +3 -0
- data/lib/showoff.rb +600 -91
- data/lib/showoff_utils.rb +110 -4
- data/public/css/disconnected-large.png +0 -0
- data/public/css/disconnected.png +0 -0
- data/public/css/fast.png +0 -0
- data/public/css/grippy-close.png +0 -0
- data/public/css/grippy.png +0 -0
- data/public/css/onepage.css +6 -0
- data/public/css/pace.png +0 -0
- data/public/css/paceMarker.png +0 -0
- data/public/css/presenter.css +333 -43
- data/public/css/sh_style.css +15 -0
- data/public/css/showoff.css +373 -48
- data/public/css/slow.png +0 -0
- data/public/css/spinner.gif +0 -0
- data/public/css/tipsy.css +26 -0
- data/public/favicon.ico +0 -0
- data/public/js/jquery.parsequery.min.js +2 -0
- data/public/js/jquery.tipsy.js +260 -0
- data/public/js/onepage.js +2 -3
- data/public/js/presenter.js +384 -33
- data/public/js/sh_lang/sh_gherkin.js +112 -0
- data/public/js/sh_lang/sh_gherkin.min.js +1 -0
- data/public/js/sh_lang/sh_ini.js +87 -0
- data/public/js/sh_lang/sh_ini.min.js +87 -0
- data/public/js/sh_lang/sh_puppet.js +182 -0
- data/public/js/sh_lang/sh_puppet.min.js +182 -0
- data/public/js/sh_lang/sh_puppet_output.js +22 -0
- data/public/js/sh_lang/sh_puppet_output.min.js +22 -0
- data/public/js/sh_lang/sh_shell.min.js +1 -0
- data/public/js/showoff.js +423 -51
- data/views/404.erb +19 -0
- data/views/download.erb +36 -0
- data/views/header.erb +35 -25
- data/views/header_mini.erb +22 -0
- data/views/index.erb +46 -1
- data/views/onepage.erb +35 -14
- data/views/presenter.erb +63 -21
- data/views/stats.erb +73 -0
- metadata +170 -131
- data/public/css/960.css +0 -653
- data/public/css/pdf.css +0 -12
data/public/js/showoff.js
CHANGED
@@ -16,10 +16,17 @@ var incrCode = false
|
|
16
16
|
var debugMode = false
|
17
17
|
var gotoSlidenum = 0
|
18
18
|
var shiftKeyActive = false
|
19
|
+
var query
|
20
|
+
var slideStartTime = new Date().getTime()
|
21
|
+
|
22
|
+
var questionPrompt = 'Ask a question...'
|
23
|
+
var feedbackPrompt = 'Why?...'
|
19
24
|
|
20
25
|
var loadSlidesBool
|
21
26
|
var loadSlidesPrefix
|
22
27
|
|
28
|
+
var mode = { track: true, follow: false };
|
29
|
+
|
23
30
|
function setupPreso(load_slides, prefix) {
|
24
31
|
if (preso_started)
|
25
32
|
{
|
@@ -28,6 +35,10 @@ function setupPreso(load_slides, prefix) {
|
|
28
35
|
}
|
29
36
|
preso_started = true
|
30
37
|
|
38
|
+
// save our query string as an object for later use
|
39
|
+
query = $.parseQuery();
|
40
|
+
|
41
|
+
// Load slides fetches images
|
31
42
|
loadSlidesBool = load_slides
|
32
43
|
loadSlidesPrefix = prefix
|
33
44
|
loadSlides(loadSlidesBool, loadSlidesPrefix)
|
@@ -36,21 +47,62 @@ function setupPreso(load_slides, prefix) {
|
|
36
47
|
|
37
48
|
// bind event handlers
|
38
49
|
document.onkeydown = keyDown
|
39
|
-
document.onkeyup
|
50
|
+
document.onkeyup = keyUp
|
40
51
|
/* window.onresize = resized; */
|
41
52
|
/* window.onscroll = scrolled; */
|
42
53
|
/* window.onunload = unloaded; */
|
43
54
|
|
44
|
-
$('
|
55
|
+
$('#preso').addSwipeEvents().
|
45
56
|
bind('tap', swipeLeft). // next
|
46
57
|
bind('swipeleft', swipeLeft). // next
|
47
58
|
bind('swiperight', swipeRight); // prev
|
59
|
+
|
60
|
+
// give us the ability to disable tracking via url parameter
|
61
|
+
if(query.track == 'false') mode.track = false;
|
62
|
+
|
63
|
+
// Make sure the slides always look right.
|
64
|
+
// Better would be dynamic calculations, but this is enough for now.
|
65
|
+
$(window).resize(function(){location.reload();});
|
66
|
+
|
67
|
+
$("#feedbackWrapper").hover(
|
68
|
+
function() {
|
69
|
+
$('#feedbackSidebar').show();
|
70
|
+
document.onkeydown = null;
|
71
|
+
document.onkeyup = null;
|
72
|
+
},
|
73
|
+
function() {
|
74
|
+
$('#feedbackSidebar').hide();
|
75
|
+
document.onkeydown = keyDown;
|
76
|
+
document.onkeyup = keyUp;
|
77
|
+
}
|
78
|
+
);
|
79
|
+
|
80
|
+
$("#paceSlower").click(function() { sendPace('slower'); });
|
81
|
+
$("#paceFaster").click(function() { sendPace('faster'); });
|
82
|
+
$("#askQuestion").click(function() { askQuestion( $("textarea#question").val()) });
|
83
|
+
$("#sendFeedback").click(function() {
|
84
|
+
sendFeedback($( "input:radio[name=rating]:checked" ).val(), $("textarea#feedback").val())
|
85
|
+
});
|
86
|
+
|
87
|
+
$("textarea#question").val(questionPrompt);
|
88
|
+
$("textarea#feedback").val(feedbackPrompt);
|
89
|
+
$("textarea#question").focus(function() { clearIf($(this), questionPrompt) });
|
90
|
+
$("textarea#feedback").focus(function() { clearIf($(this), feedbackPrompt) });
|
91
|
+
|
92
|
+
// Open up our control socket
|
93
|
+
connectControlChannel();
|
94
|
+
/*
|
95
|
+
ws = new WebSocket('ws://' + location.host + '/control');
|
96
|
+
ws.onopen = function() { connected(); };
|
97
|
+
ws.onclose = function() { disconnected(); }
|
98
|
+
ws.onmessage = function(m) { parseMessage(m.data); };
|
99
|
+
*/
|
48
100
|
}
|
49
101
|
|
50
102
|
function loadSlides(load_slides, prefix) {
|
51
103
|
//load slides offscreen, wait for images and then initialize
|
52
104
|
if (load_slides) {
|
53
|
-
$("#slides").load("slides", false, function(){
|
105
|
+
$("#slides").load(loadSlidesPrefix + "slides", false, function(){
|
54
106
|
$("#slides img").batchImageLoad({
|
55
107
|
loadingCompleteCallback: initializePresentation(prefix)
|
56
108
|
})
|
@@ -64,7 +116,7 @@ function loadSlides(load_slides, prefix) {
|
|
64
116
|
|
65
117
|
function initializePresentation(prefix) {
|
66
118
|
// unhide for height to work in static mode
|
67
|
-
|
119
|
+
$("#slides").show();
|
68
120
|
|
69
121
|
//center slides offscreen
|
70
122
|
centerSlides($('#slides > .slide'))
|
@@ -83,6 +135,7 @@ function initializePresentation(prefix) {
|
|
83
135
|
})
|
84
136
|
|
85
137
|
setupMenu()
|
138
|
+
setupStyleMenu()
|
86
139
|
if (slidesLoaded) {
|
87
140
|
showSlide()
|
88
141
|
} else {
|
@@ -90,7 +143,12 @@ function initializePresentation(prefix) {
|
|
90
143
|
slidesLoaded = true
|
91
144
|
}
|
92
145
|
setupSlideParamsCheck();
|
93
|
-
|
146
|
+
|
147
|
+
try {
|
148
|
+
sh_highlightDocument('/js/sh_lang/', '.min.js')
|
149
|
+
} catch(e) {
|
150
|
+
sh_highlightDocument();
|
151
|
+
}
|
94
152
|
$("#preso").trigger("showoff:loaded");
|
95
153
|
}
|
96
154
|
|
@@ -101,7 +159,7 @@ function centerSlides(slides) {
|
|
101
159
|
}
|
102
160
|
|
103
161
|
function centerSlide(slide) {
|
104
|
-
var slide_content = $(slide).
|
162
|
+
var slide_content = $(slide).find(".content").first()
|
105
163
|
var height = slide_content.height()
|
106
164
|
var mar_top = (0.5 * parseFloat($(slide).height())) - (0.5 * parseFloat(height))
|
107
165
|
if (mar_top < 0) {
|
@@ -117,7 +175,7 @@ function setupMenu() {
|
|
117
175
|
var menu = new ListMenu()
|
118
176
|
|
119
177
|
slides.each(function(s, elem) {
|
120
|
-
content = $(elem).
|
178
|
+
content = $(elem).find(".content")
|
121
179
|
shortTxt = $(content).text().substr(0, 20)
|
122
180
|
path = $(content).attr('ref').split('/')
|
123
181
|
currSlide += 1
|
@@ -156,11 +214,11 @@ function setupSlideParamsCheck() {
|
|
156
214
|
setTimeout(check, 100);
|
157
215
|
}
|
158
216
|
|
159
|
-
function gotoSlide(slideNum) {
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
217
|
+
function gotoSlide(slideNum, updatepv) {
|
218
|
+
slidenum = parseInt(slideNum);
|
219
|
+
if (!isNaN(slidenum)) {
|
220
|
+
showSlide(false, updatepv);
|
221
|
+
}
|
164
222
|
}
|
165
223
|
|
166
224
|
function showFirstSlide() {
|
@@ -169,7 +227,9 @@ function showFirstSlide() {
|
|
169
227
|
showSlide()
|
170
228
|
}
|
171
229
|
|
172
|
-
function showSlide(back_step) {
|
230
|
+
function showSlide(back_step, updatepv) {
|
231
|
+
// allows the master presenter view to disable the update callback
|
232
|
+
updatepv = (typeof(updatepv) === 'undefined') ? true : updatepv;
|
173
233
|
|
174
234
|
if(slidenum < 0) {
|
175
235
|
slidenum = 0
|
@@ -195,6 +255,8 @@ function showSlide(back_step) {
|
|
195
255
|
if (fullPage) {
|
196
256
|
$('#preso').css({'width' : '100%', 'overflow' : 'visible'});
|
197
257
|
currentSlide.css({'width' : '100%', 'text-align' : 'center', 'overflow' : 'visible'});
|
258
|
+
} else {
|
259
|
+
$('#preso').css({'width' : '', 'overflow' : ''});
|
198
260
|
}
|
199
261
|
|
200
262
|
percent = getSlidePercent()
|
@@ -215,7 +277,24 @@ function showSlide(back_step) {
|
|
215
277
|
var currentContent = $(currentSlide).find(".content")
|
216
278
|
currentContent.trigger("showoff:show");
|
217
279
|
|
218
|
-
|
280
|
+
var ret = setCurrentNotes();
|
281
|
+
|
282
|
+
var fileName = currentSlide.children().first().attr('ref');
|
283
|
+
$('#slideFilename').text(fileName);
|
284
|
+
|
285
|
+
// Update presenter view, if we spawned one
|
286
|
+
if (updatepv && 'presenterView' in window) {
|
287
|
+
var pv = window.presenterView;
|
288
|
+
pv.slidenum = slidenum;
|
289
|
+
pv.incrCurr = incrCurr
|
290
|
+
pv.incrSteps = incrSteps
|
291
|
+
pv.showSlide(true);
|
292
|
+
pv.postSlide();
|
293
|
+
|
294
|
+
pv.update();
|
295
|
+
}
|
296
|
+
|
297
|
+
return ret;
|
219
298
|
}
|
220
299
|
|
221
300
|
function getSlideProgress()
|
@@ -225,9 +304,21 @@ function getSlideProgress()
|
|
225
304
|
|
226
305
|
function getCurrentNotes()
|
227
306
|
{
|
228
|
-
|
229
|
-
|
230
|
-
|
307
|
+
var notes = currentSlide.find("div.notes");
|
308
|
+
return notes;
|
309
|
+
}
|
310
|
+
|
311
|
+
function getCurrentNotesText()
|
312
|
+
{
|
313
|
+
var notes = getCurrentNotes();
|
314
|
+
return notes.text();
|
315
|
+
}
|
316
|
+
|
317
|
+
function setCurrentNotes()
|
318
|
+
{
|
319
|
+
var notes = getCurrentNotesText();
|
320
|
+
$('#notesInfo').text(notes);
|
321
|
+
return notes;
|
231
322
|
}
|
232
323
|
|
233
324
|
function getSlidePercent()
|
@@ -252,20 +343,138 @@ function determineIncremental()
|
|
252
343
|
})
|
253
344
|
}
|
254
345
|
|
255
|
-
function
|
346
|
+
function showIncremental(incr)
|
256
347
|
{
|
348
|
+
elem = incrElem.eq(incrCurr)
|
349
|
+
if (incrCode && elem.hasClass('command')) {
|
350
|
+
incrElem.eq(incrCurr).css('visibility', 'visible').jTypeWriter({duration:1.0})
|
351
|
+
} else {
|
352
|
+
incrElem.eq(incrCurr).css('visibility', 'visible')
|
353
|
+
}
|
354
|
+
}
|
355
|
+
|
356
|
+
function clearIf(elem, val) {
|
357
|
+
console.log(elem.val());
|
358
|
+
console.log(val);
|
359
|
+
if(elem.val() == val ) { elem.val(''); }
|
360
|
+
}
|
361
|
+
|
362
|
+
function connectControlChannel() {
|
363
|
+
ws = new WebSocket('ws://' + location.host + '/control');
|
364
|
+
ws.onopen = function() { connected(); };
|
365
|
+
ws.onclose = function() { disconnected(); }
|
366
|
+
ws.onmessage = function(m) { parseMessage(m.data); };
|
367
|
+
}
|
368
|
+
|
369
|
+
// This exists as an intermediary simply so the presenter view can override it
|
370
|
+
function reconnectControlChannel() {
|
371
|
+
connectControlChannel();
|
372
|
+
}
|
373
|
+
|
374
|
+
function connected() {
|
375
|
+
console.log('Control socket opened');
|
376
|
+
$("#feedbackSidebar button").attr("disabled", false);
|
377
|
+
$("img#disconnected").hide();
|
257
378
|
|
379
|
+
try {
|
380
|
+
// If we are a presenter, then remind the server where we are
|
381
|
+
update();
|
382
|
+
register();
|
383
|
+
}
|
384
|
+
catch (e) {}
|
385
|
+
}
|
386
|
+
|
387
|
+
function disconnected() {
|
388
|
+
console.log('Control socket closed');
|
389
|
+
$("#feedbackSidebar button").attr("disabled", true);
|
390
|
+
$("img#disconnected").show();
|
391
|
+
|
392
|
+
setTimeout(function() { reconnectControlChannel() } , 5000);
|
393
|
+
}
|
394
|
+
|
395
|
+
function parseMessage(data) {
|
396
|
+
var command = JSON.parse(data);
|
397
|
+
|
398
|
+
if ("current" in command) { follow(command["current"]); }
|
399
|
+
|
400
|
+
// Presenter messages only, so catch errors if method doesn't exist
|
401
|
+
try {
|
402
|
+
if ("pace" in command) { paceFeedback(command["pace"]); }
|
403
|
+
if ("question" in command) { askQuestion(command["question"]); }
|
404
|
+
}
|
405
|
+
catch(e) {
|
406
|
+
console.log("Not a presenter!");
|
407
|
+
}
|
408
|
+
|
409
|
+
}
|
410
|
+
|
411
|
+
function sendPace(pace) {
|
412
|
+
ws.send(JSON.stringify({ message: 'pace', pace: pace}));
|
413
|
+
feedbackActivity();
|
414
|
+
}
|
415
|
+
|
416
|
+
function askQuestion(question) {
|
417
|
+
ws.send(JSON.stringify({ message: 'question', question: question}));
|
418
|
+
$("textarea#question").val(questionPrompt);
|
419
|
+
feedbackActivity();
|
420
|
+
}
|
421
|
+
|
422
|
+
function sendFeedback(rating, feedback) {
|
423
|
+
var slide = $("#slideFilename").text();
|
424
|
+
ws.send(JSON.stringify({ message: 'feedback', rating: rating, feedback: feedback, slide: slide}));
|
425
|
+
$("textarea#feedback").val(feedbackPrompt);
|
426
|
+
$("input:radio[name=rating]:checked").attr('checked', false);
|
427
|
+
feedbackActivity();
|
428
|
+
}
|
429
|
+
|
430
|
+
function feedbackActivity() {
|
431
|
+
$("img#feedbackActivity").show();
|
432
|
+
setTimeout(function() { $("img#feedbackActivity").hide() }, 1000);
|
433
|
+
}
|
434
|
+
|
435
|
+
function track() {
|
436
|
+
if (mode.track) {
|
437
|
+
var slideName = $("#slideFilename").text();
|
438
|
+
var slideEndTime = new Date().getTime();
|
439
|
+
var elapsedTime = slideEndTime - slideStartTime;
|
440
|
+
|
441
|
+
// reset the timer
|
442
|
+
slideStartTime = slideEndTime;
|
443
|
+
|
444
|
+
if (elapsedTime > 1000) {
|
445
|
+
elapsedTime /= 1000;
|
446
|
+
ws.send(JSON.stringify({ message: 'track', slide: slideName, time: elapsedTime}));
|
447
|
+
}
|
448
|
+
}
|
449
|
+
}
|
450
|
+
|
451
|
+
function follow(slide) {
|
452
|
+
if (mode.follow) {
|
453
|
+
console.log("New slide: " + slide);
|
454
|
+
gotoSlide(slide);
|
455
|
+
}
|
456
|
+
}
|
457
|
+
|
458
|
+
function getPosition() {
|
459
|
+
// get the current position from the server
|
460
|
+
ws.send(JSON.stringify({ message: 'position' }));
|
461
|
+
}
|
462
|
+
|
463
|
+
function prevStep(updatepv)
|
464
|
+
{
|
258
465
|
var event = jQuery.Event("showoff:prev");
|
259
466
|
$(currentSlide).find(".content").trigger(event);
|
260
467
|
if (event.isDefaultPrevented()) {
|
261
468
|
return;
|
262
469
|
}
|
263
470
|
|
471
|
+
track();
|
472
|
+
|
264
473
|
slidenum--
|
265
|
-
return showSlide(true) // We show the slide fully loaded
|
474
|
+
return showSlide(true, updatepv) // We show the slide fully loaded
|
266
475
|
}
|
267
476
|
|
268
|
-
function nextStep()
|
477
|
+
function nextStep(updatepv)
|
269
478
|
{
|
270
479
|
var event = jQuery.Event("showoff:next");
|
271
480
|
$(currentSlide).find(".content").trigger(event);
|
@@ -273,30 +482,44 @@ function nextStep()
|
|
273
482
|
return;
|
274
483
|
}
|
275
484
|
|
485
|
+
track();
|
486
|
+
|
276
487
|
if (incrCurr >= incrSteps) {
|
277
488
|
slidenum++
|
278
|
-
return showSlide()
|
489
|
+
return showSlide(false, updatepv)
|
279
490
|
} else {
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
incrCurr++
|
491
|
+
showIncremental(incrCurr);
|
492
|
+
var incrEvent = jQuery.Event("showoff:incr");
|
493
|
+
incrEvent.slidenum = slidenum;
|
494
|
+
incrEvent.incr = incrCurr;
|
495
|
+
$(currentSlide).find(".content").trigger(incrEvent);
|
496
|
+
incrCurr++;
|
287
497
|
}
|
288
498
|
}
|
289
499
|
|
290
500
|
function doDebugStuff()
|
291
501
|
{
|
292
502
|
if (debugMode) {
|
293
|
-
|
294
|
-
|
503
|
+
$('#debugInfo').show();
|
504
|
+
$('#slideFilename').show();
|
295
505
|
} else {
|
296
|
-
|
506
|
+
$('#debugInfo').hide();
|
507
|
+
$('#slideFilename').hide();
|
297
508
|
}
|
298
509
|
}
|
299
510
|
|
511
|
+
function blankScreen()
|
512
|
+
{
|
513
|
+
if ($('#screenblanker').length) { // if #screenblanker exists
|
514
|
+
$('#screenblanker').slideUp('normal', function() {
|
515
|
+
$('#screenblanker').remove();
|
516
|
+
});
|
517
|
+
} else {
|
518
|
+
$('body').prepend('<div id="screenblanker"></div>');
|
519
|
+
$('#screenblanker').slideDown();
|
520
|
+
}
|
521
|
+
}
|
522
|
+
|
300
523
|
var notesMode = false
|
301
524
|
function toggleNotes()
|
302
525
|
{
|
@@ -309,6 +532,18 @@ function toggleNotes()
|
|
309
532
|
}
|
310
533
|
}
|
311
534
|
|
535
|
+
function toggleFollow()
|
536
|
+
{
|
537
|
+
mode.follow = ! mode.follow;
|
538
|
+
|
539
|
+
if(mode.follow) {
|
540
|
+
$("#followMode").show().text('Follow Mode:');
|
541
|
+
getPosition();
|
542
|
+
} else {
|
543
|
+
$("#followMode").hide();
|
544
|
+
}
|
545
|
+
}
|
546
|
+
|
312
547
|
function executeAnyCode()
|
313
548
|
{
|
314
549
|
var $jsCode = $('.execute .sh_javascript code:visible')
|
@@ -322,7 +557,7 @@ function executeAnyCode()
|
|
322
557
|
var $coffeeCode = $('.execute .sh_coffeescript code:visible')
|
323
558
|
if ($coffeeCode.length > 0) {
|
324
559
|
executeCoffee.call($coffeeCode);
|
325
|
-
}
|
560
|
+
}
|
326
561
|
}
|
327
562
|
|
328
563
|
function debug(data)
|
@@ -396,14 +631,30 @@ function keyDown(event)
|
|
396
631
|
{
|
397
632
|
$('#navmenu').toggle().trigger('click')
|
398
633
|
}
|
634
|
+
else if (key == 83) // 's' for style
|
635
|
+
{
|
636
|
+
$('#stylemenu').toggle().trigger('click')
|
637
|
+
}
|
399
638
|
else if (key == 90 || key == 191) // z or ? for help
|
400
639
|
{
|
401
640
|
$('#help').toggle()
|
402
641
|
}
|
403
|
-
else if (key == 66
|
642
|
+
else if (key == 66) // b for blank, also what kensington remote "stop" button sends
|
643
|
+
{
|
644
|
+
blankScreen()
|
645
|
+
}
|
646
|
+
else if (key == 70) // f for footer
|
404
647
|
{
|
405
648
|
toggleFooter()
|
406
649
|
}
|
650
|
+
else if (key == 71) // g for follow mode
|
651
|
+
{
|
652
|
+
toggleFollow()
|
653
|
+
}
|
654
|
+
else if (key == 76) // l for leader mode
|
655
|
+
{
|
656
|
+
toggleLeader()
|
657
|
+
}
|
407
658
|
else if (key == 78) // 'n' for notes
|
408
659
|
{
|
409
660
|
toggleNotes()
|
@@ -412,9 +663,14 @@ function keyDown(event)
|
|
412
663
|
{
|
413
664
|
removeResults();
|
414
665
|
}
|
415
|
-
else if (key == 80) // 'p' for preshow
|
666
|
+
else if (key == 80) // 'p' for preshow, 'P' for pause
|
416
667
|
{
|
417
|
-
|
668
|
+
if (shiftKeyActive) {
|
669
|
+
togglePause();
|
670
|
+
}
|
671
|
+
else {
|
672
|
+
togglePreShow();
|
673
|
+
}
|
418
674
|
}
|
419
675
|
return true
|
420
676
|
}
|
@@ -548,22 +804,24 @@ function togglePreShow() {
|
|
548
804
|
stopPreShow()
|
549
805
|
} else {
|
550
806
|
var minutes = prompt("Minutes from now to start")
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
807
|
+
|
808
|
+
if (preshow_secondsLeft = parseFloat(minutes) * 60) {
|
809
|
+
toggleFooter()
|
810
|
+
$.getJSON("preshow_files", false, function(data) {
|
811
|
+
$('#preso').after("<div id='preshow'></div><div id='tips'></div><div id='preshow_timer'></div>")
|
812
|
+
$.each(data, function(i, n) {
|
813
|
+
if(n == "preshow.json") {
|
814
|
+
// has a descriptions file
|
815
|
+
$.getJSON("/file/_preshow/preshow.json", false, function(data) {
|
816
|
+
preshow_des = data
|
817
|
+
})
|
818
|
+
} else {
|
819
|
+
$('#preshow').append('<img ref="' + n + '" src="/file/_preshow/' + n + '"/>')
|
820
|
+
}
|
821
|
+
})
|
822
|
+
startPreShow()
|
564
823
|
})
|
565
|
-
|
566
|
-
})
|
824
|
+
}
|
567
825
|
}
|
568
826
|
}
|
569
827
|
|
@@ -596,7 +854,7 @@ function startPreShow() {
|
|
596
854
|
|
597
855
|
function addPreShowTips() {
|
598
856
|
time = secondsToTime(preshow_secondsLeft)
|
599
|
-
$('#preshow_timer').text(
|
857
|
+
$('#preshow_timer').text('Resuming in: ' + time)
|
600
858
|
var des = preshow_des && preshow_des[tmpImg.attr("ref")]
|
601
859
|
if(des) {
|
602
860
|
$('#tips').show()
|
@@ -641,3 +899,117 @@ function nextPreShowImage() {
|
|
641
899
|
/********************
|
642
900
|
End PreShow Code
|
643
901
|
********************/
|
902
|
+
|
903
|
+
function togglePause() {
|
904
|
+
$("#pauseScreen").toggle();
|
905
|
+
}
|
906
|
+
|
907
|
+
/********************
|
908
|
+
Style-Picker Code
|
909
|
+
********************/
|
910
|
+
|
911
|
+
function styleChoiceTags() {
|
912
|
+
return $('link[rel*="stylesheet"][href*="file/"]');
|
913
|
+
}
|
914
|
+
|
915
|
+
function styleChoices() {
|
916
|
+
return $.map(styleChoiceTags(), function(el) { return styleChoiceString(el.href); });
|
917
|
+
}
|
918
|
+
|
919
|
+
function styleChoiceString(href) {
|
920
|
+
var parts = href.split('/');
|
921
|
+
var file = parts[parts.length - 1];
|
922
|
+
var choice = file.replace(/\.css$/, '');
|
923
|
+
|
924
|
+
return choice;
|
925
|
+
}
|
926
|
+
|
927
|
+
function getCurrentStyle()
|
928
|
+
{
|
929
|
+
var current = '';
|
930
|
+
|
931
|
+
styleChoiceTags().each(function (i, el) {
|
932
|
+
if (el.rel == 'stylesheet') {
|
933
|
+
current = el.href;
|
934
|
+
}
|
935
|
+
});
|
936
|
+
|
937
|
+
return styleChoiceString(current);
|
938
|
+
}
|
939
|
+
|
940
|
+
function setCurrentStyle(style, prop)
|
941
|
+
{
|
942
|
+
styleChoiceTags().each(function (i, el) {
|
943
|
+
el.rel = 'alternate stylesheet';
|
944
|
+
|
945
|
+
if (styleChoiceString(el.href) == style) {
|
946
|
+
el.rel = 'stylesheet';
|
947
|
+
}
|
948
|
+
});
|
949
|
+
|
950
|
+
if (prop) {
|
951
|
+
if ('presenterView' in window) {
|
952
|
+
var pv = window.presenterView;
|
953
|
+
pv.setCurrentStyle(style, false);
|
954
|
+
}
|
955
|
+
}
|
956
|
+
}
|
957
|
+
|
958
|
+
function setupStyleMenu() {
|
959
|
+
$('#stylemenu').hide();
|
960
|
+
|
961
|
+
var menu = new StyleListMenu();
|
962
|
+
styleChoices().each(function(s) {
|
963
|
+
menu.addItem(s)
|
964
|
+
})
|
965
|
+
|
966
|
+
$('#stylepicker').html(menu.getList())
|
967
|
+
$('#stylemenu').menu({
|
968
|
+
content: $('#stylepicker').html(),
|
969
|
+
flyOut: true
|
970
|
+
});
|
971
|
+
}
|
972
|
+
|
973
|
+
function StyleListMenu()
|
974
|
+
{
|
975
|
+
this.typeName = 'StyleListMenu'
|
976
|
+
this.items = new Array();
|
977
|
+
this.addItem = function (key) {
|
978
|
+
this.items[key] = new StyleListMenuItem(key)
|
979
|
+
}
|
980
|
+
this.getList = function() {
|
981
|
+
var newMenu = $("<ul>")
|
982
|
+
for(var i in this.items) {
|
983
|
+
var item = this.items[i]
|
984
|
+
var domItem = $("<li>")
|
985
|
+
if (item.textName != undefined) {
|
986
|
+
choice = $("<a onclick=\"setCurrentStyle('" + item.textName + "', true); $('#stylemenu').hide();\" href=\"#\">" + item.textName + "</a>")
|
987
|
+
domItem.append(choice)
|
988
|
+
newMenu.append(domItem)
|
989
|
+
}
|
990
|
+
}
|
991
|
+
return newMenu
|
992
|
+
}
|
993
|
+
}
|
994
|
+
|
995
|
+
function StyleListMenuItem(t)
|
996
|
+
{
|
997
|
+
this.typeName = "StyleListMenuItem"
|
998
|
+
this.textName = t
|
999
|
+
}
|
1000
|
+
/********************
|
1001
|
+
End Style-Picker Code
|
1002
|
+
********************/
|
1003
|
+
|
1004
|
+
|
1005
|
+
/********************
|
1006
|
+
Stats page
|
1007
|
+
********************/
|
1008
|
+
|
1009
|
+
function setupStats()
|
1010
|
+
{
|
1011
|
+
$("#stats div#all div.detail").hide();
|
1012
|
+
$("#stats div#all div.row").click(function() {
|
1013
|
+
$(this).find("div.detail").slideToggle("fast");
|
1014
|
+
});
|
1015
|
+
}
|
data/views/404.erb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<%= erb :header %>
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<body id="download">
|
10
|
+
|
11
|
+
<div id="preso">
|
12
|
+
<h1>File Not Found!</h1>
|
13
|
+
<h2><%= @env['REQUEST_PATH'] %>
|
14
|
+
</div>
|
15
|
+
<div id="footer">
|
16
|
+
<span id="debugInfo"></span>
|
17
|
+
</div>
|
18
|
+
</body>
|
19
|
+
</html>
|