Bug 703241. PresShell::DoScrollContentIntoView and PresShell::ScrollFrameRectIntoView should take transforms into account. r=matspal
This commit is contained in:
@@ -2964,8 +2964,8 @@ AccumulateFrameBounds(nsIFrame* aContainerFrame,
|
||||
nsAutoLineIterator& aLines,
|
||||
PRInt32& aCurLine)
|
||||
{
|
||||
nsRect frameBounds = aFrame->GetRect() +
|
||||
aFrame->GetParent()->GetOffsetTo(aContainerFrame);
|
||||
nsIFrame* frame = aFrame;
|
||||
nsRect frameBounds = nsRect(nsPoint(0, 0), aFrame->GetSize());
|
||||
|
||||
// If this is an inline frame and either the bounds height is 0 (quirks
|
||||
// layout model) or aUseWholeLineHeightForInlines is set, we need to
|
||||
@@ -3001,7 +3001,8 @@ AccumulateFrameBounds(nsIFrame* aContainerFrame,
|
||||
|
||||
if (NS_SUCCEEDED(aLines->GetLine(index, &trash1, &trash2,
|
||||
lineBounds, &trash3))) {
|
||||
lineBounds += f->GetOffsetTo(aContainerFrame);
|
||||
frameBounds += frame->GetOffsetTo(f);
|
||||
frame = f;
|
||||
if (lineBounds.y < frameBounds.y) {
|
||||
frameBounds.height = frameBounds.YMost() - lineBounds.y;
|
||||
frameBounds.y = lineBounds.y;
|
||||
@@ -3012,14 +3013,17 @@ AccumulateFrameBounds(nsIFrame* aContainerFrame,
|
||||
}
|
||||
}
|
||||
|
||||
nsRect transformedBounds = nsLayoutUtils::TransformFrameRectToAncestor(frame,
|
||||
frameBounds, aContainerFrame);
|
||||
|
||||
if (aHaveRect) {
|
||||
// We can't use nsRect::UnionRect since it drops empty rects on
|
||||
// the floor, and we need to include them. (Thus we need
|
||||
// aHaveRect to know when to drop the initial value on the floor.)
|
||||
aRect.UnionRectEdges(aRect, frameBounds);
|
||||
aRect.UnionRectEdges(aRect, transformedBounds);
|
||||
} else {
|
||||
aHaveRect = true;
|
||||
aRect = frameBounds;
|
||||
aRect = transformedBounds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3315,8 +3319,14 @@ PresShell::ScrollFrameRectIntoView(nsIFrame* aFrame,
|
||||
break;
|
||||
}
|
||||
}
|
||||
rect += container->GetPosition();
|
||||
nsIFrame* parent = container->GetParent();
|
||||
nsIFrame* parent;
|
||||
if (container->IsTransformed()) {
|
||||
container->GetTransformMatrix(nsnull, &parent);
|
||||
rect = nsLayoutUtils::TransformFrameRectToAncestor(container, rect, parent);
|
||||
} else {
|
||||
rect += container->GetPosition();
|
||||
parent = container->GetParent();
|
||||
}
|
||||
if (!parent && !(aFlags & nsIPresShell::SCROLL_NO_PARENT_FRAMES)) {
|
||||
nsPoint extraOffset(0,0);
|
||||
parent = nsLayoutUtils::GetCrossDocParentFrame(container, &extraOffset);
|
||||
|
||||
@@ -40,6 +40,29 @@
|
||||
<div style='height:400px;'></div>">
|
||||
</iframe>
|
||||
</div>
|
||||
<div id="c5" style="overflow-y:scroll; width:200px; height:200px; position:absolute; top:400px; left:0;">
|
||||
<div style="-moz-transform:translateY(400px); transform:translateY(400px)">
|
||||
<span id="target5" style="display:inline-block; vertical-align:top; height:20px;">target</span>
|
||||
</div>
|
||||
<div style="height:800px;"></div>
|
||||
</div>
|
||||
<div id="c6" style="overflow-y:scroll; width:200px; height:200px; position:absolute; top:400px; left:200px;">
|
||||
<div style="height:200px"></div>
|
||||
<div style="height:100px; -moz-transform:scale(2); transform:scale(2)">
|
||||
<span id="target6" style="display:inline-block; vertical-align:top; height:20px;">target</span>
|
||||
</div>
|
||||
<div style="height:800px;"></div>
|
||||
</div>
|
||||
<div id="c7" style="overflow-y:scroll; width:200px; height:200px; position:absolute; top:400px; left:400px;">
|
||||
<div style="overflow:auto; height:200px; -moz-transform:translateY(400px); transform:translateY(400px)">
|
||||
<div style="height:200px;"></div>
|
||||
<div>
|
||||
<span id="target7" style="display:inline-block; vertical-align:top; height:20px;">target</span>
|
||||
</div>
|
||||
<div style="height:800px;"></div>
|
||||
</div>
|
||||
<div style="height:800px;"></div>
|
||||
</div>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
@@ -101,6 +124,18 @@ function doTest() {
|
||||
// visible.
|
||||
testCollapsed("4", -1, 1000, 400);
|
||||
|
||||
// Test that scrolling a translated element into view takes
|
||||
// account of the transform.
|
||||
testCollapsed("5", 0, 0, 400);
|
||||
|
||||
// Test that scrolling a scaled element into view takes
|
||||
// account of the transform.
|
||||
testCollapsed("6", 0, 0, 150);
|
||||
|
||||
// Test that scrolling an element with a translated, scrolling container
|
||||
// into view takes account of the transform.
|
||||
testCollapsed("7", 0, 0, 400);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
||||
@@ -1960,7 +1960,11 @@ public:
|
||||
* @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.
|
||||
* this frame has no ancestor, *aOutAncestor will be set to null. If
|
||||
* this frame is not a root frame, then *aOutAncestor will be in the same
|
||||
* document as this frame. If this frame IsTransformed(), then *aOutAncestor
|
||||
* will be the parent frame (if not preserve-3d) or the nearest non-transformed
|
||||
* ancestor (if preserve-3d).
|
||||
* @return A gfxMatrix that converts points in this frame's coordinate space
|
||||
* into points in aOutAncestor's coordinate space.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user