showoff 0.9.7.1 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/showoff +4 -0
- data/lib/showoff.rb +22 -5
- data/lib/showoff/version.rb +1 -1
- data/public/css/showoff.css +14 -5
- data/public/js/presenter.js +69 -9
- data/public/js/sh_lang/sh_docker.js +137 -0
- data/public/js/sh_lang/sh_docker.min.js +1 -0
- data/public/js/showoff.js +32 -3
- data/views/header.erb +8 -2
- data/views/header_mini.erb +4 -0
- data/views/index.erb +5 -0
- data/views/onepage.erb +4 -0
- data/views/presenter.erb +9 -3
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0cff52fdf5f38360a5e10678acb81713da42532
|
4
|
+
data.tar.gz: 3dd12a4a362f8b0de756df4de1a34727533ee89c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe5086466395d08f3667f90a76729d16d0546e5e57144ddf9a3dbcf69a1715f4cf57c6c658801f8a47d6ec4bb2e6090e707c69720eb7d4387d8670981d23b74b
|
7
|
+
data.tar.gz: 45a82534917bbdf68e3f792a381bac569a699184aa4bb3efe3b3013eda3b2367c89e3ef54f8b634d2ddaece0bd6b88fef46f7a171f9827ae23ac4e580028900b
|
data/bin/showoff
CHANGED
@@ -99,6 +99,9 @@ command :serve do |c|
|
|
99
99
|
c.desc 'Show verbose messaging'
|
100
100
|
c.switch :verbose
|
101
101
|
|
102
|
+
c.desc 'Enable code review'
|
103
|
+
c.switch :review
|
104
|
+
|
102
105
|
c.desc 'Port on which to run'
|
103
106
|
c.default_value "9090"
|
104
107
|
c.flag [:p,:port]
|
@@ -138,6 +141,7 @@ To run it from presenter view, go to: [ #{url}/presenter ]
|
|
138
141
|
:pres_file => options[:f],
|
139
142
|
:pres_dir => args[0],
|
140
143
|
:verbose => options[:verbose],
|
144
|
+
:review => options[:review],
|
141
145
|
:bind => options[:h]
|
142
146
|
end
|
143
147
|
end
|
data/lib/showoff.rb
CHANGED
@@ -14,13 +14,15 @@ require "#{here}/commandline_parser"
|
|
14
14
|
begin
|
15
15
|
require 'RMagick'
|
16
16
|
rescue LoadError
|
17
|
-
$stderr.puts '
|
17
|
+
$stderr.puts 'NOTICE: * automatic image sizing unavailable; install RMagick for this functionality.'
|
18
18
|
end
|
19
19
|
|
20
20
|
begin
|
21
21
|
require 'pdfkit'
|
22
22
|
rescue LoadError
|
23
|
-
$stderr.puts '
|
23
|
+
$stderr.puts 'NOTICE: * internal pdf generation disabled; install PDFKit for this functionality'
|
24
|
+
$stderr.puts 'NOTICE: the PDFKit integration will likely be deprecated. Instead, you should'
|
25
|
+
$stderr.puts 'NOTICE: simply use your browser to print from the /print endpoint.'
|
24
26
|
end
|
25
27
|
|
26
28
|
require 'tilt'
|
@@ -43,6 +45,8 @@ class ShowOff < Sinatra::Application
|
|
43
45
|
set :presenters, []
|
44
46
|
|
45
47
|
set :verbose, false
|
48
|
+
set :review, false
|
49
|
+
|
46
50
|
set :pres_dir, '.'
|
47
51
|
set :pres_file, 'showoff.json'
|
48
52
|
set :page_size, "Letter"
|
@@ -69,6 +73,8 @@ class ShowOff < Sinatra::Application
|
|
69
73
|
@logger.formatter = proc { |severity,datetime,progname,msg| "#{progname} #{msg}\n" }
|
70
74
|
@logger.level = settings.verbose ? Logger::DEBUG : Logger::WARN
|
71
75
|
|
76
|
+
@review = settings.review
|
77
|
+
|
72
78
|
dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
73
79
|
@logger.debug(dir)
|
74
80
|
|
@@ -590,13 +596,21 @@ class ShowOff < Sinatra::Application
|
|
590
596
|
@asset_path = "./"
|
591
597
|
end
|
592
598
|
|
599
|
+
# Display favicon in the window if configured
|
600
|
+
@favicon = settings.showoff_config['favicon']
|
601
|
+
|
593
602
|
# Check to see if the presentation has enabled feedback
|
594
|
-
@feedback = settings.showoff_config['feedback']
|
603
|
+
@feedback = settings.showoff_config['feedback'] unless params[:feedback] == 'false'
|
604
|
+
|
605
|
+
# Provide a button in the sidebar for interactive editing if configured
|
606
|
+
@edit = settings.showoff_config['edit'] if @review
|
607
|
+
|
595
608
|
erb :index
|
596
609
|
end
|
597
610
|
|
598
611
|
def presenter
|
599
612
|
@issues = settings.showoff_config['issues']
|
613
|
+
@edit = settings.showoff_config['edit'] if @review
|
600
614
|
@@cookie ||= guid()
|
601
615
|
response.set_cookie('presenter', @@cookie)
|
602
616
|
erb :presenter
|
@@ -645,17 +659,20 @@ class ShowOff < Sinatra::Application
|
|
645
659
|
|
646
660
|
def onepage(static=false)
|
647
661
|
@slides = get_slides_html(:static=>static, :toc=>true)
|
662
|
+
@favicon = settings.showoff_config['favicon']
|
648
663
|
#@languages = @slides.scan(/<pre class=".*(?!sh_sourceCode)(sh_[\w-]+).*"/).uniq.map{ |w| "/sh_lang/#{w[0]}.min.js"}
|
649
664
|
erb :onepage
|
650
665
|
end
|
651
666
|
|
652
667
|
def print(static=false)
|
653
668
|
@slides = get_slides_html(:static=>static, :toc=>true, :print=>true)
|
669
|
+
@favicon = settings.showoff_config['favicon']
|
654
670
|
erb :onepage
|
655
671
|
end
|
656
672
|
|
657
673
|
def supplemental(content, static=false)
|
658
674
|
@slides = get_slides_html(:static=>static, :supplemental=>content)
|
675
|
+
@favicon = settings.showoff_config['favicon']
|
659
676
|
@wrapper_classes = ['supplemental']
|
660
677
|
erb :onepage
|
661
678
|
end
|
@@ -665,6 +682,7 @@ class ShowOff < Sinatra::Application
|
|
665
682
|
shared = Dir.glob("#{settings.pres_dir}/_files/share/*").map { |path| File.basename(path) }
|
666
683
|
# We use the icky -999 magic index because it has to be comparable for the view sort
|
667
684
|
@downloads = { -999 => [ true, 'Shared Files', shared ] }
|
685
|
+
@favicon = settings.showoff_config['favicon']
|
668
686
|
rescue Errno::ENOENT => e
|
669
687
|
# don't fail if the directory doesn't exist
|
670
688
|
@downloads = {}
|
@@ -964,8 +982,7 @@ class ShowOff < Sinatra::Application
|
|
964
982
|
protected! if settings.showoff_config['protected'].include? what
|
965
983
|
end
|
966
984
|
|
967
|
-
|
968
|
-
@asset_path = nil
|
985
|
+
@asset_path = env['SCRIPT_NAME'] == '' ? nil : env['SCRIPT_NAME'].gsub(/^\/?/, '/').gsub(/\/?$/, '/')
|
969
986
|
|
970
987
|
begin
|
971
988
|
if (what != "favicon.ico")
|
data/lib/showoff/version.rb
CHANGED
data/public/css/showoff.css
CHANGED
@@ -38,6 +38,7 @@
|
|
38
38
|
border-top-left-radius: 3px;
|
39
39
|
border-top-right-radius: 3px;
|
40
40
|
z-index: 2147483647; /* max, see http://www.puidokas.com/max-z-index/ */
|
41
|
+
display: none;
|
41
42
|
}
|
42
43
|
#followMode {
|
43
44
|
display: none;
|
@@ -134,7 +135,8 @@
|
|
134
135
|
}
|
135
136
|
|
136
137
|
/* nested lists get their bullets back */
|
137
|
-
.content ul ul
|
138
|
+
.content ul ul,
|
139
|
+
.content ol ul {
|
138
140
|
list-style: disc;
|
139
141
|
margin: 10px 10px;
|
140
142
|
padding-left: 40px;
|
@@ -299,6 +301,17 @@ img#disconnected {
|
|
299
301
|
text-align: center;
|
300
302
|
}
|
301
303
|
|
304
|
+
#feedbackSidebar div.row.tools {
|
305
|
+
position: absolute;
|
306
|
+
bottom: 30px;
|
307
|
+
width: 100%;
|
308
|
+
text-align: center;
|
309
|
+
}
|
310
|
+
|
311
|
+
#feedbackSidebar div.row.tools button#editSlide {
|
312
|
+
width: 90%%;
|
313
|
+
margin: auto 5%;
|
314
|
+
}
|
302
315
|
|
303
316
|
.fg-menu-container {
|
304
317
|
z-index: 2147483647; /* max, see http://www.puidokas.com/max-z-index/ */
|
@@ -487,10 +500,6 @@ ul#downloads li {
|
|
487
500
|
margin: 0.5em;
|
488
501
|
}
|
489
502
|
|
490
|
-
span#issueUrl {
|
491
|
-
display: none;
|
492
|
-
}
|
493
|
-
|
494
503
|
/**********************
|
495
504
|
*** stats page ***
|
496
505
|
**********************/
|
data/public/js/presenter.js
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
// presenter js
|
2
2
|
var slaveWindow = null;
|
3
|
+
var nextWindow = null;
|
3
4
|
|
4
5
|
var paceData = [];
|
5
6
|
|
6
7
|
$(document).ready(function(){
|
7
8
|
// set up the presenter modes
|
8
|
-
mode = { track: false, follow: true, update: true, slave: false };
|
9
|
+
mode = { track: false, follow: true, update: true, slave: false, next: false};
|
9
10
|
|
10
11
|
// attempt to open another window for the presentation if the mode defaults
|
11
12
|
// to enabling this. It does not by default, so this is likely a no-op.
|
@@ -103,9 +104,14 @@ function popupLoader(elem, page, id, event)
|
|
103
104
|
}
|
104
105
|
|
105
106
|
function reportIssue() {
|
106
|
-
var slide
|
107
|
-
var
|
108
|
-
|
107
|
+
var slide = $("span#slideFile").text();
|
108
|
+
var link = issueUrl + encodeURIComponent('Issue with slide: ' + slide);
|
109
|
+
window.open(link);
|
110
|
+
}
|
111
|
+
|
112
|
+
function editSlide() {
|
113
|
+
var slide = $("span#slideFile").text();
|
114
|
+
var link = editUrl + slide + ".md";
|
109
115
|
window.open(link);
|
110
116
|
}
|
111
117
|
|
@@ -152,6 +158,58 @@ function openSlave()
|
|
152
158
|
}
|
153
159
|
}
|
154
160
|
|
161
|
+
function nextSlideNum(url) {
|
162
|
+
// Some fudging because the first slide is slide[0] but numbered 1 in the URL
|
163
|
+
console.log(typeof(url));
|
164
|
+
var snum;
|
165
|
+
if (typeof(url) == 'undefined') { snum = currentSlideFromParams()+1; }
|
166
|
+
else { snum = currentSlideFromParams()+2; }
|
167
|
+
return snum;
|
168
|
+
}
|
169
|
+
|
170
|
+
function toggleNext() {
|
171
|
+
mode.next = !mode.next;
|
172
|
+
openNext();
|
173
|
+
}
|
174
|
+
|
175
|
+
function openNext()
|
176
|
+
{
|
177
|
+
if (mode.next) {
|
178
|
+
try {
|
179
|
+
if(nextWindow == null || typeof(nextWindow) == 'undefined' || nextWindow.closed){
|
180
|
+
nextWindow = window.open('/?track=false&feedback=false&next=true#' + nextSlideNum(true),'','width=300,height=200');
|
181
|
+
}
|
182
|
+
else if(nextWindow.location.hash != '#' + nextSlideNum(true)) {
|
183
|
+
// maybe we need to reset content?
|
184
|
+
nextWindow.location.href = '/?track=false&feedback=false&next=true#' + nextSlideNum(true);
|
185
|
+
}
|
186
|
+
|
187
|
+
// maintain the pointer back to the parent.
|
188
|
+
nextWindow.presenterView = window;
|
189
|
+
nextWindow.mode = { track: false, next: true, follow: true };
|
190
|
+
|
191
|
+
$('#nextWindow').addClass('enabled');
|
192
|
+
}
|
193
|
+
catch(e) {
|
194
|
+
console.log('Failed to open or connect next window. Popup blocker?');
|
195
|
+
}
|
196
|
+
|
197
|
+
// Set up a maintenance loop to keep the connection between windows. I wish there were a cleaner way to do this.
|
198
|
+
//if (typeof maintainNext == 'undefined') {
|
199
|
+
// maintainNext = setInterval(openNext, 1000);
|
200
|
+
//}
|
201
|
+
}
|
202
|
+
else {
|
203
|
+
try {
|
204
|
+
nextWindow && nextWindow.close();
|
205
|
+
$('#nextWindow').removeClass('enabled');
|
206
|
+
}
|
207
|
+
catch (e) {
|
208
|
+
console.log('Next window failed to close properly.');
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
155
213
|
function askQuestion(question) {
|
156
214
|
$("#questions ul").prepend($('<li/>').text(question));
|
157
215
|
}
|
@@ -264,11 +322,12 @@ function register() {
|
|
264
322
|
|
265
323
|
function presPrevStep()
|
266
324
|
{
|
267
|
-
|
268
|
-
|
269
|
-
|
325
|
+
prevStep();
|
326
|
+
try { slaveWindow.prevStep(false) } catch (e) {};
|
327
|
+
try { nextWindow.gotoSlide(nextSlideNum()) } catch (e) {};
|
328
|
+
postSlide();
|
270
329
|
|
271
|
-
|
330
|
+
update();
|
272
331
|
}
|
273
332
|
|
274
333
|
function presNextStep()
|
@@ -278,8 +337,9 @@ function presNextStep()
|
|
278
337
|
incrCurr = slaveWindow.incrCurr
|
279
338
|
incrSteps = slaveWindow.incrSteps
|
280
339
|
*/
|
281
|
-
|
340
|
+
nextStep();
|
282
341
|
try { slaveWindow.nextStep(false) } catch (e) {};
|
342
|
+
try { nextWindow.gotoSlide(nextSlideNum()) } catch (e) {};
|
283
343
|
postSlide();
|
284
344
|
|
285
345
|
update();
|
@@ -0,0 +1,137 @@
|
|
1
|
+
if (! this.sh_languages) {
|
2
|
+
this.sh_languages = {};
|
3
|
+
}
|
4
|
+
sh_languages['docker'] = [
|
5
|
+
[
|
6
|
+
[
|
7
|
+
/\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g,
|
8
|
+
'sh_number',
|
9
|
+
-1
|
10
|
+
],
|
11
|
+
[
|
12
|
+
/"/g,
|
13
|
+
'sh_string',
|
14
|
+
1
|
15
|
+
],
|
16
|
+
[
|
17
|
+
/'/g,
|
18
|
+
'sh_string',
|
19
|
+
2
|
20
|
+
],
|
21
|
+
[
|
22
|
+
/</g,
|
23
|
+
'sh_string',
|
24
|
+
3
|
25
|
+
],
|
26
|
+
[
|
27
|
+
/\/[^\n]*\/\s/g, // anchor to \s to avoid matching directory names.
|
28
|
+
'sh_regexp',
|
29
|
+
-1
|
30
|
+
],
|
31
|
+
[
|
32
|
+
/(%r)(\{(?:\\\}|#\{[A-Za-z0-9]+\}|[^}])*\})/g,
|
33
|
+
['sh_symbol', 'sh_regexp'],
|
34
|
+
-1
|
35
|
+
],
|
36
|
+
[
|
37
|
+
/\b[A-Za-z0-9]+(?=\s*[=|\+]>)/g,
|
38
|
+
'sh_attribute',
|
39
|
+
-1
|
40
|
+
],
|
41
|
+
[
|
42
|
+
/\b(?:FROM|MAINTAINER|ENV|ADD|RUN|WORKDIR|VOLUME|ONBUILD|CMD|ENTRYPOINT|EXPOSE|USER)\b/g,
|
43
|
+
'sh_keyword',
|
44
|
+
-1
|
45
|
+
],
|
46
|
+
[
|
47
|
+
/(?:^\=begin)/g,
|
48
|
+
'sh_comment',
|
49
|
+
4
|
50
|
+
],
|
51
|
+
[
|
52
|
+
/[A-Za-z0-9]+(?:\?|!)/g,
|
53
|
+
'sh_normal',
|
54
|
+
-1
|
55
|
+
],
|
56
|
+
[
|
57
|
+
/~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g,
|
58
|
+
'sh_symbol',
|
59
|
+
-1
|
60
|
+
],
|
61
|
+
[
|
62
|
+
/(#)(\{)/g,
|
63
|
+
['sh_symbol', 'sh_cbracket'],
|
64
|
+
-1
|
65
|
+
],
|
66
|
+
[
|
67
|
+
/#/g,
|
68
|
+
'sh_comment',
|
69
|
+
1
|
70
|
+
],
|
71
|
+
[
|
72
|
+
/\{|\}/g,
|
73
|
+
'sh_cbracket',
|
74
|
+
-1
|
75
|
+
]
|
76
|
+
],
|
77
|
+
[
|
78
|
+
[
|
79
|
+
/$/g,
|
80
|
+
null,
|
81
|
+
-2
|
82
|
+
],
|
83
|
+
[
|
84
|
+
/\\(?:\\|")/g,
|
85
|
+
null,
|
86
|
+
-1
|
87
|
+
],
|
88
|
+
[
|
89
|
+
/"/g,
|
90
|
+
'sh_string',
|
91
|
+
-2
|
92
|
+
]
|
93
|
+
],
|
94
|
+
[
|
95
|
+
[
|
96
|
+
/$/g,
|
97
|
+
null,
|
98
|
+
-2
|
99
|
+
],
|
100
|
+
[
|
101
|
+
/\\(?:\\|')/g,
|
102
|
+
null,
|
103
|
+
-1
|
104
|
+
],
|
105
|
+
[
|
106
|
+
/'/g,
|
107
|
+
'sh_string',
|
108
|
+
-2
|
109
|
+
]
|
110
|
+
],
|
111
|
+
[
|
112
|
+
[
|
113
|
+
/$/g,
|
114
|
+
null,
|
115
|
+
-2
|
116
|
+
],
|
117
|
+
[
|
118
|
+
/>/g,
|
119
|
+
'sh_string',
|
120
|
+
-2
|
121
|
+
]
|
122
|
+
],
|
123
|
+
[
|
124
|
+
[
|
125
|
+
/^(?:\=end)/g,
|
126
|
+
'sh_comment',
|
127
|
+
5
|
128
|
+
]
|
129
|
+
],
|
130
|
+
[
|
131
|
+
[
|
132
|
+
/$/g,
|
133
|
+
null,
|
134
|
+
-2
|
135
|
+
]
|
136
|
+
]
|
137
|
+
];
|
@@ -0,0 +1 @@
|
|
1
|
+
if(!this.sh_languages){this.sh_languages={}}sh_languages.docker=[[[/\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g,"sh_number",-1],[/"/g,"sh_string",1],[/'/g,"sh_string",2],[/</g,"sh_string",3],[/\/[^\n]*\/\s/g,"sh_regexp",-1],[/(%r)(\{(?:\\\}|#\{[A-Za-z0-9]+\}|[^}])*\})/g,["sh_symbol","sh_regexp"],-1],[/\b[A-Za-z0-9]+(?=\s*[=|\+]>)/g,"sh_attribute",-1],[/\b(?:FROM|MAINTAINER|ENV|ADD|RUN|WORKDIR|VOLUME|ONBUILD|CMD|ENTRYPOINT|EXPOSE|USER)\b/g,"sh_keyword",-1],[/(?:^\=begin)/g,"sh_comment",4],[/[A-Za-z0-9]+(?:\?|!)/g,"sh_normal",-1],[/~|!|%|\^|\*|\(|\)|-|\+|=|\[|\]|\\|:|;|,|\.|\/|\?|&|<|>|\|/g,"sh_symbol",-1],[/(#)(\{)/g,["sh_symbol","sh_cbracket"],-1],[/#/g,"sh_comment",1],[/\{|\}/g,"sh_cbracket",-1]],[[/$/g,null,-2],[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/$/g,null,-2],[/\\(?:\\|')/g,null,-1],[/'/g,"sh_string",-2]],[[/$/g,null,-2],[/>/g,"sh_string",-2]],[[/^(?:\=end)/g,"sh_comment",5]],[[/$/g,null,-2]]];
|
data/public/js/showoff.js
CHANGED
@@ -60,6 +60,9 @@ function setupPreso(load_slides, prefix) {
|
|
60
60
|
// give us the ability to disable tracking via url parameter
|
61
61
|
if(query.track == 'false') mode.track = false;
|
62
62
|
|
63
|
+
// make sure that the next view doesn't bugger things on the first load
|
64
|
+
if(query.next == 'true') mode.next = true;
|
65
|
+
|
63
66
|
// Make sure the slides always look right.
|
64
67
|
// Better would be dynamic calculations, but this is enough for now.
|
65
68
|
$(window).resize(function(){location.reload();});
|
@@ -83,6 +86,7 @@ function setupPreso(load_slides, prefix) {
|
|
83
86
|
$("#sendFeedback").click(function() {
|
84
87
|
sendFeedback($( "input:radio[name=rating]:checked" ).val(), $("textarea#feedback").val())
|
85
88
|
});
|
89
|
+
$("#editSlide").click(function() { editSlide(); });
|
86
90
|
|
87
91
|
$("textarea#question").val(questionPrompt);
|
88
92
|
$("textarea#feedback").val(feedbackPrompt);
|
@@ -90,7 +94,9 @@ function setupPreso(load_slides, prefix) {
|
|
90
94
|
$("textarea#feedback").focus(function() { clearIf($(this), feedbackPrompt) });
|
91
95
|
|
92
96
|
// Open up our control socket
|
93
|
-
|
97
|
+
if(mode.track) {
|
98
|
+
connectControlChannel();
|
99
|
+
}
|
94
100
|
/*
|
95
101
|
ws = new WebSocket('ws://' + location.host + '/control');
|
96
102
|
ws.onopen = function() { connected(); };
|
@@ -195,17 +201,33 @@ function checkSlideParameter() {
|
|
195
201
|
}
|
196
202
|
}
|
197
203
|
|
204
|
+
function currentSlideFromName(name) {
|
205
|
+
var count = 0;
|
206
|
+
slides.each(function(s, slide) {
|
207
|
+
if (name == $(slide).find(".content").attr("ref") ) {
|
208
|
+
found = count;
|
209
|
+
return false;
|
210
|
+
}
|
211
|
+
count++;
|
212
|
+
});
|
213
|
+
return count;
|
214
|
+
}
|
215
|
+
|
198
216
|
function currentSlideFromParams() {
|
199
217
|
var result;
|
200
218
|
if (result = window.location.hash.match(/#([0-9]+)/)) {
|
201
219
|
return result[result.length - 1] - 1;
|
202
220
|
}
|
221
|
+
else {
|
222
|
+
var hash = window.location.hash
|
223
|
+
return currentSlideFromName(hash.substr(1, hash.length))
|
224
|
+
}
|
203
225
|
}
|
204
226
|
|
205
227
|
function setupSlideParamsCheck() {
|
206
228
|
var check = function() {
|
207
229
|
var currentSlide = currentSlideFromParams();
|
208
|
-
if (slidenum != currentSlide) {
|
230
|
+
if (!isNaN(currentSlide) && slidenum != currentSlide) {
|
209
231
|
slidenum = currentSlide;
|
210
232
|
showSlide();
|
211
233
|
}
|
@@ -283,7 +305,7 @@ function showSlide(back_step, updatepv) {
|
|
283
305
|
$('#slideFilename').text(fileName);
|
284
306
|
|
285
307
|
// Update presenter view, if we spawned one
|
286
|
-
if (updatepv && 'presenterView' in window) {
|
308
|
+
if (updatepv && 'presenterView' in window && ! mode.next) {
|
287
309
|
var pv = window.presenterView;
|
288
310
|
pv.slidenum = slidenum;
|
289
311
|
pv.incrCurr = incrCurr
|
@@ -448,6 +470,13 @@ function track() {
|
|
448
470
|
}
|
449
471
|
}
|
450
472
|
|
473
|
+
// Open a new tab with an online code editor, if so configured
|
474
|
+
function editSlide() {
|
475
|
+
var slide = $("span#slideFilename").text();
|
476
|
+
var link = editUrl + slide + ".md";
|
477
|
+
window.open(link);
|
478
|
+
}
|
479
|
+
|
451
480
|
function follow(slide) {
|
452
481
|
if (mode.follow) {
|
453
482
|
console.log("New slide: " + slide);
|
data/views/header.erb
CHANGED
@@ -5,6 +5,10 @@
|
|
5
5
|
|
6
6
|
<link rel="stylesheet" href="<%= @asset_path %>/css/reset.css" type="text/css"/>
|
7
7
|
|
8
|
+
<% if @favicon %>
|
9
|
+
<link rel="icon" href="<%= @favicon %>"/>
|
10
|
+
<% end %>
|
11
|
+
|
8
12
|
<link type="text/css" href="<%= @asset_path %>/css/fg.menu.css" media="screen" rel="stylesheet" />
|
9
13
|
<link type="text/css" href="<%= @asset_path %>/css/theme/ui.all.css" media="screen" rel="stylesheet" />
|
10
14
|
<link type="text/css" href="<%= @asset_path %>/css/sh_style.css" rel="stylesheet" />
|
@@ -44,7 +48,9 @@
|
|
44
48
|
<% end %>
|
45
49
|
|
46
50
|
<script type="text/javascript">
|
47
|
-
|
51
|
+
$(function(){
|
48
52
|
setupPreso(<%= @slides.nil? ? "true" : "false"%>, '<%= @asset_path %>');
|
49
|
-
|
53
|
+
});
|
54
|
+
|
55
|
+
editUrl = "<%= @edit %>";
|
50
56
|
</script>
|
data/views/header_mini.erb
CHANGED
@@ -3,6 +3,10 @@
|
|
3
3
|
|
4
4
|
<meta name="viewport" content="width=device-width"/>
|
5
5
|
|
6
|
+
<% if @favicon %>
|
7
|
+
<link rel="icon" href="<%= @favicon %>"/>
|
8
|
+
<% end %>
|
9
|
+
|
6
10
|
<link rel="stylesheet" href="<%= @asset_path %>/css/reset.css" type="text/css"/>
|
7
11
|
<link rel="stylesheet" href="<%= @asset_path %>/css/showoff.css" type="text/css"/>
|
8
12
|
|
data/views/index.erb
CHANGED
@@ -41,6 +41,11 @@
|
|
41
41
|
<textarea id="feedback"></textarea>
|
42
42
|
<button id="sendFeedback">Send Feedback</button>
|
43
43
|
</div>
|
44
|
+
<% if @edit then %>
|
45
|
+
<div class="row tools">
|
46
|
+
<button id="editSlide">Edit Current Slide</button>
|
47
|
+
</div>
|
48
|
+
<% end %>
|
44
49
|
<div id="disclaimer">All features are anonymous</div>
|
45
50
|
</div>
|
46
51
|
<div id="feedbackHandle"></div>
|
data/views/onepage.erb
CHANGED
@@ -5,6 +5,10 @@
|
|
5
5
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
6
6
|
<title><%= @title %></title>
|
7
7
|
|
8
|
+
<% if @favicon %>
|
9
|
+
<link rel="icon" href="<%= @favicon %>"/>
|
10
|
+
<% end %>
|
11
|
+
|
8
12
|
<% if @inline %>
|
9
13
|
|
10
14
|
<%= inline_css(['reset.css', 'showoff.css', 'theme/ui.all.css', 'sh_style.css', 'onepage.css'], 'public/css') %>
|
data/views/presenter.erb
CHANGED
@@ -6,12 +6,14 @@
|
|
6
6
|
<%= erb :header %>
|
7
7
|
<link rel="stylesheet" href="<%= @asset_path %>/css/presenter.css" type="text/css"/>
|
8
8
|
<script type="text/javascript" src="<%= @asset_path %>/js/presenter.js"></script>
|
9
|
+
<script type="text/javascript">
|
10
|
+
editUrl = "<%= @edit %>";
|
11
|
+
issueUrl = "<%= @issues %>";
|
12
|
+
</script>
|
9
13
|
</head>
|
10
14
|
|
11
15
|
<body>
|
12
16
|
|
13
|
-
<span id="issueUrl"><%= @issues %></span>
|
14
|
-
|
15
17
|
<div id="help">
|
16
18
|
<table>
|
17
19
|
<tr><td class="key">z, ?</td><td>toggle help (this)</td></tr>
|
@@ -33,12 +35,16 @@
|
|
33
35
|
</div>
|
34
36
|
<span id="links">
|
35
37
|
<span class="desktop">
|
38
|
+
<% if @edit %>
|
39
|
+
<a id="edit" href="javascript:editSlide();" title="Edit current slide in new window.">Edit Slide</a>
|
40
|
+
<% end %>
|
36
41
|
<% if @issues %>
|
37
42
|
<a id="report" href="javascript:reportIssue();" title="Report an issue with the current slide.">Report Issue With Slide</a>
|
38
43
|
<% end %>
|
39
44
|
<a id="stats" href="/stats" target="_showoffchild">Viewing Statistics</a>
|
40
45
|
<a id="downloads" href="/download" target="_showoffchild">Downloads</a>
|
41
|
-
<a id="slaveWindow" href="javascript:toggleSlave();" title="Enable the slave window.">
|
46
|
+
<a id="slaveWindow" href="javascript:toggleSlave();" title="Enable the slave window.">Slave Window</a>
|
47
|
+
<a id="nextWindow" href="javascript:toggleNext();" title="Enable the next window view.">Next Window</a>
|
42
48
|
<a id="generatePDF" href="/pdf" title="Call out to wkhtmltopdf to generate a PDF.">Generate PDF</a>
|
43
49
|
<a id="onePage" href="/onepage" title="Load the single page view. Useful for printing.">Single Page</a>
|
44
50
|
</span>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: showoff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Chacon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -239,6 +239,8 @@ files:
|
|
239
239
|
- public/js/sh_lang/sh_cucumber.min.js
|
240
240
|
- public/js/sh_lang/sh_desktop.min.js
|
241
241
|
- public/js/sh_lang/sh_diff.min.js
|
242
|
+
- public/js/sh_lang/sh_docker.js
|
243
|
+
- public/js/sh_lang/sh_docker.min.js
|
242
244
|
- public/js/sh_lang/sh_erlang.min.js
|
243
245
|
- public/js/sh_lang/sh_flex.min.js
|
244
246
|
- public/js/sh_lang/sh_gherkin.js
|
@@ -301,7 +303,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
301
303
|
version: '0'
|
302
304
|
requirements: []
|
303
305
|
rubyforge_project:
|
304
|
-
rubygems_version: 2.0.
|
306
|
+
rubygems_version: 2.0.14
|
305
307
|
signing_key:
|
306
308
|
specification_version: 4
|
307
309
|
summary: The best damn presentation software a developer could ever love.
|