showoff 0.7.0 → 0.9.7
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.
- 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>
|