Bug 1161802 part 6 - Extract FullscreenRoots::{Add,Remove} to call site of ShowWindowFullscreen. r=smaug
authorXidorn Quan <quanxunzhen@gmail.com>
Wed, 10 Jun 2015 23:13:12 +1200
changeset 248042 3c9900eeadaff920a3ef8c0122a20e5edd5beb4f
parent 248041 b0fc1997f1f385f46c3959abac1e636c1592fb8b
child 248043 10d47ad00e7a97160d74c5682605c7c82de606d0
push id28888
push userkwierso@gmail.com
push dateThu, 11 Jun 2015 01:29:45 +0000
treeherdermozilla-central@04c057942da4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1161802
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1161802 part 6 - Extract FullscreenRoots::{Add,Remove} to call site of ShowWindowFullscreen. r=smaug
dom/base/nsDocument.cpp
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -10880,29 +10880,29 @@ nsIDocument::ChildElementCount()
 namespace mozilla {
 
 // Singleton class to manage the list of fullscreen documents which are the
 // root of a branch which contains fullscreen documents. We maintain this list
 // so that we can easily exit all windows from fullscreen when the user
 // presses the escape key.
 class FullscreenRoots {
 public:
-  // Adds a root to the manager. Adding a root multiple times does not result
-  // in duplicate entries for that item, only one.
-  static void Add(nsIDocument* aRoot);
+  // Adds the root of given document to the manager. Calling this method
+  // with a document whose root is already contained has no effect.
+  static void Add(nsIDocument* aDoc);
 
   // Iterates over every root in the root list, and calls aFunction, passing
   // each root once to aFunction. It is safe to call Add() and Remove() while
   // iterating over the list (i.e. in aFunction). Documents that are removed
   // from the manager during traversal are not traversed, and documents that
   // are added to the manager during traversal are also not traversed.
   static void ForEach(void(*aFunction)(nsIDocument* aDoc));
 
-  // Removes a specific root from the manager.
-  static void Remove(nsIDocument* aRoot);
+  // Removes the root of a specific document from the manager.
+  static void Remove(nsIDocument* aDoc);
 
   // Returns true if all roots added to the list have been removed.
   static bool IsEmpty();
 
 private:
 
   FullscreenRoots() {
     MOZ_COUNT_CTOR(FullscreenRoots);
@@ -10955,23 +10955,24 @@ FullscreenRoots::ForEach(void(*aFunction
 bool
 FullscreenRoots::Contains(nsIDocument* aRoot)
 {
   return FullscreenRoots::Find(aRoot) != NotFound;
 }
 
 /* static */
 void
-FullscreenRoots::Add(nsIDocument* aRoot)
-{
-  if (!FullscreenRoots::Contains(aRoot)) {
+FullscreenRoots::Add(nsIDocument* aDoc)
+{
+  nsCOMPtr<nsIDocument> root = nsContentUtils::GetRootDocument(aDoc);
+  if (!FullscreenRoots::Contains(root)) {
     if (!sInstance) {
       sInstance = new FullscreenRoots();
     }
-    sInstance->mRoots.AppendElement(do_GetWeakReference(aRoot));
+    sInstance->mRoots.AppendElement(do_GetWeakReference(root));
   }
 }
 
 /* static */
 uint32_t
 FullscreenRoots::Find(nsIDocument* aRoot)
 {
   if (!sInstance) {
@@ -10984,19 +10985,20 @@ FullscreenRoots::Find(nsIDocument* aRoot
       return i;
     }
   }
   return NotFound;
 }
 
 /* static */
 void
-FullscreenRoots::Remove(nsIDocument* aRoot)
-{
-  uint32_t index = Find(aRoot);
+FullscreenRoots::Remove(nsIDocument* aDoc)
+{
+  nsCOMPtr<nsIDocument> root = nsContentUtils::GetRootDocument(aDoc);
+  uint32_t index = Find(root);
   NS_ASSERTION(index != NotFound,
     "Should only try to remove roots which are still added!");
   if (index == NotFound || !sInstance) {
     return;
   }
   sInstance->mRoots.RemoveElementAt(index);
   if (sInstance->mRoots.IsEmpty()) {
     delete sInstance;
@@ -11062,23 +11064,16 @@ private:
   nsCOMPtr<nsIDocument> mDoc;
   bool mValue;
   nsRefPtr<gfx::VRHMDInfo> mHMD;
 };
 
 static void
 SetWindowFullScreen(nsIDocument* aDoc, bool aValue, gfx::VRHMDInfo *aVRHMD = nullptr)
 {
-  // Maintain list of fullscreen root documents.
-  nsCOMPtr<nsIDocument> root = nsContentUtils::GetRootDocument(aDoc);
-  if (aValue) {
-    FullscreenRoots::Add(root);
-  } else {
-    FullscreenRoots::Remove(root);
-  }
   nsContentUtils::AddScriptRunner(new nsSetWindowFullScreen(aDoc, aValue, aVRHMD));
 }
 
 class nsCallExitFullscreen : public nsRunnable {
 public:
   explicit nsCallExitFullscreen(nsIDocument* aDoc)
     : mDoc(aDoc) {}
   NS_IMETHOD Run()
@@ -11184,16 +11179,17 @@ ExitFullscreenInDocTree(nsIDocument* aMa
   // the list since we want this event to follow the same path
   // MozDOMFullscreen:Entered dispatched.
   nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
     new AsyncEventDispatcher(changed.LastElement(),
                              NS_LITERAL_STRING("MozDOMFullscreen:Exited"),
                              true, true);
   asyncDispatcher->PostDOMEvent();
   // Move the top-level window out of fullscreen mode.
+  FullscreenRoots::Remove(root);
   SetWindowFullScreen(root, false);
 }
 
 /* static */
 void
 nsDocument::ExitFullscreen(nsIDocument* aDoc)
 {
   // Unlock the pointer
@@ -11303,16 +11299,17 @@ nsDocument::RestorePreviousFullScreenSta
   if (doc == nullptr) {
     // We moved all documents in this doctree out of fullscreen mode,
     // move the top-level window out of fullscreen mode.
     NS_ASSERTION(!nsContentUtils::GetRootDocument(this)->IsFullScreenDoc(),
                  "Should have cleared all docs' stacks");
     nsRefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(
       this, NS_LITERAL_STRING("MozDOMFullscreen:Exited"), true, true);
     asyncDispatcher->PostDOMEvent();
+    FullscreenRoots::Remove(this);
     SetWindowFullScreen(this, false);
   }
 }
 
 bool
 nsDocument::IsFullScreenDoc()
 {
   return GetFullScreenElement() != nullptr;
@@ -11661,16 +11658,17 @@ nsDocument::RequestFullScreen(Element* a
 
   // Make the window full-screen. Note we must make the state changes above
   // before making the window full-screen, as then the document reports as
   // being in full-screen mode when the chrome "fullscreen" event fires,
   // enabling chrome to distinguish between browser and dom full-screen
   // modes. Also note that nsGlobalWindow::SetFullScreen() (which
   // SetWindowFullScreen() calls) proxies to the root window in its hierarchy,
   // and does not operate on the a per-nsIDOMWindow basis.
+  FullscreenRoots::Add(this);
   SetWindowFullScreen(this, true, aOptions.mVRHMDDevice);
 }
 
 void
 nsDocument::ApplyFullscreen(Element* aElement,
                             const FullScreenOptions& aOptions)
 {
   // Stash a reference to any existing fullscreen doc, we'll use this later