From 6ca44eaadf9787260a87be1baabcd9bc9a306afd Mon Sep 17 00:00:00 2001 From: Eric Bidelman Date: Wed, 18 Apr 2012 01:01:02 -0700 Subject: More presenter mode. Working now --- js/slide-controller.js | 41 ++++++++++++-------- js/slides.js | 100 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 101 insertions(+), 40 deletions(-) (limited to 'js') 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 @@ +(function(window) { + +var ORIGIN = location.protocol + '//' + location.host; + function SlideController(slideDeck) { this.deck_ = slideDeck; this.win_ = null; @@ -21,34 +25,41 @@ SlideController.MOVE_RIGHT = 1; SlideController.prototype.onMessage_ = function(e) { var data = e.data; - // It would be dope if FF implemented location.origin. - if (e.origin != location.protocol + '//' + location.host) { + // Restrict messages to being from this origin. Allow local developmet + // from file:// though. + // TODO: It would be dope if FF implemented location.origin! + if (e.origin != ORIGIN && ORIGIN != 'file://') { alert('Someone tried to postMessage from an unknown origin'); return; } - if (e.source.location.hostname != 'localhost') { - alert('Someone tried to postMessage from an unknown origin'); - return; - } + // if (e.source.location.hostname != 'localhost') { + // alert('Someone tried to postMessage from an unknown origin'); + // return; + // } - if ('slideDirection' in data) { - if (data.slideDirection == SlideController.MOVE_LEFT) { - this.deck_.prevSlide(); - } else { - this.deck_.nextSlide(); - } + if ('keyCode' in data) { + var evt = document.createEvent('Event'); + evt.initEvent('keydown', true, true); + evt.keyCode = data.keyCode; + document.dispatchEvent(evt); } }; SlideController.prototype.sendMsg = function(msg) { // // Send message to popup window. // if (this.win_) { - // this.win_.postMessage(msg, location.protocol + '//' + location.host); + // this.win_.postMessage(msg, ORIGIN); // } + // Send message to main window. if (window.opener) { - // It would be dope if FF implemented location.origin. - window.opener.postMessage(msg, location.protocol + '//' + location.host); + // TODO: It would be dope if FF implemented location.origin. + window.opener.postMessage(msg, '*'); } }; + +window.SlideController = SlideController; + +})(window); + 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() { this.slides = []; this.config_ = null; this.controller_ = null; + this.IS_POPUP_ = window.opener; this.getCurrentSlideFromHash_(); @@ -49,6 +50,39 @@ SlideDeck.prototype.getCurrentSlideFromHash_ = function() { } }; +SlideDeck.prototype.loadPresenterMode = function() { + var params = location.search.substring(1).split('&').map(function(el) { + return el.split('='); + }); + + var presentMe = null; + for (var i = 0, param; param = params[i]; ++i) { + if (param[0].toLowerCase() == 'presentme') { + presentMe = param[1] == 'true'; + break; + } + } + + if (presentMe !== null) { + localStorage.ENABLE_PRESENTOR_MODE = presentMe; + location.href = location.pathname; + } + + // Turn on presenter mode? + if (localStorage.getItem('ENABLE_PRESENTOR_MODE') && + JSON.parse(localStorage.getItem('ENABLE_PRESENTOR_MODE'))) { + this.controller_ = new SlideController(this); + + // Loading in the popup? Trigger the hotkey for turning presenter mode on. + if (this.IS_POPUP_) { + var evt = document.createEvent('Event'); + evt.initEvent('keydown', true, true); + evt.keyCode = 'P'.charCodeAt(0); + document.dispatchEvent(evt); + } + } +} + /** * @private */ @@ -70,7 +104,6 @@ SlideDeck.prototype.onDomLoaded_ = function(e) { document.querySelector('slides').classList.remove('layout-widescreen'); } - // Load config. this.loadConfig_(SLIDE_CONFIG); this.addEventListeners_(); this.updateSlides_(); @@ -85,6 +118,10 @@ SlideDeck.prototype.onDomLoaded_ = function(e) { [].forEach.call(document.querySelectorAll('a'), function(a) { a.target = '_blank'; }); + + // Note: this needs to come after addEventListeners_(), which adds a + // 'keydown' listener that this method relies on. + this.loadPresenterMode(); }; /** @@ -115,6 +152,11 @@ SlideDeck.prototype.onBodyKeyDown_ = function(e) { return; } + // Forward keydown to the main slides if we're the popup. + if (this.controller_ && this.IS_POPUP_) { + this.controller_.sendMsg({keyCode: e.keyCode}); + } + switch (e.keyCode) { case 39: // right arrow case 32: // space @@ -153,14 +195,20 @@ SlideDeck.prototype.onBodyKeyDown_ = function(e) { break; case 80: // P - // If this slide contains notes, toggle them. - //if (this.slides_[this.curSlide_].querySelector('.note')) { + if (this.controller_ && this.IS_POPUP_) { document.body.classList.toggle('with-notes'); - //} + } else if (!this.controller_) { + document.body.classList.toggle('with-notes'); + } + break; + + case 82: // R + // TODO: implement refresh on main slides when popup is refreshed. break; case 27: // ESC document.body.classList.remove('with-notes'); + document.body.classList.remove('highlight-code'); break; case 70: // F @@ -287,10 +335,6 @@ SlideDeck.prototype.loadConfig_ = function(config) { } }; } - - if (!!('enableSpeakerNotes' in settings) && settings.enableSpeakerNotes) { - this.controller_ = new SlideController(this); - } }; /** @@ -343,17 +387,20 @@ SlideDeck.prototype.buildNextItem_ = function() { */ SlideDeck.prototype.prevSlide = function(opt_dontPush) { if (this.curSlide_ > 0) { - // Toggle off speaker notes and/or highlighted code if they're showing - // when we advanced. If we're the speaker notes popup, leave this put. - if (this.controller_ && !window.opener) { - var bodyClassList = document.body.classList; + var bodyClassList = document.body.classList; + bodyClassList.remove('highlight-code'); + + // Toggle off speaker notes if they're showing when we move backwards on the + // main slides. If we're the speaker notes popup, leave them up. + if (this.controller_ && !this.IS_POPUP_) { + bodyClassList.remove('with-notes'); + } else if (!this.controller_) { bodyClassList.remove('with-notes'); - bodyClassList.remove('highlight-code'); } - if (this.controller_) { - this.controller_.sendMsg({slideDirection: SlideController.MOVE_LEFT}); - } + // if (this.controller_) { + // this.controller_.sendMsg({slideDirection: SlideController.MOVE_LEFT}); + // } this.prevSlide_ = this.curSlide_; this.curSlide_--; @@ -366,22 +413,25 @@ SlideDeck.prototype.prevSlide = function(opt_dontPush) { * @param {boolean=} opt_dontPush */ SlideDeck.prototype.nextSlide = function(opt_dontPush) { - - if (this.controller_) { - this.controller_.sendMsg({slideDirection: SlideController.MOVE_RIGHT}); - } + // + // if (this.controller_) { + // this.controller_.sendMsg({slideDirection: SlideController.MOVE_RIGHT}); + // } if (this.buildNextItem_()) { return; } if (this.curSlide_ < this.slides_.length - 1) { - // Toggle off speaker notes and/or highlighted code if they're showing - // when we advanced. If we're the speaker notes popup, leave this put. - if (this.controller_ && !window.opener) { - var bodyClassList = document.body.classList; + var bodyClassList = document.body.classList; + bodyClassList.remove('highlight-code'); + + // Toggle off speaker notes if they're showing when we advanced on the main + // slides. If we're the speaker notes popup, leave them up. + if (this.controller_ && !this.IS_POPUP_) { + bodyClassList.remove('with-notes'); + } else if (!this.controller_) { bodyClassList.remove('with-notes'); - bodyClassList.remove('highlight-code'); } this.prevSlide_ = this.curSlide_; -- cgit v1.2.3