Handle some additional codepaths for position: fixed elements inside elements with -moz-transform. (Bug 455171) r+sr=bzbarsky a=blocking1.9.1+

This commit is contained in:
L. David Baron 2008-11-25 13:27:54 -08:00
parent cc9c3e69d4
commit df90903560
14 changed files with 78 additions and 3 deletions

View File

@ -2515,7 +2515,8 @@ GetParentFrameToScroll(nsPresContext* aPresContext, nsIFrame* aFrame)
if (!aPresContext || !aFrame)
return nsnull;
if (aFrame->GetStyleDisplay()->mPosition == NS_STYLE_POSITION_FIXED)
if (aFrame->GetStyleDisplay()->mPosition == NS_STYLE_POSITION_FIXED &&
nsLayoutUtils::IsReallyFixedPos(aFrame))
return aPresContext->GetPresShell()->GetRootScrollFrame();
return aFrame->GetParent();

View File

@ -0,0 +1,8 @@
<!DOCTYPE html>
<title>Testcase, bug 455171</title>
<div style="-moz-transform: translate(50px, 50px);"><div id="foo" style="position: fixed;"></div></div>
<script type="text/javascript">
var foo = document.getElementById("foo");
var h = foo.offsetHeight;
foo.parentNode.removeChild(foo);
</script>

View File

@ -128,3 +128,4 @@ load 444925-1.xul
load 455063-1.html
load 455063-2.html
load 455063-3.html
load 455171-4.html

View File

@ -1782,7 +1782,11 @@ GetChildListNameFor(nsIFrame* aChildFrame)
if (NS_STYLE_POSITION_ABSOLUTE == disp->mPosition) {
listName = nsGkAtoms::absoluteList;
} else if (NS_STYLE_POSITION_FIXED == disp->mPosition) {
listName = nsGkAtoms::fixedList;
if (nsLayoutUtils::IsReallyFixedPos(aChildFrame)) {
listName = nsGkAtoms::fixedList;
} else {
listName = nsGkAtoms::absoluteList;
}
#ifdef MOZ_XUL
} else if (NS_STYLE_DISPLAY_POPUP == disp->mDisplay) {
// Out-of-flows that are DISPLAY_POPUP must be kids of the root popup set

View File

@ -3029,6 +3029,18 @@ nsLayoutUtils::GetDeviceContextForScreenInfo(nsIDocShell* aDocShell)
return nsnull;
}
/* static */ PRBool
nsLayoutUtils::IsReallyFixedPos(nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame->GetParent(),
"IsReallyFixedPos called on frame not in tree");
NS_PRECONDITION(aFrame->GetStyleDisplay()->mPosition ==
NS_STYLE_POSITION_FIXED,
"IsReallyFixedPos called on non-'position:fixed' frame");
return aFrame->GetParent()->GetType() == nsGkAtoms::viewportFrame;
}
nsSetAttrRunnable::nsSetAttrRunnable(nsIContent* aContent, nsIAtom* aAttrName,
const nsAString& aValue)
: mContent(aContent),

View File

@ -918,6 +918,14 @@ public:
static nsIDeviceContext*
GetDeviceContextForScreenInfo(nsIDocShell* aDocShell);
/**
* Some frames with 'position: fixed' (nsStylePosition::mDisplay ==
* NS_STYLE_POSITION_FIXED) are not really fixed positioned, since
* they're inside an element with -moz-transform. This function says
* whether such an element is a real fixed-pos element.
*/
static PRBool IsReallyFixedPos(nsIFrame* aFrame);
/**
* Indicates if the nsIFrame::GetUsedXXX assertions in nsFrame.cpp should
* disabled.

View File

@ -0,0 +1,5 @@
<html style="-moz-transform: translate(50px);">
<head>
<style>html::after { content:"b"; position: fixed;}</style>
</head>
<body></body></html>

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<head></head>
<body>
<div style="-moz-transform: translate(50px, 50px);"><div style="position: fixed;"></div></div>
</body>
</html>

View File

@ -0,0 +1,2 @@
<div style="-moz-transform: scale(2);">
<iframe style="position: fixed;">

View File

@ -158,3 +158,6 @@ load 438259-1.html
load 438509-1.html
load 448903-1.html
load 451334-1.html
load 455171-1.html
load 455171-2.html
load 455171-3.html

View File

@ -890,6 +890,8 @@ static PRBool AreAllEarlierInFlowFramesEmpty(nsIFrame* aFrame,
// Calculate the hypothetical box that the element would have if it were in
// the flow. The values returned are relative to the padding edge of the
// absolute containing block
// aContainingBlock is the placeholder's containing block (XXX rename it?)
// cbrs->frame is the actual containing block
void
nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
nsIFrame* aPlaceholderFrame,
@ -1087,7 +1089,9 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
// the conversion incorrectly; specifically we want to ignore any scrolling
// that may have happened;
nsPoint cbOffset;
if (mStyleDisplay->mPosition == NS_STYLE_POSITION_FIXED) {
if (mStyleDisplay->mPosition == NS_STYLE_POSITION_FIXED &&
// Exclude cases inside -moz-transform where fixed is like absolute.
nsLayoutUtils::IsReallyFixedPos(frame)) {
// In this case, cbrs->frame will always be an ancestor of
// aContainingBlock, so can just walk our way up the frame tree.
// Make sure to not add positions of frames whose parent is a
@ -1101,6 +1105,10 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
aContainingBlock = aContainingBlock->GetParent();
} while (aContainingBlock != cbrs->frame);
} else {
// XXXldb We need to either ignore scrolling for the absolute
// positioning case too (and take the incompatibility) or figure out
// how to make these positioned elements actually *move* when we
// scroll, and thus avoid the resulting incremental reflow bugs.
cbOffset = aContainingBlock->GetOffsetTo(cbrs->frame);
}
aHypotheticalBox.mLeft += cbOffset.x;

View File

@ -0,0 +1,6 @@
<!DOCTYPE HTML>
<title>Testcase for hypothetical box calculation for position:fixed inside -moz-transform</title>
<style type="text/css">
html, body { margin: 0; padding: 0; }
</style>
<div style="margin: 30px 0 0 10px; height: 10px; width: 10px; background: blue"></div>

View File

@ -0,0 +1,9 @@
<!DOCTYPE HTML>
<title>Testcase for hypothetical box calculation for position:fixed inside -moz-transform</title>
<style type="text/css">
html, body { margin: 0; padding: 0; }
</style>
<div style="-moz-transform: translate(10px,10px)">
<div style="height: 20px"></div>
<div style="position: fixed; height: 10px; width: 10px; background: blue"></div>
</div>

View File

@ -938,6 +938,7 @@ fails == 441259-2.html 441259-2-ref.html # bug 441400
== 454361.html about:blank
== 455105-1.html 455105-ref.html
== 455105-2.html 455105-ref.html
== 455171-5.html 455171-5-ref.html
== 455280-1.xhtml 455280-1-ref.xhtml
fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 456147.xul 456147-ref.html # bug 456147, but not caused by it
== 456330-1.gif 456330-1-ref.png