mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
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:
parent
cc9c3e69d4
commit
df90903560
@ -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();
|
||||
|
8
layout/base/crashtests/455171-4.html
Normal file
8
layout/base/crashtests/455171-4.html
Normal 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>
|
@ -128,3 +128,4 @@ load 444925-1.xul
|
||||
load 455063-1.html
|
||||
load 455063-2.html
|
||||
load 455063-3.html
|
||||
load 455171-4.html
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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.
|
||||
|
5
layout/generic/crashtests/455171-1.html
Normal file
5
layout/generic/crashtests/455171-1.html
Normal file
@ -0,0 +1,5 @@
|
||||
<html style="-moz-transform: translate(50px);">
|
||||
<head>
|
||||
<style>html::after { content:"b"; position: fixed;}</style>
|
||||
</head>
|
||||
<body></body></html>
|
7
layout/generic/crashtests/455171-2.html
Normal file
7
layout/generic/crashtests/455171-2.html
Normal 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>
|
2
layout/generic/crashtests/455171-3.html
Normal file
2
layout/generic/crashtests/455171-3.html
Normal file
@ -0,0 +1,2 @@
|
||||
<div style="-moz-transform: scale(2);">
|
||||
<iframe style="position: fixed;">
|
@ -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
|
||||
|
@ -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;
|
||||
|
6
layout/reftests/bugs/455171-5-ref.html
Normal file
6
layout/reftests/bugs/455171-5-ref.html
Normal 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>
|
9
layout/reftests/bugs/455171-5.html
Normal file
9
layout/reftests/bugs/455171-5.html
Normal 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>
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user