Back out dc7c7734ec7c, f793f9cfa72c, 10ea92a6a850 (bug 591718) for Android b-c orange in mobile/chrome/tests/browser_scrollbar.js
authorPhil Ringnalda <philringnalda@gmail.com>
Tue, 27 Dec 2011 20:34:08 -0800
changeset 84654 d07146e9c62e01d8db712beca8992deb489dab50
parent 84653 0ce4de4491f8d7d86d0acbf98fde5651a602e8d8
child 84655 0b1a809be3bde1bd0230a33dcdcccac5059fea5d
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs591718
milestone12.0a1
backs outdc7c7734ec7c8067ae0dee280077b1625d5b79d0
Back out dc7c7734ec7c, f793f9cfa72c, 10ea92a6a850 (bug 591718) for Android b-c orange in mobile/chrome/tests/browser_scrollbar.js
content/base/src/nsGenericElement.cpp
dom/tests/mochitest/general/Makefile.in
dom/tests/mochitest/general/test_clientRects.html
layout/base/nsDisplayList.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/tests/test_bug677878.html
layout/forms/nsComboboxControlFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/svg/base/src/nsSVGForeignObjectFrame.cpp
layout/svg/base/src/nsSVGForeignObjectFrame.h
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -2131,18 +2131,17 @@ nsGenericElement::GetBoundingClientRect(
   
   nsIFrame* frame = GetPrimaryFrame(Flush_Layout);
   if (!frame) {
     // display:none, perhaps? Return the empty rect
     return NS_OK;
   }
 
   nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame,
-          nsLayoutUtils::GetContainingBlockForClientRect(frame),
-          nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
+          nsLayoutUtils::GetContainingBlockForClientRect(frame));
   rect->SetLayoutRect(r);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetElementsByClassName(const nsAString& aClasses,
                                          nsIDOMNodeList** aReturn)
 {
@@ -2160,18 +2159,17 @@ nsGenericElement::GetClientRects(nsIDOMC
   if (!frame) {
     // display:none, perhaps? Return an empty list
     *aResult = rectList.forget().get();
     return NS_OK;
   }
 
   nsLayoutUtils::RectListBuilder builder(rectList);
   nsLayoutUtils::GetAllInFlowRects(frame,
-          nsLayoutUtils::GetContainingBlockForClientRect(frame), &builder,
-          nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
+          nsLayoutUtils::GetContainingBlockForClientRect(frame), &builder);
   if (NS_FAILED(builder.mRV))
     return builder.mRV;
   *aResult = rectList.forget().get();
   return NS_OK;
 }
 
 
 //----------------------------------------------------------------------
--- a/dom/tests/mochitest/general/Makefile.in
+++ b/dom/tests/mochitest/general/Makefile.in
@@ -53,17 +53,16 @@ include $(topsrcdir)/config/rules.mk
 		test_497898.html \
 		test_bug504220.html \
 		test_bug628069_1.html \
 		test_bug628069_2.html \
 		file_bug628069.html \
 		test_bug631440.html \
 		test_bug653364.html \
 		test_bug629535.html \
-		test_clientRects.html \
 		test_consoleAPI.html \
 		test_domWindowUtils.html \
 		test_domWindowUtils_scrollXY.html \
 		test_offsets.html \
 		test_offsets.js \
 		test_windowProperties.html \
 		test_clipboard_events.html \
 		test_nodesFromRect.html \
deleted file mode 100644
--- a/dom/tests/mochitest/general/test_clientRects.html
+++ /dev/null
@@ -1,125 +0,0 @@
-<!DOCTYPE HTML>
-<html id="d9" style="width:800px; height:1000px">
-<head>
-  <title>Tests for getClientRects/getBoundingClientRect</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
-</head>
-<body style="margin:0" onload="doTest()">
-
-<script>
-function isWithinEps(v1, v2, eps, msg) {
-  if (eps) {
-    ok(Math.abs(v1 - v2) < eps, msg + " (within " + eps + "); got " + v1 + ", expected " + v2);
-  } else {
-    is(v1, v2, msg);
-  }
-}
-function checkRect(clientRect, r, eps, exprMsg, restMsg) {
-  isWithinEps(clientRect.left, r[0], eps, exprMsg + ".left" + restMsg);
-  isWithinEps(clientRect.top, r[1], eps, exprMsg + ".top" + restMsg);
-  isWithinEps(clientRect.right, r[2], eps, exprMsg + ".right" + restMsg);
-  isWithinEps(clientRect.bottom, r[3], eps, exprMsg + ".bottom" + restMsg);
-  isWithinEps(clientRect.width, r[2] - r[0], eps, exprMsg + ".width" + restMsg);
-  isWithinEps(clientRect.height, r[3] - r[1], eps, exprMsg + ".height" + restMsg);
-}
-function doc(id) {
-  return document.getElementById(id).contentDocument;
-}
-function checkElement(id, list, eps, doc) {
-  var e = (doc || document).getElementById(id);
-  var clientRects = e.getClientRects();
-  is(clientRects.length, list.length, "getClientRects().length for element '" + id + "'");
-  var bounds = list.length > 0 ? list[0] : [0,0,0,0];
-  for (var i = 0; i < clientRects.length && i < list.length; ++i) {
-    var r = list[i];
-    r[2] += r[0];
-    r[3] += r[1];
-    checkRect(clientRects[i], r, eps, "getClientRects()[" + i + "]", " for element '" + id + "'");
-    if (r[2] != r[0] && r[3] != r[1]) {
-      bounds[0] = Math.min(bounds[0], r[0]);
-      bounds[1] = Math.min(bounds[1], r[1]);
-      bounds[2] = Math.max(bounds[2], r[2]);
-      bounds[3] = Math.max(bounds[3], r[3]);
-    }
-  }
-  checkRect(e.getBoundingClientRect(), bounds, eps, "getBoundingClientRect()", " for element '" + id + "'");
-}
-</script>
-
-<!-- Simple case -->
-<div id="d1" style="position:absolute; left:50px; top:50px; width:20px; height:30px; background:pink;"></div>
-<!-- Multiple boxes -->
-<div style="position:absolute; left:50px; top:100px; width:400px; height:100px; -moz-column-count:2; -moz-column-gap:0; column-count:2; column-gap:0">
-  <div id="d2">
-    <div style="width:200px; height:100px; background:yellow"></div>
-    <div style="width:200px; height:100px; background:lime"></div>
-  </div>
-</div>
-<!-- No boxes -->
-<div id="d3" style="display:none"></div>
-<!-- Element in transform -->
-<div style="-moz-transform:translate(50px, 50px); transform:translate(50px,50px); position:absolute; left:0; top:200px">
-  <div id="d4" style="width:50px; height:50px; background:blue;"></div>  
-</div>
-<svg style="position:absolute; left:50px; top:300px; width:100px; height:100px;">
-  <!-- Element in SVG foreignobject -->
-  <foreignObject x="20" y="30" width="40" height="40">
-    <div id="d5" style="width:40px; height:40px; background:pink;"></div>
-  </foreignObject>
-  <!-- SVG Element -->
-  <circle id="s1" cx="60" cy="60" r="10" fill="yellow"/>
-</svg>
-<!-- Element in transform with bounding-box -->
-<div style="-moz-transform:rotate(45deg); transform:rotate(45deg); position:absolute; left:50px; top:450px; width:100px; height:100px;">
-  <div id="d6" style="width:100px; height:100px; background:orange;"></div>  
-</div>
-<!-- Element in two transforms; we should combine transforms instead of taking bounding-box twice -->
-<div style="-moz-transform:rotate(45deg); transform:rotate(45deg); position:absolute; left:50px; top:550px; width:100px; height:100px;">
-  <div style="-moz-transform:rotate(-45deg); transform:rotate(-45deg); width:100px; height:100px;">
-    <div id="d7" style="width:100px; height:100px; background:lime;"></div>
-  </div>
-</div>
-<!-- Fixed-pos element -->
-<div id="d8" style="position:fixed; left:50px; top:700px; width:100px; height:100px; background:gray;"></div>
-<!-- Root element; see d9 -->
-<!-- Element in iframe -->
-<iframe id="f1" style="position:absolute; left:300px; top:0; width:100px; height:200px; border:none"
-        src="data:text/html,<div id='d10' style='position:absolute; left:0; top:25px; width:100px; height:100px; background:cyan'>">
-</iframe>
-<!-- Root element in iframe -->
-<iframe id="f2" style="position:absolute; left:300px; top:250px; width:100px; height:200px; border:none"
-        src="data:text/html,<html id='d11' style='width:100px; height:100px; background:magenta'>">
-</iframe>
-<!-- Fixed-pos element in iframe -->
-<iframe id="f3" style="position:absolute; left:300px; top:400px; border:none"
-        src="data:text/html,<div id='d12' style='position:fixed; left:0; top:0; width:100px; height:100px;'>"></iframe>
-
-<script>
-function doTest() {
-  checkElement("d1", [[50,50,20,30]]);
-  checkElement("d2", [[50,100,200,100],[250,100,200,100]]);
-  checkElement("d3", []);
-  checkElement("d4", [[50,250,50,50]]);
-  checkElement("d5", [[70,330,40,40]]);
-  checkElement("s1", [[100,350,20,20]]);
-  var sqrt2 = Math.sqrt(2);
-  checkElement("d6", [[100 - 50*sqrt2,500 - 50*sqrt2,100*sqrt2,100*sqrt2]], 0.1);
-  checkElement("d7", [[50,550,100,100]]);
-  checkElement("d8", [[50,700,100,100]]);
-  checkElement("d9", [[0,0,800,1000]]);
-  checkElement("d10", [[0,25,100,100]], 0, doc("f1"));
-  checkElement("d11", [[0,0,100,100]], 0, doc("f2"));
-  checkElement("d12", [[0,0,100,100]], 0, doc("f3"));
-  SimpleTest.finish();
-}
-SimpleTest.waitForExplicitFinish();
-</script>
-
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-
-</body>
-</html>
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -454,18 +454,17 @@ static nsRect GetDisplayPortBounds(nsDis
 {
   nsIFrame* frame = aItem->GetUnderlyingFrame();
   const nsRect* displayport = aBuilder->GetDisplayPort();
 
   if (aIgnoreTransform) {
     return *displayport;
   }
 
-  // XXX this isn't correct, see bug 701190
-  return nsLayoutUtils::TransformAncestorRectToFrame(
+  return nsLayoutUtils::TransformRectToBoundsInAncestor(
            frame,
            nsRect(0, 0, displayport->width, displayport->height),
            aBuilder->ReferenceFrame());
 }
 
 bool
 nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
                                            nsRegion* aVisibleRegion,
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -970,17 +970,17 @@ nsLayoutUtils::GetEventCoordinatesRelati
   PRInt32 rootAPD = rootFrame->PresContext()->AppUnitsPerDevPixel();
   PRInt32 localAPD = aFrame->PresContext()->AppUnitsPerDevPixel();
   widgetToView = widgetToView.ConvertAppUnits(rootAPD, localAPD);
 
   /* If we encountered a transform, we can't do simple arithmetic to figure
    * out how to convert back to aFrame's coordinates and must use the CTM.
    */
   if (transformFound)
-    return TransformRootPointToFrame(aFrame, widgetToView);
+    return InvertTransformsToRoot(aFrame, widgetToView);
 
   /* Otherwise, all coordinate systems are translations of one another,
    * so we can just subtract out the different.
    */
   return widgetToView - aFrame->GetOffsetToCrossDoc(rootFrame);
 }
 
 nsIFrame*
@@ -1112,106 +1112,93 @@ nsLayoutUtils::MatrixTransformPoint(cons
                                     const gfx3DMatrix &aMatrix, float aFactor)
 {
   gfxPoint image = aMatrix.Transform(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, aFactor),
                                               NSAppUnitsToFloatPixels(aPoint.y, aFactor)));
   return nsPoint(NSFloatPixelsToAppUnits(float(image.x), aFactor),
                  NSFloatPixelsToAppUnits(float(image.y), aFactor));
 }
 
