diff options
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.cc | 139 |
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; } } |