Title: [261810] trunk/Source/WebCore
Revision
261810
Author
za...@apple.com
Date
2020-05-18 07:01:09 -0700 (Mon, 18 May 2020)

Log Message

[LFC][TFC] Add support for computing the collapsed table border
https://bugs.webkit.org/show_bug.cgi?id=212003

Reviewed by Antti Koivisto.

UAs must compute an initial left and right border width for the table by examining
the first and last cells in the first row of the table.
The left border width of the table is half of the first cell's collapsed left border,
and the right border width of the table is half of the last cell's collapsed right border.
The top border width of the table is computed by examining all cells who collapse their top
borders with the top border of the table. The top border width of the table is equal to half of the
maximum collapsed top border. The bottom border width is computed by examining all cells whose bottom borders collapse
with the bottom of the table. The bottom border width is equal to half of the maximum collapsed bottom border.

https://www.w3.org/TR/CSS22/tables.html#collapsing-borders

This patch implements the table box part of the border collapsing. Inner table elements need to implement collapsing as well.

* layout/LayoutState.cpp:
(WebCore::Layout::LayoutState::ensureTableFormattingState):
* layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp:
(WebCore::Layout::TableWrapperBlockFormattingContext::layoutTableBox):
(WebCore::Layout::TableWrapperBlockFormattingContext::computeBorderAndPaddingForTableBox):
(WebCore::Layout::TableWrapperBlockFormattingContext::computeWidthAndMarginForTableBox):
* layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h:
* layout/tableformatting/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::computedIntrinsicWidthConstraints):
(WebCore::Layout::TableFormattingContext::ensureTableGrid):
* layout/tableformatting/TableFormattingContext.h:
* layout/tableformatting/TableFormattingState.cpp:
(WebCore::Layout::TableFormattingState::TableFormattingState):
* layout/tableformatting/TableFormattingState.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (261809 => 261810)


--- trunk/Source/WebCore/ChangeLog	2020-05-18 12:07:00 UTC (rev 261809)
+++ trunk/Source/WebCore/ChangeLog	2020-05-18 14:01:09 UTC (rev 261810)
@@ -1,3 +1,38 @@
+2020-05-18  Zalan Bujtas  <za...@apple.com>
+
+        [LFC][TFC] Add support for computing the collapsed table border
+        https://bugs.webkit.org/show_bug.cgi?id=212003
+
+        Reviewed by Antti Koivisto.
+
+        UAs must compute an initial left and right border width for the table by examining
+        the first and last cells in the first row of the table.
+        The left border width of the table is half of the first cell's collapsed left border,
+        and the right border width of the table is half of the last cell's collapsed right border.
+        The top border width of the table is computed by examining all cells who collapse their top
+        borders with the top border of the table. The top border width of the table is equal to half of the
+        maximum collapsed top border. The bottom border width is computed by examining all cells whose bottom borders collapse
+        with the bottom of the table. The bottom border width is equal to half of the maximum collapsed bottom border.
+
+        https://www.w3.org/TR/CSS22/tables.html#collapsing-borders
+
+        This patch implements the table box part of the border collapsing. Inner table elements need to implement collapsing as well.
+
+        * layout/LayoutState.cpp:
+        (WebCore::Layout::LayoutState::ensureTableFormattingState):
+        * layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp:
+        (WebCore::Layout::TableWrapperBlockFormattingContext::layoutTableBox):
+        (WebCore::Layout::TableWrapperBlockFormattingContext::computeBorderAndPaddingForTableBox):
+        (WebCore::Layout::TableWrapperBlockFormattingContext::computeWidthAndMarginForTableBox):
+        * layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h:
+        * layout/tableformatting/TableFormattingContext.cpp:
+        (WebCore::Layout::TableFormattingContext::computedIntrinsicWidthConstraints):
+        (WebCore::Layout::TableFormattingContext::ensureTableGrid):
+        * layout/tableformatting/TableFormattingContext.h:
+        * layout/tableformatting/TableFormattingState.cpp:
+        (WebCore::Layout::TableFormattingState::TableFormattingState):
+        * layout/tableformatting/TableFormattingState.h:
+
 2020-05-18  Antoine Quint  <grao...@apple.com>
 
         Clean up media controls content for Apple platforms

Modified: trunk/Source/WebCore/layout/LayoutState.cpp (261809 => 261810)


