Bug 975931. Part 11: Make nsDOMWindowUtils::SetDisplayPortForElement take a priority parameter, and set that parameter to 1 in reftests to override automatic displayport selection. r=kats
authorRobert O'Callahan <robert@ocallahan.org>
Sat, 08 Mar 2014 22:25:15 +1300
changeset 172768 fbd66b4eaeea87051278f8b93e4d2b3eb130955b
parent 172767 6a469c5a27699870a136b84ca82e8be898749a16
child 172769 fb23f20f9c6cdebb4a674851bb4cff1c100c5b63
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerskats
bugs975931
milestone30.0a1
Bug 975931. Part 11: Make nsDOMWindowUtils::SetDisplayPortForElement take a priority parameter, and set that parameter to 1 in reftests to override automatic displayport selection. r=kats
browser/metro/base/content/apzc.js
browser/metro/base/content/bindings/browser.js
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/ipc/test-ipcbrowser-content.js
layout/tools/reftest/reftest-content.js
mobile/android/chrome/content/browser.js
widget/xpwidgets/APZCCallbackHelper.cpp
--- a/browser/metro/base/content/apzc.js
+++ b/browser/metro/base/content/apzc.js
@@ -142,11 +142,12 @@ var APZCObserver = {
     if (win.scrollY > 0) {
       portY -= ContentAreaObserver.height * factor;
     }
     let cwu = Browser.selectedBrowser.contentWindow
                       .QueryInterface(Ci.nsIInterfaceRequestor)
                       .getInterface(Ci.nsIDOMWindowUtils);
     cwu.setDisplayPortForElement(portX, portY,
                                  portWidth, portHeight,
-                                 Browser.selectedBrowser.contentDocument.documentElement);
+                                 Browser.selectedBrowser.contentDocument.documentElement,
+                                 0);
   }
 };
--- a/browser/metro/base/content/bindings/browser.js
+++ b/browser/metro/base/content/bindings/browser.js
@@ -680,17 +680,17 @@ let ContentActive =  {
   receiveMessage: function(aMessage) {
     let json = aMessage.json;
     switch (aMessage.name) {
       case "Content:Deactivate":
         docShell.isActive = false;
         let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
         if (json.keepviewport)
           break;
-        cwu.setDisplayPortForElement(0, 0, 0, 0, content.document.documentElement);
+        cwu.setDisplayPortForElement(0, 0, 0, 0, content.document.documentElement, 0);
         break;
 
       case "Content:Activate":
         docShell.isActive = true;
         break;
     }
   }
 };
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -300,16 +300,24 @@ nsDOMWindowUtils::GetViewportInfo(uint32
   *aMinZoom = info.GetMinZoom().scale;
   *aMaxZoom = info.GetMaxZoom().scale;
   *aWidth = info.GetSize().width;
   *aHeight = info.GetSize().height;
   *aAutoSize = info.IsAutoSizeEnabled();
   return NS_OK;
 }
 
+static void DestroyDisplayPortPropertyData(void* aObject, nsIAtom* aPropertyName,
+                                           void* aPropertyValue, void* aData)
+{
+  DisplayPortPropertyData* data =
+    static_cast<DisplayPortPropertyData*>(aPropertyValue);
+  delete data;
+}
+
 static void DestroyNsRect(void* aObject, nsIAtom* aPropertyName,
                           void* aPropertyValue, void* aData)
 {
   nsRect* rect = static_cast<nsRect*>(aPropertyValue);
   delete rect;
 }
 
 static void
@@ -353,17 +361,18 @@ MaybeReflowForInflationScreenWidthChange
       }
     }
   }
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
                                            float aWidthPx, float aHeightPx,
