mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-13 19:41:49 +00:00
Bug 724978: Make nsColumnSetFrame handle absolutely positioned children without crashing. [p=ehsan, r=fantasai]
This commit is contained in:
parent
999eeb2111
commit
aa7f8f28f4
234
layout/generic/crashtests/724978.xhtml
Normal file
234
layout/generic/crashtests/724978.xhtml
Normal file
@ -0,0 +1,234 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>Multi-column Layout: AbsPos Pagination (Interlaced Dynamic Height)</title>
|
||||
<link rel="author" title="Elika J. Etemad" href="http://fantasai.inkedblade.net/contact"/>
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/visudet.html#the-height-property"/>
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/syndata.html#length-units"/>
|
||||
<style type="text/css">
|
||||
html {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.container {
|
||||
background: red;
|
||||
height: 24pt;
|
||||
position: relative;
|
||||
-moz-column-count: 2;
|
||||
-moz-column-gap: 0;
|
||||
}
|
||||
.overflow {
|
||||
width: 10pt;
|
||||
border-bottom: lime 8px solid;
|
||||
top: 0;
|
||||
}
|
||||
.following {
|
||||
position: relative;
|
||||
background: white;
|
||||
width: 100pt;
|
||||
}
|
||||
#colset {
|
||||
padding-top: 1px;
|
||||
width: 300pt;
|
||||
height: 2in;
|
||||
-moz-column-count: 3;
|
||||
-moz-column-gap: 0;
|
||||
border: silver 2pt;
|
||||
border-style: none solid;
|
||||
}
|
||||
#redline {
|
||||
width: 303pt;
|
||||
border-top: 8px solid red;
|
||||
margin-top: -1in;
|
||||
position: relative;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.ocontainer {
|
||||
height: 0;
|
||||
position: relative;
|
||||
-moz-column-count: 2;
|
||||
-moz-column-gap: 0;
|
||||
}
|
||||
.o1 { /* 3rd col */
|
||||
height: 10in;
|
||||
}
|
||||
.a1 { /* 1st col */
|
||||
position: absolute;
|
||||
height: 2in;
|
||||
width: 33pt;
|
||||
}
|
||||
.a2 { /* 2nd col */
|
||||
position: absolute;
|
||||
height: 6in;
|
||||
width: 25pt;
|
||||
margin-left: 25pt;
|
||||
}
|
||||
.a3 { /* 3rd col */
|
||||
position: absolute;
|
||||
height: 10in;
|
||||
margin-left: 10pt;
|
||||
}
|
||||
.a4 { /* 2nd col */
|
||||
width: 25pt;
|
||||
height: 6in;
|
||||
}
|
||||
|
||||
.b1 { /* 3rd col */
|
||||
position: absolute;
|
||||
height: 672pt;
|
||||
margin-left: 20pt;
|
||||
}
|
||||
.b2 { /* 2nd col */
|
||||
position: absolute;
|
||||
height: 384pt;
|
||||
width: 25pt;
|
||||
margin-left: 50pt;
|
||||
}
|
||||
.b3 { /* 3rd col */
|
||||
position: absolute;
|
||||
height: 672pt;
|
||||
margin-left: 30pt;
|
||||
}
|
||||
.b4 { /* 1st col, but no border */
|
||||
position: absolute;
|
||||
height: 96pt;
|
||||
border-bottom: none;
|
||||
}
|
||||
.b4 .child1 { /* 1st col */
|
||||
position: absolute;
|
||||
height: 200%;
|
||||
width: 33pt;
|
||||
margin-left: 33pt;
|
||||
}
|
||||
.b4 .child2 { /* 3rd col */
|
||||
height: 672pt;
|
||||
margin-left: 40pt;
|
||||
|
||||
}
|
||||
.b5 { /* 1st col */
|
||||
position: absolute;
|
||||
height: 96pt;
|
||||
width: 34pt;
|
||||
margin-left: 66pt;
|
||||
}
|
||||
.b6 { /* 3rd col */
|
||||
height: 672pt;
|
||||
margin-left: 50pt;
|
||||
}
|
||||
|
||||
.c1 { /* 3rd col */
|
||||
position: absolute;
|
||||
height: 6in;
|
||||
margin-left: 60pt;
|
||||
}
|
||||
.c2 { /* 2nd col */
|
||||
position: absolute;
|
||||
height: 2in;
|
||||
width: 25pt;
|
||||
margin-left: 75pt;
|
||||
}
|
||||
.c3 { /* 3rd col */
|
||||
position: absolute;
|
||||
height: 6in;
|
||||
margin-left: 70pt;
|
||||
}
|
||||
.c4 { /* 3rd col */
|
||||
height: 6in;
|
||||
width: 20pt;
|
||||
margin-left: 80pt;
|
||||
}
|
||||
|
||||
.f1 {
|
||||
margin-top: -48pt;
|
||||
height: 96pt;
|
||||
margin-bottom: 96pt;
|
||||
}
|
||||
.f2 {
|
||||
margin-top: -24pt;
|
||||
height: 48pt;
|
||||
}
|
||||
|
||||
.centerline {
|
||||
margin: 0 auto;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 6in;
|
||||
background: aqua;
|
||||
}
|
||||
|
||||
#dynamo {
|
||||
background: transparent;
|
||||
border-bottom: 8px solid orange;
|
||||
z-index: 10;
|
||||
height: 384pt;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body onload="document.getElementById('dynamo').style.height = '96pt';
|
||||
document.getElementById('dynamo').offsetHeight;
|
||||
document.getElementById('dynamo').style.height = '672pt';
|
||||
document.getElementById('dynamo').offsetHeight;
|
||||
document.getElementById('dynamo').style.height = '96pt';
|
||||
document.getElementById('dynamo').offsetHeight;
|
||||
document.getElementById('dynamo').style.height = '384pt';
|
||||
document.getElementById('dynamo').offsetHeight;
|
||||
document.getElementById('dynamo').style.height = '3000pt';
|
||||
document.getElementById('dynamo').offsetHeight;
|
||||
document.getElementById('dynamo').style.height = '96pt';
|
||||
document.getElementById('dynamo').offsetHeight;
|
||||
document.getElementById('dynamo').style.height = '384pt';
|
||||
document.getElementById('dynamo').offsetHeight;
|
||||
document.getElementById('dynamo').style.height = '672pt';
|
||||
document.getElementById('dynamo').offsetHeight;
|
||||
document.getElementById('dynamo').style.height = '384pt';
|
||||
document.getElementById('dynamo').offsetHeight;
|
||||
document.getElementById('dynamo').style.height = '96pt';
|
||||
document.getElementById('dynamo').offsetHeight;
|
||||
document.getElementById('dynamo').style.height = '384pt';
|
||||
document.documentElement.className = ''
|
||||
">
|
||||
<div id="colset">
|
||||
<div>
|
||||
<div class="ocontainer">
|
||||
<div class="centerline"></div>
|
||||
<div class="overflow o1"></div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="overflow a1"></div>
|
||||
<div class="overflow a2"></div>
|
||||
<div class="overflow a3"></div>
|
||||
<div class="overflow a4"></div>
|
||||
</div>
|
||||
<div class="ocontainer">
|
||||
<div id="dynamo" class="centerline"></div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="overflow b1"></div>
|
||||
<div class="overflow b2"></div>
|
||||
<div class="overflow b3"></div>
|
||||
<div class="overflow b4">
|
||||
<div class="overflow child1"></div>
|
||||
<div class="overflow child2"></div>
|
||||
</div>
|
||||
<div class="overflow b5"></div>
|
||||
<div class="overflow b6"></div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="following f1">
|
||||
</p>
|
||||
<div class="container">
|
||||
<div class="overflow c1"></div>
|
||||
<div class="overflow c2"></div>
|
||||
<div class="overflow c3"></div>
|
||||
<div class="overflow c4"></div>
|
||||
</div>
|
||||
<div class="following f2"></div>
|
||||
</div>
|
||||
<div id="redline"></div>
|
||||
</body>
|
||||
</html>
|
@ -425,6 +425,7 @@ load 683712.html
|
||||
load text-overflow-bug713610.html
|
||||
load 700031.xhtml
|
||||
load 718516.html
|
||||
load 724978.xhtml
|
||||
load first-letter-638937.html
|
||||
load first-letter-638937-2.html
|
||||
load 734777.html
|
||||
|
@ -64,6 +64,12 @@ public:
|
||||
return nsContainerFrame::StealFrame(aPresContext, aChild, true);
|
||||
}
|
||||
|
||||
virtual bool IsFrameOfType(uint32_t aFlags) const
|
||||
{
|
||||
return nsContainerFrame::IsFrameOfType(aFlags &
|
||||
~(nsIFrame::eCanContainOverflowContainers));
|
||||
}
|
||||
|
||||
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsDisplayListSet& aLists) MOZ_OVERRIDE;
|
||||
@ -132,7 +138,8 @@ protected:
|
||||
* style. This function will also be responsible for implementing
|
||||
* the state machine that controls column balancing.
|
||||
*/
|
||||
ReflowConfig ChooseColumnStrategy(const nsHTMLReflowState& aReflowState);
|
||||
ReflowConfig ChooseColumnStrategy(const nsHTMLReflowState& aReflowState,
|
||||
bool aForceAuto);
|
||||
|
||||
/**
|
||||
* Reflow column children. Returns true iff the content that was reflowed
|
||||
@ -259,10 +266,14 @@ NS_IMETHODIMP
|
||||
nsColumnSetFrame::SetInitialChildList(ChildListID aListID,
|
||||
nsFrameList& aChildList)
|
||||
{
|
||||
if (aListID == kAbsoluteList) {
|
||||
return nsContainerFrame::SetInitialChildList(aListID, aChildList);
|
||||
}
|
||||
|
||||
NS_ASSERTION(aListID == kPrincipalList,
|
||||
"Only default child list supported");
|
||||
NS_ASSERTION(aChildList.OnlyChild(),
|
||||
"initial child list must have exactly one child");
|
||||
"initial child list must have exaisRevertingctly one child");
|
||||
// Queue up the frames for the content frame
|
||||
return nsContainerFrame::SetInitialChildList(kPrincipalList, aChildList);
|
||||
}
|
||||
@ -308,7 +319,8 @@ GetColumnGap(nsColumnSetFrame* aFrame,
|
||||
}
|
||||
|
||||
nsColumnSetFrame::ReflowConfig
|
||||
nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState)
|
||||
nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState,
|
||||
bool aForceAuto = false)
|
||||
{
|
||||
const nsStyleColumn* colStyle = StyleColumn();
|
||||
nscoord availContentWidth = GetAvailableContentWidth(aReflowState);
|
||||
@ -326,7 +338,8 @@ nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState)
|
||||
int32_t numColumns = colStyle->mColumnCount;
|
||||
|
||||
// If column-fill is set to 'balance', then we want to balance the columns.
|
||||
const bool isBalancing = colStyle->mColumnFill == NS_STYLE_COLUMN_FILL_BALANCE;
|
||||
const bool isBalancing = colStyle->mColumnFill == NS_STYLE_COLUMN_FILL_BALANCE
|
||||
&& !aForceAuto;
|
||||
if (isBalancing) {
|
||||
const uint32_t MAX_NESTED_COLUMN_BALANCING = 2;
|
||||
uint32_t cnt = 0;
|
||||
@ -404,6 +417,16 @@ nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState)
|
||||
// This is the case when the column-fill property is set to 'auto'.
|
||||
// No balancing, so don't limit the column count
|
||||
numColumns = INT32_MAX;
|
||||
|
||||
// XXX_jwir3: If a page's height is set to 0, we could continually
|
||||
// create continuations, resulting in an infinite loop, since
|
||||
// no progress is ever made. This is an issue with the spec
|
||||
// (css3-multicol, css3-page, and css3-break) that is
|
||||
// unresolved as of 27 Feb 2013. For the time being, we set this
|
||||
// to have a minimum of 1 css px. Once a resolution is made
|
||||
// on what minimum to have for a page height, we may need to
|
||||
// change this value to match the appropriate spec(s).
|
||||
colHeight = std::max(colHeight, nsPresContext::CSSPixelsToAppUnits(1));
|
||||
}
|
||||
|
||||
#ifdef DEBUG_roc
|
||||
@ -611,7 +634,7 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
|
||||
if (aUnboundedLastColumn && columnCount == aConfig.mBalanceColCount - 1) {
|
||||
availSize.height = GetAvailableContentHeight(aReflowState);
|
||||
}
|
||||
|
||||
|
||||
if (reflowNext)
|
||||
child->AddStateBits(NS_FRAME_IS_DIRTY);
|
||||
|
||||
@ -919,9 +942,8 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext,
|
||||
// children, we were balancing and we overflowed in the block direction.
|
||||
do {
|
||||
if (colData.mShouldRevertToAuto) {
|
||||
config = ChooseColumnStrategy(aReflowState);
|
||||
config = ChooseColumnStrategy(aReflowState, true);
|
||||
isBalancing = false;
|
||||
config.mBalanceColCount = INT32_MAX;
|
||||
}
|
||||
|
||||
bool feasible = ReflowChildren(aDesiredSize, aReflowState,
|
||||
@ -1067,10 +1089,7 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext,
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
// XXXjwir3: This call should be replaced with FinishWithAbsoluteFrames
|
||||
// when bug 724978 is fixed and nsColumnSetFrame is a full absolute
|
||||
// container.
|
||||
FinishAndStoreOverflow(&aDesiredSize);
|
||||
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus, false);
|
||||
|
||||
aDesiredSize.mCarriedOutBottomMargin = carriedOutBottomMargin;
|
||||
|
||||
@ -1103,8 +1122,12 @@ NS_IMETHODIMP
|
||||
nsColumnSetFrame::AppendFrames(ChildListID aListID,
|
||||
nsFrameList& aFrameList)
|
||||
{
|
||||
NS_NOTREACHED("AppendFrames not supported");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (aListID == kAbsoluteList) {
|
||||
return nsContainerFrame::AppendFrames(aListID, aFrameList);
|
||||
}
|
||||
|
||||
NS_ERROR("unexpected child list");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1112,14 +1135,22 @@ nsColumnSetFrame::InsertFrames(ChildListID aListID,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsFrameList& aFrameList)
|
||||
{
|
||||
NS_NOTREACHED("InsertFrames not supported");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (aListID == kAbsoluteList) {
|
||||
return nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
|
||||
}
|
||||
|
||||
NS_ERROR("unexpected child list");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsColumnSetFrame::RemoveFrame(ChildListID aListID,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
NS_NOTREACHED("RemoveFrame not supported");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (aListID == kAbsoluteList) {
|
||||
return nsContainerFrame::RemoveFrame(aListID, aOldFrame);
|
||||
}
|
||||
|
||||
NS_ERROR("unexpected child list");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
@ -4196,9 +4196,10 @@ void
|
||||
nsFrame::FinishReflowWithAbsoluteFrames(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
nsReflowStatus& aStatus,
|
||||
bool aConstrainHeight)
|
||||
{
|
||||
ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus, aConstrainHeight);
|
||||
|
||||
FinishAndStoreOverflow(&aDesiredSize);
|
||||
}
|
||||
@ -4207,7 +4208,8 @@ void
|
||||
nsFrame::ReflowAbsoluteFrames(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus)
|
||||
nsReflowStatus& aStatus,
|
||||
bool aConstrainHeight)
|
||||
{
|
||||
if (HasAbsolutelyPositionedChildren()) {
|
||||
nsAbsoluteContainingBlock* absoluteContainer = GetAbsoluteContainingBlock();
|
||||
@ -4228,7 +4230,7 @@ nsFrame::ReflowAbsoluteFrames(nsPresContext* aPresContext,
|
||||
|
||||
absoluteContainer->Reflow(container, aPresContext, aReflowState, aStatus,
|
||||
containingBlockWidth, containingBlockHeight,
|
||||
true, true, true, // XXX could be optimized
|
||||
aConstrainHeight, true, true, // XXX could be optimized
|
||||
&aDesiredSize.mOverflowAreas);
|
||||
}
|
||||
}
|
||||
|
@ -336,11 +336,13 @@ public:
|
||||
void ReflowAbsoluteFrames(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
nsReflowStatus& aStatus,
|
||||
bool aConstrainHeight = true);
|
||||
void FinishReflowWithAbsoluteFrames(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aStatus);
|
||||
nsReflowStatus& aStatus,
|
||||
bool aConstrainHeight = true);
|
||||
virtual bool CanContinueTextRun() const;
|
||||
|
||||
virtual bool UpdateOverflow();
|
||||
|
@ -13,8 +13,6 @@ fuzzy-if(gtk2Widget,1,8) == select-1.html select-1-ref.html
|
||||
fuzzy-if(gtk2Widget,1,8) == select-1-dynamic.html select-1-ref.html
|
||||
== select-2.html select-2-ref.html
|
||||
fuzzy-if(gtk2Widget,1,19) fuzzy-if(Android||B2G,17,726) == select-3.html select-3-ref.html
|
||||
|
||||
# Fails due to bug 724978. Should be re-enabled once this is fixed.
|
||||
fails == multi-column-1.html multi-column-1-ref.html
|
||||
== multi-column-1.html multi-column-1-ref.html
|
||||
== button-1.html button-1-ref.html
|
||||
== button-2.html button-2-ref.html
|
||||
|
@ -683,13 +683,11 @@ skip-if(B2G) == 378937-1.html 378937-1-ref.html
|
||||
== 379316-1.html 379316-1-ref.html
|
||||
skip-if(B2G) fails-if(Android) random-if(cocoaWidget) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(gtk2Widget,1,191) == 379316-2.html 379316-2-ref.html # bug 379786
|
||||
== 379328-1.html 379328-1-ref.html
|
||||
# The next set of reftests all fail until bug 724978 has been fixed, and the
|
||||
# overflow container ability of nsColumnSetFrame is restored.
|
||||
fails == 379349-1a.xhtml 379349-1-ref.xhtml
|
||||
fails == 379349-1b.xhtml 379349-1-ref.xhtml
|
||||
fails == 379349-1c.xhtml 379349-1-ref.xhtml
|
||||
fails == 379349-2a.xhtml 379349-2-ref.xhtml
|
||||
fails == 379349-2b.xhtml 379349-2-ref.xhtml
|
||||
== 379349-1a.xhtml 379349-1-ref.xhtml
|
||||
== 379349-1b.xhtml 379349-1-ref.xhtml
|
||||
== 379349-1c.xhtml 379349-1-ref.xhtml
|
||||
== 379349-2a.xhtml 379349-2-ref.xhtml
|
||||
== 379349-2b.xhtml 379349-2-ref.xhtml
|
||||
skip-if(B2G) == 379349-3a.xhtml 379349-3-ref.xhtml
|
||||
skip-if(B2G) == 379349-3b.xhtml 379349-3-ref.xhtml
|
||||
== 379361-1.html 379361-1-ref.html
|
||||
|
Loading…
x
Reference in New Issue
Block a user