--- trunk/Source/WebCore/layout/LayoutState.cpp	2020-05-18 12:07:00 UTC (rev 261809)
+++ trunk/Source/WebCore/layout/LayoutState.cpp	2020-05-18 14:01:09 UTC (rev 261810)
@@ -185,7 +185,7 @@
 
     auto create = [&] {
         // Table formatting context always establishes a new floating state -and it stays empty.
-        return makeUnique<TableFormattingState>(FloatingState::create(*this, formattingContextRoot), *this);
+        return makeUnique<TableFormattingState>(FloatingState::create(*this, formattingContextRoot), *this, formattingContextRoot);
     };
 
     return *m_tableFormattingStates.ensure(&formattingContextRoot, create).iterator->value;

Modified: trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp (261809 => 261810)


--- trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp	2020-05-18 12:07:00 UTC (rev 261809)
+++ trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp	2020-05-18 14:01:09 UTC (rev 261810)
@@ -28,6 +28,9 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "TableFormattingContext.h"
+#include "TableFormattingState.h"
+
 namespace WebCore {
 namespace Layout {
 
@@ -57,9 +60,11 @@
 
 void TableWrapperBlockFormattingContext::layoutTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent& constraints)
 {
-    computeBorderAndPadding(tableBox, constraints.horizontal);
+    layoutState().ensureTableFormattingState(tableBox);
+
+    computeBorderAndPaddingForTableBox(tableBox, constraints.horizontal);
     computeStaticVerticalPosition(tableBox, constraints.vertical);
-    computeWidthAndMarginForTableBox(tableBox, constraints);
+    computeWidthAndMarginForTableBox(tableBox, constraints.horizontal);
     computeStaticHorizontalPosition(tableBox, constraints.horizontal);
 
     auto invalidationState = InvalidationState { };
@@ -68,18 +73,59 @@
     computeHeightAndMarginForTableBox(tableBox, constraints);
 }
 
-void TableWrapperBlockFormattingContext::computeWidthAndMarginForTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent& constraints)
+void TableWrapperBlockFormattingContext::computeBorderAndPaddingForTableBox(const ContainerBox& tableBox, const HorizontalConstraints& horizontalConstraints)
 {
     ASSERT(tableBox.isTableBox());
+    if (tableBox.style().borderCollapse() == BorderCollapse::Collapse) {
+        // UAs must compute an initial left and right border width for the table by examining
+        // the first and last cells in the first row of the table.
+        // The left border width of the table is half of the first cell's collapsed left border,
+        // and the right border width of the table is half of the last cell's collapsed right border.
+        // The top border width of the table is computed by examining all cells who collapse their top
+        // borders with the top border of the table. The top border width of the table is equal to half of the
+        // maximum collapsed top border. The bottom border width is computed by examining all cells whose bottom borders collapse
+        // with the bottom of the table. The bottom border width is equal to half of the maximum collapsed bottom border.
+        auto& grid = layoutState().establishedTableFormattingState(tableBox).tableGrid();
+        auto tableBorder = geometry().computedBorder(tableBox);
+
+        auto& firstColumnFirstRowBox = grid.slot({ 0 , 0 })->cell().box();
+        auto leftBorder = std::max(tableBorder.horizontal.left, geometry().computedBorder(firstColumnFirstRowBox).horizontal.left);
+
+        auto& lastColumnFirstRow = grid.slot({ grid.columns().size() - 1, 0 })->cell().box();
+        auto rightBorder = std::max(tableBorder.horizontal.right, geometry().computedBorder(lastColumnFirstRow).horizontal.right);
+
+        auto topBorder = tableBorder.vertical.top;
+        auto bottomBorder = tableBorder.vertical.bottom;
+        auto lastRowIndex = grid.rows().size() - 1;
+        for (size_t columnIndex = 0; columnIndex < grid.columns().size(); ++columnIndex) {
+            auto& boxInFirstRox = grid.slot({ columnIndex, 0 })->cell().box();
+            auto& boxInLastRow = grid.slot({ columnIndex, lastRowIndex })->cell().box();
+
+            topBorder = std::max(topBorder, geometry().computedBorder(boxInFirstRox).vertical.top);
+            bottomBorder = std::max(bottomBorder, geometry().computedBorder(boxInLastRow).vertical.bottom);
+        }
+        auto collapsedBorder = Edges { { leftBorder / 2, rightBorder / 2 }, { topBorder / 2, bottomBorder / 2 } };
+
+        auto& displayBox = formattingState().displayBox(tableBox);
+        displayBox.setBorder(collapsedBorder);
+        displayBox.setPadding(geometry().computedPadding(tableBox, horizontalConstraints.logicalWidth));
+        return;
+    }
+    BlockFormattingContext::computeBorderAndPadding(tableBox, horizontalConstraints);
+}
+
+void TableWrapperBlockFormattingContext::computeWidthAndMarginForTableBox(const ContainerBox& tableBox, const HorizontalConstraints& horizontalConstraints)
+{
+    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& formattingStateForTableBox = layoutState().establishedTableFormattingState(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 computedTableWidth = geometry().computedWidth(tableBox, horizontalConstraints.logicalWidth);
     auto usedWidth = computedTableWidth;
     if (computedTableWidth && intrinsicWidthConstraints.minimum > computedTableWidth) {
         // Table content needs more space than the table has.
@@ -86,9 +132,9 @@
         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);
+        usedWidth = std::min(std::max(intrinsicWidthConstraints.minimum, horizontalConstraints.logicalWidth), intrinsicWidthConstraints.maximum);
     }
-    auto contentWidthAndMargin = geometry().inFlowWidthAndMargin(tableBox, constraints.horizontal, OverrideHorizontalValues { usedWidth, { } });
+    auto contentWidthAndMargin = geometry().inFlowWidthAndMargin(tableBox, horizontalConstraints, OverrideHorizontalValues { usedWidth, { } });
 
     auto& displayBox = formattingState().displayBox(tableBox);
     displayBox.setContentBoxWidth(contentWidthAndMargin.contentWidth);

Modified: trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h (261809 => 261810)


--- trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h	2020-05-18 12:07:00 UTC (rev 261809)
+++ trunk/Source/WebCore/layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h	2020-05-18 14:01:09 UTC (rev 261810)
@@ -45,7 +45,8 @@
 private:
     void layoutTableBox(const ContainerBox& tableBox, const ConstraintsForInFlowContent&);
 
-    void computeWidthAndMarginForTableBox(const ContainerBox&, const ConstraintsForInFlowContent&);
+    void computeBorderAndPaddingForTableBox(const ContainerBox&, const HorizontalConstraints&);
+    void computeWidthAndMarginForTableBox(const ContainerBox&, const HorizontalConstraints&);
     void computeHeightAndMarginForTableBox(const ContainerBox&, const ConstraintsForInFlowContent&);
 };
 

Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp (261809 => 261810)