-static gfx3DMatrix
-GetTransformToAncestor(nsIFrame *aFrame, nsIFrame *aAncestor)
+static gfxPoint 
+InvertTransformsToAncestor(nsIFrame *aFrame,
+                           const gfxPoint &aPoint,
+                           nsIFrame *aStopAtAncestor = nsnull)
 {
-  nsIFrame* parent;
-  gfx3DMatrix ctm = aFrame->GetTransformMatrix(aAncestor, &parent);
-  while (parent && parent != aAncestor) {
-    ctm = ctm * parent->GetTransformMatrix(aAncestor, &parent);
-  }
-  return ctm;
-}
-
-static gfxPoint
-TransformGfxPointFromAncestor(nsIFrame *aFrame,
-                              const gfxPoint &aPoint,
-                              nsIFrame *aAncestor)
-{
-  gfx3DMatrix ctm = GetTransformToAncestor(aFrame, aAncestor);
-  return ctm.Inverse().ProjectPoint(aPoint);
+  NS_PRECONDITION(aFrame, "Why are you inverting transforms when there is no frame?");
+
+  /* To invert everything to the root, we'll get the CTM, invert it, and use it to transform
+   * the point.
+   */
+  nsIFrame *parent = nsnull;
+  gfx3DMatrix ctm = aFrame->GetTransformMatrix(&parent);
+  gfxPoint result = aPoint;
+  
+  if (parent && parent != aStopAtAncestor) {
+      result = InvertTransformsToAncestor(parent, aPoint, aStopAtAncestor);
+  }
+
+  result = ctm.Inverse().ProjectPoint(result);
+  return result;
 }
 
 static gfxRect
