summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc139
1 files changed, 99 insertions, 40 deletions
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc
index aea92d5ccbf..3c80c8775fa 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.cc
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/platform/geometry/calculation_value.h"
namespace blink {
@@ -51,8 +52,15 @@ inline void InlineSizesFromStyle(
if (*min_inline_size)
*max_inline_size = std::max(**min_inline_size, **max_inline_size);
}
- if (length.IsPercent())
+ if (length.IsPercent()) {
*percentage_inline_size = length.Percent();
+ } else if (length.IsCalculated() &&
+ !length.GetCalculationValue().IsExpression()) {
+ // crbug.com/1154376 Style engine should handle %+0px case automatically.
+ PixelsAndPercent pixels_and_percent = length.GetPixelsAndPercent();
+ if (pixels_and_percent.pixels == 0.0f)
+ *percentage_inline_size = pixels_and_percent.percent;
+ }
if (*percentage_inline_size && max_length.IsPercent()) {
*percentage_inline_size =
@@ -70,7 +78,8 @@ constexpr LayoutUnit NGTableTypes::kTableMaxInlineSize;
// "outer min-content and outer max-content widths for colgroups"
NGTableTypes::Column NGTableTypes::CreateColumn(
const ComputedStyle& style,
- base::Optional<LayoutUnit> default_inline_size) {
+ base::Optional<LayoutUnit> default_inline_size,
+ bool is_table_fixed) {
base::Optional<LayoutUnit> inline_size;
base::Optional<LayoutUnit> min_inline_size;
base::Optional<LayoutUnit> max_inline_size;
@@ -78,6 +87,7 @@ NGTableTypes::Column NGTableTypes::CreateColumn(
InlineSizesFromStyle(style, /* inline_border_padding */ LayoutUnit(),
/* is_parallel */ true, &inline_size, &min_inline_size,
&max_inline_size, &percentage_inline_size);
+ bool is_mergeable;
if (!inline_size)
inline_size = default_inline_size;
if (min_inline_size && inline_size)
@@ -86,12 +96,16 @@ NGTableTypes::Column NGTableTypes::CreateColumn(
if (percentage_inline_size && *percentage_inline_size == 0.0f)
percentage_inline_size.reset();
bool is_collapsed = style.Visibility() == EVisibility::kCollapse;
- return Column{min_inline_size.value_or(LayoutUnit()),
- inline_size,
+ if (is_table_fixed) {
+ is_mergeable = false;
+ } else {
+ is_mergeable = (inline_size.value_or(LayoutUnit()) == LayoutUnit()) &&
+ (percentage_inline_size.value_or(0.0f) == 0.0f);
+ }
+ return Column(min_inline_size.value_or(LayoutUnit()), inline_size,
percentage_inline_size,
- LayoutUnit() /* percent_border_padding */,
- is_constrained,
- is_collapsed};
+ LayoutUnit() /* percent_border_padding */, is_constrained,
+ is_collapsed, is_table_fixed, is_mergeable);
}
// Implements https://www.w3.org/TR/css-tables-3/#computing-cell-measures
@@ -134,8 +148,7 @@ NGTableTypes::CellInlineConstraint NGTableTypes::CreateCellInlineConstraint(
builder.SetOrthogonalFallbackInlineSize(
IsHorizontalWritingMode(table_writing_mode) ? icb_size.height
: icb_size.width);
-
- builder.SetIsShrinkToFit(style.LogicalWidth().IsAuto());
+ builder.SetAvailableSize({kIndefiniteSize, kIndefiniteSize});
}
NGConstraintSpace space = builder.ToConstraintSpace();
// It'd be nice to avoid computing minmax if not needed, but the criteria
@@ -199,7 +212,8 @@ NGTableTypes::Section NGTableTypes::CreateSection(
const NGLayoutInputNode& section,
wtf_size_t start_row,
wtf_size_t rows,
- LayoutUnit block_size) {
+ LayoutUnit block_size,
+ bool treat_as_tbody) {
const Length& section_css_block_size = section.Style().LogicalHeight();
// TODO(crbug.com/1105272): Decide what to do with |Length::IsCalculated()|.
bool is_constrained =
@@ -207,14 +221,12 @@ NGTableTypes::Section NGTableTypes::CreateSection(
base::Optional<float> percent;
if (section_css_block_size.IsPercent())
percent = section_css_block_size.Percent();
- bool is_tbody =
- section.GetDOMNode()->HasTagName(html_names::kTbodyTag);
return Section{start_row,
rows,
block_size,
percent,
is_constrained,
- is_tbody,
+ treat_as_tbody,
/* needs_redistribution */ false};
}
@@ -267,8 +279,6 @@ void NGTableTypes::CellInlineConstraint::Encompass(
max_inline_size = std::max(min_inline_size, other.max_inline_size);
}
is_constrained = is_constrained || other.is_constrained;
- max_inline_size = std::max(max_inline_size, other.max_inline_size);
- percent = std::max(percent, other.percent);
if (other.percent > percent) {
percent = other.percent;
percent_border_padding = other.percent_border_padding;
@@ -280,6 +290,11 @@ void NGTableTypes::Column::Encompass(
if (!cell)
return;
+ // Constrained columns in fixed tables take precedence over cells.
+ if (is_constrained && is_table_fixed)
+ return;
+ if (!is_table_fixed)
+ is_mergeable = false;
if (min_inline_size) {
if (min_inline_size < cell->min_inline_size) {
min_inline_size = cell->min_inline_size;
@@ -308,7 +323,8 @@ void NGTableTypes::Column::Encompass(
is_constrained |= cell->is_constrained;
}
-NGTableGroupedChildren::NGTableGroupedChildren(const NGBlockNode& table) {
+NGTableGroupedChildren::NGTableGroupedChildren(const NGBlockNode& table)
+ : header(NGBlockNode(nullptr)), footer(NGBlockNode(nullptr)) {
for (NGLayoutInputNode child = table.FirstChild(); child;
child = child.NextSibling()) {
NGBlockNode block_child = To<NGBlockNode>(child);
@@ -321,13 +337,19 @@ NGTableGroupedChildren::NGTableGroupedChildren(const NGBlockNode& table) {
columns.push_back(block_child);
break;
case EDisplay::kTableHeaderGroup:
- headers.push_back(block_child);
+ if (!header)
+ header = block_child;
+ else
+ bodies.push_back(block_child);
break;
case EDisplay::kTableRowGroup:
bodies.push_back(block_child);
break;
case EDisplay::kTableFooterGroup:
- footers.push_back(block_child);
+ if (!footer)
+ footer = block_child;
+ else
+ bodies.push_back(block_child);
break;
default:
NOTREACHED() << "unexpected table child";
@@ -347,30 +369,57 @@ NGTableGroupedChildrenIterator NGTableGroupedChildren::end() const {
NGTableGroupedChildrenIterator::NGTableGroupedChildrenIterator(
const NGTableGroupedChildren& grouped_children,
bool is_end)
- : grouped_children_(grouped_children), current_vector_(nullptr) {
+ : grouped_children_(grouped_children) {
if (is_end) {
- current_vector_ = &grouped_children_.footers;
- current_iterator_ = current_vector_->end();
+ current_section_ = kEnd;
return;
}
+ current_section_ = kNone;
AdvanceToNonEmptySection();
}
NGTableGroupedChildrenIterator& NGTableGroupedChildrenIterator::operator++() {
- ++current_iterator_;
- if (current_iterator_ == current_vector_->end())
- AdvanceToNonEmptySection();
+ switch (current_section_) {
+ case kHead:
+ case kFoot:
+ AdvanceToNonEmptySection();
+ break;
+ case kBody:
+ ++body_iterator_;
+ if (body_iterator_ == grouped_children_.bodies.end())
+ AdvanceToNonEmptySection();
+ break;
+ case kEnd:
+ break;
+ case kNone:
+ NOTREACHED();
+ break;
+ }
return *this;
}
NGBlockNode NGTableGroupedChildrenIterator::operator*() const {
- return *current_iterator_;
+ switch (current_section_) {
+ case kHead:
+ return grouped_children_.header;
+ case kFoot:
+ return grouped_children_.footer;
+ case kBody:
+ return *body_iterator_;
+ case kEnd:
+ case kNone:
+ NOTREACHED();
+ return NGBlockNode(nullptr);
+ }
}
bool NGTableGroupedChildrenIterator::operator==(
const NGTableGroupedChildrenIterator& rhs) const {
- return rhs.current_vector_ == current_vector_ &&
- rhs.current_iterator_ == current_iterator_;
+ if (current_section_ != rhs.current_section_)
+ return false;
+ if (current_section_ == kBody)
+ return rhs.body_iterator_ == body_iterator_;
+ return true;
}
bool NGTableGroupedChildrenIterator::operator!=(
@@ -379,19 +428,29 @@ bool NGTableGroupedChildrenIterator::operator!=(
}
void NGTableGroupedChildrenIterator::AdvanceToNonEmptySection() {
- if (current_vector_ == &grouped_children_.footers)
- return;
- if (!current_vector_) {
- current_vector_ = &grouped_children_.headers;
- } else if (current_vector_ == &grouped_children_.headers) {
- current_vector_ = &grouped_children_.bodies;
- } else if (current_vector_ == &grouped_children_.bodies) {
- current_vector_ = &grouped_children_.footers;
- }
- current_iterator_ = current_vector_->begin();
- // If new group is empty, recursively advance.
- if (current_iterator_ == current_vector_->end()) {
- AdvanceToNonEmptySection();
+ switch (current_section_) {
+ case kNone:
+ current_section_ = kHead;
+ if (!grouped_children_.header)
+ AdvanceToNonEmptySection();
+ break;
+ case kHead:
+ current_section_ = kBody;
+ body_iterator_ = grouped_children_.bodies.begin();
+ if (body_iterator_ == grouped_children_.bodies.end())
+ AdvanceToNonEmptySection();
+ break;
+ case kBody:
+ current_section_ = kFoot;
+ if (!grouped_children_.footer)
+ AdvanceToNonEmptySection();
+ break;
+ case kFoot:
+ current_section_ = kEnd;
+ break;
+ case kEnd:
+ NOTREACHED();
+ break;
}
}