--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp	2020-05-18 12:07:00 UTC (rev 261809)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp	2020-05-18 14:01:09 UTC (rev 261810)
@@ -217,22 +217,19 @@
     if (auto computedWidthConstraints = grid.widthConstraints())
         return *computedWidthConstraints;
 
-    // 1. Ensure each cell slot is occupied by at least one cell.
-    ensureTableGrid();
-    // 2. Compute the minimum/maximum width of each column.
+    // Compute the minimum/maximum width of each column.
     auto computedWidthConstraints = computedPreferredWidthForColumns();
     grid.setWidthConstraints(computedWidthConstraints);
     return computedWidthConstraints;
 }
 
-void TableFormattingContext::ensureTableGrid()
+UniqueRef<TableGrid> TableFormattingContext::ensureTableGrid(const ContainerBox& tableBox)
 {
-    auto& tableBox = root();
-    auto& tableGrid = formattingState().tableGrid();
+    auto tableGrid = makeUniqueRef<TableGrid>();
     auto& tableStyle = tableBox.style();
     auto shouldApplyBorderSpacing = tableStyle.borderCollapse() == BorderCollapse::Separate;
-    tableGrid.setHorizontalSpacing(LayoutUnit { shouldApplyBorderSpacing ? tableStyle.horizontalBorderSpacing() : 0 });
-    tableGrid.setVerticalSpacing(LayoutUnit { shouldApplyBorderSpacing ? tableStyle.verticalBorderSpacing() : 0 });
+    tableGrid->setHorizontalSpacing(LayoutUnit { shouldApplyBorderSpacing ? tableStyle.horizontalBorderSpacing() : 0 });
+    tableGrid->setVerticalSpacing(LayoutUnit { shouldApplyBorderSpacing ? tableStyle.verticalBorderSpacing() : 0 });
 
     auto* firstChild = tableBox.firstChild();
     const Box* tableCaption = nullptr;
@@ -248,7 +245,7 @@
         colgroup = colgroupCandidate;
 
     if (colgroup) {
-        auto& columns = tableGrid.columns();
+        auto& columns = tableGrid->columns();
         for (auto* column = downcast<ContainerBox>(*colgroup).firstChild(); column; column = column->nextSibling()) {
             ASSERT(column->isTableColumn());
             auto columnSpanCount = column->columnSpan();
@@ -265,10 +262,11 @@
             ASSERT(row->isTableRow());
             for (auto* cell = downcast<ContainerBox>(*row).firstChild(); cell; cell = cell->nextSibling()) {
                 ASSERT(cell->isTableCell());
-                tableGrid.appendCell(downcast<ContainerBox>(*cell));
+                tableGrid->appendCell(downcast<ContainerBox>(*cell));
             }
         }
     }
+    return tableGrid;
 }
 
 FormattingContext::IntrinsicWidthConstraints TableFormattingContext::computedPreferredWidthForColumns()

Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h (261809 => 261810)


