BlockFormattingContextQuirks.cpp [plain text]
#include "config.h"
#include "BlockFormattingContext.h"
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "LayoutBox.h"
#include "LayoutContainer.h"
#include "LayoutState.h"
namespace WebCore {
namespace Layout {
static const Container& initialContainingBlock(const Box& layoutBox)
{
auto* containingBlock = layoutBox.containingBlock();
while (containingBlock->containingBlock())
containingBlock = containingBlock->containingBlock();
return *containingBlock;
}
static bool isQuirkContainer(const Box& layoutBox)
{
return layoutBox.isBodyBox() || layoutBox.isDocumentBox() || layoutBox.isTableCell();
}
static bool hasMarginBeforeQuirkValue(const Box& layoutBox)
{
return layoutBox.style().hasMarginBeforeQuirk();
}
bool BlockFormattingContext::Quirks::needsStretching(const LayoutState& layoutState, const Box& layoutBox)
{
ASSERT(layoutBox.isInFlow());
if (!layoutState.inQuirksMode())
return false;
if (!layoutBox.isDocumentBox() && !layoutBox.isBodyBox())
return false;
return layoutBox.style().logicalHeight().isAuto();
}
HeightAndMargin BlockFormattingContext::Quirks::stretchedHeight(const LayoutState& layoutState, const Box& layoutBox, HeightAndMargin heightAndMargin)
{
ASSERT(layoutBox.isDocumentBox() || layoutBox.isBodyBox());
auto& documentBox = layoutBox.isDocumentBox() ? layoutBox : *layoutBox.parent();
auto& documentBoxDisplayBox = layoutState.displayBoxForLayoutBox(documentBox);
auto documentBoxVerticalBorders = documentBoxDisplayBox.borderTop() + documentBoxDisplayBox.borderBottom();
auto documentBoxVerticalPaddings = documentBoxDisplayBox.paddingTop().valueOr(0) + documentBoxDisplayBox.paddingBottom().valueOr(0);
auto strechedHeight = layoutState.displayBoxForLayoutBox(initialContainingBlock(layoutBox)).contentBoxHeight();
strechedHeight -= documentBoxVerticalBorders + documentBoxVerticalPaddings;
LayoutUnit totalVerticalMargin;
if (layoutBox.isDocumentBox()) {
auto verticalMargin = heightAndMargin.nonCollapsedMargin;
totalVerticalMargin = verticalMargin.before + verticalMargin.after;
} else if (layoutBox.isBodyBox()) {
auto verticalMargin = Geometry::estimatedMarginBefore(layoutState, documentBox) + Geometry::estimatedMarginAfter(layoutState, documentBox);
strechedHeight -= verticalMargin;
auto nonCollapsedValues = heightAndMargin.nonCollapsedMargin;
totalVerticalMargin = nonCollapsedValues.before + nonCollapsedValues.after;
}
if (heightAndMargin.height + totalVerticalMargin < strechedHeight)
heightAndMargin.height = strechedHeight - totalVerticalMargin;
return heightAndMargin;
}
bool BlockFormattingContext::Quirks::shouldIgnoreMarginBefore(const LayoutState& layoutState, const Box& layoutBox)
{
if (!layoutBox.parent())
return false;
return layoutState.inQuirksMode() && isQuirkContainer(*layoutBox.parent()) && hasMarginBeforeQuirkValue(layoutBox);
}
}
}
#endif