aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--js/slide-controller.js41
-rw-r--r--js/slides.js100
-rw-r--r--slide_config.js8
-rw-r--r--template.html6
4 files changed, 112 insertions, 43 deletions
diff --git a/js/slide-controller.js b/js/slide-controller.js
index e2f8bf2..bdbb670 100644
--- a/js/slide-controller.js
+++ b/js/slide-controller.js
@@ -1,3 +1,7 @@
1(function(window) {
2
3var ORIGIN = location.protocol + '//' + location.host;
4
1function SlideController(slideDeck) { 5function SlideController(slideDeck) {
2 this.deck_ = slideDeck; 6 this.deck_ = slideDeck;
3 this.win_ = null; 7 this.win_ = null;
@@ -21,34 +25,41 @@ SlideController.MOVE_RIGHT = 1;
21SlideController.prototype.onMessage_ = function(e) { 25SlideController.prototype.onMessage_ = function(e) {
22 var data = e.data; 26 var data = e.data;
23 27
24 // It would be dope if FF implemented location.origin. 28 // Restrict messages to being from this origin. Allow local developmet
25 if (e.origin != location.protocol + '//' + location.host) { 29 // from file:// though.
30 // TODO: It would be dope if FF implemented location.origin!
31 if (e.origin != ORIGIN && ORIGIN != 'file://') {
26 alert('Someone tried to postMessage from an unknown origin'); 32 alert('Someone tried to postMessage from an unknown origin');
27 return; 33 return;
28 } 34 }
29 35
30 if (e.source.location.hostname != 'localhost') { 36 // if (e.source.location.hostname != 'localhost') {
31 alert('Someone tried to postMessage from an unknown origin'); 37 // alert('Someone tried to postMessage from an unknown origin');
32 return; 38 // return;
33 } 39 // }
34 40
35 if ('slideDirection' in data) { 41 if ('keyCode' in data) {
36 if (data.slideDirection == SlideController.MOVE_LEFT) { 42 var evt = document.createEvent('Event');
37 this.deck_.prevSlide(); 43 evt.initEvent('keydown', true, true);
38 } else { 44 evt.keyCode = data.keyCode;
39 this.deck_.nextSlide(); 45 document.dispatchEvent(evt);
40 }
41 } 46 }
42}; 47};
43 48
44SlideController.prototype.sendMsg = function(msg) { 49SlideController.prototype.sendMsg = function(msg) {
45 // // Send message to popup window. 50 // // Send message to popup window.
46 // if (this.win_) { 51 // if (this.win_) {
47 // this.win_.postMessage(msg, location.protocol + '//' + location.host); 52 // this.win_.postMessage(msg, ORIGIN);
48 // } 53 // }
54
49 // Send message to main window. 55 // Send message to main window.
50 if (window.opener) { 56 if (window.opener) {
51 // It would be dope if FF implemented location.origin. 57 // TODO: It would be dope if FF implemented location.origin.
52 window.opener.postMessage(msg, location.protocol + '//' + location.host); 58 window.opener.postMessage(msg, '*');
53 } 59 }
54}; 60};
61
62window.SlideController = SlideController;
63
64})(window);
65
diff --git a/js/slides.js b/js/slides.js
index 0faf06b..7afe0cf 100644
--- a/js/slides.js
+++ b/js/slides.js
@@ -14,6 +14,7 @@ function SlideDeck() {
14 this.slides = []; 14 this.slides = [];
15 this.config_ = null; 15 this.config_ = null;
16 this.controller_ = null; 16 this.controller_ = null;
17 this.IS_POPUP_ = window.opener;
17 18
18 this.getCurrentSlideFromHash_(); 19 this.getCurrentSlideFromHash_();
19 20
@@ -49,6 +50,39 @@ SlideDeck.prototype.getCurrentSlideFromHash_ = function() {
49 } 50 }
50}; 51};
51 52
53SlideDeck.prototype.loadPresenterMode = function() {
54 var params = location.search.substring(1).split('&').map(function(el) {
55 return el.split('=');
56 });
57
58 var presentMe = null;
59 for (var i = 0, param; param = params[i]; ++i) {
60 if (param[0].toLowerCase() == 'presentme') {
61 presentMe = param[1] == 'true';
62 break;
63 }
64 }
65
66 if (presentMe !== null) {
67 localStorage.ENABLE_PRESENTOR_MODE = presentMe;
68 location.href = location.pathname;
69 }
70
71 // Turn on presenter mode?
72 if (localStorage.getItem('ENABLE_PRESENTOR_MODE') &&
73 JSON.parse(localStorage.getItem('ENABLE_PRESENTOR_MODE'))) {
74 this.controller_ = new SlideController(this);
75
76 // Loading in the popup? Trigger the hotkey for turning presenter mode on.
77 if (this.IS_POPUP_) {
78 var evt = document.createEvent('Event');
79 evt.initEvent('keydown', true, true);
80 evt.keyCode = 'P'.charCodeAt(0);
81 document.dispatchEvent(evt);
82 }
83 }
84}
85
52/** 86/**
53 * @private 87 * @private
54 */ 88 */
@@ -70,7 +104,6 @@ SlideDeck.prototype.onDomLoaded_ = function(e) {
70 document.querySelector('slides').classList.remove('layout-widescreen'); 104 document.querySelector('slides').classList.remove('layout-widescreen');
71 } 105 }
72 106
73 // Load config.
74 this.loadConfig_(SLIDE_CONFIG); 107 this.loadConfig_(SLIDE_CONFIG);
75 this.addEventListeners_(); 108 this.addEventListeners_();
76 this.updateSlides_(); 109 this.updateSlides_();
@@ -85,6 +118,10 @@ SlideDeck.prototype.onDomLoaded_ = function(e) {
85 [].forEach.call(document.querySelectorAll('a'), function(a) { 118 [].forEach.call(document.querySelectorAll('a'), function(a) {
86 a.target = '_blank'; 119 a.target = '_blank';
87 }); 120 });
121
122 // Note: this needs to come after addEventListeners_(), which adds a
123 // 'keydown' listener that this method relies on.
124 this.loadPresenterMode();
88}; 125};
89 126
90/** 127/**
@@ -115,6 +152,11 @@ SlideDeck.prototype.onBodyKeyDown_ = function(e) {
115 return; 152 return;
116 } 153 }
117 154
155 // Forward keydown to the main slides if we're the popup.
156 if (this.controller_ && this.IS_POPUP_) {
157 this.controller_.sendMsg({keyCode: e.keyCode});
158 }
159
118 switch (e.keyCode) { 160 switch (e.keyCode) {
119 case 39: // right arrow 161 case 39: // right arrow
120 case 32: // space 162 case 32: // space
@@ -153,14 +195,20 @@ SlideDeck.prototype.onBodyKeyDown_ = function(e) {
153 break; 195 break;
154 196
155 case 80: // P 197 case 80: // P
156 // If this slide contains notes, toggle them. 198 if (this.controller_ && this.IS_POPUP_) {
157 //if (this.slides_[this.curSlide_].querySelector('.note')) {
158 document.body.classList.toggle('with-notes'); 199 document.body.classList.toggle('with-notes');
159 //} 200 } else if (!this.controller_) {
201 document.body.classList.toggle('with-notes');
202 }
203 break;
204
205 case 82: // R
206 // TODO: implement refresh on main slides when popup is refreshed.
160 break; 207 break;
161 208
162 case 27: // ESC 209 case 27: // ESC
163 document.body.classList.remove('with-notes'); 210 document.body.classList.remove('with-notes');
211 document.body.classList.remove('highlight-code');
164 break; 212 break;
165 213
166 case 70: // F 214 case 70: // F
@@ -287,10 +335,6 @@ SlideDeck.prototype.loadConfig_ = function(config) {
287 } 335 }
288 }; 336 };
289 } 337 }
290
291 if (!!('enableSpeakerNotes' in settings) && settings.enableSpeakerNotes) {
292 this.controller_ = new SlideController(this);
293 }
294}; 338};
295 339
296/** 340/**
@@ -343,17 +387,20 @@ SlideDeck.prototype.buildNextItem_ = function() {
343 */ 387 */
344SlideDeck.prototype.prevSlide = function(opt_dontPush) { 388SlideDeck.prototype.prevSlide = function(opt_dontPush) {
345 if (this.curSlide_ > 0) { 389 if (this.curSlide_ > 0) {
346 // Toggle off speaker notes and/or highlighted code if they're showing 390 var bodyClassList = document.body.classList;
347 // when we advanced. If we're the speaker notes popup, leave this put. 391 bodyClassList.remove('highlight-code');
348 if (this.controller_ && !window.opener) { 392
349 var bodyClassList = document.body.classList; 393 // Toggle off speaker notes if they're showing when we move backwards on the
394 // main slides. If we're the speaker notes popup, leave them up.
395 if (this.controller_ && !this.IS_POPUP_) {
396 bodyClassList.remove('with-notes');
397 } else if (!this.controller_) {
350 bodyClassList.remove('with-notes'); 398 bodyClassList.remove('with-notes');
351 bodyClassList.remove('highlight-code');
352 } 399 }
353 400
354 if (this.controller_) { 401 // if (this.controller_) {
355 this.controller_.sendMsg({slideDirection: SlideController.MOVE_LEFT}); 402 // this.controller_.sendMsg({slideDirection: SlideController.MOVE_LEFT});
356 } 403 // }
357 404
358 this.prevSlide_ = this.curSlide_; 405 this.prevSlide_ = this.curSlide_;
359 this.curSlide_--; 406 this.curSlide_--;
@@ -366,22 +413,25 @@ SlideDeck.prototype.prevSlide = function(opt_dontPush) {
366 * @param {boolean=} opt_dontPush 413 * @param {boolean=} opt_dontPush
367 */ 414 */
368SlideDeck.prototype.nextSlide = function(opt_dontPush) { 415SlideDeck.prototype.nextSlide = function(opt_dontPush) {
369 416 //
370 if (this.controller_) { 417 // if (this.controller_) {
371 this.controller_.sendMsg({slideDirection: SlideController.MOVE_RIGHT}); 418 // this.controller_.sendMsg({slideDirection: SlideController.MOVE_RIGHT});
372 } 419 // }
373