-                                           nsIDOMElement* aElement)
+                                           nsIDOMElement* aElement,
+                                           uint32_t aPriority)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsIPresShell* presShell = GetPresShell();
   if (!presShell) {
     return NS_ERROR_FAILURE;
@@ -383,18 +392,25 @@ nsDOMWindowUtils::SetDisplayPortForEleme
   if (!content) {
     return NS_ERROR_INVALID_ARG;
   }
 
   if (content->GetCurrentDoc() != presShell->GetDocument()) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  content->SetProperty(nsGkAtoms::DisplayPort, new nsRect(displayport),
-                       DestroyNsRect);
+  DisplayPortPropertyData* currentData =
+    static_cast<DisplayPortPropertyData*>(content->GetProperty(nsGkAtoms::DisplayPort));
+  if (currentData && currentData->mPriority > aPriority) {
+    return NS_OK;
+  }
+
+  content->SetProperty(nsGkAtoms::DisplayPort,
+                       new DisplayPortPropertyData(displayport, aPriority),
+                       DestroyDisplayPortPropertyData);
 
   nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
   if (rootScrollFrame) {
     if (content == rootScrollFrame->GetContent()) {
       // We are setting a root displayport for a document.
       // The pres shell needs a special flag set.
       presShell->SetIgnoreViewportScrolling(true);
 
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -38,17 +38,17 @@ interface nsIDOMFile;
 interface nsIFile;
 interface nsIDOMTouch;
 interface nsIDOMClientRect;
 interface nsIURI;
 interface nsIDOMEventTarget;
 interface nsIRunnable;
 interface nsICompositionStringSynthesizer;
 
-[scriptable, uuid(17fccbaa-9cef-4217-9c98-3275d9a6c6de)]
+[scriptable, uuid(27efada9-b8ea-4d70-a2e6-f46b9ba905f4)]
 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.
@@ -138,20 +138,25 @@ interface nsIDOMWindowUtils : nsISupport
    * area's bounds.  No pixels are rendered outside the area bounds.
    *
    * The caller of this method must have chrome privileges.
    *
    * Calling this will always force a recomposite, so it should be
    * avoided if at all possible. Client code should do checks before
    * calling this so that duplicate sets are not made with the same
    * displayport.
+   *
+   * aPriority is recorded along with the displayport rectangle. If this
+   * method is called with a lower priority than the current priority, the
+   * call is ignored.
    */
   void setDisplayPortForElement(in float aXPx, in float aYPx,
                                 in float aWidthPx, in float aHeightPx,
-                                in nsIDOMElement aElement);
+                                in nsIDOMElement aElement,
+                                in uint32_t aPriority);
 
   /**
    * When a display port is set, this allows a sub-section of that
    * display port to be marked as 'critical'. In this scenario, the
    * area outside of this rectangle may be rendered at a lower
    * detail (for example, by reducing its resolution), or not rendered
    * at all under some circumstances.
    * This call will have no effect if a display port has not been set.
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -656,17 +656,17 @@ bool
 nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult)
 {
   void* property = aContent->GetProperty(nsGkAtoms::DisplayPort);
   if (!property) {
     return false;
   }
 
   if (aResult) {
-    *aResult = *static_cast<nsRect*>(property);
+    *aResult = (static_cast<DisplayPortPropertyData*>(property))->mRect;
   }
   return true;
 }
 
 bool
 nsLayoutUtils::GetCriticalDisplayPort(nsIContent* aContent, nsRect* aResult)
 {
   void* property = aContent->GetProperty(nsGkAtoms::CriticalDisplayPort);
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -65,16 +65,28 @@ class DOMRectList;
 class Element;
 class HTMLImageElement;
 class HTMLCanvasElement;
 class HTMLVideoElement;
 } // namespace dom
 namespace layers {
 class Layer;
 }
+}
+
+namespace mozilla {
+
+struct DisplayPortPropertyData {
+  DisplayPortPropertyData(const nsRect& aRect, uint32_t aPriority)
+    : mRect(aRect)
+    , mPriority(aPriority)
+  {}
+  nsRect mRect;
+  uint32_t mPriority;
+};
 
 template <class AnimationsOrTransitions>
 extern AnimationsOrTransitions* HasAnimationOrTransition(nsIContent* aContent,
                                                          nsIAtom* aAnimationProperty,
                                                          nsCSSProperty aProperty);
 
 } // namespace mozilla
 
--- a/layout/ipc/test-ipcbrowser-content.js
+++ b/layout/ipc/test-ipcbrowser-content.js
@@ -13,17 +13,17 @@ function recvSetViewport(w, h) {
 
     windowUtils().setCSSViewport(w, h);
 }
 
 function recvSetDisplayPort(x, y, w, h) {
 
     dump("setting displayPort to <"+ x +", "+ y +", "+ w +", "+ h +">\n");
 
-    windowUtils().setDisplayPortForElement(x, y, w, h, content.document.documentElement);
+    windowUtils().setDisplayPortForElement(x, y, w, h, content.document.documentElement, 0);
 }
 
 function recvSetResolution(xres, yres) {
 
     dump("setting xres="+ xres +" yres="+ yres +"\n");
 
     windowUtils().setResolution(xres, yres);
 }
--- a/layout/tools/reftest/reftest-content.js
+++ b/layout/tools/reftest/reftest-content.js
@@ -210,17 +210,17 @@ function setupDisplayport(contentRootEle
 
     function setupDisplayportForElement(element) {
         var dpw = attrOrDefault(element, "reftest-displayport-w", 0);
         var dph = attrOrDefault(element, "reftest-displayport-h", 0);
         var dpx = attrOrDefault(element, "reftest-displayport-x", 0);
         var dpy = attrOrDefault(element, "reftest-displayport-y", 0);
         if (dpw !== 0 || dph !== 0 || dpx != 0 || dpy != 0) {
             LogInfo("Setting displayport to <x="+ dpx +", y="+ dpy +", w="+ dpw +", h="+ dph +">");
-            windowUtils().setDisplayPortForElement(dpx, dpy, dpw, dph, element);
+            windowUtils().setDisplayPortForElement(dpx, dpy, dpw, dph, element, 1);
         }
     }
 
     function setupDisplayportForElementSubtree(element) {
         setupDisplayportForElement(element);
         for (var c = element.firstElementChild; c; c = c.nextElementSibling) {
             setupDisplayportForElementSubtree(c);
         }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3118,24 +3118,24 @@ Tab.prototype = {
 
         let dpW = Math.min(pageRect.right - pageRect.left, displayPort.width * 4);
         let dpH = Math.min(pageRect.bottom - pageRect.top, displayPort.height * 4);
 
         let dpX = Math.min(Math.max(displayPort.x - displayPort.width * 1.5,
                                     pageRect.left - geckoScrollX), pageXMost - dpW);
         let dpY = Math.min(Math.max(displayPort.y - displayPort.height * 1.5,
                                     pageRect.top - geckoScrollY), pageYMost - dpH);
-        cwu.setDisplayPortForElement(dpX, dpY, dpW, dpH, element);
+        cwu.setDisplayPortForElement(dpX, dpY, dpW, dpH, element, 0);
         cwu.setCriticalDisplayPortForElement(displayPort.x, displayPort.y,
                                              displayPort.width, displayPort.height,
                                              element);
       } else {
         cwu.setDisplayPortForElement(displayPort.x, displayPort.y,
                                      displayPort.width, displayPort.height,
-                                     element);
+                                     element, 0);
       }
     }
 
     this._oldDisplayPort = displayPort;
   },
 
   /*
    * Yes, this is ugly. But it's currently the safest way to account for the rounding errors that occur
--- a/widget/xpwidgets/APZCCallbackHelper.cpp
+++ b/widget/xpwidgets/APZCCallbackHelper.cpp
@@ -204,17 +204,17 @@ APZCCallbackHelper::UpdateRootFrame(nsID
     nsCOMPtr<nsIDOMElement> element = do_QueryInterface(content);
     if (!element) {
         return;
     }
     aUtils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
                                      aMetrics.mDisplayPort.y,
                                      aMetrics.mDisplayPort.width,
                                      aMetrics.mDisplayPort.height,
-                                     element);
+                                     element, 0);
 }
 
 void
 APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent,
                                    FrameMetrics& aMetrics)
 {
     // Precondition checks
     MOZ_ASSERT(aContent);
@@ -239,17 +239,17 @@ APZCCallbackHelper::UpdateSubFrame(nsICo
         if (!scrollUpdated) {
             RecenterDisplayPort(aMetrics);
         }
         MaybeAlignAndClampDisplayPort(aMetrics, actualScrollOffset);
         utils->SetDisplayPortForElement(aMetrics.mDisplayPort.x,
                                         aMetrics.mDisplayPort.y,
                                         aMetrics.mDisplayPort.width,
                                         aMetrics.mDisplayPort.height,
-                                        element);
+                                        element, 0);
     }
 
     aMetrics.mScrollOffset = actualScrollOffset;
 }
 
 already_AddRefed<nsIDOMWindowUtils>
 APZCCallbackHelper::GetDOMWindowUtils(const nsIDocument* aDoc)
 {