Bug 1369815 - Add display mode to nsIDocShell and use it for media queries r=heycam
☠☠ backed out by 7780a4af9028 ☠ ☠
authorJames Willcox <snorp@snorp.net>
Wed, 09 Aug 2017 08:54:06 -0500
changeset 411405 3b956ceaaf8bd8a1750ae4405fbe1220f25ae70d
parent 411404 61b906754ea7ad905d0775e2190fc8ca81b116de
child 411406 d25a5921d961a0f5dc392a785f5d46704ca82bfa
push idunknown
push userunknown
push dateunknown
reviewersheycam
bugs1369815
milestone57.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 1369815 - Add display mode to nsIDocShell and use it for media queries r=heycam MozReview-Commit-ID: EVT0fTk6GfC
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/base/nsIDocShell.idl
layout/style/nsMediaFeatures.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -837,16 +837,17 @@ nsDocShell::nsDocShell()
   , mBlankTiming(false)
   , mCreatingDocument(false)
 #ifdef DEBUG
   , mInEnsureScriptEnv(false)
 #endif
   , mDefaultLoadFlags(nsIRequest::LOAD_NORMAL)
   , mFrameType(FRAME_TYPE_REGULAR)
   , mPrivateBrowsingId(0)
+  , mDisplayMode(nsIDocShell::DISPLAY_MODE_BROWSER)
   , mForcedCharset(nullptr)
   , mParentCharset(nullptr)
   , mParentCharsetSource(0)
   , mJSRunToCompletionDepth(0)
   , mTouchEventsOverride(nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE)
 {
   AssertOriginAttributesMatchPrivateBrowsing();
 
@@ -15083,8 +15084,38 @@ nsIDocShell::GetHTMLEditor()
 }
 
 nsresult
 nsIDocShell::SetHTMLEditor(HTMLEditor* aHTMLEditor)
 {
   nsDocShell* docShell = static_cast<nsDocShell*>(this);
   return docShell->SetHTMLEditorInternal(aHTMLEditor);
 }
