From a8e534158525f69db7276cded5f79e6fb6819754 Mon Sep 17 00:00:00 2001
From: Eric Bidelman
Date: Wed, 18 Apr 2012 14:45:38 -0700
Subject: Using history.replaceState. Presenter mode code cleanup

---
 js/slide-controller.js | 79 ++++++++++++++++++++++++++++++++++++++------------
 js/slides.js           | 69 ++++++++++++-------------------------------
 2 files changed, 79 insertions(+), 69 deletions(-)

(limited to 'js')

diff --git a/js/slide-controller.js b/js/slide-controller.js
index bdbb670..594ee47 100644
--- a/js/slide-controller.js
+++ b/js/slide-controller.js
@@ -1,26 +1,67 @@
 (function(window) {
 
-var ORIGIN = location.protocol + '//' + location.host;
+var ORIGIN_ = location.protocol + '//' + location.host;
 
-function SlideController(slideDeck) {
-  this.deck_ = slideDeck;
-  this.win_ = null;
+function SlideController() {
+  this.popup = null;
+  this.isPopup = window.opener;
 
-  window.addEventListener('message', this.onMessage_.bind(this), false);
+  if (this.setupDone()) {
+    window.addEventListener('message', this.onMessage_.bind(this), false);
 
-  // Close popups if we reload the main window.
-  window.addEventListener('beforeunload', function(e) {
-    this.win_.close()
-  }.bind(this), false);
-
-  // Only open one new popup. The recursion popup opening!
-  if (!window.opener) {
-    this.win_ = window.open(location.href, 'mywindow');
+    // Close popups if we reload the main window.
+    window.addEventListener('beforeunload', function(e) {
+      if (this.popup) {
+        this.popup.close();
+      }
+    }.bind(this), false);
   }
 }
 
-SlideController.MOVE_LEFT = -1;
-SlideController.MOVE_RIGHT = 1;
+SlideController.PRESENTER_MODE_PARAM = 'presentme';
+
+SlideController.prototype.setupDone = 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() == SlideController.PRESENTER_MODE_PARAM) {
+      presentMe = param[1] == 'true';
+      break;
+    }
+  }
+
+  if (presentMe !== null) {
+    localStorage.ENABLE_PRESENTOR_MODE = presentMe;
+    // TODO: use window.history.pushState to update URL instead of the redirect.
+    if (window.history.replaceState) {
+      window.history.replaceState({}, '', location.pathname);
+    } else {
+      location.replace(location.pathname);
+      return false;
+    }
+  }
+
+  var enablePresenterMode = localStorage.getItem('ENABLE_PRESENTOR_MODE');
+  if (enablePresenterMode && JSON.parse(enablePresenterMode)) {
+    // Only open popup from main deck. Don't want recursive popup opening!
+    if (!this.isPopup) {
+      this.popup = window.open(location.href, 'mywindow');
+
+      // Loading in the popup? Trigger the hotkey for turning presenter mode on.
+      this.popup.addEventListener('load', function(e) {
+        var evt = this.popup.document.createEvent('Event');
+        evt.initEvent('keydown', true, true);
+        evt.keyCode = 'P'.charCodeAt(0);
+        this.popup.document.dispatchEvent(evt);
+      }.bind(this), false);
+    }
+  }
+
+  return true;
+}
 
 SlideController.prototype.onMessage_ = function(e) {
   var data = e.data;
@@ -28,7 +69,7 @@ SlideController.prototype.onMessage_ = function(e) {
   // 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://') {
+  if (e.origin != ORIGIN_ && ORIGIN_ != 'file://') {
     alert('Someone tried to postMessage from an unknown origin');
     return;
   }
@@ -48,12 +89,12 @@ SlideController.prototype.onMessage_ = function(e) {
 
 SlideController.prototype.sendMsg = function(msg) {
   // // Send message to popup window.
-  // if (this.win_) {
-  //   this.win_.postMessage(msg, ORIGIN);
+  // if (this.popup) {
+  //   this.popup.postMessage(msg, ORIGIN_);
   // }
 
   // Send message to main window.
-  if (window.opener) {
+  if (this.isPopup) {
     // TODO: It would be dope if FF implemented location.origin.
     window.opener.postMessage(msg, '*');
   }
diff --git a/js/slides.js b/js/slides.js
index 7afe0cf..cd9e646 100644
--- a/js/slides.js
+++ b/js/slides.js
@@ -13,8 +13,7 @@ function SlideDeck() {
   this.prevSlide_ = 0;
   this.slides = [];
   this.config_ = null;
-  this.controller_ = null;
-  this.IS_POPUP_ = window.opener;
+  this.controller = null;
 
   this.getCurrentSlideFromHash_();
 
@@ -50,39 +49,6 @@ 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
  */
@@ -120,8 +86,11 @@ SlideDeck.prototype.onDomLoaded_ = function(e) {
   });
 
   // Note: this needs to come after addEventListeners_(), which adds a
-  // 'keydown' listener that this method relies on.
-  this.loadPresenterMode();
+  // 'keydown' listener that this controller relies on.
+  // Also, no need to set this up if we're on mobile.
+  if (!Modernizr.touch) {
+    this.controller = new SlideController(this);
+  }
 };
 
 /**
@@ -152,9 +121,9 @@ 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});
+  // Forward keydowns to the main slides if we're the popup.
+  if (this.controller && this.controller.isPopup) {
+    this.controller.sendMsg({keyCode: e.keyCode});
   }
 
   switch (e.keyCode) {
@@ -195,9 +164,9 @@ SlideDeck.prototype.onBodyKeyDown_ = function(e) {
       break;
 
     case 80: // P
-      if (this.controller_ && this.IS_POPUP_) {
+      if (this.controller && this.controller.isPopup) {
         document.body.classList.toggle('with-notes');
-      } else if (!this.controller_) {
+      } else if (this.controller && !this.controller.popup) {
         document.body.classList.toggle('with-notes');
       }
       break;
@@ -392,14 +361,14 @@ SlideDeck.prototype.prevSlide = function(opt_dontPush) {
 
     // 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_) {
+    if (this.controller && !this.controller.isPopup) {
       bodyClassList.remove('with-notes');
-    } else if (!this.controller_) {
+    } else if (!this.controller) {
       bodyClassList.remove('with-notes');
     }
 
-    // if (this.controller_) {
-    //   this.controller_.sendMsg({slideDirection: SlideController.MOVE_LEFT});
+    // if (this.controller) {
+    //   this.controller.sendMsg({slideDirection: SlideController.MOVE_LEFT});
     // }
 
     this.prevSlide_ = this.curSlide_;
@@ -414,8 +383,8 @@ SlideDeck.prototype.prevSlide = function(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_()) {
@@ -428,9 +397,9 @@ SlideDeck.prototype.nextSlide = function(opt_dontPush) {
 
     // 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_) {
+    if (this.controller && !this.controller.isPopup) {
       bodyClassList.remove('with-notes');
-    } else if (!this.controller_) {
+    } else if (!this.controller) {
       bodyClassList.remove('with-notes');
     }
 
-- 
cgit v1.2.3