slippery 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/assets/deck.js/core/deck.core.css +60 -0
- data/assets/deck.js/core/deck.core.js +728 -0
- data/assets/deck.js/core/deck.core.scss +65 -0
- data/assets/deck.js/core/print.css +25 -0
- data/assets/deck.js/core/print.scss +14 -0
- data/assets/deck.js/css/common.css +216 -0
- data/assets/deck.js/css/common.scss +233 -0
- data/assets/deck.js/css/home.css +790 -0
- data/assets/deck.js/css/home.scss +892 -0
- data/assets/deck.js/extensions/goto/deck.goto.css +36 -0
- data/assets/deck.js/extensions/goto/deck.goto.html +7 -0
- data/assets/deck.js/extensions/goto/deck.goto.js +190 -0
- data/assets/deck.js/extensions/goto/deck.goto.scss +39 -0
- data/assets/deck.js/extensions/hash/deck.hash.css +13 -0
- data/assets/deck.js/extensions/hash/deck.hash.html +2 -0
- data/assets/deck.js/extensions/hash/deck.hash.js +145 -0
- data/assets/deck.js/extensions/hash/deck.hash.scss +13 -0
- data/assets/deck.js/extensions/menu/deck.menu.css +45 -0
- data/assets/deck.js/extensions/menu/deck.menu.js +225 -0
- data/assets/deck.js/extensions/menu/deck.menu.scss +55 -0
- data/assets/deck.js/extensions/navigation/deck.navigation.css +42 -0
- data/assets/deck.js/extensions/navigation/deck.navigation.html +5 -0
- data/assets/deck.js/extensions/navigation/deck.navigation.js +94 -0
- data/assets/deck.js/extensions/navigation/deck.navigation.scss +44 -0
- data/assets/deck.js/extensions/scale/deck.scale.css +20 -0
- data/assets/deck.js/extensions/scale/deck.scale.js +190 -0
- data/assets/deck.js/extensions/scale/deck.scale.scss +22 -0
- data/assets/deck.js/extensions/status/deck.status.css +18 -0
- data/assets/deck.js/extensions/status/deck.status.html +6 -0
- data/assets/deck.js/extensions/status/deck.status.js +108 -0
- data/assets/deck.js/extensions/status/deck.status.scss +18 -0
- data/assets/deck.js/modernizr.custom.js +4 -0
- data/assets/deck.js/themes/style/_reset.scss +300 -0
- data/assets/deck.js/themes/style/neon.css +421 -0
- data/assets/deck.js/themes/style/neon.scss +148 -0
- data/assets/deck.js/themes/style/swiss.css +389 -0
- data/assets/deck.js/themes/style/swiss.scss +109 -0
- data/assets/deck.js/themes/style/web-2.0.css +500 -0
- data/assets/deck.js/themes/style/web-2.0.scss +228 -0
- data/assets/deck.js/themes/transition/fade.css +35 -0
- data/assets/deck.js/themes/transition/fade.scss +59 -0
- data/assets/deck.js/themes/transition/horizontal-slide.css +53 -0
- data/assets/deck.js/themes/transition/horizontal-slide.scss +72 -0
- data/assets/deck.js/themes/transition/vertical-slide.css +67 -0
- data/assets/deck.js/themes/transition/vertical-slide.scss +92 -0
- data/assets/highlight.js/CHANGES.md +953 -0
- data/assets/highlight.js/LICENSE +24 -0
- data/assets/highlight.js/README.md +101 -0
- data/assets/highlight.js/README.ru.md +101 -0
- data/assets/highlight.js/highlight-0.8.default.min.css +1 -0
- data/assets/highlight.js/highlight-0.8.min.js +1 -0
- data/assets/highlight.js/highlight.pack.js +1 -0
- data/assets/highlight.js/styles/arta.css +141 -0
- data/assets/highlight.js/styles/ascetic.css +53 -0
- data/assets/highlight.js/styles/atelier-dune.dark.css +95 -0
- data/assets/highlight.js/styles/atelier-dune.light.css +95 -0
- data/assets/highlight.js/styles/atelier-forest.dark.css +95 -0
- data/assets/highlight.js/styles/atelier-forest.light.css +95 -0
- data/assets/highlight.js/styles/atelier-heath.dark.css +95 -0
- data/assets/highlight.js/styles/atelier-heath.light.css +95 -0
- data/assets/highlight.js/styles/atelier-lakeside.dark.css +95 -0
- data/assets/highlight.js/styles/atelier-lakeside.light.css +95 -0
- data/assets/highlight.js/styles/atelier-seaside.dark.css +95 -0
- data/assets/highlight.js/styles/atelier-seaside.light.css +95 -0
- data/assets/highlight.js/styles/brown_paper.css +105 -0
- data/assets/highlight.js/styles/brown_papersq.png +0 -0
- data/assets/highlight.js/styles/codepen-embed.css +108 -0
- data/assets/highlight.js/styles/color-brewer.css +169 -0
- data/assets/highlight.js/styles/dark.css +105 -0
- data/assets/highlight.js/styles/default.css +153 -0
- data/assets/highlight.js/styles/docco.css +136 -0
- data/assets/highlight.js/styles/far.css +112 -0
- data/assets/highlight.js/styles/foundation.css +136 -0
- data/assets/highlight.js/styles/github.css +127 -0
- data/assets/highlight.js/styles/googlecode.css +148 -0
- data/assets/highlight.js/styles/hybrid.css +171 -0
- data/assets/highlight.js/styles/idea.css +126 -0
- data/assets/highlight.js/styles/ir_black.css +110 -0
- data/assets/highlight.js/styles/kimbie.dark.css +96 -0
- data/assets/highlight.js/styles/kimbie.light.css +96 -0
- data/assets/highlight.js/styles/magula.css +122 -0
- data/assets/highlight.js/styles/mono-blue.css +70 -0
- data/assets/highlight.js/styles/monokai.css +127 -0
- data/assets/highlight.js/styles/monokai_sublime.css +148 -0
- data/assets/highlight.js/styles/obsidian.css +154 -0
- data/assets/highlight.js/styles/paraiso.dark.css +95 -0
- data/assets/highlight.js/styles/paraiso.light.css +95 -0
- data/assets/highlight.js/styles/pojoaque.css +108 -0
- data/assets/highlight.js/styles/pojoaque.jpg +0 -0
- data/assets/highlight.js/styles/railscasts.css +185 -0
- data/assets/highlight.js/styles/rainbow.css +109 -0
- data/assets/highlight.js/styles/school_book.css +113 -0
- data/assets/highlight.js/styles/school_book.png +0 -0
- data/assets/highlight.js/styles/solarized_dark.css +109 -0
- data/assets/highlight.js/styles/solarized_light.css +109 -0
- data/assets/highlight.js/styles/sunburst.css +165 -0
- data/assets/highlight.js/styles/tomorrow-night-blue.css +95 -0
- data/assets/highlight.js/styles/tomorrow-night-bright.css +94 -0
- data/assets/highlight.js/styles/tomorrow-night-eighties.css +94 -0
- data/assets/highlight.js/styles/tomorrow-night.css +95 -0
- data/assets/highlight.js/styles/tomorrow.css +92 -0
- data/assets/highlight.js/styles/vs.css +94 -0
- data/assets/highlight.js/styles/xcode.css +159 -0
- data/assets/highlight.js/styles/zenburn.css +119 -0
- data/assets/jquery/jquery-2.1.0.min.js +4 -0
- data/assets/reveal.js/css/print/paper.css +1 -1
- data/assets/reveal.js/css/print/pdf.css +2 -2
- data/assets/reveal.js/css/reveal.css +372 -108
- data/assets/reveal.js/css/reveal.min.css +2 -2
- data/assets/reveal.js/css/theme/README.md +3 -1
- data/assets/reveal.js/css/theme/beige.css +7 -1
- data/assets/reveal.js/css/theme/blood.css +175 -0
- data/assets/reveal.js/css/theme/default.css +7 -1
- data/assets/reveal.js/css/theme/moon.css +7 -1
- data/assets/reveal.js/css/theme/night.css +7 -1
- data/assets/reveal.js/css/theme/serif.css +7 -1
- data/assets/reveal.js/css/theme/simple.css +7 -1
- data/assets/reveal.js/css/theme/sky.css +7 -1
- data/assets/reveal.js/css/theme/solarized.css +7 -1
- data/assets/reveal.js/css/theme/source/blood.scss +91 -0
- data/assets/reveal.js/css/theme/template/settings.scss +1 -0
- data/assets/reveal.js/css/theme/template/theme.scss +9 -2
- data/assets/reveal.js/js/reveal.js +1238 -433
- data/assets/reveal.js/js/reveal.min.js +4 -3
- data/assets/reveal.js/lib/css/zenburn.css +16 -17
- data/assets/reveal.js/plugin/highlight/highlight.js +3 -2
- data/assets/reveal.js/plugin/leap/leap.js +3 -0
- data/assets/reveal.js/plugin/markdown/example.html +37 -5
- data/assets/reveal.js/plugin/markdown/example.md +2 -0
- data/assets/reveal.js/plugin/markdown/markdown.js +373 -171
- data/assets/reveal.js/plugin/math/math.js +64 -0
- data/assets/reveal.js/plugin/multiplex/master.js +2 -1
- data/assets/reveal.js/plugin/notes/notes.html +33 -19
- data/assets/reveal.js/plugin/notes/notes.js +25 -47
- data/assets/reveal.js/plugin/remotes/remotes.js +4 -4
- data/assets/reveal.js/plugin/zoom-js/zoom.js +3 -1
- data/assets/reveal.old/css/print/paper.css +176 -0
- data/assets/reveal.old/css/print/pdf.css +190 -0
- data/assets/reveal.old/css/reveal.css +1616 -0
- data/assets/reveal.old/css/reveal.min.css +7 -0
- data/assets/reveal.old/css/theme/README.md +23 -0
- data/assets/reveal.old/css/theme/beige.css +142 -0
- data/assets/reveal.old/css/theme/default.css +142 -0
- data/assets/reveal.old/css/theme/moon.css +142 -0
- data/assets/reveal.old/css/theme/night.css +130 -0
- data/assets/reveal.old/css/theme/serif.css +132 -0
- data/assets/reveal.old/css/theme/simple.css +132 -0
- data/assets/reveal.old/css/theme/sky.css +139 -0
- data/assets/reveal.old/css/theme/solarized.css +142 -0
- data/assets/reveal.old/css/theme/source/beige.scss +50 -0
- data/assets/reveal.old/css/theme/source/default.scss +42 -0
- data/assets/reveal.old/css/theme/source/moon.scss +68 -0
- data/assets/reveal.old/css/theme/source/night.scss +35 -0
- data/assets/reveal.old/css/theme/source/serif.scss +35 -0
- data/assets/reveal.old/css/theme/source/simple.scss +38 -0
- data/assets/reveal.old/css/theme/source/sky.scss +46 -0
- data/assets/reveal.old/css/theme/source/solarized.scss +74 -0
- data/assets/reveal.old/css/theme/template/mixins.scss +29 -0
- data/assets/reveal.old/css/theme/template/settings.scss +33 -0
- data/assets/reveal.old/css/theme/template/theme.scss +163 -0
- data/assets/{reveal.js → reveal.old}/js/head.min.js +0 -0
- data/assets/reveal.old/js/reveal.js +2577 -0
- data/assets/reveal.old/js/reveal.min.js +8 -0
- data/assets/reveal.old/lib/css/zenburn.css +115 -0
- data/assets/reveal.old/lib/font/league_gothic-webfont.eot +0 -0
- data/assets/reveal.old/lib/font/league_gothic-webfont.svg +230 -0
- data/assets/reveal.old/lib/font/league_gothic-webfont.ttf +0 -0
- data/assets/reveal.old/lib/font/league_gothic-webfont.woff +0 -0
- data/assets/reveal.old/lib/font/league_gothic_license +2 -0
- data/assets/reveal.old/lib/js/classList.js +2 -0
- data/assets/reveal.old/lib/js/head.min.js +8 -0
- data/assets/reveal.old/lib/js/html5shiv.js +7 -0
- data/assets/reveal.old/plugin/highlight/highlight.js +31 -0
- data/assets/reveal.old/plugin/leap/leap.js +154 -0
- data/assets/reveal.old/plugin/markdown/example.html +97 -0
- data/assets/reveal.old/plugin/markdown/example.md +29 -0
- data/assets/reveal.old/plugin/markdown/markdown.js +190 -0
- data/assets/reveal.old/plugin/markdown/marked.js +37 -0
- data/assets/reveal.old/plugin/multiplex/client.js +13 -0
- data/assets/reveal.old/plugin/multiplex/index.js +56 -0
- data/assets/reveal.old/plugin/multiplex/master.js +50 -0
- data/assets/reveal.old/plugin/notes-server/client.js +57 -0
- data/assets/reveal.old/plugin/notes-server/index.js +59 -0
- data/assets/reveal.old/plugin/notes-server/notes.html +142 -0
- data/assets/reveal.old/plugin/notes/notes.html +253 -0
- data/assets/reveal.old/plugin/notes/notes.js +100 -0
- data/assets/reveal.old/plugin/postmessage/example.html +39 -0
- data/assets/reveal.old/plugin/postmessage/postmessage.js +42 -0
- data/assets/reveal.old/plugin/print-pdf/print-pdf.js +44 -0
- data/assets/reveal.old/plugin/remotes/remotes.js +39 -0
- data/assets/reveal.old/plugin/search/search.js +196 -0
- data/assets/reveal.old/plugin/zoom-js/zoom.js +256 -0
- data/bin/slippery +1 -0
- data/code_of_conduct.md +32 -0
- data/lib/slippery.rb +5 -3
- data/lib/slippery/document.rb +2 -2
- data/lib/slippery/presentation.rb +10 -1
- data/lib/slippery/processor.rb +18 -0
- data/lib/slippery/processor_helpers.rb +16 -2
- data/lib/slippery/processors/add_highlight.rb +9 -2
- data/lib/slippery/processors/deck_js.rb +81 -0
- data/lib/slippery/processors/fathom_js.rb +31 -0
- data/lib/slippery/processors/impress_js/add_impress_js.rb +2 -2
- data/lib/slippery/processors/jquery.rb +12 -0
- data/lib/slippery/processors/reveal_js/add_reveal_js.rb +12 -9
- data/lib/slippery/rake_tasks.rb +59 -31
- data/lib/slippery/version.rb +1 -1
- data/slippery.gemspec +5 -4
- metadata +215 -33
- data/lib/slippery/converter.rb +0 -132
|
@@ -12,7 +12,7 @@ body {
|
|
|
12
12
|
.reveal {
|
|
13
13
|
font-family: $mainFont;
|
|
14
14
|
font-size: $mainFontSize;
|
|
15
|
-
font-weight:
|
|
15
|
+
font-weight: normal;
|
|
16
16
|
letter-spacing: -0.02em;
|
|
17
17
|
color: $mainColor;
|
|
18
18
|
}
|
|
@@ -33,7 +33,7 @@ body {
|
|
|
33
33
|
.reveal h4,
|
|
34
34
|
.reveal h5,
|
|
35
35
|
.reveal h6 {
|
|
36
|
-
margin:
|
|
36
|
+
margin: $headingMargin;
|
|
37
37
|
color: $headingColor;
|
|
38
38
|
|
|
39
39
|
font-family: $headingFont;
|
|
@@ -160,4 +160,11 @@ body {
|
|
|
160
160
|
transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
/*********************************************
|
|
164
|
+
* SLIDE NUMBER
|
|
165
|
+
*********************************************/
|
|
166
|
+
.reveal .slide-number {
|
|
167
|
+
color: $linkColor;
|
|
168
|
+
}
|
|
169
|
+
|
|
163
170
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* http://lab.hakim.se/reveal-js
|
|
4
4
|
* MIT licensed
|
|
5
5
|
*
|
|
6
|
-
* Copyright (C)
|
|
6
|
+
* Copyright (C) 2014 Hakim El Hattab, http://hakim.se
|
|
7
7
|
*/
|
|
8
8
|
var Reveal = (function(){
|
|
9
9
|
|
|
@@ -12,7 +12,7 @@ var Reveal = (function(){
|
|
|
12
12
|
var SLIDES_SELECTOR = '.reveal .slides section',
|
|
13
13
|
HORIZONTAL_SLIDES_SELECTOR = '.reveal .slides>section',
|
|
14
14
|
VERTICAL_SLIDES_SELECTOR = '.reveal .slides>section.present>section',
|
|
15
|
-
HOME_SLIDE_SELECTOR = '.reveal .slides>section:first-
|
|
15
|
+
HOME_SLIDE_SELECTOR = '.reveal .slides>section:first-of-type',
|
|
16
16
|
|
|
17
17
|
// Configurations defaults, can be overridden at initialization time
|
|
18
18
|
config = {
|
|
@@ -35,6 +35,9 @@ var Reveal = (function(){
|
|
|
35
35
|
// Display a presentation progress bar
|
|
36
36
|
progress: true,
|
|
37
37
|
|
|
38
|
+
// Display the page number of the current slide
|
|
39
|
+
slideNumber: false,
|
|
40
|
+
|
|
38
41
|
// Push each slide change to the browser history
|
|
39
42
|
history: false,
|
|
40
43
|
|
|
@@ -44,7 +47,7 @@ var Reveal = (function(){
|
|
|
44
47
|
// Enable the slide overview mode
|
|
45
48
|
overview: true,
|
|
46
49
|
|
|
47
|
-
// Vertical
|
|
50
|
+
// Vertical centering of slides
|
|
48
51
|
center: true,
|
|
49
52
|
|
|
50
53
|
// Enables touch navigation on devices with touch input
|
|
@@ -59,20 +62,33 @@ var Reveal = (function(){
|
|
|
59
62
|
// Turns fragments on and off globally
|
|
60
63
|
fragments: true,
|
|
61
64
|
|
|
65
|
+
// Flags if the presentation is running in an embedded mode,
|
|
66
|
+
// i.e. contained within a limited portion of the screen
|
|
67
|
+
embedded: false,
|
|
68
|
+
|
|
62
69
|
// Number of milliseconds between automatically proceeding to the
|
|
63
70
|
// next slide, disabled when set to 0, this value can be overwritten
|
|
64
71
|
// by using a data-autoslide attribute on your slides
|
|
65
72
|
autoSlide: 0,
|
|
66
73
|
|
|
74
|
+
// Stop auto-sliding after user input
|
|
75
|
+
autoSlideStoppable: true,
|
|
76
|
+
|
|
67
77
|
// Enable slide navigation via mouse wheel
|
|
68
78
|
mouseWheel: false,
|
|
69
79
|
|
|
70
80
|
// Apply a 3D roll to links on hover
|
|
71
|
-
rollingLinks:
|
|
81
|
+
rollingLinks: false,
|
|
82
|
+
|
|
83
|
+
// Hides the address bar on mobile devices
|
|
84
|
+
hideAddressBar: true,
|
|
72
85
|
|
|
73
86
|
// Opens links in an iframe preview overlay
|
|
74
87
|
previewLinks: false,
|
|
75
88
|
|
|
89
|
+
// Focuses body when page changes visiblity to ensure keyboard shortcuts work
|
|
90
|
+
focusBodyOnPageVisiblityChange: true,
|
|
91
|
+
|
|
76
92
|
// Theme (see /css/theme)
|
|
77
93
|
theme: null,
|
|
78
94
|
|
|
@@ -83,23 +99,35 @@ var Reveal = (function(){
|
|
|
83
99
|
transitionSpeed: 'default', // default/fast/slow
|
|
84
100
|
|
|
85
101
|
// Transition style for full page slide backgrounds
|
|
86
|
-
backgroundTransition: 'default', // default/linear
|
|
102
|
+
backgroundTransition: 'default', // default/linear/none
|
|
103
|
+
|
|
104
|
+
// Parallax background image
|
|
105
|
+
parallaxBackgroundImage: '', // CSS syntax, e.g. "a.jpg"
|
|
106
|
+
|
|
107
|
+
// Parallax background size
|
|
108
|
+
parallaxBackgroundSize: '', // CSS syntax, e.g. "3000px 2000px"
|
|
109
|
+
|
|
110
|
+
// Number of slides away from the current that are visible
|
|
111
|
+
viewDistance: 3,
|
|
87
112
|
|
|
88
113
|
// Script dependencies to load
|
|
89
114
|
dependencies: []
|
|
115
|
+
|
|
90
116
|
},
|
|
91
117
|
|
|
92
|
-
//
|
|
93
|
-
|
|
118
|
+
// Flags if reveal.js is loaded (has dispatched the 'ready' event)
|
|
119
|
+
loaded = false,
|
|
94
120
|
|
|
95
121
|
// The horizontal and vertical index of the currently active slide
|
|
96
|
-
indexh
|
|
97
|
-
indexv
|
|
122
|
+
indexh,
|
|
123
|
+
indexv,
|
|
98
124
|
|
|
99
125
|
// The previous and current slide HTML elements
|
|
100
126
|
previousSlide,
|
|
101
127
|
currentSlide,
|
|
102
128
|
|
|
129
|
+
previousBackground,
|
|
130
|
+
|
|
103
131
|
// Slides may hold a data-state attribute which we pick up and apply
|
|
104
132
|
// as a class to the body. This list contains the combined state of
|
|
105
133
|
// all current slides.
|
|
@@ -111,26 +139,15 @@ var Reveal = (function(){
|
|
|
111
139
|
// Cached references to DOM elements
|
|
112
140
|
dom = {},
|
|
113
141
|
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
'MozPerspective' in document.body.style ||
|
|
117
|
-
'msPerspective' in document.body.style ||
|
|
118
|
-
'OPerspective' in document.body.style ||
|
|
119
|
-
'perspective' in document.body.style,
|
|
142
|
+
// Features supported by the browser, see #checkCapabilities()
|
|
143
|
+
features = {},
|
|
120
144
|
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
'MozTransform' in document.body.style ||
|
|
124
|
-
'msTransform' in document.body.style ||
|
|
125
|
-
'OTransform' in document.body.style ||
|
|
126
|
-
'transform' in document.body.style,
|
|
145
|
+
// Client is a mobile device, see #checkCapabilities()
|
|
146
|
+
isMobileDevice,
|
|
127
147
|
|
|
128
148
|
// Throttles mouse wheel navigation
|
|
129
149
|
lastMouseWheelStep = 0,
|
|
130
150
|
|
|
131
|
-
// An interval used to automatically move on to the next slide
|
|
132
|
-
autoSlideTimeout = 0,
|
|
133
|
-
|
|
134
151
|
// Delays updates to the URL due to a Chrome thumbnailer bug
|
|
135
152
|
writeURLTimeout = 0,
|
|
136
153
|
|
|
@@ -143,14 +160,23 @@ var Reveal = (function(){
|
|
|
143
160
|
// Flags if the interaction event listeners are bound
|
|
144
161
|
eventsAreBound = false,
|
|
145
162
|
|
|
163
|
+
// The current auto-slide duration
|
|
164
|
+
autoSlide = 0,
|
|
165
|
+
|
|
166
|
+
// Auto slide properties
|
|
167
|
+
autoSlidePlayer,
|
|
168
|
+
autoSlideTimeout = 0,
|
|
169
|
+
autoSlideStartTime = -1,
|
|
170
|
+
autoSlidePaused = false,
|
|
171
|
+
|
|
146
172
|
// Holds information about the currently ongoing touch input
|
|
147
173
|
touch = {
|
|
148
174
|
startX: 0,
|
|
149
175
|
startY: 0,
|
|
150
176
|
startSpan: 0,
|
|
151
177
|
startCount: 0,
|
|
152
|
-
|
|
153
|
-
threshold:
|
|
178
|
+
captured: false,
|
|
179
|
+
threshold: 40
|
|
154
180
|
};
|
|
155
181
|
|
|
156
182
|
/**
|
|
@@ -158,7 +184,9 @@ var Reveal = (function(){
|
|
|
158
184
|
*/
|
|
159
185
|
function initialize( options ) {
|
|
160
186
|
|
|
161
|
-
|
|
187
|
+
checkCapabilities();
|
|
188
|
+
|
|
189
|
+
if( !features.transforms2d && !features.transforms3d ) {
|
|
162
190
|
document.body.setAttribute( 'class', 'no-transforms' );
|
|
163
191
|
|
|
164
192
|
// If the browser doesn't support core features we won't be
|
|
@@ -169,8 +197,15 @@ var Reveal = (function(){
|
|
|
169
197
|
// Force a layout when the whole page, incl fonts, has loaded
|
|
170
198
|
window.addEventListener( 'load', layout, false );
|
|
171
199
|
|
|
200
|
+
var query = Reveal.getQueryHash();
|
|
201
|
+
|
|
202
|
+
// Do not accept new dependencies via query config to avoid
|
|
203
|
+
// the potential of malicious script injection
|
|
204
|
+
if( typeof query['dependencies'] !== 'undefined' ) delete query['dependencies'];
|
|
205
|
+
|
|
172
206
|
// Copy options over to our config object
|
|
173
207
|
extend( config, options );
|
|
208
|
+
extend( config, query );
|
|
174
209
|
|
|
175
210
|
// Hide the address bar in mobile browsers
|
|
176
211
|
hideAddressBar();
|
|
@@ -180,6 +215,136 @@ var Reveal = (function(){
|
|
|
180
215
|
|
|
181
216
|
}
|
|
182
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Inspect the client to see what it's capable of, this
|
|
220
|
+
* should only happens once per runtime.
|
|
221
|
+
*/
|
|
222
|
+
function checkCapabilities() {
|
|
223
|
+
|
|
224
|
+
features.transforms3d = 'WebkitPerspective' in document.body.style ||
|
|
225
|
+
'MozPerspective' in document.body.style ||
|
|
226
|
+
'msPerspective' in document.body.style ||
|
|
227
|
+
'OPerspective' in document.body.style ||
|
|
228
|
+
'perspective' in document.body.style;
|
|
229
|
+
|
|
230
|
+
features.transforms2d = 'WebkitTransform' in document.body.style ||
|
|
231
|
+
'MozTransform' in document.body.style ||
|
|
232
|
+
'msTransform' in document.body.style ||
|
|
233
|
+
'OTransform' in document.body.style ||
|
|
234
|
+
'transform' in document.body.style;
|
|
235
|
+
|
|
236
|
+
features.requestAnimationFrameMethod = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
|
|
237
|
+
features.requestAnimationFrame = typeof features.requestAnimationFrameMethod === 'function';
|
|
238
|
+
|
|
239
|
+
features.canvas = !!document.createElement( 'canvas' ).getContext;
|
|
240
|
+
|
|
241
|
+
isMobileDevice = navigator.userAgent.match( /(iphone|ipod|android)/gi );
|
|
242
|
+
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Loads the dependencies of reveal.js. Dependencies are
|
|
248
|
+
* defined via the configuration option 'dependencies'
|
|
249
|
+
* and will be loaded prior to starting/binding reveal.js.
|
|
250
|
+
* Some dependencies may have an 'async' flag, if so they
|
|
251
|
+
* will load after reveal.js has been started up.
|
|
252
|
+
*/
|
|
253
|
+
function load() {
|
|
254
|
+
|
|
255
|
+
var scripts = [],
|
|
256
|
+
scriptsAsync = [],
|
|
257
|
+
scriptsToPreload = 0;
|
|
258
|
+
|
|
259
|
+
// Called once synchronous scripts finish loading
|
|
260
|
+
function proceed() {
|
|
261
|
+
if( scriptsAsync.length ) {
|
|
262
|
+
// Load asynchronous scripts
|
|
263
|
+
head.js.apply( null, scriptsAsync );
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
start();
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function loadScript( s ) {
|
|
270
|
+
head.ready( s.src.match( /([\w\d_\-]*)\.?js$|[^\\\/]*$/i )[0], function() {
|
|
271
|
+
// Extension may contain callback functions
|
|
272
|
+
if( typeof s.callback === 'function' ) {
|
|
273
|
+
s.callback.apply( this );
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if( --scriptsToPreload === 0 ) {
|
|
277
|
+
proceed();
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
for( var i = 0, len = config.dependencies.length; i < len; i++ ) {
|
|
283
|
+
var s = config.dependencies[i];
|
|
284
|
+
|
|
285
|
+
// Load if there's no condition or the condition is truthy
|
|
286
|
+
if( !s.condition || s.condition() ) {
|
|
287
|
+
if( s.async ) {
|
|
288
|
+
scriptsAsync.push( s.src );
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
scripts.push( s.src );
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
loadScript( s );
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if( scripts.length ) {
|
|
299
|
+
scriptsToPreload = scripts.length;
|
|
300
|
+
|
|
301
|
+
// Load synchronous scripts
|
|
302
|
+
head.js.apply( null, scripts );
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
proceed();
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Starts up reveal.js by binding input events and navigating
|
|
312
|
+
* to the current URL deeplink if there is one.
|
|
313
|
+
*/
|
|
314
|
+
function start() {
|
|
315
|
+
|
|
316
|
+
// Make sure we've got all the DOM elements we need
|
|
317
|
+
setupDOM();
|
|
318
|
+
|
|
319
|
+
// Resets all vertical slides so that only the first is visible
|
|
320
|
+
resetVerticalSlides();
|
|
321
|
+
|
|
322
|
+
// Updates the presentation to match the current configuration values
|
|
323
|
+
configure();
|
|
324
|
+
|
|
325
|
+
// Read the initial hash
|
|
326
|
+
readURL();
|
|
327
|
+
|
|
328
|
+
// Update all backgrounds
|
|
329
|
+
updateBackground( true );
|
|
330
|
+
|
|
331
|
+
// Notify listeners that the presentation is ready but use a 1ms
|
|
332
|
+
// timeout to ensure it's not fired synchronously after #initialize()
|
|
333
|
+
setTimeout( function() {
|
|
334
|
+
// Enable transitions now that we're loaded
|
|
335
|
+
dom.slides.classList.remove( 'no-transition' );
|
|
336
|
+
|
|
337
|
+
loaded = true;
|
|
338
|
+
|
|
339
|
+
dispatchEvent( 'ready', {
|
|
340
|
+
'indexh': indexh,
|
|
341
|
+
'indexv': indexv,
|
|
342
|
+
'currentSlide': currentSlide
|
|
343
|
+
} );
|
|
344
|
+
}, 1 );
|
|
345
|
+
|
|
346
|
+
}
|
|
347
|
+
|
|
183
348
|
/**
|
|
184
349
|
* Finds and stores references to DOM elements which are
|
|
185
350
|
* required by the presentation. If a required element is
|
|
@@ -192,61 +357,62 @@ var Reveal = (function(){
|
|
|
192
357
|
dom.wrapper = document.querySelector( '.reveal' );
|
|
193
358
|
dom.slides = document.querySelector( '.reveal .slides' );
|
|
194
359
|
|
|
360
|
+
// Prevent transitions while we're loading
|
|
361
|
+
dom.slides.classList.add( 'no-transition' );
|
|
362
|
+
|
|
195
363
|
// Background element
|
|
196
|
-
|
|
197
|
-
dom.background = document.createElement( 'div' );
|
|
198
|
-
dom.background.classList.add( 'backgrounds' );
|
|
199
|
-
dom.wrapper.appendChild( dom.background );
|
|
200
|
-
}
|
|
364
|
+
dom.background = createSingletonNode( dom.wrapper, 'div', 'backgrounds', null );
|
|
201
365
|
|
|
202
366
|
// Progress bar
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
progressElement.classList.add( 'progress' );
|
|
206
|
-
progressElement.innerHTML = '<span></span>';
|
|
207
|
-
dom.wrapper.appendChild( progressElement );
|
|
208
|
-
}
|
|
367
|
+
dom.progress = createSingletonNode( dom.wrapper, 'div', 'progress', '<span></span>' );
|
|
368
|
+
dom.progressbar = dom.progress.querySelector( 'span' );
|
|
209
369
|
|
|
210
370
|
// Arrow controls
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
371
|
+
createSingletonNode( dom.wrapper, 'aside', 'controls',
|
|
372
|
+
'<div class="navigate-left"></div>' +
|
|
373
|
+
'<div class="navigate-right"></div>' +
|
|
374
|
+
'<div class="navigate-up"></div>' +
|
|
375
|
+
'<div class="navigate-down"></div>' );
|
|
376
|
+
|
|
377
|
+
// Slide number
|
|
378
|
+
dom.slideNumber = createSingletonNode( dom.wrapper, 'div', 'slide-number', '' );
|
|
220
379
|
|
|
221
380
|
// State background element [DEPRECATED]
|
|
222
|
-
|
|
223
|
-
var stateBackgroundElement = document.createElement( 'div' );
|
|
224
|
-
stateBackgroundElement.classList.add( 'state-background' );
|
|
225
|
-
dom.wrapper.appendChild( stateBackgroundElement );
|
|
226
|
-
}
|
|
381
|
+
createSingletonNode( dom.wrapper, 'div', 'state-background', null );
|
|
227
382
|
|
|
228
383
|
// Overlay graphic which is displayed during the paused mode
|
|
229
|
-
|
|
230
|
-
var pausedElement = document.createElement( 'div' );
|
|
231
|
-
pausedElement.classList.add( 'pause-overlay' );
|
|
232
|
-
dom.wrapper.appendChild( pausedElement );
|
|
233
|
-
}
|
|
384
|
+
createSingletonNode( dom.wrapper, 'div', 'pause-overlay', null );
|
|
234
385
|
|
|
235
386
|
// Cache references to elements
|
|
236
|
-
dom.
|
|
237
|
-
|
|
387
|
+
dom.controls = document.querySelector( '.reveal .controls' );
|
|
388
|
+
|
|
389
|
+
// There can be multiple instances of controls throughout the page
|
|
390
|
+
dom.controlsLeft = toArray( document.querySelectorAll( '.navigate-left' ) );
|
|
391
|
+
dom.controlsRight = toArray( document.querySelectorAll( '.navigate-right' ) );
|
|
392
|
+
dom.controlsUp = toArray( document.querySelectorAll( '.navigate-up' ) );
|
|
393
|
+
dom.controlsDown = toArray( document.querySelectorAll( '.navigate-down' ) );
|
|
394
|
+
dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) );
|
|
395
|
+
dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) );
|
|
396
|
+
|
|
397
|
+
}
|
|
238
398
|
|
|
239
|
-
|
|
240
|
-
|
|
399
|
+
/**
|
|
400
|
+
* Creates an HTML element and returns a reference to it.
|
|
401
|
+
* If the element already exists the existing instance will
|
|
402
|
+
* be returned.
|
|
403
|
+
*/
|
|
404
|
+
function createSingletonNode( container, tagname, classname, innerHTML ) {
|
|
241
405
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
406
|
+
var node = container.querySelector( '.' + classname );
|
|
407
|
+
if( !node ) {
|
|
408
|
+
node = document.createElement( tagname );
|
|
409
|
+
node.classList.add( classname );
|
|
410
|
+
if( innerHTML !== null ) {
|
|
411
|
+
node.innerHTML = innerHTML;
|
|
412
|
+
}
|
|
413
|
+
container.appendChild( node );
|
|
249
414
|
}
|
|
415
|
+
return node;
|
|
250
416
|
|
|
251
417
|
}
|
|
252
418
|
|
|
@@ -284,7 +450,7 @@ var Reveal = (function(){
|
|
|
284
450
|
|
|
285
451
|
if( data.background ) {
|
|
286
452
|
// Auto-wrap image urls in url(...)
|
|
287
|
-
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
|
|
453
|
+
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test( data.background ) ) {
|
|
288
454
|
element.style.backgroundImage = 'url('+ data.background +')';
|
|
289
455
|
}
|
|
290
456
|
else {
|
|
@@ -292,6 +458,10 @@ var Reveal = (function(){
|
|
|
292
458
|
}
|
|
293
459
|
}
|
|
294
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
|
+
|
|
295
465
|
// Additional and optional background properties
|
|
296
466
|
if( data.backgroundSize ) element.style.backgroundSize = data.backgroundSize;
|
|
297
467
|
if( data.backgroundImage ) element.style.backgroundImage = 'url("' + data.backgroundImage + '")';
|
|
@@ -332,98 +502,27 @@ var Reveal = (function(){
|
|
|
332
502
|
|
|
333
503
|
} );
|
|
334
504
|
|
|
335
|
-
|
|
505
|
+
// Add parallax background if specified
|
|
506
|
+
if( config.parallaxBackgroundImage ) {
|
|
336
507
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
*/
|
|
340
|
-
function hideAddressBar() {
|
|
508
|
+
dom.background.style.backgroundImage = 'url("' + config.parallaxBackgroundImage + '")';
|
|
509
|
+
dom.background.style.backgroundSize = config.parallaxBackgroundSize;
|
|
341
510
|
|
|
342
|
-
|
|
343
|
-
//
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
511
|
+
// Make sure the below properties are set on the element - these properties are
|
|
512
|
+
// needed for proper transitions to be set on the element via CSS. To remove
|
|
513
|
+
// annoying background slide-in effect when the presentation starts, apply
|
|
514
|
+
// these properties after short time delay
|
|
515
|
+
setTimeout( function() {
|
|
516
|
+
dom.wrapper.classList.add( 'has-parallax-background' );
|
|
517
|
+
}, 1 );
|
|
347
518
|
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Loads the dependencies of reveal.js. Dependencies are
|
|
352
|
-
* defined via the configuration option 'dependencies'
|
|
353
|
-
* and will be loaded prior to starting/binding reveal.js.
|
|
354
|
-
* Some dependencies may have an 'async' flag, if so they
|
|
355
|
-
* will load after reveal.js has been started up.
|
|
356
|
-
*/
|
|
357
|
-
function load() {
|
|
358
|
-
|
|
359
|
-
var scripts = [],
|
|
360
|
-
scriptsAsync = [];
|
|
361
|
-
|
|
362
|
-
for( var i = 0, len = config.dependencies.length; i < len; i++ ) {
|
|
363
|
-
var s = config.dependencies[i];
|
|
364
|
-
|
|
365
|
-
// Load if there's no condition or the condition is truthy
|
|
366
|
-
if( !s.condition || s.condition() ) {
|
|
367
|
-
if( s.async ) {
|
|
368
|
-
scriptsAsync.push( s.src );
|
|
369
|
-
}
|
|
370
|
-
else {
|
|
371
|
-
scripts.push( s.src );
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// Extension may contain callback functions
|
|
375
|
-
if( typeof s.callback === 'function' ) {
|
|
376
|
-
head.ready( s.src.match( /([\w\d_\-]*)\.?js$|[^\\\/]*$/i )[0], s.callback );
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
// Called once synchronous scripts finish loading
|
|
382
|
-
function proceed() {
|
|
383
|
-
if( scriptsAsync.length ) {
|
|
384
|
-
// Load asynchronous scripts
|
|
385
|
-
head.js.apply( null, scriptsAsync );
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
start();
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if( scripts.length ) {
|
|
392
|
-
head.ready( proceed );
|
|
393
|
-
|
|
394
|
-
// Load synchronous scripts
|
|
395
|
-
head.js.apply( null, scripts );
|
|
396
519
|
}
|
|
397
520
|
else {
|
|
398
|
-
proceed();
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* Starts up reveal.js by binding input events and navigating
|
|
405
|
-
* to the current URL deeplink if there is one.
|
|
406
|
-
*/
|
|
407
|
-
function start() {
|
|
408
|
-
|
|
409
|
-
// Make sure we've got all the DOM elements we need
|
|
410
|
-
setupDOM();
|
|
411
521
|
|
|
412
|
-
|
|
413
|
-
|
|
522
|
+
dom.background.style.backgroundImage = '';
|
|
523
|
+
dom.wrapper.classList.remove( 'has-parallax-background' );
|
|
414
524
|
|
|
415
|
-
|
|
416
|
-
readURL();
|
|
417
|
-
|
|
418
|
-
// Notify listeners that the presentation is ready but use a 1ms
|
|
419
|
-
// timeout to ensure it's not fired synchronously after #initialize()
|
|
420
|
-
setTimeout( function() {
|
|
421
|
-
dispatchEvent( 'ready', {
|
|
422
|
-
'indexh': indexh,
|
|
423
|
-
'indexv': indexv,
|
|
424
|
-
'currentSlide': currentSlide
|
|
425
|
-
} );
|
|
426
|
-
}, 1 );
|
|
525
|
+
}
|
|
427
526
|
|
|
428
527
|
}
|
|
429
528
|
|
|
@@ -433,6 +532,8 @@ var Reveal = (function(){
|
|
|
433
532
|
*/
|
|
434
533
|
function configure( options ) {
|
|
435
534
|
|
|
535
|
+
var numberOfSlides = document.querySelectorAll( SLIDES_SELECTOR ).length;
|
|
536
|
+
|
|
436
537
|
dom.wrapper.classList.remove( config.transition );
|
|
437
538
|
|
|
438
539
|
// New config options may be passed when this method
|
|
@@ -440,20 +541,15 @@ var Reveal = (function(){
|
|
|
440
541
|
if( typeof options === 'object' ) extend( config, options );
|
|
441
542
|
|
|
442
543
|
// Force linear transition based on browser capabilities
|
|
443
|
-
if(
|
|
544
|
+
if( features.transforms3d === false ) config.transition = 'linear';
|
|
444
545
|
|
|
445
546
|
dom.wrapper.classList.add( config.transition );
|
|
446
547
|
|
|
447
548
|
dom.wrapper.setAttribute( 'data-transition-speed', config.transitionSpeed );
|
|
448
549
|
dom.wrapper.setAttribute( 'data-background-transition', config.backgroundTransition );
|
|
449
550
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
if( dom.progress ) {
|
|
455
|
-
dom.progress.style.display = ( config.progress && dom.progress ) ? 'block' : 'none';
|
|
456
|
-
}
|
|
551
|
+
dom.controls.style.display = config.controls ? 'block' : 'none';
|
|
552
|
+
dom.progress.style.display = config.progress ? 'block' : 'none';
|
|
457
553
|
|
|
458
554
|
if( config.rtl ) {
|
|
459
555
|
dom.wrapper.classList.add( 'rtl' );
|
|
@@ -495,6 +591,20 @@ var Reveal = (function(){
|
|
|
495
591
|
enablePreviewLinks( '[data-preview-link]' );
|
|
496
592
|
}
|
|
497
593
|
|
|
594
|
+
// Auto-slide playback controls
|
|
595
|
+
if( numberOfSlides > 1 && config.autoSlide && config.autoSlideStoppable && features.canvas && features.requestAnimationFrame ) {
|
|
596
|
+
autoSlidePlayer = new Playback( dom.wrapper, function() {
|
|
597
|
+
return Math.min( Math.max( ( Date.now() - autoSlideStartTime ) / autoSlide, 0 ), 1 );
|
|
598
|
+
} );
|
|
599
|
+
|
|
600
|
+
autoSlidePlayer.on( 'click', onAutoSlidePlayerClick );
|
|
601
|
+
autoSlidePaused = false;
|
|
602
|
+
}
|
|
603
|
+
else if( autoSlidePlayer ) {
|
|
604
|
+
autoSlidePlayer.destroy();
|
|
605
|
+
autoSlidePlayer = null;
|
|
606
|
+
}
|
|
607
|
+
|
|
498
608
|
// Load the theme in the config, if it's not already loaded
|
|
499
609
|
if( config.theme && dom.theme ) {
|
|
500
610
|
var themeURL = dom.theme.getAttribute( 'href' );
|
|
@@ -538,21 +648,37 @@ var Reveal = (function(){
|
|
|
538
648
|
document.addEventListener( 'keydown', onDocumentKeyDown, false );
|
|
539
649
|
}
|
|
540
650
|
|
|
541
|
-
if
|
|
651
|
+
if( config.progress && dom.progress ) {
|
|
542
652
|
dom.progress.addEventListener( 'click', onProgressClicked, false );
|
|
543
653
|
}
|
|
544
654
|
|
|
545
|
-
if
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
}
|
|
655
|
+
if( config.focusBodyOnPageVisiblityChange ) {
|
|
656
|
+
var visibilityChange;
|
|
657
|
+
|
|
658
|
+
if( 'hidden' in document ) {
|
|
659
|
+
visibilityChange = 'visibilitychange';
|
|
660
|
+
}
|
|
661
|
+
else if( 'msHidden' in document ) {
|
|
662
|
+
visibilityChange = 'msvisibilitychange';
|
|
663
|
+
}
|
|
664
|
+
else if( 'webkitHidden' in document ) {
|
|
665
|
+
visibilityChange = 'webkitvisibilitychange';
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
if( visibilityChange ) {
|
|
669
|
+
document.addEventListener( visibilityChange, onPageVisibilityChange, false );
|
|
670
|
+
}
|
|
554
671
|
}
|
|
555
672
|
|
|
673
|
+
[ 'touchstart', 'click' ].forEach( function( eventName ) {
|
|
674
|
+
dom.controlsLeft.forEach( function( el ) { el.addEventListener( eventName, onNavigateLeftClicked, false ); } );
|
|
675
|
+
dom.controlsRight.forEach( function( el ) { el.addEventListener( eventName, onNavigateRightClicked, false ); } );
|
|
676
|
+
dom.controlsUp.forEach( function( el ) { el.addEventListener( eventName, onNavigateUpClicked, false ); } );
|
|
677
|
+
dom.controlsDown.forEach( function( el ) { el.addEventListener( eventName, onNavigateDownClicked, false ); } );
|
|
678
|
+
dom.controlsPrev.forEach( function( el ) { el.addEventListener( eventName, onNavigatePrevClicked, false ); } );
|
|
679
|
+
dom.controlsNext.forEach( function( el ) { el.addEventListener( eventName, onNavigateNextClicked, false ); } );
|
|
680
|
+
} );
|
|
681
|
+
|
|
556
682
|
}
|
|
557
683
|
|
|
558
684
|
/**
|
|
@@ -580,16 +706,14 @@ var Reveal = (function(){
|
|
|
580
706
|
dom.progress.removeEventListener( 'click', onProgressClicked, false );
|
|
581
707
|
}
|
|
582
708
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
} );
|
|
592
|
-
}
|
|
709
|
+
[ 'touchstart', 'click' ].forEach( function( eventName ) {
|
|
710
|
+
dom.controlsLeft.forEach( function( el ) { el.removeEventListener( eventName, onNavigateLeftClicked, false ); } );
|
|
711
|
+
dom.controlsRight.forEach( function( el ) { el.removeEventListener( eventName, onNavigateRightClicked, false ); } );
|
|
712
|
+
dom.controlsUp.forEach( function( el ) { el.removeEventListener( eventName, onNavigateUpClicked, false ); } );
|
|
713
|
+
dom.controlsDown.forEach( function( el ) { el.removeEventListener( eventName, onNavigateDownClicked, false ); } );
|
|
714
|
+
dom.controlsPrev.forEach( function( el ) { el.removeEventListener( eventName, onNavigatePrevClicked, false ); } );
|
|
715
|
+
dom.controlsNext.forEach( function( el ) { el.removeEventListener( eventName, onNavigateNextClicked, false ); } );
|
|
716
|
+
} );
|
|
593
717
|
|
|
594
718
|
}
|
|
595
719
|
|
|
@@ -630,6 +754,19 @@ var Reveal = (function(){
|
|
|
630
754
|
|
|
631
755
|
}
|
|
632
756
|
|
|
757
|
+
/**
|
|
758
|
+
* Applies a CSS transform to the target element.
|
|
759
|
+
*/
|
|
760
|
+
function transformElement( element, transform ) {
|
|
761
|
+
|
|
762
|
+
element.style.WebkitTransform = transform;
|
|
763
|
+
element.style.MozTransform = transform;
|
|
764
|
+
element.style.msTransform = transform;
|
|
765
|
+
element.style.OTransform = transform;
|
|
766
|
+
element.style.transform = transform;
|
|
767
|
+
|
|
768
|
+
}
|
|
769
|
+
|
|
633
770
|
/**
|
|
634
771
|
* Retrieves the height of the given element by looking
|
|
635
772
|
* at the position and height of its immediate children.
|
|
@@ -665,6 +802,48 @@ var Reveal = (function(){
|
|
|
665
802
|
|
|
666
803
|
}
|
|
667
804
|
|
|
805
|
+
/**
|
|
806
|
+
* Returns the remaining height within the parent of the
|
|
807
|
+
* target element after subtracting the height of all
|
|
808
|
+
* siblings.
|
|
809
|
+
*
|
|
810
|
+
* remaining height = [parent height] - [ siblings height]
|
|
811
|
+
*/
|
|
812
|
+
function getRemainingHeight( element, height ) {
|
|
813
|
+
|
|
814
|
+
height = height || 0;
|
|
815
|
+
|
|
816
|
+
if( element ) {
|
|
817
|
+
var parent = element.parentNode;
|
|
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
|
+
} );
|
|
834
|
+
|
|
835
|
+
var elementStyles = window.getComputedStyle( element );
|
|
836
|
+
|
|
837
|
+
// Subtract the margins of the target element
|
|
838
|
+
height -= parseInt( elementStyles.marginTop, 10 ) +
|
|
839
|
+
parseInt( elementStyles.marginBottom, 10 );
|
|
840
|
+
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
return height;
|
|
844
|
+
|
|
845
|
+
}
|
|
846
|
+
|
|
668
847
|
/**
|
|
669
848
|
* Checks if this instance is being used to print a PDF.
|
|
670
849
|
*/
|
|
@@ -674,21 +853,25 @@ var Reveal = (function(){
|
|
|
674
853
|
|
|
675
854
|
}
|
|
676
855
|
|
|
856
|
+
/**
|
|
857
|
+
* Hides the address bar if we're on a mobile device.
|
|
858
|
+
*/
|
|
859
|
+
function hideAddressBar() {
|
|
860
|
+
|
|
861
|
+
if( config.hideAddressBar && isMobileDevice ) {
|
|
862
|
+
// Events that should trigger the address bar to hide
|
|
863
|
+
window.addEventListener( 'load', removeAddressBar, false );
|
|
864
|
+
window.addEventListener( 'orientationchange', removeAddressBar, false );
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
}
|
|
868
|
+
|
|
677
869
|
/**
|
|
678
870
|
* Causes the address bar to hide on mobile devices,
|
|
679
871
|
* more vertical space ftw.
|
|
680
872
|
*/
|
|
681
873
|
function removeAddressBar() {
|
|
682
874
|
|
|
683
|
-
if( window.orientation === 0 ) {
|
|
684
|
-
document.documentElement.style.overflow = 'scroll';
|
|
685
|
-
document.body.style.height = '120%';
|
|
686
|
-
}
|
|
687
|
-
else {
|
|
688
|
-
document.documentElement.style.overflow = '';
|
|
689
|
-
document.body.style.height = '100%';
|
|
690
|
-
}
|
|
691
|
-
|
|
692
875
|
setTimeout( function() {
|
|
693
876
|
window.scrollTo( 0, 1 );
|
|
694
877
|
}, 10 );
|
|
@@ -713,7 +896,7 @@ var Reveal = (function(){
|
|
|
713
896
|
*/
|
|
714
897
|
function enableRollingLinks() {
|
|
715
898
|
|
|
716
|
-
if(
|
|
899
|
+
if( features.transforms3d && !( 'msPerspective' in document.body.style ) ) {
|
|
717
900
|
var anchors = document.querySelectorAll( SLIDES_SELECTOR + ' a:not(.image)' );
|
|
718
901
|
|
|
719
902
|
for( var i = 0, len = anchors.length; i < len; i++ ) {
|
|
@@ -836,38 +1019,6 @@ var Reveal = (function(){
|
|
|
836
1019
|
|
|
837
1020
|
}
|
|
838
1021
|
|
|
839
|
-
/**
|
|
840
|
-
* Return a sorted fragments list, ordered by an increasing
|
|
841
|
-
* "data-fragment-index" attribute.
|
|
842
|
-
*
|
|
843
|
-
* Fragments will be revealed in the order that they are returned by
|
|
844
|
-
* this function, so you can use the index attributes to control the
|
|
845
|
-
* order of fragment appearance.
|
|
846
|
-
*
|
|
847
|
-
* To maintain a sensible default fragment order, fragments are presumed
|
|
848
|
-
* to be passed in document order. This function adds a "fragment-index"
|
|
849
|
-
* attribute to each node if such an attribute is not already present,
|
|
850
|
-
* and sets that attribute to an integer value which is the position of
|
|
851
|
-
* the fragment within the fragments list.
|
|
852
|
-
*/
|
|
853
|
-
function sortFragments( fragments ) {
|
|
854
|
-
|
|
855
|
-
var a = toArray( fragments );
|
|
856
|
-
|
|
857
|
-
a.forEach( function( el, idx ) {
|
|
858
|
-
if( !el.hasAttribute( 'data-fragment-index' ) ) {
|
|
859
|
-
el.setAttribute( 'data-fragment-index', idx );
|
|
860
|
-
}
|
|
861
|
-
} );
|
|
862
|
-
|
|
863
|
-
a.sort( function( l, r ) {
|
|
864
|
-
return l.getAttribute( 'data-fragment-index' ) - r.getAttribute( 'data-fragment-index');
|
|
865
|
-
} );
|
|
866
|
-
|
|
867
|
-
return a;
|
|
868
|
-
|
|
869
|
-
}
|
|
870
|
-
|
|
871
1022
|
/**
|
|
872
1023
|
* Applies JavaScript-controlled layout rules to the
|
|
873
1024
|
* presentation.
|
|
@@ -886,7 +1037,11 @@ var Reveal = (function(){
|
|
|
886
1037
|
|
|
887
1038
|
// Dimensions of the content
|
|
888
1039
|
var slideWidth = config.width,
|
|
889
|
-
slideHeight = config.height
|
|
1040
|
+
slideHeight = config.height,
|
|
1041
|
+
slidePadding = 20; // TODO Dig this out of DOM
|
|
1042
|
+
|
|
1043
|
+
// Layout the contents of the slides
|
|
1044
|
+
layoutSlideContents( config.width, config.height, slidePadding );
|
|
890
1045
|
|
|
891
1046
|
// Slide width may be a percentage of available width
|
|
892
1047
|
if( typeof slideWidth === 'string' && /%$/.test( slideWidth ) ) {
|
|
@@ -915,13 +1070,7 @@ var Reveal = (function(){
|
|
|
915
1070
|
}
|
|
916
1071
|
// Apply scale transform as a fallback
|
|
917
1072
|
else {
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
dom.slides.style.WebkitTransform = transform;
|
|
921
|
-
dom.slides.style.MozTransform = transform;
|
|
922
|
-
dom.slides.style.msTransform = transform;
|
|
923
|
-
dom.slides.style.OTransform = transform;
|
|
924
|
-
dom.slides.style.transform = transform;
|
|
1073
|
+
transformElement( dom.slides, 'translate(-50%, -50%) scale('+ scale +') translate(50%, 50%)' );
|
|
925
1074
|
}
|
|
926
1075
|
|
|
927
1076
|
// Select all slides, vertical and horizontal
|
|
@@ -935,14 +1084,14 @@ var Reveal = (function(){
|
|
|
935
1084
|
continue;
|
|
936
1085
|
}
|
|
937
1086
|
|
|
938
|
-
if( config.center ) {
|
|
1087
|
+
if( config.center || slide.classList.contains( 'center' ) ) {
|
|
939
1088
|
// Vertical stacks are not centred since their section
|
|
940
1089
|
// children will be
|
|
941
1090
|
if( slide.classList.contains( 'stack' ) ) {
|
|
942
1091
|
slide.style.top = 0;
|
|
943
1092
|
}
|
|
944
1093
|
else {
|
|
945
|
-
slide.style.top = Math.max( - ( getAbsoluteHeight( slide ) / 2 ) -
|
|
1094
|
+
slide.style.top = Math.max( - ( getAbsoluteHeight( slide ) / 2 ) - slidePadding, -slideHeight / 2 ) + 'px';
|
|
946
1095
|
}
|
|
947
1096
|
}
|
|
948
1097
|
else {
|
|
@@ -952,11 +1101,44 @@ var Reveal = (function(){
|
|
|
952
1101
|
}
|
|
953
1102
|
|
|
954
1103
|
updateProgress();
|
|
1104
|
+
updateParallax();
|
|
955
1105
|
|
|
956
1106
|
}
|
|
957
1107
|
|
|
958
1108
|
}
|
|
959
1109
|
|
|
1110
|
+
/**
|
|
1111
|
+
* Applies layout logic to the contents of all slides in
|
|
1112
|
+
* the presentation.
|
|
1113
|
+
*/
|
|
1114
|
+
function layoutSlideContents( width, height, padding ) {
|
|
1115
|
+
|
|
1116
|
+
// Handle sizing of elements with the 'stretch' class
|
|
1117
|
+
toArray( dom.slides.querySelectorAll( 'section > .stretch' ) ).forEach( function( element ) {
|
|
1118
|
+
|
|
1119
|
+
// Determine how much vertical space we can use
|
|
1120
|
+
var remainingHeight = getRemainingHeight( element, ( height - ( padding * 2 ) ) );
|
|
1121
|
+
|
|
1122
|
+
// Consider the aspect ratio of media elements
|
|
1123
|
+
if( /(img|video)/gi.test( element.nodeName ) ) {
|
|
1124
|
+
var nw = element.naturalWidth || element.videoWidth,
|
|
1125
|
+
nh = element.naturalHeight || element.videoHeight;
|
|
1126
|
+
|
|
1127
|
+
var es = Math.min( width / nw, remainingHeight / nh );
|
|
1128
|
+
|
|
1129
|
+
element.style.width = ( nw * es ) + 'px';
|
|
1130
|
+
element.style.height = ( nh * es ) + 'px';
|
|
1131
|
+
|
|
1132
|
+
}
|
|
1133
|
+
else {
|
|
1134
|
+
element.style.width = width + 'px';
|
|
1135
|
+
element.style.height = remainingHeight + 'px';
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
} );
|
|
1139
|
+
|
|
1140
|
+
}
|
|
1141
|
+
|
|
960
1142
|
/**
|
|
961
1143
|
* Stores the vertical index of a stack so that the same
|
|
962
1144
|
* vertical slide can be selected when navigating to and
|
|
@@ -1010,8 +1192,11 @@ var Reveal = (function(){
|
|
|
1010
1192
|
|
|
1011
1193
|
var wasActive = dom.wrapper.classList.contains( 'overview' );
|
|
1012
1194
|
|
|
1195
|
+
// Vary the depth of the overview based on screen size
|
|
1196
|
+
var depth = window.innerWidth < 400 ? 1000 : 2500;
|
|
1197
|
+
|
|
1013
1198
|
dom.wrapper.classList.add( 'overview' );
|
|
1014
|
-
dom.wrapper.classList.remove( '
|
|
1199
|
+
dom.wrapper.classList.remove( 'overview-deactivating' );
|
|
1015
1200
|
|
|
1016
1201
|
clearTimeout( activateOverviewTimeout );
|
|
1017
1202
|
clearTimeout( deactivateOverviewTimeout );
|
|
@@ -1019,22 +1204,18 @@ var Reveal = (function(){
|
|
|
1019
1204
|
// Not the pretties solution, but need to let the overview
|
|
1020
1205
|
// class apply first so that slides are measured accurately
|
|
1021
1206
|
// before we can position them
|
|
1022
|
-
activateOverviewTimeout = setTimeout( function(){
|
|
1207
|
+
activateOverviewTimeout = setTimeout( function() {
|
|
1023
1208
|
|
|
1024
1209
|
var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
|
|
1025
1210
|
|
|
1026
1211
|
for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) {
|
|
1027
1212
|
var hslide = horizontalSlides[i],
|
|
1028
|
-
hoffset = config.rtl ? -105 : 105
|
|
1029
|
-
htransform = 'translateZ(-2500px) translate(' + ( ( i - indexh ) * hoffset ) + '%, 0%)';
|
|
1213
|
+
hoffset = config.rtl ? -105 : 105;
|
|
1030
1214
|
|
|
1031
1215
|
hslide.setAttribute( 'data-index-h', i );
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
hslide
|
|
1035
|
-
hslide.style.msTransform = htransform;
|
|
1036
|
-
hslide.style.OTransform = htransform;
|
|
1037
|
-
hslide.style.transform = htransform;
|
|
1216
|
+
|
|
1217
|
+
// Apply CSS transform
|
|
1218
|
+
transformElement( hslide, 'translateZ(-'+ depth +'px) translate(' + ( ( i - indexh ) * hoffset ) + '%, 0%)' );
|
|
1038
1219
|
|
|
1039
1220
|
if( hslide.classList.contains( 'stack' ) ) {
|
|
1040
1221
|
|
|
@@ -1043,17 +1224,13 @@ var Reveal = (function(){
|
|
|
1043
1224
|
for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) {
|
|
1044
1225
|
var verticalIndex = i === indexh ? indexv : getPreviousVerticalIndex( hslide );
|
|
1045
1226
|
|
|
1046
|
-
var vslide = verticalSlides[j]
|
|
1047
|
-
vtransform = 'translate(0%, ' + ( ( j - verticalIndex ) * 105 ) + '%)';
|
|
1227
|
+
var vslide = verticalSlides[j];
|
|
1048
1228
|
|
|
1049
1229
|
vslide.setAttribute( 'data-index-h', i );
|
|
1050
1230
|
vslide.setAttribute( 'data-index-v', j );
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
vslide
|
|
1054
|
-
vslide.style.msTransform = vtransform;
|
|
1055
|
-
vslide.style.OTransform = vtransform;
|
|
1056
|
-
vslide.style.transform = vtransform;
|
|
1231
|
+
|
|
1232
|
+
// Apply CSS transform
|
|
1233
|
+
transformElement( vslide, 'translate(0%, ' + ( ( j - verticalIndex ) * 105 ) + '%)' );
|
|
1057
1234
|
|
|
1058
1235
|
// Navigate to this slide on click
|
|
1059
1236
|
vslide.addEventListener( 'click', onOverviewSlideClicked, true );
|
|
@@ -1068,6 +1245,8 @@ var Reveal = (function(){
|
|
|
1068
1245
|
}
|
|
1069
1246
|
}
|
|
1070
1247
|
|
|
1248
|
+
updateSlidesVisibility();
|
|
1249
|
+
|
|
1071
1250
|
layout();
|
|
1072
1251
|
|
|
1073
1252
|
if( !wasActive ) {
|
|
@@ -1102,29 +1281,19 @@ var Reveal = (function(){
|
|
|
1102
1281
|
// Temporarily add a class so that transitions can do different things
|
|
1103
1282
|
// depending on whether they are exiting/entering overview, or just
|
|
1104
1283
|
// moving from slide to slide
|
|
1105
|
-
dom.wrapper.classList.add( '
|
|
1284
|
+
dom.wrapper.classList.add( 'overview-deactivating' );
|
|
1106
1285
|
|
|
1107
1286
|
deactivateOverviewTimeout = setTimeout( function () {
|
|
1108
|
-
dom.wrapper.classList.remove( '
|
|
1109
|
-
},
|
|
1287
|
+
dom.wrapper.classList.remove( 'overview-deactivating' );
|
|
1288
|
+
}, 1 );
|
|
1110
1289
|
|
|
1111
1290
|
// Select all slides
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
for( var i = 0, len = slides.length; i < len; i++ ) {
|
|
1115
|
-
var element = slides[i];
|
|
1116
|
-
|
|
1117
|
-
element.style.display = '';
|
|
1118
|
-
|
|
1291
|
+
toArray( document.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) {
|
|
1119
1292
|
// Resets all transforms to use the external styles
|
|
1120
|
-
|
|
1121
|
-
element.style.MozTransform = '';
|
|
1122
|
-
element.style.msTransform = '';
|
|
1123
|
-
element.style.OTransform = '';
|
|
1124
|
-
element.style.transform = '';
|
|
1293
|
+
transformElement( slide, '' );
|
|
1125
1294
|
|
|
1126
|
-
|
|
1127
|
-
}
|
|
1295
|
+
slide.removeEventListener( 'click', onOverviewSlideClicked, true );
|
|
1296
|
+
} );
|
|
1128
1297
|
|
|
1129
1298
|
slide( indexh, indexv );
|
|
1130
1299
|
|
|
@@ -1182,7 +1351,7 @@ var Reveal = (function(){
|
|
|
1182
1351
|
// Prefer slide argument, otherwise use current slide
|
|
1183
1352
|
slide = slide ? slide : currentSlide;
|
|
1184
1353
|
|
|
1185
|
-
return slide && !!slide.parentNode.nodeName.match( /section/i );
|
|
1354
|
+
return slide && slide.parentNode && !!slide.parentNode.nodeName.match( /section/i );
|
|
1186
1355
|
|
|
1187
1356
|
}
|
|
1188
1357
|
|
|
@@ -1302,13 +1471,16 @@ var Reveal = (function(){
|
|
|
1302
1471
|
// Reset the state array
|
|
1303
1472
|
state.length = 0;
|
|
1304
1473
|
|
|
1305
|
-
var indexhBefore = indexh,
|
|
1306
|
-
indexvBefore = indexv;
|
|
1474
|
+
var indexhBefore = indexh || 0,
|
|
1475
|
+
indexvBefore = indexv || 0;
|
|
1307
1476
|
|
|
1308
1477
|
// Activate and transition to the new slide
|
|
1309
1478
|
indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );
|
|
1310
1479
|
indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );
|
|
1311
1480
|
|
|
1481
|
+
// Update the visibility of slides now that the indices have changed
|
|
1482
|
+
updateSlidesVisibility();
|
|
1483
|
+
|
|
1312
1484
|
layout();
|
|
1313
1485
|
|
|
1314
1486
|
// Apply the new state
|
|
@@ -1338,10 +1510,6 @@ var Reveal = (function(){
|
|
|
1338
1510
|
activateOverview();
|
|
1339
1511
|
}
|
|
1340
1512
|
|
|
1341
|
-
// Update the URL hash after a delay since updating it mid-transition
|
|
1342
|
-
// is likely to cause visual lag
|
|
1343
|
-
writeURL( 1500 );
|
|
1344
|
-
|
|
1345
1513
|
// Find the current horizontal slide and any possible vertical slides
|
|
1346
1514
|
// within it
|
|
1347
1515
|
var currentHorizontalSlide = horizontalSlides[ indexh ],
|
|
@@ -1350,19 +1518,9 @@ var Reveal = (function(){
|
|
|
1350
1518
|
// Store references to the previous and current slides
|
|
1351
1519
|
currentSlide = currentVerticalSlides[ indexv ] || currentHorizontalSlide;
|
|
1352
1520
|
|
|
1353
|
-
|
|
1354
1521
|
// Show fragment, if specified
|
|
1355
1522
|
if( typeof f !== 'undefined' ) {
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
toArray( fragments ).forEach( function( fragment, indexf ) {
|
|
1359
|
-
if( indexf < f ) {
|
|
1360
|
-
fragment.classList.add( 'visible' );
|
|
1361
|
-
}
|
|
1362
|
-
else {
|
|
1363
|
-
fragment.classList.remove( 'visible' );
|
|
1364
|
-
}
|
|
1365
|
-
} );
|
|
1523
|
+
navigateFragment( f );
|
|
1366
1524
|
}
|
|
1367
1525
|
|
|
1368
1526
|
// Dispatch an event if the slide changed
|
|
@@ -1412,6 +1570,13 @@ var Reveal = (function(){
|
|
|
1412
1570
|
updateControls();
|
|
1413
1571
|
updateProgress();
|
|
1414
1572
|
updateBackground();
|
|
1573
|
+
updateParallax();
|
|
1574
|
+
updateSlideNumber();
|
|
1575
|
+
|
|
1576
|
+
// Update the URL hash
|
|
1577
|
+
writeURL();
|
|
1578
|
+
|
|
1579
|
+
cueAutoSlide();
|
|
1415
1580
|
|
|
1416
1581
|
}
|
|
1417
1582
|
|
|
@@ -1438,9 +1603,58 @@ var Reveal = (function(){
|
|
|
1438
1603
|
// Re-create the slide backgrounds
|
|
1439
1604
|
createBackgrounds();
|
|
1440
1605
|
|
|
1606
|
+
sortAllFragments();
|
|
1607
|
+
|
|
1441
1608
|
updateControls();
|
|
1442
1609
|
updateProgress();
|
|
1443
|
-
updateBackground();
|
|
1610
|
+
updateBackground( true );
|
|
1611
|
+
updateSlideNumber();
|
|
1612
|
+
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
/**
|
|
1616
|
+
* Resets all vertical slides so that only the first
|
|
1617
|
+
* is visible.
|
|
1618
|
+
*/
|
|
1619
|
+
function resetVerticalSlides() {
|
|
1620
|
+
|
|
1621
|
+
var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
|
|
1622
|
+
horizontalSlides.forEach( function( horizontalSlide ) {
|
|
1623
|
+
|
|
1624
|
+
var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
|
|
1625
|
+
verticalSlides.forEach( function( verticalSlide, y ) {
|
|
1626
|
+
|
|
1627
|
+
if( y > 0 ) {
|
|
1628
|
+
verticalSlide.classList.remove( 'present' );
|
|
1629
|
+
verticalSlide.classList.remove( 'past' );
|
|
1630
|
+
verticalSlide.classList.add( 'future' );
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
} );
|
|
1634
|
+
|
|
1635
|
+
} );
|
|
1636
|
+
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
/**
|
|
1640
|
+
* Sorts and formats all of fragments in the
|
|
1641
|
+
* presentation.
|
|
1642
|
+
*/
|
|
1643
|
+
function sortAllFragments() {
|
|
1644
|
+
|
|
1645
|
+
var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
|
|
1646
|
+
horizontalSlides.forEach( function( horizontalSlide ) {
|
|
1647
|
+
|
|
1648
|
+
var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) );
|
|
1649
|
+
verticalSlides.forEach( function( verticalSlide, y ) {
|
|
1650
|
+
|
|
1651
|
+
sortFragments( verticalSlide.querySelectorAll( '.fragment' ) );
|
|
1652
|
+
|
|
1653
|
+
} );
|
|
1654
|
+
|
|
1655
|
+
if( verticalSlides.length === 0 ) sortFragments( horizontalSlide.querySelectorAll( '.fragment' ) );
|
|
1656
|
+
|
|
1657
|
+
} );
|
|
1444
1658
|
|
|
1445
1659
|
}
|
|
1446
1660
|
|
|
@@ -1481,16 +1695,6 @@ var Reveal = (function(){
|
|
|
1481
1695
|
for( var i = 0; i < slidesLength; i++ ) {
|
|
1482
1696
|
var element = slides[i];
|
|
1483
1697
|
|
|
1484
|
-
// Optimization; hide all slides that are three or more steps
|
|
1485
|
-
// away from the present slide
|
|
1486
|
-
if( isOverview() === false ) {
|
|
1487
|
-
// The distance loops so that it measures 1 between the first
|
|
1488
|
-
// and last slides
|
|
1489
|
-
var distance = Math.abs( ( index - i ) % ( slidesLength - 3 ) ) || 0;
|
|
1490
|
-
|
|
1491
|
-
element.style.display = distance > 3 ? 'none' : 'block';
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
1698
|
var reverse = config.rtl && !isVerticalSlide( element );
|
|
1495
1699
|
|
|
1496
1700
|
element.classList.remove( 'past' );
|
|
@@ -1503,10 +1707,28 @@ var Reveal = (function(){
|
|
|
1503
1707
|
if( i < index ) {
|
|
1504
1708
|
// Any element previous to index is given the 'past' class
|
|
1505
1709
|
element.classList.add( reverse ? 'future' : 'past' );
|
|
1710
|
+
|
|
1711
|
+
var pastFragments = toArray( element.querySelectorAll( '.fragment' ) );
|
|
1712
|
+
|
|
1713
|
+
// Show all fragments on prior slides
|
|
1714
|
+
while( pastFragments.length ) {
|
|
1715
|
+
var pastFragment = pastFragments.pop();
|
|
1716
|
+
pastFragment.classList.add( 'visible' );
|
|
1717
|
+
pastFragment.classList.remove( 'current-fragment' );
|
|
1718
|
+
}
|
|
1506
1719
|
}
|
|
1507
1720
|
else if( i > index ) {
|
|
1508
1721
|
// Any element subsequent to index is given the 'future' class
|
|
1509
1722
|
element.classList.add( reverse ? 'past' : 'future' );
|
|
1723
|
+
|
|
1724
|
+
var futureFragments = toArray( element.querySelectorAll( '.fragment.visible' ) );
|
|
1725
|
+
|
|
1726
|
+
// No fragments in future slides should be visible ahead of time
|
|
1727
|
+
while( futureFragments.length ) {
|
|
1728
|
+
var futureFragment = futureFragments.pop();
|
|
1729
|
+
futureFragment.classList.remove( 'visible' );
|
|
1730
|
+
futureFragment.classList.remove( 'current-fragment' );
|
|
1731
|
+
}
|
|
1510
1732
|
}
|
|
1511
1733
|
|
|
1512
1734
|
// If this element contains vertical slides
|
|
@@ -1526,16 +1748,6 @@ var Reveal = (function(){
|
|
|
1526
1748
|
state = state.concat( slideState.split( ' ' ) );
|
|
1527
1749
|
}
|
|
1528
1750
|
|
|
1529
|
-
// If this slide has a data-autoslide attribtue associated use this as
|
|
1530
|
-
// autoSlide value otherwise use the global configured time
|
|
1531
|
-
var slideAutoSlide = slides[index].getAttribute( 'data-autoslide' );
|
|
1532
|
-
if( slideAutoSlide ) {
|
|
1533
|
-
autoSlide = parseInt( slideAutoSlide, 10 );
|
|
1534
|
-
}
|
|
1535
|
-
else {
|
|
1536
|
-
autoSlide = config.autoSlide;
|
|
1537
|
-
}
|
|
1538
|
-
|
|
1539
1751
|
}
|
|
1540
1752
|
else {
|
|
1541
1753
|
// Since there are no slides we can't be anywhere beyond the
|
|
@@ -1547,6 +1759,61 @@ var Reveal = (function(){
|
|
|
1547
1759
|
|
|
1548
1760
|
}
|
|
1549
1761
|
|
|
1762
|
+
/**
|
|
1763
|
+
* Optimization method; hide all slides that are far away
|
|
1764
|
+
* from the present slide.
|
|
1765
|
+
*/
|
|
1766
|
+
function updateSlidesVisibility() {
|
|
1767
|
+
|
|
1768
|
+
// Select all slides and convert the NodeList result to
|
|
1769
|
+
// an array
|
|
1770
|
+
var horizontalSlides = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ),
|
|
1771
|
+
horizontalSlidesLength = horizontalSlides.length,
|
|
1772
|
+
distanceX,
|
|
1773
|
+
distanceY;
|
|
1774
|
+
|
|
1775
|
+
if( horizontalSlidesLength ) {
|
|
1776
|
+
|
|
1777
|
+
// The number of steps away from the present slide that will
|
|
1778
|
+
// be visible
|
|
1779
|
+
var viewDistance = isOverview() ? 10 : config.viewDistance;
|
|
1780
|
+
|
|
1781
|
+
// Limit view distance on weaker devices
|
|
1782
|
+
if( isMobileDevice ) {
|
|
1783
|
+
viewDistance = isOverview() ? 6 : 1;
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
for( var x = 0; x < horizontalSlidesLength; x++ ) {
|
|
1787
|
+
var horizontalSlide = horizontalSlides[x];
|
|
1788
|
+
|
|
1789
|
+
var verticalSlides = toArray( horizontalSlide.querySelectorAll( 'section' ) ),
|
|
1790
|
+
verticalSlidesLength = verticalSlides.length;
|
|
1791
|
+
|
|
1792
|
+
// Loops so that it measures 1 between the first and last slides
|
|
1793
|
+
distanceX = Math.abs( ( indexh - x ) % ( horizontalSlidesLength - viewDistance ) ) || 0;
|
|
1794
|
+
|
|
1795
|
+
// Show the horizontal slide if it's within the view distance
|
|
1796
|
+
horizontalSlide.style.display = distanceX > viewDistance ? 'none' : 'block';
|
|
1797
|
+
|
|
1798
|
+
if( verticalSlidesLength ) {
|
|
1799
|
+
|
|
1800
|
+
var oy = getPreviousVerticalIndex( horizontalSlide );
|
|
1801
|
+
|
|
1802
|
+
for( var y = 0; y < verticalSlidesLength; y++ ) {
|
|
1803
|
+
var verticalSlide = verticalSlides[y];
|
|
1804
|
+
|
|
1805
|
+
distanceY = x === indexh ? Math.abs( indexv - y ) : Math.abs( y - oy );
|
|
1806
|
+
|
|
1807
|
+
verticalSlide.style.display = ( distanceX + distanceY ) > viewDistance ? 'none' : 'block';
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1550
1817
|
/**
|
|
1551
1818
|
* Updates the progress bar to reflect the current slide.
|
|
1552
1819
|
*/
|
|
@@ -1597,52 +1864,68 @@ var Reveal = (function(){
|
|
|
1597
1864
|
}
|
|
1598
1865
|
|
|
1599
1866
|
/**
|
|
1600
|
-
* Updates the
|
|
1867
|
+
* Updates the slide number div to reflect the current slide.
|
|
1601
1868
|
*/
|
|
1602
|
-
function
|
|
1869
|
+
function updateSlideNumber() {
|
|
1603
1870
|
|
|
1604
|
-
|
|
1871
|
+
// Update slide number if enabled
|
|
1872
|
+
if( config.slideNumber && dom.slideNumber) {
|
|
1605
1873
|
|
|
1606
|
-
|
|
1607
|
-
var
|
|
1874
|
+
// Display the number of the page using 'indexh - indexv' format
|
|
1875
|
+
var indexString = indexh;
|
|
1876
|
+
if( indexv > 0 ) {
|
|
1877
|
+
indexString += ' - ' + indexv;
|
|
1878
|
+
}
|
|
1608
1879
|
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
.concat( dom.controlsUp )
|
|
1612
|
-
.concat( dom.controlsDown )
|
|
1613
|
-
.concat( dom.controlsPrev )
|
|
1614
|
-
.concat( dom.controlsNext ).forEach( function( node ) {
|
|
1615
|
-
node.classList.remove( 'enabled' );
|
|
1616
|
-
node.classList.remove( 'fragmented' );
|
|
1617
|
-
} );
|
|
1880
|
+
dom.slideNumber.innerHTML = indexString;
|
|
1881
|
+
}
|
|
1618
1882
|
|
|
1619
|
-
|
|
1620
|
-
if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
|
1621
|
-
if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
|
1622
|
-
if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
|
1623
|
-
if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
|
1883
|
+
}
|
|
1624
1884
|
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1885
|
+
/**
|
|
1886
|
+
* Updates the state of all control/navigation arrows.
|
|
1887
|
+
*/
|
|
1888
|
+
function updateControls() {
|
|
1628
1889
|
|
|
1629
|
-
|
|
1630
|
-
|
|
1890
|
+
var routes = availableRoutes();
|
|
1891
|
+
var fragments = availableFragments();
|
|
1892
|
+
|
|
1893
|
+
// Remove the 'enabled' class from all directions
|
|
1894
|
+
dom.controlsLeft.concat( dom.controlsRight )
|
|
1895
|
+
.concat( dom.controlsUp )
|
|
1896
|
+
.concat( dom.controlsDown )
|
|
1897
|
+
.concat( dom.controlsPrev )
|
|
1898
|
+
.concat( dom.controlsNext ).forEach( function( node ) {
|
|
1899
|
+
node.classList.remove( 'enabled' );
|
|
1900
|
+
node.classList.remove( 'fragmented' );
|
|
1901
|
+
} );
|
|
1631
1902
|
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1903
|
+
// Add the 'enabled' class to the available routes
|
|
1904
|
+
if( routes.left ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
|
1905
|
+
if( routes.right ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
|
1906
|
+
if( routes.up ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
|
1907
|
+
if( routes.down ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
|
1635
1908
|
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1909
|
+
// Prev/next buttons
|
|
1910
|
+
if( routes.left || routes.up ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
|
1911
|
+
if( routes.right || routes.down ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'enabled' ); } );
|
|
1912
|
+
|
|
1913
|
+
// Highlight fragment directions
|
|
1914
|
+
if( currentSlide ) {
|
|
1915
|
+
|
|
1916
|
+
// Always apply fragment decorator to prev/next buttons
|
|
1917
|
+
if( fragments.prev ) dom.controlsPrev.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
|
1918
|
+
if( fragments.next ) dom.controlsNext.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
|
1919
|
+
|
|
1920
|
+
// Apply fragment decorators to directional buttons based on
|
|
1921
|
+
// what slide axis they are in
|
|
1922
|
+
if( isVerticalSlide( currentSlide ) ) {
|
|
1923
|
+
if( fragments.prev ) dom.controlsUp.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
|
1924
|
+
if( fragments.next ) dom.controlsDown.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
|
1925
|
+
}
|
|
1926
|
+
else {
|
|
1927
|
+
if( fragments.prev ) dom.controlsLeft.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
|
1928
|
+
if( fragments.next ) dom.controlsRight.forEach( function( el ) { el.classList.add( 'fragmented', 'enabled' ); } );
|
|
1646
1929
|
}
|
|
1647
1930
|
|
|
1648
1931
|
}
|
|
@@ -1650,33 +1933,110 @@ var Reveal = (function(){
|
|
|
1650
1933
|
}
|
|
1651
1934
|
|
|
1652
1935
|
/**
|
|
1653
|
-
* Updates the background elements to reflect the current
|
|
1936
|
+
* Updates the background elements to reflect the current
|
|
1654
1937
|
* slide.
|
|
1938
|
+
*
|
|
1939
|
+
* @param {Boolean} includeAll If true, the backgrounds of
|
|
1940
|
+
* all vertical slides (not just the present) will be updated.
|
|
1655
1941
|
*/
|
|
1656
|
-
function updateBackground() {
|
|
1942
|
+
function updateBackground( includeAll ) {
|
|
1943
|
+
|
|
1944
|
+
var currentBackground = null;
|
|
1945
|
+
|
|
1946
|
+
// Reverse past/future classes when in RTL mode
|
|
1947
|
+
var horizontalPast = config.rtl ? 'future' : 'past',
|
|
1948
|
+
horizontalFuture = config.rtl ? 'past' : 'future';
|
|
1657
1949
|
|
|
1658
|
-
// Update the classes of all backgrounds to match the
|
|
1950
|
+
// Update the classes of all backgrounds to match the
|
|
1659
1951
|
// states of their slides (past/present/future)
|
|
1660
1952
|
toArray( dom.background.childNodes ).forEach( function( backgroundh, h ) {
|
|
1661
1953
|
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1954
|
+
if( h < indexh ) {
|
|
1955
|
+
backgroundh.className = 'slide-background ' + horizontalPast;
|
|
1956
|
+
}
|
|
1957
|
+
else if ( h > indexh ) {
|
|
1958
|
+
backgroundh.className = 'slide-background ' + horizontalFuture;
|
|
1959
|
+
}
|
|
1960
|
+
else {
|
|
1961
|
+
backgroundh.className = 'slide-background present';
|
|
1962
|
+
|
|
1963
|
+
// Store a reference to the current background element
|
|
1964
|
+
currentBackground = backgroundh;
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
if( includeAll || h === indexh ) {
|
|
1968
|
+
toArray( backgroundh.childNodes ).forEach( function( backgroundv, v ) {
|
|
1969
|
+
|
|
1970
|
+
if( v < indexv ) {
|
|
1971
|
+
backgroundv.className = 'slide-background past';
|
|
1972
|
+
}
|
|
1973
|
+
else if ( v > indexv ) {
|
|
1974
|
+
backgroundv.className = 'slide-background future';
|
|
1975
|
+
}
|
|
1976
|
+
else {
|
|
1977
|
+
backgroundv.className = 'slide-background present';
|
|
1665
1978
|
|
|
1666
|
-
|
|
1979
|
+
// Only if this is the present horizontal and vertical slide
|
|
1980
|
+
if( h === indexh ) currentBackground = backgroundv;
|
|
1981
|
+
}
|
|
1667
1982
|
|
|
1668
|
-
|
|
1983
|
+
} );
|
|
1984
|
+
}
|
|
1669
1985
|
|
|
1670
|
-
|
|
1986
|
+
} );
|
|
1671
1987
|
|
|
1672
|
-
|
|
1988
|
+
// Don't transition between identical backgrounds. This
|
|
1989
|
+
// prevents unwanted flicker.
|
|
1990
|
+
if( currentBackground ) {
|
|
1991
|
+
var previousBackgroundHash = previousBackground ? previousBackground.getAttribute( 'data-background-hash' ) : null;
|
|
1992
|
+
var currentBackgroundHash = currentBackground.getAttribute( 'data-background-hash' );
|
|
1993
|
+
if( currentBackgroundHash && currentBackgroundHash === previousBackgroundHash && currentBackground !== previousBackground ) {
|
|
1994
|
+
dom.background.classList.add( 'no-transition' );
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
previousBackground = currentBackground;
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
// Allow the first background to apply without transition
|
|
2001
|
+
setTimeout( function() {
|
|
2002
|
+
dom.background.classList.remove( 'no-transition' );
|
|
2003
|
+
}, 1 );
|
|
2004
|
+
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
/**
|
|
2008
|
+
* Updates the position of the parallax background based
|
|
2009
|
+
* on the current slide index.
|
|
2010
|
+
*/
|
|
2011
|
+
function updateParallax() {
|
|
2012
|
+
|
|
2013
|
+
if( config.parallaxBackgroundImage ) {
|
|
2014
|
+
|
|
2015
|
+
var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ),
|
|
2016
|
+
verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
|
|
2017
|
+
|
|
2018
|
+
var backgroundSize = dom.background.style.backgroundSize.split( ' ' ),
|
|
2019
|
+
backgroundWidth, backgroundHeight;
|
|
2020
|
+
|
|
2021
|
+
if( backgroundSize.length === 1 ) {
|
|
2022
|
+
backgroundWidth = backgroundHeight = parseInt( backgroundSize[0], 10 );
|
|
2023
|
+
}
|
|
2024
|
+
else {
|
|
2025
|
+
backgroundWidth = parseInt( backgroundSize[0], 10 );
|
|
2026
|
+
backgroundHeight = parseInt( backgroundSize[1], 10 );
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
var slideWidth = dom.background.offsetWidth;
|
|
2030
|
+
var horizontalSlideCount = horizontalSlides.length;
|
|
2031
|
+
var horizontalOffset = -( backgroundWidth - slideWidth ) / ( horizontalSlideCount-1 ) * indexh;
|
|
2032
|
+
|
|
2033
|
+
var slideHeight = dom.background.offsetHeight;
|
|
2034
|
+
var verticalSlideCount = verticalSlides.length;
|
|
2035
|
+
var verticalOffset = verticalSlideCount > 0 ? -( backgroundHeight - slideHeight ) / ( verticalSlideCount-1 ) * indexv : 0;
|
|
1673
2036
|
|
|
1674
|
-
|
|
2037
|
+
dom.background.style.backgroundPosition = horizontalOffset + 'px ' + verticalOffset + 'px';
|
|
1675
2038
|
|
|
1676
|
-
|
|
1677
|
-
setTimeout( function() {
|
|
1678
|
-
dom.background.classList.remove( 'no-transition' );
|
|
1679
|
-
}, 1 );
|
|
2039
|
+
}
|
|
1680
2040
|
|
|
1681
2041
|
}
|
|
1682
2042
|
|
|
@@ -1737,7 +2097,7 @@ var Reveal = (function(){
|
|
|
1737
2097
|
*/
|
|
1738
2098
|
function startEmbeddedContent( slide ) {
|
|
1739
2099
|
|
|
1740
|
-
if( slide ) {
|
|
2100
|
+
if( slide && !isSpeakerNotes() ) {
|
|
1741
2101
|
// HTML5 media elements
|
|
1742
2102
|
toArray( slide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
|
|
1743
2103
|
if( el.hasAttribute( 'data-autoplay' ) ) {
|
|
@@ -1745,10 +2105,15 @@ var Reveal = (function(){
|
|
|
1745
2105
|
}
|
|
1746
2106
|
} );
|
|
1747
2107
|
|
|
2108
|
+
// iframe embeds
|
|
2109
|
+
toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
|
|
2110
|
+
el.contentWindow.postMessage( 'slide:start', '*' );
|
|
2111
|
+
});
|
|
2112
|
+
|
|
1748
2113
|
// YouTube embeds
|
|
1749
2114
|
toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
|
|
1750
2115
|
if( el.hasAttribute( 'data-autoplay' ) ) {
|
|
1751
|
-
el.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
|
|
2116
|
+
el.contentWindow.postMessage( '{"event":"command","func":"playVideo","args":""}', '*' );
|
|
1752
2117
|
}
|
|
1753
2118
|
});
|
|
1754
2119
|
}
|
|
@@ -1769,16 +2134,31 @@ var Reveal = (function(){
|
|
|
1769
2134
|
}
|
|
1770
2135
|
} );
|
|
1771
2136
|
|
|
2137
|
+
// iframe embeds
|
|
2138
|
+
toArray( slide.querySelectorAll( 'iframe' ) ).forEach( function( el ) {
|
|
2139
|
+
el.contentWindow.postMessage( 'slide:stop', '*' );
|
|
2140
|
+
});
|
|
2141
|
+
|
|
1772
2142
|
// YouTube embeds
|
|
1773
2143
|
toArray( slide.querySelectorAll( 'iframe[src*="youtube.com/embed/"]' ) ).forEach( function( el ) {
|
|
1774
2144
|
if( !el.hasAttribute( 'data-ignore' ) && typeof el.contentWindow.postMessage === 'function' ) {
|
|
1775
|
-
el.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
|
|
2145
|
+
el.contentWindow.postMessage( '{"event":"command","func":"pauseVideo","args":""}', '*' );
|
|
1776
2146
|
}
|
|
1777
2147
|
});
|
|
1778
2148
|
}
|
|
1779
2149
|
|
|
1780
2150
|
}
|
|
1781
2151
|
|
|
2152
|
+
/**
|
|
2153
|
+
* Checks if this presentation is running inside of the
|
|
2154
|
+
* speaker notes window.
|
|
2155
|
+
*/
|
|
2156
|
+
function isSpeakerNotes() {
|
|
2157
|
+
|
|
2158
|
+
return !!window.location.search.match( /receiver/gi );
|
|
2159
|
+
|
|
2160
|
+
}
|
|
2161
|
+
|
|
1782
2162
|
/**
|
|
1783
2163
|
* Reads the current URL (hash) and navigates accordingly.
|
|
1784
2164
|
*/
|
|
@@ -1803,7 +2183,7 @@ var Reveal = (function(){
|
|
|
1803
2183
|
}
|
|
1804
2184
|
// If the slide doesn't exist, navigate to the current slide
|
|
1805
2185
|
else {
|
|
1806
|
-
slide( indexh, indexv );
|
|
2186
|
+
slide( indexh || 0, indexv || 0 );
|
|
1807
2187
|
}
|
|
1808
2188
|
}
|
|
1809
2189
|
else {
|
|
@@ -1811,7 +2191,9 @@ var Reveal = (function(){
|
|
|
1811
2191
|
var h = parseInt( bits[0], 10 ) || 0,
|
|
1812
2192
|
v = parseInt( bits[1], 10 ) || 0;
|
|
1813
2193
|
|
|
1814
|
-
|
|
2194
|
+
if( h !== indexh || v !== indexv ) {
|
|
2195
|
+
slide( h, v );
|
|
2196
|
+
}
|
|
1815
2197
|
}
|
|
1816
2198
|
|
|
1817
2199
|
}
|
|
@@ -1888,9 +2270,10 @@ var Reveal = (function(){
|
|
|
1888
2270
|
}
|
|
1889
2271
|
|
|
1890
2272
|
if( !slide && currentSlide ) {
|
|
1891
|
-
var
|
|
1892
|
-
if(
|
|
1893
|
-
|
|
2273
|
+
var hasFragments = currentSlide.querySelectorAll( '.fragment' ).length > 0;
|
|
2274
|
+
if( hasFragments ) {
|
|
2275
|
+
var visibleFragments = currentSlide.querySelectorAll( '.fragment.visible' );
|
|
2276
|
+
f = visibleFragments.length - 1;
|
|
1894
2277
|
}
|
|
1895
2278
|
}
|
|
1896
2279
|
|
|
@@ -1899,83 +2282,226 @@ var Reveal = (function(){
|
|
|
1899
2282
|
}
|
|
1900
2283
|
|
|
1901
2284
|
/**
|
|
1902
|
-
*
|
|
2285
|
+
* Return a sorted fragments list, ordered by an increasing
|
|
2286
|
+
* "data-fragment-index" attribute.
|
|
1903
2287
|
*
|
|
1904
|
-
*
|
|
1905
|
-
*
|
|
2288
|
+
* Fragments will be revealed in the order that they are returned by
|
|
2289
|
+
* this function, so you can use the index attributes to control the
|
|
2290
|
+
* order of fragment appearance.
|
|
2291
|
+
*
|
|
2292
|
+
* To maintain a sensible default fragment order, fragments are presumed
|
|
2293
|
+
* to be passed in document order. This function adds a "fragment-index"
|
|
2294
|
+
* attribute to each node if such an attribute is not already present,
|
|
2295
|
+
* and sets that attribute to an integer value which is the position of
|
|
2296
|
+
* the fragment within the fragments list.
|
|
1906
2297
|
*/
|
|
1907
|
-
function
|
|
1908
|
-
|
|
1909
|
-
if( currentSlide && config.fragments ) {
|
|
1910
|
-
var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment:not(.visible)' ) );
|
|
2298
|
+
function sortFragments( fragments ) {
|
|
1911
2299
|
|
|
1912
|
-
|
|
1913
|
-
// Find the index of the next fragment
|
|
1914
|
-
var index = fragments[0].getAttribute( 'data-fragment-index' );
|
|
2300
|
+
fragments = toArray( fragments );
|
|
1915
2301
|
|
|
1916
|
-
|
|
1917
|
-
|
|
2302
|
+
var ordered = [],
|
|
2303
|
+
unordered = [],
|
|
2304
|
+
sorted = [];
|
|
1918
2305
|
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
2306
|
+
// Group ordered and unordered elements
|
|
2307
|
+
fragments.forEach( function( fragment, i ) {
|
|
2308
|
+
if( fragment.hasAttribute( 'data-fragment-index' ) ) {
|
|
2309
|
+
var index = parseInt( fragment.getAttribute( 'data-fragment-index' ), 10 );
|
|
1922
2310
|
|
|
1923
|
-
|
|
1924
|
-
|
|
2311
|
+
if( !ordered[index] ) {
|
|
2312
|
+
ordered[index] = [];
|
|
2313
|
+
}
|
|
1925
2314
|
|
|
1926
|
-
|
|
1927
|
-
return true;
|
|
2315
|
+
ordered[index].push( fragment );
|
|
1928
2316
|
}
|
|
1929
|
-
|
|
2317
|
+
else {
|
|
2318
|
+
unordered.push( [ fragment ] );
|
|
2319
|
+
}
|
|
2320
|
+
} );
|
|
1930
2321
|
|
|
1931
|
-
|
|
2322
|
+
// Append fragments without explicit indices in their
|
|
2323
|
+
// DOM order
|
|
2324
|
+
ordered = ordered.concat( unordered );
|
|
2325
|
+
|
|
2326
|
+
// Manually count the index up per group to ensure there
|
|
2327
|
+
// are no gaps
|
|
2328
|
+
var index = 0;
|
|
2329
|
+
|
|
2330
|
+
// Push all fragments in their sorted order to an array,
|
|
2331
|
+
// this flattens the groups
|
|
2332
|
+
ordered.forEach( function( group ) {
|
|
2333
|
+
group.forEach( function( fragment ) {
|
|
2334
|
+
sorted.push( fragment );
|
|
2335
|
+
fragment.setAttribute( 'data-fragment-index', index );
|
|
2336
|
+
} );
|
|
2337
|
+
|
|
2338
|
+
index ++;
|
|
2339
|
+
} );
|
|
2340
|
+
|
|
2341
|
+
return sorted;
|
|
1932
2342
|
|
|
1933
2343
|
}
|
|
1934
2344
|
|
|
1935
2345
|
/**
|
|
1936
|
-
* Navigate to the
|
|
2346
|
+
* Navigate to the specified slide fragment.
|
|
1937
2347
|
*
|
|
1938
|
-
* @
|
|
1939
|
-
*
|
|
2348
|
+
* @param {Number} index The index of the fragment that
|
|
2349
|
+
* should be shown, -1 means all are invisible
|
|
2350
|
+
* @param {Number} offset Integer offset to apply to the
|
|
2351
|
+
* fragment index
|
|
2352
|
+
*
|
|
2353
|
+
* @return {Boolean} true if a change was made in any
|
|
2354
|
+
* fragments visibility as part of this call
|
|
1940
2355
|
*/
|
|
1941
|
-
function
|
|
2356
|
+
function navigateFragment( index, offset ) {
|
|
1942
2357
|
|
|
1943
2358
|
if( currentSlide && config.fragments ) {
|
|
1944
|
-
var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) );
|
|
1945
2359
|
|
|
2360
|
+
var fragments = sortFragments( currentSlide.querySelectorAll( '.fragment' ) );
|
|
1946
2361
|
if( fragments.length ) {
|
|
1947
|
-
// Find the index of the previous fragment
|
|
1948
|
-
var index = fragments[ fragments.length - 1 ].getAttribute( 'data-fragment-index' );
|
|
1949
2362
|
|
|
1950
|
-
//
|
|
1951
|
-
|
|
2363
|
+
// If no index is specified, find the current
|
|
2364
|
+
if( typeof index !== 'number' ) {
|
|
2365
|
+
var lastVisibleFragment = sortFragments( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
|
|
2366
|
+
|
|
2367
|
+
if( lastVisibleFragment ) {
|
|
2368
|
+
index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );
|
|
2369
|
+
}
|
|
2370
|
+
else {
|
|
2371
|
+
index = -1;
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
// If an offset is specified, apply it to the index
|
|
2376
|
+
if( typeof offset === 'number' ) {
|
|
2377
|
+
index += offset;
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
var fragmentsShown = [],
|
|
2381
|
+
fragmentsHidden = [];
|
|
2382
|
+
|
|
2383
|
+
toArray( fragments ).forEach( function( element, i ) {
|
|
2384
|
+
|
|
2385
|
+
if( element.hasAttribute( 'data-fragment-index' ) ) {
|
|
2386
|
+
i = parseInt( element.getAttribute( 'data-fragment-index' ), 10 );
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
// Visible fragments
|
|
2390
|
+
if( i <= index ) {
|
|
2391
|
+
if( !element.classList.contains( 'visible' ) ) fragmentsShown.push( element );
|
|
2392
|
+
element.classList.add( 'visible' );
|
|
2393
|
+
element.classList.remove( 'current-fragment' );
|
|
2394
|
+
|
|
2395
|
+
if( i === index ) {
|
|
2396
|
+
element.classList.add( 'current-fragment' );
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
// Hidden fragments
|
|
2400
|
+
else {
|
|
2401
|
+
if( element.classList.contains( 'visible' ) ) fragmentsHidden.push( element );
|
|
2402
|
+
element.classList.remove( 'visible' );
|
|
2403
|
+
element.classList.remove( 'current-fragment' );
|
|
2404
|
+
}
|
|
2405
|
+
|
|
1952
2406
|
|
|
1953
|
-
toArray( fragments ).forEach( function( f ) {
|
|
1954
|
-
f.classList.remove( 'visible' );
|
|
1955
2407
|
} );
|
|
1956
2408
|
|
|
1957
|
-
|
|
1958
|
-
|
|
2409
|
+
if( fragmentsHidden.length ) {
|
|
2410
|
+
dispatchEvent( 'fragmenthidden', { fragment: fragmentsHidden[0], fragments: fragmentsHidden } );
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2413
|
+
if( fragmentsShown.length ) {
|
|
2414
|
+
dispatchEvent( 'fragmentshown', { fragment: fragmentsShown[0], fragments: fragmentsShown } );
|
|
2415
|
+
}
|
|
1959
2416
|
|
|
1960
2417
|
updateControls();
|
|
1961
|
-
|
|
2418
|
+
|
|
2419
|
+
return !!( fragmentsShown.length || fragmentsHidden.length );
|
|
2420
|
+
|
|
1962
2421
|
}
|
|
2422
|
+
|
|
1963
2423
|
}
|
|
1964
2424
|
|
|
1965
2425
|
return false;
|
|
1966
2426
|
|
|
1967
2427
|
}
|
|
1968
2428
|
|
|
2429
|
+
/**
|
|
2430
|
+
* Navigate to the next slide fragment.
|
|
2431
|
+
*
|
|
2432
|
+
* @return {Boolean} true if there was a next fragment,
|
|
2433
|
+
* false otherwise
|
|
2434
|
+
*/
|
|
2435
|
+
function nextFragment() {
|
|
2436
|
+
|
|
2437
|
+
return navigateFragment( null, 1 );
|
|
2438
|
+
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
/**
|
|
2442
|
+
* Navigate to the previous slide fragment.
|
|
2443
|
+
*
|
|
2444
|
+
* @return {Boolean} true if there was a previous fragment,
|
|
2445
|
+
* false otherwise
|
|
2446
|
+
*/
|
|
2447
|
+
function previousFragment() {
|
|
2448
|
+
|
|
2449
|
+
return navigateFragment( null, -1 );
|
|
2450
|
+
|
|
2451
|
+
}
|
|
2452
|
+
|
|
1969
2453
|
/**
|
|
1970
2454
|
* Cues a new automated slide if enabled in the config.
|
|
1971
2455
|
*/
|
|
1972
2456
|
function cueAutoSlide() {
|
|
1973
2457
|
|
|
1974
|
-
|
|
2458
|
+
cancelAutoSlide();
|
|
2459
|
+
|
|
2460
|
+
if( currentSlide ) {
|
|
2461
|
+
|
|
2462
|
+
var parentAutoSlide = currentSlide.parentNode ? currentSlide.parentNode.getAttribute( 'data-autoslide' ) : null;
|
|
2463
|
+
var slideAutoSlide = currentSlide.getAttribute( 'data-autoslide' );
|
|
2464
|
+
|
|
2465
|
+
// Pick value in the following priority order:
|
|
2466
|
+
// 1. Current slide's data-autoslide
|
|
2467
|
+
// 2. Parent slide's data-autoslide
|
|
2468
|
+
// 3. Global autoSlide setting
|
|
2469
|
+
if( slideAutoSlide ) {
|
|
2470
|
+
autoSlide = parseInt( slideAutoSlide, 10 );
|
|
2471
|
+
}
|
|
2472
|
+
else if( parentAutoSlide ) {
|
|
2473
|
+
autoSlide = parseInt( parentAutoSlide, 10 );
|
|
2474
|
+
}
|
|
2475
|
+
else {
|
|
2476
|
+
autoSlide = config.autoSlide;
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
// If there are media elements with data-autoplay,
|
|
2480
|
+
// automatically set the autoSlide duration to the
|
|
2481
|
+
// length of that media
|
|
2482
|
+
toArray( currentSlide.querySelectorAll( 'video, audio' ) ).forEach( function( el ) {
|
|
2483
|
+
if( el.hasAttribute( 'data-autoplay' ) ) {
|
|
2484
|
+
if( autoSlide && el.duration * 1000 > autoSlide ) {
|
|
2485
|
+
autoSlide = ( el.duration * 1000 ) + 1000;
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
} );
|
|
2489
|
+
|
|
2490
|
+
// Cue the next auto-slide if:
|
|
2491
|
+
// - There is an autoSlide value
|
|
2492
|
+
// - Auto-sliding isn't paused by the user
|
|
2493
|
+
// - The presentation isn't paused
|
|
2494
|
+
// - The overview isn't active
|
|
2495
|
+
// - The presentation isn't over
|
|
2496
|
+
if( autoSlide && !autoSlidePaused && !isPaused() && !isOverview() && ( !Reveal.isLastSlide() || config.loop === true ) ) {
|
|
2497
|
+
autoSlideTimeout = setTimeout( navigateNext, autoSlide );
|
|
2498
|
+
autoSlideStartTime = Date.now();
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
if( autoSlidePlayer ) {
|
|
2502
|
+
autoSlidePlayer.setPlaying( autoSlideTimeout !== -1 );
|
|
2503
|
+
}
|
|
1975
2504
|
|
|
1976
|
-
// Cue the next auto-slide if enabled
|
|
1977
|
-
if( autoSlide && !isPaused() && !isOverview() ) {
|
|
1978
|
-
autoSlideTimeout = setTimeout( navigateNext, autoSlide );
|
|
1979
2505
|
}
|
|
1980
2506
|
|
|
1981
2507
|
}
|
|
@@ -1986,6 +2512,25 @@ var Reveal = (function(){
|
|
|
1986
2512
|
function cancelAutoSlide() {
|
|
1987
2513
|
|
|
1988
2514
|
clearTimeout( autoSlideTimeout );
|
|
2515
|
+
autoSlideTimeout = -1;
|
|
2516
|
+
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
function pauseAutoSlide() {
|
|
2520
|
+
|
|
2521
|
+
autoSlidePaused = true;
|
|
2522
|
+
clearTimeout( autoSlideTimeout );
|
|
2523
|
+
|
|
2524
|
+
if( autoSlidePlayer ) {
|
|
2525
|
+
autoSlidePlayer.setPlaying( false );
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
function resumeAutoSlide() {
|
|
2531
|
+
|
|
2532
|
+
autoSlidePaused = false;
|
|
2533
|
+
cueAutoSlide();
|
|
1989
2534
|
|
|
1990
2535
|
}
|
|
1991
2536
|
|
|
@@ -2085,14 +2630,25 @@ var Reveal = (function(){
|
|
|
2085
2630
|
// ----------------------------- EVENTS -------------------------------//
|
|
2086
2631
|
// --------------------------------------------------------------------//
|
|
2087
2632
|
|
|
2633
|
+
/**
|
|
2634
|
+
* Called by all event handlers that are based on user
|
|
2635
|
+
* input.
|
|
2636
|
+
*/
|
|
2637
|
+
function onUserInput( event ) {
|
|
2638
|
+
|
|
2639
|
+
if( config.autoSlideStoppable ) {
|
|
2640
|
+
pauseAutoSlide();
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
}
|
|
2088
2644
|
|
|
2089
2645
|
/**
|
|
2090
2646
|
* Handler for the document level 'keydown' event.
|
|
2091
|
-
*
|
|
2092
|
-
* @param {Object} event
|
|
2093
2647
|
*/
|
|
2094
2648
|
function onDocumentKeyDown( event ) {
|
|
2095
2649
|
|
|
2650
|
+
onUserInput( event );
|
|
2651
|
+
|
|
2096
2652
|
// Check if there's a focused element that could be using
|
|
2097
2653
|
// the keyboard
|
|
2098
2654
|
var activeElement = document.activeElement;
|
|
@@ -2119,7 +2675,7 @@ var Reveal = (function(){
|
|
|
2119
2675
|
|
|
2120
2676
|
var value = config.keyboard[ key ];
|
|
2121
2677
|
|
|
2122
|
-
//
|
|
2678
|
+
// Callback function
|
|
2123
2679
|
if( typeof value === 'function' ) {
|
|
2124
2680
|
value.apply( null, [ event ] );
|
|
2125
2681
|
}
|
|
@@ -2178,8 +2734,14 @@ var Reveal = (function(){
|
|
|
2178
2734
|
if( triggered ) {
|
|
2179
2735
|
event.preventDefault();
|
|
2180
2736
|
}
|
|
2181
|
-
|
|
2182
|
-
|
|
2737
|
+
// ESC or O key
|
|
2738
|
+
else if ( ( event.keyCode === 27 || event.keyCode === 79 ) && features.transforms3d ) {
|
|
2739
|
+
if( dom.preview ) {
|
|
2740
|
+
closePreview();
|
|
2741
|
+
}
|
|
2742
|
+
else {
|
|
2743
|
+
toggleOverview();
|
|
2744
|
+
}
|
|
2183
2745
|
|
|
2184
2746
|
event.preventDefault();
|
|
2185
2747
|
}
|
|
@@ -2220,11 +2782,13 @@ var Reveal = (function(){
|
|
|
2220
2782
|
function onTouchMove( event ) {
|
|
2221
2783
|
|
|
2222
2784
|
// Each touch should only trigger one action
|
|
2223
|
-
if( !touch.
|
|
2785
|
+
if( !touch.captured ) {
|
|
2786
|
+
onUserInput( event );
|
|
2787
|
+
|
|
2224
2788
|
var currentX = event.touches[0].clientX;
|
|
2225
2789
|
var currentY = event.touches[0].clientY;
|
|
2226
2790
|
|
|
2227
|
-
// If the touch started
|
|
2791
|
+
// If the touch started with two points and still has
|
|
2228
2792
|
// two active touches; test for the pinch gesture
|
|
2229
2793
|
if( event.touches.length === 2 && touch.startCount === 2 && config.overview ) {
|
|
2230
2794
|
|
|
@@ -2240,7 +2804,7 @@ var Reveal = (function(){
|
|
|
2240
2804
|
// If the span is larger than the desire amount we've got
|
|
2241
2805
|
// ourselves a pinch
|
|
2242
2806
|
if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) {
|
|
2243
|
-
touch.
|
|
2807
|
+
touch.captured = true;
|
|
2244
2808
|
|
|
2245
2809
|
if( currentSpan < touch.startSpan ) {
|
|
2246
2810
|
activateOverview();
|
|
@@ -2260,23 +2824,34 @@ var Reveal = (function(){
|
|
|
2260
2824
|
deltaY = currentY - touch.startY;
|
|
2261
2825
|
|
|
2262
2826
|
if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
|
|
2263
|
-
touch.
|
|
2827
|
+
touch.captured = true;
|
|
2264
2828
|
navigateLeft();
|
|
2265
2829
|
}
|
|
2266
2830
|
else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
|
|
2267
|
-
touch.
|
|
2831
|
+
touch.captured = true;
|
|
2268
2832
|
navigateRight();
|
|
2269
2833
|
}
|
|
2270
2834
|
else if( deltaY > touch.threshold ) {
|
|
2271
|
-
touch.
|
|
2835
|
+
touch.captured = true;
|
|
2272
2836
|
navigateUp();
|
|
2273
2837
|
}
|
|
2274
2838
|
else if( deltaY < -touch.threshold ) {
|
|
2275
|
-
touch.
|
|
2839
|
+
touch.captured = true;
|
|
2276
2840
|
navigateDown();
|
|
2277
2841
|
}
|
|
2278
2842
|
|
|
2279
|
-
|
|
2843
|
+
// If we're embedded, only block touch events if they have
|
|
2844
|
+
// triggered an action
|
|
2845
|
+
if( config.embedded ) {
|
|
2846
|
+
if( touch.captured || isVerticalSlide( currentSlide ) ) {
|
|
2847
|
+
event.preventDefault();
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2850
|
+
// Not embedded? Block them all to avoid needless tossing
|
|
2851
|
+
// around of the viewport in iOS
|
|
2852
|
+
else {
|
|
2853
|
+
event.preventDefault();
|
|
2854
|
+
}
|
|
2280
2855
|
|
|
2281
2856
|
}
|
|
2282
2857
|
}
|
|
@@ -2293,7 +2868,7 @@ var Reveal = (function(){
|
|
|
2293
2868
|
*/
|
|
2294
2869
|
function onTouchEnd( event ) {
|
|
2295
2870
|
|
|
2296
|
-
touch.
|
|
2871
|
+
touch.captured = false;
|
|
2297
2872
|
|
|
2298
2873
|
}
|
|
2299
2874
|
|
|
@@ -2363,6 +2938,8 @@ var Reveal = (function(){
|
|
|
2363
2938
|
*/
|
|
2364
2939
|
function onProgressClicked( event ) {
|
|
2365
2940
|
|
|
2941
|
+
onUserInput( event );
|
|
2942
|
+
|
|
2366
2943
|
event.preventDefault();
|
|
2367
2944
|
|
|
2368
2945
|
var slidesTotal = toArray( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) ).length;
|
|
@@ -2375,12 +2952,12 @@ var Reveal = (function(){
|
|
|
2375
2952
|
/**
|
|
2376
2953
|
* Event handler for navigation control buttons.
|
|
2377
2954
|
*/
|
|
2378
|
-
function onNavigateLeftClicked( event ) { event.preventDefault(); navigateLeft(); }
|
|
2379
|
-
function onNavigateRightClicked( event ) { event.preventDefault(); navigateRight(); }
|
|
2380
|
-
function onNavigateUpClicked( event ) { event.preventDefault(); navigateUp(); }
|
|
2381
|
-
function onNavigateDownClicked( event ) { event.preventDefault(); navigateDown(); }
|
|
2382
|
-
function onNavigatePrevClicked( event ) { event.preventDefault(); navigatePrev(); }
|
|
2383
|
-
function onNavigateNextClicked( event ) { event.preventDefault(); navigateNext(); }
|
|
2955
|
+
function onNavigateLeftClicked( event ) { event.preventDefault(); onUserInput(); navigateLeft(); }
|
|
2956
|
+
function onNavigateRightClicked( event ) { event.preventDefault(); onUserInput(); navigateRight(); }
|
|
2957
|
+
function onNavigateUpClicked( event ) { event.preventDefault(); onUserInput(); navigateUp(); }
|
|
2958
|
+
function onNavigateDownClicked( event ) { event.preventDefault(); onUserInput(); navigateDown(); }
|
|
2959
|
+
function onNavigatePrevClicked( event ) { event.preventDefault(); onUserInput(); navigatePrev(); }
|
|
2960
|
+
function onNavigateNextClicked( event ) { event.preventDefault(); onUserInput(); navigateNext(); }
|
|
2384
2961
|
|
|
2385
2962
|
/**
|
|
2386
2963
|
* Handler for the window level 'hashchange' event.
|
|
@@ -2400,6 +2977,24 @@ var Reveal = (function(){
|
|
|
2400
2977
|
|
|
2401
2978
|
}
|
|
2402
2979
|
|
|
2980
|
+
/**
|
|
2981
|
+
* Handle for the window level 'visibilitychange' event.
|
|
2982
|
+
*/
|
|
2983
|
+
function onPageVisibilityChange( event ) {
|
|
2984
|
+
|
|
2985
|
+
var isHidden = document.webkitHidden ||
|
|
2986
|
+
document.msHidden ||
|
|
2987
|
+
document.hidden;
|
|
2988
|
+
|
|
2989
|
+
// If, after clicking a link or similar and we're coming back,
|
|
2990
|
+
// focus the document.body to ensure we can use keyboard shortcuts
|
|
2991
|
+
if( isHidden === false && document.activeElement !== document.body ) {
|
|
2992
|
+
document.activeElement.blur();
|
|
2993
|
+
document.body.focus();
|
|
2994
|
+
}
|
|
2995
|
+
|
|
2996
|
+
}
|
|
2997
|
+
|
|
2403
2998
|
/**
|
|
2404
2999
|
* Invoked when a slide is and we're in the overview.
|
|
2405
3000
|
*/
|
|
@@ -2446,6 +3041,191 @@ var Reveal = (function(){
|
|
|
2446
3041
|
|
|
2447
3042
|
}
|
|
2448
3043
|
|
|
3044
|
+
/**
|
|
3045
|
+
* Handles click on the auto-sliding controls element.
|
|
3046
|
+
*/
|
|
3047
|
+
function onAutoSlidePlayerClick( event ) {
|
|
3048
|
+
|
|
3049
|
+
// Replay
|
|
3050
|
+
if( Reveal.isLastSlide() && config.loop === false ) {
|
|
3051
|
+
slide( 0, 0 );
|
|
3052
|
+
resumeAutoSlide();
|
|
3053
|
+
}
|
|
3054
|
+
// Resume
|
|
3055
|
+
else if( autoSlidePaused ) {
|
|
3056
|
+
resumeAutoSlide();
|
|
3057
|
+
}
|
|
3058
|
+
// Pause
|
|
3059
|
+
else {
|
|
3060
|
+
pauseAutoSlide();
|
|
3061
|
+
}
|
|
3062
|
+
|
|
3063
|
+
}
|
|
3064
|
+
|
|
3065
|
+
|
|
3066
|
+
// --------------------------------------------------------------------//
|
|
3067
|
+
// ------------------------ PLAYBACK COMPONENT ------------------------//
|
|
3068
|
+
// --------------------------------------------------------------------//
|
|
3069
|
+
|
|
3070
|
+
|
|
3071
|
+
/**
|
|
3072
|
+
* Constructor for the playback component, which displays
|
|
3073
|
+
* play/pause/progress controls.
|
|
3074
|
+
*
|
|
3075
|
+
* @param {HTMLElement} container The component will append
|
|
3076
|
+
* itself to this
|
|
3077
|
+
* @param {Function} progressCheck A method which will be
|
|
3078
|
+
* called frequently to get the current progress on a range
|
|
3079
|
+
* of 0-1
|
|
3080
|
+
*/
|
|
3081
|
+
function Playback( container, progressCheck ) {
|
|
3082
|
+
|
|
3083
|
+
// Cosmetics
|
|
3084
|
+
this.diameter = 50;
|
|
3085
|
+
this.thickness = 3;
|
|
3086
|
+
|
|
3087
|
+
// Flags if we are currently playing
|
|
3088
|
+
this.playing = false;
|
|
3089
|
+
|
|
3090
|
+
// Current progress on a 0-1 range
|
|
3091
|
+
this.progress = 0;
|
|
3092
|
+
|
|
3093
|
+
// Used to loop the animation smoothly
|
|
3094
|
+
this.progressOffset = 1;
|
|
3095
|
+
|
|
3096
|
+
this.container = container;
|
|
3097
|
+
this.progressCheck = progressCheck;
|
|
3098
|
+
|
|
3099
|
+
this.canvas = document.createElement( 'canvas' );
|
|
3100
|
+
this.canvas.className = 'playback';
|
|
3101
|
+
this.canvas.width = this.diameter;
|
|
3102
|
+
this.canvas.height = this.diameter;
|
|
3103
|
+
this.context = this.canvas.getContext( '2d' );
|
|
3104
|
+
|
|
3105
|
+
this.container.appendChild( this.canvas );
|
|
3106
|
+
|
|
3107
|
+
this.render();
|
|
3108
|
+
|
|
3109
|
+
}
|
|
3110
|
+
|
|
3111
|
+
Playback.prototype.setPlaying = function( value ) {
|
|
3112
|
+
|
|
3113
|
+
var wasPlaying = this.playing;
|
|
3114
|
+
|
|
3115
|
+
this.playing = value;
|
|
3116
|
+
|
|
3117
|
+
// Start repainting if we weren't already
|
|
3118
|
+
if( !wasPlaying && this.playing ) {
|
|
3119
|
+
this.animate();
|
|
3120
|
+
}
|
|
3121
|
+
else {
|
|
3122
|
+
this.render();
|
|
3123
|
+
}
|
|
3124
|
+
|
|
3125
|
+
};
|
|
3126
|
+
|
|
3127
|
+
Playback.prototype.animate = function() {
|
|
3128
|
+
|
|
3129
|
+
var progressBefore = this.progress;
|
|
3130
|
+
|
|
3131
|
+
this.progress = this.progressCheck();
|
|
3132
|
+
|
|
3133
|
+
// When we loop, offset the progress so that it eases
|
|
3134
|
+
// smoothly rather than immediately resetting
|
|
3135
|
+
if( progressBefore > 0.8 && this.progress < 0.2 ) {
|
|
3136
|
+
this.progressOffset = this.progress;
|
|
3137
|
+
}
|
|
3138
|
+
|
|
3139
|
+
this.render();
|
|
3140
|
+
|
|
3141
|
+
if( this.playing ) {
|
|
3142
|
+
features.requestAnimationFrameMethod.call( window, this.animate.bind( this ) );
|
|
3143
|
+
}
|
|
3144
|
+
|
|
3145
|
+
};
|
|
3146
|
+
|
|
3147
|
+
/**
|
|
3148
|
+
* Renders the current progress and playback state.
|
|
3149
|
+
*/
|
|
3150
|
+
Playback.prototype.render = function() {
|
|
3151
|
+
|
|
3152
|
+
var progress = this.playing ? this.progress : 0,
|
|
3153
|
+
radius = ( this.diameter / 2 ) - this.thickness,
|
|
3154
|
+
x = this.diameter / 2,
|
|
3155
|
+
y = this.diameter / 2,
|
|
3156
|
+
iconSize = 14;
|
|
3157
|
+
|
|
3158
|
+
// Ease towards 1
|
|
3159
|
+
this.progressOffset += ( 1 - this.progressOffset ) * 0.1;
|
|
3160
|
+
|
|
3161
|
+
var endAngle = ( - Math.PI / 2 ) + ( progress * ( Math.PI * 2 ) );
|
|
3162
|
+
var startAngle = ( - Math.PI / 2 ) + ( this.progressOffset * ( Math.PI * 2 ) );
|
|
3163
|
+
|
|
3164
|
+
this.context.save();
|
|
3165
|
+
this.context.clearRect( 0, 0, this.diameter, this.diameter );
|
|
3166
|
+
|
|
3167
|
+
// Solid background color
|
|
3168
|
+
this.context.beginPath();
|
|
3169
|
+
this.context.arc( x, y, radius + 2, 0, Math.PI * 2, false );
|
|
3170
|
+
this.context.fillStyle = 'rgba( 0, 0, 0, 0.4 )';
|
|
3171
|
+
this.context.fill();
|
|
3172
|
+
|
|
3173
|
+
// Draw progress track
|
|
3174
|
+
this.context.beginPath();
|
|
3175
|
+
this.context.arc( x, y, radius, 0, Math.PI * 2, false );
|
|
3176
|
+
this.context.lineWidth = this.thickness;
|
|
3177
|
+
this.context.strokeStyle = '#666';
|
|
3178
|
+
this.context.stroke();
|
|
3179
|
+
|
|
3180
|
+
if( this.playing ) {
|
|
3181
|
+
// Draw progress on top of track
|
|
3182
|
+
this.context.beginPath();
|
|
3183
|
+
this.context.arc( x, y, radius, startAngle, endAngle, false );
|
|
3184
|
+
this.context.lineWidth = this.thickness;
|
|
3185
|
+
this.context.strokeStyle = '#fff';
|
|
3186
|
+
this.context.stroke();
|
|
3187
|
+
}
|
|
3188
|
+
|
|
3189
|
+
this.context.translate( x - ( iconSize / 2 ), y - ( iconSize / 2 ) );
|
|
3190
|
+
|
|
3191
|
+
// Draw play/pause icons
|
|
3192
|
+
if( this.playing ) {
|
|
3193
|
+
this.context.fillStyle = '#fff';
|
|
3194
|
+
this.context.fillRect( 0, 0, iconSize / 2 - 2, iconSize );
|
|
3195
|
+
this.context.fillRect( iconSize / 2 + 2, 0, iconSize / 2 - 2, iconSize );
|
|
3196
|
+
}
|
|
3197
|
+
else {
|
|
3198
|
+
this.context.beginPath();
|
|
3199
|
+
this.context.translate( 2, 0 );
|
|
3200
|
+
this.context.moveTo( 0, 0 );
|
|
3201
|
+
this.context.lineTo( iconSize - 2, iconSize / 2 );
|
|
3202
|
+
this.context.lineTo( 0, iconSize );
|
|
3203
|
+
this.context.fillStyle = '#fff';
|
|
3204
|
+
this.context.fill();
|
|
3205
|
+
}
|
|
3206
|
+
|
|
3207
|
+
this.context.restore();
|
|
3208
|
+
|
|
3209
|
+
};
|
|
3210
|
+
|
|
3211
|
+
Playback.prototype.on = function( type, listener ) {
|
|
3212
|
+
this.canvas.addEventListener( type, listener, false );
|
|
3213
|
+
};
|
|
3214
|
+
|
|
3215
|
+
Playback.prototype.off = function( type, listener ) {
|
|
3216
|
+
this.canvas.removeEventListener( type, listener, false );
|
|
3217
|
+
};
|
|
3218
|
+
|
|
3219
|
+
Playback.prototype.destroy = function() {
|
|
3220
|
+
|
|
3221
|
+
this.playing = false;
|
|
3222
|
+
|
|
3223
|
+
if( this.canvas.parentNode ) {
|
|
3224
|
+
this.container.removeChild( this.canvas );
|
|
3225
|
+
}
|
|
3226
|
+
|
|
3227
|
+
};
|
|
3228
|
+
|
|
2449
3229
|
|
|
2450
3230
|
// --------------------------------------------------------------------//
|
|
2451
3231
|
// ------------------------------- API --------------------------------//
|
|
@@ -2465,6 +3245,9 @@ var Reveal = (function(){
|
|
|
2465
3245
|
down: navigateDown,
|
|
2466
3246
|
prev: navigatePrev,
|
|
2467
3247
|
next: navigateNext,
|
|
3248
|
+
|
|
3249
|
+
// Fragment methods
|
|
3250
|
+
navigateFragment: navigateFragment,
|
|
2468
3251
|
prevFragment: previousFragment,
|
|
2469
3252
|
nextFragment: nextFragment,
|
|
2470
3253
|
|
|
@@ -2539,10 +3322,22 @@ var Reveal = (function(){
|
|
|
2539
3322
|
getQueryHash: function() {
|
|
2540
3323
|
var query = {};
|
|
2541
3324
|
|
|
2542
|
-
location.search.replace( /[A-Z0-9]+?=(\w*)/gi, function(a) {
|
|
3325
|
+
location.search.replace( /[A-Z0-9]+?=([\w\.%-]*)/gi, function(a) {
|
|
2543
3326
|
query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
|
|
2544
3327
|
} );
|
|
2545
3328
|
|
|
3329
|
+
// Basic deserialization
|
|
3330
|
+
for( var i in query ) {
|
|
3331
|
+
var value = query[ i ];
|
|
3332
|
+
|
|
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 );
|
|
3339
|
+
}
|
|
3340
|
+
|
|
2546
3341
|
return query;
|
|
2547
3342
|
},
|
|
2548
3343
|
|
|
@@ -2553,12 +3348,22 @@ var Reveal = (function(){
|
|
|
2553
3348
|
|
|
2554
3349
|
// Returns true if we're currently on the last slide
|
|
2555
3350
|
isLastSlide: function() {
|
|
2556
|
-
if( currentSlide
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
3351
|
+
if( currentSlide ) {
|
|
3352
|
+
// Does this slide has next a sibling?
|
|
3353
|
+
if( currentSlide.nextElementSibling ) return false;
|
|
3354
|
+
|
|
3355
|
+
// If it's vertical, does its parent have a next sibling?
|
|
3356
|
+
if( isVerticalSlide( currentSlide ) && currentSlide.parentNode.nextElementSibling ) return false;
|
|
3357
|
+
|
|
3358
|
+
return true;
|
|
2561
3359
|
}
|
|
3360
|
+
|
|
3361
|
+
return false;
|
|
3362
|
+
},
|
|
3363
|
+
|
|
3364
|
+
// Checks if reveal.js has been loaded and is ready for use
|
|
3365
|
+
isReady: function() {
|
|
3366
|
+
return loaded;
|
|
2562
3367
|
},
|
|
2563
3368
|
|
|
2564
3369
|
// Forward event binding to the reveal DOM element
|