reveal.rb 0.4.0 → 0.5.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 +5 -5
- data/.ruby-version +1 -1
- data/.travis.yml +2 -1
- data/Dockerfile +4 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +7 -1
- data/README.md +1 -1
- data/lib/reveal/command.rb +9 -3
- data/lib/reveal/templates/revealjs/css/print/paper.css +4 -3
- data/lib/reveal/templates/revealjs/css/print/pdf.css +59 -38
- data/lib/reveal/templates/revealjs/css/reveal.css +654 -274
- data/lib/reveal/templates/revealjs/css/theme/beige.css +65 -68
- data/lib/reveal/templates/revealjs/css/theme/black.css +58 -61
- data/lib/reveal/templates/revealjs/css/theme/blood.css +64 -62
- data/lib/reveal/templates/revealjs/css/theme/league.css +59 -62
- data/lib/reveal/templates/revealjs/css/theme/moon.css +59 -62
- data/lib/reveal/templates/revealjs/css/theme/night.css +58 -61
- data/lib/reveal/templates/revealjs/css/theme/serif.css +56 -59
- data/lib/reveal/templates/revealjs/css/theme/simple.css +60 -60
- data/lib/reveal/templates/revealjs/css/theme/sky.css +59 -62
- data/lib/reveal/templates/revealjs/css/theme/solarized.css +59 -62
- data/lib/reveal/templates/revealjs/css/theme/white.css +59 -62
- data/lib/reveal/templates/revealjs/index.html +14 -376
- data/lib/reveal/templates/revealjs/js/reveal.js +1073 -342
- data/lib/reveal/templates/revealjs/lib/css/zenburn.css +41 -78
- data/lib/reveal/templates/revealjs/lib/js/head.min.js +9 -8
- data/lib/reveal/templates/revealjs/plugin/highlight/highlight.js +51 -4
- data/lib/reveal/templates/revealjs/plugin/markdown/markdown.js +38 -19
- data/lib/reveal/templates/revealjs/plugin/markdown/marked.js +1 -1
- data/lib/reveal/templates/revealjs/plugin/math/math.js +5 -2
- data/lib/reveal/templates/revealjs/plugin/multiplex/client.js +1 -1
- data/lib/reveal/templates/revealjs/plugin/multiplex/index.js +24 -16
- data/lib/reveal/templates/revealjs/plugin/multiplex/master.js +26 -43
- data/lib/reveal/templates/revealjs/plugin/multiplex/package.json +19 -0
- data/lib/reveal/templates/revealjs/plugin/notes/notes.html +385 -32
- data/lib/reveal/templates/revealjs/plugin/notes/notes.js +39 -6
- data/lib/reveal/templates/revealjs/plugin/notes-server/client.js +6 -1
- data/lib/reveal/templates/revealjs/plugin/notes-server/index.js +17 -14
- data/lib/reveal/templates/revealjs/plugin/notes-server/notes.html +215 -26
- data/lib/reveal/templates/revealjs/plugin/print-pdf/print-pdf.js +48 -27
- data/lib/reveal/templates/revealjs/plugin/search/search.js +41 -31
- data/lib/reveal/templates/revealjs/plugin/zoom-js/zoom.js +17 -23
- data/lib/reveal/templates/template.html +12 -41
- data/lib/reveal/version.rb +1 -1
- data/spec/lib/reveal/command_spec.rb +37 -0
- metadata +14 -16
- data/lib/reveal/templates/revealjs/lib/font/league-gothic/LICENSE +0 -2
- data/lib/reveal/templates/revealjs/lib/font/source-sans-pro/LICENSE +0 -45
- data/lib/reveal/templates/revealjs/plugin/leap/leap.js +0 -159
- data/lib/reveal/templates/revealjs/plugin/remotes/remotes.js +0 -39
@@ -1,39 +1,42 @@
|
|
1
|
+
var http = require('http');
|
1
2
|
var express = require('express');
|
2
3
|
var fs = require('fs');
|
3
4
|
var io = require('socket.io');
|
4
|
-
var _ = require('underscore');
|
5
5
|
var Mustache = require('mustache');
|
6
6
|
|
7
|
-
var app = express
|
7
|
+
var app = express();
|
8
8
|
var staticDir = express.static;
|
9
|
+
var server = http.createServer(app);
|
9
10
|
|
10
|
-
io
|
11
|
+
io = io(server);
|
11
12
|
|
12
13
|
var opts = {
|
13
14
|
port : 1947,
|
14
15
|
baseDir : __dirname + '/../../'
|
15
16
|
};
|
16
17
|
|
17
|
-
io.
|
18
|
+
io.on( 'connection', function( socket ) {
|
18
19
|
|
19
|
-
socket.on( '
|
20
|
-
socket.broadcast.emit( '
|
20
|
+
socket.on( 'new-subscriber', function( data ) {
|
21
|
+
socket.broadcast.emit( 'new-subscriber', data );
|
21
22
|
});
|
22
23
|
|
23
24
|
socket.on( 'statechanged', function( data ) {
|
25
|
+
delete data.state.overview;
|
24
26
|
socket.broadcast.emit( 'statechanged', data );
|
25
27
|
});
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach( function( dir ) {
|
32
|
-
app.use( '/' + dir, staticDir( opts.baseDir + dir ) );
|
29
|
+
socket.on( 'statechanged-speaker', function( data ) {
|
30
|
+
delete data.state.overview;
|
31
|
+
socket.broadcast.emit( 'statechanged-speaker', data );
|
33
32
|
});
|
34
33
|
|
35
34
|
});
|
36
35
|
|
36
|
+
[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach( function( dir ) {
|
37
|
+
app.use( '/' + dir, staticDir( opts.baseDir + dir ) );
|
38
|
+
});
|
39
|
+
|
37
40
|
app.get('/', function( req, res ) {
|
38
41
|
|
39
42
|
res.writeHead( 200, { 'Content-Type': 'text/html' } );
|
@@ -52,7 +55,7 @@ app.get( '/notes/:socketId', function( req, res ) {
|
|
52
55
|
});
|
53
56
|
|
54
57
|
// Actually listen
|
55
|
-
|
58
|
+
server.listen( opts.port || null );
|
56
59
|
|
57
60
|
var brown = '\033[33m',
|
58
61
|
green = '\033[32m',
|
@@ -62,5 +65,5 @@ var slidesLocation = 'http://localhost' + ( opts.port ? ( ':' + opts.port ) : ''
|
|
62
65
|
|
63
66
|
console.log( brown + 'reveal.js - Speaker Notes' + reset );
|
64
67
|
console.log( '1. Open the slides at ' + green + slidesLocation + reset );
|
65
|
-
console.log( '2. Click on the link your JS console to go to the notes page' );
|
68
|
+
console.log( '2. Click on the link in your JS console to go to the notes page' );
|
66
69
|
console.log( '3. Advance through your slides and your notes will advance automatically' );
|
@@ -8,6 +8,7 @@
|
|
8
8
|
<style>
|
9
9
|
body {
|
10
10
|
font-family: Helvetica;
|
11
|
+
font-size: 18px;
|
11
12
|
}
|
12
13
|
|
13
14
|
#current-slide,
|
@@ -30,15 +31,26 @@
|
|
30
31
|
position: absolute;
|
31
32
|
top: 10px;
|
32
33
|
left: 10px;
|
33
|
-
font-weight: bold;
|
34
|
-
font-size: 14px;
|
35
34
|
z-index: 2;
|
36
|
-
|
35
|
+
}
|
36
|
+
|
37
|
+
.overlay-element {
|
38
|
+
height: 34px;
|
39
|
+
line-height: 34px;
|
40
|
+
padding: 0 10px;
|
41
|
+
text-shadow: none;
|
42
|
+
background: rgba( 220, 220, 220, 0.8 );
|
43
|
+
color: #222;
|
44
|
+
font-size: 14px;
|
45
|
+
}
|
46
|
+
|
47
|
+
.overlay-element.interactive:hover {
|
48
|
+
background: rgba( 220, 220, 220, 1 );
|
37
49
|
}
|
38
50
|
|
39
51
|
#current-slide {
|
40
52
|
position: absolute;
|
41
|
-
width:
|
53
|
+
width: 60%;
|
42
54
|
height: 100%;
|
43
55
|
top: 0;
|
44
56
|
left: 0;
|
@@ -47,19 +59,20 @@
|
|
47
59
|
|
48
60
|
#upcoming-slide {
|
49
61
|
position: absolute;
|
50
|
-
width:
|
62
|
+
width: 40%;
|
51
63
|
height: 40%;
|
52
64
|
right: 0;
|
53
65
|
top: 0;
|
54
66
|
}
|
55
67
|
|
68
|
+
/* Speaker controls */
|
56
69
|
#speaker-controls {
|
57
70
|
position: absolute;
|
58
71
|
top: 40%;
|
59
72
|
right: 0;
|
60
|
-
width:
|
73
|
+
width: 40%;
|
61
74
|
height: 60%;
|
62
|
-
|
75
|
+
overflow: auto;
|
63
76
|
font-size: 18px;
|
64
77
|
}
|
65
78
|
|
@@ -124,26 +137,108 @@
|
|
124
137
|
font-size: 1.2em;
|
125
138
|
}
|
126
139
|
|
140
|
+
/* Layout selector */
|
141
|
+
#speaker-layout {
|
142
|
+
position: absolute;
|
143
|
+
top: 10px;
|
144
|
+
right: 10px;
|
145
|
+
color: #222;
|
146
|
+
z-index: 10;
|
147
|
+
}
|
148
|
+
#speaker-layout select {
|
149
|
+
position: absolute;
|
150
|
+
width: 100%;
|
151
|
+
height: 100%;
|
152
|
+
top: 0;
|
153
|
+
left: 0;
|
154
|
+
border: 0;
|
155
|
+
box-shadow: 0;
|
156
|
+
cursor: pointer;
|
157
|
+
opacity: 0;
|
158
|
+
|
159
|
+
font-size: 1em;
|
160
|
+
background-color: transparent;
|
161
|
+
|
162
|
+
-moz-appearance: none;
|
163
|
+
-webkit-appearance: none;
|
164
|
+
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
165
|
+
}
|
166
|
+
|
167
|
+
#speaker-layout select:focus {
|
168
|
+
outline: none;
|
169
|
+
box-shadow: none;
|
170
|
+
}
|
171
|
+
|
127
172
|
.clear {
|
128
173
|
clear: both;
|
129
174
|
}
|
130
175
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
176
|
+
/* Speaker layout: Wide */
|
177
|
+
body[data-speaker-layout="wide"] #current-slide,
|
178
|
+
body[data-speaker-layout="wide"] #upcoming-slide {
|
179
|
+
width: 50%;
|
180
|
+
height: 45%;
|
181
|
+
padding: 6px;
|
135
182
|
}
|
136
183
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
}
|
184
|
+
body[data-speaker-layout="wide"] #current-slide {
|
185
|
+
top: 0;
|
186
|
+
left: 0;
|
141
187
|
}
|
142
188
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
189
|
+
body[data-speaker-layout="wide"] #upcoming-slide {
|
190
|
+
top: 0;
|
191
|
+
left: 50%;
|
192
|
+
}
|
193
|
+
|
194
|
+
body[data-speaker-layout="wide"] #speaker-controls {
|
195
|
+
top: 45%;
|
196
|
+
left: 0;
|
197
|
+
width: 100%;
|
198
|
+
height: 50%;
|
199
|
+
font-size: 1.25em;
|
200
|
+
}
|
201
|
+
|
202
|
+
/* Speaker layout: Tall */
|
203
|
+
body[data-speaker-layout="tall"] #current-slide,
|
204
|
+
body[data-speaker-layout="tall"] #upcoming-slide {
|
205
|
+
width: 45%;
|
206
|
+
height: 50%;
|
207
|
+
padding: 6px;
|
208
|
+
}
|
209
|
+
|
210
|
+
body[data-speaker-layout="tall"] #current-slide {
|
211
|
+
top: 0;
|
212
|
+
left: 0;
|
213
|
+
}
|
214
|
+
|
215
|
+
body[data-speaker-layout="tall"] #upcoming-slide {
|
216
|
+
top: 50%;
|
217
|
+
left: 0;
|
218
|
+
}
|
219
|
+
|
220
|
+
body[data-speaker-layout="tall"] #speaker-controls {
|
221
|
+
padding-top: 40px;
|
222
|
+
top: 0;
|
223
|
+
left: 45%;
|
224
|
+
width: 55%;
|
225
|
+
height: 100%;
|
226
|
+
font-size: 1.25em;
|
227
|
+
}
|
228
|
+
|
229
|
+
/* Speaker layout: Notes only */
|
230
|
+
body[data-speaker-layout="notes-only"] #current-slide,
|
231
|
+
body[data-speaker-layout="notes-only"] #upcoming-slide {
|
232
|
+
display: none;
|
233
|
+
}
|
234
|
+
|
235
|
+
body[data-speaker-layout="notes-only"] #speaker-controls {
|
236
|
+
padding-top: 40px;
|
237
|
+
top: 0;
|
238
|
+
left: 0;
|
239
|
+
width: 100%;
|
240
|
+
height: 100%;
|
241
|
+
font-size: 1.25em;
|
147
242
|
}
|
148
243
|
|
149
244
|
</style>
|
@@ -152,7 +247,7 @@
|
|
152
247
|
<body>
|
153
248
|
|
154
249
|
<div id="current-slide"></div>
|
155
|
-
<div id="upcoming-slide"><span class="label">
|
250
|
+
<div id="upcoming-slide"><span class="overlay-element label">Upcoming</span></div>
|
156
251
|
<div id="speaker-controls">
|
157
252
|
<div class="speaker-controls-time">
|
158
253
|
<h4 class="label">Time <span class="reset-button">Click to Reset</span></h4>
|
@@ -170,6 +265,10 @@
|
|
170
265
|
<div class="value"></div>
|
171
266
|
</div>
|
172
267
|
</div>
|
268
|
+
<div id="speaker-layout" class="overlay-element interactive">
|
269
|
+
<span class="speaker-layout-label"></span>
|
270
|
+
<select class="speaker-layout-dropdown"></select>
|
271
|
+
</div>
|
173
272
|
|
174
273
|
<script src="/socket.io/socket.io.js"></script>
|
175
274
|
<script src="/plugin/markdown/marked.js"></script>
|
@@ -182,11 +281,20 @@
|
|
182
281
|
currentState,
|
183
282
|
currentSlide,
|
184
283
|
upcomingSlide,
|
284
|
+
layoutLabel,
|
285
|
+
layoutDropdown,
|
185
286
|
connected = false;
|
186
287
|
|
187
288
|
var socket = io.connect( window.location.origin ),
|
188
289
|
socketId = '{{socketId}}';
|
189
290
|
|
291
|
+
var SPEAKER_LAYOUTS = {
|
292
|
+
'default': 'Default',
|
293
|
+
'wide': 'Wide',
|
294
|
+
'tall': 'Tall',
|
295
|
+
'notes-only': 'Notes only'
|
296
|
+
};
|
297
|
+
|
190
298
|
socket.on( 'statechanged', function( data ) {
|
191
299
|
|
192
300
|
// ignore data from sockets that aren't ours
|
@@ -195,7 +303,6 @@
|
|
195
303
|
if( connected === false ) {
|
196
304
|
connected = true;
|
197
305
|
|
198
|
-
setupIframes( data );
|
199
306
|
setupKeyboard();
|
200
307
|
setupNotes();
|
201
308
|
setupTimer();
|
@@ -206,13 +313,28 @@
|
|
206
313
|
|
207
314
|
} );
|
208
315
|
|
316
|
+
setupLayout();
|
317
|
+
|
318
|
+
// Load our presentation iframes
|
319
|
+
setupIframes();
|
320
|
+
|
321
|
+
// Once the iframes have loaded, emit a signal saying there's
|
322
|
+
// a new subscriber which will trigger a 'statechanged'
|
323
|
+
// message to be sent back
|
209
324
|
window.addEventListener( 'message', function( event ) {
|
210
325
|
|
211
326
|
var data = JSON.parse( event.data );
|
212
327
|
|
213
328
|
if( data && data.namespace === 'reveal' ) {
|
214
329
|
if( /ready/.test( data.eventName ) ) {
|
215
|
-
socket.emit( '
|
330
|
+
socket.emit( 'new-subscriber', { socketId: socketId } );
|
331
|
+
}
|
332
|
+
}
|
333
|
+
|
334
|
+
// Messages sent by reveal.js inside of the current slide preview
|
335
|
+
if( data && data.namespace === 'reveal' ) {
|
336
|
+
if( /slidechanged|fragmentshown|fragmenthidden|overviewshown|overviewhidden|paused|resumed/.test( data.eventName ) && currentState !== JSON.stringify( data.state ) ) {
|
337
|
+
socket.emit( 'statechanged-speaker', { state: data.state } );
|
216
338
|
}
|
217
339
|
}
|
218
340
|
|
@@ -267,7 +389,7 @@
|
|
267
389
|
/**
|
268
390
|
* Creates the preview iframes.
|
269
391
|
*/
|
270
|
-
function setupIframes(
|
392
|
+
function setupIframes() {
|
271
393
|
|
272
394
|
var params = [
|
273
395
|
'receiver',
|
@@ -277,9 +399,8 @@
|
|
277
399
|
'backgroundTransition=none'
|
278
400
|
].join( '&' );
|
279
401
|
|
280
|
-
var
|
281
|
-
var
|
282
|
-
var upcomingURL = '/?' + params + '&controls=false' + hash;
|
402
|
+
var currentURL = '/?' + params + '&postMessageEvents=true';
|
403
|
+
var upcomingURL = '/?' + params + '&controls=false';
|
283
404
|
|
284
405
|
currentSlide = document.createElement( 'iframe' );
|
285
406
|
currentSlide.setAttribute( 'width', 1280 );
|
@@ -351,6 +472,74 @@
|
|
351
472
|
|
352
473
|
}
|
353
474
|
|
475
|
+
/**
|
476
|
+
* Sets up the speaker view layout and layout selector.
|
477
|
+
*/
|
478
|
+
function setupLayout() {
|
479
|
+
|
480
|
+
layoutDropdown = document.querySelector( '.speaker-layout-dropdown' );
|
481
|
+
layoutLabel = document.querySelector( '.speaker-layout-label' );
|
482
|
+
|
483
|
+
// Render the list of available layouts
|
484
|
+
for( var id in SPEAKER_LAYOUTS ) {
|
485
|
+
var option = document.createElement( 'option' );
|
486
|
+
option.setAttribute( 'value', id );
|
487
|
+
option.textContent = SPEAKER_LAYOUTS[ id ];
|
488
|
+
layoutDropdown.appendChild( option );
|
489
|
+
}
|
490
|
+
|
491
|
+
// Monitor the dropdown for changes
|
492
|
+
layoutDropdown.addEventListener( 'change', function( event ) {
|
493
|
+
|
494
|
+
setLayout( layoutDropdown.value );
|
495
|
+
|
496
|
+
}, false );
|
497
|
+
|
498
|
+
// Restore any currently persisted layout
|
499
|
+
setLayout( getLayout() );
|
500
|
+
|
501
|
+
}
|
502
|
+
|
503
|
+
/**
|
504
|
+
* Sets a new speaker view layout. The layout is persisted
|
505
|
+
* in local storage.
|
506
|
+
*/
|
507
|
+
function setLayout( value ) {
|
508
|
+
|
509
|
+
var title = SPEAKER_LAYOUTS[ value ];
|
510
|
+
|
511
|
+
layoutLabel.innerHTML = 'Layout' + ( title ? ( ': ' + title ) : '' );
|
512
|
+
layoutDropdown.value = value;
|
513
|
+
|
514
|
+
document.body.setAttribute( 'data-speaker-layout', value );
|
515
|
+
|
516
|
+
// Persist locally
|
517
|
+
if( window.localStorage ) {
|
518
|
+
window.localStorage.setItem( 'reveal-speaker-layout', value );
|
519
|
+
}
|
520
|
+
|
521
|
+
}
|
522
|
+
|
523
|
+
/**
|
524
|
+
* Returns the ID of the most recently set speaker layout
|
525
|
+
* or our default layout if none has been set.
|
526
|
+
*/
|
527
|
+
function getLayout() {
|
528
|
+
|
529
|
+
if( window.localStorage ) {
|
530
|
+
var layout = window.localStorage.getItem( 'reveal-speaker-layout' );
|
531
|
+
if( layout ) {
|
532
|
+
return layout;
|
533
|
+
}
|
534
|
+
}
|
535
|
+
|
536
|
+
// Default to the first record in the layouts hash
|
537
|
+
for( var id in SPEAKER_LAYOUTS ) {
|
538
|
+
return id;
|
539
|
+
}
|
540
|
+
|
541
|
+
}
|
542
|
+
|
354
543
|
function zeroPadInteger( num ) {
|
355
544
|
|
356
545
|
var str = '00' + parseInt( num );
|
@@ -2,32 +2,18 @@
|
|
2
2
|
* phantomjs script for printing presentations to PDF.
|
3
3
|
*
|
4
4
|
* Example:
|
5
|
-
* phantomjs print-pdf.js "http://
|
5
|
+
* phantomjs print-pdf.js "http://revealjs.com?print-pdf" reveal-demo.pdf
|
6
6
|
*
|
7
|
-
*
|
7
|
+
* @author Manuel Bieh (https://github.com/manuelbieh)
|
8
|
+
* @author Hakim El Hattab (https://github.com/hakimel)
|
9
|
+
* @author Manuel Riezebosch (https://github.com/riezebosch)
|
8
10
|
*/
|
9
11
|
|
10
12
|
// html2pdf.js
|
11
|
-
var page = new WebPage();
|
12
13
|
var system = require( 'system' );
|
13
14
|
|
14
|
-
var
|
15
|
-
var
|
16
|
-
|
17
|
-
page.viewportSize = {
|
18
|
-
width: slideWidth,
|
19
|
-
height: slideHeight
|
20
|
-
};
|
21
|
-
|
22
|
-
// TODO
|
23
|
-
// Something is wrong with these config values. An input
|
24
|
-
// paper width of 1920px actually results in a 756px wide
|
25
|
-
// PDF.
|
26
|
-
page.paperSize = {
|
27
|
-
width: Math.round( slideWidth * 2 ),
|
28
|
-
height: Math.round( slideHeight * 2 ),
|
29
|
-
border: 0
|
30
|
-
};
|
15
|
+
var probePage = new WebPage();
|
16
|
+
var printPage = new WebPage();
|
31
17
|
|
32
18
|
var inputFile = system.args[1] || 'index.html?print-pdf';
|
33
19
|
var outputFile = system.args[2] || 'slides.pdf';
|
@@ -36,13 +22,48 @@ if( outputFile.match( /\.pdf$/gi ) === null ) {
|
|
36
22
|
outputFile += '.pdf';
|
37
23
|
}
|
38
24
|
|
39
|
-
console.log( '
|
25
|
+
console.log( 'Export PDF: Reading reveal.js config [1/4]' );
|
26
|
+
|
27
|
+
probePage.open( inputFile, function( status ) {
|
28
|
+
|
29
|
+
console.log( 'Export PDF: Preparing print layout [2/4]' );
|
30
|
+
|
31
|
+
var config = probePage.evaluate( function() {
|
32
|
+
return Reveal.getConfig();
|
33
|
+
} );
|
34
|
+
|
35
|
+
if( config ) {
|
40
36
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
37
|
+
printPage.paperSize = {
|
38
|
+
width: Math.floor( config.width * ( 1 + config.margin ) ),
|
39
|
+
height: Math.floor( config.height * ( 1 + config.margin ) ),
|
40
|
+
border: 0
|
41
|
+
};
|
42
|
+
|
43
|
+
printPage.open( inputFile, function( status ) {
|
44
|
+
console.log( 'Export PDF: Preparing pdf [3/4]')
|
45
|
+
printPage.evaluate(function() {
|
46
|
+
Reveal.isReady() ? window.callPhantom() : Reveal.addEventListener( 'pdf-ready', window.callPhantom );
|
47
|
+
});
|
48
|
+
} );
|
49
|
+
|
50
|
+
printPage.onCallback = function(data) {
|
51
|
+
// For some reason we need to "jump the queue" for syntax highlighting to work.
|
52
|
+
// See: http://stackoverflow.com/a/3580132/129269
|
53
|
+
setTimeout(function() {
|
54
|
+
console.log( 'Export PDF: Writing file [4/4]' );
|
55
|
+
printPage.render( outputFile );
|
56
|
+
console.log( 'Export PDF: Finished successfully!' );
|
57
|
+
phantom.exit();
|
58
|
+
}, 0);
|
59
|
+
};
|
60
|
+
}
|
61
|
+
else {
|
62
|
+
|
63
|
+
console.log( 'Export PDF: Unable to read reveal.js config. Make sure the input address points to a reveal.js page.' );
|
64
|
+
phantom.exit(1);
|
65
|
+
|
66
|
+
}
|
47
67
|
} );
|
48
68
|
|
69
|
+
|
@@ -21,7 +21,7 @@ function Hilitor(id, tag)
|
|
21
21
|
|
22
22
|
var targetNode = document.getElementById(id) || document.body;
|
23
23
|
var hiliteTag = tag || "EM";
|
24
|
-
var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM
|
24
|
+
var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$");
|
25
25
|
var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
|
26
26
|
var wordColor = [];
|
27
27
|
var colorIdx = 0;
|
@@ -53,11 +53,11 @@ function Hilitor(id, tag)
|
|
53
53
|
if(node.nodeType == 3) { // NODE_TEXT
|
54
54
|
if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
|
55
55
|
//find the slide's section element and save it in our list of matching slides
|
56
|
-
var secnode = node
|
57
|
-
while (secnode.nodeName != 'SECTION') {
|
56
|
+
var secnode = node;
|
57
|
+
while (secnode != null && secnode.nodeName != 'SECTION') {
|
58
58
|
secnode = secnode.parentNode;
|
59
59
|
}
|
60
|
-
|
60
|
+
|
61
61
|
var slideIndex = Reveal.getIndices(secnode);
|
62
62
|
var slidelen = matchingSlides.length;
|
63
63
|
var alreadyAdded = false;
|
@@ -69,7 +69,7 @@ function Hilitor(id, tag)
|
|
69
69
|
if (! alreadyAdded) {
|
70
70
|
matchingSlides.push(slideIndex);
|
71
71
|
}
|
72
|
-
|
72
|
+
|
73
73
|
if(!wordColor[regs[0].toLowerCase()]) {
|
74
74
|
wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
|
75
75
|
}
|
@@ -110,20 +110,26 @@ function Hilitor(id, tag)
|
|
110
110
|
|
111
111
|
function openSearch() {
|
112
112
|
//ensure the search term input dialog is visible and has focus:
|
113
|
+
var inputboxdiv = document.getElementById("searchinputdiv");
|
113
114
|
var inputbox = document.getElementById("searchinput");
|
114
|
-
|
115
|
+
inputboxdiv.style.display = "inline";
|
115
116
|
inputbox.focus();
|
116
117
|
inputbox.select();
|
117
118
|
}
|
118
119
|
|
120
|
+
function closeSearch() {
|
121
|
+
var inputboxdiv = document.getElementById("searchinputdiv");
|
122
|
+
inputboxdiv.style.display = "none";
|
123
|
+
if(myHilitor) myHilitor.remove();
|
124
|
+
}
|
125
|
+
|
119
126
|
function toggleSearch() {
|
120
|
-
var
|
121
|
-
if (
|
127
|
+
var inputboxdiv = document.getElementById("searchinputdiv");
|
128
|
+
if (inputboxdiv.style.display !== "inline") {
|
122
129
|
openSearch();
|
123
130
|
}
|
124
131
|
else {
|
125
|
-
|
126
|
-
myHilitor.remove();
|
132
|
+
closeSearch();
|
127
133
|
}
|
128
134
|
}
|
129
135
|
|
@@ -132,19 +138,27 @@ function Hilitor(id, tag)
|
|
132
138
|
if (searchboxDirty) {
|
133
139
|
var searchstring = document.getElementById("searchinput").value;
|
134
140
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
141
|
+
if (searchstring === '') {
|
142
|
+
if(myHilitor) myHilitor.remove();
|
143
|
+
matchedSlides = null;
|
144
|
+
}
|
145
|
+
else {
|
146
|
+
//find the keyword amongst the slides
|
147
|
+
myHilitor = new Hilitor("slidecontent");
|
148
|
+
matchedSlides = myHilitor.apply(searchstring);
|
149
|
+
currentMatchedIndex = 0;
|
150
|
+
}
|
139
151
|
}
|
140
152
|
|
141
|
-
|
142
|
-
|
143
|
-
currentMatchedIndex
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
153
|
+
if (matchedSlides) {
|
154
|
+
//navigate to the next slide that has the keyword, wrapping to the first if necessary
|
155
|
+
if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
|
156
|
+
currentMatchedIndex = 0;
|
157
|
+
}
|
158
|
+
if (matchedSlides.length > currentMatchedIndex) {
|
159
|
+
Reveal.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
|
160
|
+
currentMatchedIndex++;
|
161
|
+
}
|
148
162
|
}
|
149
163
|
}
|
150
164
|
|
@@ -157,7 +171,8 @@ function Hilitor(id, tag)
|
|
157
171
|
searchElement.classList.add( 'searchdiv' );
|
158
172
|
searchElement.style.position = 'absolute';
|
159
173
|
searchElement.style.top = '10px';
|
160
|
-
searchElement.style.
|
174
|
+
searchElement.style.right = '10px';
|
175
|
+
searchElement.style.zIndex = 10;
|
161
176
|
//embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
|
162
177
|
searchElement.innerHTML = '<span><input type="search" id="searchinput" class="searchinput" style="vertical-align: top;"/><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJiSURBVHjatFZNaxNBGH5md+Mmu92NVdKDRipSAyqCghgQD4L4cRe86UUtAQ+eFCxoa4/25EXBFi8eBE+eRPoDhB6KgiiixdAPCEkx2pjvTXadd9yNsflwuyUDD/O+u8PzzDPvzOwyx3EwyCZhwG3gAkp7MnpjgbopjsltcD4gjuXZZKeAR348MYLYTm3LzOs/y3j3JTfZxgXWXmTuwPHIc4VmoOmv5IrI53+AO2DdHLjkDWQ3GoEEVFXtXQOvkSnPWcyUceviLhwbDYv8/XIVj97kse7TodLvZXxYxrPUHkQ1ufXs3FEdybEIxucySOesoNvUgWU1cP3MkCBfTFdw9fGaAMVmRELq7LBw2Q3/FaAxxWIRpw+ZIr/7IouPqzUBiqmdHAv7EuhRAwf1er2Vy4x1jW3b2d5Jfvu5IPp7l2LYbcgCFFNb+FoJ7oBqEAqFMPNqFcmEgVMJDfMT+1tvN0pNjERlMS6QA5pFOKxiKVPFhakPeL3It+WGJUDxt2wFR+JhzI7v5ctkd8DXOZAkCYYxhO+lKm4+Xfqz/rIixBuNBl7eOYzkQQNzqX249mRl6zUgEcYkaJrGhUwBinVdh6IouPzwE6/DL5w4oLkH8y981aDf+uq6hlKpJESiUdNfDZi7/ehG9K6KfiA3pml0PLcsq+cSMTj2NL9ukc4UOmz7AZ3+crkC4mHujFvXNaMFB3bEr8xPS6p5O+jXxq4VZtaen7/PwzrntjcLUE0iHPS1Ud1cdiEJl/8WivZk0wXd7zWOMkeF8s0CcAmkNrC2nvXZDbbbN73ccYnZoH9bfgswAFzAe9/h3dbKAAAAAElFTkSuQmCC" id="searchbutton" class="searchicon" style="vertical-align: top; margin-top: -1px;"/></span>';
|
163
178
|
dom.wrapper.appendChild( searchElement );
|
@@ -179,18 +194,13 @@ function Hilitor(id, tag)
|
|
179
194
|
}
|
180
195
|
}, false );
|
181
196
|
|
182
|
-
// Open the search when the 's' key is hit (yes, this conflicts with the notes plugin, disabling for now)
|
183
|
-
/*
|
184
197
|
document.addEventListener( 'keydown', function( event ) {
|
185
|
-
|
186
|
-
// modifier is present
|
187
|
-
if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
|
188
|
-
|
189
|
-
if( event.keyCode === 83 ) {
|
198
|
+
if( event.key == "F" && (event.ctrlKey || event.metaKey) ) {//Control+Shift+f
|
190
199
|
event.preventDefault();
|
191
|
-
|
200
|
+
toggleSearch();
|
192
201
|
}
|
193
202
|
}, false );
|
194
|
-
|
203
|
+
if( window.Reveal ) Reveal.registerKeyboardShortcut( 'Ctrl-Shift-F', 'Search' );
|
204
|
+
closeSearch();
|
195
205
|
return { open: openSearch };
|
196
206
|
})();
|