reveal-ck 3.6.0 → 3.7.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/files/reveal.js/CONTRIBUTING.md +4 -0
- data/files/reveal.js/Gruntfile.js +44 -26
- data/files/reveal.js/LICENSE +1 -1
- data/files/reveal.js/README.md +375 -161
- data/files/reveal.js/bower.json +27 -0
- data/files/reveal.js/css/print/paper.css +4 -3
- data/files/reveal.js/css/print/pdf.css +53 -38
- data/files/reveal.js/css/reveal.css +452 -206
- data/files/reveal.js/css/reveal.scss +328 -175
- data/files/reveal.js/css/theme/README.md +2 -6
- data/files/reveal.js/css/theme/beige.css +81 -50
- data/files/reveal.js/css/theme/black.css +70 -39
- data/files/reveal.js/css/theme/blood.css +81 -57
- data/files/reveal.js/css/theme/league.css +75 -44
- data/files/reveal.js/css/theme/moon.css +75 -44
- data/files/reveal.js/css/theme/night.css +70 -39
- data/files/reveal.js/css/theme/serif.css +72 -41
- data/files/reveal.js/css/theme/simple.css +72 -38
- data/files/reveal.js/css/theme/sky.css +75 -44
- data/files/reveal.js/css/theme/solarized.css +75 -44
- data/files/reveal.js/css/theme/source/black.scss +2 -2
- data/files/reveal.js/css/theme/source/blood.scss +3 -16
- data/files/reveal.js/css/theme/source/night.scss +0 -1
- data/files/reveal.js/css/theme/source/simple.scss +5 -0
- data/files/reveal.js/css/theme/source/white.scss +2 -2
- data/files/reveal.js/css/theme/template/settings.scss +1 -1
- data/files/reveal.js/css/theme/template/theme.scss +36 -23
- data/files/reveal.js/css/theme/white.css +75 -44
- data/files/reveal.js/demo.html +410 -0
- data/files/reveal.js/index.html +14 -373
- data/files/reveal.js/js/reveal.js +1186 -350
- data/files/reveal.js/lib/css/zenburn.css +41 -78
- data/files/reveal.js/lib/js/head.min.js +9 -8
- data/files/reveal.js/package.json +22 -26
- data/files/reveal.js/plugin/highlight/highlight.js +52 -4
- data/files/reveal.js/plugin/markdown/example.html +1 -1
- data/files/reveal.js/plugin/markdown/markdown.js +40 -21
- data/files/reveal.js/plugin/markdown/marked.js +2 -33
- data/files/reveal.js/plugin/math/math.js +5 -2
- data/files/reveal.js/plugin/multiplex/client.js +1 -1
- data/files/reveal.js/plugin/multiplex/index.js +24 -16
- data/files/reveal.js/plugin/multiplex/master.js +22 -42
- data/files/reveal.js/plugin/multiplex/package.json +19 -0
- data/files/reveal.js/plugin/notes-server/client.js +6 -1
- data/files/reveal.js/plugin/notes-server/index.js +17 -14
- data/files/reveal.js/plugin/notes-server/notes.html +215 -26
- data/files/reveal.js/plugin/notes/notes.html +372 -32
- data/files/reveal.js/plugin/notes/notes.js +40 -7
- data/files/reveal.js/plugin/print-pdf/print-pdf.js +47 -26
- data/files/reveal.js/plugin/zoom-js/zoom.js +12 -2
- data/files/reveal.js/test/examples/math.html +1 -1
- data/files/reveal.js/test/examples/slide-backgrounds.html +1 -1
- data/files/reveal.js/test/examples/slide-transitions.html +101 -0
- data/files/reveal.js/test/simple.md +12 -0
- data/files/reveal.js/test/test-markdown-element-attributes.html +3 -3
- data/files/reveal.js/test/test-markdown-element-attributes.js +1 -1
- data/files/reveal.js/test/test-markdown-external.html +36 -0
- data/files/reveal.js/test/test-markdown-external.js +24 -0
- data/files/reveal.js/test/test-markdown-options.html +41 -0
- data/files/reveal.js/test/test-markdown-options.js +26 -0
- data/files/reveal.js/test/test-markdown.html +1 -1
- data/files/reveal.js/test/test.html +5 -1
- data/files/reveal.js/test/test.js +26 -1
- data/lib/reveal-ck/version.rb +1 -1
- metadata +11 -4
- data/files/reveal.js/plugin/leap/leap.js +0 -159
- data/files/reveal.js/plugin/remotes/remotes.js +0 -39
@@ -7,14 +7,17 @@
|
|
7
7
|
var RevealMath = window.RevealMath || (function(){
|
8
8
|
|
9
9
|
var options = Reveal.getConfig().math || {};
|
10
|
-
options.mathjax = options.mathjax || '
|
10
|
+
options.mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
|
11
11
|
options.config = options.config || 'TeX-AMS_HTML-full';
|
12
12
|
|
13
13
|
loadScript( options.mathjax + '?config=' + options.config, function() {
|
14
14
|
|
15
15
|
MathJax.Hub.Config({
|
16
16
|
messageStyle: 'none',
|
17
|
-
tex2jax: {
|
17
|
+
tex2jax: {
|
18
|
+
inlineMath: [['$','$'],['\\(','\\)']] ,
|
19
|
+
skipTags: ['script','noscript','style','textarea','pre']
|
20
|
+
},
|
18
21
|
skipStartupTypeset: true
|
19
22
|
});
|
20
23
|
|
@@ -1,37 +1,45 @@
|
|
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
5
|
var crypto = require('crypto');
|
5
6
|
|
6
|
-
var app
|
7
|
-
var staticDir
|
7
|
+
var app = express();
|
8
|
+
var staticDir = express.static;
|
9
|
+
var server = http.createServer(app);
|
8
10
|
|
9
|
-
io
|
11
|
+
io = io(server);
|
10
12
|
|
11
13
|
var opts = {
|
12
|
-
port: 1948,
|
14
|
+
port: process.env.PORT || 1948,
|
13
15
|
baseDir : __dirname + '/../../'
|
14
16
|
};
|
15
17
|
|
16
|
-
io.
|
17
|
-
socket.on('
|
18
|
-
if (typeof
|
19
|
-
if (createHash(
|
20
|
-
|
21
|
-
socket.broadcast.emit(
|
18
|
+
io.on( 'connection', function( socket ) {
|
19
|
+
socket.on('multiplex-statechanged', function(data) {
|
20
|
+
if (typeof data.secret == 'undefined' || data.secret == null || data.secret === '') return;
|
21
|
+
if (createHash(data.secret) === data.socketId) {
|
22
|
+
data.secret = null;
|
23
|
+
socket.broadcast.emit(data.socketId, data);
|
22
24
|
};
|
23
25
|
});
|
24
26
|
});
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
app.use('/' + dir, staticDir(opts.baseDir + dir));
|
29
|
-
});
|
28
|
+
[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
|
29
|
+
app.use('/' + dir, staticDir(opts.baseDir + dir));
|
30
30
|
});
|
31
31
|
|
32
32
|
app.get("/", function(req, res) {
|
33
33
|
res.writeHead(200, {'Content-Type': 'text/html'});
|
34
|
-
|
34
|
+
|
35
|
+
var stream = fs.createReadStream(opts.baseDir + '/index.html');
|
36
|
+
stream.on('error', function( error ) {
|
37
|
+
res.write('<style>body{font-family: sans-serif;}</style><h2>reveal.js multiplex server.</h2><a href="/token">Generate token</a>');
|
38
|
+
res.end();
|
39
|
+
});
|
40
|
+
stream.on('readable', function() {
|
41
|
+
stream.pipe(res);
|
42
|
+
});
|
35
43
|
});
|
36
44
|
|
37
45
|
app.get("/token", function(req,res) {
|
@@ -47,7 +55,7 @@ var createHash = function(secret) {
|
|
47
55
|
};
|
48
56
|
|
49
57
|
// Actually listen
|
50
|
-
|
58
|
+
server.listen( opts.port || null );
|
51
59
|
|
52
60
|
var brown = '\033[33m',
|
53
61
|
green = '\033[32m',
|
@@ -1,51 +1,31 @@
|
|
1
1
|
(function() {
|
2
|
+
|
2
3
|
// Don't emit events from inside of notes windows
|
3
4
|
if ( window.location.search.match( /receiver/gi ) ) { return; }
|
4
5
|
|
5
6
|
var multiplex = Reveal.getConfig().multiplex;
|
6
7
|
|
7
|
-
var socket = io.connect(multiplex.url);
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
|
20
|
-
nextindexh = indexh;
|
21
|
-
nextindexv = indexv + 1;
|
22
|
-
} else {
|
23
|
-
nextindexh = indexh + 1;
|
24
|
-
nextindexv = 0;
|
25
|
-
}
|
26
|
-
|
27
|
-
var slideData = {
|
28
|
-
indexh : indexh,
|
29
|
-
indexv : indexv,
|
30
|
-
indexf : fragmentindex,
|
31
|
-
nextindexh : nextindexh,
|
32
|
-
nextindexv : nextindexv,
|
33
|
-
secret: multiplex.secret,
|
34
|
-
socketId : multiplex.id
|
35
|
-
};
|
36
|
-
|
37
|
-
socket.emit('slidechanged', slideData);
|
38
|
-
}
|
39
|
-
}
|
40
|
-
|
41
|
-
Reveal.addEventListener( 'slidechanged', function( event ) {
|
42
|
-
notify( event.currentSlide, event.indexh, event.indexv, event.origin );
|
43
|
-
} );
|
44
|
-
|
45
|
-
var fragmentNotify = function( event ) {
|
46
|
-
notify( Reveal.getCurrentSlide(), Reveal.getIndices().h, Reveal.getIndices().v, event.origin );
|
8
|
+
var socket = io.connect( multiplex.url );
|
9
|
+
|
10
|
+
function post() {
|
11
|
+
|
12
|
+
var messageData = {
|
13
|
+
state: Reveal.getState(),
|
14
|
+
secret: multiplex.secret,
|
15
|
+
socketId: multiplex.id
|
16
|
+
};
|
17
|
+
|
18
|
+
socket.emit( 'multiplex-statechanged', messageData );
|
19
|
+
|
47
20
|
};
|
48
21
|
|
49
|
-
|
50
|
-
Reveal.addEventListener( '
|
22
|
+
// Monitor events that trigger a change in state
|
23
|
+
Reveal.addEventListener( 'slidechanged', post );
|
24
|
+
Reveal.addEventListener( 'fragmentshown', post );
|
25
|
+
Reveal.addEventListener( 'fragmenthidden', post );
|
26
|
+
Reveal.addEventListener( 'overviewhidden', post );
|
27
|
+
Reveal.addEventListener( 'overviewshown', post );
|
28
|
+
Reveal.addEventListener( 'paused', post );
|
29
|
+
Reveal.addEventListener( 'resumed', post );
|
30
|
+
|
51
31
|
}());
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"name": "reveal-js-multiplex",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "reveal.js multiplex server",
|
5
|
+
"homepage": "http://lab.hakim.se/reveal-js",
|
6
|
+
"scripts": {
|
7
|
+
"start": "node index.js"
|
8
|
+
},
|
9
|
+
"engines": {
|
10
|
+
"node": "~4.1.1"
|
11
|
+
},
|
12
|
+
"dependencies": {
|
13
|
+
"express": "~4.13.3",
|
14
|
+
"grunt-cli": "~0.1.13",
|
15
|
+
"mustache": "~2.2.1",
|
16
|
+
"socket.io": "~1.3.7"
|
17
|
+
},
|
18
|
+
"license": "MIT"
|
19
|
+
}
|
@@ -41,10 +41,15 @@
|
|
41
41
|
}
|
42
42
|
|
43
43
|
// When a new notes window connects, post our current state
|
44
|
-
socket.on( '
|
44
|
+
socket.on( 'new-subscriber', function( data ) {
|
45
45
|
post();
|
46
46
|
} );
|
47
47
|
|
48
|
+
// When the state changes from inside of the speaker view
|
49
|
+
socket.on( 'statechanged-speaker', function( data ) {
|
50
|
+
Reveal.setState( data.state );
|
51
|
+
} );
|
52
|
+
|
48
53
|
// Monitor events that trigger a change in state
|
49
54
|
Reveal.addEventListener( 'slidechanged', post );
|
50
55
|
Reveal.addEventListener( 'fragmentshown', post );
|
@@ -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 );
|