[LFC][TFC] Add support for colgroup/col
https://bugs.webkit.org/show_bug.cgi?id=202991
<rdar://problem/56294715>

Reviewed by Antti Koivisto.

This patch sets up the column context when <colgroup> is present. This is in preparation for using <col>'s width to adjust the preferred width on table columns.

* layout/layouttree/LayoutTreeBuilder.cpp:
(WebCore::Layout::TreeBuilder::createLayoutBox):
* layout/tableformatting/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::ensureTableGrid):
* layout/tableformatting/TableGrid.cpp:
(WebCore::Layout::TableGrid::Column::Column):
(WebCore::Layout::TableGrid::ColumnsContext::addColumn):
* layout/tableformatting/TableGrid.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251147 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 3549c23..35c3595 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2019-10-15  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][TFC] Add support for colgroup/col
+        https://bugs.webkit.org/show_bug.cgi?id=202991
+        <rdar://problem/56294715>
+
+        Reviewed by Antti Koivisto.
+
+        This patch sets up the column context when <colgroup> is present. This is in preparation for using <col>'s width to adjust the preferred width on table columns.
+
+        * layout/layouttree/LayoutTreeBuilder.cpp:
+        (WebCore::Layout::TreeBuilder::createLayoutBox):
+        * layout/tableformatting/TableFormattingContext.cpp:
+        (WebCore::Layout::TableFormattingContext::ensureTableGrid):
+        * layout/tableformatting/TableGrid.cpp:
+        (WebCore::Layout::TableGrid::Column::Column):
+        (WebCore::Layout::TableGrid::ColumnsContext::addColumn):
+        * layout/tableformatting/TableGrid.h:
+
 2019-10-15  Alex Christensen  <achristensen@webkit.org>
 
         Unreviewed, rolling out r251138.
diff --git a/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp b/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
index dd91cad..71928a8 100644
--- a/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
+++ b/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
@@ -187,9 +187,12 @@
             childLayoutBox = makeUnique<Container>(elementAttributes(renderer), RenderStyle::clone(renderer.style()));
         } else if (displayType == DisplayType::TableColumn) {
             childLayoutBox = makeUnique<Container>(elementAttributes(renderer), RenderStyle::clone(renderer.style()));
-            auto columnWidth = static_cast<HTMLTableColElement&>(*renderer.element()).width();
+            auto& tableColElement = static_cast<HTMLTableColElement&>(*renderer.element());
+            auto columnWidth = tableColElement.width();
             if (!columnWidth.isEmpty())
                 childLayoutBox->setColumnWidth(columnWidth.toInt());
+            if (tableColElement.span() > 1)
+                childLayoutBox->setColumnSpan(tableColElement.span());
         } else {
             ASSERT_NOT_IMPLEMENTED_YET();
             return { };
diff --git a/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp b/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp
index 2ee019c..dafdb97 100644
--- a/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp
+++ b/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp
@@ -168,7 +168,32 @@
     tableGrid.setHorizontalSpacing(LayoutUnit { tableWrapperBox.style().horizontalBorderSpacing() });
     tableGrid.setVerticalSpacing(LayoutUnit { tableWrapperBox.style().verticalBorderSpacing() });
 
-    for (auto* section = tableWrapperBox.firstChild(); section; section = section->nextSibling()) {
+    auto* firstChild = tableWrapperBox.firstChild();
+    const Box* tableCaption = nullptr;
+    const Box* colgroup = nullptr;
+    // Table caption is an optional element; if used, it is always the first child of a <table>.
+    if (firstChild->isTableCaption())
+        tableCaption = firstChild;
+    // The <colgroup> must appear after any optional <caption> element but before any <thead>, <th>, <tbody>, <tfoot> and <tr> element.
+    auto* colgroupCandidate = firstChild;
+    if (tableCaption)
+        colgroupCandidate = tableCaption->nextSibling();
+    if (colgroupCandidate->isTableColumnGroup())
+        colgroup = colgroupCandidate;
+
+    if (colgroup) {
+        auto& columnsContext = tableGrid.columnsContext();
+        for (auto* column = downcast<Container>(*colgroup).firstChild(); column; column = column->nextSibling()) {
+            ASSERT(column->isTableColumn());
+            auto columnSpanCount = column->columnSpan();
+            ASSERT(columnSpanCount > 0);
+            while (columnSpanCount--)
+                columnsContext.addColumn(column);
+        }
+    }
+
+    auto* firstSection = colgroup ? colgroup->nextSibling() : tableCaption ? tableCaption->nextSibling() : firstChild;
+    for (auto* section = firstSection; section; section = section->nextSibling()) {
         ASSERT(section->isTableHeader() || section->isTableBody() || section->isTableFooter());
         for (auto* row = downcast<Container>(*section).firstChild(); row; row = row->nextSibling()) {
             ASSERT(row->isTableRow());
diff --git a/Source/WebCore/layout/tableformatting/TableGrid.cpp b/Source/WebCore/layout/tableformatting/TableGrid.cpp
index 2717fc1..dca1916 100644
--- a/Source/WebCore/layout/tableformatting/TableGrid.cpp
+++ b/Source/WebCore/layout/tableformatting/TableGrid.cpp
@@ -35,6 +35,11 @@
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(TableGrid);
 
+TableGrid::Column::Column(const Box* columnBox)
+    : m_columnBox(makeWeakPtr(columnBox))
+{
+}
+
 void TableGrid::Column::setWidthConstraints(FormattingContext::IntrinsicWidthConstraints widthConstraints)
 {
 #ifndef NDEBUG
@@ -77,9 +82,9 @@
     return m_computedLogicalLeft;
 }
 
-void TableGrid::ColumnsContext::addColumn()
+void TableGrid::ColumnsContext::addColumn(const Box* columnBox)
 {
-    m_columns.append({ });
+    m_columns.append({ columnBox });
 }
 
 TableGrid::Row::Row(const Box& rowBox)
diff --git a/Source/WebCore/layout/tableformatting/TableGrid.h b/Source/WebCore/layout/tableformatting/TableGrid.h
index 1339df6..70694a4 100644
--- a/Source/WebCore/layout/tableformatting/TableGrid.h
+++ b/Source/WebCore/layout/tableformatting/TableGrid.h
@@ -82,11 +82,13 @@
 
     private:
         friend class ColumnsContext;
-        Column() = default;
+        Column(const Box* columnBox);
 
         FormattingContext::IntrinsicWidthConstraints m_widthConstraints;
         LayoutUnit m_computedLogicalWidth;
         LayoutUnit m_computedLogicalLeft;
+        WeakPtr<const Box> m_columnBox;
+
 #ifndef NDEBUG
         bool m_hasWidthConstraints { false };
         bool m_hasComputedWidth { false };
@@ -99,11 +101,12 @@
         using ColumnList = Vector<Column>;
         ColumnList& columns() { return m_columns; }
         const ColumnList& columns() const { return m_columns; }
+        void addColumn(const Box* columnBox = nullptr);
+
         LayoutUnit logicalWidth() const { return columns().last().logicalRight() - columns().first().logicalLeft(); }
 
     private:
         friend class TableGrid;
-        void addColumn();
 
         ColumnList m_columns;
     };