+
+NS_IMETHODIMP
+nsDocShell::GetDisplayMode(uint32_t* aDisplayMode)
+{
+  NS_ENSURE_ARG_POINTER(aDisplayMode);
+  *aDisplayMode = mDisplayMode;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::SetDisplayMode(uint32_t aDisplayMode)
+{
+  if (!(aDisplayMode == nsIDocShell::DISPLAY_MODE_BROWSER ||
+        aDisplayMode == nsIDocShell::DISPLAY_MODE_STANDALONE ||
+        aDisplayMode == nsIDocShell::DISPLAY_MODE_FULLSCREEN ||
+        aDisplayMode == nsIDocShell::DISPLAY_MODE_MINIMAL_UI)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  if (aDisplayMode != mDisplayMode) {
+    mDisplayMode = aDisplayMode;
+
+    nsPresContext* presContext;
+    if (NS_SUCCEEDED(GetPresContext(&presContext))) {
+      presContext->MediaFeatureValuesChangedAllDocuments(nsRestyleHint(0));
+    }
+  }
+
+  return NS_OK;
+}
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -1049,16 +1049,28 @@ protected:
   // Currently treated as a binary value: 1 - in private mode, 0 - not private mode
   // On content docshells mPrivateBrowsingId == mOriginAttributes.mPrivateBrowsingId
   // On chrome docshells this value will be set, but not have the corresponding
   // origin attribute set.
   uint32_t mPrivateBrowsingId;
 
   nsString mInterceptedDocumentId;
 
+  // This represents the CSS display-mode we are currently using.
+  // It can be any of the following values from nsIDocShell.idl:
+  //
+  // DISPLAY_MODE_BROWSER = 0
+  // DISPLAY_MODE_MINIMAL_UI = 1
+  // DISPLAY_MODE_STANDALONE = 2
+  // DISPLAY_MODE_FULLSCREEN = 3
+  //
+  // This is mostly used for media queries. The integer values above
+  // match those used in nsStyleConsts.h
+  uint32_t mDisplayMode;
+
 private:
   const Encoding* mForcedCharset;
   const Encoding* mParentCharset;
   int32_t mParentCharsetSource;
   nsCOMPtr<nsIPrincipal> mParentCharsetPrincipal;
   nsTObserverArray<nsWeakPtr> mPrivacyObservers;
   nsTObserverArray<nsWeakPtr> mReflowObservers;
   nsTObserverArray<nsWeakPtr> mScrollObservers;
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -1159,9 +1159,24 @@ interface nsIDocShell : nsIDocShellTreeI
 %{C++
   /**
    * These methods call nsDocShell::GetHTMLEditorInternal() and
    * nsDocShell::SetHTMLEditorInternal() with static_cast.
    */
   mozilla::HTMLEditor* GetHTMLEditor();
   nsresult SetHTMLEditor(mozilla::HTMLEditor* aHTMLEditor);
 %}
+
+  /**
+   * Allowed CSS display modes. This needs to be kept in
+   * sync with similar values in nsStyleConsts.h
+   */
+  const unsigned long DISPLAY_MODE_BROWSER = 0;
+  const unsigned long DISPLAY_MODE_MINIMAL_UI = 1;
+  const unsigned long DISPLAY_MODE_STANDALONE = 2;
+  const unsigned long DISPLAY_MODE_FULLSCREEN = 3;
+
+  /**
+   * Display mode for this docshell. Defaults to DISPLAY_MODE_BROWSER.
+   * Media queries only look at the value in the parent docshell.
+   */
+  attribute unsigned long displayMode;
 };
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -13,16 +13,17 @@
 #include "nsPresContext.h"
 #include "nsCSSValue.h"
 #ifdef XP_WIN
 #include "mozilla/LookAndFeel.h"
 #endif
 #include "nsCSSRuleProcessor.h"
 #include "nsDeviceContext.h"
 #include "nsIBaseWindow.h"
+#include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIWidget.h"
 #include "nsContentUtils.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 
 using namespace mozilla;
 
@@ -299,43 +300,54 @@ GetScan(nsPresContext* aPresContext, con
   aResult.Reset();
 }
 
 static void
 GetDisplayMode(nsPresContext* aPresContext, const nsMediaFeature*,
                nsCSSValue& aResult)
 {
   nsCOMPtr<nsISupports> container;
+  RefPtr<nsIDocShell> docShell;
+
+  if (!aPresContext) {
+    aResult.SetIntValue(NS_STYLE_DISPLAY_MODE_BROWSER, eCSSUnit_Enumerated);
+    return;
+  }
+
   if (aPresContext) {
     // Calling GetRootPresContext() can be slow, so make sure to call it
     // just once.
     nsRootPresContext* root = aPresContext->GetRootPresContext();
     if (root && root->Document()) {
       container = root->Document()->GetContainer();
+      docShell = root->GetDocShell();
     }
   }
+
   nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
-  if (!baseWindow) {
-    aResult.SetIntValue(NS_STYLE_DISPLAY_MODE_BROWSER, eCSSUnit_Enumerated);
-    return;
+  if (baseWindow) {
+    nsCOMPtr<nsIWidget> mainWidget;
+    baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
+    nsSizeMode mode = mainWidget ? mainWidget->SizeMode() : nsSizeMode_Normal;
+
+    if (mode == nsSizeMode_Fullscreen) {
+      aResult.SetIntValue(NS_STYLE_DISPLAY_MODE_FULLSCREEN, eCSSUnit_Enumerated);
+      return;
+    }
   }
-  nsCOMPtr<nsIWidget> mainWidget;
-  baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
-  int32_t displayMode;
-  nsSizeMode mode = mainWidget ? mainWidget->SizeMode() : nsSizeMode_Normal;
-  // Background tabs are always in 'browser' mode for now.
-  // If new modes are supported, please ensure not cause the regression in
-  // Bug 1259641.
-  switch (mode) {
-    case nsSizeMode_Fullscreen:
-      displayMode = NS_STYLE_DISPLAY_MODE_FULLSCREEN;
-      break;
-    default:
-      displayMode = NS_STYLE_DISPLAY_MODE_BROWSER;
-      break;
+
+  static_assert(nsIDocShell::DISPLAY_MODE_BROWSER == NS_STYLE_DISPLAY_MODE_BROWSER &&
+                nsIDocShell::DISPLAY_MODE_MINIMAL_UI == NS_STYLE_DISPLAY_MODE_MINIMAL_UI &&
+                nsIDocShell::DISPLAY_MODE_STANDALONE == NS_STYLE_DISPLAY_MODE_STANDALONE &&
+                nsIDocShell::DISPLAY_MODE_FULLSCREEN == NS_STYLE_DISPLAY_MODE_FULLSCREEN,
+                "nsIDocShell display modes must mach nsStyleConsts.h");
+
+  uint32_t displayMode = NS_STYLE_DISPLAY_MODE_BROWSER;
+  if (docShell) {
+    docShell->GetDisplayMode(&displayMode);
   }
 
   aResult.SetIntValue(displayMode, eCSSUnit_Enumerated);
 }
 
 static void
 GetGrid(nsPresContext* aPresContext, const nsMediaFeature*,
         nsCSSValue& aResult)