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.
Files changed (214) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +218 -0
  5. data/bin/slideoff +127 -0
  6. data/lib/slideoff/config_builder.rb +60 -0
  7. data/lib/slideoff/flickr_api.rb +50 -0
  8. data/lib/slideoff/flickr_image.rb +92 -0
  9. data/lib/slideoff/markdown.rb +145 -0
  10. data/lib/slideoff/presentation.rb +90 -0
  11. data/lib/slideoff/remote_api.rb +53 -0
  12. data/lib/slideoff/routes.rb +20 -0
  13. data/lib/slideoff/server.rb +50 -0
  14. data/lib/slideoff/slides_api.rb +59 -0
  15. data/lib/slideoff/utils.rb +453 -0
  16. data/lib/slideoff.rb +15 -0
  17. data/themes/3d_slideshow/README +2 -0
  18. data/themes/3d_slideshow/css/main.css +232 -0
  19. data/themes/3d_slideshow/css/reset.css +57 -0
  20. data/themes/3d_slideshow/index.erb +31 -0
  21. data/themes/3d_slideshow/js/slideshow.js +288 -0
  22. data/themes/CSSS/README +2 -0
  23. data/themes/CSSS/css/slideshow.css +304 -0
  24. data/themes/CSSS/css/theme.css +250 -0
  25. data/themes/CSSS/images/rainbow-wood.jpg +0 -0
  26. data/themes/CSSS/index.erb +36 -0
  27. data/themes/CSSS/js/classList.js +116 -0
  28. data/themes/CSSS/js/prefixfree.min.js +5 -0
  29. data/themes/CSSS/js/slideshow.js +621 -0
  30. data/themes/common/css/pygments/colorful.css +62 -0
  31. data/themes/common/css/pygments/manni.css +61 -0
  32. data/themes/common/css/pygments/native.css +70 -0
  33. data/themes/common/css/pygments/solarized.css +66 -0
  34. data/themes/common/fonts/DroidSansMono.svg +626 -0
  35. data/themes/common/fonts/DroidSansMono.ttf +0 -0
  36. data/themes/common/fonts/Lato-BoldItalic.woff +0 -0
  37. data/themes/common/fonts/Lato-Italic.woff +0 -0
  38. data/themes/common/fonts/Lato-bold.woff +0 -0
  39. data/themes/common/fonts/Lato.woff +0 -0
  40. data/themes/common/fonts/OpenSans-Bold.woff +0 -0
  41. data/themes/common/fonts/OpenSans-BoldItalic.woff +0 -0
  42. data/themes/common/fonts/OpenSans-Italic.woff +0 -0
  43. data/themes/common/fonts/OpenSans.woff +0 -0
  44. data/themes/common/fonts/PTMono.woff +0 -0
  45. data/themes/common/fonts/PTSans.Bold.Italic.woff +0 -0
  46. data/themes/common/fonts/PTSans.Bold.woff +0 -0
  47. data/themes/common/fonts/PTSans.Italic.woff +0 -0
  48. data/themes/common/fonts/PTSans.Narrow.Bold.woff +0 -0
  49. data/themes/common/fonts/PTSans.Narrow.woff +0 -0
  50. data/themes/common/fonts/PTSans.woff +0 -0
  51. data/themes/common/fonts/TargetBlank.otf +0 -0
  52. data/themes/common/fonts/TargetBlank.svg +14 -0
  53. data/themes/common/fonts/YanoneKaffeesatz-Bold.woff +0 -0
  54. data/themes/common/fonts/YanoneKaffeesatz-Regular.woff +0 -0
  55. data/themes/common/fonts/crimson_text.ttf +0 -0
  56. data/themes/common/fonts/crimson_text_bold.ttf +0 -0
  57. data/themes/common/fonts/crimson_text_semibold.ttf +0 -0
  58. data/themes/common/fonts/league_gothic-webfont.ttf +0 -0
  59. data/themes/html5rocks/README +2 -0
  60. data/themes/html5rocks/css/default.css +501 -0
  61. data/themes/html5rocks/css/moon.css +543 -0
  62. data/themes/html5rocks/css/sand.css +508 -0
  63. data/themes/html5rocks/css/sea_wave.css +492 -0
  64. data/themes/html5rocks/index.erb +64 -0
  65. data/themes/html5rocks/js/slides.js +464 -0
  66. data/themes/io2012/README +2 -0
  67. data/themes/io2012/css/default.css +1481 -0
  68. data/themes/io2012/css/fonts.css +24 -0
  69. data/themes/io2012/css/phone.css +27 -0
  70. data/themes/io2012/images/google_developers_icon_128.png +0 -0
  71. data/themes/io2012/images/io2012_logo.png +0 -0
  72. data/themes/io2012/index.erb +73 -0
  73. data/themes/io2012/js/hammer.js +586 -0
  74. data/themes/io2012/js/modernizr.custom.45394.js +4 -0
  75. data/themes/io2012/js/order.js +8 -0
  76. data/themes/io2012/js/polyfills/classList.min.js +2 -0
  77. data/themes/io2012/js/polyfills/dataset.min.js +2 -0
  78. data/themes/io2012/js/polyfills/history.min.js +1 -0
  79. data/themes/io2012/js/prettify/lang-apollo.js +2 -0
  80. data/themes/io2012/js/prettify/lang-clj.js +18 -0
  81. data/themes/io2012/js/prettify/lang-css.js +2 -0
  82. data/themes/io2012/js/prettify/lang-go.js +1 -0
  83. data/themes/io2012/js/prettify/lang-hs.js +2 -0
  84. data/themes/io2012/js/prettify/lang-lisp.js +3 -0
  85. data/themes/io2012/js/prettify/lang-lua.js +2 -0
  86. data/themes/io2012/js/prettify/lang-ml.js +2 -0
  87. data/themes/io2012/js/prettify/lang-n.js +4 -0
  88. data/themes/io2012/js/prettify/lang-proto.js +1 -0
  89. data/themes/io2012/js/prettify/lang-scala.js +2 -0
  90. data/themes/io2012/js/prettify/lang-sql.js +2 -0
  91. data/themes/io2012/js/prettify/lang-tex.js +1 -0
  92. data/themes/io2012/js/prettify/lang-vb.js +2 -0
  93. data/themes/io2012/js/prettify/lang-vhdl.js +3 -0
  94. data/themes/io2012/js/prettify/lang-wiki.js +2 -0
  95. data/themes/io2012/js/prettify/lang-xq.js +3 -0
  96. data/themes/io2012/js/prettify/lang-yaml.js +2 -0
  97. data/themes/io2012/js/prettify/prettify.css +1 -0
  98. data/themes/io2012/js/prettify/prettify.js +28 -0
  99. data/themes/io2012/js/require-1.0.8.min.js +33 -0
  100. data/themes/io2012/js/slide-controller.js +109 -0
  101. data/themes/io2012/js/slide-deck.js +768 -0
  102. data/themes/io2012/js/slides.js +5 -0
  103. data/themes/memories/README +5 -0
  104. data/themes/memories/css/fonts.css +25 -0
  105. data/themes/memories/css/slideshow.css +286 -0
  106. data/themes/memories/css/theme.css +183 -0
  107. data/themes/memories/index.erb +37 -0
  108. data/themes/memories/js/prefixfree.min.js +13 -0
  109. data/themes/memories/js/slideshow.js +577 -0
  110. data/themes/modern/LICENSE +20 -0
  111. data/themes/modern/README.md +52 -0
  112. data/themes/modern/css/GENERATED_CONTENT +0 -0
  113. data/themes/modern/css/defaults.css +0 -0
  114. data/themes/modern/css/fonts.css +166 -0
  115. data/themes/modern/css/pygments/colorful.css +215 -0
  116. data/themes/modern/css/pygments/github.css +208 -0
  117. data/themes/modern/css/pygments/solarized-dark.css +213 -0
  118. data/themes/modern/css/pygments/solarized-light.css +213 -0
  119. data/themes/modern/css/reset.css +41 -0
  120. data/themes/modern/css/screen.css +1183 -0
  121. data/themes/modern/fonts/Collegiate.woff +0 -0
  122. data/themes/modern/fonts/GoudyBookletter.1911.woff +0 -0
  123. data/themes/modern/fonts/Inconsolata.Bold.woff +0 -0
  124. data/themes/modern/fonts/Inconsolata.woff +0 -0
  125. data/themes/modern/fonts/Junction.woff +0 -0
  126. data/themes/modern/fonts/LiberationMono.Bold.woff +0 -0
  127. data/themes/modern/fonts/LiberationMono.BoldItalic.woff +0 -0
  128. data/themes/modern/fonts/LiberationMono.Italic.woff +0 -0
  129. data/themes/modern/fonts/LiberationMono.Regular.woff +0 -0
  130. data/themes/modern/fonts/OpenSans.Bold.woff +0 -0
  131. data/themes/modern/fonts/OpenSans.BoldItalic.woff +0 -0
  132. data/themes/modern/fonts/OpenSans.ExtraBold.woff +0 -0
  133. data/themes/modern/fonts/OpenSans.ExtraBoldItalic.woff +0 -0
  134. data/themes/modern/fonts/OpenSans.Italic.woff +0 -0
  135. data/themes/modern/fonts/OpenSans.Light.woff +0 -0
  136. data/themes/modern/fonts/OpenSans.LightItalic.woff +0 -0
  137. data/themes/modern/fonts/OpenSans.Regular.woff +0 -0
  138. data/themes/modern/fonts/OpenSans.Semibold.woff +0 -0
  139. data/themes/modern/fonts/OpenSans.SemiboldItalic.woff +0 -0
  140. data/themes/modern/fonts/PTMono.woff +0 -0
  141. data/themes/modern/fonts/PTSans.Bold.Italic.woff +0 -0
  142. data/themes/modern/fonts/PTSans.Bold.woff +0 -0
  143. data/themes/modern/fonts/PTSans.Italic.woff +0 -0
  144. data/themes/modern/fonts/PTSans.Narrow.Bold.woff +0 -0
  145. data/themes/modern/fonts/PTSans.woff +0 -0
  146. data/themes/modern/fonts/Raleway.Thin.woff +0 -0
  147. data/themes/modern/fonts/STIXGeneral.Bold.woff +0 -0
  148. data/themes/modern/fonts/STIXGeneral.BoldItalic.woff +0 -0
  149. data/themes/modern/fonts/STIXGeneral.Italic.woff +0 -0
  150. data/themes/modern/fonts/STIXGeneral.Regular.woff +0 -0
  151. data/themes/modern/fonts/YanoneKaffeesatz.Bold.woff +0 -0
  152. data/themes/modern/fonts/YanoneKaffeesatz.ExtraLight.woff +0 -0
  153. data/themes/modern/fonts/YanoneKaffeesatz.Light.woff +0 -0
  154. data/themes/modern/fonts/YanoneKaffeesatz.Regular.woff +0 -0
  155. data/themes/modern/images/cc/by.svg +29 -0
  156. data/themes/modern/images/cc/cc-white.svg +23 -0
  157. data/themes/modern/images/cc/cc.svg +23 -0
  158. data/themes/modern/images/cc/nc-eu.svg +21 -0
  159. data/themes/modern/images/cc/nc-jp.svg +18 -0
  160. data/themes/modern/images/cc/nc.svg +23 -0
  161. data/themes/modern/images/cc/nd.svg +20 -0
  162. data/themes/modern/images/cc/pd.svg +24 -0
  163. data/themes/modern/images/cc/remix.svg +20 -0
  164. data/themes/modern/images/cc/sa.svg +22 -0
  165. data/themes/modern/images/cc/sampling.plus.svg +33 -0
  166. data/themes/modern/images/cc/sampling.svg +36 -0
  167. data/themes/modern/images/cc/share.svg +22 -0
  168. data/themes/modern/images/cc/zero.svg +24 -0
  169. data/themes/modern/images/flickr.svg +65 -0
  170. data/themes/modern/images/mesh.png +0 -0
  171. data/themes/modern/images/mesh@2x.png +0 -0
  172. data/themes/modern/images/progress-grayDark.svg +55 -0
  173. data/themes/modern/images/progress.svg +3 -0
  174. data/themes/modern/index.erb +76 -0
  175. data/themes/modern/js/highcharts.js +294 -0
  176. data/themes/modern/js/jquery-2.1.0.min.js +4 -0
  177. data/themes/modern/js/script.coffee +480 -0
  178. data/themes/modern/js/script.js +678 -0
  179. data/themes/modern/styles/_box.scss +89 -0
  180. data/themes/modern/styles/_figure.scss +81 -0
  181. data/themes/modern/styles/_full.scss +74 -0
  182. data/themes/modern/styles/_increment.scss +38 -0
  183. data/themes/modern/styles/_list.scss +129 -0
  184. data/themes/modern/styles/_progress.scss +19 -0
  185. data/themes/modern/styles/defaults.scss +46 -0
  186. data/themes/modern/styles/fonts.scss +197 -0
  187. data/themes/modern/styles/pygments/_solarized.scss +82 -0
  188. data/themes/modern/styles/pygments/colorful.scss +67 -0
  189. data/themes/modern/styles/pygments/github.scss +67 -0
  190. data/themes/modern/styles/pygments/solarized-dark.scss +15 -0
  191. data/themes/modern/styles/pygments/solarized-light.scss +15 -0
  192. data/themes/modern/styles/reset.scss +46 -0
  193. data/themes/modern/styles/screen.scss +841 -0
  194. data/themes/reveal/README +2 -0
  195. data/themes/reveal/css/main.css +1029 -0
  196. data/themes/reveal/css/reset.css +57 -0
  197. data/themes/reveal/index.erb +102 -0
  198. data/themes/reveal/js/classList.js +2 -0
  199. data/themes/reveal/js/head.min.js +8 -0
  200. data/themes/reveal/js/reveal.js +951 -0
  201. data/themes/shower/README +2 -0
  202. data/themes/shower/css/fonts.css +50 -0
  203. data/themes/shower/css/reset.css +42 -0
  204. data/themes/shower/css/style.css +418 -0
  205. data/themes/shower/images/grid.png +0 -0
  206. data/themes/shower/images/linen.png +0 -0
  207. data/themes/shower/images/ribbon.svg +4 -0
  208. data/themes/shower/index.erb +35 -0
  209. data/themes/shower/js/script.js +325 -0
  210. data/themes/template/README +5 -0
  211. data/themes/template/css/reset.css +42 -0
  212. data/themes/template/index.erb +35 -0
  213. data/themes/template/js/prefixfree.min.js +13 -0
  214. 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