-TransformGfxRectFromAncestor(nsIFrame *aFrame,
-                             const gfxRect &aRect,
-                             nsIFrame *aAncestor)
+InvertGfxRectToAncestor(nsIFrame *aFrame,
+                     const gfxRect &aRect,
+                     nsIFrame *aStopAtAncestor = nsnull)
 {
-  gfx3DMatrix ctm = GetTransformToAncestor(aFrame, aAncestor);
-  return ctm.Inverse().ProjectRectBounds(aRect);
-}
-
-static gfxRect
-TransformGfxRectToAncestor(nsIFrame *aFrame,
-                           const gfxRect &aRect,
-                           nsIFrame *aAncestor)
-{
-  gfx3DMatrix ctm = GetTransformToAncestor(aFrame, aAncestor);
-  return ctm.ProjectRectBounds(aRect);
+  NS_PRECONDITION(aFrame, "Why are you inverting transforms when there is no frame?");
+
+  /* To invert everything to the root, we'll get the CTM, invert it, and use it to transform
+   * the point.
+   */
+  nsIFrame *parent = nsnull;
+  gfx3DMatrix ctm = aFrame->GetTransformMatrix(&parent);
+  gfxRect result = aRect;
+  
+  if (parent && parent != aStopAtAncestor) {
+      result = InvertGfxRectToAncestor(parent, aRect, aStopAtAncestor);
+  }
+
+  result = ctm.Inverse().ProjectRectBounds(result);
+  return result;
 }
 
 nsPoint
