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;
};
}