BlockFormattingContextQuirks.cpp [plain text]
#include "config.h"
#include "BlockFormattingContext.h"
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "BlockFormattingState.h"
#include "DisplayBox.h"
#include "LayoutBox.h"
#include "LayoutContainerBox.h"
#include "LayoutInitialContainingBlock.h"
#include "LayoutState.h"
namespace WebCore {
namespace Layout {
static bool isQuirkContainer(const Box& layoutBox)
{
return layoutBox.isBodyBox() || layoutBox.isDocumentBox() || layoutBox.isTableCell();
}
bool BlockFormattingContext::Quirks::needsStretching(const Box& layoutBox) const
{
ASSERT(layoutBox.isInFlow());
if (!layoutState().inQuirksMode())
return false;
if (!layoutBox.isDocumentBox() && !layoutBox.isBodyBox())
return false;
return layoutBox.style().logicalHeight().isAuto();
}
LayoutUnit BlockFormattingContext::Quirks::stretchedInFlowHeight(const Box& layoutBox, ContentHeightAndMargin contentHeightAndMargin)
{
ASSERT(needsStretching(layoutBox));
auto& formattingContext = this->formattingContext();
auto nonCollapsedVerticalMargin = contentHeightAndMargin.nonCollapsedMargin.before + contentHeightAndMargin.nonCollapsedMargin.after;
if (layoutBox.isDocumentBox()) {
auto documentBoxContentHeight = formattingContext.geometryForBox(layoutBox.initialContainingBlock(), EscapeReason::DocumentBoxStretchesToViewportQuirk).contentBoxHeight();
auto& documentBoxGeometry = formattingContext.geometryForBox(layoutBox);
documentBoxContentHeight -= nonCollapsedVerticalMargin + documentBoxGeometry.verticalBorder() + documentBoxGeometry.verticalPadding().valueOr(0);
return std::max(contentHeightAndMargin.contentHeight, documentBoxContentHeight);
}
ASSERT(layoutBox.isBodyBox());
auto& initialContainingBlock = layoutBox.initialContainingBlock();
auto& initialContainingBlockGeometry = formattingContext.geometryForBox(initialContainingBlock, EscapeReason::BodyStretchesToViewportQuirk);
auto bodyBoxContentHeight = initialContainingBlockGeometry.contentBoxHeight();
auto& bodyBoxGeometry = formattingContext.geometryForBox(layoutBox);
bodyBoxContentHeight -= bodyBoxGeometry.verticalBorder() + bodyBoxGeometry.verticalPadding().valueOr(0);
auto nonCollapsedMargin = contentHeightAndMargin.nonCollapsedMargin;
auto collapsedMargin = formattingContext.marginCollapse().collapsedVerticalValues(layoutBox, nonCollapsedMargin).collapsedValues;
auto usedVerticalMargin = collapsedMargin.before.valueOr(nonCollapsedMargin.before);
usedVerticalMargin += collapsedMargin.isCollapsedThrough ? nonCollapsedMargin.after : collapsedMargin.after.valueOr(nonCollapsedMargin.after);
bodyBoxContentHeight -= usedVerticalMargin;
auto& documentBox = layoutBox.parent();
auto& documentBoxGeometry = formattingContext.geometryForBox(documentBox, EscapeReason::BodyStretchesToViewportQuirk);
bodyBoxContentHeight -= documentBoxGeometry.verticalBorder() + documentBoxGeometry.verticalPadding().valueOr(0);
if (documentBox.isInFlow()) {
auto geometry = this->geometry();
auto precomputeDocumentBoxVerticalMargin = geometry.computedVerticalMargin(documentBox, geometry.constraintsForInFlowContent(initialContainingBlock, EscapeReason::BodyStretchesToViewportQuirk).horizontal);
bodyBoxContentHeight -= precomputeDocumentBoxVerticalMargin.before.valueOr(0) + precomputeDocumentBoxVerticalMargin.after.valueOr(0);
}
return std::max(contentHeightAndMargin.contentHeight, bodyBoxContentHeight);
}
bool BlockFormattingContext::Quirks::shouldIgnoreCollapsedQuirkMargin(const Box& layoutBox) const
{
return layoutState().inQuirksMode() && isQuirkContainer(layoutBox);
}
bool BlockFormattingContext::Quirks::shouldCollapseMarginBeforeWithParentMarginBefore(const Box& layoutBox) const
{
return layoutState().inQuirksMode() && layoutBox.style().hasMarginBeforeQuirk() && isQuirkContainer(layoutBox.containingBlock());
}
bool BlockFormattingContext::Quirks::shouldCollapseMarginAfterWithParentMarginAfter(const Box& layoutBox) const
{
return layoutState().inQuirksMode() && layoutBox.style().hasMarginAfterQuirk() && isQuirkContainer(layoutBox.containingBlock());
}
}
}
#endif