showoff 0.14.3 → 0.15.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.
- checksums.yaml +4 -4
- data/lib/keymap.rb +2 -1
- data/lib/showoff/version.rb +1 -1
- data/lib/showoff.rb +7 -4
- data/lib/showoff_utils.rb +8 -2
- data/public/css/{TimeCircles.css → TimeCircles-89ac5ae.css} +0 -0
- data/public/css/presenter.css +148 -8
- data/public/css/showoff.css +17 -9
- data/public/js/{TimeCircles.js → TimeCircles-89ac5ae.js} +986 -984
- data/public/js/annotations.js +1 -1
- data/public/js/{coffee-script.js → coffee-script-1.1.3-pre.js} +0 -0
- data/public/js/{highlight.pack.js → highlight.pack-9.2.0.js} +0 -0
- data/public/js/{jTypeWriter.js → jTypeWriter-1.1.js} +0 -0
- data/public/js/jquery-print.js +3 -2
- data/public/js/{jquery.batchImageLoad.js → jquery.batchImageLoad-1.0.0.js} +0 -0
- data/public/js/{jquery.cycle.all.js → jquery.cycle.all-2.8.0.js} +0 -0
- data/public/js/{jquery.doubletap-0.1.js → jquery.doubletap-4ff02c5.js} +3 -2
- data/public/js/{jquery.parsequery.min.js → jquery.parsequery.min-6a20f83.js} +1 -0
- data/public/js/presenter.js +192 -65
- data/public/js/showoff.js +102 -74
- data/views/header.erb +10 -11
- data/views/header_mini.erb +2 -3
- data/views/help.erb +6 -1
- data/views/presenter.erb +18 -7
- metadata +11 -11
data/public/js/annotations.js
CHANGED
@@ -208,7 +208,7 @@ jQuery.fn.extend({
|
|
208
208
|
|
209
209
|
// let the annotation overlay own mouse events.
|
210
210
|
// This means that clicking links or copying text will not work.
|
211
|
-
$(this).css('pointer-events', '
|
211
|
+
$(this).css('pointer-events', 'auto');
|
212
212
|
|
213
213
|
$(this).unbind( "mousedown" );
|
214
214
|
$(this).mousedown(function(e){
|
File without changes
|
File without changes
|
File without changes
|
data/public/js/jquery-print.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
/* https://github.com/smparkes/jquery.print/blob/master/src/jquery.print.js */
|
1
2
|
(function($) {
|
2
3
|
|
3
4
|
function print_array(obj, opts) {
|
@@ -60,7 +61,7 @@
|
|
60
61
|
'\\': '\\\\'
|
61
62
|
};
|
62
63
|
var r = /["\\\x00-\x1f\x7f-\x9f]/g;
|
63
|
-
|
64
|
+
|
64
65
|
var str = r.test(value)
|
65
66
|
? value.replace(r, function (a) {
|
66
67
|
var c = character_substitutions[a];
|
@@ -106,4 +107,4 @@
|
|
106
107
|
return obj.toString().replace(/\n\s*/g, '');
|
107
108
|
}
|
108
109
|
|
109
|
-
})(jQuery);
|
110
|
+
})(jQuery);
|
File without changes
|
File without changes
|
@@ -1,3 +1,4 @@
|
|
1
|
+
/* https://github.com/technoweenie/jquery.doubletap */
|
1
2
|
(function($) {
|
2
3
|
var touchStatus = function(target, touch) {
|
3
4
|
this.target = $(target);
|
@@ -31,7 +32,7 @@
|
|
31
32
|
|
32
33
|
touchStatus.prototype.checkForDoubleTap = function() {
|
33
34
|
if(touchStatus.latestTap) {
|
34
|
-
if((new Date() - touchStatus.latestTap) < 400)
|
35
|
+
if((new Date() - touchStatus.latestTap) < 400)
|
35
36
|
this.eventType = 'doubletap'
|
36
37
|
}
|
37
38
|
if(!this.eventType) this.eventType = 'tap'
|
@@ -102,4 +103,4 @@
|
|
102
103
|
if(callback) this.bind('touch', callback)
|
103
104
|
return this;
|
104
105
|
}
|
105
|
-
})(jQuery);
|
106
|
+
})(jQuery);
|
@@ -1,2 +1,3 @@
|
|
1
|
+
/* https://github.com/rapportive-oss/jquery-parsequery */
|
1
2
|
(function($){$.parseQuery=function(options){var config={query:window.location.search||""},params={};if(typeof options==='string'){options={query:options};}
|
2
3
|
$.extend(config,$.parseQuery,options);config.query=config.query.replace(/^\?/,'');$.each(config.query.split(config.separator),function(i,param){var pair=param.split('='),key=config.decode(pair.shift(),null).toString(),value=config.decode(pair.length?pair.join('='):null,key);if(config.array_keys(key)){params[key]=params[key]||[];params[key].push(value);}else{params[key]=value;}});return params;};$.parseQuery.decode=$.parseQuery.default_decode=function(string){return decodeURIComponent((string||"").replace('+',' '));};$.parseQuery.array_keys=function(){return false;};$.parseQuery.separator="&";}(jQuery));
|
data/public/js/presenter.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
// presenter js
|
2
2
|
var slaveWindow = null;
|
3
|
-
var nextWindow
|
3
|
+
var nextWindow = null;
|
4
4
|
var notesWindow = null;
|
5
5
|
|
6
6
|
var paceData = [];
|
@@ -9,7 +9,7 @@ section = 'notes'; // which section the presenter has chosen to view
|
|
9
9
|
|
10
10
|
$(document).ready(function(){
|
11
11
|
// set up the presenter modes
|
12
|
-
mode = { track: true, follow: true, update: true, slave: false,
|
12
|
+
mode = { track: true, follow: true, update: true, slave: false, notes: false, annotations: false, layout: 'default'};
|
13
13
|
|
14
14
|
// attempt to open another window for the presentation if the mode defaults
|
15
15
|
// to enabling this. It does not by default, so this is likely a no-op.
|
@@ -32,6 +32,10 @@ $(document).ready(function(){
|
|
32
32
|
$('#downloadslink').click(function(e) {
|
33
33
|
presenterPopupToggle('/download', e);
|
34
34
|
});
|
35
|
+
$('#layoutSelector').change(function(e) {
|
36
|
+
chooseLayout(e.target.value);
|
37
|
+
});
|
38
|
+
|
35
39
|
|
36
40
|
// Bind events for mobile viewing
|
37
41
|
if( mobile() ) {
|
@@ -54,6 +58,20 @@ $(document).ready(function(){
|
|
54
58
|
});
|
55
59
|
}
|
56
60
|
|
61
|
+
// wait until the presentation is loaded to hook up the previews.
|
62
|
+
// TODO: If we decide to implement this for the audience display, we can move it later
|
63
|
+
$("body").bind("showoff:loaded", function (event) {
|
64
|
+
$('#navigation li a.navItem').hover(function() {
|
65
|
+
var position = $(this).position();
|
66
|
+
$('#navigationHover').css({top: position.top, left: position.left + $('#navigation').width() + 5})
|
67
|
+
$('#navigationHover').html(slides.eq($(this).attr('rel')).html());
|
68
|
+
$('#navigationHover').show();
|
69
|
+
},function() {
|
70
|
+
$('#navigationHover').hide();
|
71
|
+
});
|
72
|
+
});
|
73
|
+
|
74
|
+
|
57
75
|
// Hide with js so jquery knows what display property to assign when showing
|
58
76
|
toggleAnnotations();
|
59
77
|
|
@@ -143,7 +161,7 @@ function presenterPopupToggle(page, event) {
|
|
143
161
|
|
144
162
|
content.attr('id', page.substring(1, page.length));
|
145
163
|
content.append(link);
|
146
|
-
/* use .
|
164
|
+
/* use .siblings() because of how jquery formats $(data) */
|
147
165
|
content.append($(data).siblings('#wrapper').html());
|
148
166
|
popup.append(content);
|
149
167
|
|
@@ -175,16 +193,26 @@ function openEditor() {
|
|
175
193
|
$.get(link);
|
176
194
|
}
|
177
195
|
|
196
|
+
function windowIsClosed(window)
|
197
|
+
{
|
198
|
+
return(window == null || typeof(window) == 'undefined' || window.closed);
|
199
|
+
}
|
200
|
+
|
201
|
+
function windowIsOpen(window) {
|
202
|
+
return (window && typeof(window) != 'undefined' && !window.closed)
|
203
|
+
}
|
204
|
+
|
178
205
|
function toggleSlave() {
|
179
206
|
mode.slave = !mode.slave;
|
180
207
|
openSlave();
|
181
208
|
}
|
182
209
|
|
210
|
+
// Open, or maintain connection & reopen slave window.
|
183
211
|
function openSlave()
|
184
212
|
{
|
185
213
|
if (mode.slave) {
|
186
214
|
try {
|
187
|
-
if(
|
215
|
+
if(windowIsClosed(slaveWindow)){
|
188
216
|
slaveWindow = window.open('/' + window.location.hash, 'toolbar');
|
189
217
|
}
|
190
218
|
else if(slaveWindow.location.hash != window.location.hash) {
|
@@ -223,65 +251,21 @@ function openSlave()
|
|
223
251
|
|
224
252
|
function nextSlideNum(url) {
|
225
253
|
// Some fudging because the first slide is slide[0] but numbered 1 in the URL
|
226
|
-
console.log(typeof(url));
|
227
254
|
var snum;
|
228
255
|
if (typeof(url) == 'undefined') { snum = currentSlideFromParams()+1; }
|
229
256
|
else { snum = currentSlideFromParams()+2; }
|
230
257
|
return snum;
|
231
258
|
}
|
232
259
|
|
233
|
-
function toggleNext() {
|
234
|
-
mode.next = !mode.next;
|
235
|
-
openNext();
|
236
|
-
}
|
237
|
-
|
238
|
-
function openNext()
|
239
|
-
{
|
240
|
-
if (mode.next) {
|
241
|
-
try {
|
242
|
-
if(nextWindow == null || typeof(nextWindow) == 'undefined' || nextWindow.closed){
|
243
|
-
nextWindow = window.open('/?track=false&feedback=false&next=true#' + nextSlideNum(true),'','width=320,height=300');
|
244
|
-
}
|
245
|
-
else if(nextWindow.location.hash != '#' + nextSlideNum(true)) {
|
246
|
-
// maybe we need to reset content?
|
247
|
-
nextWindow.location.href = '/?track=false&feedback=false&next=true#' + nextSlideNum(true);
|
248
|
-
}
|
249
|
-
|
250
|
-
// maintain the pointer back to the parent.
|
251
|
-
nextWindow.presenterView = window;
|
252
|
-
nextWindow.mode = { track: false, next: true, follow: true };
|
253
|
-
|
254
|
-
$('#nextWindow').addClass('enabled');
|
255
|
-
}
|
256
|
-
catch(e) {
|
257
|
-
console.log('Failed to open or connect next window. Popup blocker?');
|
258
|
-
}
|
259
|
-
}
|
260
|
-
else {
|
261
|
-
try {
|
262
|
-
nextWindow && nextWindow.close();
|
263
|
-
$('#nextWindow').removeClass('enabled');
|
264
|
-
}
|
265
|
-
catch (e) {
|
266
|
-
console.log('Next window failed to close properly.');
|
267
|
-
}
|
268
|
-
}
|
269
|
-
}
|
270
260
|
|
271
261
|
function toggleNotes() {
|
272
262
|
mode.notes = !mode.notes;
|
273
|
-
openNotes();
|
274
|
-
}
|
275
263
|
|
276
|
-
function openNotes()
|
277
|
-
{
|
278
264
|
if (mode.notes) {
|
279
265
|
try {
|
280
|
-
if(
|
281
|
-
|
282
|
-
|
283
|
-
notesWindow.document.title = "Showoff Notes";
|
284
|
-
postSlide();
|
266
|
+
if(windowIsClosed(notesWindow)){
|
267
|
+
notesWindow = blankStyledWindow("Showoff Notes", 'width=350,height=450', 'notes', true);
|
268
|
+
window.setTimeout(postSlide, 500);
|
285
269
|
}
|
286
270
|
$('#notesWindow').addClass('enabled');
|
287
271
|
}
|
@@ -300,6 +284,40 @@ function openNotes()
|
|
300
284
|
}
|
301
285
|
}
|
302
286
|
|
287
|
+
function blankStyledWindow(title, dimensions, classes, resizable) {
|
288
|
+
// yes, the explicit address is needed. Because Chrome.
|
289
|
+
var opts = "status=0,toolbar=0,location=0,menubar=0,"+dimensions;
|
290
|
+
if(resizable) {
|
291
|
+
opts += ",resizable=1,scrollbars=1";
|
292
|
+
}
|
293
|
+
newWindow = window.open('about:blank','', opts);
|
294
|
+
|
295
|
+
// allow time for the window to load for Firefox and IE
|
296
|
+
window.setTimeout(function() {
|
297
|
+
newWindow.document.title = title;
|
298
|
+
|
299
|
+
// IE is terrible and will explode if you try to add a DOM element to another
|
300
|
+
// document. Instead, serialize everything into STRINGS and let jquery rebuild
|
301
|
+
// them into elements again in the context of the other document.
|
302
|
+
// Because IE.
|
303
|
+
|
304
|
+
$(newWindow.document.head).append('<base href="' + window.location.origin + '"/>');
|
305
|
+
$('link[rel="stylesheet"]').each(function() {
|
306
|
+
var href = $(this).attr('href');
|
307
|
+
var style = '<link rel="stylesheet" type="text/css" href="' + href + '">'
|
308
|
+
$(newWindow.document.head).append(style);
|
309
|
+
});
|
310
|
+
|
311
|
+
$(newWindow.document.body).addClass('floating');
|
312
|
+
if(classes) {
|
313
|
+
$(newWindow.document.body).addClass(classes);
|
314
|
+
}
|
315
|
+
|
316
|
+
}, 500);
|
317
|
+
|
318
|
+
return newWindow;
|
319
|
+
}
|
320
|
+
|
303
321
|
function printSlides()
|
304
322
|
{
|
305
323
|
try {
|
@@ -422,7 +440,7 @@ function markCompleted(questionID) {
|
|
422
440
|
function update() {
|
423
441
|
if(mode.update) {
|
424
442
|
var slideName = $("#slideFile").text();
|
425
|
-
ws.send(JSON.stringify({ message: 'update', slide: slidenum, name: slideName}));
|
443
|
+
ws.send(JSON.stringify({ message: 'update', slide: slidenum, name: slideName, increment: incrCurr}));
|
426
444
|
}
|
427
445
|
}
|
428
446
|
|
@@ -499,7 +517,18 @@ function postSlide() {
|
|
499
517
|
$('#notes').prepend(ul);
|
500
518
|
}
|
501
519
|
|
502
|
-
|
520
|
+
var nextIndex = slidenum + 1;
|
521
|
+
var nextSlide = (nextIndex >= slides.size()) ? '' : slides.eq(nextIndex).html();
|
522
|
+
var prevSlide = (slidenum > 0) ? slides.eq(slidenum - 1).html() : ''
|
523
|
+
|
524
|
+
$('#nextSlide .container').html(nextSlide);
|
525
|
+
$('#prevSlide .container').html(prevSlide);
|
526
|
+
|
527
|
+
if (windowIsOpen(nextWindow)) {
|
528
|
+
$(nextWindow.document.body).html(nextSlide);
|
529
|
+
}
|
530
|
+
|
531
|
+
if (windowIsOpen(notesWindow)) {
|
503
532
|
$(notesWindow.document.body).html(notes);
|
504
533
|
}
|
505
534
|
|
@@ -522,18 +551,19 @@ function presenterKeyDown(event){
|
|
522
551
|
}
|
523
552
|
|
524
553
|
switch(getAction(event)) {
|
525
|
-
case 'DEBUG': toggleDebug();
|
526
|
-
case 'PREV': presPrevStep();
|
527
|
-
case 'NEXT': presNextStep();
|
528
|
-
case '
|
529
|
-
case '
|
530
|
-
case '
|
531
|
-
case '
|
532
|
-
case '
|
533
|
-
case '
|
534
|
-
case '
|
535
|
-
case '
|
536
|
-
case '
|
554
|
+
case 'DEBUG': toggleDebug(); break;
|
555
|
+
case 'PREV': presPrevStep(); break; // Watch that this uses presPrevStep and not prevStep
|
556
|
+
case 'NEXT': presNextStep(); break; // Same here
|
557
|
+
case 'REFRESH': reloadSlides(); break;
|
558
|
+
case 'RELOAD': reloadSlides(true); break;
|
559
|
+
case 'CONTENTS': toggleContents(); break;
|
560
|
+
case 'HELP': toggleHelp(); break;
|
561
|
+
case 'BLANK': blankScreen(); break;
|
562
|
+
case 'FOOTER': toggleFooter(); break;
|
563
|
+
case 'FOLLOW': toggleFollow(); break;
|
564
|
+
case 'NOTES': toggleNotes(); break;
|
565
|
+
case 'PAUSE': togglePause(); break;
|
566
|
+
case 'PRESHOW': togglePreShow(); break;
|
537
567
|
case 'CLEAR':
|
538
568
|
removeResults();
|
539
569
|
try {
|
@@ -722,3 +752,100 @@ function toggleAnnotations()
|
|
722
752
|
$('canvas.annotations').hide();
|
723
753
|
}
|
724
754
|
}
|
755
|
+
|
756
|
+
function openNext() {
|
757
|
+
$("#nextWindowConfirmation").slideUp(125);
|
758
|
+
try {
|
759
|
+
if(windowIsClosed(nextWindow)){
|
760
|
+
nextWindow = blankStyledWindow("Next Slide Preview", 'width=320,height=300', 'next');
|
761
|
+
|
762
|
+
// Firefox doesn't load content properly unless we delay it slightly. Yay for race conditions.
|
763
|
+
// nextWindow.addEventListener("unload", function() {
|
764
|
+
window.setTimeout(function() {
|
765
|
+
// call back and update the parent presenter if the window is closed
|
766
|
+
nextWindow.onunload = function(e) {
|
767
|
+
nextWindow.opener.chooseLayout('default');
|
768
|
+
};
|
769
|
+
|
770
|
+
postSlide();
|
771
|
+
}, 500);
|
772
|
+
|
773
|
+
}
|
774
|
+
}
|
775
|
+
catch(e) {
|
776
|
+
console.log(e);
|
777
|
+
console.log('Failed to open or connect next window. Popup blocker?');
|
778
|
+
}
|
779
|
+
}
|
780
|
+
|
781
|
+
/********************
|
782
|
+
Layout selection incorporates previews and the old next window
|
783
|
+
********************/
|
784
|
+
function chooseLayout(layout)
|
785
|
+
{
|
786
|
+
// in case we're being called externally, make the UI match
|
787
|
+
$('#layoutSelector').val(layout);
|
788
|
+
$("#nextWindowConfirmation").slideUp(125);
|
789
|
+
console.log("Setting layout to " + layout);
|
790
|
+
|
791
|
+
// change focus so we don't inadvertently change layout again by changing slides
|
792
|
+
$("#preview").focus();
|
793
|
+
$("#layoutSelector").blur();
|
794
|
+
|
795
|
+
// what we are switching *from*
|
796
|
+
switch(mode.layout) {
|
797
|
+
case 'thumbs':
|
798
|
+
$('#preview').removeClass('thumbs');
|
799
|
+
$('#preview .thumb').hide();
|
800
|
+
break;
|
801
|
+
|
802
|
+
case 'beside':
|
803
|
+
$('#preview').removeClass('beside');
|
804
|
+
$('#preview #nextSlide .container').removeAttr("style");
|
805
|
+
$('#preview #nextSlide').hide();
|
806
|
+
break;
|
807
|
+
|
808
|
+
case 'floating':
|
809
|
+
try {
|
810
|
+
if (nextWindow) {
|
811
|
+
// unregister the event so we don't accidentally double-fire
|
812
|
+
nextWindow.window.onunload = null;
|
813
|
+
nextWindow.close();
|
814
|
+
}
|
815
|
+
}
|
816
|
+
catch (e) {
|
817
|
+
console.log(e);
|
818
|
+
console.log('Next window failed to close properly.');
|
819
|
+
}
|
820
|
+
break;
|
821
|
+
|
822
|
+
default:
|
823
|
+
|
824
|
+
}
|
825
|
+
|
826
|
+
// what we are switching *to*
|
827
|
+
switch(layout) {
|
828
|
+
case 'thumbs':
|
829
|
+
$('#preview').addClass('thumbs');
|
830
|
+
$('#preview .thumb').show();
|
831
|
+
break;
|
832
|
+
|
833
|
+
case 'beside':
|
834
|
+
$('#preview').addClass('beside');
|
835
|
+
$('#preview #nextSlide').show();
|
836
|
+
|
837
|
+
var w = $('#nextSlide .container').width();
|
838
|
+
$('#nextSlide .container').height(w*.75)
|
839
|
+
break;
|
840
|
+
|
841
|
+
case 'floating':
|
842
|
+
$("#nextWindowConfirmation").slideDown(125);
|
843
|
+
break;
|
844
|
+
|
845
|
+
default:
|
846
|
+
|
847
|
+
}
|
848
|
+
|
849
|
+
mode.layout = layout;
|
850
|
+
zoom(true);
|
851
|
+
}
|