slide_hero 0.0.8 → 0.0.9
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/.ruby-version +1 -1
- data/README.md +1 -1
- data/lib/slide_hero/version.rb +1 -1
- data/lib/slide_hero/views/layout.html.erb +2 -2
- data/vendor/reveal.js/.gitignore +3 -1
- data/vendor/reveal.js/.travis.yml +1 -1
- data/vendor/reveal.js/CONTRIBUTING.md +19 -0
- data/vendor/reveal.js/Gruntfile.js +58 -21
- data/vendor/reveal.js/LICENSE +1 -1
- data/vendor/reveal.js/README.md +154 -74
- data/vendor/reveal.js/css/print/paper.css +193 -167
- data/vendor/reveal.js/css/print/pdf.css +20 -53
- data/vendor/reveal.js/css/reveal.css +912 -1651
- data/vendor/reveal.js/css/reveal.scss +1316 -0
- data/vendor/reveal.js/css/theme/README.md +1 -1
- data/vendor/reveal.js/css/theme/beige.css +177 -60
- data/vendor/reveal.js/css/theme/black.css +261 -0
- data/vendor/reveal.js/css/theme/blood.css +191 -75
- data/vendor/reveal.js/css/theme/league.css +267 -0
- data/vendor/reveal.js/css/theme/moon.css +168 -51
- data/vendor/reveal.js/css/theme/night.css +165 -42
- data/vendor/reveal.js/css/theme/serif.css +181 -58
- data/vendor/reveal.js/css/theme/simple.css +173 -50
- data/vendor/reveal.js/css/theme/sky.css +170 -47
- data/vendor/reveal.js/css/theme/solarized.css +168 -51
- data/vendor/reveal.js/css/theme/source/beige.scss +1 -12
- data/vendor/reveal.js/css/theme/source/black.scss +49 -0
- data/vendor/reveal.js/css/theme/source/blood.scss +4 -4
- data/vendor/reveal.js/css/theme/source/{default.scss → league.scss} +5 -13
- data/vendor/reveal.js/css/theme/source/moon.scss +1 -12
- data/vendor/reveal.js/css/theme/source/serif.scss +1 -1
- data/vendor/reveal.js/css/theme/source/sky.scss +1 -1
- data/vendor/reveal.js/css/theme/source/solarized.scss +1 -12
- data/vendor/reveal.js/css/theme/source/white.scss +49 -0
- data/vendor/reveal.js/css/theme/template/settings.scss +13 -4
- data/vendor/reveal.js/css/theme/template/theme.scss +182 -13
- data/vendor/reveal.js/css/theme/white.css +261 -0
- data/vendor/reveal.js/index.html +198 -178
- data/vendor/reveal.js/js/reveal.js +1286 -392
- data/vendor/reveal.js/lib/css/zenburn.css +74 -71
- data/vendor/reveal.js/lib/font/{league_gothic_license → league-gothic/LICENSE} +0 -0
- data/vendor/reveal.js/lib/font/league-gothic/league-gothic.css +10 -0
- data/vendor/reveal.js/lib/font/league-gothic/league-gothic.eot +0 -0
- data/vendor/reveal.js/lib/font/league-gothic/league-gothic.ttf +0 -0
- data/vendor/reveal.js/lib/font/league-gothic/league-gothic.woff +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/LICENSE +45 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.eot +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.ttf +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-italic.woff +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.eot +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.ttf +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-regular.woff +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.eot +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.ttf +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibold.woff +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.eot +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.ttf +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro-semibolditalic.woff +0 -0
- data/vendor/reveal.js/lib/font/source-sans-pro/source-sans-pro.css +39 -0
- data/vendor/reveal.js/package.json +9 -7
- data/vendor/reveal.js/plugin/highlight/highlight.js +2 -4
- data/vendor/reveal.js/plugin/leap/leap.js +4 -2
- data/vendor/reveal.js/plugin/markdown/example.html +2 -2
- data/vendor/reveal.js/plugin/markdown/markdown.js +8 -7
- data/vendor/reveal.js/plugin/notes/notes.html +321 -182
- data/vendor/reveal.js/plugin/notes/notes.js +89 -45
- data/vendor/reveal.js/plugin/notes-server/client.js +49 -46
- data/vendor/reveal.js/plugin/notes-server/index.js +28 -21
- data/vendor/reveal.js/plugin/notes-server/notes.html +351 -97
- data/vendor/reveal.js/plugin/print-pdf/print-pdf.js +24 -20
- data/vendor/reveal.js/plugin/zoom-js/zoom.js +77 -57
- data/vendor/reveal.js/test/examples/barebones.html +2 -2
- data/vendor/reveal.js/test/examples/embedded-media.html +2 -2
- data/vendor/reveal.js/test/examples/math.html +2 -2
- data/vendor/reveal.js/test/examples/slide-backgrounds.html +29 -7
- data/vendor/reveal.js/test/test-markdown-element-attributes.html +6 -6
- data/vendor/reveal.js/test/test-markdown-slide-attributes.html +7 -7
- data/vendor/reveal.js/test/test-markdown.html +4 -4
- data/vendor/reveal.js/test/test-pdf.html +83 -0
- data/vendor/reveal.js/test/test-pdf.js +15 -0
- data/vendor/reveal.js/test/test.html +5 -4
- data/vendor/reveal.js/test/test.js +143 -9
- metadata +31 -13
- data/vendor/reveal.js/css/reveal.min.css +0 -7
- data/vendor/reveal.js/css/theme/default.css +0 -148
- data/vendor/reveal.js/js/reveal.min.js +0 -9
- data/vendor/reveal.js/lib/font/league_gothic-webfont.eot +0 -0
- data/vendor/reveal.js/lib/font/league_gothic-webfont.svg +0 -230
- data/vendor/reveal.js/lib/font/league_gothic-webfont.ttf +0 -0
- data/vendor/reveal.js/lib/font/league_gothic-webfont.woff +0 -0
- data/vendor/reveal.js/plugin/postmessage/example.html +0 -39
- data/vendor/reveal.js/plugin/postmessage/postmessage.js +0 -42
|
@@ -3,16 +3,32 @@
|
|
|
3
3
|
* http://lab.hakim.se/reveal-js
|
|
4
4
|
* MIT licensed
|
|
5
5
|
*
|
|
6
|
-
* Copyright (C)
|
|
6
|
+
* Copyright (C) 2015 Hakim El Hattab, http://hakim.se
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
(function( root, factory ) {
|
|
9
|
+
if( typeof define === 'function' && define.amd ) {
|
|
10
|
+
// AMD. Register as an anonymous module.
|
|
11
|
+
define( function() {
|
|
12
|
+
root.Reveal = factory();
|
|
13
|
+
return root.Reveal;
|
|
14
|
+
} );
|
|
15
|
+
} else if( typeof exports === 'object' ) {
|
|
16
|
+
// Node. Does not work with strict CommonJS.
|
|
17
|
+
module.exports = factory();
|
|
18
|
+
} else {
|
|
19
|
+
// Browser globals.
|
|
20
|
+
root.Reveal = factory();
|
|
21
|
+
}
|
|
22
|
+
}( this, function() {
|
|
9
23
|
|
|
10
24
|
'use strict';
|
|
11
25
|
|
|
12
|
-
var
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
26
|
+
var Reveal;
|
|
27
|
+
|
|
28
|
+
var SLIDES_SELECTOR = '.slides section',
|
|
29
|
+
HORIZONTAL_SLIDES_SELECTOR = '.slides>section',
|
|
30
|
+
VERTICAL_SLIDES_SELECTOR = '.slides>section.present>section',
|
|
31
|
+
HOME_SLIDE_SELECTOR = '.slides>section:first-of-type',
|
|
16
32
|
|
|
17
33
|
// Configurations defaults, can be overridden at initialization time
|
|
18
34
|
config = {
|
|
@@ -27,7 +43,7 @@ var Reveal = (function(){
|
|
|
27
43
|
|
|
28
44
|
// Bounds for smallest/largest possible scale to apply to content
|
|
29
45
|
minScale: 0.2,
|
|
30
|
-
maxScale: 1.
|
|
46
|
+
maxScale: 1.5,
|
|
31
47
|
|
|
32
48
|
// Display controls in the bottom right corner
|
|
33
49
|
controls: true,
|
|
@@ -44,6 +60,9 @@ var Reveal = (function(){
|
|
|
44
60
|
// Enable keyboard shortcuts for navigation
|
|
45
61
|
keyboard: true,
|
|
46
62
|
|
|
63
|
+
// Optional function that blocks keyboard events when retuning false
|
|
64
|
+
keyboardCondition: null,
|
|
65
|
+
|
|
47
66
|
// Enable the slide overview mode
|
|
48
67
|
overview: true,
|
|
49
68
|
|
|
@@ -66,6 +85,13 @@ var Reveal = (function(){
|
|
|
66
85
|
// i.e. contained within a limited portion of the screen
|
|
67
86
|
embedded: false,
|
|
68
87
|
|
|
88
|
+
// Flags if we should show a help overlay when the questionmark
|
|
89
|
+
// key is pressed
|
|
90
|
+
help: true,
|
|
91
|
+
|
|
92
|
+
// Flags if it should be possible to pause the presentation (blackout)
|
|
93
|
+
pause: true,
|
|
94
|
+
|
|
69
95
|
// Number of milliseconds between automatically proceeding to the
|
|
70
96
|
// next slide, disabled when set to 0, this value can be overwritten
|
|
71
97
|
// by using a data-autoslide attribute on your slides
|
|
@@ -86,20 +112,23 @@ var Reveal = (function(){
|
|
|
86
112
|
// Opens links in an iframe preview overlay
|
|
87
113
|
previewLinks: false,
|
|
88
114
|
|
|
89
|
-
//
|
|
90
|
-
|
|
115
|
+
// Exposes the reveal.js API through window.postMessage
|
|
116
|
+
postMessage: true,
|
|
91
117
|
|
|
92
|
-
//
|
|
93
|
-
|
|
118
|
+
// Dispatches all reveal.js events to the parent window through postMessage
|
|
119
|
+
postMessageEvents: false,
|
|
120
|
+
|
|
121
|
+
// Focuses body when page changes visiblity to ensure keyboard shortcuts work
|
|
122
|
+
focusBodyOnPageVisibilityChange: true,
|
|
94
123
|
|
|
95
124
|
// Transition style
|
|
96
|
-
transition: '
|
|
125
|
+
transition: 'slide', // none/fade/slide/convex/concave/zoom
|
|
97
126
|
|
|
98
127
|
// Transition speed
|
|
99
128
|
transitionSpeed: 'default', // default/fast/slow
|
|
100
129
|
|
|
101
130
|
// Transition style for full page slide backgrounds
|
|
102
|
-
backgroundTransition: '
|
|
131
|
+
backgroundTransition: 'fade', // none/fade/slide/convex/concave/zoom
|
|
103
132
|
|
|
104
133
|
// Parallax background image
|
|
105
134
|
parallaxBackgroundImage: '', // CSS syntax, e.g. "a.jpg"
|
|
@@ -151,12 +180,6 @@ var Reveal = (function(){
|
|
|
151
180
|
// Delays updates to the URL due to a Chrome thumbnailer bug
|
|
152
181
|
writeURLTimeout = 0,
|
|
153
182
|
|
|
154
|
-
// A delay used to activate the overview mode
|
|
155
|
-
activateOverviewTimeout = 0,
|
|
156
|
-
|
|
157
|
-
// A delay used to deactivate the overview mode
|
|
158
|
-
deactivateOverviewTimeout = 0,
|
|
159
|
-
|
|
160
183
|
// Flags if the interaction event listeners are bound
|
|
161
184
|
eventsAreBound = false,
|
|
162
185
|
|
|
@@ -177,6 +200,21 @@ var Reveal = (function(){
|
|
|
177
200
|
startCount: 0,
|
|
178
201
|
captured: false,
|
|
179
202
|
threshold: 40
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
// Holds information about the keyboard shortcuts
|
|
206
|
+
keyboardShortcuts = {
|
|
207
|
+
'N , SPACE': 'Next slide',
|
|
208
|
+
'P': 'Previous slide',
|
|
209
|
+
'← , H': 'Navigate left',
|
|
210
|
+
'→ , L': 'Navigate right',
|
|
211
|
+
'↑ , K': 'Navigate up',
|
|
212
|
+
'↓ , J': 'Navigate down',
|
|
213
|
+
'Home': 'First slide',
|
|
214
|
+
'End': 'Last slide',
|
|
215
|
+
'B , .': 'Pause',
|
|
216
|
+
'F': 'Fullscreen',
|
|
217
|
+
'ESC, O': 'Slide overview'
|
|
180
218
|
};
|
|
181
219
|
|
|
182
220
|
/**
|
|
@@ -189,11 +227,26 @@ var Reveal = (function(){
|
|
|
189
227
|
if( !features.transforms2d && !features.transforms3d ) {
|
|
190
228
|
document.body.setAttribute( 'class', 'no-transforms' );
|
|
191
229
|
|
|
230
|
+
// Since JS won't be running any further, we need to load all
|
|
231
|
+
// images that were intended to lazy load now
|
|
232
|
+
var images = document.getElementsByTagName( 'img' );
|
|
233
|
+
for( var i = 0, len = images.length; i < len; i++ ) {
|
|
234
|
+
var image = images[i];
|
|
235
|
+
if( image.getAttribute( 'data-src' ) ) {
|
|
236
|
+
image.setAttribute( 'src', image.getAttribute( 'data-src' ) );
|
|
237
|
+
image.removeAttribute( 'data-src' );
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
192
241
|
// If the browser doesn't support core features we won't be
|
|
193
242
|
// using JavaScript to control the presentation
|
|
194
243
|
return;
|
|
195
244
|
}
|
|
196
245
|
|
|
246
|
+
// Cache references to key DOM elements
|
|
247
|
+
dom.wrapper = document.querySelector( '.reveal' );
|
|
248
|
+
dom.slides = document.querySelector( '.reveal .slides' );
|
|
249
|
+
|
|
197
250
|
// Force a layout when the whole page, incl fonts, has loaded
|
|
198
251
|
window.addEventListener( 'load', layout, false );
|
|
199
252
|
|
|
@@ -238,10 +291,11 @@ var Reveal = (function(){
|
|
|
238
291
|
|
|
239
292
|
features.canvas = !!document.createElement( 'canvas' ).getContext;
|
|
240
293
|
|
|
241
|
-
|
|
294
|
+
features.touch = !!( 'ontouchstart' in window );
|
|
242
295
|
|
|
243
|
-
|
|
296
|
+
isMobileDevice = navigator.userAgent.match( /(iphone|ipod|ipad|android)/gi );
|
|
244
297
|
|
|
298
|
+
}
|
|
245
299
|
|
|
246
300
|
/**
|
|
247
301
|
* Loads the dependencies of reveal.js. Dependencies are
|
|
@@ -316,6 +370,9 @@ var Reveal = (function(){
|
|
|
316
370
|
// Make sure we've got all the DOM elements we need
|
|
317
371
|
setupDOM();
|
|
318
372
|
|
|
373
|
+
// Listen to messages posted to this window
|
|
374
|
+
setupPostMessage();
|
|
375
|
+
|
|
319
376
|
// Resets all vertical slides so that only the first is visible
|
|
320
377
|
resetVerticalSlides();
|
|
321
378
|
|
|
@@ -343,6 +400,20 @@ var Reveal = (function(){
|
|
|
343
400
|
} );
|
|
344
401
|
}, 1 );
|
|
345
402
|
|
|
403
|
+
// Special setup and config is required when printing to PDF
|
|
404
|
+
if( isPrintingPDF() ) {
|
|
405
|
+
removeEventListeners();
|
|
406
|
+
|
|
407
|
+
// The document needs to have loaded for the PDF layout
|
|
408
|
+
// measurements to be accurate
|
|
409
|
+
if( document.readyState === 'complete' ) {
|
|
410
|
+
setupPDF();
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
window.addEventListener( 'load', setupPDF );
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
346
417
|
}
|
|
347
418
|
|
|
348
419
|
/**
|
|
@@ -352,11 +423,6 @@ var Reveal = (function(){
|
|
|
352
423
|
*/
|
|
353
424
|
function setupDOM() {
|
|
354
425
|
|
|
355
|
-
// Cache references to key DOM elements
|
|
356
|
-
dom.theme = document.querySelector( '#theme' );
|
|
357
|
-
dom.wrapper = document.querySelector( '.reveal' );
|
|
358
|
-
dom.slides = document.querySelector( '.reveal .slides' );
|
|
359
|
-
|
|
360
426
|
// Prevent transitions while we're loading
|
|
361
427
|
dom.slides.classList.add( 'no-transition' );
|
|
362
428
|
|
|
@@ -377,14 +443,14 @@ var Reveal = (function(){
|
|
|
377
443
|
// Slide number
|
|
378
444
|
dom.slideNumber = createSingletonNode( dom.wrapper, 'div', 'slide-number', '' );
|
|
379
445
|
|
|
380
|
-
// State background element [DEPRECATED]
|
|
381
|
-
createSingletonNode( dom.wrapper, 'div', 'state-background', null );
|
|
382
|
-
|
|
383
446
|
// Overlay graphic which is displayed during the paused mode
|
|
384
447
|
createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null );
|
|
385
448
|
|
|
386
449
|
// Cache references to elements
|
|
387
450
|
dom.controls = document.querySelector( '.reveal .controls' );
|
|
451
|
+
dom.theme = document.querySelector( '#theme' );
|
|
452
|
+
|
|
453
|
+
dom.wrapper.setAttribute( 'role', 'application' );
|
|
388
454
|
|
|
389
455
|
// There can be multiple instances of controls throughout the page
|
|
390
456
|
dom.controlsLeft = toArray( document.querySelectorAll( '.navigate-left' ) );
|
|
@@ -394,6 +460,100 @@ var Reveal = (function(){
|
|
|
394
460
|
dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) );
|
|
395
461
|
dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) );
|
|
396
462
|
|
|
463
|
+
dom.statusDiv = createStatusDiv();
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Creates a hidden div with role aria-live to announce the
|
|
468
|
+
* current slide content. Hide the div off-screen to make it
|
|
469
|
+
* available only to Assistive Technologies.
|
|
470
|
+
*/
|
|
471
|
+
function createStatusDiv() {
|
|
472
|
+
|
|
473
|
+
var statusDiv = document.getElementById( 'aria-status-div' );
|
|
474
|
+
if( !statusDiv ) {
|
|
475
|
+
statusDiv = document.createElement( 'div' );
|
|
476
|
+
statusDiv.style.position = 'absolute';
|
|
477
|
+
statusDiv.style.height = '1px';
|
|
478
|
+
statusDiv.style.width = '1px';
|
|
479
|
+
statusDiv.style.overflow ='hidden';
|
|
480
|
+
statusDiv.style.clip = 'rect( 1px, 1px, 1px, 1px )';
|
|
481
|
+
statusDiv.setAttribute( 'id', 'aria-status-div' );
|
|
482
|
+
statusDiv.setAttribute( 'aria-live', 'polite' );
|
|
483
|
+
statusDiv.setAttribute( 'aria-atomic','true' );
|
|
484
|
+
dom.wrapper.appendChild( statusDiv );
|
|
485
|
+
}
|
|
486
|
+
return statusDiv;
|
|
487
|
+
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Configures the presentation for printing to a static
|
|
492
|
+
* PDF.
|
|
493
|
+
*/
|
|
494
|
+
function setupPDF() {
|
|
495
|
+
|
|
496
|
+
var slideSize = getComputedSlideSize( window.innerWidth, window.innerHeight );
|
|
497
|
+
|
|
498
|
+
// Dimensions of the PDF pages
|
|
499
|
+
var pageWidth = Math.floor( slideSize.width * ( 1 + config.margin ) ),
|
|
500
|
+
pageHeight = Math.floor( slideSize.height * ( 1 + config.margin ) );
|
|
501
|
+
|
|
502
|
+
// Dimensions of slides within the pages
|
|
503
|
+
var slideWidth = slideSize.width,
|
|
504
|
+
slideHeight = slideSize.height;
|
|
505
|
+
|
|
506
|
+
// Let the browser know what page size we want to print
|
|
507
|
+
injectStyleSheet( '@page{size:'+ pageWidth +'px '+ pageHeight +'px; margin: 0;}' );
|
|
508
|
+
|
|
509
|
+
// Limit the size of certain elements to the dimensions of the slide
|
|
510
|
+
injectStyleSheet( '.reveal section>img, .reveal section>video, .reveal section>iframe{max-width: '+ slideWidth +'px; max-height:'+ slideHeight +'px}' );
|
|
511
|
+
|
|
512
|
+
document.body.classList.add( 'print-pdf' );
|
|
513
|
+
document.body.style.width = pageWidth + 'px';
|
|
514
|
+
document.body.style.height = pageHeight + 'px';
|
|
515
|
+
|
|
516
|
+
// Slide and slide background layout
|
|
517
|
+
toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) {
|
|
518
|
+
|
|
519
|
+
// Vertical stacks are not centred since their section
|
|
520
|
+
// children will be
|
|
521
|
+
if( slide.classList.contains( 'stack' ) === false ) {
|
|
522
|
+
// Center the slide inside of the page, giving the slide some margin
|
|
523
|
+
var left = ( pageWidth - slideWidth ) / 2,
|
|
524
|
+
top = ( pageHeight - slideHeight ) / 2;
|
|
525
|
+
|
|
526
|
+
var contentHeight = getAbsoluteHeight( slide );
|
|
527
|
+
var numberOfPages = Math.max( Math.ceil( contentHeight / pageHeight ), 1 );
|
|
528
|
+
|
|
529
|
+
// Center slides vertically
|
|
530
|
+
if( numberOfPages === 1 && config.center || slide.classList.contains( 'center' ) ) {
|
|
531
|
+
top = Math.max( ( pageHeight - contentHeight ) / 2, 0 );
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// Position the slide inside of the page
|
|
535
|
+
slide.style.left = left + 'px';
|
|
536
|
+
slide.style.top = top + 'px';
|
|
537
|
+
slide.style.width = slideWidth + 'px';
|
|
538
|
+
|
|
539
|
+
// TODO Backgrounds need to be multiplied when the slide
|
|
540
|
+
// stretches over multiple pages
|
|
541
|
+
var background = slide.querySelector( '.slide-background' );
|
|
542
|
+
if( background ) {
|
|
543
|
+
background.style.width = pageWidth + 'px';
|
|
544
|
+
background.style.height = ( pageHeight * numberOfPages ) + 'px';
|
|
545
|
+
background.style.top = -top + 'px';
|
|
546
|
+
background.style.left = -left + 'px';
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
} );
|
|
551
|
+
|
|
552
|
+
// Show all fragments
|
|
553
|
+
toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ' .fragment' ) ).forEach( function( fragment ) {
|
|
554
|
+
fragment.classList.add( 'visible' );
|
|
555
|
+
} );
|
|
556
|
+
|
|
397
557
|
}
|
|
398
558
|
|
|
399
559
|
/**
|
|
@@ -403,15 +563,26 @@ var Reveal = (function(){
|
|
|
403
563
|
*/
|
|
404
564
|
function createSingletonNode( container, tagname, classname, innerHTML ) {
|
|
405
565
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
566
|
+
// Find all nodes matching the description
|
|
567
|
+
var nodes = container.querySelectorAll( '.' + classname );
|
|
568
|
+
|
|
569
|
+
// Check all matches to find one which is a direct child of
|
|
570
|
+
// the specified container
|
|
571
|
+
for( var i = 0; i < nodes.length; i++ ) {
|
|
572
|
+
var testNode = nodes[i];
|
|
573
|
+
if( testNode.parentNode === container ) {
|
|
574
|
+
return testNode;
|
|
412
575
|
}
|
|
413
|
-
container.appendChild( node );
|
|
414
576
|
}
|
|
577
|
+
|
|
578
|
+
// If no node was found, create it now
|
|
579
|
+
var node = document.createElement( tagname );
|
|
580
|
+
node.classList.add( classname );
|
|
581
|
+
if( typeof innerHTML === 'string' ) {
|
|
582
|
+
node.innerHTML = innerHTML;
|
|
583
|
+
}
|
|
584
|
+
container.appendChild( node );
|
|
585
|
+
|
|
415
586
|
return node;
|
|
416
587
|
|
|
417
588
|
}
|
|
@@ -423,81 +594,36 @@ var Reveal = (function(){
|
|
|
423
594
|
*/
|
|
424
595
|
function createBackgrounds() {
|
|
425
596
|
|
|
426
|
-
|
|
427
|
-
document.body.classList.add( 'print-pdf' );
|
|
428
|
-
}
|
|
597
|
+
var printMode = isPrintingPDF();
|
|
429
598
|
|
|
430
599
|
// Clear prior backgrounds
|
|
431
600
|
dom.background.innerHTML = '';
|
|
432
601
|
dom.background.classList.add( 'no-transition' );
|
|
433
602
|
|
|
434
|
-
// Helper method for creating a background element for the
|
|
435
|
-
// given slide
|
|
436
|
-
function _createBackground( slide, container ) {
|
|
437
|
-
|
|
438
|
-
var data = {
|
|
439
|
-
background: slide.getAttribute( 'data-background' ),
|
|
440
|
-
backgroundSize: slide.getAttribute( 'data-background-size' ),
|
|
441
|
-
backgroundImage: slide.getAttribute( 'data-background-image' ),
|
|
442
|
-
backgroundColor: slide.getAttribute( 'data-background-color' ),
|
|
443
|
-
backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
|
|
444
|
-
backgroundPosition: slide.getAttribute( 'data-background-position' ),
|
|
445
|
-
backgroundTransition: slide.getAttribute( 'data-background-transition' )
|
|
446
|
-
};
|
|
447
|
-
|
|
448
|
-
var element = document.createElement( 'div' );
|
|
449
|
-
element.className = 'slide-background';
|
|
450
|
-
|
|
451
|
-
if( data.background ) {
|
|
452
|
-
// Auto-wrap image urls in url(...)
|
|
453
|
-
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
|
|
454
|
-
element.style.backgroundImage = 'url('+ data.background +')';
|
|
455
|
-
}
|
|
456
|
-
else {
|
|
457
|
-
element.style.background = data.background;
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
if( data.background || data.backgroundColor || data.backgroundImage ) {
|
|
462
|
-
element.setAttribute( 'data-background-hash', data.background + data.backgroundSize + data.backgroundImage + data.backgroundColor + data.backgroundRepeat + data.backgroundPosition + data.backgroundTransition );
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// Additional and optional background properties
|
|
466
|
-
if( data.backgroundSize ) element.style.backgroundSize = data.backgroundSize;
|
|
467
|
-
if( data.backgroundImage ) element.style.backgroundImage = 'url("' + data.backgroundImage + '")';
|
|
468
|
-
if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
|
|
469
|
-
if( data.backgroundRepeat ) element.style.backgroundRepeat = data.backgroundRepeat;
|
|
470
|
-
if( data.backgroundPosition ) element.style.backgroundPosition = data.backgroundPosition;
|
|
471
|
-
if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
|
|
472
|
-
|
|
473
|
-
container.appendChild( element );
|
|
474
|
-
|
|
475
|
-
return element;
|
|
476
|
-
|
|
477
|
-
}
|
|
478
|
-
|
|
479
603
|
// Iterate over all horizontal slides
|
|
480
|
-
toArray(
|
|
604
|
+
toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).forEach( function( slideh ) {
|
|
481
605
|
|
|
482
606
|
var backgroundStack;
|
|
483
607
|
|
|
484
|
-
if(
|
|
485
|
-
backgroundStack =
|
|
608
|
+
if( printMode ) {
|
|
609
|
+
backgroundStack = createBackground( slideh, slideh );
|
|
486
610
|
}
|
|
487
611
|
else {
|
|
488
|
-
backgroundStack =
|
|
612
|
+
backgroundStack = createBackground( slideh, dom.background );
|
|
489
613
|
}
|
|
490
614
|
|
|
491
615
|
// Iterate over all vertical slides
|
|
492
616
|
toArray( slideh.querySelectorAll( 'section' ) ).forEach( function( slidev ) {
|
|
493
617
|
|
|
494
|
-
if(
|
|
495
|
-
|
|
618
|
+
if( printMode ) {
|
|
619
|
+
createBackground( slidev, slidev );
|
|
496
620
|
}
|
|
497
621
|
else {
|
|
498
|
-
|
|
622
|
+
createBackground( slidev, backgroundStack );
|
|
499
623
|
}
|
|
500
624
|
|
|
625
|
+
backgroundStack.classList.add( 'stack' );
|
|
626
|
+
|
|
501
627
|
} );
|
|
502
628
|
|
|
503
629
|
} );
|
|
@@ -526,13 +652,131 @@ var Reveal = (function(){
|
|
|
526
652
|
|
|
527
653
|
}
|
|
528
654
|
|
|
655
|
+
/**
|
|
656
|
+
* Creates a background for the given slide.
|
|
657
|
+
*
|
|
658
|
+
* @param {HTMLElement} slide
|
|
659
|
+
* @param {HTMLElement} container The element that the background
|
|
660
|
+
* should be appended to
|
|
661
|
+
*/
|
|
662
|
+
function createBackground( slide, container ) {
|
|
663
|
+
|
|
664
|
+
var data = {
|
|
665
|
+
background: slide.getAttribute( 'data-background' ),
|
|
666
|
+
backgroundSize: slide.getAttribute( 'data-background-size' ),
|
|
667
|
+
backgroundImage: slide.getAttribute( 'data-background-image' ),
|
|
668
|
+
backgroundVideo: slide.getAttribute( 'data-background-video' ),
|
|
669
|
+
backgroundIframe: slide.getAttribute( 'data-background-iframe' ),
|
|
670
|
+
backgroundColor: slide.getAttribute( 'data-background-color' ),
|
|
671
|
+
backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
|
|
672
|
+
backgroundPosition: slide.getAttribute( 'data-background-position' ),
|
|
673
|
+
backgroundTransition: slide.getAttribute( 'data-background-transition' )
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
var element = document.createElement( 'div' );
|
|
677
|
+
|
|
678
|
+
// Carry over custom classes from the slide to the background
|
|
679
|
+
element.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' );
|
|
680
|
+
|
|
681
|
+
if( data.background ) {
|
|
682
|
+
// Auto-wrap image urls in url(...)
|
|
683
|
+
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
|
|
684
|
+
slide.setAttribute( 'data-background-image', data.background );
|
|
685
|
+
}
|
|
686
|
+
else {
|
|
687
|
+
element.style.background = data.background;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Create a hash for this combination of background settings.
|
|
692
|
+
// This is used to determine when two slide backgrounds are
|
|
693
|
+
// the same.
|
|
694
|
+
if( data.background || data.backgroundColor || data.backgroundImage || data.backgroundVideo || data.backgroundIframe ) {
|
|
695
|
+
element.setAttribute( 'data-background-hash', data.background +
|
|
696
|
+
data.backgroundSize +
|
|
697
|
+
data.backgroundImage +
|
|
698
|
+
data.backgroundVideo +
|
|
699
|
+
data.backgroundIframe +
|
|
700
|
+
data.backgroundColor +
|
|
701
|
+
data.backgroundRepeat +
|
|
702
|
+
data.backgroundPosition +
|
|
703
|
+
data.backgroundTransition );
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// Additional and optional background properties
|
|
707
|
+
if( data.backgroundSize ) element.style.backgroundSize = data.backgroundSize;
|
|
708
|
+
if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
|
|
709
|
+
if( data.backgroundRepeat ) element.style.backgroundRepeat = data.backgroundRepeat;
|
|
710
|
+
if( data.backgroundPosition ) element.style.backgroundPosition = data.backgroundPosition;
|
|
711
|
+
if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
|
|
712
|
+
|
|
713
|
+
container.appendChild( element );
|
|
714
|
+
|
|
715
|
+
// If backgrounds are being recreated, clear old classes
|
|
716
|
+
slide.classList.remove( 'has-dark-background' );
|
|
717
|
+
slide.classList.remove( 'has-light-background' );
|
|
718
|
+
|
|
719
|
+
// If this slide has a background color, add a class that
|
|
720
|
+
// signals if it is light or dark. If the slide has no background
|
|
721
|
+
// color, no class will be set
|
|
722
|
+
var computedBackgroundColor = window.getComputedStyle( element ).backgroundColor;
|
|
723
|
+
if( computedBackgroundColor ) {
|
|
724
|
+
var rgb = colorToRgb( computedBackgroundColor );
|
|
725
|
+
|
|
726
|
+
// Ignore fully transparent backgrounds. Some browsers return
|
|
727
|
+
// rgba(0,0,0,0) when reading the computed background color of
|
|
728
|
+
// an element with no background
|
|
729
|
+
if( rgb && rgb.a !== 0 ) {
|
|
730
|
+
if( colorBrightness( computedBackgroundColor ) < 128 ) {
|
|
731
|
+
slide.classList.add( 'has-dark-background' );
|
|
732
|
+
}
|
|
733
|
+
else {
|
|
734
|
+
slide.classList.add( 'has-light-background' );
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
return element;
|
|
740
|
+
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Registers a listener to postMessage events, this makes it
|
|
745
|
+
* possible to call all reveal.js API methods from another
|
|
746
|
+
* window. For example:
|
|
747
|
+
*
|
|
748
|
+
* revealWindow.postMessage( JSON.stringify({
|
|
749
|
+
* method: 'slide',
|
|
750
|
+
* args: [ 2 ]
|
|
751
|
+
* }), '*' );
|
|
752
|
+
*/
|
|
753
|
+
function setupPostMessage() {
|
|
754
|
+
|
|
755
|
+
if( config.postMessage ) {
|
|
756
|
+
window.addEventListener( 'message', function ( event ) {
|
|
757
|
+
var data = event.data;
|
|
758
|
+
|
|
759
|
+
// Make sure we're dealing with JSON
|
|
760
|
+
if( data.charAt( 0 ) === '{' && data.charAt( data.length - 1 ) === '}' ) {
|
|
761
|
+
data = JSON.parse( data );
|
|
762
|
+
|
|
763
|
+
// Check if the requested method can be found
|
|
764
|
+
if( data.method && typeof Reveal[data.method] === 'function' ) {
|
|
765
|
+
Reveal[data.method].apply( Reveal, data.args );
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}, false );
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
}
|
|
772
|
+
|
|
529
773
|
/**
|
|
530
774
|
* Applies the configuration settings from the config
|
|
531
775
|
* object. May be called multiple times.
|
|
532
776
|
*/
|
|
533
777
|
function configure( options ) {
|
|
534
778
|
|
|
535
|
-
var numberOfSlides =
|
|
779
|
+
var numberOfSlides = dom.wrapper.querySelectorAll( SLIDES_SELECTOR ).length;
|
|
536
780
|
|
|
537
781
|
dom.wrapper.classList.remove( config.transition );
|
|
538
782
|
|
|
@@ -565,6 +809,11 @@ var Reveal = (function(){
|
|
|
565
809
|
dom.wrapper.classList.remove( 'center' );
|
|
566
810
|
}
|
|
567
811
|
|
|
812
|
+
// Exit the paused mode if it was configured off
|
|
813
|
+
if( config.pause === false ) {
|
|
814
|
+
resume();
|
|
815
|
+
}
|
|
816
|
+
|
|
568
817
|
if( config.mouseWheel ) {
|
|
569
818
|
document.addEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF
|
|
570
819
|
document.addEventListener( 'mousewheel', onDocumentMouseScroll, false );
|
|
@@ -591,7 +840,13 @@ var Reveal = (function(){
|
|
|
591
840
|
enablePreviewLinks( '[data-preview-link]' );
|
|
592
841
|
}
|
|
593
842
|
|
|
594
|
-
//
|
|
843
|
+
// Remove existing auto-slide controls
|
|
844
|
+
if( autoSlidePlayer ) {
|
|
845
|
+
autoSlidePlayer.destroy();
|
|
846
|
+
autoSlidePlayer = null;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
// Generate auto-slide controls if needed
|
|
595
850
|
if( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable && features.canvas && features.requestAnimationFrame ) {
|
|
596
851
|
autoSlidePlayer = new Playback( dom.wrapper, function() {
|
|
597
852
|
return Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 );
|
|
@@ -600,21 +855,13 @@ var Reveal = (function(){
|
|
|
600
855
|
autoSlidePlayer.on( 'click', onAutoSlidePlayerClick );
|
|
601
856
|
autoSlidePaused = false;
|
|
602
857
|
}
|
|
603
|
-
else if( autoSlidePlayer ) {
|
|
604
|
-
autoSlidePlayer.destroy();
|
|
605
|
-
autoSlidePlayer = null;
|
|
606
|
-
}
|
|
607
858
|
|
|
608
|
-
//
|
|
609
|
-
if( config.
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
if( config.theme !== themeName ) {
|
|
615
|
-
themeURL = themeURL.replace(themeFinder, config.theme);
|
|
616
|
-
dom.theme.setAttribute( 'href', themeURL );
|
|
617
|
-
}
|
|
859
|
+
// When fragments are turned off they should be visible
|
|
860
|
+
if( config.fragments === false ) {
|
|
861
|
+
toArray( dom.slides.querySelectorAll( '.fragment' ) ).forEach( function( element ) {
|
|
862
|
+
element.classList.add( 'visible' );
|
|
863
|
+
element.classList.remove( 'current-fragment' );
|
|
864
|
+
} );
|
|
618
865
|
}
|
|
619
866
|
|
|
620
867
|
sync();
|
|
@@ -637,7 +884,14 @@ var Reveal = (function(){
|
|
|
637
884
|
dom.wrapper.addEventListener( 'touchend', onTouchEnd, false );
|
|
638
885
|
|
|
639
886
|
// Support pointer-style touch interaction as well
|
|
640
|
-
if( window.navigator.
|
|
887
|
+
if( window.navigator.pointerEnabled ) {
|
|
888
|
+
// IE 11 uses un-prefixed version of pointer events
|
|
889
|
+
dom.wrapper.addEventListener( 'pointerdown', onPointerDown, false );
|
|
890
|
+
dom.wrapper.addEventListener( 'pointermove', onPointerMove, false );
|
|
891
|
+
dom.wrapper.addEventListener( 'pointerup', onPointerUp, false );
|
|
892
|
+
}
|
|
893
|
+
else if( window.navigator.msPointerEnabled ) {
|
|
894
|
+
// IE 10 uses prefixed version of pointer events
|
|
641
895
|
dom.wrapper.addEventListener( 'MSPointerDown', onPointerDown, false );
|
|
642
896
|
dom.wrapper.addEventListener( 'MSPointerMove', onPointerMove, false );
|
|
643
897
|
dom.wrapper.addEventListener( 'MSPointerUp', onPointerUp, false );
|
|
@@ -646,13 +900,14 @@ var Reveal = (function(){
|
|
|
646
900
|
|
|
647
901
|
if( config.keyboard ) {
|
|
648
902
|
document.addEventListener( 'keydown', onDocumentKeyDown, false );
|
|
903
|
+
document.addEventListener( 'keypress', onDocumentKeyPress, false );
|
|
649
904
|
}
|
|
650
905
|
|
|
651
906
|
if( config.progress && dom.progress ) {
|
|
652
907
|
dom.progress.addEventListener( 'click', onProgressClicked, false );
|
|
653
908
|
}
|
|
654
909
|
|
|
655
|
-
if( config.
|
|
910
|
+
if( config.focusBodyOnPageVisibilityChange ) {
|
|
656
911
|
var visibilityChange;
|
|
657
912
|
|
|
658
913
|
if( 'hidden' in document ) {
|
|
@@ -670,7 +925,17 @@ var Reveal = (function(){
|
|
|
670
925
|
}
|
|
671
926
|
}
|
|
672
927
|
|
|
673
|
-
|
|
928
|
+
// Listen to both touch and click events, in case the device
|
|
929
|
+
// supports both
|
|
930
|
+
var pointerEvents = [ 'touchstart', 'click' ];
|
|
931
|
+
|
|
932
|
+
// Only support touch for Android, fixes double navigations in
|
|
933
|
+
// stock browser
|
|
934
|
+
if( navigator.userAgent.match( /android/gi ) ) {
|
|
935
|
+
pointerEvents = [ 'touchstart' ];
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
pointerEvents.forEach( function( eventName ) {
|
|
674
939
|
dom.controlsLeft.forEach( function( el ) { el.addEventListener( eventName, onNavigateLeftClicked, false ); } );
|
|
675
940
|
dom.controlsRight.forEach( function( el ) { el.addEventListener( eventName, onNavigateRightClicked, false ); } );
|
|
676
941
|
dom.controlsUp.forEach( function( el ) { el.addEventListener( eventName, onNavigateUpClicked, false ); } );
|
|
@@ -689,6 +954,7 @@ var Reveal = (function(){
|
|
|
689
954
|
eventsAreBound = false;
|
|
690
955
|
|
|
691
956
|
document.removeEventListener( 'keydown', onDocumentKeyDown, false );
|
|
957
|
+
document.removeEventListener( 'keypress', onDocumentKeyPress, false );
|
|
692
958
|
window.removeEventListener( 'hashchange', onWindowHashChange, false );
|
|
693
959
|
window.removeEventListener( 'resize', onWindowResize, false );
|
|
694
960
|
|
|
@@ -696,7 +962,14 @@ var Reveal = (function(){
|
|
|
696
962
|
dom.wrapper.removeEventListener( 'touchmove', onTouchMove, false );
|
|
697
963
|
dom.wrapper.removeEventListener( 'touchend', onTouchEnd, false );
|
|
698
964
|
|
|
699
|
-
|
|
965
|
+
// IE11
|
|
966
|
+
if( window.navigator.pointerEnabled ) {
|
|
967
|
+
dom.wrapper.removeEventListener( 'pointerdown', onPointerDown, false );
|
|
968
|
+
dom.wrapper.removeEventListener( 'pointermove', onPointerMove, false );
|
|
969
|
+
dom.wrapper.removeEventListener( 'pointerup', onPointerUp, false );
|
|
970
|
+
}
|
|
971
|
+
// IE10
|
|
972
|
+
else if( window.navigator.msPointerEnabled ) {
|
|
700
973
|
dom.wrapper.removeEventListener( 'MSPointerDown', onPointerDown, false );
|
|
701
974
|
dom.wrapper.removeEventListener( 'MSPointerMove', onPointerMove, false );
|
|
702
975
|
dom.wrapper.removeEventListener( 'MSPointerUp', onPointerUp, false );
|
|
@@ -738,6 +1011,22 @@ var Reveal = (function(){
|
|
|
738
1011
|
|
|
739
1012
|
}
|
|
740
1013
|
|
|
1014
|
+
/**
|
|
1015
|
+
* Utility for deserializing a value.
|
|
1016
|
+
*/
|
|
1017
|
+
function deserialize( value ) {
|
|
1018
|
+
|
|
1019
|
+
if( typeof value === 'string' ) {
|
|
1020
|
+
if( value === 'null' ) return null;
|
|
1021
|
+
else if( value === 'true' ) return true;
|
|
1022
|
+
else if( value === 'false' ) return false;
|
|
1023
|
+
else if( value.match( /^\d+$/ ) ) return parseFloat( value );
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
return value;
|
|
1027
|
+
|
|
1028
|
+
}
|
|
1029
|
+
|
|
741
1030
|
/**
|
|
742
1031
|
* Measures the distance in pixels between point a
|
|
743
1032
|
* and point b.
|
|
@@ -767,6 +1056,94 @@ var Reveal = (function(){
|
|
|
767
1056
|
|
|
768
1057
|
}
|
|
769
1058
|
|
|
1059
|
+
/**
|
|
1060
|
+
* Injects the given CSS styles into the DOM.
|
|
1061
|
+
*/
|
|
1062
|
+
function injectStyleSheet( value ) {
|
|
1063
|
+
|
|
1064
|
+
var tag = document.createElement( 'style' );
|
|
1065
|
+
tag.type = 'text/css';
|
|
1066
|
+
if( tag.styleSheet ) {
|
|
1067
|
+
tag.styleSheet.cssText = value;
|
|
1068
|
+
}
|
|
1069
|
+
else {
|
|
1070
|
+
tag.appendChild( document.createTextNode( value ) );
|
|
1071
|
+
}
|
|
1072
|
+
document.getElementsByTagName( 'head' )[0].appendChild( tag );
|
|
1073
|
+
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
/**
|
|
1077
|
+
* Measures the distance in pixels between point a and point b.
|
|
1078
|
+
*
|
|
1079
|
+
* @param {String} color The string representation of a color,
|
|
1080
|
+
* the following formats are supported:
|
|
1081
|
+
* - #000
|
|
1082
|
+
* - #000000
|
|
1083
|
+
* - rgb(0,0,0)
|
|
1084
|
+
*/
|
|
1085
|
+
function colorToRgb( color ) {
|
|
1086
|
+
|
|
1087
|
+
var hex3 = color.match( /^#([0-9a-f]{3})$/i );
|
|
1088
|
+
if( hex3 && hex3[1] ) {
|
|
1089
|
+
hex3 = hex3[1];
|
|
1090
|
+
return {
|
|
1091
|
+
r: parseInt( hex3.charAt( 0 ), 16 ) * 0x11,
|
|
1092
|
+
g: parseInt( hex3.charAt( 1 ), 16 ) * 0x11,
|
|
1093
|
+
b: parseInt( hex3.charAt( 2 ), 16 ) * 0x11
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
var hex6 = color.match( /^#([0-9a-f]{6})$/i );
|
|
1098
|
+
if( hex6 && hex6[1] ) {
|
|
1099
|
+
hex6 = hex6[1];
|
|
1100
|
+
return {
|
|
1101
|
+
r: parseInt( hex6.substr( 0, 2 ), 16 ),
|
|
1102
|
+
g: parseInt( hex6.substr( 2, 2 ), 16 ),
|
|
1103
|
+
b: parseInt( hex6.substr( 4, 2 ), 16 )
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
var rgb = color.match( /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i );
|
|
1108
|
+
if( rgb ) {
|
|
1109
|
+
return {
|
|
1110
|
+
r: parseInt( rgb[1], 10 ),
|
|
1111
|
+
g: parseInt( rgb[2], 10 ),
|
|
1112
|
+
b: parseInt( rgb[3], 10 )
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
var rgba = color.match( /^rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\,\s*([\d]+|[\d]*.[\d]+)\s*\)$/i );
|
|
1117
|
+
if( rgba ) {
|
|
1118
|
+
return {
|
|
1119
|
+
r: parseInt( rgba[1], 10 ),
|
|
1120
|
+
g: parseInt( rgba[2], 10 ),
|
|
1121
|
+
b: parseInt( rgba[3], 10 ),
|
|
1122
|
+
a: parseFloat( rgba[4] )
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
return null;
|
|
1127
|
+
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
/**
|
|
1131
|
+
* Calculates brightness on a scale of 0-255.
|
|
1132
|
+
*
|
|
1133
|
+
* @param color See colorStringToRgb for supported formats.
|
|
1134
|
+
*/
|
|
1135
|
+
function colorBrightness( color ) {
|
|
1136
|
+
|
|
1137
|
+
if( typeof color === 'string' ) color = colorToRgb( color );
|
|
1138
|
+
|
|
1139
|
+
if( color ) {
|
|
1140
|
+
return ( color.r * 299 + color.g * 587 + color.b * 114 ) / 1000;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
return null;
|
|
1144
|
+
|
|
1145
|
+
}
|
|
1146
|
+
|
|
770
1147
|
/**
|
|
771
1148
|
* Retrieves the height of the given element by looking
|
|
772
1149
|
* at the position and height of its immediate children.
|
|
@@ -782,7 +1159,7 @@ var Reveal = (function(){
|
|
|
782
1159
|
|
|
783
1160
|
if( typeof child.offsetTop === 'number' && child.style ) {
|
|
784
1161
|
// Count # of abs children
|
|
785
|
-
if( child.
|
|
1162
|
+
if( window.getComputedStyle( child ).position === 'absolute' ) {
|
|
786
1163
|
absoluteChildren += 1;
|
|
787
1164
|
}
|
|
788
1165
|
|
|
@@ -804,40 +1181,26 @@ var Reveal = (function(){
|
|
|
804
1181
|
|
|
805
1182
|
/**
|
|
806
1183
|
* Returns the remaining height within the parent of the
|
|
807
|
-
* target element
|
|
808
|
-
* siblings.
|
|
1184
|
+
* target element.
|
|
809
1185
|
*
|
|
810
|
-
* remaining height = [parent height] - [
|
|
1186
|
+
* remaining height = [ configured parent height ] - [ current parent height ]
|
|
811
1187
|
*/
|
|
812
1188
|
function getRemainingHeight( element, height ) {
|
|
813
1189
|
|
|
814
1190
|
height = height || 0;
|
|
815
1191
|
|
|
816
1192
|
if( element ) {
|
|
817
|
-
var
|
|
818
|
-
var siblings = parent.childNodes;
|
|
819
|
-
|
|
820
|
-
// Subtract the height of each sibling
|
|
821
|
-
toArray( siblings ).forEach( function( sibling ) {
|
|
822
|
-
|
|
823
|
-
if( typeof sibling.offsetHeight === 'number' && sibling !== element ) {
|
|
824
|
-
|
|
825
|
-
var styles = window.getComputedStyle( sibling ),
|
|
826
|
-
marginTop = parseInt( styles.marginTop, 10 ),
|
|
827
|
-
marginBottom = parseInt( styles.marginBottom, 10 );
|
|
828
|
-
|
|
829
|
-
height -= sibling.offsetHeight + marginTop + marginBottom;
|
|
830
|
-
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
} );
|
|
1193
|
+
var newHeight, oldHeight = element.style.height;
|
|
834
1194
|
|
|
835
|
-
|
|
1195
|
+
// Change the .stretch element height to 0 in order find the height of all
|
|
1196
|
+
// the other elements
|
|
1197
|
+
element.style.height = '0px';
|
|
1198
|
+
newHeight = height - element.parentNode.offsetHeight;
|
|
836
1199
|
|
|
837
|
-
//
|
|
838
|
-
height
|
|
839
|
-
parseInt( elementStyles.marginBottom, 10 );
|
|
1200
|
+
// Restore the old height, just in case
|
|
1201
|
+
element.style.height = oldHeight + 'px';
|
|
840
1202
|
|
|
1203
|
+
return newHeight;
|
|
841
1204
|
}
|
|
842
1205
|
|
|
843
1206
|
return height;
|
|
@@ -882,13 +1245,19 @@ var Reveal = (function(){
|
|
|
882
1245
|
* Dispatches an event of the specified type from the
|
|
883
1246
|
* reveal DOM element.
|
|
884
1247
|
*/
|
|
885
|
-
function dispatchEvent( type,
|
|
1248
|
+
function dispatchEvent( type, args ) {
|
|
886
1249
|
|
|
887
|
-
var event = document.createEvent(
|
|
1250
|
+
var event = document.createEvent( 'HTMLEvents', 1, 2 );
|
|
888
1251
|
event.initEvent( type, true, true );
|
|
889
|
-
extend( event,
|
|
1252
|
+
extend( event, args );
|
|
890
1253
|
dom.wrapper.dispatchEvent( event );
|
|
891
1254
|
|
|
1255
|
+
// If we're in an iframe, post each reveal.js event to the
|
|
1256
|
+
// parent window. Used by the notes plugin
|
|
1257
|
+
if( config.postMessageEvents && window.parent !== window.self ) {
|
|
1258
|
+
window.parent.postMessage( JSON.stringify({ namespace: 'reveal', eventName: type, state: getState() }), '*' );
|
|
1259
|
+
}
|
|
1260
|
+
|
|
892
1261
|
}
|
|
893
1262
|
|
|
894
1263
|
/**
|
|
@@ -897,7 +1266,7 @@ var Reveal = (function(){
|
|
|
897
1266
|
function enableRollingLinks() {
|
|
898
1267
|
|
|
899
1268
|
if( features.transforms3d && !( 'msPerspective' in document.body.style ) ) {
|
|
900
|
-
var anchors =
|
|
1269
|
+
var anchors = dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ' a' );
|
|
901
1270
|
|
|
902
1271
|
for( var i = 0, len = anchors.length; i < len; i++ ) {
|
|
903
1272
|
var anchor = anchors[i];
|
|
@@ -921,7 +1290,7 @@ var Reveal = (function(){
|
|
|
921
1290
|
*/
|
|
922
1291
|
function disableRollingLinks() {
|
|
923
1292
|
|
|
924
|
-
var anchors =
|
|
1293
|
+
var anchors = dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ' a.roll' );
|
|
925
1294
|
|
|
926
1295
|
for( var i = 0, len = anchors.length; i < len; i++ ) {
|
|
927
1296
|
var anchor = anchors[i];
|
|
@@ -968,15 +1337,16 @@ var Reveal = (function(){
|
|
|
968
1337
|
/**
|
|
969
1338
|
* Opens a preview window for the target URL.
|
|
970
1339
|
*/
|
|
971
|
-
function
|
|
1340
|
+
function showPreview( url ) {
|
|
972
1341
|
|
|
973
|
-
|
|
1342
|
+
closeOverlay();
|
|
974
1343
|
|
|
975
|
-
dom.
|
|
976
|
-
dom.
|
|
977
|
-
dom.
|
|
1344
|
+
dom.overlay = document.createElement( 'div' );
|
|
1345
|
+
dom.overlay.classList.add( 'overlay' );
|
|
1346
|
+
dom.overlay.classList.add( 'overlay-preview' );
|
|
1347
|
+
dom.wrapper.appendChild( dom.overlay );
|
|
978
1348
|
|
|
979
|
-
dom.
|
|
1349
|
+
dom.overlay.innerHTML = [
|
|
980
1350
|
'<header>',
|
|
981
1351
|
'<a class="close" href="#"><span class="icon"></span></a>',
|
|
982
1352
|
'<a class="external" href="'+ url +'" target="_blank"><span class="icon"></span></a>',
|
|
@@ -987,34 +1357,78 @@ var Reveal = (function(){
|
|
|
987
1357
|
'</div>'
|
|
988
1358
|
].join('');
|
|
989
1359
|
|
|
990
|
-
dom.
|
|
991
|
-
dom.
|
|
1360
|
+
dom.overlay.querySelector( 'iframe' ).addEventListener( 'load', function( event ) {
|
|
1361
|
+
dom.overlay.classList.add( 'loaded' );
|
|
992
1362
|
}, false );
|
|
993
1363
|
|
|
994
|
-
dom.
|
|
995
|
-
|
|
1364
|
+
dom.overlay.querySelector( '.close' ).addEventListener( 'click', function( event ) {
|
|
1365
|
+
closeOverlay();
|
|
996
1366
|
event.preventDefault();
|
|
997
1367
|
}, false );
|
|
998
1368
|
|
|
999
|
-
dom.
|
|
1000
|
-
|
|
1369
|
+
dom.overlay.querySelector( '.external' ).addEventListener( 'click', function( event ) {
|
|
1370
|
+
closeOverlay();
|
|
1001
1371
|
}, false );
|
|
1002
1372
|
|
|
1003
1373
|
setTimeout( function() {
|
|
1004
|
-
dom.
|
|
1374
|
+
dom.overlay.classList.add( 'visible' );
|
|
1005
1375
|
}, 1 );
|
|
1006
1376
|
|
|
1007
1377
|
}
|
|
1008
1378
|
|
|
1009
1379
|
/**
|
|
1010
|
-
*
|
|
1380
|
+
* Opens a overlay window with help material.
|
|
1011
1381
|
*/
|
|
1012
|
-
function
|
|
1382
|
+
function showHelp() {
|
|
1383
|
+
|
|
1384
|
+
if( config.help ) {
|
|
1385
|
+
|
|
1386
|
+
closeOverlay();
|
|
1387
|
+
|
|
1388
|
+
dom.overlay = document.createElement( 'div' );
|
|
1389
|
+
dom.overlay.classList.add( 'overlay' );
|
|
1390
|
+
dom.overlay.classList.add( 'overlay-help' );
|
|
1391
|
+
dom.wrapper.appendChild( dom.overlay );
|
|
1392
|
+
|
|
1393
|
+
var html = '<p class="title">Keyboard Shortcuts</p><br/>';
|
|
1394
|
+
|
|
1395
|
+
html += '<table><th>KEY</th><th>ACTION</th>';
|
|
1396
|
+
for( var key in keyboardShortcuts ) {
|
|
1397
|
+
html += '<tr><td>' + key + '</td><td>' + keyboardShortcuts[ key ] + '</td></tr>';
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
html += '</table>';
|
|
1401
|
+
|
|
1402
|
+
dom.overlay.innerHTML = [
|
|
1403
|
+
'<header>',
|
|
1404
|
+
'<a class="close" href="#"><span class="icon"></span></a>',
|
|
1405
|
+
'</header>',
|
|
1406
|
+
'<div class="viewport">',
|
|
1407
|
+
'<div class="viewport-inner">'+ html +'</div>',
|
|
1408
|
+
'</div>'
|
|
1409
|
+
].join('');
|
|
1410
|
+
|
|
1411
|
+
dom.overlay.querySelector( '.close' ).addEventListener( 'click', function( event ) {
|
|
1412
|
+
closeOverlay();
|
|
1413
|
+
event.preventDefault();
|
|
1414
|
+
}, false );
|
|
1415
|
+
|
|
1416
|
+
setTimeout( function() {
|
|
1417
|
+
dom.overlay.classList.add( 'visible' );
|
|
1418
|
+
}, 1 );
|
|
1013
1419
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
/**
|
|
1425
|
+
* Closes any currently open overlay.
|
|
1426
|
+
*/
|
|
1427
|
+
function closeOverlay() {
|
|
1428
|
+
|
|
1429
|
+
if( dom.overlay ) {
|
|
1430
|
+
dom.overlay.parentNode.removeChild( dom.overlay );
|
|
1431
|
+
dom.overlay = null;
|
|
1018
1432
|
}
|
|
1019
1433
|
|
|
1020
1434
|
}
|
|
@@ -1027,54 +1441,49 @@ var Reveal = (function(){
|
|
|
1027
1441
|
|
|
1028
1442
|
if( dom.wrapper && !isPrintingPDF() ) {
|
|
1029
1443
|
|
|
1030
|
-
|
|
1031
|
-
var availableWidth = dom.wrapper.offsetWidth,
|
|
1032
|
-
availableHeight = dom.wrapper.offsetHeight;
|
|
1033
|
-
|
|
1034
|
-
// Reduce available space by margin
|
|
1035
|
-
availableWidth -= ( availableHeight * config.margin );
|
|
1036
|
-
availableHeight -= ( availableHeight * config.margin );
|
|
1444
|
+
var size = getComputedSlideSize();
|
|
1037
1445
|
|
|
1038
|
-
//
|
|
1039
|
-
var slideWidth = config.width,
|
|
1040
|
-
slideHeight = config.height,
|
|
1041
|
-
slidePadding = 20; // TODO Dig this out of DOM
|
|
1446
|
+
var slidePadding = 20; // TODO Dig this out of DOM
|
|
1042
1447
|
|
|
1043
1448
|
// Layout the contents of the slides
|
|
1044
1449
|
layoutSlideContents( config.width, config.height, slidePadding );
|
|
1045
1450
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
slideWidth = parseInt( slideWidth, 10 ) / 100 * availableWidth;
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
// Slide height may be a percentage of available height
|
|
1052
|
-
if( typeof slideHeight === 'string' && /%$/.test( slideHeight ) ) {
|
|
1053
|
-
slideHeight = parseInt( slideHeight, 10 ) / 100 * availableHeight;
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
|
-
dom.slides.style.width = slideWidth + 'px';
|
|
1057
|
-
dom.slides.style.height = slideHeight + 'px';
|
|
1451
|
+
dom.slides.style.width = size.width + 'px';
|
|
1452
|
+
dom.slides.style.height = size.height + 'px';
|
|
1058
1453
|
|
|
1059
1454
|
// Determine scale of content to fit within available space
|
|
1060
|
-
scale = Math.min(
|
|
1455
|
+
scale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height );
|
|
1061
1456
|
|
|
1062
1457
|
// Respect max/min scale settings
|
|
1063
1458
|
scale = Math.max( scale, config.minScale );
|
|
1064
1459
|
scale = Math.min( scale, config.maxScale );
|
|
1065
1460
|
|
|
1066
|
-
//
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
dom.slides.style.
|
|
1461
|
+
// Don't apply any scaling styles if scale is 1
|
|
1462
|
+
if( scale === 1 ) {
|
|
1463
|
+
dom.slides.style.zoom = '';
|
|
1464
|
+
dom.slides.style.left = '';
|
|
1465
|
+
dom.slides.style.top = '';
|
|
1466
|
+
dom.slides.style.bottom = '';
|
|
1467
|
+
dom.slides.style.right = '';
|
|
1468
|
+
transformElement( dom.slides, '' );
|
|
1070
1469
|
}
|
|
1071
|
-
// Apply scale transform as a fallback
|
|
1072
1470
|
else {
|
|
1073
|
-
|
|
1471
|
+
// Prefer zooming in desktop Chrome so that content remains crisp
|
|
1472
|
+
if( !isMobileDevice && /chrome/i.test( navigator.userAgent ) && typeof dom.slides.style.zoom !== 'undefined' ) {
|
|
1473
|
+
dom.slides.style.zoom = scale;
|
|
1474
|
+
}
|
|
1475
|
+
// Apply scale transform as a fallback
|
|
1476
|
+
else {
|
|
1477
|
+
dom.slides.style.left = '50%';
|
|
1478
|
+
dom.slides.style.top = '50%';
|
|
1479
|
+
dom.slides.style.bottom = 'auto';
|
|
1480
|
+
dom.slides.style.right = 'auto';
|
|
1481
|
+
transformElement( dom.slides, 'translate(-50%, -50%) scale('+ scale +')' );
|
|
1482
|
+
}
|
|
1074
1483
|
}
|
|
1075
1484
|
|
|
1076
1485
|
// Select all slides, vertical and horizontal
|
|
1077
|
-
var slides = toArray(
|
|
1486
|
+
var slides = toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) );
|
|
1078
1487
|
|
|
1079
1488
|
for( var i = 0, len = slides.length; i < len; i++ ) {
|
|
1080
1489
|
var slide = slides[ i ];
|
|
@@ -1091,7 +1500,7 @@ var Reveal = (function(){
|
|
|
1091
1500
|
slide.style.top = 0;
|
|
1092
1501
|
}
|
|
1093
1502
|
else {
|
|
1094
|
-
slide.style.top = Math.max(
|
|
1503
|
+
slide.style.top = Math.max( ( ( size.height - getAbsoluteHeight( slide ) ) / 2 ) - slidePadding, 0 ) + 'px';
|
|
1095
1504
|
}
|
|
1096
1505
|
}
|
|
1097
1506
|
else {
|
|
@@ -1117,7 +1526,7 @@ var Reveal = (function(){
|
|
|
1117
1526
|
toArray( dom.slides.querySelectorAll( 'section > .stretch' ) ).forEach( function( element ) {
|
|
1118
1527
|
|
|
1119
1528
|
// Determine how much vertical space we can use
|
|
1120
|
-
var remainingHeight = getRemainingHeight( element,
|
|
1529
|
+
var remainingHeight = getRemainingHeight( element, height );
|
|
1121
1530
|
|
|
1122
1531
|
// Consider the aspect ratio of media elements
|
|
1123
1532
|
if( /(img|video)/gi.test( element.nodeName ) ) {
|
|
@@ -1139,6 +1548,41 @@ var Reveal = (function(){
|
|
|
1139
1548
|
|
|
1140
1549
|
}
|
|
1141
1550
|
|
|
1551
|
+
/**
|
|
1552
|
+
* Calculates the computed pixel size of our slides. These
|
|
1553
|
+
* values are based on the width and height configuration
|
|
1554
|
+
* options.
|
|
1555
|
+
*/
|
|
1556
|
+
function getComputedSlideSize( presentationWidth, presentationHeight ) {
|
|
1557
|
+
|
|
1558
|
+
var size = {
|
|
1559
|
+
// Slide size
|
|
1560
|
+
width: config.width,
|
|
1561
|
+
height: config.height,
|
|
1562
|
+
|
|
1563
|
+
// Presentation size
|
|
1564
|
+
presentationWidth: presentationWidth || dom.wrapper.offsetWidth,
|
|
1565
|
+
presentationHeight: presentationHeight || dom.wrapper.offsetHeight
|
|
1566
|
+
};
|
|
1567
|
+
|
|
1568
|
+
// Reduce available space by margin
|
|
1569
|
+
size.presentationWidth -= ( size.presentationHeight * config.margin );
|
|
1570
|
+
size.presentationHeight -= ( size.presentationHeight * config.margin );
|
|
1571
|
+
|
|
1572
|
+
// Slide width may be a percentage of available width
|
|
1573
|
+
if( typeof size.width === 'string' && /%$/.test( size.width ) ) {
|
|
1574
|
+
size.width = parseInt( size.width, 10 ) / 100 * size.presentationWidth;
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
// Slide height may be a percentage of available height
|
|
1578
|
+
if( typeof size.height === 'string' && /%$/.test( size.height ) ) {
|
|
1579
|
+
size.height = parseInt( size.height, 10 ) / 100 * size.presentationHeight;
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
return size;
|
|
1583
|
+
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1142
1586
|
/**
|
|
1143
1587
|
* Stores the vertical index of a stack so that the same
|
|
1144
1588
|
* vertical slide can be selected when navigating to and
|
|
@@ -1198,67 +1642,57 @@ var Reveal = (function(){
|
|
|
1198
1642
|
dom.wrapper.classList.add( 'overview' );
|
|
1199
1643
|
dom.wrapper.classList.remove( 'overview-deactivating' );
|
|
1200
1644
|
|
|
1201
|
-
|
|
1202
|
-
clearTimeout( deactivateOverviewTimeout );
|
|
1203
|
-
|
|
1204
|
-
// Not the pretties solution, but need to let the overview
|
|
1205
|
-
// class apply first so that slides are measured accurately
|
|
1206
|
-
// before we can position them
|
|
1207
|
-
activateOverviewTimeout = setTimeout( function() {
|
|
1208
|
-
|
|
1209
|
-
var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
|
|
1645
|
+
var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
|
|
1210
1646
|
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1647
|
+
for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) {
|
|
1648
|
+
var hslide = horizontalSlides[i],
|
|
1649
|
+
hoffset = config.rtl ? -105 : 105;
|
|
1214
1650
|
|
|
1215
|
-
|
|
1651
|
+
hslide.setAttribute( 'data-index-h', i );
|
|
1216
1652
|
|
|
1217
|
-
|
|
1218
|
-
|
|
1653
|
+
// Apply CSS transform
|
|
1654
|
+
transformElement( hslide, 'translateZ(-'+ depth +'px) translate(' + ( ( i - indexh ) * hoffset ) + '%, 0%)' );
|
|
1219
1655
|
|
|
1220
|
-
|
|
1656
|
+
if( hslide.classList.contains( 'stack' ) ) {
|
|
1221
1657
|
|
|
1222
|
-
|
|
1658
|
+
var verticalSlides = hslide.querySelectorAll( 'section' );
|
|
1223
1659
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1660
|
+
for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) {
|
|
1661
|
+
var verticalIndex = i === indexh ? indexv : getPreviousVerticalIndex( hslide );
|
|
1226
1662
|
|
|
1227
|
-
|
|
1663
|
+
var vslide = verticalSlides[j];
|
|
1228
1664
|
|
|
1229
|
-
|
|
1230
|
-
|
|
1665
|
+
vslide.setAttribute( 'data-index-h', i );
|
|
1666
|
+
vslide.setAttribute( 'data-index-v', j );
|
|
1231
1667
|
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
// Navigate to this slide on click
|
|
1236
|
-
vslide.addEventListener( 'click', onOverviewSlideClicked, true );
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
}
|
|
1240
|
-
else {
|
|
1668
|
+
// Apply CSS transform
|
|
1669
|
+
transformElement( vslide, 'translate(0%, ' + ( ( j - verticalIndex ) * 105 ) + '%)' );
|
|
1241
1670
|
|
|
1242
1671
|
// Navigate to this slide on click
|
|
1243
|
-
|
|
1244
|
-
|
|
1672
|
+
vslide.addEventListener( 'click', onOverviewSlideClicked, true );
|
|
1245
1673
|
}
|
|
1246
|
-
}
|
|
1247
1674
|
|
|
1248
|
-
|
|
1675
|
+
}
|
|
1676
|
+
else {
|
|
1249
1677
|
|
|
1250
|
-
|
|
1678
|
+
// Navigate to this slide on click
|
|
1679
|
+
hslide.addEventListener( 'click', onOverviewSlideClicked, true );
|
|
1251
1680
|
|
|
1252
|
-
if( !wasActive ) {
|
|
1253
|
-
// Notify observers of the overview showing
|
|
1254
|
-
dispatchEvent( 'overviewshown', {
|
|
1255
|
-
'indexh': indexh,
|
|
1256
|
-
'indexv': indexv,
|
|
1257
|
-
'currentSlide': currentSlide
|
|
1258
|
-
} );
|
|
1259
1681
|
}
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
updateSlidesVisibility();
|
|
1260
1685
|
|
|
1261
|
-
|
|
1686
|
+
layout();
|
|
1687
|
+
|
|
1688
|
+
if( !wasActive ) {
|
|
1689
|
+
// Notify observers of the overview showing
|
|
1690
|
+
dispatchEvent( 'overviewshown', {
|
|
1691
|
+
'indexh': indexh,
|
|
1692
|
+
'indexv': indexv,
|
|
1693
|
+
'currentSlide': currentSlide
|
|
1694
|
+
} );
|
|
1695
|
+
}
|
|
1262
1696
|
|
|
1263
1697
|
}
|
|
1264
1698
|
|
|
@@ -1273,9 +1707,6 @@ var Reveal = (function(){
|
|
|
1273
1707
|
// Only proceed if enabled in config
|
|
1274
1708
|
if( config.overview ) {
|
|
1275
1709
|
|
|
1276
|
-
clearTimeout( activateOverviewTimeout );
|
|
1277
|
-
clearTimeout( deactivateOverviewTimeout );
|
|
1278
|
-
|
|
1279
1710
|
dom.wrapper.classList.remove( 'overview' );
|
|
1280
1711
|
|
|
1281
1712
|
// Temporarily add a class so that transitions can do different things
|
|
@@ -1283,12 +1714,12 @@ var Reveal = (function(){
|
|
|
1283
1714
|
// moving from slide to slide
|
|
1284
1715
|
dom.wrapper.classList.add( 'overview-deactivating' );
|
|
1285
1716
|
|
|
1286
|
-
|
|
1717
|
+
setTimeout( function () {
|
|
1287
1718
|
dom.wrapper.classList.remove( 'overview-deactivating' );
|
|
1288
1719
|
}, 1 );
|
|
1289
1720
|
|
|
1290
1721
|
// Select all slides
|
|
1291
|
-
toArray(
|
|
1722
|
+
toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) {
|
|
1292
1723
|
// Resets all transforms to use the external styles
|
|
1293
1724
|
transformElement( slide, '' );
|
|
1294
1725
|
|
|
@@ -1370,7 +1801,7 @@ var Reveal = (function(){
|
|
|
1370
1801
|
element.webkitRequestFullscreen ||
|
|
1371
1802
|
element.webkitRequestFullScreen ||
|
|
1372
1803
|
element.mozRequestFullScreen ||
|
|
1373
|
-
element.
|
|
1804
|
+
element.msRequestFullscreen;
|
|
1374
1805
|
|
|
1375
1806
|
if( requestMethod ) {
|
|
1376
1807
|
requestMethod.apply( element );
|
|
@@ -1384,13 +1815,15 @@ var Reveal = (function(){
|
|
|
1384
1815
|
*/
|
|
1385
1816
|
function pause() {
|
|
1386
1817
|
|
|
1387
|
-
|
|
1818
|
+
if( config.pause ) {
|
|
1819
|
+
var wasPaused = dom.wrapper.classList.contains( 'paused' );
|
|
1388
1820
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1821
|
+
cancelAutoSlide();
|
|
1822
|
+
dom.wrapper.classList.add( 'paused' );
|
|
1391
1823
|
|
|
1392
|
-
|
|
1393
|
-
|
|
1824
|
+
if( wasPaused === false ) {
|
|
1825
|
+
dispatchEvent( 'paused' );
|
|
1826
|
+
}
|
|
1394
1827
|
}
|
|
1395
1828
|
|
|
1396
1829
|
}
|
|
@@ -1414,13 +1847,13 @@ var Reveal = (function(){
|
|
|
1414
1847
|
/**
|
|
1415
1848
|
* Toggles the paused mode on and off.
|
|
1416
1849
|
*/
|
|
1417
|
-
function togglePause() {
|
|
1850
|
+
function togglePause( override ) {
|
|
1418
1851
|
|
|
1419
|
-
if(
|
|
1420
|
-
resume();
|
|
1852
|
+
if( typeof override === 'boolean' ) {
|
|
1853
|
+
override ? pause() : resume();
|
|
1421
1854
|
}
|
|
1422
1855
|
else {
|
|
1423
|
-
pause();
|
|
1856
|
+
isPaused() ? resume() : pause();
|
|
1424
1857
|
}
|
|
1425
1858
|
|
|
1426
1859
|
}
|
|
@@ -1434,6 +1867,34 @@ var Reveal = (function(){
|
|
|
1434
1867
|
|
|
1435
1868
|
}
|
|
1436
1869
|
|
|
1870
|
+
/**
|
|
1871
|
+
* Toggles the auto slide mode on and off.
|
|
1872
|
+
*
|
|
1873
|
+
* @param {Boolean} override Optional flag which sets the desired state.
|
|
1874
|
+
* True means autoplay starts, false means it stops.
|
|
1875
|
+
*/
|
|
1876
|
+
|
|
1877
|
+
function toggleAutoSlide( override ) {
|
|
1878
|
+
|
|
1879
|
+
if( typeof override === 'boolean' ) {
|
|
1880
|
+
override ? resumeAutoSlide() : pauseAutoSlide();
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
else {
|
|
1884
|
+
autoSlidePaused ? resumeAutoSlide() : pauseAutoSlide();
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
/**
|
|
1890
|
+
* Checks if the auto slide mode is currently on.
|
|
1891
|
+
*/
|
|
1892
|
+
function isAutoSliding() {
|
|
1893
|
+
|
|
1894
|
+
return !!( autoSlide && !autoSlidePaused );
|
|
1895
|
+
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1437
1898
|
/**
|
|
1438
1899
|
* Steps from the current point in the presentation to the
|
|
1439
1900
|
* slide which matches the specified horizontal and vertical
|
|
@@ -1451,7 +1912,7 @@ var Reveal = (function(){
|
|
|
1451
1912
|
previousSlide = currentSlide;
|
|
1452
1913
|
|
|
1453
1914
|
// Query all horizontal slides in the deck
|
|
1454
|
-
var horizontalSlides =
|
|
1915
|
+
var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
|
|
1455
1916
|
|
|
1456
1917
|
// If no vertical index is specified and the upcoming slide is a
|
|
1457
1918
|
// stack, resume at its previous vertical index
|
|
@@ -1544,13 +2005,14 @@ var Reveal = (function(){
|
|
|
1544
2005
|
// stacks
|
|
1545
2006
|
if( previousSlide ) {
|
|
1546
2007
|
previousSlide.classList.remove( 'present' );
|
|
2008
|
+
previousSlide.setAttribute( 'aria-hidden', 'true' );
|
|
1547
2009
|
|
|
1548
2010
|
// Reset all slides upon navigate to home
|
|
1549
2011
|
// Issue: #285
|
|
1550
|
-
if (
|
|
2012
|
+
if ( dom.wrapper.querySelector( HOME_SLIDE_SELECTOR ).classList.contains( 'present' ) ) {
|
|
1551
2013
|
// Launch async task
|
|
1552
2014
|
setTimeout( function () {
|
|
1553
|
-
var slides = toArray(
|
|
2015
|
+
var slides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.stack') ), i;
|
|
1554
2016
|
for( i in slides ) {
|
|
1555
2017
|
if( slides[i] ) {
|
|
1556
2018
|
// Reset stack
|
|
@@ -1562,11 +2024,14 @@ var Reveal = (function(){
|
|
|
1562
2024
|
}
|
|
1563
2025
|
|
|
1564
2026
|
// Handle embedded content
|
|
1565
|
-
if( slideChanged ) {
|
|
2027
|
+
if( slideChanged || !previousSlide ) {
|
|
1566
2028
|
stopEmbeddedContent( previousSlide );
|
|
1567
2029
|
startEmbeddedContent( currentSlide );
|
|
1568
2030
|
}
|
|
1569
2031
|
|
|
2032
|
+
// Announce the current slide contents, for screen readers
|
|
2033
|
+
dom.statusDiv.textContent = currentSlide.textContent;
|
|
2034
|
+
|
|
1570
2035
|
updateControls();
|
|
1571
2036
|
updateProgress();
|
|
1572
2037
|
updateBackground();
|
|
@@ -1603,12 +2068,18 @@ var Reveal = (function(){
|
|
|
1603
2068
|
// Re-create the slide backgrounds
|
|
1604
2069
|
createBackgrounds();
|
|
1605
2070
|
|
|
2071
|
+
// Write the current hash to the URL
|
|
2072
|
+
writeURL();
|
|
2073
|
+
|
|
1606
2074
|
sortAllFragments();
|
|
1607
2075
|
|
|
1608
2076
|
updateControls();
|
|
1609
2077
|
updateProgress();
|
|
1610
2078
|
updateBackground( true );
|
|
1611
2079
|
updateSlideNumber();
|
|
2080
|
+
updateSlidesVisibility();
|
|
2081
|
+
|
|
2082
|
+
formatEmbeddedContent();
|
|
1612
2083
|
|
|
1613
2084
|
}
|
|
1614
2085
|
|
|
@@ -1618,7 +2089,7 @@ var Reveal = (function(){
|
|
|
1618
2089
|
*/
|
|
1619
2090
|
function resetVerticalSlides() {
|
|
1620
2091
|
|
|
1621
|
-
var horizontalSlides = toArray(
|
|
2092
|
+
var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
|
|
1622
2093
|
horizontalSlides.forEach( function( horizontalSlide ) {
|
|
1623
2094
|
|
|
1624
2095
|
var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
|
|
@@ -1628,6 +2099,7 @@ var Reveal = (function(){
|
|
|
1628
2099
|
verticalSlide.classList.remove( 'present' );
|
|
1629
2100
|
verticalSlide.classList.remove( 'past' );
|
|
1630
2101
|
verticalSlide.classList.add( 'future' );
|
|
2102
|
+
verticalSlide.setAttribute( 'aria-hidden', 'true' );
|
|
1631
2103
|
}
|
|
1632
2104
|
|
|
1633
2105
|
} );
|
|
@@ -1642,7 +2114,7 @@ var Reveal = (function(){
|
|
|
1642
2114
|
*/
|
|
1643
2115
|
function sortAllFragments() {
|
|
1644
2116
|
|
|
1645
|
-
var horizontalSlides = toArray(
|
|
2117
|
+
var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
|
|
1646
2118
|
horizontalSlides.forEach( function( horizontalSlide ) {
|
|
1647
2119
|
|
|
1648
2120
|
var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
|
|
@@ -1675,9 +2147,11 @@ var Reveal = (function(){
|
|
|
1675
2147
|
|
|
1676
2148
|
// Select all slides and convert the NodeList result to
|
|
1677
2149
|
// an array
|
|
1678
|
-
var slides = toArray(
|
|
2150
|
+
var slides = toArray( dom.wrapper.querySelectorAll( selector ) ),
|
|
1679
2151
|
slidesLength = slides.length;
|
|
1680
2152
|
|
|
2153
|
+
var printMode = isPrintingPDF();
|
|
2154
|
+
|
|
1681
2155
|
if( slidesLength ) {
|
|
1682
2156
|
|
|
1683
2157
|
// Should the index loop?
|
|
@@ -1703,43 +2177,55 @@ var Reveal = (function(){
|
|
|
1703
2177
|
|
|
1704
2178
|
// http://www.w3.org/html/wg/drafts/html/master/editing.html#the-hidden-attribute
|
|
1705
2179
|
element.setAttribute( 'hidden', '' );
|
|
2180
|
+
element.setAttribute( 'aria-hidden', 'true' );
|
|
2181
|
+
|
|
2182
|
+
// If this element contains vertical slides
|
|
2183
|
+
if( element.querySelector( 'section' ) ) {
|
|
2184
|
+
element.classList.add( 'stack' );
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
// If we're printing static slides, all slides are "present"
|
|
2188
|
+
if( printMode ) {
|
|
2189
|
+
element.classList.add( 'present' );
|
|
2190
|
+
continue;
|
|
2191
|
+
}
|
|
1706
2192
|
|
|
1707
2193
|
if( i < index ) {
|
|
1708
2194
|
// Any element previous to index is given the 'past' class
|
|
1709
2195
|
element.classList.add( reverse ? 'future' : 'past' );
|
|
1710
2196
|
|
|
1711
|
-
|
|
2197
|
+
if( config.fragments ) {
|
|
2198
|
+
var pastFragments = toArray( element.querySelectorAll( '.fragment' ) );
|
|
1712
2199
|
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
2200
|
+
// Show all fragments on prior slides
|
|
2201
|
+
while( pastFragments.length ) {
|
|
2202
|
+
var pastFragment = pastFragments.pop();
|
|
2203
|
+
pastFragment.classList.add( 'visible' );
|
|
2204
|
+
pastFragment.classList.remove( 'current-fragment' );
|
|
2205
|
+
}
|
|
1718
2206
|
}
|
|
1719
2207
|
}
|
|
1720
2208
|
else if( i > index ) {
|
|
1721
2209
|
// Any element subsequent to index is given the 'future' class
|
|
1722
2210
|
element.classList.add( reverse ? 'past' : 'future' );
|
|
1723
2211
|
|
|
1724
|
-
|
|
2212
|
+
if( config.fragments ) {
|
|
2213
|
+
var futureFragments = toArray( element.querySelectorAll( '.fragment.visible' ) );
|
|
1725
2214
|
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
2215
|
+
// No fragments in future slides should be visible ahead of time
|
|
2216
|
+
while( futureFragments.length ) {
|
|
2217
|
+
var futureFragment = futureFragments.pop();
|
|
2218
|
+
futureFragment.classList.remove( 'visible' );
|
|
2219
|
+
futureFragment.classList.remove( 'current-fragment' );
|
|
2220
|
+
}
|
|
1731
2221
|
}
|
|
1732
2222
|
}
|
|
1733
|
-
|
|
1734
|
-
// If this element contains vertical slides
|
|
1735
|
-
if( element.querySelector( 'section' ) ) {
|
|
1736
|
-
element.classList.add( 'stack' );
|
|
1737
|
-
}
|
|
1738
2223
|
}
|
|
1739
2224
|
|
|
1740
2225
|
// Mark the current slide as present
|
|
1741
2226
|
slides[index].classList.add( 'present' );
|
|
1742
2227
|
slides[index].removeAttribute( 'hidden' );
|
|
2228
|
+
slides[index].removeAttribute( 'aria-hidden' );
|
|
1743
2229
|
|
|
1744
2230
|
// If this slide has a state associated with it, add it
|
|
1745
2231
|
// onto the current state of the deck
|
|
@@ -1767,12 +2253,12 @@ var Reveal = (function(){
|
|
|
1767
2253
|
|
|
1768
2254
|
// Select all slides and convert the NodeList result to
|
|
1769
2255
|
// an array
|
|
1770
|
-
var horizontalSlides = toArray(
|
|
2256
|
+
var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ),
|
|
1771
2257
|
horizontalSlidesLength = horizontalSlides.length,
|
|
1772
2258
|
distanceX,
|
|
1773
2259
|
distanceY;
|
|
1774
2260
|
|
|
1775
|
-
if( horizontalSlidesLength ) {
|
|
2261
|
+
if( horizontalSlidesLength && typeof indexh !== 'undefined' ) {
|
|
1776
2262
|
|
|
1777
2263
|
// The number of steps away from the present slide that will
|
|
1778
2264
|
// be visible
|
|
@@ -1780,7 +2266,12 @@ var Reveal = (function(){
|
|
|
1780
2266
|
|
|
1781
2267
|
// Limit view distance on weaker devices
|
|
1782
2268
|
if( isMobileDevice ) {
|
|
1783
|
-
viewDistance = isOverview() ? 6 :
|
|
2269
|
+
viewDistance = isOverview() ? 6 : 2;
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
// Limit view distance on weaker devices
|
|
2273
|
+
if( isPrintingPDF() ) {
|
|
2274
|
+
viewDistance = Number.MAX_VALUE;
|
|
1784
2275
|
}
|
|
1785
2276
|
|
|
1786
2277
|
for( var x = 0; x < horizontalSlidesLength; x++ ) {
|
|
@@ -1790,10 +2281,15 @@ var Reveal = (function(){
|
|
|
1790
2281
|
verticalSlidesLength = verticalSlides.length;
|
|
1791
2282
|
|
|
1792
2283
|
// Loops so that it measures 1 between the first and last slides
|
|
1793
|
-
distanceX = Math.abs( ( indexh - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0;
|
|
2284
|
+
distanceX = Math.abs( ( ( indexh || 0 ) - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0;
|
|
1794
2285
|
|
|
1795
2286
|
// Show the horizontal slide if it's within the view distance
|
|
1796
|
-
|
|
2287
|
+
if( distanceX < viewDistance ) {
|
|
2288
|
+
showSlide( horizontalSlide );
|
|
2289
|
+
}
|
|
2290
|
+
else {
|
|
2291
|
+
hideSlide( horizontalSlide );
|
|
2292
|
+
}
|
|
1797
2293
|
|
|
1798
2294
|
if( verticalSlidesLength ) {
|
|
1799
2295
|
|
|
@@ -1802,9 +2298,14 @@ var Reveal = (function(){
|
|
|
1802
2298
|
for( var y = 0; y < verticalSlidesLength; y++ ) {
|
|
1803
2299
|
var verticalSlide = verticalSlides[y];
|
|
1804
2300
|
|
|
1805
|
-
distanceY = x === indexh ? Math.abs( indexv - y ) : Math.abs( y - oy );
|
|
2301
|
+
distanceY = x === ( indexh || 0 ) ? Math.abs( ( indexv || 0 ) - y ) : Math.abs( y - oy );
|
|
1806
2302
|
|
|
1807
|
-
|
|
2303
|
+
if( distanceX + distanceY < viewDistance ) {
|
|
2304
|
+
showSlide( verticalSlide );
|
|
2305
|
+
}
|
|
2306
|
+
else {
|
|
2307
|
+
hideSlide( verticalSlide );
|
|
2308
|
+
}
|
|
1808
2309
|
}
|
|
1809
2310
|
|
|
1810
2311
|
}
|
|
@@ -1820,44 +2321,9 @@ var Reveal = (function(){
|
|
|
1820
2321
|
function updateProgress() {
|
|
1821
2322
|
|
|
1822
2323
|
// Update progress if enabled
|
|
1823
|
-
if( config.progress && dom.
|
|
1824
|
-
|
|
1825
|
-
var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
|
|
1826
|
-
|
|
1827
|
-
// The number of past and total slides
|
|
1828
|
-
var totalCount = document.querySelectorAll( SLIDES_SELECTOR + ':not(.stack)' ).length;
|
|
1829
|
-
var pastCount = 0;
|
|
1830
|
-
|
|
1831
|
-
// Step through all slides and count the past ones
|
|
1832
|
-
mainLoop: for( var i = 0; i < horizontalSlides.length; i++ ) {
|
|
1833
|
-
|
|
1834
|
-
var horizontalSlide = horizontalSlides[i];
|
|
1835
|
-
var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
|
|
2324
|
+
if( config.progress && dom.progressbar ) {
|
|
1836
2325
|
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
// Stop as soon as we arrive at the present
|
|
1840
|
-
if( verticalSlides[j].classList.contains( 'present' ) ) {
|
|
1841
|
-
break mainLoop;
|
|
1842
|
-
}
|
|
1843
|
-
|
|
1844
|
-
pastCount++;
|
|
1845
|
-
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
// Stop as soon as we arrive at the present
|
|
1849
|
-
if( horizontalSlide.classList.contains( 'present' ) ) {
|
|
1850
|
-
break;
|
|
1851
|
-
}
|
|
1852
|
-
|
|
1853
|
-
// Don't count the wrapping section for vertical slides
|
|
1854
|
-
if( horizontalSlide.classList.contains( 'stack' ) === false ) {
|
|
1855
|
-
pastCount++;
|
|
1856
|
-
}
|
|
1857
|
-
|
|
1858
|
-
}
|
|
1859
|
-
|
|
1860
|
-
dom.progressbar.style.width = ( pastCount / ( totalCount - 1 ) ) * window.innerWidth + 'px';
|
|
2326
|
+
dom.progressbar.style.width = getProgress() * dom.wrapper.offsetWidth + 'px';
|
|
1861
2327
|
|
|
1862
2328
|
}
|
|
1863
2329
|
|
|
@@ -1951,30 +2417,38 @@ var Reveal = (function(){
|
|
|
1951
2417
|
// states of their slides (past/present/future)
|
|
1952
2418
|
toArray( dom.background.childNodes ).forEach( function( backgroundh, h ) {
|
|
1953
2419
|
|
|
2420
|
+
backgroundh.classList.remove( 'past' );
|
|
2421
|
+
backgroundh.classList.remove( 'present' );
|
|
2422
|
+
backgroundh.classList.remove( 'future' );
|
|
2423
|
+
|
|
1954
2424
|
if( h < indexh ) {
|
|
1955
|
-
backgroundh.
|
|
2425
|
+
backgroundh.classList.add( horizontalPast );
|
|
1956
2426
|
}
|
|
1957
2427
|
else if ( h > indexh ) {
|
|
1958
|
-
backgroundh.
|
|
2428
|
+
backgroundh.classList.add( horizontalFuture );
|
|
1959
2429
|
}
|
|
1960
2430
|
else {
|
|
1961
|
-
backgroundh.
|
|
2431
|
+
backgroundh.classList.add( 'present' );
|
|
1962
2432
|
|
|
1963
2433
|
// Store a reference to the current background element
|
|
1964
2434
|
currentBackground = backgroundh;
|
|
1965
2435
|
}
|
|
1966
2436
|
|
|
1967
2437
|
if( includeAll || h === indexh ) {
|
|
1968
|
-
toArray( backgroundh.
|
|
2438
|
+
toArray( backgroundh.querySelectorAll( '.slide-background' ) ).forEach( function( backgroundv, v ) {
|
|
2439
|
+
|
|
2440
|
+
backgroundv.classList.remove( 'past' );
|
|
2441
|
+
backgroundv.classList.remove( 'present' );
|
|
2442
|
+
backgroundv.classList.remove( 'future' );
|
|
1969
2443
|
|
|
1970
2444
|
if( v < indexv ) {
|
|
1971
|
-
backgroundv.
|
|
2445
|
+
backgroundv.classList.add( 'past' );
|
|
1972
2446
|
}
|
|
1973
2447
|
else if ( v > indexv ) {
|
|
1974
|
-
backgroundv.
|
|
2448
|
+
backgroundv.classList.add( 'future' );
|
|
1975
2449
|
}
|
|
1976
2450
|
else {
|
|
1977
|
-
backgroundv.
|
|
2451
|
+
backgroundv.classList.add( 'present' );
|
|
1978
2452
|
|
|
1979
2453
|
// Only if this is the present horizontal and vertical slide
|
|
1980
2454
|
if( h === indexh ) currentBackground = backgroundv;
|
|
@@ -1985,9 +2459,25 @@ var Reveal = (function(){
|
|
|
1985
2459
|
|
|
1986
2460
|
} );
|
|
1987
2461
|
|
|
1988
|
-
//
|
|
1989
|
-
|
|
2462
|
+
// Stop any currently playing video background
|
|
2463
|
+
if( previousBackground ) {
|
|
2464
|
+
|
|
2465
|
+
var previousVideo = previousBackground.querySelector( 'video' );
|
|
2466
|
+
if( previousVideo ) previousVideo.pause();
|
|
2467
|
+
|
|
2468
|
+
}
|
|
2469
|
+
|
|
1990
2470
|
if( currentBackground ) {
|
|
2471
|
+
|
|
2472
|
+
// Start video playback
|
|
2473
|
+
var currentVideo = currentBackground.querySelector( 'video' );
|
|
2474
|
+
if( currentVideo ) {
|
|
2475
|
+
currentVideo.currentTime = 0;
|
|
2476
|
+
currentVideo.play();
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
// Don't transition between identical backgrounds. This
|
|
2480
|
+
// prevents unwanted flicker.
|
|
1991
2481
|
var previousBackgroundHash = previousBackground ? previousBackground.getAttribute( 'data-background-hash' ) : null;
|
|
1992
2482
|
var currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );
|
|
1993
2483
|
if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== previousBackground ) {
|
|
@@ -1995,6 +2485,20 @@ var Reveal = (function(){
|
|
|
1995
2485
|
}
|
|
1996
2486
|
|
|
1997
2487
|
previousBackground = currentBackground;
|
|
2488
|
+
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
// If there's a background brightness flag for this slide,
|
|
2492
|
+
// bubble it to the .reveal container
|
|
2493
|
+
if( currentSlide ) {
|
|
2494
|
+
[ 'has-light-background', 'has-dark-background' ].forEach( function( classToBubble ) {
|
|
2495
|
+
if( currentSlide.classList.contains( classToBubble ) ) {
|
|
2496
|
+
dom.wrapper.classList.add( classToBubble );
|
|
2497
|
+
}
|
|
2498
|
+
else {
|
|
2499
|
+
dom.wrapper.classList.remove( classToBubble );
|
|
2500
|
+
}
|
|
2501
|
+
} );
|
|
1998
2502
|
}
|
|
1999
2503
|
|
|
2000
2504
|
// Allow the first background to apply without transition
|
|
@@ -2012,8 +2516,8 @@ var Reveal = (function(){
|
|
|
2012
2516
|
|
|
2013
2517
|
if( config.parallaxBackgroundImage ) {
|
|
2014
2518
|
|
|
2015
|
-
var horizontalSlides =
|
|
2016
|
-
verticalSlides =
|
|
2519
|
+
var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),
|
|
2520
|
+
verticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
|
|
2017
2521
|
|
|
2018
2522
|
var backgroundSize = dom.background.style.backgroundSize.split( ' ' ),
|
|
2019
2523
|
backgroundWidth, backgroundHeight;
|
|
@@ -2032,7 +2536,7 @@ var Reveal = (function(){
|
|
|
2032
2536
|
|
|
2033
2537
|
var slideHeight = dom.background.offsetHeight;
|
|
2034
2538
|
var verticalSlideCount = verticalSlides.length;
|
|
2035
|
-
var verticalOffset = verticalSlideCount >
|
|
2539
|
+
var verticalOffset = verticalSlideCount > 1 ? -( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 ) * indexv : 0;
|
|
2036
2540
|
|
|
2037
2541
|
dom.background.style.backgroundPosition = horizontalOffset + 'px ' + verticalOffset + 'px';
|
|
2038
2542
|
|
|
@@ -2040,6 +2544,103 @@ var Reveal = (function(){
|
|
|
2040
2544
|
|
|
2041
2545
|
}
|
|
2042
2546
|
|
|
2547
|
+
/**
|
|
2548
|
+
* Called when the given slide is within the configured view
|
|
2549
|
+
* distance. Shows the slide element and loads any content
|
|
2550
|
+
* that is set to load lazily (data-src).
|
|
2551
|
+
*/
|
|
2552
|
+
function showSlide( slide ) {
|
|
2553
|
+
|
|
2554
|
+
// Show the slide element
|
|
2555
|
+
slide.style.display = 'block';
|
|
2556
|
+
|
|
2557
|
+
// Media elements with data-src attributes
|
|
2558
|
+
toArray( slide.querySelectorAll( 'img[data-src], video[data-src], audio[data-src], iframe[data-src]' ) ).forEach( function( element ) {
|
|
2559
|
+
element.setAttribute( 'src', element.getAttribute( 'data-src' ) );
|
|
2560
|
+
element.removeAttribute( 'data-src' );
|
|
2561
|
+
} );
|
|
2562
|
+
|
|
2563
|
+
// Media elements with <source> children
|
|
2564
|
+
toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( media ) {
|
|
2565
|
+
var sources = 0;
|
|
2566
|
+
|
|
2567
|
+
toArray( media.querySelectorAll( 'source[data-src]' ) ).forEach( function( source ) {
|
|
2568
|
+
source.setAttribute( 'src', source.getAttribute( 'data-src' ) );
|
|
2569
|
+
source.removeAttribute( 'data-src' );
|
|
2570
|
+
sources += 1;
|
|
2571
|
+
} );
|
|
2572
|
+
|
|
2573
|
+
// If we rewrote sources for this video/audio element, we need
|
|
2574
|
+
// to manually tell it to load from its new origin
|
|
2575
|
+
if( sources > 0 ) {
|
|
2576
|
+
media.load();
|
|
2577
|
+
}
|
|
2578
|
+
} );
|
|
2579
|
+
|
|
2580
|
+
|
|
2581
|
+
// Show the corresponding background element
|
|
2582
|
+
var indices = getIndices( slide );
|
|
2583
|
+
var background = getSlideBackground( indices.h, indices.v );
|
|
2584
|
+
if( background ) {
|
|
2585
|
+
background.style.display = 'block';
|
|
2586
|
+
|
|
2587
|
+
// If the background contains media, load it
|
|
2588
|
+
if( background.hasAttribute( 'data-loaded' ) === false ) {
|
|
2589
|
+
background.setAttribute( 'data-loaded', 'true' );
|
|
2590
|
+
|
|
2591
|
+
var backgroundImage = slide.getAttribute( 'data-background-image' ),
|
|
2592
|
+
backgroundVideo = slide.getAttribute( 'data-background-video' ),
|
|
2593
|
+
backgroundIframe = slide.getAttribute( 'data-background-iframe' );
|
|
2594
|
+
|
|
2595
|
+
// Images
|
|
2596
|
+
if( backgroundImage ) {
|
|
2597
|
+
background.style.backgroundImage = 'url('+ backgroundImage +')';
|
|
2598
|
+
}
|
|
2599
|
+
// Videos
|
|
2600
|
+
else if ( backgroundVideo && !isSpeakerNotes() ) {
|
|
2601
|
+
var video = document.createElement( 'video' );
|
|
2602
|
+
|
|
2603
|
+
// Support comma separated lists of video sources
|
|
2604
|
+
backgroundVideo.split( ',' ).forEach( function( source ) {
|
|
2605
|
+
video.innerHTML += '<source src="'+ source +'">';
|
|
2606
|
+
} );
|
|
2607
|
+
|
|
2608
|
+
background.appendChild( video );
|
|
2609
|
+
}
|
|
2610
|
+
// Iframes
|
|
2611
|
+
else if ( backgroundIframe ) {
|
|
2612
|
+
var iframe = document.createElement( 'iframe' );
|
|
2613
|
+
iframe.setAttribute( 'src', backgroundIframe );
|
|
2614
|
+
iframe.style.width = '100%';
|
|
2615
|
+
iframe.style.height = '100%';
|
|
2616
|
+
iframe.style.maxHeight = '100%';
|
|
2617
|
+
iframe.style.maxWidth = '100%';
|
|
2618
|
+
|
|
2619
|
+
background.appendChild( iframe );
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
/**
|
|
2627
|
+
* Called when the given slide is moved outside of the
|
|
2628
|
+
* configured view distance.
|
|
2629
|
+
*/
|
|
2630
|
+
function hideSlide( slide ) {
|
|
2631
|
+
|
|
2632
|
+
// Hide the slide element
|
|
2633
|
+
slide.style.display = 'none';
|
|
2634
|
+
|
|
2635
|
+
// Hide the corresponding background element
|
|
2636
|
+
var indices = getIndices( slide );
|
|
2637
|
+
var background = getSlideBackground( indices.h, indices.v );
|
|
2638
|
+
if( background ) {
|
|
2639
|
+
background.style.display = 'none';
|
|
2640
|
+
}
|
|
2641
|
+
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2043
2644
|
/**
|
|
2044
2645
|
* Determine what available routes there are for navigation.
|
|
2045
2646
|
*
|
|
@@ -2047,8 +2648,8 @@ var Reveal = (function(){
|
|
|
2047
2648
|
*/
|
|
2048
2649
|
function availableRoutes() {
|
|
2049
2650
|
|
|
2050
|
-
var horizontalSlides =
|
|
2051
|
-
verticalSlides =
|
|
2651
|
+
var horizontalSlides = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),
|
|
2652
|
+
verticalSlides = dom.wrapper.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
|
|
2052
2653
|
|
|
2053
2654
|
var routes = {
|
|
2054
2655
|
left: indexh > 0 || config.loop,
|
|
@@ -2091,6 +2692,29 @@ var Reveal = (function(){
|
|
|
2091
2692
|
|
|
2092
2693
|
}
|
|
2093
2694
|
|
|
2695
|
+
/**
|
|
2696
|
+
* Enforces origin-specific format rules for embedded media.
|
|
2697
|
+
*/
|
|
2698
|
+
function formatEmbeddedContent() {
|
|
2699
|
+
|
|
2700
|
+
// YouTube frames must include "?enablejsapi=1"
|
|
2701
|
+
toArray( dom.slides.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
|
|
2702
|
+
var src = el.getAttribute( 'src' );
|
|
2703
|
+
if( !/enablejsapi\=1/gi.test( src ) ) {
|
|
2704
|
+
el.setAttribute( 'src', src + ( !/\?/.test( src ) ? '?' : '&' ) + 'enablejsapi=1' );
|
|
2705
|
+
}
|
|
2706
|
+
});
|
|
2707
|
+
|
|
2708
|
+
// Vimeo frames must include "?api=1"
|
|
2709
|
+
toArray( dom.slides.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) {
|
|
2710
|
+
var src = el.getAttribute( 'src' );
|
|
2711
|
+
if( !/api\=1/gi.test( src ) ) {
|
|
2712
|
+
el.setAttribute( 'src', src + ( !/\?/.test( src ) ? '?' : '&' ) + 'api=1' );
|
|
2713
|
+
}
|
|
2714
|
+
});
|
|
2715
|
+
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2094
2718
|
/**
|
|
2095
2719
|
* Start playback of any embedded content inside of
|
|
2096
2720
|
* the targeted slide.
|
|
@@ -2116,6 +2740,13 @@ var Reveal = (function(){
|
|
|
2116
2740
|
el.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
|
|
2117
2741
|
}
|
|
2118
2742
|
});
|
|
2743
|
+
|
|
2744
|
+
// Vimeo embeds
|
|
2745
|
+
toArray( slide.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) {
|
|
2746
|
+
if( el.hasAttribute( 'data-autoplay' ) ) {
|
|
2747
|
+
el.contentWindow.postMessage( '{"method":"play"}', '*' );
|
|
2748
|
+
}
|
|
2749
|
+
});
|
|
2119
2750
|
}
|
|
2120
2751
|
|
|
2121
2752
|
}
|
|
@@ -2126,7 +2757,7 @@ var Reveal = (function(){
|
|
|
2126
2757
|
*/
|
|
2127
2758
|
function stopEmbeddedContent( slide ) {
|
|
2128
2759
|
|
|
2129
|
-
if( slide ) {
|
|
2760
|
+
if( slide && slide.parentNode ) {
|
|
2130
2761
|
// HTML5 media elements
|
|
2131
2762
|
toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
|
|
2132
2763
|
if( !el.hasAttribute( 'data-ignore' ) ) {
|
|
@@ -2145,8 +2776,79 @@ var Reveal = (function(){
|
|
|
2145
2776
|
el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' );
|
|
2146
2777
|
}
|
|
2147
2778
|
});
|
|
2779
|
+
|
|
2780
|
+
// Vimeo embeds
|
|
2781
|
+
toArray( slide.querySelectorAll( 'iframe[src*="player.vimeo.com/"]' ) ).forEach( function( el ) {
|
|
2782
|
+
if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
|
|
2783
|
+
el.contentWindow.postMessage( '{"method":"pause"}', '*' );
|
|
2784
|
+
}
|
|
2785
|
+
});
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
/**
|
|
2791
|
+
* Returns a value ranging from 0-1 that represents
|
|
2792
|
+
* how far into the presentation we have navigated.
|
|
2793
|
+
*/
|
|
2794
|
+
function getProgress() {
|
|
2795
|
+
|
|
2796
|
+
var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
|
|
2797
|
+
|
|
2798
|
+
// The number of past and total slides
|
|
2799
|
+
var totalCount = getTotalSlides();
|
|
2800
|
+
var pastCount = 0;
|
|
2801
|
+
|
|
2802
|
+
// Step through all slides and count the past ones
|
|
2803
|
+
mainLoop: for( var i = 0; i < horizontalSlides.length; i++ ) {
|
|
2804
|
+
|
|
2805
|
+
var horizontalSlide = horizontalSlides[i];
|
|
2806
|
+
var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
|
|
2807
|
+
|
|
2808
|
+
for( var j = 0; j < verticalSlides.length; j++ ) {
|
|
2809
|
+
|
|
2810
|
+
// Stop as soon as we arrive at the present
|
|
2811
|
+
if( verticalSlides[j].classList.contains( 'present' ) ) {
|
|
2812
|
+
break mainLoop;
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
pastCount++;
|
|
2816
|
+
|
|
2817
|
+
}
|
|
2818
|
+
|
|
2819
|
+
// Stop as soon as we arrive at the present
|
|
2820
|
+
if( horizontalSlide.classList.contains( 'present' ) ) {
|
|
2821
|
+
break;
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
// Don't count the wrapping section for vertical slides
|
|
2825
|
+
if( horizontalSlide.classList.contains( 'stack' ) === false ) {
|
|
2826
|
+
pastCount++;
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2829
|
+
}
|
|
2830
|
+
|
|
2831
|
+
if( currentSlide ) {
|
|
2832
|
+
|
|
2833
|
+
var allFragments = currentSlide.querySelectorAll( '.fragment' );
|
|
2834
|
+
|
|
2835
|
+
// If there are fragments in the current slide those should be
|
|
2836
|
+
// accounted for in the progress.
|
|
2837
|
+
if( allFragments.length > 0 ) {
|
|
2838
|
+
var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' );
|
|
2839
|
+
|
|
2840
|
+
// This value represents how big a portion of the slide progress
|
|
2841
|
+
// that is made up by its fragments (0-1)
|
|
2842
|
+
var fragmentWeight = 0.9;
|
|
2843
|
+
|
|
2844
|
+
// Add fragment progress to the past slide count
|
|
2845
|
+
pastCount += ( visibleFragments.length / allFragments.length ) * fragmentWeight;
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2148
2848
|
}
|
|
2149
2849
|
|
|
2850
|
+
return pastCount / ( totalCount - 1 );
|
|
2851
|
+
|
|
2150
2852
|
}
|
|
2151
2853
|
|
|
2152
2854
|
/**
|
|
@@ -2173,8 +2875,13 @@ var Reveal = (function(){
|
|
|
2173
2875
|
// If the first bit is invalid and there is a name we can
|
|
2174
2876
|
// assume that this is a named link
|
|
2175
2877
|
if( isNaN( parseInt( bits[0], 10 ) ) && name.length ) {
|
|
2176
|
-
|
|
2177
|
-
|
|
2878
|
+
var element;
|
|
2879
|
+
|
|
2880
|
+
// Ensure the named link is a valid HTML ID attribute
|
|
2881
|
+
if( /^[a-zA-Z][\w:.-]*$/.test( name ) ) {
|
|
2882
|
+
// Find the slide with the specified ID
|
|
2883
|
+
element = document.querySelector( '#' + name );
|
|
2884
|
+
}
|
|
2178
2885
|
|
|
2179
2886
|
if( element ) {
|
|
2180
2887
|
// Find the position of the named slide and navigate to it
|
|
@@ -2216,12 +2923,19 @@ var Reveal = (function(){
|
|
|
2216
2923
|
if( typeof delay === 'number' ) {
|
|
2217
2924
|
writeURLTimeout = setTimeout( writeURL, delay );
|
|
2218
2925
|
}
|
|
2219
|
-
else {
|
|
2926
|
+
else if( currentSlide ) {
|
|
2220
2927
|
var url = '/';
|
|
2221
2928
|
|
|
2929
|
+
// Attempt to create a named link based on the slide's ID
|
|
2930
|
+
var id = currentSlide.getAttribute( 'id' );
|
|
2931
|
+
if( id ) {
|
|
2932
|
+
id = id.toLowerCase();
|
|
2933
|
+
id = id.replace( /[^a-zA-Z0-9\-\_\:\.]/g, '' );
|
|
2934
|
+
}
|
|
2935
|
+
|
|
2222
2936
|
// If the current slide has an ID, use that as a named link
|
|
2223
|
-
if(
|
|
2224
|
-
url = '/' +
|
|
2937
|
+
if( typeof id === 'string' && id.length ) {
|
|
2938
|
+
url = '/' + id;
|
|
2225
2939
|
}
|
|
2226
2940
|
// Otherwise use the /h/v index
|
|
2227
2941
|
else {
|
|
@@ -2258,11 +2972,14 @@ var Reveal = (function(){
|
|
|
2258
2972
|
var slideh = isVertical ? slide.parentNode : slide;
|
|
2259
2973
|
|
|
2260
2974
|
// Select all horizontal slides
|
|
2261
|
-
var horizontalSlides = toArray(
|
|
2975
|
+
var horizontalSlides = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
|
|
2262
2976
|
|
|
2263
2977
|
// Now that we know which the horizontal slide is, get its index
|
|
2264
2978
|
h = Math.max( horizontalSlides.indexOf( slideh ), 0 );
|
|
2265
2979
|
|
|
2980
|
+
// Assume we're not vertical
|
|
2981
|
+
v = undefined;
|
|
2982
|
+
|
|
2266
2983
|
// If this is a vertical slide, grab the vertical index
|
|
2267
2984
|
if( isVertical ) {
|
|
2268
2985
|
v = Math.max( toArray( slide.parentNode.querySelectorAll( 'section' ) ).indexOf( slide ), 0 );
|
|
@@ -2272,8 +2989,13 @@ var Reveal = (function(){
|
|
|
2272
2989
|
if( !slide && currentSlide ) {
|
|
2273
2990
|
var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0;
|
|
2274
2991
|
if( hasFragments ) {
|
|
2275
|
-
var
|
|
2276
|
-
|
|
2992
|
+
var currentFragment = currentSlide.querySelector( '.current-fragment' );
|
|
2993
|
+
if( currentFragment && currentFragment.hasAttribute( 'data-fragment-index' ) ) {
|
|
2994
|
+
f = parseInt( currentFragment.getAttribute( 'data-fragment-index' ), 10 );
|
|
2995
|
+
}
|
|
2996
|
+
else {
|
|
2997
|
+
f = currentSlide.querySelectorAll( '.fragment.visible' ).length - 1;
|
|
2998
|
+
}
|
|
2277
2999
|
}
|
|
2278
3000
|
}
|
|
2279
3001
|
|
|
@@ -2281,6 +3003,107 @@ var Reveal = (function(){
|
|
|
2281
3003
|
|
|
2282
3004
|
}
|
|
2283
3005
|
|
|
3006
|
+
/**
|
|
3007
|
+
* Retrieves the total number of slides in this presentation.
|
|
3008
|
+
*/
|
|
3009
|
+
function getTotalSlides() {
|
|
3010
|
+
|
|
3011
|
+
return dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ':not(.stack)' ).length;
|
|
3012
|
+
|
|
3013
|
+
}
|
|
3014
|
+
|
|
3015
|
+
/**
|
|
3016
|
+
* Returns the slide element matching the specified index.
|
|
3017
|
+
*/
|
|
3018
|
+
function getSlide( x, y ) {
|
|
3019
|
+
|
|
3020
|
+
var horizontalSlide = dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR )[ x ];
|
|
3021
|
+
var verticalSlides = horizontalSlide && horizontalSlide.querySelectorAll( 'section' );
|
|
3022
|
+
|
|
3023
|
+
if( verticalSlides && verticalSlides.length && typeof y === 'number' ) {
|
|
3024
|
+
return verticalSlides ? verticalSlides[ y ] : undefined;
|
|
3025
|
+
}
|
|
3026
|
+
|
|
3027
|
+
return horizontalSlide;
|
|
3028
|
+
|
|
3029
|
+
}
|
|
3030
|
+
|
|
3031
|
+
/**
|
|
3032
|
+
* Returns the background element for the given slide.
|
|
3033
|
+
* All slides, even the ones with no background properties
|
|
3034
|
+
* defined, have a background element so as long as the
|
|
3035
|
+
* index is valid an element will be returned.
|
|
3036
|
+
*/
|
|
3037
|
+
function getSlideBackground( x, y ) {
|
|
3038
|
+
|
|
3039
|
+
// When printing to PDF the slide backgrounds are nested
|
|
3040
|
+
// inside of the slides
|
|
3041
|
+
if( isPrintingPDF() ) {
|
|
3042
|
+
var slide = getSlide( x, y );
|
|
3043
|
+
if( slide ) {
|
|
3044
|
+
var background = slide.querySelector( '.slide-background' );
|
|
3045
|
+
if( background && background.parentNode === slide ) {
|
|
3046
|
+
return background;
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
|
|
3050
|
+
return undefined;
|
|
3051
|
+
}
|
|
3052
|
+
|
|
3053
|
+
var horizontalBackground = dom.wrapper.querySelectorAll( '.backgrounds>.slide-background' )[ x ];
|
|
3054
|
+
var verticalBackgrounds = horizontalBackground && horizontalBackground.querySelectorAll( '.slide-background' );
|
|
3055
|
+
|
|
3056
|
+
if( verticalBackgrounds && verticalBackgrounds.length && typeof y === 'number' ) {
|
|
3057
|
+
return verticalBackgrounds ? verticalBackgrounds[ y ] : undefined;
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
return horizontalBackground;
|
|
3061
|
+
|
|
3062
|
+
}
|
|
3063
|
+
|
|
3064
|
+
/**
|
|
3065
|
+
* Retrieves the current state of the presentation as
|
|
3066
|
+
* an object. This state can then be restored at any
|
|
3067
|
+
* time.
|
|
3068
|
+
*/
|
|
3069
|
+
function getState() {
|
|
3070
|
+
|
|
3071
|
+
var indices = getIndices();
|
|
3072
|
+
|
|
3073
|
+
return {
|
|
3074
|
+
indexh: indices.h,
|
|
3075
|
+
indexv: indices.v,
|
|
3076
|
+
indexf: indices.f,
|
|
3077
|
+
paused: isPaused(),
|
|
3078
|
+
overview: isOverview()
|
|
3079
|
+
};
|
|
3080
|
+
|
|
3081
|
+
}
|
|
3082
|
+
|
|
3083
|
+
/**
|
|
3084
|
+
* Restores the presentation to the given state.
|
|
3085
|
+
*
|
|
3086
|
+
* @param {Object} state As generated by getState()
|
|
3087
|
+
*/
|
|
3088
|
+
function setState( state ) {
|
|
3089
|
+
|
|
3090
|
+
if( typeof state === 'object' ) {
|
|
3091
|
+
slide( deserialize( state.indexh ), deserialize( state.indexv ), deserialize( state.indexf ) );
|
|
3092
|
+
|
|
3093
|
+
var pausedFlag = deserialize( state.paused ),
|
|
3094
|
+
overviewFlag = deserialize( state.overview );
|
|
3095
|
+
|
|
3096
|
+
if( typeof pausedFlag === 'boolean' && pausedFlag !== isPaused() ) {
|
|
3097
|
+
togglePause( pausedFlag );
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
if( typeof overviewFlag === 'boolean' && overviewFlag !== isOverview() ) {
|
|
3101
|
+
toggleOverview( overviewFlag );
|
|
3102
|
+
}
|
|
3103
|
+
}
|
|
3104
|
+
|
|
3105
|
+
}
|
|
3106
|
+
|
|
2284
3107
|
/**
|
|
2285
3108
|
* Return a sorted fragments list, ordered by an increasing
|
|
2286
3109
|
* "data-fragment-index" attribute.
|
|
@@ -2392,6 +3215,9 @@ var Reveal = (function(){
|
|
|
2392
3215
|
element.classList.add( 'visible' );
|
|
2393
3216
|
element.classList.remove( 'current-fragment' );
|
|
2394
3217
|
|
|
3218
|
+
// Announce the fragments one by one to the Screen Reader
|
|
3219
|
+
dom.statusDiv.textContent = element.textContent;
|
|
3220
|
+
|
|
2395
3221
|
if( i === index ) {
|
|
2396
3222
|
element.classList.add( 'current-fragment' );
|
|
2397
3223
|
}
|
|
@@ -2415,6 +3241,7 @@ var Reveal = (function(){
|
|
|
2415
3241
|
}
|
|
2416
3242
|
|
|
2417
3243
|
updateControls();
|
|
3244
|
+
updateProgress();
|
|
2418
3245
|
|
|
2419
3246
|
return !!( fragmentsShown.length || fragmentsHidden.length );
|
|
2420
3247
|
|
|
@@ -2459,14 +3286,21 @@ var Reveal = (function(){
|
|
|
2459
3286
|
|
|
2460
3287
|
if( currentSlide ) {
|
|
2461
3288
|
|
|
3289
|
+
var currentFragment = currentSlide.querySelector( '.current-fragment' );
|
|
3290
|
+
|
|
3291
|
+
var fragmentAutoSlide = currentFragment ? currentFragment.getAttribute( 'data-autoslide' ) : null;
|
|
2462
3292
|
var parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null;
|
|
2463
3293
|
var slideAutoSlide = currentSlide.getAttribute( 'data-autoslide' );
|
|
2464
3294
|
|
|
2465
3295
|
// Pick value in the following priority order:
|
|
2466
|
-
// 1. Current
|
|
2467
|
-
// 2.
|
|
2468
|
-
// 3.
|
|
2469
|
-
|
|
3296
|
+
// 1. Current fragment's data-autoslide
|
|
3297
|
+
// 2. Current slide's data-autoslide
|
|
3298
|
+
// 3. Parent slide's data-autoslide
|
|
3299
|
+
// 4. Global autoSlide setting
|
|
3300
|
+
if( fragmentAutoSlide ) {
|
|
3301
|
+
autoSlide = parseInt( fragmentAutoSlide, 10 );
|
|
3302
|
+
}
|
|
3303
|
+
else if( slideAutoSlide ) {
|
|
2470
3304
|
autoSlide = parseInt( slideAutoSlide, 10 );
|
|
2471
3305
|
}
|
|
2472
3306
|
else if( parentAutoSlide ) {
|
|
@@ -2493,7 +3327,7 @@ var Reveal = (function(){
|
|
|
2493
3327
|
// - The presentation isn't paused
|
|
2494
3328
|
// - The overview isn't active
|
|
2495
3329
|
// - The presentation isn't over
|
|
2496
|
-
if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || config.loop === true ) ) {
|
|
3330
|
+
if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || availableFragments().next || config.loop === true ) ) {
|
|
2497
3331
|
autoSlideTimeout = setTimeout( navigateNext, autoSlide );
|
|
2498
3332
|
autoSlideStartTime = Date.now();
|
|
2499
3333
|
}
|
|
@@ -2518,19 +3352,25 @@ var Reveal = (function(){
|
|
|
2518
3352
|
|
|
2519
3353
|
function pauseAutoSlide() {
|
|
2520
3354
|
|
|
2521
|
-
autoSlidePaused
|
|
2522
|
-
|
|
3355
|
+
if( autoSlide && !autoSlidePaused ) {
|
|
3356
|
+
autoSlidePaused = true;
|
|
3357
|
+
dispatchEvent( 'autoslidepaused' );
|
|
3358
|
+
clearTimeout( autoSlideTimeout );
|
|
2523
3359
|
|
|
2524
|
-
|
|
2525
|
-
|
|
3360
|
+
if( autoSlidePlayer ) {
|
|
3361
|
+
autoSlidePlayer.setPlaying( false );
|
|
3362
|
+
}
|
|
2526
3363
|
}
|
|
2527
3364
|
|
|
2528
3365
|
}
|
|
2529
3366
|
|
|
2530
3367
|
function resumeAutoSlide() {
|
|
2531
3368
|
|
|
2532
|
-
autoSlidePaused
|
|
2533
|
-
|
|
3369
|
+
if( autoSlide && autoSlidePaused ) {
|
|
3370
|
+
autoSlidePaused = false;
|
|
3371
|
+
dispatchEvent( 'autoslideresumed' );
|
|
3372
|
+
cueAutoSlide();
|
|
3373
|
+
}
|
|
2534
3374
|
|
|
2535
3375
|
}
|
|
2536
3376
|
|
|
@@ -2597,7 +3437,14 @@ var Reveal = (function(){
|
|
|
2597
3437
|
}
|
|
2598
3438
|
else {
|
|
2599
3439
|
// Fetch the previous horizontal slide, if there is one
|
|
2600
|
-
var previousSlide
|
|
3440
|
+
var previousSlide;
|
|
3441
|
+
|
|
3442
|
+
if( config.rtl ) {
|
|
3443
|
+
previousSlide = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.future' ) ).pop();
|
|
3444
|
+
}
|
|
3445
|
+
else {
|
|
3446
|
+
previousSlide = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.past' ) ).pop();
|
|
3447
|
+
}
|
|
2601
3448
|
|
|
2602
3449
|
if( previousSlide ) {
|
|
2603
3450
|
var v = ( previousSlide.querySelectorAll( 'section' ).length - 1 ) || undefined;
|
|
@@ -2610,13 +3457,21 @@ var Reveal = (function(){
|
|
|
2610
3457
|
}
|
|
2611
3458
|
|
|
2612
3459
|
/**
|
|
2613
|
-
*
|
|
3460
|
+
* The reverse of #navigatePrev().
|
|
2614
3461
|
*/
|
|
2615
3462
|
function navigateNext() {
|
|
2616
3463
|
|
|
2617
3464
|
// Prioritize revealing fragments
|
|
2618
3465
|
if( nextFragment() === false ) {
|
|
2619
|
-
availableRoutes().down
|
|
3466
|
+
if( availableRoutes().down ) {
|
|
3467
|
+
navigateDown();
|
|
3468
|
+
}
|
|
3469
|
+
else if( config.rtl ) {
|
|
3470
|
+
navigateLeft();
|
|
3471
|
+
}
|
|
3472
|
+
else {
|
|
3473
|
+
navigateRight();
|
|
3474
|
+
}
|
|
2620
3475
|
}
|
|
2621
3476
|
|
|
2622
3477
|
// If auto-sliding is enabled we need to cue up
|
|
@@ -2642,21 +3497,47 @@ var Reveal = (function(){
|
|
|
2642
3497
|
|
|
2643
3498
|
}
|
|
2644
3499
|
|
|
3500
|
+
/**
|
|
3501
|
+
* Handler for the document level 'keypress' event.
|
|
3502
|
+
*/
|
|
3503
|
+
function onDocumentKeyPress( event ) {
|
|
3504
|
+
|
|
3505
|
+
// Check if the pressed key is question mark
|
|
3506
|
+
if( event.shiftKey && event.charCode === 63 ) {
|
|
3507
|
+
if( dom.overlay ) {
|
|
3508
|
+
closeOverlay();
|
|
3509
|
+
}
|
|
3510
|
+
else {
|
|
3511
|
+
showHelp( true );
|
|
3512
|
+
}
|
|
3513
|
+
}
|
|
3514
|
+
|
|
3515
|
+
}
|
|
3516
|
+
|
|
2645
3517
|
/**
|
|
2646
3518
|
* Handler for the document level 'keydown' event.
|
|
2647
3519
|
*/
|
|
2648
3520
|
function onDocumentKeyDown( event ) {
|
|
2649
3521
|
|
|
3522
|
+
// If there's a condition specified and it returns false,
|
|
3523
|
+
// ignore this event
|
|
3524
|
+
if( typeof config.keyboardCondition === 'function' && config.keyboardCondition() === false ) {
|
|
3525
|
+
return true;
|
|
3526
|
+
}
|
|
3527
|
+
|
|
3528
|
+
// Remember if auto-sliding was paused so we can toggle it
|
|
3529
|
+
var autoSlideWasPaused = autoSlidePaused;
|
|
3530
|
+
|
|
2650
3531
|
onUserInput( event );
|
|
2651
3532
|
|
|
2652
3533
|
// Check if there's a focused element that could be using
|
|
2653
3534
|
// the keyboard
|
|
2654
|
-
var
|
|
2655
|
-
var
|
|
3535
|
+
var activeElementIsCE = document.activeElement && document.activeElement.contentEditable !== 'inherit';
|
|
3536
|
+
var activeElementIsInput = document.activeElement && document.activeElement.tagName && /input|textarea/i.test( document.activeElement.tagName );
|
|
2656
3537
|
|
|
2657
3538
|
// Disregard the event if there's a focused element or a
|
|
2658
3539
|
// keyboard modifier key is present
|
|
2659
|
-
if(
|
|
3540
|
+
if( activeElementIsCE || activeElementIsInput || (event.shiftKey && event.keyCode !== 32) || event.altKey || event.ctrlKey || event.metaKey ) return;
|
|
2660
3541
|
|
|
2661
3542
|
// While paused only allow "unpausing" keyboard events (b and .)
|
|
2662
3543
|
if( isPaused() && [66,190,191].indexOf( event.keyCode ) === -1 ) {
|
|
@@ -2719,10 +3600,12 @@ var Reveal = (function(){
|
|
|
2719
3600
|
case 32: isOverview() ? deactivateOverview() : event.shiftKey ? navigatePrev() : navigateNext(); break;
|
|
2720
3601
|
// return
|
|
2721
3602
|
case 13: isOverview() ? deactivateOverview() : triggered = false; break;
|
|
2722
|
-
// b, period, Logitech presenter tools "black screen" button
|
|
2723
|
-
case 66: case 190: case 191: togglePause(); break;
|
|
3603
|
+
// two-spot, semicolon, b, period, Logitech presenter tools "black screen" button
|
|
3604
|
+
case 58: case 59: case 66: case 190: case 191: togglePause(); break;
|
|
2724
3605
|
// f
|
|
2725
3606
|
case 70: enterFullscreen(); break;
|
|
3607
|
+
// a
|
|
3608
|
+
case 65: if ( config.autoSlideStoppable ) toggleAutoSlide( autoSlideWasPaused ); break;
|
|
2726
3609
|
default:
|
|
2727
3610
|
triggered = false;
|
|
2728
3611
|
}
|
|
@@ -2732,18 +3615,18 @@ var Reveal = (function(){
|
|
|
2732
3615
|
// If the input resulted in a triggered action we should prevent
|
|
2733
3616
|
// the browsers default behavior
|
|
2734
3617
|
if( triggered ) {
|
|
2735
|
-
event.preventDefault();
|
|
3618
|
+
event.preventDefault && event.preventDefault();
|
|
2736
3619
|
}
|
|
2737
3620
|
// ESC or O key
|
|
2738
3621
|
else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && features.transforms3d ) {
|
|
2739
|
-
if( dom.
|
|
2740
|
-
|
|
3622
|
+
if( dom.overlay ) {
|
|
3623
|
+
closeOverlay();
|
|
2741
3624
|
}
|
|
2742
3625
|
else {
|
|
2743
3626
|
toggleOverview();
|
|
2744
3627
|
}
|
|
2745
3628
|
|
|
2746
|
-
event.preventDefault();
|
|
3629
|
+
event.preventDefault && event.preventDefault();
|
|
2747
3630
|
}
|
|
2748
3631
|
|
|
2749
3632
|
// If auto-sliding is enabled we need to cue up
|
|
@@ -2877,7 +3760,7 @@ var Reveal = (function(){
|
|
|
2877
3760
|
*/
|
|
2878
3761
|
function onPointerDown( event ) {
|
|
2879
3762
|
|
|
2880
|
-
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH ) {
|
|
3763
|
+
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
|
|
2881
3764
|
event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
|
|
2882
3765
|
onTouchStart( event );
|
|
2883
3766
|
}
|
|
@@ -2889,7 +3772,7 @@ var Reveal = (function(){
|
|
|
2889
3772
|
*/
|
|
2890
3773
|
function onPointerMove( event ) {
|
|
2891
3774
|
|
|
2892
|
-
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH )
|
|
3775
|
+
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
|
|
2893
3776
|
event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
|
|
2894
3777
|
onTouchMove( event );
|
|
2895
3778
|
}
|
|
@@ -2901,7 +3784,7 @@ var Reveal = (function(){
|
|
|
2901
3784
|
*/
|
|
2902
3785
|
function onPointerUp( event ) {
|
|
2903
3786
|
|
|
2904
|
-
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH )
|
|
3787
|
+
if( event.pointerType === event.MSPOINTER_TYPE_TOUCH || event.pointerType === "touch" ) {
|
|
2905
3788
|
event.touches = [{ clientX: event.clientX, clientY: event.clientY }];
|
|
2906
3789
|
onTouchEnd( event );
|
|
2907
3790
|
}
|
|
@@ -2942,7 +3825,7 @@ var Reveal = (function(){
|
|
|
2942
3825
|
|
|
2943
3826
|
event.preventDefault();
|
|
2944
3827
|
|
|
2945
|
-
var slidesTotal = toArray(
|
|
3828
|
+
var slidesTotal = toArray( dom.wrapper.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).length;
|
|
2946
3829
|
var slideIndex = Math.floor( ( event.clientX / dom.wrapper.offsetWidth ) * slidesTotal );
|
|
2947
3830
|
|
|
2948
3831
|
slide( slideIndex );
|
|
@@ -3033,10 +3916,12 @@ var Reveal = (function(){
|
|
|
3033
3916
|
*/
|
|
3034
3917
|
function onPreviewLinkClicked( event ) {
|
|
3035
3918
|
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3919
|
+
if( event.currentTarget && event.currentTarget.hasAttribute( 'href' ) ) {
|
|
3920
|
+
var url = event.currentTarget.getAttribute( 'href' );
|
|
3921
|
+
if( url ) {
|
|
3922
|
+
showPreview( url );
|
|
3923
|
+
event.preventDefault();
|
|
3924
|
+
}
|
|
3040
3925
|
}
|
|
3041
3926
|
|
|
3042
3927
|
}
|
|
@@ -3232,7 +4117,7 @@ var Reveal = (function(){
|
|
|
3232
4117
|
// --------------------------------------------------------------------//
|
|
3233
4118
|
|
|
3234
4119
|
|
|
3235
|
-
|
|
4120
|
+
Reveal = {
|
|
3236
4121
|
initialize: initialize,
|
|
3237
4122
|
configure: configure,
|
|
3238
4123
|
sync: sync,
|
|
@@ -3275,28 +4160,35 @@ var Reveal = (function(){
|
|
|
3275
4160
|
// Toggles the "black screen" mode on/off
|
|
3276
4161
|
togglePause: togglePause,
|
|
3277
4162
|
|
|
4163
|
+
// Toggles the auto slide mode on/off
|
|
4164
|
+
toggleAutoSlide: toggleAutoSlide,
|
|
4165
|
+
|
|
3278
4166
|
// State checks
|
|
3279
4167
|
isOverview: isOverview,
|
|
3280
4168
|
isPaused: isPaused,
|
|
4169
|
+
isAutoSliding: isAutoSliding,
|
|
3281
4170
|
|
|
3282
4171
|
// Adds or removes all internal event listeners (such as keyboard)
|
|
3283
4172
|
addEventListeners: addEventListeners,
|
|
3284
4173
|
removeEventListeners: removeEventListeners,
|
|
3285
4174
|
|
|
4175
|
+
// Facility for persisting and restoring the presentation state
|
|
4176
|
+
getState: getState,
|
|
4177
|
+
setState: setState,
|
|
4178
|
+
|
|
4179
|
+
// Presentation progress on range of 0-1
|
|
4180
|
+
getProgress: getProgress,
|
|
4181
|
+
|
|
3286
4182
|
// Returns the indices of the current, or specified, slide
|
|
3287
4183
|
getIndices: getIndices,
|
|
3288
4184
|
|
|
3289
|
-
|
|
3290
|
-
getSlide: function( x, y ) {
|
|
3291
|
-
var horizontalSlide = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR )[ x ];
|
|
3292
|
-
var verticalSlides = horizontalSlide && horizontalSlide.querySelectorAll( 'section' );
|
|
4185
|
+
getTotalSlides: getTotalSlides,
|
|
3293
4186
|
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
}
|
|
4187
|
+
// Returns the slide element at the specified index
|
|
4188
|
+
getSlide: getSlide,
|
|
3297
4189
|
|
|
3298
|
-
|
|
3299
|
-
|
|
4190
|
+
// Returns the slide background element at the specified index
|
|
4191
|
+
getSlideBackground: getSlideBackground,
|
|
3300
4192
|
|
|
3301
4193
|
// Returns the previous slide element, may be null
|
|
3302
4194
|
getPreviousSlide: function() {
|
|
@@ -3330,12 +4222,7 @@ var Reveal = (function(){
|
|
|
3330
4222
|
for( var i in query ) {
|
|
3331
4223
|
var value = query[ i ];
|
|
3332
4224
|
|
|
3333
|
-
query[ i ] = unescape( value );
|
|
3334
|
-
|
|
3335
|
-
if( value === 'null' ) query[ i ] = null;
|
|
3336
|
-
else if( value === 'true' ) query[ i ] = true;
|
|
3337
|
-
else if( value === 'false' ) query[ i ] = false;
|
|
3338
|
-
else if( value.match( /^\d+$/ ) ) query[ i ] = parseFloat( value );
|
|
4225
|
+
query[ i ] = deserialize( unescape( value ) );
|
|
3339
4226
|
}
|
|
3340
4227
|
|
|
3341
4228
|
return query;
|
|
@@ -3343,7 +4230,7 @@ var Reveal = (function(){
|
|
|
3343
4230
|
|
|
3344
4231
|
// Returns true if we're currently on the first slide
|
|
3345
4232
|
isFirstSlide: function() {
|
|
3346
|
-
return
|
|
4233
|
+
return ( indexh === 0 && indexv === 0 );
|
|
3347
4234
|
},
|
|
3348
4235
|
|
|
3349
4236
|
// Returns true if we're currently on the last slide
|
|
@@ -3376,7 +4263,14 @@ var Reveal = (function(){
|
|
|
3376
4263
|
if( 'addEventListener' in window ) {
|
|
3377
4264
|
( dom.wrapper || document.querySelector( '.reveal' ) ).removeEventListener( type, listener, useCapture );
|
|
3378
4265
|
}
|
|
4266
|
+
},
|
|
4267
|
+
|
|
4268
|
+
// Programatically triggers a keyboard event
|
|
4269
|
+
triggerKey: function( keyCode ) {
|
|
4270
|
+
onDocumentKeyDown( { keyCode: keyCode } );
|
|
3379
4271
|
}
|
|
3380
4272
|
};
|
|
3381
4273
|
|
|
3382
|
-
|
|
4274
|
+
return Reveal;
|
|
4275
|
+
|
|
4276
|
+
}));
|