mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 812899 - Make vertical 'auto' margins on absolutely positioned elements always center, even when the margins are negative. r=dbaron
This commit is contained in:
parent
0e8fe9d3c7
commit
4e6511a3e2
@ -45,7 +45,7 @@ using namespace mozilla::layout;
|
||||
|
||||
enum eNormalLineHeightControl {
|
||||
eUninitialized = -1,
|
||||
eNoExternalLeading = 0, // does not include external leading
|
||||
eNoExternalLeading = 0, // does not include external leading
|
||||
eIncludeExternalLeading, // use whatever value font vendor provides
|
||||
eCompensateLeading // compensate leading if leading provided by font vendor is not enough
|
||||
};
|
||||
@ -485,11 +485,11 @@ void nsHTMLReflowState::InitCBReflowState()
|
||||
}
|
||||
|
||||
/* Check whether CalcQuirkContainingBlockHeight would stop on the
|
||||
* given reflow state, using its block as a height. (essentially
|
||||
* returns false for any case in which CalcQuirkContainingBlockHeight
|
||||
* given reflow state, using its block as a height. (essentially
|
||||
* returns false for any case in which CalcQuirkContainingBlockHeight
|
||||
* has a "continue" in its main loop.)
|
||||
*
|
||||
* XXX Maybe refactor CalcQuirkContainingBlockHeight so it uses
|
||||
* XXX Maybe refactor CalcQuirkContainingBlockHeight so it uses
|
||||
* this function as well
|
||||
*/
|
||||
static bool
|
||||
@ -669,9 +669,9 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT
|
||||
// the special bsize reflow, since in that case it will already be
|
||||
// set correctly above if we need it set.
|
||||
if (!IsBResize() && mCBReflowState &&
|
||||
(IS_TABLE_CELL(mCBReflowState->frame->GetType()) ||
|
||||
(IS_TABLE_CELL(mCBReflowState->frame->GetType()) ||
|
||||
mCBReflowState->mFlags.mHeightDependsOnAncestorCell) &&
|
||||
!mCBReflowState->mFlags.mSpecialBSizeReflow &&
|
||||
!mCBReflowState->mFlags.mSpecialBSizeReflow &&
|
||||
dependsOnCBBSize) {
|
||||
SetBResize(true);
|
||||
mFlags.mHeightDependsOnAncestorCell = true;
|
||||
@ -694,11 +694,11 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT
|
||||
if (!rs) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (rs->frame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE)
|
||||
break; // no need to go further
|
||||
rs->frame->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
|
||||
|
||||
|
||||
// Keep track of whether we've hit the containing block, because
|
||||
// we need to go at least that far.
|
||||
if (rs == mCBReflowState) {
|
||||
@ -716,7 +716,7 @@ nsHTMLReflowState::InitResizeFlags(nsPresContext* aPresContext, nsIAtom* aFrameT
|
||||
// where we hit the early break statements in
|
||||
// CalcQuirkContainingBlockHeight. But it doesn't hurt
|
||||
// us to set the bit in these cases.
|
||||
|
||||
|
||||
}
|
||||
if (frame->GetStateBits() & NS_FRAME_IS_DIRTY) {
|
||||
// If we're reflowing everything, then we'll find out if we need
|
||||
@ -1741,15 +1741,10 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
|
||||
|
||||
if (marginBStartIsAuto) {
|
||||
if (marginBEndIsAuto) {
|
||||
if (availMarginSpace < 0) {
|
||||
// FIXME: Note that the spec doesn't actually say we should do this!
|
||||
margin.BEnd(cbwm) = availMarginSpace;
|
||||
} else {
|
||||
// Both margin-block-start and -end are 'auto', so they get
|
||||
// equal values
|
||||
margin.BStart(cbwm) = availMarginSpace / 2;
|
||||
margin.BEnd(cbwm) = availMarginSpace - margin.BStart(cbwm);
|
||||
}
|
||||
// Both 'margin-top' and 'margin-bottom' are 'auto', so they get
|
||||
// equal values
|
||||
margin.BStart(cbwm) = availMarginSpace / 2;
|
||||
margin.BEnd(cbwm) = availMarginSpace - margin.BStart(cbwm);
|
||||
} else {
|
||||
// Just margin-block-start is 'auto'
|
||||
margin.BStart(cbwm) = availMarginSpace;
|
||||
@ -1783,19 +1778,19 @@ GetBlockMarginBorderPadding(const nsHTMLReflowState* aReflowState)
|
||||
|
||||
// zero auto margins
|
||||
nsMargin margin = aReflowState->ComputedPhysicalMargin();
|
||||
if (NS_AUTOMARGIN == margin.top)
|
||||
if (NS_AUTOMARGIN == margin.top)
|
||||
margin.top = 0;
|
||||
if (NS_AUTOMARGIN == margin.bottom)
|
||||
if (NS_AUTOMARGIN == margin.bottom)
|
||||
margin.bottom = 0;
|
||||
|
||||
result += margin.top + margin.bottom;
|
||||
result += aReflowState->ComputedPhysicalBorderPadding().top +
|
||||
result += aReflowState->ComputedPhysicalBorderPadding().top +
|
||||
aReflowState->ComputedPhysicalBorderPadding().bottom;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Get the height based on the viewport of the containing block specified
|
||||
/* Get the height based on the viewport of the containing block specified
|
||||
* in aReflowState when the containing block has mComputedHeight == NS_AUTOHEIGHT
|
||||
* This will walk up the chain of containing blocks looking for a computed height
|
||||
* until it finds the canvas frame, or it encounters a frame that is not a block,
|
||||
@ -1811,16 +1806,16 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState* aCBReflowState)
|
||||
{
|
||||
const nsHTMLReflowState* firstAncestorRS = nullptr; // a candidate for html frame
|
||||
const nsHTMLReflowState* secondAncestorRS = nullptr; // a candidate for body frame
|
||||
|
||||
|
||||
// initialize the default to NS_AUTOHEIGHT as this is the containings block
|
||||
// computed height when this function is called. It is possible that we
|
||||
// computed height when this function is called. It is possible that we
|
||||
// don't alter this height especially if we are restricted to one level
|
||||
nscoord result = NS_AUTOHEIGHT;
|
||||
|
||||
nscoord result = NS_AUTOHEIGHT;
|
||||
|
||||
const nsHTMLReflowState* rs = aCBReflowState;
|
||||
for (; rs; rs = rs->parentReflowState) {
|
||||
nsIAtom* frameType = rs->frame->GetType();
|
||||
// if the ancestor is auto height then skip it and continue up if it
|
||||
// if the ancestor is auto height then skip it and continue up if it
|
||||
// is the first block frame and possibly the body/html
|
||||
if (nsGkAtoms::blockFrame == frameType ||
|
||||
#ifdef MOZ_XUL
|
||||
@ -1849,23 +1844,23 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState* aCBReflowState)
|
||||
else if (nsGkAtoms::pageContentFrame == frameType) {
|
||||
nsIFrame* prevInFlow = rs->frame->GetPrevInFlow();
|
||||
// only use the page content frame for a height basis if it is the first in flow
|
||||
if (prevInFlow)
|
||||
if (prevInFlow)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
|
||||
// if the ancestor is the page content frame then the percent base is
|
||||
// if the ancestor is the page content frame then the percent base is
|
||||
// the avail height, otherwise it is the computed height
|
||||
result = (nsGkAtoms::pageContentFrame == frameType)
|
||||
? rs->AvailableHeight() : rs->ComputedHeight();
|
||||
// if unconstrained - don't sutract borders - would result in huge height
|
||||
if (NS_AUTOHEIGHT == result) return result;
|
||||
|
||||
// if we got to the canvas or page content frame, then subtract out
|
||||
// if we got to the canvas or page content frame, then subtract out
|
||||
// margin/border/padding for the BODY and HTML elements
|
||||
if ((nsGkAtoms::canvasFrame == frameType) ||
|
||||
if ((nsGkAtoms::canvasFrame == frameType) ||
|
||||
(nsGkAtoms::pageContentFrame == frameType)) {
|
||||
|
||||
result -= GetBlockMarginBorderPadding(firstAncestorRS);
|
||||
@ -1888,7 +1883,7 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState* aCBReflowState)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
// if we got to the html frame (a block child of the canvas) ...
|
||||
else if (nsGkAtoms::blockFrame == frameType &&
|
||||
@ -2443,7 +2438,7 @@ nsCSSOffsetState::InitOffsets(WritingMode aWM,
|
||||
//
|
||||
// 'margin-left' + 'border-left-width' + 'padding-left' + 'width' +
|
||||
// 'padding-right' + 'border-right-width' + 'margin-right'
|
||||
// = width of containing block
|
||||
// = width of containing block
|
||||
//
|
||||
// Note: the width unit is not auto when this is called
|
||||
void
|
||||
@ -2559,14 +2554,14 @@ nsHTMLReflowState::CalculateBlockSideMargins(nsIAtom* aFrameType)
|
||||
SetComputedLogicalMargin(margin.ConvertTo(mWritingMode, cbWM));
|
||||
}
|
||||
|
||||
#define NORMAL_LINE_HEIGHT_FACTOR 1.2f // in term of emHeight
|
||||
#define NORMAL_LINE_HEIGHT_FACTOR 1.2f // in term of emHeight
|
||||
// For "normal" we use the font's normal line height (em height + leading).
|
||||
// If both internal leading and external leading specified by font itself
|
||||
// are zeros, we should compensate this by creating extra (external) leading
|
||||
// in eCompensateLeading mode. This is necessary because without this
|
||||
// compensation, normal line height might looks too tight.
|
||||
// are zeros, we should compensate this by creating extra (external) leading
|
||||
// in eCompensateLeading mode. This is necessary because without this
|
||||
// compensation, normal line height might looks too tight.
|
||||
|
||||
// For risk management, we use preference to control the behavior, and
|
||||
// For risk management, we use preference to control the behavior, and
|
||||
// eNoExternalLeading is the old behavior.
|
||||
static nscoord
|
||||
GetNormalLineHeight(nsFontMetrics* aFontMetrics)
|
||||
@ -2611,7 +2606,7 @@ ComputeLineHeight(nsStyleContext* aStyleContext,
|
||||
}
|
||||
|
||||
if (lhCoord.GetUnit() == eStyleUnit_Factor)
|
||||
// For factor units the computed value of the line-height property
|
||||
// For factor units the computed value of the line-height property
|
||||
// is found by multiplying the factor by the font's computed size
|
||||
// (adjusted for min-size prefs and text zoom).
|
||||
return NSToCoordRound(lhCoord.GetFactorValue() * aFontSizeInflation *
|
||||
@ -2620,7 +2615,7 @@ ComputeLineHeight(nsStyleContext* aStyleContext,
|
||||
NS_ASSERTION(lhCoord.GetUnit() == eStyleUnit_Normal ||
|
||||
lhCoord.GetUnit() == eStyleUnit_Enumerated,
|
||||
"bad line-height unit");
|
||||
|
||||
|
||||
if (lhCoord.GetUnit() == eStyleUnit_Enumerated) {
|
||||
NS_ASSERTION(lhCoord.GetIntValue() == NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT,
|
||||
"bad line-height value");
|
||||
@ -2875,4 +2870,4 @@ uint8_t
|
||||
nsHTMLReflowState::GetDisplay() const
|
||||
{
|
||||
return mStyleDisplay->GetDisplay(frame);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title> absolutely positioned element should be vertically centered even if the height is bigger than that of the containing block (reference) - bug 812899</title>
|
||||
<style>
|
||||
body > div {
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
border: red solid;
|
||||
margin-top: 5em;
|
||||
width: 5em;
|
||||
height: 5em;
|
||||
}
|
||||
|
||||
body > div > div {
|
||||
position: absolute;
|
||||
border: medium solid blue;
|
||||
margin: -23px auto
|
||||
height: 150%;
|
||||
width: 150%;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<div></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
32
layout/reftests/abs-pos/abs-pos-auto-margin-centered.html
Normal file
32
layout/reftests/abs-pos/abs-pos-auto-margin-centered.html
Normal file
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title> absolutely positioned element should be vertically centered even if the height is bigger than that of the containing block (reference) - bug 812899</title>
|
||||
<style>
|
||||
body > div {
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
border: red solid;
|
||||
margin-top: 5em;
|
||||
width: 5em;
|
||||
height: 5em;
|
||||
}
|
||||
|
||||
body > div > div {
|
||||
position: absolute;
|
||||
border: medium solid blue;
|
||||
margin: auto auto;
|
||||
height: 150%;
|
||||
width: 150%;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<div></div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,5 +1,6 @@
|
||||
== font-size-wrap.html font-size-wrap-ref.html
|
||||
== abs-pos-auto-margin-1.html abs-pos-auto-margin-1-ref.html
|
||||
== abs-pos-auto-margin-centered.html abs-pos-auto-margin-centered-ref.html
|
||||
fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,73,1) == auto-offset-inline-block-1.html auto-offset-inline-block-1-ref.html # bug 696670
|
||||
== fieldset-1.html fieldset-1-ref.html
|
||||
== table-1.html table-1-ref.html
|
||||
|
Loading…
Reference in New Issue
Block a user