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 83422 d07146e9c62e01d8db712beca8992deb489dab50
parent 83421 0ce4de4491f8d7d86d0acbf98fde5651a602e8d8
child 83423 0b1a809be3bde1bd0230a33dcdcccac5059fea5d
push id4402
push userphilringnalda@gmail.com
push dateWed, 28 Dec 2011 04:48:55 +0000
treeherdermozilla-inbound@d07146e9c62e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs591718
milestone12.0a1
backs outdc7c7734ec7c8067ae0dee280077b1625d5b79d0
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
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;