slideoff 0.1
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 +7 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +218 -0
- data/bin/slideoff +127 -0
- data/lib/slideoff/config_builder.rb +60 -0
- data/lib/slideoff/flickr_api.rb +50 -0
- data/lib/slideoff/flickr_image.rb +92 -0
- data/lib/slideoff/markdown.rb +145 -0
- data/lib/slideoff/presentation.rb +90 -0
- data/lib/slideoff/remote_api.rb +53 -0
- data/lib/slideoff/routes.rb +20 -0
- data/lib/slideoff/server.rb +50 -0
- data/lib/slideoff/slides_api.rb +59 -0
- data/lib/slideoff/utils.rb +453 -0
- data/lib/slideoff.rb +15 -0
- data/themes/3d_slideshow/README +2 -0
- data/themes/3d_slideshow/css/main.css +232 -0
- data/themes/3d_slideshow/css/reset.css +57 -0
- data/themes/3d_slideshow/index.erb +31 -0
- data/themes/3d_slideshow/js/slideshow.js +288 -0
- data/themes/CSSS/README +2 -0
- data/themes/CSSS/css/slideshow.css +304 -0
- data/themes/CSSS/css/theme.css +250 -0
- data/themes/CSSS/images/rainbow-wood.jpg +0 -0
- data/themes/CSSS/index.erb +36 -0
- data/themes/CSSS/js/classList.js +116 -0
- data/themes/CSSS/js/prefixfree.min.js +5 -0
- data/themes/CSSS/js/slideshow.js +621 -0
- data/themes/common/css/pygments/colorful.css +62 -0
- data/themes/common/css/pygments/manni.css +61 -0
- data/themes/common/css/pygments/native.css +70 -0
- data/themes/common/css/pygments/solarized.css +66 -0
- data/themes/common/fonts/DroidSansMono.svg +626 -0
- data/themes/common/fonts/DroidSansMono.ttf +0 -0
- data/themes/common/fonts/Lato-BoldItalic.woff +0 -0
- data/themes/common/fonts/Lato-Italic.woff +0 -0
- data/themes/common/fonts/Lato-bold.woff +0 -0
- data/themes/common/fonts/Lato.woff +0 -0
- data/themes/common/fonts/OpenSans-Bold.woff +0 -0
- data/themes/common/fonts/OpenSans-BoldItalic.woff +0 -0
- data/themes/common/fonts/OpenSans-Italic.woff +0 -0
- data/themes/common/fonts/OpenSans.woff +0 -0
- data/themes/common/fonts/PTMono.woff +0 -0
- data/themes/common/fonts/PTSans.Bold.Italic.woff +0 -0
- data/themes/common/fonts/PTSans.Bold.woff +0 -0
- data/themes/common/fonts/PTSans.Italic.woff +0 -0
- data/themes/common/fonts/PTSans.Narrow.Bold.woff +0 -0
- data/themes/common/fonts/PTSans.Narrow.woff +0 -0
- data/themes/common/fonts/PTSans.woff +0 -0
- data/themes/common/fonts/TargetBlank.otf +0 -0
- data/themes/common/fonts/TargetBlank.svg +14 -0
- data/themes/common/fonts/YanoneKaffeesatz-Bold.woff +0 -0
- data/themes/common/fonts/YanoneKaffeesatz-Regular.woff +0 -0
- data/themes/common/fonts/crimson_text.ttf +0 -0
- data/themes/common/fonts/crimson_text_bold.ttf +0 -0
- data/themes/common/fonts/crimson_text_semibold.ttf +0 -0
- data/themes/common/fonts/league_gothic-webfont.ttf +0 -0
- data/themes/html5rocks/README +2 -0
- data/themes/html5rocks/css/default.css +501 -0
- data/themes/html5rocks/css/moon.css +543 -0
- data/themes/html5rocks/css/sand.css +508 -0
- data/themes/html5rocks/css/sea_wave.css +492 -0
- data/themes/html5rocks/index.erb +64 -0
- data/themes/html5rocks/js/slides.js +464 -0
- data/themes/io2012/README +2 -0
- data/themes/io2012/css/default.css +1481 -0
- data/themes/io2012/css/fonts.css +24 -0
- data/themes/io2012/css/phone.css +27 -0
- data/themes/io2012/images/google_developers_icon_128.png +0 -0
- data/themes/io2012/images/io2012_logo.png +0 -0
- data/themes/io2012/index.erb +73 -0
- data/themes/io2012/js/hammer.js +586 -0
- data/themes/io2012/js/modernizr.custom.45394.js +4 -0
- data/themes/io2012/js/order.js +8 -0
- data/themes/io2012/js/polyfills/classList.min.js +2 -0
- data/themes/io2012/js/polyfills/dataset.min.js +2 -0
- data/themes/io2012/js/polyfills/history.min.js +1 -0
- data/themes/io2012/js/prettify/lang-apollo.js +2 -0
- data/themes/io2012/js/prettify/lang-clj.js +18 -0
- data/themes/io2012/js/prettify/lang-css.js +2 -0
- data/themes/io2012/js/prettify/lang-go.js +1 -0
- data/themes/io2012/js/prettify/lang-hs.js +2 -0
- data/themes/io2012/js/prettify/lang-lisp.js +3 -0
- data/themes/io2012/js/prettify/lang-lua.js +2 -0
- data/themes/io2012/js/prettify/lang-ml.js +2 -0
- data/themes/io2012/js/prettify/lang-n.js +4 -0
- data/themes/io2012/js/prettify/lang-proto.js +1 -0
- data/themes/io2012/js/prettify/lang-scala.js +2 -0
- data/themes/io2012/js/prettify/lang-sql.js +2 -0
- data/themes/io2012/js/prettify/lang-tex.js +1 -0
- data/themes/io2012/js/prettify/lang-vb.js +2 -0
- data/themes/io2012/js/prettify/lang-vhdl.js +3 -0
- data/themes/io2012/js/prettify/lang-wiki.js +2 -0
- data/themes/io2012/js/prettify/lang-xq.js +3 -0
- data/themes/io2012/js/prettify/lang-yaml.js +2 -0
- data/themes/io2012/js/prettify/prettify.css +1 -0
- data/themes/io2012/js/prettify/prettify.js +28 -0
- data/themes/io2012/js/require-1.0.8.min.js +33 -0
- data/themes/io2012/js/slide-controller.js +109 -0
- data/themes/io2012/js/slide-deck.js +768 -0
- data/themes/io2012/js/slides.js +5 -0
- data/themes/memories/README +5 -0
- data/themes/memories/css/fonts.css +25 -0
- data/themes/memories/css/slideshow.css +286 -0
- data/themes/memories/css/theme.css +183 -0
- data/themes/memories/index.erb +37 -0
- data/themes/memories/js/prefixfree.min.js +13 -0
- data/themes/memories/js/slideshow.js +577 -0
- data/themes/modern/LICENSE +20 -0
- data/themes/modern/README.md +52 -0
- data/themes/modern/css/GENERATED_CONTENT +0 -0
- data/themes/modern/css/defaults.css +0 -0
- data/themes/modern/css/fonts.css +166 -0
- data/themes/modern/css/pygments/colorful.css +215 -0
- data/themes/modern/css/pygments/github.css +208 -0
- data/themes/modern/css/pygments/solarized-dark.css +213 -0
- data/themes/modern/css/pygments/solarized-light.css +213 -0
- data/themes/modern/css/reset.css +41 -0
- data/themes/modern/css/screen.css +1183 -0
- data/themes/modern/fonts/Collegiate.woff +0 -0
- data/themes/modern/fonts/GoudyBookletter.1911.woff +0 -0
- data/themes/modern/fonts/Inconsolata.Bold.woff +0 -0
- data/themes/modern/fonts/Inconsolata.woff +0 -0
- data/themes/modern/fonts/Junction.woff +0 -0
- data/themes/modern/fonts/LiberationMono.Bold.woff +0 -0
- data/themes/modern/fonts/LiberationMono.BoldItalic.woff +0 -0
- data/themes/modern/fonts/LiberationMono.Italic.woff +0 -0
- data/themes/modern/fonts/LiberationMono.Regular.woff +0 -0
- data/themes/modern/fonts/OpenSans.Bold.woff +0 -0
- data/themes/modern/fonts/OpenSans.BoldItalic.woff +0 -0
- data/themes/modern/fonts/OpenSans.ExtraBold.woff +0 -0
- data/themes/modern/fonts/OpenSans.ExtraBoldItalic.woff +0 -0
- data/themes/modern/fonts/OpenSans.Italic.woff +0 -0
- data/themes/modern/fonts/OpenSans.Light.woff +0 -0
- data/themes/modern/fonts/OpenSans.LightItalic.woff +0 -0
- data/themes/modern/fonts/OpenSans.Regular.woff +0 -0
- data/themes/modern/fonts/OpenSans.Semibold.woff +0 -0
- data/themes/modern/fonts/OpenSans.SemiboldItalic.woff +0 -0
- data/themes/modern/fonts/PTMono.woff +0 -0
- data/themes/modern/fonts/PTSans.Bold.Italic.woff +0 -0
- data/themes/modern/fonts/PTSans.Bold.woff +0 -0
- data/themes/modern/fonts/PTSans.Italic.woff +0 -0
- data/themes/modern/fonts/PTSans.Narrow.Bold.woff +0 -0
- data/themes/modern/fonts/PTSans.woff +0 -0
- data/themes/modern/fonts/Raleway.Thin.woff +0 -0
- data/themes/modern/fonts/STIXGeneral.Bold.woff +0 -0
- data/themes/modern/fonts/STIXGeneral.BoldItalic.woff +0 -0
- data/themes/modern/fonts/STIXGeneral.Italic.woff +0 -0
- data/themes/modern/fonts/STIXGeneral.Regular.woff +0 -0
- data/themes/modern/fonts/YanoneKaffeesatz.Bold.woff +0 -0
- data/themes/modern/fonts/YanoneKaffeesatz.ExtraLight.woff +0 -0
- data/themes/modern/fonts/YanoneKaffeesatz.Light.woff +0 -0
- data/themes/modern/fonts/YanoneKaffeesatz.Regular.woff +0 -0
- data/themes/modern/images/cc/by.svg +29 -0
- data/themes/modern/images/cc/cc-white.svg +23 -0
- data/themes/modern/images/cc/cc.svg +23 -0
- data/themes/modern/images/cc/nc-eu.svg +21 -0
- data/themes/modern/images/cc/nc-jp.svg +18 -0
- data/themes/modern/images/cc/nc.svg +23 -0
- data/themes/modern/images/cc/nd.svg +20 -0
- data/themes/modern/images/cc/pd.svg +24 -0
- data/themes/modern/images/cc/remix.svg +20 -0
- data/themes/modern/images/cc/sa.svg +22 -0
- data/themes/modern/images/cc/sampling.plus.svg +33 -0
- data/themes/modern/images/cc/sampling.svg +36 -0
- data/themes/modern/images/cc/share.svg +22 -0
- data/themes/modern/images/cc/zero.svg +24 -0
- data/themes/modern/images/flickr.svg +65 -0
- data/themes/modern/images/mesh.png +0 -0
- data/themes/modern/images/mesh@2x.png +0 -0
- data/themes/modern/images/progress-grayDark.svg +55 -0
- data/themes/modern/images/progress.svg +3 -0
- data/themes/modern/index.erb +76 -0
- data/themes/modern/js/highcharts.js +294 -0
- data/themes/modern/js/jquery-2.1.0.min.js +4 -0
- data/themes/modern/js/script.coffee +480 -0
- data/themes/modern/js/script.js +678 -0
- data/themes/modern/styles/_box.scss +89 -0
- data/themes/modern/styles/_figure.scss +81 -0
- data/themes/modern/styles/_full.scss +74 -0
- data/themes/modern/styles/_increment.scss +38 -0
- data/themes/modern/styles/_list.scss +129 -0
- data/themes/modern/styles/_progress.scss +19 -0
- data/themes/modern/styles/defaults.scss +46 -0
- data/themes/modern/styles/fonts.scss +197 -0
- data/themes/modern/styles/pygments/_solarized.scss +82 -0
- data/themes/modern/styles/pygments/colorful.scss +67 -0
- data/themes/modern/styles/pygments/github.scss +67 -0
- data/themes/modern/styles/pygments/solarized-dark.scss +15 -0
- data/themes/modern/styles/pygments/solarized-light.scss +15 -0
- data/themes/modern/styles/reset.scss +46 -0
- data/themes/modern/styles/screen.scss +841 -0
- data/themes/reveal/README +2 -0
- data/themes/reveal/css/main.css +1029 -0
- data/themes/reveal/css/reset.css +57 -0
- data/themes/reveal/index.erb +102 -0
- data/themes/reveal/js/classList.js +2 -0
- data/themes/reveal/js/head.min.js +8 -0
- data/themes/reveal/js/reveal.js +951 -0
- data/themes/shower/README +2 -0
- data/themes/shower/css/fonts.css +50 -0
- data/themes/shower/css/reset.css +42 -0
- data/themes/shower/css/style.css +418 -0
- data/themes/shower/images/grid.png +0 -0
- data/themes/shower/images/linen.png +0 -0
- data/themes/shower/images/ribbon.svg +4 -0
- data/themes/shower/index.erb +35 -0
- data/themes/shower/js/script.js +325 -0
- data/themes/template/README +5 -0
- data/themes/template/css/reset.css +42 -0
- data/themes/template/index.erb +35 -0
- data/themes/template/js/prefixfree.min.js +13 -0
- metadata +343 -0
@@ -0,0 +1,577 @@
|
|
1
|
+
/**
|
2
|
+
* CSSS javascript code
|
3
|
+
* @author Lea Verou (http://leaverou.me)
|
4
|
+
* @version 2.0
|
5
|
+
*/
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Make the environment a bit friendlier
|
9
|
+
*/
|
10
|
+
function $(expr, con) { return (con || document).querySelector(expr); }
|
11
|
+
function $$(expr, con) { return [].slice.call((con || document).querySelectorAll(expr)); }
|
12
|
+
|
13
|
+
(function(head, body, html){
|
14
|
+
|
15
|
+
// Check for classList support and include the polyfill if it's not supported
|
16
|
+
if(!('classList' in body)) {
|
17
|
+
var thisScript = $('script[src$="slideshow.js"]'),
|
18
|
+
script = document.createElement('script');
|
19
|
+
script.src = thisScript.src.replace(/\bslideshow\.js/, 'classList.js');
|
20
|
+
thisScript.parentNode.insertBefore(script, thisScript);
|
21
|
+
}
|
22
|
+
|
23
|
+
// Cache <title> element, we may need it for slides that don't have titles
|
24
|
+
var documentTitle = document.title + '';
|
25
|
+
|
26
|
+
var self = window.SlideShow = function(slide) {
|
27
|
+
var me = this;
|
28
|
+
|
29
|
+
// Set instance
|
30
|
+
if(!window.slideshow) {
|
31
|
+
window.slideshow = this;
|
32
|
+
}
|
33
|
+
|
34
|
+
// Current slide
|
35
|
+
this.index = this.slide = slide || 0;
|
36
|
+
|
37
|
+
// Current .delayed item in the slide
|
38
|
+
this.item = 0;
|
39
|
+
|
40
|
+
// Create timer, if needed
|
41
|
+
this.duration = body.getAttribute('data-duration');
|
42
|
+
|
43
|
+
if(this.duration > 0) {
|
44
|
+
var timer = document.createElement('div');
|
45
|
+
|
46
|
+
timer.id = 'timer';
|
47
|
+
timer.setAttribute('style', PrefixFree.prefixCSS('transition-duration: ' + this.duration * 60 + 's;'));
|
48
|
+
body.appendChild(timer);
|
49
|
+
|
50
|
+
addEventListener('load', function() {
|
51
|
+
timer.className = 'end';
|
52
|
+
|
53
|
+
setTimeout(function() {
|
54
|
+
timer.classList.add('overtime');
|
55
|
+
}, me.duration * 60000);
|
56
|
+
});
|
57
|
+
}
|
58
|
+
|
59
|
+
// Create slide indicator
|
60
|
+
this.indicator = document.createElement('div');
|
61
|
+
|
62
|
+
this.indicator.id = 'indicator';
|
63
|
+
body.appendChild(this.indicator);
|
64
|
+
|
65
|
+
// Get the slide elements into an array
|
66
|
+
this.slides = $$('.slide', body);
|
67
|
+
|
68
|
+
// Order of the slides
|
69
|
+
this.order = [];
|
70
|
+
|
71
|
+
for(var i=0; i<this.slides.length; i++) {
|
72
|
+
var slide = this.slides[i]; // to speed up references
|
73
|
+
|
74
|
+
// Asign ids to slides that don't have one
|
75
|
+
if(!slide.id) {
|
76
|
+
slide.id = 'slide' + (i+1);
|
77
|
+
}
|
78
|
+
|
79
|
+
// Set data-title attribute to the title of the slide
|
80
|
+
if(!slide.title) {
|
81
|
+
// no title attribute, fetch title from heading(s)
|
82
|
+
var heading = $('hgroup', slide) || $('h1,h2,h3,h4,h5,h6', slide);
|
83
|
+
|
84
|
+
if(heading && heading.textContent.trim()) {
|
85
|
+
slide.setAttribute('data-title', heading.textContent);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
else {
|
89
|
+
// The title attribute is set, use that
|
90
|
+
slide.setAttribute('data-title', slide.title);
|
91
|
+
slide.removeAttribute('title');
|
92
|
+
}
|
93
|
+
|
94
|
+
slide.setAttribute('data-index', i);
|
95
|
+
|
96
|
+
var imp = slide.getAttribute('data-import'),
|
97
|
+
imported = imp? this.getSlideById(imp) : null;
|
98
|
+
|
99
|
+
this.order.push(imported? +imported.getAttribute('data-index') : i);
|
100
|
+
}
|
101
|
+
|
102
|
+
if(window.name === 'projector' && window.opener && opener.slideshow) {
|
103
|
+
body.classList.add('projector');
|
104
|
+
this.presenter = opener.slideshow;
|
105
|
+
this.presenter.projector = this;
|
106
|
+
}
|
107
|
+
|
108
|
+
// Adjust the font-size when the window is resized
|
109
|
+
addEventListener('resize', this, false);
|
110
|
+
|
111
|
+
// In some browsers DOMContentLoaded is too early, so try again onload
|
112
|
+
addEventListener('load', this, false);
|
113
|
+
|
114
|
+
addEventListener('hashchange', this, false);
|
115
|
+
|
116
|
+
// If there's already a hash, update current slide number...
|
117
|
+
this.handleEvent({type: 'hashchange'});
|
118
|
+
|
119
|
+
document.addEventListener('keyup', this, false);
|
120
|
+
document.addEventListener('keydown', this, false);
|
121
|
+
|
122
|
+
window.setTimeout(function() {
|
123
|
+
this.startEventSourceHandler('/remote/sub/events');
|
124
|
+
}, 100);
|
125
|
+
|
126
|
+
// Process iframe slides
|
127
|
+
$$('.slide[data-src]:empty').forEach(function(slide) {
|
128
|
+
var iframe = document.createElement('iframe');
|
129
|
+
|
130
|
+
iframe.setAttribute('data-src', slide.getAttribute('data-src'));
|
131
|
+
slide.removeAttribute('data-src');
|
132
|
+
|
133
|
+
slide.appendChild(iframe);
|
134
|
+
});
|
135
|
+
|
136
|
+
$$('.slide > iframe:only-child').forEach(function(iframe) {
|
137
|
+
var slide = iframe.parentNode,
|
138
|
+
src = iframe.src || iframe.getAttribute('data-src');
|
139
|
+
|
140
|
+
slide.classList.add('iframe');
|
141
|
+
|
142
|
+
if(!slide.classList.contains('notitle')) {
|
143
|
+
var h = document.createElement('h1'),
|
144
|
+
a = document.createElement('a'),
|
145
|
+
title = iframe.title || slide.title || slide.getAttribute('data-title') || src.replace(/\/#?$/, '')
|
146
|
+
.replace(/^\w+:\/\/w{0,3}\.?/, '');
|
147
|
+
|
148
|
+
a.href = src;
|
149
|
+
a.target = '_blank';
|
150
|
+
a.textContent = title;
|
151
|
+
h.appendChild(a);
|
152
|
+
|
153
|
+
slide.appendChild(h);
|
154
|
+
}
|
155
|
+
});
|
156
|
+
};
|
157
|
+
|
158
|
+
self.prototype = {
|
159
|
+
handleEvent: function(evt) {
|
160
|
+
var me = this;
|
161
|
+
|
162
|
+
switch(evt.type) {
|
163
|
+
/**
|
164
|
+
Keyboard navigation
|
165
|
+
Ctrl+G : Go to slide...
|
166
|
+
Ctrl+H : Show thumbnails and go to slide
|
167
|
+
Ctrl+P : Presenter view
|
168
|
+
(Shift instead of Ctrl works too)
|
169
|
+
*/
|
170
|
+
case 'keyup':
|
171
|
+
if((evt.ctrlKey || evt.shiftKey) && !evt.altKey) {
|
172
|
+
switch(evt.keyCode) {
|
173
|
+
case 71: // G
|
174
|
+
var slide = prompt('Which slide?');
|
175
|
+
me.goto(+slide? slide - 1 : slide);
|
176
|
+
break;
|
177
|
+
case 72: // H
|
178
|
+
if(body.classList.contains('show-thumbnails')) {
|
179
|
+
body.classList.remove('show-thumbnails');
|
180
|
+
body.classList.remove('headers-only');
|
181
|
+
}
|
182
|
+
else {
|
183
|
+
body.classList.add('show-thumbnails');
|
184
|
+
|
185
|
+
if(!evt.shiftKey || !evt.ctrlKey) {
|
186
|
+
body.classList.add('headers-only');
|
187
|
+
}
|
188
|
+
|
189
|
+
body.addEventListener('click', function(evt) {
|
190
|
+
var slide = evt.target;
|
191
|
+
|
192
|
+
while(slide && !slide.classList.contains('slide')) {
|
193
|
+
slide = slide.parentNode;
|
194
|
+
}
|
195
|
+
|
196
|
+
if(slide) {
|
197
|
+
me.goto(slide.id);
|
198
|
+
setTimeout(function() { me.adjustFontSize(); }, 1000); // for Opera
|
199
|
+
}
|
200
|
+
|
201
|
+
body.classList.remove('show-thumbnails');
|
202
|
+
body.classList.remove('headers-only');
|
203
|
+
|
204
|
+
body.removeEventListener('click', arguments.callee);
|
205
|
+
}, false);
|
206
|
+
}
|
207
|
+
break;
|
208
|
+
case 74: // J
|
209
|
+
if(body.classList.contains('hide-elements')) {
|
210
|
+
body.classList.remove('hide-elements');
|
211
|
+
}
|
212
|
+
else {
|
213
|
+
body.classList.add('hide-elements');
|
214
|
+
}
|
215
|
+
break;
|
216
|
+
case 80: // P
|
217
|
+
// Open new window for attendee view
|
218
|
+
this.projector = open(location, 'projector');
|
219
|
+
|
220
|
+
// Get the focus back
|
221
|
+
window.focus();
|
222
|
+
|
223
|
+
// Switch this one to presenter view
|
224
|
+
body.classList.add('presenter');
|
225
|
+
}
|
226
|
+
}
|
227
|
+
break;
|
228
|
+
case 'keydown':
|
229
|
+
/**
|
230
|
+
Keyboard navigation
|
231
|
+
Home : First slide
|
232
|
+
End : Last slide
|
233
|
+
Space/Up/Right arrow : Next item/slide
|
234
|
+
Ctrl + Space/Up/Right arrow : Next slide
|
235
|
+
Down/Left arrow : Previous item/slide
|
236
|
+
Ctrl + Down/Left arrow : Previous slide
|
237
|
+
(Shift instead of Ctrl works too)
|
238
|
+
*/
|
239
|
+
if((evt.target === body || evt.target === body.parentNode) && !evt.altKey) {
|
240
|
+
if(evt.keyCode >= 32 && evt.keyCode <= 40) {
|
241
|
+
evt.preventDefault();
|
242
|
+
}
|
243
|
+
|
244
|
+
switch(evt.keyCode) {
|
245
|
+
case 33: //page up
|
246
|
+
this.previous();
|
247
|
+
break;
|
248
|
+
case 34: //page down
|
249
|
+
this.next();
|
250
|
+
break;
|
251
|
+
case 35: // end
|
252
|
+
this.end();
|
253
|
+
break;
|
254
|
+
case 36: // home
|
255
|
+
this.start();
|
256
|
+
break;
|
257
|
+
case 37: // <-
|
258
|
+
case 38: // up arrow
|
259
|
+
this.previous(evt.ctrlKey || evt.shiftKey);
|
260
|
+
break;
|
261
|
+
case 32: // space
|
262
|
+
case 39: // ->
|
263
|
+
case 40: // down arrow
|
264
|
+
this.next(evt.ctrlKey || evt.shiftKey);
|
265
|
+
break;
|
266
|
+
}
|
267
|
+
}
|
268
|
+
break;
|
269
|
+
case 'load':
|
270
|
+
case 'resize':
|
271
|
+
this.adjustFontSize();
|
272
|
+
break;
|
273
|
+
case 'hashchange':
|
274
|
+
this.goto(location.hash.substr(1) || 0);
|
275
|
+
}
|
276
|
+
},
|
277
|
+
|
278
|
+
start: function() {
|
279
|
+
this.goto(0);
|
280
|
+
},
|
281
|
+
|
282
|
+
end: function() {
|
283
|
+
this.goto(this.slides.length - 1);
|
284
|
+
},
|
285
|
+
|
286
|
+
/**
|
287
|
+
@param hard {Boolean} Whether to advance to the next slide (true) or
|
288
|
+
just the next step (which could very well be showing a list item)
|
289
|
+
*/
|
290
|
+
next: function(hard) {
|
291
|
+
if(!hard && this.items.length) {
|
292
|
+
this.nextItem();
|
293
|
+
}
|
294
|
+
else {
|
295
|
+
this.goto(this.index + 1);
|
296
|
+
|
297
|
+
this.item = 0;
|
298
|
+
|
299
|
+
// Mark all items as not displayed, if there are any
|
300
|
+
if(this.items.length) {
|
301
|
+
for (var i=0; i<this.items.length; i++) {
|
302
|
+
if(this.items[i].classList) {
|
303
|
+
this.items[i].classList.remove('displayed');
|
304
|
+
this.items[i].classList.remove('current');
|
305
|
+
}
|
306
|
+
}
|
307
|
+
}
|
308
|
+
}
|
309
|
+
},
|
310
|
+
|
311
|
+
nextItem: function() {
|
312
|
+
if(this.item < this.items.length) {
|
313
|
+
this.gotoItem(++this.item);
|
314
|
+
}
|
315
|
+
else {
|
316
|
+
this.item = 0;
|
317
|
+
this.next(true);
|
318
|
+
}
|
319
|
+
},
|
320
|
+
|
321
|
+
previous: function(hard) {
|
322
|
+
if(!hard && this.item > 0) {
|
323
|
+
this.previousItem();
|
324
|
+
}
|
325
|
+
else {
|
326
|
+
this.goto(this.index - 1);
|
327
|
+
|
328
|
+
this.item = this.items.length;
|
329
|
+
|
330
|
+
// Mark all items as displayed, if there are any
|
331
|
+
if(this.items.length) {
|
332
|
+
for (var i=0; i<this.items.length; i++) {
|
333
|
+
if(this.items[i].classList) {
|
334
|
+
this.items[i].classList.add('displayed');
|
335
|
+
}
|
336
|
+
}
|
337
|
+
|
338
|
+
// Mark the last one as current
|
339
|
+
var lastItem = this.items[this.items.length - 1];
|
340
|
+
|
341
|
+
lastItem.classList.remove('displayed');
|
342
|
+
lastItem.classList.add('current');
|
343
|
+
}
|
344
|
+
}
|
345
|
+
},
|
346
|
+
|
347
|
+
previousItem: function() {
|
348
|
+
this.gotoItem(--this.item);
|
349
|
+
},
|
350
|
+
|
351
|
+
getSlideById: function(id) {
|
352
|
+
return $('.slide#' + id);
|
353
|
+
},
|
354
|
+
|
355
|
+
/**
|
356
|
+
Go to an aribtary slide
|
357
|
+
@param which {String|Integer} Which slide (identifier or slide number)
|
358
|
+
*/
|
359
|
+
goto: function(which) {
|
360
|
+
var slide;
|
361
|
+
|
362
|
+
// We have to remove it to prevent multiple calls to goto messing up
|
363
|
+
// our current item (and there's no point either, so we save on performance)
|
364
|
+
window.removeEventListener('hashchange', this, false);
|
365
|
+
|
366
|
+
var id;
|
367
|
+
|
368
|
+
if(which + 0 === which && which in this.slides) {
|
369
|
+
// Argument is a valid slide number
|
370
|
+
this.index = which;
|
371
|
+
this.slide = this.order[which]
|
372
|
+
|
373
|
+
slide = this.slides[this.slide];
|
374
|
+
|
375
|
+
location.hash = '#' + slide.id;
|
376
|
+
}
|
377
|
+
else if(which + '' === which) { // Argument is a slide id
|
378
|
+
slide = this.getSlideById(which);
|
379
|
+
|
380
|
+
if(slide) {
|
381
|
+
this.slide = this.index = +slide.getAttribute('data-index');
|
382
|
+
location.hash = '#' + which;
|
383
|
+
}
|
384
|
+
}
|
385
|
+
|
386
|
+
if(slide) { // Slide actually changed, perform any other tasks needed
|
387
|
+
document.title = slide.getAttribute('data-title') || documentTitle;
|
388
|
+
|
389
|
+
if(slide.classList.contains('iframe')) {
|
390
|
+
var iframe = $('iframe', slide), src;
|
391
|
+
|
392
|
+
if(!iframe.hasAttribute('src') && (src = iframe.getAttribute('data-src'))) {
|
393
|
+
iframe.setAttribute('src', src);
|
394
|
+
}
|
395
|
+
}
|
396
|
+
else {
|
397
|
+
this.adjustFontSize();
|
398
|
+
}
|
399
|
+
|
400
|
+
this.indicator.textContent = this.index + 1;
|
401
|
+
|
402
|
+
// Update items collection
|
403
|
+
this.items = $$('.delayed, .delayed-children > *', this.slides[this.slide]);
|
404
|
+
this.items.sort(function(a, b){
|
405
|
+
return (a.getAttribute('data-index') || 0) - (b.getAttribute('data-index') || 0)
|
406
|
+
});
|
407
|
+
this.item = 0;
|
408
|
+
|
409
|
+
this.projector && this.projector.goto(which);
|
410
|
+
|
411
|
+
// Update next/previous
|
412
|
+
for (var i=this.slides.length; i--;) {
|
413
|
+
this.slides[i].classList.remove('previous');
|
414
|
+
this.slides[i].classList.remove('next');
|
415
|
+
}
|
416
|
+
|
417
|
+
this.slides.previous = this.slides[this.order[this.index - 1]];
|
418
|
+
this.slides.next = this.slides[this.order[this.index + 1]];
|
419
|
+
|
420
|
+
this.slides.previous && this.slides.previous.classList.add('previous');
|
421
|
+
this.slides.next && this.slides.next.classList.add('next');
|
422
|
+
}
|
423
|
+
|
424
|
+
// If you attach the listener immediately again then it will catch the event
|
425
|
+
// We have to do it asynchronously
|
426
|
+
var me = this;
|
427
|
+
setTimeout(function() {
|
428
|
+
addEventListener('hashchange', me, false);
|
429
|
+
}, 1000);
|
430
|
+
},
|
431
|
+
|
432
|
+
gotoItem: function(which) {
|
433
|
+
this.item = which;
|
434
|
+
|
435
|
+
var items = this.items, classes;
|
436
|
+
|
437
|
+
for(var i=items.length; i-- > 0;) {
|
438
|
+
classes = this.items[i].classList;
|
439
|
+
|
440
|
+
classes.remove('current');
|
441
|
+
classes.remove('displayed');
|
442
|
+
}
|
443
|
+
|
444
|
+
for(var i=this.item - 1; i-- > 0;) {
|
445
|
+
this.items[i].classList.add('displayed');
|
446
|
+
}
|
447
|
+
|
448
|
+
if(this.item > 0) {
|
449
|
+
this.items[this.item - 1].classList.add('current');
|
450
|
+
}
|
451
|
+
|
452
|
+
this.projector && this.projector.gotoItem(which);
|
453
|
+
},
|
454
|
+
|
455
|
+
adjustFontSize: function() {
|
456
|
+
// Cache long lookup chains, for performance
|
457
|
+
var htmlStyle = html.style,
|
458
|
+
scrollRoot = html.scrollHeight? html : body,
|
459
|
+
innerHeight = window.innerHeight,
|
460
|
+
innerWidth = window.innerWidth,
|
461
|
+
slide = this.slides[this.slide];
|
462
|
+
|
463
|
+
// Clear previous styles
|
464
|
+
htmlStyle.fontSize = '';
|
465
|
+
|
466
|
+
if(body.classList.contains('show-thumbnails')
|
467
|
+
|| slide.classList.contains('dont-resize')) {
|
468
|
+
return;
|
469
|
+
}
|
470
|
+
|
471
|
+
for(
|
472
|
+
var percent = 100;
|
473
|
+
(scrollRoot.scrollHeight > innerHeight || scrollRoot.scrollWidth > innerWidth) && percent >= 35;
|
474
|
+
percent-=5
|
475
|
+
) {
|
476
|
+
htmlStyle.fontSize = percent + '%';
|
477
|
+
}
|
478
|
+
|
479
|
+
// Individual slide
|
480
|
+
|
481
|
+
if(slide.clientHeight && slide.clientWidth) {
|
482
|
+
// Strange FF bug: scrollHeight doesn't work properly with overflow:hidden
|
483
|
+
var previousStyle = slide.getAttribute('style');
|
484
|
+
slide.style.overflow = 'auto';
|
485
|
+
|
486
|
+
for(
|
487
|
+
;
|
488
|
+
(slide.scrollHeight > slide.clientHeight || slide.scrollWidth > slide.clientWidth) && percent >= 35;
|
489
|
+
percent--
|
490
|
+
) {
|
491
|
+
htmlStyle.fontSize = percent + '%';
|
492
|
+
}
|
493
|
+
|
494
|
+
slide.setAttribute('style', previousStyle);
|
495
|
+
}
|
496
|
+
|
497
|
+
if(percent <= 35) {
|
498
|
+
// Something probably went wrong, so just give up altogether
|
499
|
+
htmlStyle.fontSize = '';
|
500
|
+
}
|
501
|
+
},
|
502
|
+
|
503
|
+
// Is the element on the current slide?
|
504
|
+
onCurrent: function(element) {
|
505
|
+
var slide = self.getSlide(element);
|
506
|
+
|
507
|
+
if(slide) {
|
508
|
+
return '#' + slide.id === location.hash;
|
509
|
+
}
|
510
|
+
|
511
|
+
return false;
|
512
|
+
},
|
513
|
+
|
514
|
+
startEventSourceHandler: function(uri) {
|
515
|
+
if (window['EventSource'] == undefined) return ;
|
516
|
+
|
517
|
+
var source = new EventSource(uri);
|
518
|
+
|
519
|
+
var me = this;
|
520
|
+
|
521
|
+
source.onmessage = function(e) {
|
522
|
+
switch(e.data){
|
523
|
+
case 'next':
|
524
|
+
me.next();
|
525
|
+
break;
|
526
|
+
case 'prev':
|
527
|
+
me.previous();
|
528
|
+
break;
|
529
|
+
case 'up':
|
530
|
+
me.end();
|
531
|
+
break;
|
532
|
+
case 'down':
|
533
|
+
me.start();
|
534
|
+
break;
|
535
|
+
default:
|
536
|
+
console.log(e);
|
537
|
+
};
|
538
|
+
};
|
539
|
+
}
|
540
|
+
};
|
541
|
+
|
542
|
+
/**********************************************
|
543
|
+
* Static methods
|
544
|
+
**********************************************/
|
545
|
+
|
546
|
+
// Helper method for plugins
|
547
|
+
self.getSlide = function(element) {
|
548
|
+
var slide = element;
|
549
|
+
|
550
|
+
while (slide && slide.classList && !slide.classList.contains('slide')) {
|
551
|
+
slide = slide.parentNode;
|
552
|
+
}
|
553
|
+
|
554
|
+
return slide;
|
555
|
+
}
|
556
|
+
|
557
|
+
})(document.head || document.getElementsByTagName('head')[0], document.body, document.documentElement);
|
558
|
+
|
559
|
+
// Rudimentary style[scoped] polyfill
|
560
|
+
addEventListener('load', function(){ // no idea why the timeout is needed
|
561
|
+
$$('style[scoped]').forEach(function(style) {
|
562
|
+
var rulez = style.sheet.cssRules,
|
563
|
+
parentid = style.parentNode.id || self.getSlide(style).id || style.parentNode.parentNode.id;
|
564
|
+
|
565
|
+
for(var j=rulez.length; j--;) {
|
566
|
+
var selector = rulez[j].selectorText.replace(/^|,/g, function($0) {
|
567
|
+
return '#' + parentid + ' ' + $0
|
568
|
+
});
|
569
|
+
|
570
|
+
var cssText = rulez[j].cssText.replace(/^.+?{/, selector + '{');
|
571
|
+
|
572
|
+
style.sheet.deleteRule(j);
|
573
|
+
style.sheet.insertRule(cssText, j);
|
574
|
+
}
|
575
|
+
|
576
|
+
});
|
577
|
+
});
|
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 DSIW
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Modern theme
|
2
|
+
|
3
|
+
Theme for [slide-em-up](https://github.com/nono/slide-em-up)
|
4
|
+
|
5
|
+
This theme is based on [Bright Theme](https://github.com/shower/bright).
|
6
|
+
|
7
|
+
# Installation
|
8
|
+
|
9
|
+
0. `cd /tmp`
|
10
|
+
1. `git clone url modern`
|
11
|
+
2. `cd modern`
|
12
|
+
2. `sass --update styles:css`
|
13
|
+
2. `mkdir ~/.slide-em-up`
|
14
|
+
3. `cp -r modern ~/.slide-em-up/modern`
|
15
|
+
4. `mkdir ~/presentation`
|
16
|
+
5. `cd ~/presentation`
|
17
|
+
6. `mkdir main`
|
18
|
+
7. `vim main/slides.md`
|
19
|
+
```sh
|
20
|
+
cat > main/slides.md <<EOF
|
21
|
+
!SLIDE
|
22
|
+
# My first slide
|
23
|
+
|
24
|
+
* First bullet point
|
25
|
+
EOF
|
26
|
+
```
|
27
|
+
8. Create presentation.json
|
28
|
+
```sh
|
29
|
+
cat > presentation.json <<EOF
|
30
|
+
{
|
31
|
+
"title": "My first presentation",
|
32
|
+
"theme": "modern",
|
33
|
+
"pygments_style": "github",
|
34
|
+
"duration": 20,
|
35
|
+
"sections": {
|
36
|
+
"main": "Title of my main section"
|
37
|
+
}
|
38
|
+
}
|
39
|
+
EOF
|
40
|
+
```
|
41
|
+
9. `gem install slide-em-up`
|
42
|
+
10. `slide-em-up`
|
43
|
+
11. Open your browser on http://localhost:9000
|
44
|
+
|
45
|
+
# Usage
|
46
|
+
|
47
|
+
```html
|
48
|
+
!SLIDE chapter
|
49
|
+
!SLIDE section
|
50
|
+
!SLIDE shout [up|right]
|
51
|
+
!SLIDE cover [w|h|wh]
|
52
|
+
```
|
File without changes
|
File without changes
|