Bug 716575 (1/4) - Add a scriptable interface to GetViewportInfo [r=dbaron]
authorMatt Brubeck <mbrubeck@mozilla.com>
Wed, 22 Aug 2012 13:17:20 -0700
changeset 107778 ab874d12dcde471855f0a5de5b40d3400018f86d
parent 107777 e96de94819152214bc21bbdcd6bcd5222a948a97
child 107779 39803b4c2b9d0bf3011379ec6079b2cf5878af27
push id23509
push userryanvm@gmail.com
push dateSat, 22 Sep 2012 12:28:38 +0000
treeherdermozilla-central@b461a7cd250e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs716575
milestone18.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 716575 (1/4) - Add a scriptable interface to GetViewportInfo [r=dbaron]
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
layout/base/nsLayoutUtils.cpp
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1532,20 +1532,27 @@ public:
 
   /**
    * Retrieve information about the viewport as a data structure.
    * This will return information in the viewport META data section
    * of the document. This can be used in lieu of ProcessViewportInfo(),
    * which places the viewport information in the document header instead
    * of returning it directly.
    *
+   * @param aDisplayWidth width of the on-screen display area for this
+   * document, in device pixels.
+   * @param aDisplayHeight height of the on-screen display area for this
+   * document, in device pixels.
+   *
    * NOTE: If the site is optimized for mobile (via the doctype), this
    * will return viewport information that specifies default information.
    */
-  static ViewportInfo GetViewportInfo(nsIDocument* aDocument);
+  static ViewportInfo GetViewportInfo(nsIDocument* aDocument,
+                                      uint32_t aDisplayWidth,
+                                      uint32_t aDisplayHeight);
 
   // Call EnterMicroTask when you're entering JS execution.
   // Usually the best way to do this is to use nsAutoMicroTask.
   static void EnterMicroTask() { ++sMicroTaskLevel; }
   static void LeaveMicroTask();
 
   static bool IsInMicroTask() { return sMicroTaskLevel != 0; }
   static uint32_t MicroTaskLevel() { return sMicroTaskLevel; }
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5078,17 +5078,19 @@ static void ProcessViewportToken(nsIDocu
     aDocument->SetHeaderData(nsGkAtoms::viewport_user_scalable, value);
 }
 
 #define IS_SEPARATOR(c) ((c == '=') || (c == ',') || (c == ';') || \
                          (c == '\t') || (c == '\n') || (c == '\r'))
 
 /* static */
 ViewportInfo