-nsLayoutUtils::TransformRootPointToFrame(nsIFrame *aFrame,
-                                         const nsPoint &aPoint)
+nsLayoutUtils::InvertTransformsToRoot(nsIFrame *aFrame,
+                                      const nsPoint &aPoint)
 {
     float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
     gfxPoint result(NSAppUnitsToFloatPixels(aPoint.x, factor),
                     NSAppUnitsToFloatPixels(aPoint.y, factor));
     
-    result = TransformGfxPointFromAncestor(aFrame, result, nsnull);
+    result = InvertTransformsToAncestor(aFrame, result);
    
     return nsPoint(NSFloatPixelsToAppUnits(float(result.x), factor),
                    NSFloatPixelsToAppUnits(float(result.y), factor));
 }
 
 nsRect 
-nsLayoutUtils::TransformAncestorRectToFrame(nsIFrame* aFrame,
-                                            const nsRect &aRect,
-                                            nsIFrame* aAncestor)
+nsLayoutUtils::TransformRectToBoundsInAncestor(nsIFrame* aFrame,
+                                               const nsRect &aRect,
+                                               nsIFrame* aStopAtAncestor)
 {
     float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
     gfxRect result(NSAppUnitsToFloatPixels(aRect.x, factor),
                    NSAppUnitsToFloatPixels(aRect.y, factor),
                    NSAppUnitsToFloatPixels(aRect.width, factor),
                    NSAppUnitsToFloatPixels(aRect.height, factor));
 
-    result = TransformGfxRectFromAncestor(aFrame, result, aAncestor);
+    result = InvertGfxRectToAncestor(aFrame, result, aStopAtAncestor);
 
     return nsRect(NSFloatPixelsToAppUnits(float(result.x), factor),
                   NSFloatPixelsToAppUnits(float(result.y), factor),
                   NSFloatPixelsToAppUnits(float(result.width), factor),
                   NSFloatPixelsToAppUnits(float(result.height), factor));
 }
 
