slide-em-up 0.2.0 → 0.2.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.
- data/README.md +2 -1
- data/lib/slide-em-up/version.rb +1 -1
- data/themes/CSSS/README +2 -0
- data/themes/CSSS/css/slideshow.css +340 -0
- data/themes/CSSS/css/theme.css +246 -0
- data/themes/CSSS/images/rainbow-wood.jpg +0 -0
- data/themes/CSSS/index.erb +35 -0
- data/themes/CSSS/js/classList.js +116 -0
- data/themes/CSSS/js/slideshow.js +483 -0
- data/themes/common/css/pygments/native.css +70 -0
- data/themes/shower/index.erb +3 -0
- metadata +22 -14
Binary file
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
6
|
+
<title><%= meta.title %></title>
|
7
|
+
<% (theme.css + meta.css).each do |css| %>
|
8
|
+
<link rel="stylesheet" href="<%= css%>">
|
9
|
+
<% end %>
|
10
|
+
<link rel="stylesheet" href="css/pygments/native.css">
|
11
|
+
</head>
|
12
|
+
<body data-duration="60">
|
13
|
+
<section>
|
14
|
+
<header class="slide">
|
15
|
+
<h1><%= meta.title %></h1>
|
16
|
+
</header>
|
17
|
+
</section>
|
18
|
+
<% sections.each do |section| %>
|
19
|
+
<section>
|
20
|
+
<header class="slide">
|
21
|
+
<h1><%= section.title %></h1>
|
22
|
+
</header>
|
23
|
+
<% section.slides.each do |slide| %>
|
24
|
+
<section class="slide <%= slide.classes %>">
|
25
|
+
<%= slide.html %>
|
26
|
+
</section>
|
27
|
+
<% end %>
|
28
|
+
</section>
|
29
|
+
<% end %>
|
30
|
+
<% (theme.js + meta.js).each do |js| %>
|
31
|
+
<script src="<%= js %>"></script>
|
32
|
+
<% end %>
|
33
|
+
<script>var slideshow = new SlideShow();</script>
|
34
|
+
</body>
|
35
|
+
</html>
|
@@ -0,0 +1,116 @@
|
|
1
|
+
/*
|
2
|
+
* classList.js: Implements a cross-browser element.classList getter.
|
3
|
+
* 2010-09-06
|
4
|
+
*
|
5
|
+
* By Eli Grey, http://eligrey.com
|
6
|
+
* Public Domain.
|
7
|
+
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
8
|
+
*/
|
9
|
+
|
10
|
+
"use strict";
|
11
|
+
|
12
|
+
if (typeof Element !== "undefined") {
|
13
|
+
|
14
|
+
(function () {
|
15
|
+
|
16
|
+
var
|
17
|
+
classListProp = "classList"
|
18
|
+
, protoProp = "prototype"
|
19
|
+
, elemCtrProto = Element[protoProp]
|
20
|
+
, objCtr = Object
|
21
|
+
;
|
22
|
+
if (!objCtr.hasOwnProperty.call(elemCtrProto, classListProp)) {
|
23
|
+
var
|
24
|
+
strTrim = String[protoProp].trim || function () {
|
25
|
+
return this.replace(/^\s+|\s+$/g, "");
|
26
|
+
}
|
27
|
+
, arrIndexOf = Array[protoProp].indexOf || function (item) {
|
28
|
+
for (var i = 0, len = this.length; i < len; i++) {
|
29
|
+
if (i in this && this[i] === item) {
|
30
|
+
return i;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
return -1;
|
34
|
+
}
|
35
|
+
, checkTokenAndGetIndex = function (classList, token) {
|
36
|
+
if (token === "") {
|
37
|
+
throw "SYNTAX_ERR";
|
38
|
+
}
|
39
|
+
if (/\s/.test(token)) {
|
40
|
+
throw "INVALID_CHARACTER_ERR";
|
41
|
+
}
|
42
|
+
return arrIndexOf.call(classList, token);
|
43
|
+
}
|
44
|
+
, ClassList = function (elem) {
|
45
|
+
var
|
46
|
+
trimmedClasses = strTrim.call(elem.className)
|
47
|
+
, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
|
48
|
+
;
|
49
|
+
for (var i = 0, len = classes.length; i < len; i++) {
|
50
|
+
this.push(classes[i]);
|
51
|
+
}
|
52
|
+
this.updateClassName = function () {
|
53
|
+
elem.className = this.toString();
|
54
|
+
};
|
55
|
+
}
|
56
|
+
, classListProto = ClassList[protoProp] = []
|
57
|
+
, classListGetter = function () {
|
58
|
+
return new ClassList(this);
|
59
|
+
}
|
60
|
+
;
|
61
|
+
classListProto.item = function (i) {
|
62
|
+
return this[i] || null;
|
63
|
+
};
|
64
|
+
classListProto.contains = function (token) {
|
65
|
+
token += "";
|
66
|
+
return checkTokenAndGetIndex(this, token) !== -1;
|
67
|
+
};
|
68
|
+
classListProto.add = function (token) {
|
69
|
+
token += "";
|
70
|
+
if (checkTokenAndGetIndex(this, token) === -1) {
|
71
|
+
this.push(token);
|
72
|
+
this.updateClassName();
|
73
|
+
}
|
74
|
+
};
|
75
|
+
classListProto.remove = function (token) {
|
76
|
+
token += "";
|
77
|
+
var index = checkTokenAndGetIndex(this, token);
|
78
|
+
if (index !== -1) {
|
79
|
+
this.splice(index, 1);
|
80
|
+
this.updateClassName();
|
81
|
+
}
|
82
|
+
};
|
83
|
+
classListProto.toggle = function (token) {
|
84
|
+
token += "";
|
85
|
+
if (checkTokenAndGetIndex(this, token) === -1) {
|
86
|
+
this.add(token);
|
87
|
+
} else {
|
88
|
+
this.remove(token);
|
89
|
+
}
|
90
|
+
};
|
91
|
+
classListProto.toString = function () {
|
92
|
+
return this.join(" ");
|
93
|
+
};
|
94
|
+
|
95
|
+
if (objCtr.defineProperty) {
|
96
|
+
var classListDescriptor = {
|
97
|
+
get: classListGetter
|
98
|
+
, enumerable: true
|
99
|
+
, configurable: true
|
100
|
+
};
|
101
|
+
try {
|
102
|
+
objCtr.defineProperty(elemCtrProto, classListProp, classListDescriptor);
|
103
|
+
} catch (ex) { // IE 8 doesn't support enumerable:true
|
104
|
+
if (ex.number === -0x7FF5EC54) {
|
105
|
+
classListDescriptor.enumerable = false;
|
106
|
+
objCtr.defineProperty(elemCtrProto, classListProp, classListDescriptor);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
} else if (objCtr[protoProp].__defineGetter__) {
|
110
|
+
elemCtrProto.__defineGetter__(classListProp, classListGetter);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
}());
|
115
|
+
|
116
|
+
}
|
@@ -0,0 +1,483 @@
|
|
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) { if(con && !con.querySelector) console.trace();
|
11
|
+
return (con || document).querySelector(expr); }
|
12
|
+
function $$(expr, con) { return [].slice.call((con || document).querySelectorAll(expr)); }
|
13
|
+
|
14
|
+
(function(head, body){
|
15
|
+
|
16
|
+
// Check for classList support and include the polyfill if it's not supported
|
17
|
+
if(!('classList' in body)) {
|
18
|
+
var thisScript = $('script[src$="slideshow.js"]'),
|
19
|
+
script = document.createElement('script');
|
20
|
+
script.src = thisScript.src.replace(/\bslideshow\.js/, 'classList.js');
|
21
|
+
thisScript.parentNode.insertBefore(script, thisScript);
|
22
|
+
}
|
23
|
+
|
24
|
+
// Cache <title> element, we may need it for slides that don't have titles
|
25
|
+
var documentTitle = document.title + '';
|
26
|
+
|
27
|
+
var self = window.SlideShow = function(container, slide) {
|
28
|
+
var me = this;
|
29
|
+
|
30
|
+
// Set instance
|
31
|
+
if(!window.slideshow) {
|
32
|
+
window.slideshow = this;
|
33
|
+
}
|
34
|
+
|
35
|
+
container = container || body;
|
36
|
+
|
37
|
+
// Current slide
|
38
|
+
this.slide = slide || 0;
|
39
|
+
|
40
|
+
// Current .delayed item in the slide
|
41
|
+
this.item = 0;
|
42
|
+
|
43
|
+
// Do we need to add a timer?
|
44
|
+
this.duration = container.getAttribute('data-duration');
|
45
|
+
|
46
|
+
if(this.duration > 0) {
|
47
|
+
var timer = document.createElement('div'),
|
48
|
+
declaration = 'transition: ' + this.duration * 60 + 's linear; ';
|
49
|
+
|
50
|
+
timer.id = 'timer';
|
51
|
+
timer.setAttribute('style', '-moz-' + declaration + '-webkit-' + declaration + '-o-' + declaration + '-ms-' + declaration + declaration);
|
52
|
+
container.appendChild(timer);
|
53
|
+
|
54
|
+
setTimeout(function() {
|
55
|
+
timer.className = 'end';
|
56
|
+
}, 1);
|
57
|
+
}
|
58
|
+
|
59
|
+
var delayed = $$('ol li', container);
|
60
|
+
for (var i=0; i<delayed.length; i++) {
|
61
|
+
delayed[i].className = "delayed";
|
62
|
+
}
|
63
|
+
|
64
|
+
// Get the slide elements into an array
|
65
|
+
this.slides = Array.prototype.slice.apply($$('.slide', container));
|
66
|
+
|
67
|
+
for(var i=0; i<this.slides.length; i++) {
|
68
|
+
var slide = this.slides[i]; // to speed up references
|
69
|
+
|
70
|
+
// Asign ids to slides that don't have one
|
71
|
+
if(!slide.id) {
|
72
|
+
slide.id = 'slide' + (i+1);
|
73
|
+
}
|
74
|
+
|
75
|
+
// Set data-title attribute to the title of the slide
|
76
|
+
if(!slide.title) {
|
77
|
+
// no title attribute, fetch title from heading(s)
|
78
|
+
var heading = $('hgroup', slide) || $('h1,h2,h3,h4,h5,h6', slide);
|
79
|
+
|
80
|
+
if(heading && heading.textContent.trim()) {
|
81
|
+
slide.setAttribute('data-title', heading.textContent);
|
82
|
+
}
|
83
|
+
}
|
84
|
+
else {
|
85
|
+
// The title attribute is set, use that
|
86
|
+
slide.setAttribute('data-title', slide.title);
|
87
|
+
slide.removeAttribute('title');
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
// If there's already a hash, update current slide number...
|
92
|
+
this.goto(location.hash.substr(1) || 0);
|
93
|
+
|
94
|
+
// ...and keep doing so every time the hash changes
|
95
|
+
this.onhashchange = function() {
|
96
|
+
me.goto(location.hash.substr(1) || 0);
|
97
|
+
};
|
98
|
+
window.addEventListener('hashchange', this.onhashchange, false);
|
99
|
+
|
100
|
+
if(window.name === 'projector') {
|
101
|
+
document.body.classList.add('projector');
|
102
|
+
}
|
103
|
+
|
104
|
+
// Adjust the font-size when the window is resized
|
105
|
+
addEventListener('resize', function() {
|
106
|
+
me.adjustFontSize();
|
107
|
+
}, false);
|
108
|
+
|
109
|
+
// In some browsers DOMContentLoaded is too early, so try again onload
|
110
|
+
addEventListener('load', function() {
|
111
|
+
me.adjustFontSize();
|
112
|
+
}, false);
|
113
|
+
|
114
|
+
/**
|
115
|
+
Keyboard navigation
|
116
|
+
Ctrl+G : Go to slide...
|
117
|
+
Ctrl+H : Show thumbnails and go to slide
|
118
|
+
Ctrl+P : Presenter view
|
119
|
+
(Shift instead of Ctrl works too)
|
120
|
+
*/
|
121
|
+
document.addEventListener('keyup', function(evt) {
|
122
|
+
if(evt.ctrlKey || evt.shiftKey) {
|
123
|
+
switch(evt.keyCode) {
|
124
|
+
case 71: // G
|
125
|
+
var slide = prompt('Which slide?');
|
126
|
+
me.goto(+slide? slide - 1 : slide);
|
127
|
+
break;
|
128
|
+
case 72: // H
|
129
|
+
if(body.classList.contains('show-thumbnails')) {
|
130
|
+
body.classList.remove('show-thumbnails');
|
131
|
+
body.classList.remove('headers-only');
|
132
|
+
}
|
133
|
+
else {
|
134
|
+
body.classList.add('show-thumbnails');
|
135
|
+
|
136
|
+
if(!evt.shiftKey || !evt.ctrlKey) {
|
137
|
+
body.classList.add('headers-only');
|
138
|
+
}
|
139
|
+
|
140
|
+
body.addEventListener('click', function(evt) {
|
141
|
+
var slide = evt.target;
|
142
|
+
|
143
|
+
while(slide && !slide.classList.contains('slide')) {
|
144
|
+
slide = slide.parentNode;
|
145
|
+
}
|
146
|
+
|
147
|
+
if(slide) {
|
148
|
+
me.goto(slide.id);
|
149
|
+
setTimeout(function() { me.adjustFontSize(); }, 1000); // for Opera
|
150
|
+
}
|
151
|
+
|
152
|
+
body.classList.remove('show-thumbnails');
|
153
|
+
body.classList.remove('headers-only');
|
154
|
+
}, false);
|
155
|
+
}
|
156
|
+
break;
|
157
|
+
case 74: // J
|
158
|
+
if(body.classList.contains('hide-elements')) {
|
159
|
+
body.classList.remove('hide-elements');
|
160
|
+
}
|
161
|
+
else {
|
162
|
+
body.classList.add('hide-elements');
|
163
|
+
}
|
164
|
+
break;
|
165
|
+
case 80: // P
|
166
|
+
// Open new window for attendee view
|
167
|
+
me.projector = open(location, 'projector');
|
168
|
+
|
169
|
+
// Get the focus back
|
170
|
+
window.focus();
|
171
|
+
|
172
|
+
// Switch this one to presenter view
|
173
|
+
body.classList.add('presenter');
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}, false);
|
177
|
+
|
178
|
+
/**
|
179
|
+
Keyboard navigation
|
180
|
+
Home : First slide
|
181
|
+
End : Last slide
|
182
|
+
Space/Up/Right arrow : Next item/slide
|
183
|
+
Ctrl + Space/Up/Right arrow : Next slide
|
184
|
+
Down/Left arrow : Previous item/slide
|
185
|
+
Ctrl + Down/Left arrow : Previous slide
|
186
|
+
(Shift instead of Ctrl works too)
|
187
|
+
*/
|
188
|
+
document.addEventListener('keydown', function(evt) {
|
189
|
+
if(evt.target === body || evt.target === body.parentNode || evt.altKey) {
|
190
|
+
if(evt.keyCode >= 32 && evt.keyCode <= 40) {
|
191
|
+
evt.preventDefault();
|
192
|
+
}
|
193
|
+
|
194
|
+
switch(evt.keyCode) {
|
195
|
+
case 33: //page up
|
196
|
+
me.previous();
|
197
|
+
break;
|
198
|
+
case 34: //page down
|
199
|
+
me.next();
|
200
|
+
break;
|
201
|
+
case 35: // end
|
202
|
+
me.end();
|
203
|
+
break;
|
204
|
+
case 36: // home
|
205
|
+
me.start();
|
206
|
+
break;
|
207
|
+
case 37: // <-
|
208
|
+
case 38: // up arrow
|
209
|
+
me.previous(evt.ctrlKey || evt.shiftKey);
|
210
|
+
break;
|
211
|
+
case 32: // space
|
212
|
+
case 39: // ->
|
213
|
+
case 40: // down arrow
|
214
|
+
me.next(evt.ctrlKey || evt.shiftKey);
|
215
|
+
break;
|
216
|
+
}
|
217
|
+
}
|
218
|
+
}, false);
|
219
|
+
|
220
|
+
if (window['EventSource'] != undefined) {
|
221
|
+
var source = new EventSource('/remote/sub/events');
|
222
|
+
source.onmessage = function(e) {
|
223
|
+
switch(e.data){
|
224
|
+
case 'next':
|
225
|
+
me.next();
|
226
|
+
break;
|
227
|
+
case 'prev':
|
228
|
+
me.prev();
|
229
|
+
break;
|
230
|
+
case 'up':
|
231
|
+
me.next(true);
|
232
|
+
break;
|
233
|
+
case 'down':
|
234
|
+
me.prev(true);
|
235
|
+
break;
|
236
|
+
default:
|
237
|
+
console.log(e);
|
238
|
+
};
|
239
|
+
};
|
240
|
+
}
|
241
|
+
|
242
|
+
// Rudimentary style[scoped] polyfill
|
243
|
+
var scoped = $$('style[scoped]', container);
|
244
|
+
|
245
|
+
for(var i=scoped.length; i--;) {
|
246
|
+
var style = scoped[i],
|
247
|
+
rulez = style.sheet.cssRules,
|
248
|
+
parentid = style.parentNode.id || self.getSlide(style).id;
|
249
|
+
|
250
|
+
for(var j=rulez.length; j--;) {
|
251
|
+
var cssText = rulez[j].cssText.replace(/^|,/g, function($0) { return '#' + parentid + ' ' + $0 });
|
252
|
+
|
253
|
+
style.sheet.deleteRule(0);
|
254
|
+
style.sheet.insertRule(cssText, 0);
|
255
|
+
}
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
self.prototype = {
|
260
|
+
start: function() {
|
261
|
+
this.goto(0);
|
262
|
+
},
|
263
|
+
|
264
|
+
end: function() {
|
265
|
+
this.goto(this.slides.length - 1);
|
266
|
+
},
|
267
|
+
|
268
|
+
/**
|
269
|
+
@param hard {Boolean} Whether to advance to the next slide (true) or
|
270
|
+
just the next step (which could very well be showing a list item)
|
271
|
+
*/
|
272
|
+
next: function(hard) {
|
273
|
+
if(!hard && this.items.length) {
|
274
|
+
// If there's no current, then just mark the first one as such
|
275
|
+
if(!this.item) {
|
276
|
+
this.items[this.item++].classList.add('current');
|
277
|
+
}
|
278
|
+
// Add .current to current item if it exists, otherwise advance to next slide
|
279
|
+
else if(this.item < this.items.length) {
|
280
|
+
classes = this.items[this.item - 1].classList; // to speed up lookups
|
281
|
+
|
282
|
+
classes.remove('current');
|
283
|
+
classes.add('displayed');
|
284
|
+
|
285
|
+
this.items[this.item++].classList.add('current');
|
286
|
+
}
|
287
|
+
else {
|
288
|
+
this.item = 0;
|
289
|
+
this.next(true);
|
290
|
+
}
|
291
|
+
}
|
292
|
+
else {
|
293
|
+
this.goto(this.slide + 1);
|
294
|
+
|
295
|
+
this.item = 0;
|
296
|
+
|
297
|
+
// Mark all items as not displayed, if there are any
|
298
|
+
if(this.items.length) {
|
299
|
+
for (var i=0; i<this.items.length; i++) {
|
300
|
+
if(this.items[i].classList) {
|
301
|
+
this.items[i].classList.remove('displayed');
|
302
|
+
this.items[i].classList.remove('current');
|
303
|
+
}
|
304
|
+
}
|
305
|
+
}
|
306
|
+
}
|
307
|
+
},
|
308
|
+
|
309
|
+
previous: function(hard) {
|
310
|
+
if(!hard && this.item > 0) {
|
311
|
+
var classes = this.items[this.item - 1].classList; // to speed up lookups
|
312
|
+
|
313
|
+
classes.remove('current');
|
314
|
+
|
315
|
+
if(this.item > 1) {
|
316
|
+
classes = this.items[--this.item - 1].classList;
|
317
|
+
|
318
|
+
classes.remove('displayed');
|
319
|
+
classes.add('current');
|
320
|
+
}
|
321
|
+
else {
|
322
|
+
this.item = 0;
|
323
|
+
}
|
324
|
+
}
|
325
|
+
else {
|
326
|
+
|
327
|
+
this.goto(this.slide - 1);
|
328
|
+
|
329
|
+
this.item = this.items.length;
|
330
|
+
|
331
|
+
// Mark all items as displayed, if there are any
|
332
|
+
if(this.items.length) {
|
333
|
+
for (var i=0; i<this.items.length; i++) {
|
334
|
+
if(this.items[i].classList) {
|
335
|
+
this.items[i].classList.add('displayed');
|
336
|
+
}
|
337
|
+
}
|
338
|
+
|
339
|
+
// Mark the last one as current
|
340
|
+
var lastItem = this.items[this.items.length - 1];
|
341
|
+
|
342
|
+
lastItem.classList.remove('displayed');
|
343
|
+
lastItem.classList.add('current');
|
344
|
+
}
|
345
|
+
}
|
346
|
+
},
|
347
|
+
|
348
|
+
/**
|
349
|
+
Go to an aribtary slide
|
350
|
+
@param which {String|Integer} Which slide (identifier or slide number)
|
351
|
+
*/
|
352
|
+
goto: function(which) {
|
353
|
+
var slide;
|
354
|
+
|
355
|
+
// We have to remove it to prevent multiple calls to goto messing up
|
356
|
+
// our current item (and there's no point either, so we save on performance)
|
357
|
+
window.removeEventListener('hashchange', this.onhashchange, false);
|
358
|
+
|
359
|
+
if(which + 0 === which && which in this.slides) { // Argument is a valid slide number
|
360
|
+
this.slide = which;
|
361
|
+
|
362
|
+
slide = this.slides[this.slide];
|
363
|
+
location.hash = '#' + slide.id;
|
364
|
+
}
|
365
|
+
else if(which + '' === which) { // Argument is a slide id
|
366
|
+
slide = document.getElementById(which);
|
367
|
+
|
368
|
+
if(slide) {
|
369
|
+
this.slide = this.slides.indexOf(slide);
|
370
|
+
location.hash = '#' + which;
|
371
|
+
}
|
372
|
+
}
|
373
|
+
|
374
|
+
if(slide) { // Slide actually changed, perform any other tasks needed
|
375
|
+
document.title = slide.getAttribute('data-title') || documentTitle;
|
376
|
+
|
377
|
+
this.adjustFontSize();
|
378
|
+
|
379
|
+
// Update items collection
|
380
|
+
this.items = $$('.delayed, .delayed-children > *', this.slides[this.slide]);
|
381
|
+
this.item = 0;
|
382
|
+
|
383
|
+
// Tell other windows
|
384
|
+
if(this.projector && this.projector.slideshow && this.projector.slideshow.slide != this.slide) {
|
385
|
+
this.projector.slideshow.goto(this.slide);
|
386
|
+
}
|
387
|
+
|
388
|
+
if(window.opener && opener.slideshow && opener.slideshow.slide != this.slide) {
|
389
|
+
opener.slideshow.goto(this.slide);
|
390
|
+
}
|
391
|
+
|
392
|
+
// Update next/previous
|
393
|
+
for (var i=this.slides.length; i--;) {
|
394
|
+
this.slides[i].classList.remove('previous');
|
395
|
+
this.slides[i].classList.remove('next');
|
396
|
+
}
|
397
|
+
|
398
|
+
this.slides.previous = this.slides[this.slide-1];
|
399
|
+
this.slides.next = this.slides[this.slide+1];
|
400
|
+
|
401
|
+
this.slides.previous && this.slides.previous.classList.add('previous');
|
402
|
+
this.slides.next && this.slides.next.classList.add('next');
|
403
|
+
}
|
404
|
+
|
405
|
+
// If you attach the listener immediately again then it will catch the event
|
406
|
+
// We have to do it asynchronously
|
407
|
+
var me = this;
|
408
|
+
setTimeout(function() {
|
409
|
+
window.addEventListener('hashchange', me.onhashchange, false);
|
410
|
+
}, 1000);
|
411
|
+
},
|
412
|
+
|
413
|
+
adjustFontSize: function() {
|
414
|
+
// Cache long lookup chains, for performance
|
415
|
+
var bodyStyle = body.style,
|
416
|
+
scrollRoot = document[document.documentElement.scrollHeight? 'documentElement' : 'body'],
|
417
|
+
innerHeight = window.innerHeight,
|
418
|
+
innerWidth = window.innerWidth,
|
419
|
+
slide = this.slides[this.slide];
|
420
|
+
|
421
|
+
// Clear previous styles
|
422
|
+
bodyStyle.fontSize = '';
|
423
|
+
|
424
|
+
if(body.classList.contains('show-thumbnails')
|
425
|
+
|| slide.classList.contains('dont-resize')) {
|
426
|
+
return;
|
427
|
+
}
|
428
|
+
|
429
|
+
for(
|
430
|
+
var percent = 100;
|
431
|
+
(scrollRoot.scrollHeight > innerHeight || scrollRoot.scrollWidth > innerWidth) && percent >= 35;
|
432
|
+
percent-=5
|
433
|
+
) {
|
434
|
+
bodyStyle.fontSize = percent + '%';
|
435
|
+
}
|
436
|
+
|
437
|
+
// Individual slide
|
438
|
+
|
439
|
+
if(slide.clientHeight && slide.clientWidth) {
|
440
|
+
// Strange FF bug: scrollHeight doesn't work properly with overflow:hidden
|
441
|
+
var previousStyle = slide.getAttribute('style');
|
442
|
+
slide.style.overflow = 'auto';
|
443
|
+
|
444
|
+
for(
|
445
|
+
;
|
446
|
+
(slide.scrollHeight > slide.clientHeight || slide.scrollWidth > slide.clientWidth) && percent >= 35;
|
447
|
+
percent--
|
448
|
+
) {
|
449
|
+
bodyStyle.fontSize = percent + '%';
|
450
|
+
}
|
451
|
+
|
452
|
+
slide.setAttribute('style', previousStyle);
|
453
|
+
}
|
454
|
+
},
|
455
|
+
|
456
|
+
// Is the element on the current slide?
|
457
|
+
onCurrent: function(element) {
|
458
|
+
var slide = self.getSlide(element);
|
459
|
+
|
460
|
+
if(slide) {
|
461
|
+
return '#' + slide.id === location.hash;
|
462
|
+
}
|
463
|
+
|
464
|
+
return false;
|
465
|
+
}
|
466
|
+
};
|
467
|
+
|
468
|
+
/**********************************************
|
469
|
+
* Static methods
|
470
|
+
**********************************************/
|
471
|
+
|
472
|
+
// Helper method for plugins
|
473
|
+
self.getSlide = function(element) {
|
474
|
+
var slide = element;
|
475
|
+
|
476
|
+
while (slide && slide.classList && !slide.classList.contains('slide')) {
|
477
|
+
slide = slide.parentNode;
|
478
|
+
}
|
479
|
+
|
480
|
+
return slide;
|
481
|
+
}
|
482
|
+
|
483
|
+
})(document.head || document.getElementsByTagName('head')[0], document.body);
|