Bug 545812 - Implement -moz-full-screen css pseudoclass. r=bz
authorChris Pearce <chris@pearce.org.nz>
Mon, 05 Sep 2011 08:39:08 +1200
changeset 76533 8794e3692ee86a90940c4a376801324f8abc7deb
parent 76532 f212867dce42ff6aa6d63c76570d5eb4a3c9f5f8
child 76534 be0876c4aa2bc9ff1e307e25111d214ebbc1a63b
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersbz
bugs545812
milestone9.0a1
Bug 545812 - Implement -moz-full-screen css pseudoclass. r=bz
content/base/src/nsDocument.cpp
content/events/public/nsEventStates.h
content/events/src/nsEventStateManager.cpp
content/events/src/nsEventStateManager.h
layout/style/html.css
layout/style/nsCSSPseudoClassList.h
layout/style/ua.css
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -176,16 +176,17 @@
 #ifdef MOZ_MEDIA
 #include "nsHTMLMediaElement.h"
 #endif // MOZ_MEDIA
 
 #include "mozAutoDocUpdate.h"
 #include "nsGlobalWindow.h"
 #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
 #include "nsDOMNavigationTiming.h"
+#include "nsEventStateManager.h"
 
 #ifdef MOZ_SMIL
 #include "nsSMILAnimationController.h"
 #include "imgIContainer.h"
 #include "nsSVGUtils.h"
 #endif // MOZ_SMIL
 
 #include "nsRefreshDriver.h"
@@ -8511,16 +8512,19 @@ UpdateFullScreenStatusInDocTree(nsIDocum
   if (root) {
     UpdateFullScreenStatus(root, static_cast<void*>(&aIsFullScreen));
   }
 }
 
 void
 nsDocument::ResetFullScreenElement()
 {
+  if (mFullScreenElement) {
+    nsEventStateManager::SetFullScreenState(mFullScreenElement, PR_FALSE);
+  }
   mFullScreenElement = nsnull;
 }
 
 static PRBool
 ResetFullScreenElement(nsIDocument* aDocument, void* aData)
 {
   aDocument->ResetFullScreenElement();
   aDocument->EnumerateSubDocuments(ResetFullScreenElement, aData);
@@ -8572,21 +8576,26 @@ nsDocument::RequestFullScreen(Element* a
   ResetFullScreenElementInDocTree(this);
   
   if (aElement->IsInDoc()) {
     // Propagate up the document hierarchy, setting the full-screen element as
     // the element's container in ancestor documents. Note we don't propagate
     // down the document hierarchy, the full-screen element (or its container)
     // is not visible there.
     mFullScreenElement = aElement;
+    // Set the full-screen state on the element, so the css-pseudo class
+    // applies to the element.
+    nsEventStateManager::SetFullScreenState(mFullScreenElement, PR_TRUE);
     nsIDocument* child = this;
     nsIDocument* parent;
     while (parent = child->GetParentDocument()) {
       nsIContent* content = parent->FindContentForSubDocument(child);
       nsCOMPtr<Element> element(do_QueryInterface(content));
+      // Containing frames also need the css-pseudo class applied.
+      nsEventStateManager::SetFullScreenState(element, PR_TRUE);
       static_cast<nsDocument*>(parent)->mFullScreenElement = element;
       child = parent;
     }
   }
 
   // Set all documents in hierarchy to full-screen mode.
   UpdateFullScreenStatusInDocTree(this, PR_TRUE);
 
--- a/content/events/public/nsEventStates.h
+++ b/content/events/public/nsEventStates.h
@@ -256,21 +256,25 @@ private:
 // Content shows its placeholder
 #define NS_EVENT_STATE_MOZ_PLACEHOLDER NS_DEFINE_EVENT_STATE_MACRO(30)
 // Content is a submit control and the form isn't valid.
 #define NS_EVENT_STATE_MOZ_SUBMITINVALID NS_DEFINE_EVENT_STATE_MACRO(31)
 // UI friendly version of :invalid pseudo-class.
 #define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(32)
 // UI friendly version of :valid pseudo-class.
 #define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(33)
+// Content is the full screen element, or a frame containing the
+// current full-screen element.
+#define NS_EVENT_STATE_FULL_SCREEN   NS_DEFINE_EVENT_STATE_MACRO(34)
 
 /**
  * NOTE: do not go over 63 without updating nsEventStates::InternalType!
  */
 
 #define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS |     \
                             NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER |   \
-                            NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING)
+                            NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
+                            NS_EVENT_STATE_FULL_SCREEN)
 
 #define INTRINSIC_STATES (~ESM_MANAGED_STATES)
 
 #endif // nsEventStates_h__
 
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -4380,16 +4380,24 @@ static nsIContent* FindCommonAncestor(ns
       }
       return anc1;
     }
   }
   return nsnull;
 }
 
 /* static */
