aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Bidelman2012-04-17 18:59:07 -0700
committerEric Bidelman2012-04-17 18:59:07 -0700
commit64c8d6328a9d0e4fe68a5899e3e8710342f3b7dd (patch)
treecc30183c85cbdadac0607b4c370f94e981708564
parent5a15dcab5fd3bf90915f811bc7072f6ef8c34a07 (diff)
downloadio-slides-remote-64c8d6328a9d0e4fe68a5899e3e8710342f3b7dd.tar.gz
Basic presenter mode working
-rw-r--r--js/slide-controller.js54
-rw-r--r--js/slides.js44
-rw-r--r--slide_config.js11
-rw-r--r--template.html23
-rw-r--r--theme/css/default.css416
-rw-r--r--theme/sass/_base.scss9
-rw-r--r--theme/sass/default.scss71
-rw-r--r--theme/sass/phone.scss4
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 @@
1function 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
18SlideController.MOVE_LEFT = -1;
19SlideController.MOVE_RIGHT = 1;
20
21SlideController.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
44SlideController.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 */
54SlideDeck.prototype.onDomLoaded_ = function(e) { 55SlideDeck.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 */
336SlideDeck.prototype.prevSlide = function(opt_dontPush) { 344SlideDeck.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 */
353SlideDeck.prototype.nextSlide = function(opt_dontPush) { 368SlideDeck.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 <