Diff
Modified: trunk/Source/WebCore/CMakeLists.txt (261792 => 261793)
--- trunk/Source/WebCore/CMakeLists.txt 2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/CMakeLists.txt 2020-05-17 16:17:45 UTC (rev 261793)
@@ -100,6 +100,7 @@
"${WEBCORE_DIR}/inspector/agents/worker"
"${WEBCORE_DIR}/layout"
"${WEBCORE_DIR}/layout/blockformatting"
+ "${WEBCORE_DIR}/layout/blockformatting/tablewrapper"
"${WEBCORE_DIR}/layout/displaytree"
"${WEBCORE_DIR}/layout/floats"
"${WEBCORE_DIR}/layout/inlineformatting"
Modified: trunk/Source/WebCore/ChangeLog (261792 => 261793)
--- trunk/Source/WebCore/ChangeLog 2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/ChangeLog 2020-05-17 16:17:45 UTC (rev 261793)
@@ -1,3 +1,34 @@
+2020-05-17 Zalan Bujtas <[email protected]>
+
+ [LFC][BFC] Introduce TableWrapperBlockFormattingContext
+ https://bugs.webkit.org/show_bug.cgi?id=211996
+
+ Reviewed by Antti Koivisto.
+
+ Table wrapper box establishes a special BFC with only captions and the actual table box in it.
+ It mostly behaves like a normal BFC but the table box requires some special handing when it comes
+ to padding/border and width/height computation.
+ This patch moves the table box specific code from generic BFC to this new subclass.
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * layout/FormattingContext.h:
+ * layout/LayoutContext.cpp:
+ (WebCore::Layout::LayoutContext::createFormattingContext):
+ * layout/blockformatting/BlockFormattingContext.cpp:
+ (WebCore::Layout::BlockFormattingContext::computeHeightAndMargin):
+ * layout/blockformatting/BlockFormattingContext.h:
+ (): Deleted.
+ * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowWidthAndMargin):
+ * layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp: Added.
+ (WebCore::Layout::TableWrapperBlockFormattingContext::TableWrapperBlockFormattingContext):
+ (WebCore::Layout::TableWrapperBlockFormattingContext::layoutInFlowContent):
+ (WebCore::Layout::TableWrapperBlockFormattingContext::layoutTableBox):
+ (WebCore::Layout::TableWrapperBlockFormattingContext::computeWidthAndMarginForTableBox):
+ (WebCore::Layout::TableWrapperBlockFormattingContext::computeHeightAndMarginForTableBox):
+ * layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h: Added.
+
2020-05-17 Carlos Garcia Campos <[email protected]>
[GTK] Move to new Pasteboard API
Modified: trunk/Source/WebCore/Sources.txt (261792 => 261793)
--- trunk/Source/WebCore/Sources.txt 2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/Sources.txt 2020-05-17 16:17:45 UTC (rev 261793)
@@ -1462,6 +1462,7 @@
layout/blockformatting/BlockFormattingState.cpp
layout/blockformatting/BlockMarginCollapse.cpp
layout/blockformatting/PrecomputedBlockMarginCollapse.cpp
+layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp
layout/displaytree/DisplayBox.cpp
layout/displaytree/DisplayInlineContent.cpp
layout/displaytree/DisplayPainter.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (261792 => 261793)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-05-17 16:17:45 UTC (rev 261793)
@@ -2049,6 +2049,7 @@
6EE8A77310F803F3005A4A24 /* JSWebGLContextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE8A77110F803F3005A4A24 /* JSWebGLContextAttributes.h */; };
6F0B98B523F268EC00EEC2F2 /* LayoutInlineTextBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F0B98B323F268EB00EEC2F2 /* LayoutInlineTextBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
6F0CD695229ED32700C5994E /* InlineLineBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F0CD694229ED32700C5994E /* InlineLineBuilder.h */; };
+ 6F17264F2470C60B00518C96 /* TableWrapperBlockFormattingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F17264E2470C60A00518C96 /* TableWrapperBlockFormattingContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
6F1CC1DE225F8B4900720AD2 /* InlineTextItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F1CC1DD225F8B4200720AD2 /* InlineTextItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
6F26BB6C23343E6F002F2BEA /* LayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F26BB6B23343E5B002F2BEA /* LayoutContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
6F26EB48234004A5006906E2 /* LineLayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F26EB46234004A5006906E2 /* LineLayoutContext.h */; };
@@ -9417,6 +9418,8 @@
6F0CD692229ED31900C5994E /* InlineLineBuilder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineLineBuilder.cpp; sourceTree = "<group>"; };
6F0CD694229ED32700C5994E /* InlineLineBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineLineBuilder.h; sourceTree = "<group>"; };
6F10B08622B8568D0090E69C /* InlineFormattingContextQuirks.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineFormattingContextQuirks.cpp; sourceTree = "<group>"; };
+ 6F17264C2470C5F700518C96 /* TableWrapperBlockFormattingContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TableWrapperBlockFormattingContext.cpp; sourceTree = "<group>"; };
+ 6F17264E2470C60A00518C96 /* TableWrapperBlockFormattingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableWrapperBlockFormattingContext.h; sourceTree = "<group>"; };
6F1CC1DC225F8B4100720AD2 /* InlineTextItem.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineTextItem.cpp; sourceTree = "<group>"; };
6F1CC1DD225F8B4200720AD2 /* InlineTextItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InlineTextItem.h; sourceTree = "<group>"; };
6F222B741AB52D640094651A /* WebGLVertexArrayObjectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGLVertexArrayObjectBase.h; sourceTree = "<group>"; };
@@ -17073,6 +17076,7 @@
115CFA99208BC09A001E6991 /* blockformatting */ = {
isa = PBXGroup;
children = (
+ 6FD4FE3E2470B3AD007374CC /* tablewrapper */,
115CFA6D208AFAB6001E6991 /* BlockFormattingContext.cpp */,
115CFA6C208AFAB6001E6991 /* BlockFormattingContext.h */,
6F0830DF20B46951008A945B /* BlockFormattingContextGeometry.cpp */,
@@ -21292,6 +21296,15 @@
path = floats;
sourceTree = "<group>";
};
+ 6FD4FE3E2470B3AD007374CC /* tablewrapper */ = {
+ isa = PBXGroup;
+ children = (
+ 6F17264C2470C5F700518C96 /* TableWrapperBlockFormattingContext.cpp */,
+ 6F17264E2470C60A00518C96 /* TableWrapperBlockFormattingContext.h */,
+ );
+ path = tablewrapper;
+ sourceTree = "<group>";
+ };
6FE7DDDD20EC6E8B008B5B4E /* text */ = {
isa = PBXGroup;
children = (
@@ -33280,6 +33293,7 @@
0F03C0741884695E00A5F8CA /* SystemMemory.h in Headers */,
5D5975B319635F1100D00878 /* SystemVersion.h in Headers */,
A8CFF0510A154F09000A4234 /* TableLayout.h in Headers */,
+ 6F17264F2470C60B00518C96 /* TableWrapperBlockFormattingContext.h in Headers */,
3BB6B81122A7D313003A2A69 /* TabSize.h in Headers */,
463EB6231B8789E00096ED51 /* TagCollection.h in Headers */,
9B0ABCAE236BB43100B45085 /* TaskSource.h in Headers */,
Modified: trunk/Source/WebCore/layout/FormattingContext.h (261792 => 261793)
--- trunk/Source/WebCore/layout/FormattingContext.h 2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/layout/FormattingContext.h 2020-05-17 16:17:45 UTC (rev 261793)
@@ -160,13 +160,13 @@
ConstraintsForOutOfFlowContent constraintsForOutOfFlowContent(const ContainerBox&);
ConstraintsForInFlowContent constraintsForInFlowContent(const ContainerBox&, Optional<EscapeReason> = WTF::nullopt);
+ Optional<LayoutUnit> computedHeight(const Box&, Optional<LayoutUnit> containingBlockHeight = WTF::nullopt) const;
+ Optional<LayoutUnit> computedWidth(const Box&, LayoutUnit containingBlockWidth) const;
+
protected:
friend class FormattingContext;
Geometry(const FormattingContext&);
- Optional<LayoutUnit> computedHeight(const Box&, Optional<LayoutUnit> containingBlockHeight = WTF::nullopt) const;
- Optional<LayoutUnit> computedWidth(const Box&, LayoutUnit containingBlockWidth) const;
-
const LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
LayoutState& layoutState() { return m_formattingContext.layoutState(); }
const FormattingContext& formattingContext() const { return m_formattingContext; }
Modified: trunk/Source/WebCore/layout/LayoutContext.cpp (261792 => 261793)
--- trunk/Source/WebCore/layout/LayoutContext.cpp 2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/layout/LayoutContext.cpp 2020-05-17 16:17:45 UTC (rev 261793)
@@ -45,6 +45,7 @@
#include "RuntimeEnabledFeatures.h"
#include "TableFormattingContext.h"
#include "TableFormattingState.h"
+#include "TableWrapperBlockFormattingContext.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
@@ -124,6 +125,8 @@
if (formattingContextRoot.establishesBlockFormattingContext()) {
ASSERT(!formattingContextRoot.establishesInlineFormattingContext());
auto& blockFormattingState = layoutState.ensureBlockFormattingState(formattingContextRoot);
+ if (formattingContextRoot.isTableWrapperBox())
+ return makeUnique<TableWrapperBlockFormattingContext>(formattingContextRoot, blockFormattingState);
return makeUnique<BlockFormattingContext>(formattingContextRoot, blockFormattingState);
}
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp (261792 => 261793)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp 2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp 2020-05-17 16:17:45 UTC (rev 261793)
@@ -372,34 +372,23 @@
return { };
};
- auto usedHeightValue = Optional<LayoutUnit> { };
- auto ignoreMinMaxHeightCompute = false;
- if (layoutBox.establishesTableFormattingContext()) {
- // Table is a special BFC content. Its height is mainly driven by the content. Computed height, min-height and max-height are all
- // already been taken into account during the TFC layout.
- usedHeightValue = geometry().contentHeightForFormattingContextRoot(downcast<ContainerBox>(layoutBox));
- ignoreMinMaxHeightCompute = true;
+ auto contentHeightAndMargin = compute({ });
+ if (auto maxHeight = geometry().computedMaxHeight(layoutBox)) {
+ if (contentHeightAndMargin.contentHeight > *maxHeight) {
+ auto maxHeightAndMargin = compute(maxHeight);
+ // Used height should remain the same.
+ ASSERT((layoutState().inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || maxHeightAndMargin.contentHeight == *maxHeight);
+ contentHeightAndMargin = { *maxHeight, maxHeightAndMargin.nonCollapsedMargin };
+ }
}
- auto contentHeightAndMargin = compute({ usedHeightValue });
- if (!ignoreMinMaxHeightCompute) {
- if (auto maxHeight = geometry().computedMaxHeight(layoutBox)) {
- if (contentHeightAndMargin.contentHeight > *maxHeight) {
- auto maxHeightAndMargin = compute(maxHeight);
- // Used height should remain the same.
- ASSERT((layoutState().inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || maxHeightAndMargin.contentHeight == *maxHeight);
- contentHeightAndMargin = { *maxHeight, maxHeightAndMargin.nonCollapsedMargin };
- }
+ if (auto minHeight = geometry().computedMinHeight(layoutBox)) {
+ if (contentHeightAndMargin.contentHeight < *minHeight) {
+ auto minHeightAndMargin = compute(minHeight);
+ // Used height should remain the same.
+ ASSERT((layoutState().inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || minHeightAndMargin.contentHeight == *minHeight);
+ contentHeightAndMargin = { *minHeight, minHeightAndMargin.nonCollapsedMargin };
}
-
- if (auto minHeight = geometry().computedMinHeight(layoutBox)) {
- if (contentHeightAndMargin.contentHeight < *minHeight) {
- auto minHeightAndMargin = compute(minHeight);
- // Used height should remain the same.
- ASSERT((layoutState().inQuirksMode() && (layoutBox.isBodyBox() || layoutBox.isDocumentBox())) || minHeightAndMargin.contentHeight == *minHeight);
- contentHeightAndMargin = { *minHeight, minHeightAndMargin.nonCollapsedMargin };
- }
- }
}
// 1. Compute collapsed margins.
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h (261792 => 261793)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h 2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.h 2020-05-17 16:17:45 UTC (rev 261793)
@@ -43,7 +43,7 @@
// This class implements the layout logic for block formatting contexts.
// https://www.w3.org/TR/CSS22/visuren.html#block-formatting
-class BlockFormattingContext final : public FormattingContext {
+class BlockFormattingContext : public FormattingContext {
WTF_MAKE_ISO_ALLOCATED(BlockFormattingContext);
public:
BlockFormattingContext(const ContainerBox& formattingContextRoot, BlockFormattingState&);
@@ -50,8 +50,7 @@
void layoutInFlowContent(InvalidationState&, const ConstraintsForInFlowContent&) override;
-private:
-
+protected:
struct ConstraintsPair {
const ConstraintsForInFlowContent formattingContextRoot;
const ConstraintsForInFlowContent containingBlock;
@@ -75,6 +74,8 @@
// This class implements positioning and sizing for boxes participating in a block formatting context.
class Geometry : public FormattingContext::Geometry {
public:
+ Geometry(const BlockFormattingContext&);
+
ContentHeightAndMargin inFlowHeightAndMargin(const Box&, const HorizontalConstraints&, const OverrideVerticalValues&);
ContentWidthAndMargin inFlowWidthAndMargin(const Box&, const HorizontalConstraints&, const OverrideHorizontalValues&);
@@ -85,13 +86,9 @@
IntrinsicWidthConstraints intrinsicWidthConstraints(const Box&);
private:
- friend class BlockFormattingContext;
- Geometry(const BlockFormattingContext&);
-
ContentHeightAndMargin inFlowNonReplacedHeightAndMargin(const Box&, const HorizontalConstraints&, const OverrideVerticalValues&);
ContentWidthAndMargin inFlowNonReplacedWidthAndMargin(const Box&, const HorizontalConstraints&, const OverrideHorizontalValues&) const;
ContentWidthAndMargin inFlowReplacedWidthAndMargin(const ReplacedBox&, const HorizontalConstraints&, const OverrideHorizontalValues&) const;
- Point staticPositionForOutOfFlowPositioned(const Box&) const;
const BlockFormattingContext& formattingContext() const { return downcast<BlockFormattingContext>(FormattingContext::Geometry::formattingContext()); }
};
Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp (261792 => 261793)
--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp 2020-05-17 08:35:41 UTC (rev 261792)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp 2020-05-17 16:17:45 UTC (rev 261793)
@@ -278,32 +278,8 @@
{
ASSERT(layoutBox.isInFlow());
- if (!layoutBox.isReplacedBox()) {
- if (!layoutBox.establishesTableFormattingContext())
- return inFlowNonReplacedWidthAndMargin(layoutBox, horizontalConstraints, overrideHorizontalValues);
- // This is a special table "fit-content size" behavior handling. Not in the spec though.
- // Table returns its final width as min/max. Use this final width value to computed horizontal margins etc.
- if (overrideHorizontalValues.width)
- return inFlowNonReplacedWidthAndMargin(layoutBox, horizontalConstraints, OverrideHorizontalValues { overrideHorizontalValues.width, overrideHorizontalValues.margin });
-
- auto& tableBox = downcast<ContainerBox>(layoutBox);
- auto& formattingStateForTableBox = layoutState().ensureFormattingState(tableBox);
- auto intrinsicWidthConstraints = IntrinsicWidthConstraints { };
- if (auto precomputedIntrinsicWidthConstraints = formattingStateForTableBox.intrinsicWidthConstraints())
- intrinsicWidthConstraints = *precomputedIntrinsicWidthConstraints;
- else
- intrinsicWidthConstraints = LayoutContext::createFormattingContext(tableBox, layoutState())->computedIntrinsicWidthConstraints();
- auto computedTableWidth = computedWidth(tableBox, horizontalConstraints.logicalWidth);
- auto usedWidth = computedTableWidth;
- if (computedTableWidth && intrinsicWidthConstraints.minimum > computedTableWidth) {
- // Table content needs more space than the table has.
- usedWidth = intrinsicWidthConstraints.minimum;
- } else if (!computedTableWidth) {
- // Use the generic shrink-to-fit-width logic.
- usedWidth = std::min(std::max(intrinsicWidthConstraints.minimum, horizontalConstraints.logicalWidth), intrinsicWidthConstraints.maximum);
- }
- return inFlowNonReplacedWidthAndMargin(layoutBox, horizontalConstraints, OverrideHorizontalValues { usedWidth, overrideHorizontalValues.margin });
- }
+ if (!layoutBox.isReplacedBox())
+ return inFlowNonReplacedWidthAndMargin(layoutBox, horizontalConstraints, overrideHorizontalValues);
return inFlowReplacedWidthAndMargin(downcast<ReplacedBox>(layoutBox), horizontalConstraints, overrideHorizontalValues);
}
Added: trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp (0 => 261793)
--- trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp (rev 0)
+++ trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp 2020-05-17 16:17:45 UTC (rev 261793)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TableWrapperBlockFormattingContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(TableWrapperBlockFormattingContext);
+
+TableWrapperBlockFormattingContext::TableWrapperBlockFormattingContext(const ContainerBox& formattingContextRoot, BlockFormattingState& formattingState)
+ : BlockFormattingContext(formattingContextRoot, formattingState)
+{
+}
+
+void TableWrapperBlockFormattingContext::layoutInFlowContent(InvalidationState&, const ConstraintsForInFlowContent& constraints)
+{
+ // The table generates a principal block container box called the table wrapper box that contains the table box itself and any caption boxes
+ // (in document order). The table box is a block-level box that contains the table's internal table boxes.
+ // The caption boxes are principal block-level boxes that retain their own content, padding, margin, and border areas, and are rendered
+ // as normal block boxes inside the table wrapper box. Whether the caption boxes are placed before or after the table box is decided by
+ // the 'caption-side' property, as described below.
+ for (auto& child : childrenOfType<ContainerBox>(root())) {
+ if (child.isTableBox())
+ layoutTableBox(child, constraints);
+ else if (child.isTableCaption())
+ ASSERT_NOT_IMPLEMENTED_YET();
+ else
+ ASSERT_NOT_REACHED();
+ }
+}
+
+void TableWrapperBlockFormattingContext::layoutTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent& constraints)
+{
+ computeBorderAndPadding(tableBox, constraints.horizontal);
+ computeStaticVerticalPosition(tableBox, constraints.vertical);
+ computeWidthAndMarginForTableBox(tableBox, constraints);
+ computeStaticHorizontalPosition(tableBox, constraints.horizontal);
+
+ auto invalidationState = InvalidationState { };
+ LayoutContext::createFormattingContext(tableBox, layoutState())->layoutInFlowContent(invalidationState, geometry().constraintsForInFlowContent(tableBox));
+
+ computeHeightAndMarginForTableBox(tableBox, constraints);
+}
+
+void TableWrapperBlockFormattingContext::computeWidthAndMarginForTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent& constraints)
+{
+ ASSERT(tableBox.isTableBox());
+ // This is a special table "fit-content size" behavior handling. Not in the spec though.
+ // Table returns its final width as min/max. Use this final width value to computed horizontal margins etc.
+ auto& formattingStateForTableBox = layoutState().ensureFormattingState(tableBox);
+ auto intrinsicWidthConstraints = IntrinsicWidthConstraints { };
+ if (auto precomputedIntrinsicWidthConstraints = formattingStateForTableBox.intrinsicWidthConstraints())
+ intrinsicWidthConstraints = *precomputedIntrinsicWidthConstraints;
+ else
+ intrinsicWidthConstraints = LayoutContext::createFormattingContext(tableBox, layoutState())->computedIntrinsicWidthConstraints();
+ auto computedTableWidth = geometry().computedWidth(tableBox, constraints.horizontal.logicalWidth);
+ auto usedWidth = computedTableWidth;
+ if (computedTableWidth && intrinsicWidthConstraints.minimum > computedTableWidth) {
+ // Table content needs more space than the table has.
+ usedWidth = intrinsicWidthConstraints.minimum;
+ } else if (!computedTableWidth) {
+ // Use the generic shrink-to-fit-width logic.
+ usedWidth = std::min(std::max(intrinsicWidthConstraints.minimum, constraints.horizontal.logicalWidth), intrinsicWidthConstraints.maximum);
+ }
+ auto contentWidthAndMargin = geometry().inFlowWidthAndMargin(tableBox, constraints.horizontal, OverrideHorizontalValues { usedWidth, { } });
+
+ auto& displayBox = formattingState().displayBox(tableBox);
+ displayBox.setContentBoxWidth(contentWidthAndMargin.contentWidth);
+ displayBox.setHorizontalMargin(contentWidthAndMargin.usedMargin);
+ displayBox.setHorizontalComputedMargin(contentWidthAndMargin.computedMargin);
+}
+
+void TableWrapperBlockFormattingContext::computeHeightAndMarginForTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent& constraints)
+{
+ ASSERT(tableBox.isTableBox());
+ // Table is a special BFC content. Its height is mainly driven by the content. Computed height, min-height and max-height are all
+ // already been taken into account during the TFC layout.
+ auto usedHeight = geometry().contentHeightForFormattingContextRoot(tableBox);
+ auto heightAndMargin = geometry().inFlowHeightAndMargin(tableBox, constraints.horizontal, { usedHeight });
+
+ auto marginCollapse = this->marginCollapse();
+ auto collapsedAndPositiveNegativeValues = marginCollapse.collapsedVerticalValues(tableBox, heightAndMargin.nonCollapsedMargin);
+ // Cache the computed positive and negative margin value pair.
+ formattingState().setPositiveAndNegativeVerticalMargin(tableBox, collapsedAndPositiveNegativeValues.positiveAndNegativeVerticalValues);
+ auto verticalMargin = UsedVerticalMargin { heightAndMargin.nonCollapsedMargin, collapsedAndPositiveNegativeValues.collapsedValues };
+
+ auto& displayBox = formattingState().displayBox(tableBox);
+ displayBox.setTop(verticalPositionWithMargin(tableBox, verticalMargin, constraints.vertical));
+ displayBox.setContentBoxHeight(heightAndMargin.contentHeight);
+ displayBox.setVerticalMargin(verticalMargin);
+ // Adjust the previous sibling's margin bottom now that this box's vertical margin is computed.
+ MarginCollapse::updateMarginAfterForPreviousSibling(*this, marginCollapse, tableBox);
+}
+
+}
+}
+
+#endif
Added: trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h (0 => 261793)
--- trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h (rev 0)
+++ trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h 2020-05-17 16:17:45 UTC (rev 261793)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "BlockFormattingContext.h"
+#include <wtf/IsoMalloc.h>
+
+namespace WebCore {
+namespace Layout {
+
+// This class implements the special block formatting context layout logic for the table wrapper.
+// https://www.w3.org/TR/CSS22/tables.html#model
+class TableWrapperBlockFormattingContext final : public BlockFormattingContext {
+ WTF_MAKE_ISO_ALLOCATED(TableWrapperBlockFormattingContext);
+public:
+ TableWrapperBlockFormattingContext(const ContainerBox& formattingContextRoot, BlockFormattingState&);
+
+ void layoutInFlowContent(InvalidationState&, const ConstraintsForInFlowContent&) final;
+
+private:
+ void layoutTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent&);
+
+ void computeWidthAndMarginForTableBox(const ContainerBox&, const ConstraintsForInFlowContent&);
+ void computeHeightAndMarginForTableBox(const ContainerBox&, const ConstraintsForInFlowContent&);
+};
+
+}
+}
+
+#endif