diff options
author | Eric Bidelman | 2012-04-17 18:59:07 -0700 |
---|---|---|
committer | Eric Bidelman | 2012-04-17 18:59:07 -0700 |
commit | 64c8d6328a9d0e4fe68a5899e3e8710342f3b7dd (patch) | |
tree | cc30183c85cbdadac0607b4c370f94e981708564 | |
parent | 5a15dcab5fd3bf90915f811bc7072f6ef8c34a07 (diff) | |
download | io-slides-remote-64c8d6328a9d0e4fe68a5899e3e8710342f3b7dd.tar.gz |
Basic presenter mode working
-rw-r--r-- | js/slide-controller.js | 54 | ||||
-rw-r--r-- | js/slides.js | 44 | ||||
-rw-r--r-- | slide_config.js | 11 | ||||
-rw-r--r-- | template.html | 23 | ||||
-rw-r--r-- | theme/css/default.css | 416 | ||||
-rw-r--r-- | theme/sass/_base.scss | 9 | ||||
-rw-r--r-- | theme/sass/default.scss | 71 | ||||
-rw-r--r-- | theme/sass/phone.scss | 4 |
8 files changed, 408 insertions, 224 deletions
diff --git a/js/slide-controller.js b/js/slide-controller.js new file mode 100644 index 0000000..e2f8bf2 --- /dev/null +++ b/js/slide-controller.js | |||
@@ -0,0 +1,54 @@ | |||
1 | function SlideController(slideDeck) { | ||
2 | this.deck_ = slideDeck; | ||
3 | this.win_ = null; | ||
4 | |||
5 | window.addEventListener('message', this.onMessage_.bind(this), false); | ||
6 | |||
7 | // Close popups if we reload the main window. | ||
8 | window.addEventListener('beforeunload', function(e) { | ||
9 | this.win_.close() | ||
10 | }.bind(this), false); | ||
11 | |||
12 | // Only open one new popup. The recursion popup opening! | ||
13 | if (!window.opener) { | ||
14 | this.win_ = window.open(location.href, 'mywindow'); | ||
15 | } | ||
16 | } | ||
17 | |||
18 | SlideController.MOVE_LEFT = -1; | ||
19 | SlideController.MOVE_RIGHT = 1; | ||
20 | |||
21 | SlideController.prototype.onMessage_ = function(e) { | ||
22 | var data = e.data; | ||
23 | |||
24 | // It would be dope if FF implemented location.origin. | ||
25 | if (e.origin != location.protocol + '//' + location.host) { | ||
26 | alert('Someone tried to postMessage from an unknown origin'); | ||
27 | return; | ||
28 | } | ||
29 | |||
30 | if (e.source.location.hostname != 'localhost') { | ||
31 | alert('Someone tried to postMessage from an unknown origin'); | ||
32 | return; | ||
33 | } | ||
34 | |||
35 | if ('slideDirection' in data) { | ||
36 | if (data.slideDirection == SlideController.MOVE_LEFT) { | ||
37 | this.deck_.prevSlide(); | ||
38 | } else { | ||
39 | this.deck_.nextSlide(); | ||
40 | } | ||
41 | } | ||
42 | }; | ||
43 | |||
44 | SlideController.prototype.sendMsg = function(msg) { | ||
45 | // // Send message to popup window. | ||
46 | // if (this.win_) { | ||
47 | // this.win_.postMessage(msg, location.protocol + '//' + location.host); | ||
48 | // } | ||
49 | // Send message to main window. | ||
50 | if (window.opener) { | ||
51 | // It would be dope if FF implemented location.origin. | ||
52 | window.opener.postMessage(msg, location.protocol + '//' + location.host); | ||
53 | } | ||
54 | }; | ||
diff --git a/js/slides.js b/js/slides.js index 20bb1bd..0faf06b 100644 --- a/js/slides.js +++ b/js/slides.js | |||
@@ -13,6 +13,7 @@ function SlideDeck() { | |||
13 | this.prevSlide_ = 0; | 13 | this.prevSlide_ = 0; |
14 | this.slides = []; | 14 | this.slides = []; |
15 | this.config_ = null; | 15 | this.config_ = null; |
16 | this.controller_ = null; | ||
16 | 17 | ||
17 | this.getCurrentSlideFromHash_(); | 18 | this.getCurrentSlideFromHash_(); |
18 | 19 | ||
@@ -52,6 +53,9 @@ SlideDeck.prototype.getCurrentSlideFromHash_ = function() { | |||
52 | * @private | 53 | * @private |
53 | */ | 54 | */ |
54 | SlideDeck.prototype.onDomLoaded_ = function(e) { | 55 | SlideDeck.prototype.onDomLoaded_ = function(e) { |
56 | // Fade in deck. | ||
57 | document.body.classList.add('loaded'); | ||
58 | |||
55 | this.slides_ = document.querySelectorAll('slide:not([hidden]):not(.backdrop)'); | 59 | this.slides_ = document.querySelectorAll('slide:not([hidden]):not(.backdrop)'); |
56 | 60 | ||
57 | // If we're on a smartphone device, load phone.css. | 61 | // If we're on a smartphone device, load phone.css. |
@@ -148,11 +152,11 @@ SlideDeck.prototype.onBodyKeyDown_ = function(e) { | |||
148 | document.body.classList.toggle('highlight-code'); | 152 | document.body.classList.toggle('highlight-code'); |
149 | break; | 153 | break; |
150 | 154 | ||
151 | case 78: // N | 155 | case 80: // P |
152 | // If this slide contains notes, toggle them. | 156 | // If this slide contains notes, toggle them. |
153 | if (this.slides_[this.curSlide_].querySelector('.note')) { | 157 | //if (this.slides_[this.curSlide_].querySelector('.note')) { |
154 | document.body.classList.toggle('with-notes'); | 158 | document.body.classList.toggle('with-notes'); |
155 | } | 159 | //} |
156 | break; | 160 | break; |
157 | 161 | ||
158 | case 27: // ESC | 162 | case 27: // ESC |
@@ -283,6 +287,10 @@ SlideDeck.prototype.loadConfig_ = function(config) { | |||
283 | } | 287 | } |
284 | }; | 288 | }; |
285 | } | 289 | } |
290 | |||
291 | if (!!('enableSpeakerNotes' in settings) && settings.enableSpeakerNotes) { | ||
292 | this.controller_ = new SlideController(this); | ||
293 | } | ||
286 | }; | 294 | }; |
287 | 295 | ||
288 | /** | 296 | /** |
@@ -335,10 +343,17 @@ SlideDeck.prototype.buildNextItem_ = function() { | |||
335 | */ | 343 | */ |
336 | SlideDeck.prototype.prevSlide = function(opt_dontPush) { | 344 | SlideDeck.prototype.prevSlide = function(opt_dontPush) { |
337 | if (this.curSlide_ > 0) { | 345 | if (this.curSlide_ > 0) { |
338 | // Toggle off speaker notes and/or highlighted code if they're showing. | 346 | // Toggle off speaker notes and/or highlighted code if they're showing |
339 | var bodyClassList = document.body.classList; | 347 | // when we advanced. If we're the speaker notes popup, leave this put. |
340 | bodyClassList.remove('with-notes'); | 348 | if (this.controller_ && !window.opener) { |
341 | bodyClassList.remove('highlight-code'); | 349 | var bodyClassList = document.body.classList; |
350 | bodyClassList.remove('with-notes'); | ||
351 | bodyClassList.remove('highlight-code'); | ||
352 | } | ||
353 | |||
354 | if (this.controller_) { | ||
355 | this.controller_.sendMsg({slideDirection: SlideController.MOVE_LEFT}); | ||
356 | } | ||
342 | 357 | ||
343 | this.prevSlide_ = this.curSlide_; | 358 | this.prevSlide_ = this.curSlide_; |
344 | this.curSlide_--; | 359 | this.curSlide_--; |
@@ -352,15 +367,22 @@ SlideDeck.prototype.prevSlide = function(opt_dontPush) { | |||
352 | */ | 367 | */ |
353 | SlideDeck.prototype.nextSlide = function(opt_dontPush) { | 368 | SlideDeck.prototype.nextSlide = function(opt_dontPush) { |
354 | 369 | ||
370 | if (this.controller_) { | ||
371 | this.controller_.sendMsg({slideDirection: SlideController.MOVE_RIGHT}); | ||
372 | } | ||
373 | |||
355 | if (this.buildNextItem_()) { | 374 | if (this.buildNextItem_()) { |
356 | return; | 375 | return; |
357 | } | 376 | } |
358 | 377 | ||
359 | if (this.curSlide_ < this.slides_.length - 1) { | 378 | if (this.curSlide_ < this.slides_.length - 1) { |
360 | // Toggle off speaker notes and/or highlighted code if they're showing. | 379 | // Toggle off speaker notes and/or highlighted code if they're showing |
361 | var bodyClassList = document.body.classList; | 380 | // when we advanced. If we're the speaker notes popup, leave this put. |
362 | bodyClassList.remove('with-notes'); | 381 | if (this.controller_ && !window.opener) { |
363 | bodyClassList.remove('highlight-code'); | 382 | var bodyClassList = document.body.classList; |
383 | bodyClassList.remove('with-notes'); | ||
384 | bodyClassList.remove('highlight-code'); | ||
385 | } | ||
364 | 386 | ||
365 | this.prevSlide_ = this.curSlide_; | 387 | this.prevSlide_ = this.curSlide_; |
366 | this.curSlide_++; | 388 | this.curSlide_++; |
diff --git a/slide_config.js b/slide_config.js index e8ff552..eab9ff8 100644 --- a/slide_config.js +++ b/slide_config.js | |||
@@ -4,11 +4,12 @@ var SLIDE_CONFIG = { | |||
4 | title: 'Title Goes Here<br>Up To Two Lines', | 4 | title: 'Title Goes Here<br>Up To Two Lines', |
5 | subtitle: 'Subtitle Goes Here', | 5 | subtitle: 'Subtitle Goes Here', |
6 | //theme: ['mytheme'], | 6 | //theme: ['mytheme'], |
7 | hashtag: '#html5', //TODO | 7 | //hashtag: '#html5', //TODO |
8 | useBuilds: true, | 8 | useBuilds: true, // Default: true |
9 | usePrettify: true, | 9 | usePrettify: true, // Default: true |
10 | enableSideAreas: true, | 10 | enableSideAreas: true, // Default: true |
11 | enableTouch: true, // TODO: base this on media query instead. | 11 | enableTouch: true, // Default: true if device supports touch. |
12 | //enableSpeakerNotes: true, // Default: false | ||
12 | analytics: 'UA-XXXXXXXX-1', | 13 | analytics: 'UA-XXXXXXXX-1', |
13 | favIcon: 'http://bleedinghtml5.appspot.com/images/chrome-logo-tiny2.png', | 14 | favIcon: 'http://bleedinghtml5.appspot.com/images/chrome-logo-tiny2.png', |
14 | onLoad: null, // TODO. function to call onload | 15 | onLoad: null, // TODO. function to call onload |
diff --git a/template.html b/template.html index 6bfb029..24dd7b8 100644 --- a/template.html +++ b/template.html | |||
@@ -13,11 +13,13 @@ URL: https://code.google.com/p/io-2012-slides | |||
13 | <meta charset="utf-8"> | 13 | <meta charset="utf-8"> |
14 | <meta http-equiv="X-UA-Compatible" content="chrome=1"> | 14 | <meta http-equiv="X-UA-Compatible" content="chrome=1"> |
15 | <!--<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">--> | 15 | <!--<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">--> |
16 | <!--<meta name="viewport" content="width=device-width, initial-scale=1.0">--> | ||
17 | <!--This one seems to work all the time, but really small on ipad--> | ||
16 | <!--<meta name="viewport" content="initial-scale=0.4">--> | 18 | <!--<meta name="viewport" content="initial-scale=0.4">--> |
17 | <link rel="stylesheet" media="all" href="theme/css/default.css"> | 19 | <link rel="stylesheet" media="all" href="theme/css/default.css"> |
18 | <link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="theme/css/phone.css"> | 20 | <link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="theme/css/phone.css"> |
19 | </head> | 21 | </head> |
20 | <body style="opacity: 0;"> | 22 | <body> |
21 | 23 | ||
22 | <slides class="layout-widescreen"> | 24 | <slides class="layout-widescreen"> |
23 | 25 | ||
@@ -64,7 +66,7 @@ URL: https://code.google.com/p/io-2012-slides | |||
64 | <p>A list where items build:</p> | 66 | <p>A list where items build:</p> |
65 | <ul class="build"> | 67 | <ul class="build"> |
66 | <li>Pressing 'h' will highlight code snippets</li> | 68 | <li>Pressing 'h' will highlight code snippets</li> |
67 | <li>Pressing 'n' will toggle extra notes</li> | 69 | <li>Pressing 'p' will toggle presenter mode</li> |
68 | <li>Pressing 'f' will toggle fullscreen viewing</li> | 70 | <li>Pressing 'f' will toggle fullscreen viewing</li> |
69 | </ul> | 71 | </ul> |
70 | <p>Another list, but items fade as they build:</p> | 72 | <p>Another list, but items fade as they build:</p> |
@@ -155,13 +157,23 @@ function helloWorld(world) { | |||
155 | 157 | ||
156 | <slide> | 158 | <slide> |
157 | <aside class="note"> | 159 | <aside class="note"> |
158 | <section>Speaker notes go here!</section> | 160 | <section> |
161 | <ul> | ||
162 | <li>Point I wanted to make #1</li> | ||
163 | <li>Point I wanted to make #2</li> | ||
164 | <li>Point I wanted to make #3</li> | ||
165 | <li>Point I wanted to make #3</li> | ||
166 | <li>Point I wanted to make #3</li> | ||
167 | < |