+void
+nsEventStateManager::SetFullScreenState(Element* aElement,
+                                        PRBool aIsFullScreen)
+{
+  DoStateChange(aElement, NS_EVENT_STATE_FULL_SCREEN, aIsFullScreen);
+}
+
+/* static */
 inline void
 nsEventStateManager::DoStateChange(Element* aElement, nsEventStates aState,
                                    PRBool aAddState)
 {
   if (aAddState) {
     aElement->AddStates(aState);
   } else {
     aElement->RemoveStates(aState);
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -198,16 +198,20 @@ public:
   static nsIDocument* sMouseOverDocument;
 
   static nsEventStateManager* GetActiveEventStateManager() { return sActiveESM; }
 
   // Sets aNewESM to be the active event state manager, and
   // if aContent is non-null, marks the object as active.
   static void SetActiveManager(nsEventStateManager* aNewESM,
                                nsIContent* aContent);
+
+  // Sets the full-screen event state on aElement to aIsFullScreen.
+  static void SetFullScreenState(mozilla::dom::Element* aElement, PRBool aIsFullScreen);
+
 protected:
   void UpdateCursor(nsPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus);
   /**
    * Turn a GUI mouse event into a mouse event targeted at the specified
    * content.  This returns the primary frame for the content (or null
    * if it goes away during the event).
    */
   nsIFrame* DispatchMouseEvent(nsGUIEvent* aEvent, PRUint32 aMessage,
--- a/layout/style/html.css
+++ b/layout/style/html.css
@@ -710,16 +710,21 @@ noembed, param {
    display: none;
 }
 
 area {
   /* Don't give it frames other than its imageframe */
   display: none ! important;
 }
 
+iframe:-moz-full-screen {
+  /* iframes in full-screen mode don't show a border. */
+  border: none;
+}
+
 /* media elements */
 video > xul|videocontrols, audio > xul|videocontrols {
   display: -moz-box;
   -moz-box-orient: vertical;
   -moz-binding: url("chrome://global/content/bindings/videocontrols.xml#videoControls");
 }
 
 video:not([controls]) > xul|videocontrols,
--- a/layout/style/nsCSSPseudoClassList.h
+++ b/layout/style/nsCSSPseudoClassList.h
@@ -135,16 +135,20 @@ CSS_STATE_PSEUDO_CLASS(disabled, ":disab
 CSS_STATE_PSEUDO_CLASS(enabled, ":enabled", NS_EVENT_STATE_ENABLED)
 CSS_STATE_PSEUDO_CLASS(focus, ":focus", NS_EVENT_STATE_FOCUS)
 CSS_STATE_PSEUDO_CLASS(hover, ":hover", NS_EVENT_STATE_HOVER)
 CSS_STATE_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over", NS_EVENT_STATE_DRAGOVER)
 CSS_STATE_PSEUDO_CLASS(target, ":target", NS_EVENT_STATE_URLTARGET)
 CSS_STATE_PSEUDO_CLASS(indeterminate, ":indeterminate",
                        NS_EVENT_STATE_INDETERMINATE)
 
+// Matches the element which is being displayed full-screen, and
+// any containing frames.
+CSS_STATE_PSEUDO_CLASS(mozFullScreen, ":-moz-full-screen", NS_EVENT_STATE_FULL_SCREEN)
+
 // Matches if the element is focused and should show a focus ring
 CSS_STATE_PSEUDO_CLASS(mozFocusRing, ":-moz-focusring", NS_EVENT_STATE_FOCUSRING)
 
 // Image, object, etc state pseudo-classes
 CSS_STATE_PSEUDO_CLASS(mozBroken, ":-moz-broken", NS_EVENT_STATE_BROKEN)
 CSS_STATE_PSEUDO_CLASS(mozUserDisabled, ":-moz-user-disabled",
                        NS_EVENT_STATE_USERDISABLED)
 CSS_STATE_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed",
--- a/layout/style/ua.css
+++ b/layout/style/ua.css
@@ -235,16 +235,28 @@
 @media print {
 
   * {
     cursor: default !important;
   }
 
 }
 
+*|*:-moz-full-screen {
+  position:fixed;
+  top:0;
+  left:0;
+  right:0;
+  bottom:0;
+  z-index:2147483647;
+  background:black;
+  width: 100% !important;
+  height: 100% !important;
+}
+
 /* XML parse error reporting */
 
 parsererror|parsererror {
   display: block;
   font-family: sans-serif;
   font-weight: bold;
   white-space: pre;
   margin: 1em;