slide-em-up 0.1.4 → 0.1.5

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.
@@ -0,0 +1,64 @@
1
+ <!DOCTYPE html>
2
+ <!--
3
+ Slides from Google (slides.html5rocks.com) cleaned up for new presentations
4
+
5
+ Copyright 2011 Google Inc.
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
18
+
19
+ Original slides: Marcin Wichary (mwichary@google.com)
20
+ Modifications: Chrome DevRel Team (chrome-devrel@googlegroups.com)
21
+ Alex Russell (slightlyoff@chromium.org)
22
+ Brad Neuberg
23
+ -->
24
+ <html>
25
+ <head>
26
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge;chrome=1" />
27
+ <title><%= meta.title %></title>
28
+ <link href="http://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans+Mono" rel="stylesheet" type="text/css" />
29
+ <link href="css/moon.css" class="theme" rel="stylesheet" />
30
+ <link href="css/sand.css" class="theme" rel="stylesheet" />
31
+ <link href="css/sea_wave.css" class="theme" rel="stylesheet" />
32
+ <link href="css/default.css" class="theme" rel="stylesheet" media="screen" />
33
+ </head>
34
+ <body>
35
+
36
+ <div class="presentation">
37
+ <div id="presentation-counter">Loading...</div>
38
+ <div class="slides">
39
+ <div class="slide" id="landing-slide">
40
+ <section class="middle">
41
+ <p><%= meta.title %></p>
42
+ <p>Press <span id="left-init-key" class="key">&rarr;</span> key to advance.</p>
43
+ <p>Press <span class="key">t</span> to switch CSS theme.</p>
44
+ </section>
45
+ </div>
46
+ <% sections.each do |section| %>
47
+ <% section.slides.each do |slide| %>
48
+ <div id="slide-<%= section.number %>-<%= slide.number%>" class="slide">
49
+ <section class="<%= slide.classes %>">
50
+ <%= slide.html %>
51
+ </section>
52
+ </div>
53
+ <% end %>
54
+ <% end %>
55
+ </div>
56
+
57
+ <!--[if lt IE 9]>
58
+ <script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js">
59
+ </script>
60
+ <script>CFInstall.check({ mode: "overlay" });</script>
61
+ <![endif]-->
62
+ <script src="js/slides.js"></script>
63
+ </body>
64
+ </html>
@@ -0,0 +1,441 @@
1
+ (function() {
2
+ var doc = document;
3
+ var disableBuilds = false;
4
+
5
+ var ctr = 0;
6
+ var spaces = /\s+/, a1 = [''];
7
+
8
+ var toArray = function(list) {
9
+ return Array.prototype.slice.call(list || [], 0);
10
+ };
11
+
12
+ var byId = function(id) {
13
+ if (typeof id == 'string') { return doc.getElementById(id); }
14
+ return id;
15
+ };
16
+
17
+ var query = function(query, root) {
18
+ return queryAll(query, root)[0];
19
+ }
20
+
21
+ var queryAll = function(query, root) {
22
+ if (!query) { return []; }
23
+ if (typeof query != 'string') { return toArray(query); }
24
+ if (typeof root == 'string') {
25
+ root = byId(root);
26
+ if(!root){ return []; }
27
+ }
28
+
29
+ root = root || document;
30
+ var rootIsDoc = (root.nodeType == 9);
31
+ var doc = rootIsDoc ? root : (root.ownerDocument || document);
32
+
33
+ // rewrite the query to be ID rooted
34
+ if (!rootIsDoc || ('>~+'.indexOf(query.charAt(0)) >= 0)) {
35
+ root.id = root.id || ('qUnique' + (ctr++));
36
+ query = '#' + root.id + ' ' + query;
37
+ }
38
+ // don't choke on something like ".yada.yada >"
39
+ if ('>~+'.indexOf(query.slice(-1)) >= 0) { query += ' *'; }
40
+ return toArray(doc.querySelectorAll(query));
41
+ };
42
+
43
+ var strToArray = function(s) {
44
+ if (typeof s == 'string' || s instanceof String) {
45
+ if (s.indexOf(' ') < 0) {
46
+ a1[0] = s;
47
+ return a1;
48
+ } else {
49
+ return s.split(spaces);
50
+ }
51
+ }
52
+ return s;
53
+ };
54
+
55
+ // Needed for browsers that don't support String.trim() (e.g. iPad)
56
+ var trim = function(str) {
57
+ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
58
+ };
59
+
60
+ var addClass = function(node, classStr) {
61
+ classStr = strToArray(classStr);
62
+ var cls = ' ' + node.className + ' ';
63
+ for (var i = 0, len = classStr.length, c; i < len; ++i) {
64
+ c = classStr[i];
65
+ if (c && cls.indexOf(' ' + c + ' ') < 0) {
66
+ cls += c + ' ';
67
+ }
68
+ }
69
+ node.className = trim(cls);
70
+ };
71
+
72
+ var removeClass = function(node, classStr) {
73
+ var cls;
74
+ if (classStr !== undefined) {
75
+ classStr = strToArray(classStr);
76
+ cls = ' ' + node.className + ' ';
77
+ for (var i = 0, len = classStr.length; i < len; ++i) {
78
+ cls = cls.replace(' ' + classStr[i] + ' ', ' ');
79
+ }
80
+ cls = trim(cls);
81
+ } else {
82
+ cls = '';
83
+ }
84
+ if (node.className != cls) {
85
+ node.className = cls;
86
+ }
87
+ };
88
+
89
+ var toggleClass = function(node, classStr) {
90
+ var cls = ' ' + node.className + ' ';
91
+ if (cls.indexOf(' ' + trim(classStr) + ' ') >= 0) {
92
+ removeClass(node, classStr);
93
+ } else {
94
+ addClass(node, classStr);
95
+ }
96
+ };
97
+
98
+
99
+ // modernizr lite via https://gist.github.com/598008
100
+ var testStyle = function(style) {
101
+
102
+ var elem = document.createElement('div');
103
+ var prefixes = ['Webkit', 'Moz', 'O', 'ms', 'Khtml'];
104
+ var bool;
105
+ var bump = function(all, letter) {
106
+ return letter.toUpperCase();
107
+ };
108
+ var prop;
109
+
110
+ bool = style in elem.style;
111
+ prop = style.replace(/^(.)/, bump).replace(/-([a-z])/ig, bump);
112
+
113
+ for (var len = prefixes.length; len--; ){
114
+ if (bool) {
115
+ break;
116
+ }
117
+ bool = prefixes[len] + prop in elem.style;
118
+ }
119
+
120
+ document.documentElement.className += ' ' + (bool ? '' : 'no-') + style.replace(/-/g, '');
121
+ return bool;
122
+ };
123
+
124
+ var canTransition = testStyle('transition');
125
+
126
+ //
127
+ // Slide class
128
+ //
129
+ var Slide = function(node, idx) {
130
+ this._node = node;
131
+ if (idx >= 0) {
132
+ this._count = idx + 1;
133
+ }
134
+ if (this._node) {
135
+ addClass(this._node, 'slide distant-slide');
136
+ }
137
+ this._makeCounter();
138
+ this._makeBuildList();
139
+ };
140
+
141
+ Slide.prototype = {
142
+ _node: null,
143
+ _count: 0,
144
+ _buildList: [],
145
+ _visited: false,
146
+ _currentState: '',
147
+ _states: [ 'distant-slide', 'far-past',
148
+ 'past', 'current', 'future',
149
+ 'far-future', 'distant-slide' ],
150
+ setState: function(state) {
151
+ if (typeof state != 'string') {
152
+ state = this._states[state];
153
+ }
154
+ if (state == 'current' && !this._visited) {
155
+ this._visited = true;
156
+ this._makeBuildList();
157
+ }
158
+ removeClass(this._node, this._states);
159
+ addClass(this._node, state);
160
+ this._currentState = state;
161
+
162
+ // delay first auto run. Really wish this were in CSS.
163
+ /*
164
+ this._runAutos();
165
+ */
166
+ var _t = this;
167
+ setTimeout(function(){ _t._runAutos(); } , 400);
168
+
169
+ if (state == 'current') {
170
+ this._onLoad();
171
+ } else {
172
+ this._onUnload();
173
+ }
174
+ },
175
+ _onLoad: function() {
176
+ this._fireEvent('onload');
177
+ this._showFrames();
178
+ },
179
+ _onUnload: function() {
180
+ this._fireEvent('onunload');
181
+ this._hideFrames();
182
+ },
183
+ _fireEvent: function(name) {
184
+ var eventSrc = this._node.getAttribute(name);
185
+ if (eventSrc) {
186
+ eventSrc = '(function() { ' + eventSrc + ' })';
187
+ var fn = eval(eventSrc);
188
+ fn.call(this._node);
189
+ }
190
+ },
191
+ _showFrames: function() {
192
+ var frames = queryAll('iframe', this._node);
193
+ function show() {
194
+ frames.forEach(function(el) {
195
+ var _src = el.getAttribute('_src');
196
+ if (_src && _src.length) {
197
+ el.src = _src;
198
+ }
199
+ });
200
+ }
201
+ setTimeout(show, 0);
202
+ },
203
+ _hideFrames: function() {
204
+ var frames = queryAll('iframe', this._node);
205
+ function hide() {
206
+ frames.forEach(function(el) {
207
+ var _src = el.getAttribute('_src');
208
+ if (_src && _src.length) {
209
+ el.src = '';
210
+ }
211
+ });
212
+ }
213
+ setTimeout(hide, 250);
214
+ },
215
+ _makeCounter: function() {
216
+ if(!this._count || !this._node) { return; }
217
+ var c = doc.createElement('span');
218
+ c.textContent = this._count;
219
+ c.className = 'counter';
220
+ this._node.appendChild(c);
221
+ },
222
+ _makeBuildList: function() {
223
+ this._buildList = [];
224
+ if (disableBuilds) { return; }
225
+ if (this._node) {
226
+ this._buildList = queryAll('[data-build] > *', this._node);
227
+ }
228
+ this._buildList.forEach(function(el) {
229
+ addClass(el, 'to-build');
230
+ });
231
+ },
232
+ _runAutos: function() {
233
+ if (this._currentState != 'current') {
234
+ return;
235
+ }
236
+ // find the next auto, slice it out of the list, and run it
237
+ var idx = -1;
238
+ this._buildList.some(function(n, i) {
239
+ if (n.hasAttribute('data-auto')) {
240
+ idx = i;
241
+ return true;
242
+ }
243
+ return false;
244
+ });
245
+ if (idx >= 0) {
246
+ var elem = this._buildList.splice(idx, 1)[0];
247
+
248
+ var _t = this;
249
+ if (canTransition) {
250
+ var l = function(evt) {
251
+ elem.parentNode.removeEventListener('webkitTransitionEnd', l, false);
252
+ elem.parentNode.removeEventListener('transitionend', l, false); // moz
253
+ elem.parentNode.removeEventListener('oTransitionEnd', l, false);
254
+ _t._runAutos();
255
+ };
256
+ elem.parentNode.addEventListener('webkitTransitionEnd', l, false);
257
+ elem.parentNode.addEventListener('transitionend', l, false);
258
+ elem.parentNode.addEventListener('oTransitionEnd', l, false);
259
+ removeClass(elem, 'to-build');
260
+ } else {
261
+ setTimeout(function() {
262
+ removeClass(elem, 'to-build');
263
+ _t._runAutos();
264
+ }, 400);
265
+ }
266
+ }
267
+ },
268
+ buildNext: function() {
269
+ if (!this._buildList.length) {
270
+ return false;
271
+ }
272
+ removeClass(this._buildList.shift(), 'to-build');
273
+ return true;
274
+ },
275
+ };
276
+
277
+ //
278
+ // SlideShow class
279
+ //
280
+ var SlideShow = function(slides) {
281
+ this._slides = (slides || []).map(function(el, idx) {
282
+ return new Slide(el, idx);
283
+ });
284
+ var h = window.location.hash;
285
+ try {
286
+ this.current = h;
287
+ } catch (e) { /* squeltch */ }
288
+ this.current = (!this.current) ? "landing-slide" : this.current.replace('#', '');
289
+ if (!query('#' + this.current)) {
290
+ // if this happens is very likely that someone is coming from
291
+ // a link with the old permalink format, i.e. #slide24
292
+ alert('The format of the permalinks have recently changed. If you are coming ' +
293
+ 'here from an old external link it\'s very likely you will land to the wrong slide');
294
+ this.current = "landing-slide";
295
+ }
296
+ var _t = this;
297
+ doc.addEventListener('keydown',
298
+ function(e) { _t.handleKeys(e); }, false);
299
+ doc.addEventListener('touchstart',
300
+ function(e) { _t.handleTouchStart(e); }, false);
301
+ doc.addEventListener('touchend',
302
+ function(e) { _t.handleTouchEnd(e); }, false);
303
+ window.addEventListener('popstate',
304
+ function(e) { if (e.state) { _t.go(e.state); } }, false);
305
+ query('#left-init-key').addEventListener('click',
306
+ function() { _t.next(); }, false);
307
+ this._update();
308
+ };
309
+
310
+ SlideShow.prototype = {
311
+ _presentationCounter: query('#presentation-counter'),
312
+ _slides: [],
313
+ _getCurrentIndex: function() {
314
+ var me = this;
315
+ var slideCount = null;
316
+ queryAll('.slide').forEach(function(slide, i) {
317
+ if (slide.id == me.current) {
318
+ slideCount = i;
319
+ }
320
+ });
321
+ return slideCount + 1;
322
+ },
323
+ _update: function(dontPush) {
324
+ // in order to delay the time where the counter shows the slide number we check if
325
+ // the slides are already loaded (so we show the loading... instead)
326
+ // the technique to test visibility is taken from here
327
+ // http://stackoverflow.com/questions/704758/how-to-check-if-an-element-is-really-visible-with-javascript
328
+ var docElem = document.documentElement;
329
+ var elem = document.elementFromPoint( docElem.clientWidth / 2, docElem.clientHeight / 2);
330
+ var currentIndex = this._getCurrentIndex();
331
+ if (elem && elem.className != 'presentation') {
332
+ this._presentationCounter.textContent = currentIndex;
333
+ }
334
+ if (history.pushState) {
335
+ if (!dontPush) {
336
+ history.replaceState(this.current, 'Slide ' + this.current, '#' + this.current);
337
+ }
338
+ } else {
339
+ window.location.hash = this.current;
340
+ }
341
+ for (var x = currentIndex-1; x < currentIndex + 7; x++) {
342
+ if (this._slides[x-4]) {
343
+ this._slides[x-4].setState(Math.max(0, x-currentIndex));
344
+ }
345
+ }
346
+ },
347
+
348
+ current: 0,
349
+ next: function() {
350
+ if (!this._slides[this._getCurrentIndex() - 1].buildNext()) {
351
+ var next = query('#' + this.current + ' + .slide');
352
+ this.current = (next) ? next.id : this.current;
353
+ this._update();
354
+ }
355
+ },
356
+ prev: function() {
357
+ var prev = query('.slide:nth-child(' + (this._getCurrentIndex() - 1) + ')');
358
+ this.current = (prev) ? prev.id : this.current;
359
+ this._update();
360
+ },
361
+ go: function(slideId) {
362
+ this.current = slideId;
363
+ this._update(true);
364
+ },
365
+
366
+ _notesOn: false,
367
+ showNotes: function() {
368
+ var isOn = this._notesOn = !this._notesOn;
369
+ queryAll('.notes').forEach(function(el) {
370
+ el.style.display = (notesOn) ? 'block' : 'none';
371
+ });
372
+ },
373
+ switch3D: function() {
374
+ toggleClass(document.body, 'three-d');
375
+ },
376
+ changeTheme: function() {
377
+ var linkEls = queryAll('link.theme');
378
+ var sheetIndex = 0;
379
+ linkEls.forEach(function(stylesheet, i) {
380
+ if (!stylesheet.disabled) {
381
+ sheetIndex = i;
382
+ }
383
+ });
384
+ linkEls[sheetIndex].disabled = true;
385
+ linkEls[(sheetIndex + 1) % linkEls.length].disabled = false;
386
+ sessionStorage['theme'] = linkEls[(sheetIndex + 1) % linkEls.length].href;
387
+ },
388
+ handleKeys: function(e) {
389
+
390
+ if (/^(input|textarea)$/i.test(e.target.nodeName) || e.target.isContentEditable) {
391
+ return;
392
+ }
393
+
394
+ switch (e.keyCode) {
395
+ case 37: // left arrow
396
+ this.prev(); e.preventDefault(); break;
397
+ case 39: // right arrow
398
+ case 32: // space
399
+ this.next(); e.preventDefault(); break;
400
+ case 50: // 2
401
+ this.showNotes(); e.preventDefault(); break;
402
+ case 51: // 3
403
+ this.switch3D(); e.preventDefault(); break;
404
+ case 84: // T
405
+ this.changeTheme(); e.preventDefault(); break;
406
+ }
407
+ },
408
+ _touchStartX: 0,
409
+ handleTouchStart: function(e) {
410
+ this._touchStartX = e.touches[0].pageX;
411
+ },
412
+ handleTouchEnd: function(e) {
413
+ var delta = this._touchStartX - e.changedTouches[0].pageX;
414
+ var SWIPE_SIZE = 150;
415
+ if (delta > SWIPE_SIZE) {
416
+ this.next();
417
+ } else if (delta< -SWIPE_SIZE) {
418
+ this.prev();
419
+ }
420
+ },
421
+ };
422
+
423
+ // disable style theme stylesheets
424
+ var linkEls = queryAll('link.theme');
425
+ var stylesheetPath = sessionStorage['theme'] || 'css/default.css';
426
+ linkEls.forEach(function(stylesheet) {
427
+ stylesheet.disabled = !(stylesheet.href.indexOf(stylesheetPath) != -1);
428
+ });
429
+
430
+ // Initialize
431
+ var slideshow = new SlideShow(queryAll('.slide'));
432
+
433
+ document.addEventListener('DOMContentLoaded', function() {
434
+ query('.slides').style.display = 'block';
435
+ }, false);
436
+
437
+ queryAll('pre').forEach(function(el) {
438
+ addClass(el, 'prettyprint');
439
+ });
440
+
441
+ })();