mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 851379 part 2: Make ComputeMargin, ComputePadding, and InitOffsets take a horizontal *and* vertical percent basis, so that we can resolve vertical margins and padding against containing block *height* in flex items. r=mats
This commit is contained in:
parent
cee9a2f474
commit
a0d53d01a9
@ -1839,8 +1839,17 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
|
||||
// If this is the root frame, then set the computed width and
|
||||
// height equal to the available space
|
||||
if (nullptr == parentReflowState) {
|
||||
MOZ_ASSERT(!frame->IsFlexItem(),
|
||||
"the root frame can't be a flex item, since being a flex item "
|
||||
"requires that you have a parent");
|
||||
// Note that we pass the containing block width as the percent basis for
|
||||
// both horizontal *and* vertical margins & padding, in our InitOffsets
|
||||
// call here. This is correct per CSS 2.1; it'd be incorrect for e.g. flex
|
||||
// items and grid items, but the root frame can't be either of those.
|
||||
// XXXldb This doesn't mean what it used to!
|
||||
InitOffsets(aContainingBlockWidth, aFrameType, aBorder, aPadding);
|
||||
InitOffsets(aContainingBlockWidth,
|
||||
aContainingBlockWidth,
|
||||
aFrameType, aBorder, aPadding);
|
||||
// Override mComputedMargin since reflow roots start from the
|
||||
// frame's boundary, which is inside the margin.
|
||||
mComputedMargin.SizeTo(0, 0, 0, 0);
|
||||
@ -1887,7 +1896,20 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
InitOffsets(aContainingBlockWidth, aFrameType, aBorder, aPadding);
|
||||
// Flex containers resolve percentage margin & padding against the flex
|
||||
// container's height (which is the containing block height).
|
||||
// For everything else: the CSS21 spec requires that margin and padding
|
||||
// percentage values are calculated with respect to the *width* of the
|
||||
// containing block, even for margin & padding in the vertical axis.
|
||||
// XXX Might need to also pass the CB height (not width) for page boxes,
|
||||
// too, if we implement them.
|
||||
nscoord verticalPercentBasis = aContainingBlockWidth;
|
||||
if (frame->IsFlexItem()) {
|
||||
verticalPercentBasis =
|
||||
aContainingBlockHeight == NS_AUTOHEIGHT ? 0 : aContainingBlockHeight;
|
||||
}
|
||||
InitOffsets(aContainingBlockWidth, verticalPercentBasis,
|
||||
aFrameType, aBorder, aPadding);
|
||||
|
||||
const nsStyleCoord &height = mStylePosition->mHeight;
|
||||
nsStyleUnit heightUnit = height.GetUnit();
|
||||
@ -2110,12 +2132,14 @@ UpdateProp(FrameProperties& aProps,
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSOffsetState::InitOffsets(nscoord aContainingBlockWidth,
|
||||
nsCSSOffsetState::InitOffsets(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis,
|
||||
nsIAtom* aFrameType,
|
||||
const nsMargin *aBorder,
|
||||
const nsMargin *aPadding)
|
||||
{
|
||||
DISPLAY_INIT_OFFSETS(frame, this, aContainingBlockWidth, aBorder, aPadding);
|
||||
// XXXdholbert This macro probably needs to take aVerticalPercentBasis too
|
||||
DISPLAY_INIT_OFFSETS(frame, this, aHorizontalPercentBasis, 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.
|
||||
@ -2127,7 +2151,8 @@ nsCSSOffsetState::InitOffsets(nscoord aContainingBlockWidth,
|
||||
// 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
|
||||
bool needMarginProp = ComputeMargin(aContainingBlockWidth);
|
||||
bool needMarginProp = ComputeMargin(aHorizontalPercentBasis,
|
||||
aVerticalPercentBasis);
|
||||
// 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
|
||||
@ -2159,7 +2184,8 @@ nsCSSOffsetState::InitOffsets(nscoord aContainingBlockWidth,
|
||||
needPaddingProp = frame->StylePadding()->IsWidthDependent();
|
||||
}
|
||||
else {
|
||||
needPaddingProp = ComputePadding(aContainingBlockWidth, aFrameType);
|
||||
needPaddingProp = ComputePadding(aHorizontalPercentBasis,
|
||||
aVerticalPercentBasis, aFrameType);
|
||||
}
|
||||
|
||||
if (isThemed) {
|
||||
@ -2419,7 +2445,8 @@ nsHTMLReflowState::CalcLineHeight(nsStyleContext* aStyleContext,
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSSOffsetState::ComputeMargin(nscoord aContainingBlockWidth)
|
||||
nsCSSOffsetState::ComputeMargin(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis)
|
||||
{
|
||||
// SVG text frames have no margin.
|
||||
if (frame->IsSVGText()) {
|
||||
@ -2428,25 +2455,21 @@ nsCSSOffsetState::ComputeMargin(nscoord aContainingBlockWidth)
|
||||
|
||||
// If style style can provide us the margin directly, then use it.
|
||||
const nsStyleMargin *styleMargin = frame->StyleMargin();
|
||||
bool isWidthDependent = !styleMargin->GetMargin(mComputedMargin);
|
||||
if (isWidthDependent) {
|
||||
bool isCBDependent = !styleMargin->GetMargin(mComputedMargin);
|
||||
if (isCBDependent) {
|
||||
// We have to compute the value
|
||||
mComputedMargin.left = nsLayoutUtils::
|
||||
ComputeCBDependentValue(aContainingBlockWidth,
|
||||
ComputeCBDependentValue(aHorizontalPercentBasis,
|
||||
styleMargin->mMargin.GetLeft());
|
||||
mComputedMargin.right = nsLayoutUtils::
|
||||
ComputeCBDependentValue(aContainingBlockWidth,
|
||||
ComputeCBDependentValue(aHorizontalPercentBasis,
|
||||
styleMargin->mMargin.GetRight());
|
||||
|
||||
// According to the CSS2 spec, margin percentages are
|
||||
// calculated with respect to the *width* of the containing
|
||||
// block, even for margin-top and margin-bottom.
|
||||
// XXX This isn't true for page boxes, if we implement them.
|
||||
mComputedMargin.top = nsLayoutUtils::
|
||||
ComputeCBDependentValue(aContainingBlockWidth,
|
||||
ComputeCBDependentValue(aVerticalPercentBasis,
|
||||
styleMargin->mMargin.GetTop());
|
||||
mComputedMargin.bottom = nsLayoutUtils::
|
||||
ComputeCBDependentValue(aContainingBlockWidth,
|
||||
ComputeCBDependentValue(aVerticalPercentBasis,
|
||||
styleMargin->mMargin.GetBottom());
|
||||
}
|
||||
|
||||
@ -2461,15 +2484,17 @@ nsCSSOffsetState::ComputeMargin(nscoord aContainingBlockWidth)
|
||||
}
|
||||
}
|
||||
|
||||
return isWidthDependent;
|
||||
return isCBDependent;
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSSOffsetState::ComputePadding(nscoord aContainingBlockWidth, nsIAtom* aFrameType)
|
||||
nsCSSOffsetState::ComputePadding(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis,
|
||||
nsIAtom* aFrameType)
|
||||
{
|
||||
// If style can provide us the padding directly, then use it.
|
||||
const nsStylePadding *stylePadding = frame->StylePadding();
|
||||
bool isWidthDependent = !stylePadding->GetPadding(mComputedPadding);
|
||||
bool isCBDependent = !stylePadding->GetPadding(mComputedPadding);
|
||||
// a table row/col group, row/col doesn't have padding
|
||||
// XXXldb Neither do border-collapse tables.
|
||||
if (nsGkAtoms::tableRowGroupFrame == aFrameType ||
|
||||
@ -2478,26 +2503,24 @@ nsCSSOffsetState::ComputePadding(nscoord aContainingBlockWidth, nsIAtom* aFrameT
|
||||
nsGkAtoms::tableColFrame == aFrameType) {
|
||||
mComputedPadding.SizeTo(0,0,0,0);
|
||||
}
|
||||
else if (isWidthDependent) {
|
||||
else if (isCBDependent) {
|
||||
// We have to compute the value
|
||||
// clamp negative calc() results to 0
|
||||
mComputedPadding.left = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(aContainingBlockWidth,
|
||||
ComputeCBDependentValue(aHorizontalPercentBasis,
|
||||
stylePadding->mPadding.GetLeft()));
|
||||
mComputedPadding.right = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(aContainingBlockWidth,
|
||||
ComputeCBDependentValue(aHorizontalPercentBasis,
|
||||
stylePadding->mPadding.GetRight()));
|
||||
|
||||
// According to the CSS2 spec, percentages are calculated with respect to
|
||||
// containing block width for padding-top and padding-bottom
|
||||
mComputedPadding.top = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(aContainingBlockWidth,
|
||||
ComputeCBDependentValue(aVerticalPercentBasis,
|
||||
stylePadding->mPadding.GetTop()));
|
||||
mComputedPadding.bottom = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(aContainingBlockWidth,
|
||||
ComputeCBDependentValue(aVerticalPercentBasis,
|
||||
stylePadding->mPadding.GetBottom()));
|
||||
}
|
||||
return isWidthDependent;
|
||||
return isCBDependent;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "nsStyleCoord.h"
|
||||
#include "nsStyleStructInlines.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include <algorithm>
|
||||
|
||||
class nsPresContext;
|
||||
@ -144,12 +145,19 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
// NOTE: If we ever want to use nsCSSOffsetState for a flex item or a grid
|
||||
// item, we need to make it take the containing-block height as well as the
|
||||
// width, since flex items and grid items resolve vertical percent margins
|
||||
// and padding against the containing-block height, rather than its width.
|
||||
nsCSSOffsetState(nsIFrame *aFrame, nsRenderingContext *aRenderingContext,
|
||||
nscoord aContainingBlockWidth)
|
||||
: frame(aFrame)
|
||||
, rendContext(aRenderingContext)
|
||||
{
|
||||
InitOffsets(aContainingBlockWidth, frame->GetType());
|
||||
MOZ_ASSERT(!aFrame->IsFlexItem(),
|
||||
"We're about to resolve vertical percent margin & padding "
|
||||
"values against CB width, which is incorrect for flex items");
|
||||
InitOffsets(aContainingBlockWidth, aContainingBlockWidth, frame->GetType());
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -169,20 +177,39 @@ private:
|
||||
/**
|
||||
* Computes margin values from the specified margin style information, and
|
||||
* fills in the mComputedMargin member.
|
||||
* @return true if the margin is dependent on the containing block width
|
||||
*
|
||||
* @param aHorizontalPercentBasis
|
||||
* Length to use for resolving percentage margin values in the horizontal
|
||||
* axis. Usually the containing block width.
|
||||
* @param aVerticalPercentBasis
|
||||
* Length to use for resolving percentage margin values in the vertical
|
||||
* axis. Usually the containing block width, per CSS21 sec 8.3, but may
|
||||
* be the containing block *height*, e.g. in CSS3 Flexbox and Grid.
|
||||
* @return true if the margin is dependent on the containing block size.
|
||||
*/
|
||||
bool ComputeMargin(nscoord aContainingBlockWidth);
|
||||
bool ComputeMargin(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis);
|
||||
|
||||
/**
|
||||
* Computes padding values from the specified padding style information, and
|
||||
* fills in the mComputedPadding member.
|
||||
* @return true if the padding is dependent on the containing block width
|
||||
*
|
||||
* @param aHorizontalPercentBasis
|
||||
* Length to use for resolving percentage padding values in the horizontal
|
||||
* axis. Usually the containing block width.
|
||||
* @param aVerticalPercentBasis
|
||||
* Length to use for resolving percentage padding values in the vertical
|
||||
* axis. Usually the containing block width, per CSS21 sec 8.4, but may
|
||||
* be the containing block *height* in e.g. CSS3 Flexbox and Grid.
|
||||
* @return true if the padding is dependent on the containing block size.
|
||||
*/
|
||||
bool ComputePadding(nscoord aContainingBlockWidth, nsIAtom* aFrameType);
|
||||
bool ComputePadding(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis, nsIAtom* aFrameType);
|
||||
|
||||
protected:
|
||||
|
||||
void InitOffsets(nscoord aContainingBlockWidth,
|
||||
void InitOffsets(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis,
|
||||
nsIAtom* aFrameType,
|
||||
const nsMargin *aBorder = nullptr,
|
||||
const nsMargin *aPadding = nullptr);
|
||||
|
Loading…
Reference in New Issue
Block a user