-nsRect
-nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame,
-                                            const nsRect& aRect,
-                                            nsIFrame* aAncestor)
-{
-  float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
-  gfxRect result(NSAppUnitsToFloatPixels(aRect.x, factor),
-                 NSAppUnitsToFloatPixels(aRect.y, factor),
-                 NSAppUnitsToFloatPixels(aRect.width, factor),
-                 NSAppUnitsToFloatPixels(aRect.height, factor));
-
-  result = TransformGfxRectToAncestor(aFrame, result, aAncestor);
-
-  return nsRect(NSFloatPixelsToAppUnits(float(result.x), factor),
-                NSFloatPixelsToAppUnits(float(result.y), factor),
-                NSFloatPixelsToAppUnits(float(result.width), factor),
-                NSFloatPixelsToAppUnits(float(result.height), factor));
-}
-
 static nsIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) {
   nsIntPoint offset(0, 0);
   nsIWidget* parent = aWidget->GetParent();
   while (parent) {
     nsIntRect bounds;
     aWidget->GetBounds(bounds);
     offset += bounds.TopLeft();
     aWidget = parent;
@@ -1842,45 +1829,37 @@ nsLayoutUtils::GetAllInFlowBoxes(nsIFram
 {
   while (aFrame) {
     AddBoxesForFrame(aFrame, aCallback);
     aFrame = nsLayoutUtils::GetNextContinuationOrSpecialSibling(aFrame);
   }
 }
 
 struct BoxToBorderRect : public nsLayoutUtils::BoxCallback {
-  nsIFrame* mRelativeTo;
+  nsIFrame*                    mRelativeTo;
   nsLayoutUtils::RectCallback* mCallback;
-  PRUint32 mFlags;
-
-  BoxToBorderRect(nsIFrame* aRelativeTo, nsLayoutUtils::RectCallback* aCallback,
-                  PRUint32 aFlags)
-    : mRelativeTo(aRelativeTo), mCallback(aCallback), mFlags(aFlags) {}
+
+  BoxToBorderRect(nsIFrame* aRelativeTo, nsLayoutUtils::RectCallback* aCallback)
+    : mRelativeTo(aRelativeTo), mCallback(aCallback) {}
 
   virtual void AddBox(nsIFrame* aFrame) {
     nsRect r;
     nsIFrame* outer = nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(aFrame, &r);
-    if (!outer) {
-      outer = aFrame;
-      r = nsRect(nsPoint(0, 0), aFrame->GetSize());
-    }
-    if (mFlags & nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS) {
-      r = nsLayoutUtils::TransformFrameRectToAncestor(outer, r, mRelativeTo);
-    } else {
-      r += outer->GetOffsetTo(mRelativeTo);
-    }
-    mCallback->AddRect(r);
+    if (outer) {
+      mCallback->AddRect(r + outer->GetOffsetTo(mRelativeTo));
+    } else
+      mCallback->AddRect(nsRect(aFrame->GetOffsetTo(mRelativeTo), aFrame->GetSize()));
   }
 };
 
 void
 nsLayoutUtils::GetAllInFlowRects(nsIFrame* aFrame, nsIFrame* aRelativeTo,
-                                 RectCallback* aCallback, PRUint32 aFlags)
+                                 RectCallback* aCallback)
 {
-  BoxToBorderRect converter(aRelativeTo, aCallback, aFlags);
+  BoxToBorderRect converter(aRelativeTo, aCallback);
   GetAllInFlowBoxes(aFrame, &converter);
 }
 
 nsLayoutUtils::RectAccumulator::RectAccumulator() : mSeenFirstRect(false) {}
 
 void nsLayoutUtils::RectAccumulator::AddRect(const nsRect& aRect) {
   mResultRect.UnionRect(mResultRect, aRect);
   if (!mSeenFirstRect) {
@@ -1896,24 +1875,29 @@ void nsLayoutUtils::RectListBuilder::Add
   nsRefPtr<nsClientRect> rect = new nsClientRect();
 
   rect->SetLayoutRect(aRect);
   mRectList->Append(rect);
 }
 
 nsIFrame* nsLayoutUtils::GetContainingBlockForClientRect(nsIFrame* aFrame)
 {
-  return aFrame->PresContext()->PresShell()->GetRootFrame();
+  // get the nearest enclosing SVG foreign object frame or the root frame
+  while (aFrame->GetParent() &&
+         !aFrame->IsFrameOfType(nsIFrame::eSVGForeignObject)) {
+    aFrame = aFrame->GetParent();
+  }
+
+  return aFrame;
 }
 
 nsRect
-nsLayoutUtils::GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo,
-                                      PRUint32 aFlags) {
+nsLayoutUtils::GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo) {
   RectAccumulator accumulator;
-  GetAllInFlowRects(aFrame, aRelativeTo, &accumulator, aFlags);
+  GetAllInFlowRects(aFrame, aRelativeTo, &accumulator);
   return accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect
           : accumulator.mResultRect;
 }
 
 nsRect
 nsLayoutUtils::GetTextShadowRectsUnion(const nsRect& aTextAndDecorationsRect,
                                        nsIFrame* aFrame,
                                        PRUint32 aFlags)
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -510,43 +510,33 @@ public:
    * @param aIgnoreRootScrollFrame whether or not the display list builder
    * should ignore the root scroll frame.
    */
   static nsresult GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
                                    nsTArray<nsIFrame*> &aOutFrames,
                                    bool aShouldIgnoreSuppression = false,
                                    bool aIgnoreRootScrollFrame = false);
 
-  /**
-   * Transform aRect relative to aAncestor down to the coordinate system of
-   * aFrame. Computes the bounding-box of the true quadrilateral.
-   */
-  static nsRect TransformAncestorRectToFrame(nsIFrame* aFrame,
-                                             const nsRect& aRect,
-                                             nsIFrame* aAncestor);
+  
 
-  /**
-   * Transform aRect relative to aFrame up to the coordinate system of
-   * aAncestor. Computes the bounding-box of the true quadrilateral.
-   */
-  static nsRect TransformFrameRectToAncestor(nsIFrame* aFrame,
-                                             const nsRect& aRect,
-                                             nsIFrame* aAncestor);
+  static nsRect TransformRectToBoundsInAncestor(nsIFrame* aFrame,
+                                                const nsRect& aRect,
+                                                nsIFrame* aStopAtAncestor);
 
   /**
    * Given a point in the global coordinate space, returns that point expressed
    * in the coordinate system of aFrame.  This effectively inverts all transforms
    * between this point and the root frame.
    *
    * @param aFrame The frame that acts as the coordinate space container.
    * @param aPoint The point, in the global space, to get in the frame-local space.
    * @return aPoint, expressed in aFrame's canonical coordinate space.
    */
-  static nsPoint TransformRootPointToFrame(nsIFrame* aFrame,
-                                           const nsPoint &aPt);
+  static nsPoint InvertTransformsToRoot(nsIFrame* aFrame,
+                                        const nsPoint &aPt);
 
   /**
    * Helper function that, given a rectangle and a matrix, returns the smallest
    * rectangle containing the image of the source rectangle.
    *
    * @param aBounds The rectangle to transform.
    * @param aMatrix The matrix to transform it with.
    * @param aFactor The number of app units per graphics unit.
@@ -699,18 +689,18 @@ public:
   static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback);
 
   class RectCallback {
   public:
     virtual void AddRect(const nsRect& aRect) = 0;
   };
 
   struct RectAccumulator : public RectCallback {
-    nsRect mResultRect;
-    nsRect mFirstRect;
+    nsRect       mResultRect;
+    nsRect       mFirstRect;
     bool mSeenFirstRect;
 
     RectAccumulator();
 
     virtual void AddRect(const nsRect& aRect);
   };
 
   struct RectListBuilder : public RectCallback {
@@ -718,43 +708,33 @@ public:
     nsresult          mRV;
 
     RectListBuilder(nsClientRectList* aList);
      virtual void AddRect(const nsRect& aRect);
   };
 
   static nsIFrame* GetContainingBlockForClientRect(nsIFrame* aFrame);
 
-  enum {
-    RECTS_ACCOUNT_FOR_TRANSFORMS = 0x01
-  };
   /**
    * Collect all CSS border-boxes associated with aFrame and its
    * continuations, "drilling down" through outer table frames and
    * some anonymous blocks since they're not real CSS boxes.
    * The boxes are positioned relative to aRelativeTo (taking scrolling
    * into account) and passed to the callback in frame-tree order.
    * If aFrame is null, no boxes are returned.
    * For SVG frames, returns one rectangle, the bounding box.
-   * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
-   * the boxes into aRelativeTo coordinates, transforms (including CSS
-   * and SVG transforms) are taken into account.
    */
   static void GetAllInFlowRects(nsIFrame* aFrame, nsIFrame* aRelativeTo,
-                                RectCallback* aCallback, PRUint32 aFlags = 0);
+                                RectCallback* aCallback);
 
   /**
    * Computes the union of all rects returned by GetAllInFlowRects. If
    * the union is empty, returns the first rect.
-   * If aFlags includes RECTS_ACCOUNT_FOR_TRANSFORMS, then when converting
-   * the boxes into aRelativeTo coordinates, transforms (including CSS
-   * and SVG transforms) are taken into account.
    */
