"ASSERTION: We should have padding here" with abs pos, overflow:scroll. r=roc a=blocking2.0:final

This commit is contained in:
Mats Palmgren
2010-11-09 22:14:05 +01:00
parent 280eff5b3d
commit f4570cb369
10 changed files with 97 additions and 63 deletions

View File

@@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mats Palmgren <matspal@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@@ -1652,12 +1653,6 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
aContainingBlockWidth, aContainingBlockHeight,
aBorder, aPadding);
// Since we are in reflow, we don't need to store these properties anymore
FrameProperties props(aPresContext->PropertyTable(), frame);
props.Delete(nsIFrame::UsedBorderProperty());
props.Delete(nsIFrame::UsedPaddingProperty());
props.Delete(nsIFrame::UsedMarginProperty());
// If this is the root frame, then set the computed width and
// height equal to the available space
if (nsnull == parentReflowState) {
@@ -1872,6 +1867,24 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
}
}
static void
UpdateProp(FrameProperties& aProps,
const FramePropertyDescriptor* aProperty,
PRBool aNeeded,
nsMargin& aNewValue)
{
if (aNeeded) {
nsMargin* propValue = static_cast<nsMargin*>(aProps.Get(aProperty));
if (propValue) {
*propValue = aNewValue;
} else {
aProps.Set(aProperty, new nsMargin(aNewValue));
}
} else {
aProps.Delete(aProperty);
}
}
void
nsCSSOffsetState::InitOffsets(nscoord aContainingBlockWidth,
const nsMargin *aBorder,
@@ -1879,16 +1892,28 @@ nsCSSOffsetState::InitOffsets(nscoord aContainingBlockWidth,
{
DISPLAY_INIT_OFFSETS(frame, this, aContainingBlockWidth, aBorder, aPadding);
// Since we are in reflow, we don't need to store these properties anymore
// unless they are dependent on width, in which case we store the new value.
nsPresContext *presContext = frame->PresContext();
FrameProperties props(presContext->PropertyTable(), frame);
props.Delete(nsIFrame::UsedBorderProperty());
// Compute margins from the specified margin style information. These
// become the default computed values, and may be adjusted below
// XXX fix to provide 0,0 for the top&bottom margins for
// inline-non-replaced elements
ComputeMargin(aContainingBlockWidth);
PRBool needMarginProp = ComputeMargin(aContainingBlockWidth);
// XXX We need to include 'auto' horizontal margins in this too!
// ... but if we did that, we'd need to fix nsFrame::GetUsedMargin
// to use it even when the margins are all zero (since sometimes
// they get treated as auto)
::UpdateProp(props, nsIFrame::UsedMarginProperty(), needMarginProp,
mComputedMargin);
const nsStyleDisplay *disp = frame->GetStyleDisplay();
PRBool isThemed = frame->IsThemed(disp);
nsPresContext *presContext = frame->PresContext();
PRBool needPaddingProp;
nsIntMargin widget;
if (isThemed &&
presContext->GetTheme()->GetWidgetPadding(presContext->DeviceContext(),
@@ -1898,15 +1923,14 @@ nsCSSOffsetState::InitOffsets(nscoord aContainingBlockWidth,
mComputedPadding.right = presContext->DevPixelsToAppUnits(widget.right);
mComputedPadding.bottom = presContext->DevPixelsToAppUnits(widget.bottom);
mComputedPadding.left = presContext->DevPixelsToAppUnits(widget.left);
needPaddingProp = PR_FALSE;
}
else if (aPadding) { // padding is an input arg
mComputedPadding.top = aPadding->top;
mComputedPadding.right = aPadding->right;
mComputedPadding.bottom = aPadding->bottom;
mComputedPadding.left = aPadding->left;
mComputedPadding = *aPadding;
needPaddingProp = frame->GetStylePadding()->IsWidthDependent();
}
else {
ComputePadding(aContainingBlockWidth);
needPaddingProp = ComputePadding(aContainingBlockWidth);
}
if (isThemed) {
@@ -1949,16 +1973,12 @@ nsCSSOffsetState::InitOffsets(nscoord aContainingBlockWidth,
// any padding or border.
nsSize size(frame->GetSize());
if (size.width == 0 || size.height == 0) {
mComputedPadding.left = 0;
mComputedPadding.right = 0;
mComputedBorderPadding.left = 0;
mComputedBorderPadding.right = 0;
mComputedPadding.top = 0;
mComputedPadding.bottom = 0;
mComputedBorderPadding.top = 0;
mComputedBorderPadding.bottom = 0;
mComputedPadding.SizeTo(0,0,0,0);
mComputedBorderPadding.SizeTo(0,0,0,0);
}
}
::UpdateProp(props, nsIFrame::UsedPaddingProperty(), needPaddingProp,
mComputedPadding);
}
// This code enforces section 10.3.3 of the CSS2 spec for this formula:
@@ -2152,12 +2172,13 @@ nsHTMLReflowState::CalcLineHeight(nsStyleContext* aStyleContext,
return lineHeight;
}
void
PRBool
nsCSSOffsetState::ComputeMargin(nscoord aContainingBlockWidth)
{
// If style style can provide us the margin directly, then use it.
const nsStyleMargin *styleMargin = frame->GetStyleMargin();
if (!styleMargin->GetMargin(mComputedMargin)) {
PRBool isWidthDependent = !styleMargin->GetMargin(mComputedMargin);
if (isWidthDependent) {
// We have to compute the value
mComputedMargin.left = nsLayoutUtils::
ComputeWidthDependentValue(aContainingBlockWidth,
@@ -2176,22 +2197,26 @@ nsCSSOffsetState::ComputeMargin(nscoord aContainingBlockWidth)
mComputedMargin.bottom = nsLayoutUtils::
ComputeWidthDependentValue(aContainingBlockWidth,
styleMargin->mMargin.GetBottom());
// XXX We need to include 'auto' horizontal margins in this too!
// ... but if we did that, we'd need to fix nsFrame::GetUsedMargin
// to use it even when the margins are all zero (since sometimes
// they get treated as auto)
frame->Properties().Set(nsIFrame::UsedMarginProperty(),
new nsMargin(mComputedMargin));
}
return isWidthDependent;
}
void
PRBool
nsCSSOffsetState::ComputePadding(nscoord aContainingBlockWidth)
{
// If style can provide us the padding directly, then use it.
const nsStylePadding *stylePadding = frame->GetStylePadding();
if (!stylePadding->GetPadding(mComputedPadding)) {
PRBool isWidthDependent = !stylePadding->GetPadding(mComputedPadding);
// a table row/col group, row/col doesn't have padding
// XXXldb Neither do border-collapse tables.
nsIAtom* frameType = frame->GetType();
if (nsGkAtoms::tableRowGroupFrame == frameType ||
nsGkAtoms::tableColGroupFrame == frameType ||
nsGkAtoms::tableRowFrame == frameType ||
nsGkAtoms::tableColFrame == frameType) {
mComputedPadding.SizeTo(0,0,0,0);
}
else if (isWidthDependent) {
// We have to compute the value
// clamp negative calc() results to 0
mComputedPadding.left = NS_MAX(0, nsLayoutUtils::
@@ -2209,22 +2234,8 @@ nsCSSOffsetState::ComputePadding(nscoord aContainingBlockWidth)
mComputedPadding.bottom = NS_MAX(0, nsLayoutUtils::
ComputeWidthDependentValue(aContainingBlockWidth,
stylePadding->mPadding.GetBottom()));
frame->Properties().Set(nsIFrame::UsedPaddingProperty(),
new nsMargin(mComputedPadding));
}
// a table row/col group, row/col doesn't have padding
// XXXldb Neither do border-collapse tables.
nsIAtom* frameType = frame->GetType();
if (nsGkAtoms::tableRowGroupFrame == frameType ||
nsGkAtoms::tableColGroupFrame == frameType ||
nsGkAtoms::tableRowFrame == frameType ||
nsGkAtoms::tableColFrame == frameType) {
mComputedPadding.top = 0;
mComputedPadding.right = 0;
mComputedPadding.bottom = 0;
mComputedPadding.left = 0;
}
return isWidthDependent;
}
void