--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h	2020-05-18 12:07:00 UTC (rev 261809)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.h	2020-05-18 14:01:09 UTC (rev 261810)
@@ -31,6 +31,7 @@
 #include "TableFormattingState.h"
 #include "TableGrid.h"
 #include <wtf/IsoMalloc.h>
+#include <wtf/UniqueRef.h>
 
 namespace WebCore {
 namespace Layout {
@@ -44,6 +45,8 @@
     TableFormattingContext(const ContainerBox& formattingContextRoot, TableFormattingState&);
     void layoutInFlowContent(InvalidationState&, const ConstraintsForInFlowContent&) override;
 
+    static UniqueRef<TableGrid> ensureTableGrid(const ContainerBox& tableBox);
+
 private:
     class TableLayout {
     public:
@@ -82,7 +85,6 @@
     void setUsedGeometryForRows(LayoutUnit availableHorizontalSpace);
     void setUsedGeometryForSections(const ConstraintsForInFlowContent&);
 
-    void ensureTableGrid();
     IntrinsicWidthConstraints computedPreferredWidthForColumns();
     void computeAndDistributeExtraSpace(LayoutUnit availableHorizontalSpace, Optional<LayoutUnit> availableVerticalSpace);
 

Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingState.cpp (261809 => 261810)


--- trunk/Source/WebCore/layout/tableformatting/TableFormattingState.cpp	2020-05-18 12:07:00 UTC (rev 261809)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingState.cpp	2020-05-18 14:01:09 UTC (rev 261810)
@@ -35,8 +35,9 @@
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(TableFormattingState);
 
-TableFormattingState::TableFormattingState(Ref<FloatingState>&& floatingState, LayoutState& layoutState)
+TableFormattingState::TableFormattingState(Ref<FloatingState>&& floatingState, LayoutState& layoutState, const ContainerBox& tableBox)
     : FormattingState(WTFMove(floatingState), Type::Table, layoutState)
+    , m_tableGrid(TableFormattingContext::ensureTableGrid(tableBox))
 {
 }
 

Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingState.h (261809 => 261810)


--- trunk/Source/WebCore/layout/tableformatting/TableFormattingState.h	2020-05-18 12:07:00 UTC (rev 261809)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingState.h	2020-05-18 14:01:09 UTC (rev 261810)
@@ -30,6 +30,7 @@
 #include "FormattingState.h"
 #include "TableGrid.h"
 #include <wtf/IsoMalloc.h>
+#include <wtf/UniqueRef.h>
 
 namespace WebCore {
 namespace Layout {
@@ -38,7 +39,7 @@
 class TableFormattingState : public FormattingState {
     WTF_MAKE_ISO_ALLOCATED(TableFormattingState);
 public:
-    TableFormattingState(Ref<FloatingState>&&, LayoutState&);
+    TableFormattingState(Ref<FloatingState>&&, LayoutState&, const ContainerBox& tableBox);
     ~TableFormattingState();
 
     TableGrid& tableGrid() { return m_tableGrid; }
@@ -45,7 +46,7 @@
     const TableGrid& tableGrid() const { return m_tableGrid; }
 
 private:
-    TableGrid m_tableGrid;
+    UniqueRef<TableGrid> m_tableGrid;
 };
 
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to