-  static nsRect GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo,
-                                       PRUint32 aFlags = 0);
+  static nsRect GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo);
 
   enum {
     EXCLUDE_BLUR_SHADOWS = 0x01
   };
   /**
    * Takes a text-shadow array from the style properties of a given nsIFrame and
    * computes the union of those shadows along with the given initial rect.
    * If there are no shadows, the initial rect is returned.
--- a/layout/base/tests/test_bug677878.html
+++ b/layout/base/tests/test_bug677878.html
@@ -31,19 +31,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script type="application/javascript">
 SimpleTest.waitForExplicitFinish();
 runtests();
 
 function runtests() {
   function doClick() {
     document.getElementById("test2").addEventListener("mousedown", testFinish, true);
-    // Don't target the center because the center could actually be outside the
-    // viewport.
-    synthesizeMouse(document.getElementById("test2"), 10, 10, { type: "mousedown" })
+    synthesizeMouseAtCenter(document.getElementById("test2"), { type: "mousedown" })
   }
   setTimeout(doClick, 300);
 }
 
 function testFinish(event){
   ok(true, "We can still interact with the item after it is transformed");
   SimpleTest.finish();
 }
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -545,18 +545,18 @@ nsComboboxControlFrame::ReflowDropdown(n
 
 nsPoint
 nsComboboxControlFrame::GetCSSTransformTranslation()
 {
   nsIFrame* frame = this;
   bool is3DTransform = false;
   gfxMatrix transform;
   while (frame) {
-    nsIFrame* parent;
-    gfx3DMatrix ctm = frame->GetTransformMatrix(nsnull, &parent);
+    nsIFrame* parent = nsnull;
+    gfx3DMatrix ctm = frame->GetTransformMatrix(&parent);
     gfxMatrix matrix;
     if (ctm.Is2D(&matrix)) {
       transform = transform * matrix;
     } else {
       is3DTransform = true;
       break;
     }
     frame = parent;
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4536,31 +4536,29 @@ nsIFrame::InvalidateInternal(const nsRec
     InvalidateInternalAfterResize(r, 0, 0, aFlags);
     return;
   }
   
   InvalidateInternalAfterResize(aDamageRect, aX, aY, aFlags);
 }
 
 gfx3DMatrix
-nsIFrame::GetTransformMatrix(nsIFrame* aStopAtAncestor,
-                             nsIFrame** aOutAncestor)
+nsIFrame::GetTransformMatrix(nsIFrame **aOutAncestor)
 {
   NS_PRECONDITION(aOutAncestor, "Need a place to put the ancestor!");
 
   /* If we're transformed, we want to hand back the combination
    * transform/translate matrix that will apply our current transform, then
    * shift us to our parent.
    */
   if (IsTransformed()) {
     /* Compute the delta to the parent, which we need because we are converting
      * coordinates to our parent.
      */
-    NS_ASSERTION(nsLayoutUtils::GetCrossDocParentFrame(this),
-	             "Cannot transform the viewport frame!");
+    NS_ASSERTION(nsLayoutUtils::GetCrossDocParentFrame(this), "Cannot transform the viewport frame!");
     PRInt32 scaleFactor = PresContext()->AppUnitsPerDevPixel();
 
     gfx3DMatrix result =
       nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0),
                                                       scaleFactor, nsnull, aOutAncestor);
     nsPoint delta = GetOffsetToCrossDoc(*aOutAncestor);
     /* Combine the raw transform with a translation to our parent. */
     result *= gfx3DMatrix::Translation