-nsContentUtils::GetViewportInfo(nsIDocument *aDocument)
+nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
+                                uint32_t aDisplayWidth,
+                                uint32_t aDisplayHeight)
 {
   ViewportInfo ret;
   ret.defaultZoom = 1.0;
   ret.autoSize = true;
   ret.allowZoom = true;
 
   nsAutoString viewport;
   aDocument->GetHeaderData(nsGkAtoms::viewport, viewport);
@@ -5167,82 +5169,57 @@ nsContentUtils::GetViewportInfo(nsIDocum
 
   if (widthStr.IsEmpty() &&
      (heightStr.EqualsLiteral("device-height") ||
           scaleFloat == 1.0))
   {
     autoSize = true;
   }
 
-  // XXXjwir3:
-  // See bug 706918, comment 23 for more information on this particular section
-  // of the code. We're using "screen size" in place of the size of the content
-  // area, because on mobile, these are close or equal. This will work for our
-  // purposes (bug 706198), but it will need to be changed in the future to be
-  // more correct when we bring the rest of the viewport code into platform.
-  // We actually want the size of the content area, in the event that we don't
-  // have any metadata about the width and/or height. On mobile, the screen size
-  // and the size of the content area are very close, or the same value.
-  // In XUL fennec, the content area is the size of the <browser> widget, but
-  // in native fennec, the content area is the size of the Gecko LayerView
-  // object.
-
-  // TODO:
-  // Once bug 716575 has been resolved, this code should be changed so that it
-  // does the right thing on all platforms.
-  nsresult result;
-  int32_t screenLeft, screenTop, screenWidth, screenHeight;
-  nsCOMPtr<nsIScreenManager> screenMgr =
-    do_GetService("@mozilla.org/gfx/screenmanager;1", &result);
-
-  nsCOMPtr<nsIScreen> screen;
-  screenMgr->GetPrimaryScreen(getter_AddRefs(screen));
-  screen->GetRect(&screenLeft, &screenTop, &screenWidth, &screenHeight);
-
   uint32_t width = widthStr.ToInteger(&errorCode);
   if (NS_FAILED(errorCode)) {
     if (autoSize) {
-      width = screenWidth;
+      width = aDisplayWidth;
     } else {
       width = Preferences::GetInt("browser.viewport.desktopWidth", 0);
     }
   }
 
   width = NS_MIN(width, kViewportMaxWidth);
   width = NS_MAX(width, kViewportMinWidth);
 
   // Also recalculate the default zoom, if it wasn't specified in the metadata,
   // and the width is specified.
   if (scaleStr.IsEmpty() && !widthStr.IsEmpty()) {
-    scaleFloat = NS_MAX(scaleFloat, (float)(screenWidth/width));
+    scaleFloat = NS_MAX(scaleFloat, (float)(aDisplayWidth/width));
   }
 
   uint32_t height = heightStr.ToInteger(&errorCode);
 
   if (NS_FAILED(errorCode)) {
-    height = width * ((float)screenHeight / screenWidth);
+    height = width * ((float)aDisplayHeight / aDisplayWidth);
   }
 
   // If height was provided by the user, but width wasn't, then we should
   // calculate the width.
   if (widthStr.IsEmpty() && !heightStr.IsEmpty()) {
-    width = (uint32_t) ((height * screenWidth) / screenHeight);
+    width = (uint32_t) ((height * aDisplayWidth) / aDisplayHeight);
   }
 
   height = NS_MIN(height, kViewportMaxHeight);
   height = NS_MAX(height, kViewportMinHeight);
 
   // We need to perform a conversion, but only if the initial or maximum
   // scale were set explicitly by the user.
   if (!scaleStr.IsEmpty() && NS_SUCCEEDED(scaleErrorCode)) {
-    width = NS_MAX(width, (uint32_t)(screenWidth / scaleFloat));
-    height = NS_MAX(height, (uint32_t)(screenHeight / scaleFloat));
+    width = NS_MAX(width, (uint32_t)(aDisplayWidth / scaleFloat));
+    height = NS_MAX(height, (uint32_t)(aDisplayHeight / scaleFloat));
   } else if (!maxScaleStr.IsEmpty() && NS_SUCCEEDED(scaleMaxErrorCode)) {
-    width = NS_MAX(width, (uint32_t)(screenWidth / scaleMaxFloat));
-    height = NS_MAX(height, (uint32_t)(screenHeight / scaleMaxFloat));
+    width = NS_MAX(width, (uint32_t)(aDisplayWidth / scaleMaxFloat));
+    height = NS_MAX(height, (uint32_t)(aDisplayHeight / scaleMaxFloat));
   }
 
   bool allowZoom = true;
   nsAutoString userScalable;
   aDocument->GetHeaderData(nsGkAtoms::viewport_user_scalable, userScalable);
 
   if ((userScalable.EqualsLiteral("0")) ||
       (userScalable.EqualsLiteral("no")) ||
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -172,17 +172,17 @@ nsDOMWindowUtils::GetDocCharsetIsForced(
   *aIsForced = false;
 
   if (!IsUniversalXPConnectCapable()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   if (window) {
-    nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
+    nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
     *aIsForced = doc &&
       doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
@@ -258,16 +258,41 @@ nsDOMWindowUtils::SetCSSViewport(float a
   nscoord width = nsPresContext::CSSPixelsToAppUnits(aWidthPx);
   nscoord height = nsPresContext::CSSPixelsToAppUnits(aHeightPx);
 
   presShell->ResizeReflowOverride(width, height);
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth,
+                                  uint32_t aDisplayHeight,
+                                  double *aDefaultZoom, bool *aAllowZoom,
+                                  double *aMinZoom, double *aMaxZoom,
+                                  uint32_t *aWidth, uint32_t *aHeight,
+                                  bool *aAutoSize)
+{
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
+  NS_ENSURE_STATE(window);
+
+  nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
+  NS_ENSURE_STATE(doc);
+
+  ViewportInfo info = nsContentUtils::GetViewportInfo(doc, aDisplayWidth, aDisplayHeight);
+  *aDefaultZoom = info.defaultZoom;
+  *aAllowZoom = info.allowZoom;
+  *aMinZoom = info.minZoom;
+  *aMaxZoom = info.maxZoom;
+  *aWidth = info.width;
+  *aHeight = info.height;
+  *aAutoSize = info.autoSize;
+  return NS_OK;
+}
+
 static void DestroyNsRect(void* aObject, nsIAtom* aPropertyName,
                           void* aPropertyValue, void* aData)
 {
   nsRect* rect = static_cast<nsRect*>(aPropertyValue);
   delete rect;
 }
 
 static void
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -35,17 +35,17 @@ interface nsIQueryContentEventResult;
 interface nsIDOMWindow;
 interface nsIDOMBlob;
 interface nsIDOMFile;
 interface nsIFile;
 interface nsIDOMTouch;
 interface nsIDOMClientRect;
 interface nsIURI;
 
-[scriptable, uuid(6cf3e8f0-fb82-11e1-a21f-0800200c9a66)]
+[scriptable, uuid(90d8e97b-2c61-4c05-9f1c-e568d22f5bdc)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -99,16 +99,26 @@ interface nsIDOMWindowUtils : nsISupport
    * This will trigger reflow.
    *
    * The caller of this method must have UniversalXPConnect
    * privileges.
    */
   void setCSSViewport(in float aWidthPx, in float aHeightPx);
 
   /**
+   * Information retrieved from the <meta name="viewport"> tag.
+   * See nsContentUtils::GetViewportInfo for more information.
+   */
+  void getViewportInfo(in uint32_t aDisplayWidth, in uint32_t aDisplayHeight,
+                       out double aDefaultZoom, out boolean aAllowZoom,
+                       out double aMinZoom, out double aMaxZoom,
+                       out uint32_t aWidth, out uint32_t aHeight,
+                       out boolean aAutoSize);
+
+  /**
    * For any scrollable element, this allows you to override the
    * visible region and draw more than what is visible, which is
    * useful for asynchronous drawing. The "displayport" will be
    * <xPx, yPx, widthPx, heightPx> in units of CSS pixels,
    * regardless of the size of the enclosing container.  This
    * will *not* trigger reflow.
    *
    * For the root scroll area, pass in the root document element.
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -5061,17 +5061,46 @@ nsLayoutUtils::FontSizeInflationEnabled(
 
   if (!presShell ||
       (presShell->FontSizeInflationEmPerLine() == 0 &&
        presShell->FontSizeInflationMinTwips() == 0) ||
        aPresContext->IsChrome()) {
     return false;
   }
 
-  ViewportInfo vInf =
-    nsContentUtils::GetViewportInfo(aPresContext->PresShell()->GetDocument());
-
-  if (vInf.defaultZoom >= 1.0 || vInf.autoSize) {
-    return false;
+  // XXXjwir3:
+  // See bug 706918, comment 23 for more information on this particular section
+  // of the code. We're using "screen size" in place of the size of the content
+  // area, because on mobile, these are close or equal. This will work for our
+  // purposes (bug 706198), but it will need to be changed in the future to be
+  // more correct when we bring the rest of the viewport code into platform.
+  // We actually want the size of the content area, in the event that we don't
+  // have any metadata about the width and/or height. On mobile, the screen size
+  // and the size of the content area are very close, or the same value.
+  // In XUL fennec, the content area is the size of the <browser> widget, but
+  // in native fennec, the content area is the size of the Gecko LayerView
+  // object.
+
+  // TODO:
+  // Once bug 716575 has been resolved, this code should be changed so that it
+  // does the right thing on all platforms.
+  nsresult rv;
+  nsCOMPtr<nsIScreenManager> screenMgr =
+    do_GetService("@mozilla.org/gfx/screenmanager;1", &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIScreen> screen;
+  screenMgr->GetPrimaryScreen(getter_AddRefs(screen));
+  if (screen) {
+    int32_t screenLeft, screenTop, screenWidth, screenHeight;
+    screen->GetRect(&screenLeft, &screenTop, &screenWidth, &screenHeight);
+
+    ViewportInfo vInf =
+      nsContentUtils::GetViewportInfo(aPresContext->PresShell()->GetDocument(),
+                                      screenWidth, screenHeight);
+
+    if (vInf.defaultZoom >= 1.0 || vInf.autoSize) {
+      return false;
+    }
   }
 
   return true;
 }