@@ -4579,17 +4577,17 @@ nsIFrame::GetTransformMatrix(nsIFrame* a
    * we have to check to see if we have a parent.  If not, we'll set the
    * outparam to null (indicating that there's nothing left) and will hand back
    * the identity matrix.
    */
   if (!*aOutAncestor)
     return gfx3DMatrix();
   
   /* Keep iterating while the frame can't possibly be transformed. */
-  while (!(*aOutAncestor)->IsTransformed() && *aOutAncestor != aStopAtAncestor) {
+  while (!(*aOutAncestor)->IsTransformed()) {
     /* If no parent, stop iterating.  Otherwise, update the ancestor. */
     nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(*aOutAncestor);
     if (!parent)
       break;
 
     *aOutAncestor = parent;
   }
 
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1927,30 +1927,27 @@ public:
   /**
    * Get the "type" of the frame. May return a NULL atom pointer
    *
    * @see nsGkAtoms
    */
   virtual nsIAtom* GetType() const = 0;
 
   /**
-   * Returns a transformation matrix that converts points in this frame's
-   * coordinate space to points in some ancestor frame's coordinate space.
-   * The frame decides which ancestor it will use as a reference point.
-   * If this frame has no ancestor, aOutAncestor will be set to null.
+   * Returns a transformation matrix that converts points in this frame's coordinate space
+   * to points in some ancestor frame's coordinate space.  The frame decides which ancestor
+   * it will use as a reference point.  If this frame has no ancestor, aOutAncestor will be
+   * set to null.
    *
-   * @param aStopAtAncestor don't look further than aStopAtAncestor. If null,
-   *   all ancestors (including across documents) will be traversed.
-   * @param aOutAncestor [out] The ancestor frame the frame has chosen.  If
-   *   this frame has no ancestor, *aOutAncestor will be set to null.
-   * @return A gfxMatrix that converts points in this frame's coordinate space
-   *   into points in aOutAncestor's coordinate space.
+   * @param aOutAncestor [out] The ancestor frame the frame has chosen.  If this frame has no
+   *        ancestor, aOutAncestor will be nsnull.
+   * @return A gfxMatrix that converts points in this frame's coordinate space into
+   *         points in aOutAncestor's coordinate space.
    */
-  virtual gfx3DMatrix GetTransformMatrix(nsIFrame* aStopAtAncestor,
-                                         nsIFrame **aOutAncestor);
+  virtual gfx3DMatrix GetTransformMatrix(nsIFrame **aOutAncestor);
 
   /**
    * Bit-flags to pass to IsFrameOfType()
    */
   enum {
     eMathML =                           1 << 0,
     eSVG =                              1 << 1,
     eSVGForeignObject =                 1 << 2,
--- a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp
@@ -273,18 +273,17 @@ nsSVGForeignObjectFrame::PaintSVG(nsSVGR
                                           NS_RGBA(0,0,0,0), flags);
 
   gfx->Restore();
 
   return rv;
 }
 
 gfx3DMatrix
-nsSVGForeignObjectFrame::GetTransformMatrix(nsIFrame* aAncestor,
-                                            nsIFrame **aOutAncestor)
+nsSVGForeignObjectFrame::GetTransformMatrix(nsIFrame **aOutAncestor)
 {
   NS_PRECONDITION(aOutAncestor, "We need an ancestor to write to!");
 
   /* Set the ancestor to be the outer frame. */
   *aOutAncestor = nsSVGUtils::GetOuterSVGFrame(this);
   NS_ASSERTION(*aOutAncestor, "How did we end up without an outer frame?");
 
   /* Return the matrix back to the root, factoring in the x and y offsets. */
--- a/layout/svg/base/src/nsSVGForeignObjectFrame.h
+++ b/layout/svg/base/src/nsSVGForeignObjectFrame.h
@@ -88,18 +88,17 @@ public:
   virtual bool IsTransformed() const
   {
     return true;
   }
 
   /**
    * Foreign objects can return a transform matrix.
    */
-  virtual gfx3DMatrix GetTransformMatrix(nsIFrame* aAncestor,
-                                         nsIFrame **aOutAncestor);
+  virtual gfx3DMatrix GetTransformMatrix(nsIFrame **aOutAncestor);
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgForeignObjectFrame
    */
   virtual nsIAtom* GetType() const;