Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(299)

Unified Diff: third_party/WebKit/Source/core/layout/LayoutTable.cpp

Issue 2884573002: Replace LayoutTableCell::AbsoluteColumnIndex() with EffectiveColumnIndex()
Patch Set: - Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/LayoutTable.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index 3e64f7298ab2b4bdaaceb428a285793cb3c289cd..eef3dd5c0faaf05b0e396947cf4ccfb07371c292 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -58,10 +58,10 @@ LayoutTable::LayoutTable(Element* element)
first_body_(nullptr),
collapsed_borders_valid_(false),
needs_invalidate_collapsed_borders_for_all_cells_(false),
- has_col_elements_(false),
needs_section_recalc_(false),
column_logical_width_changed_(false),
- column_layout_objects_valid_(false),
+ // This is initially true because we don't have column elements initially.
+ cols_at_effective_columns_valid_(true),
no_cell_colspan_at_least_(0),
h_spacing_(0),
v_spacing_(0),
@@ -136,10 +136,7 @@ static inline bool NeedsTableSection(LayoutObject* object) {
void LayoutTable::AddChild(LayoutObject* child, LayoutObject* before_child) {
bool wrap_in_anonymous_section = !child->IsOutOfFlowPositioned();
- if (child->IsTableCaption()) {
- wrap_in_anonymous_section = false;
- } else if (child->IsLayoutTableCol()) {
- has_col_elements_ = true;
+ if (child->IsTableCaption() || child->IsLayoutTableCol()) {
wrap_in_anonymous_section = false;
} else if (child->IsTableSection()) {
switch (child->Style()->Display()) {
@@ -236,21 +233,17 @@ void LayoutTable::RemoveCaption(const LayoutTableCaption* old_caption) {
captions_.erase(index);
}
-void LayoutTable::InvalidateCachedColumns() {
- column_layout_objects_valid_ = false;
- column_layout_objects_.resize(0);
+void LayoutTable::InvalidateColsAtEffectiveColumns() const {
+ cols_at_effective_columns_valid_ = false;
+ cols_at_effective_columns_ = nullptr;
}
void LayoutTable::AddColumn(const LayoutTableCol*) {
- InvalidateCachedColumns();
+ InvalidateColsAtEffectiveColumns();
}
void LayoutTable::RemoveColumn(const LayoutTableCol*) {
- InvalidateCachedColumns();
- // We don't really need to recompute our sections, but we need to update our
- // column count and whether we have a column. Currently, we only have one
- // size-fit-all flag but we may have to consider splitting it.
- SetNeedsSectionRecalc();
+ InvalidateColsAtEffectiveColumns();
}
bool LayoutTable::IsLogicalWidthAuto() const {
@@ -1009,6 +1002,8 @@ void LayoutTable::SplitEffectiveColumn(unsigned index, unsigned first_span) {
}
effective_column_positions_.Grow(NumEffectiveColumns() + 1);
+
+ InvalidateColsAtEffectiveColumns();
}
void LayoutTable::AppendEffectiveColumn(unsigned span) {
@@ -1038,6 +1033,8 @@ void LayoutTable::AppendEffectiveColumn(unsigned span) {
}
effective_column_positions_.Grow(NumEffectiveColumns() + 1);
+
+ InvalidateColsAtEffectiveColumns();
}
LayoutTableCol* LayoutTable::FirstColumn() const {
@@ -1050,60 +1047,72 @@ LayoutTableCol* LayoutTable::FirstColumn() const {
return nullptr;
}
-void LayoutTable::UpdateColumnCache() const {
- DCHECK(has_col_elements_);
- DCHECK(column_layout_objects_.IsEmpty());
- DCHECK(!column_layout_objects_valid_);
+LayoutTableCol* LayoutTable::FirstInnermostColumn() const {
+ auto* col = FirstColumn();
+ return !col || col->IsInnermost() ? col : col->NextInnermostColumn();
+}
- for (LayoutTableCol* column_layout_object = FirstColumn();
- column_layout_object;
- column_layout_object = column_layout_object->NextColumn()) {
- if (column_layout_object->IsTableColumnGroupWithColumnChildren())
- continue;
- column_layout_objects_.push_back(column_layout_object);
- }
- column_layout_objects_valid_ = true;
-}
-
-LayoutTable::ColAndColGroup LayoutTable::SlowColElementAtAbsoluteColumn(
- unsigned absolute_column_index) const {
- DCHECK(has_col_elements_);
-
- if (!column_layout_objects_valid_)
- UpdateColumnCache();
-
- unsigned column_count = 0;
- for (unsigned i = 0; i < column_layout_objects_.size(); i++) {
- LayoutTableCol* column_layout_object = column_layout_objects_[i];
- DCHECK(!column_layout_object->IsTableColumnGroupWithColumnChildren());
- unsigned span = column_layout_object->Span();
- unsigned start_col = column_count;
- DCHECK_GE(span, 1u);
- unsigned end_col = column_count + span - 1;
- column_count += span;
- if (column_count > absolute_column_index) {
- ColAndColGroup col_and_col_group;
- bool is_at_start_edge = start_col == absolute_column_index;
- bool is_at_end_edge = end_col == absolute_column_index;
- if (column_layout_object->IsTableColumnGroup()) {
- col_and_col_group.colgroup = column_layout_object;
- col_and_col_group.adjoins_start_border_of_col_group = is_at_start_edge;
- col_and_col_group.adjoins_end_border_of_col_group = is_at_end_edge;
- } else {
- col_and_col_group.col = column_layout_object;
- col_and_col_group.colgroup =
- column_layout_object->EnclosingColumnGroup();
- if (col_and_col_group.colgroup) {
- col_and_col_group.adjoins_start_border_of_col_group =
- is_at_start_edge && !col_and_col_group.col->PreviousSibling();
- col_and_col_group.adjoins_end_border_of_col_group =
- is_at_end_edge && !col_and_col_group.col->NextSibling();
- }
+void LayoutTable::UpdateColsAtEffectiveColumns() const {
+ DCHECK(!NeedsSectionRecalc());
+ DCHECK(!cols_at_effective_columns_valid_);
+ DCHECK(!cols_at_effective_columns_);
+
+ cols_at_effective_columns_valid_ = true;
+ auto* col = FirstInnermostColumn();
+ if (!col)
+ return;
+
+ cols_at_effective_columns_ = WTF::MakeUnique<Vector<ColAndColGroup>>();
+
+ unsigned absolute_column_index = 0;
+ unsigned col_absolute_column_index = 0;
+ unsigned next_col_absolute_column_index = col->Span();
+ for (unsigned effective_column_index = 0;
+ col && effective_column_index < effective_columns_.size();
+ effective_column_index++) {
+ unsigned next_absolute_column_index =
+ absolute_column_index + effective_columns_[effective_column_index].span;
+ bool is_at_start_edge = absolute_column_index == col_absolute_column_index;
+ bool is_at_end_edge =
+ next_absolute_column_index == next_col_absolute_column_index;
+ ColAndColGroup col_and_col_group;
+ if (col->IsTableColumnGroup()) {
+ col_and_col_group.colgroup = col;
+ col_and_col_group.adjoins_start_border_of_col_group = is_at_start_edge;
+ col_and_col_group.adjoins_end_border_of_col_group = is_at_end_edge;
+ } else {
+ col_and_col_group.col = col;
+ col_and_col_group.colgroup = col->EnclosingColumnGroup();
+ if (col_and_col_group.colgroup) {
+ col_and_col_group.adjoins_start_border_of_col_group =
+ is_at_start_edge && !col->PreviousSibling();
+ col_and_col_group.adjoins_end_border_of_col_group =
+ is_at_end_edge && !col->NextSibling();
}
- return col_and_col_group;
}
+
+ // Skip useless col objects that don't generate effective columns.
+ while (next_absolute_column_index >= next_col_absolute_column_index) {
+ if (next_col_absolute_column_index == next_absolute_column_index &&
+ !col_and_col_group.adjoins_end_border_of_col_group &&
+ col_and_col_group.colgroup == col->EnclosingColumnGroup()) {
+ // Special case: the effective column adjoins the end border of
+ // col_and_col_group.colgroup though it doesn't adjoin the end border of
+ // col_and_col_group.col. All subsequent cols of col_and_col_group.col
+ // don't generate new effective columns.
+ col_and_col_group.adjoins_end_border_of_col_group = true;
+ }
+
+ col_absolute_column_index = next_col_absolute_column_index;
+ col = col->NextInnermostColumn();
+ if (!col)
+ break;
+ next_col_absolute_column_index += col->Span();
+ }
+
+ absolute_column_index = next_absolute_column_index;
+ cols_at_effective_columns_->push_back(col_and_col_group);
}
- return ColAndColGroup();
}
void LayoutTable::RecalcSections() const {
@@ -1112,17 +1121,12 @@ void LayoutTable::RecalcSections() const {
head_ = nullptr;
foot_ = nullptr;
first_body_ = nullptr;
- has_col_elements_ = false;
// We need to get valid pointers to caption, head, foot and first body again
LayoutObject* next_sibling;
for (LayoutObject* child = FirstChild(); child; child = next_sibling) {
next_sibling = child->NextSibling();
switch (child->Style()->Display()) {
- case EDisplay::kTableColumn:
- case EDisplay::kTableColumnGroup:
- has_col_elements_ = true;
- break;
case EDisplay::kTableHeaderGroup:
if (child->IsTableSection()) {
LayoutTableSection* section = ToLayoutTableSection(child);
@@ -1163,7 +1167,7 @@ void LayoutTable::RecalcSections() const {
child = child->NextSibling()) {
if (child->IsTableSection()) {
LayoutTableSection* section = ToLayoutTableSection(child);
- unsigned section_cols = section->NumEffectiveColumns();
+ unsigned section_cols = section->MaxNumEffectiveColumnsOfRows();
if (section_cols > max_cols)
max_cols = section_cols;
}
@@ -1173,6 +1177,8 @@ void LayoutTable::RecalcSections() const {
effective_column_positions_.resize(max_cols + 1);
no_cell_colspan_at_least_ = CalcNoCellColspanAtLeast();
+ InvalidateColsAtEffectiveColumns();
+
DCHECK(SelfNeedsLayout());
needs_section_recalc_ = false;
@@ -1198,7 +1204,7 @@ int LayoutTable::CalcBorderStart() const {
// TODO(dgrogan): This logic doesn't properly account for the first column in
// the first column-group case.
if (LayoutTableCol* column =
- ColElementAtAbsoluteColumn(0).InnermostColOrColGroup()) {
+ ColAndColGroupAtEffectiveColumn(0).InnermostColOrColGroup()) {
// FIXME: We don't account for direction on columns and column groups.
const BorderValue& column_adjoining_border = column->Style()->BorderStart();
if (column_adjoining_border.Style() == EBorderStyle::kHidden)
@@ -1266,8 +1272,8 @@ int LayoutTable::CalcBorderEnd() const {
// TODO(dgrogan): This logic doesn't properly account for the last column in
// the last column-group case.
- if (LayoutTableCol* column =
- ColElementAtAbsoluteColumn(end_column).InnermostColOrColGroup()) {
+ if (LayoutTableCol* column = ColAndColGroupAtEffectiveColumn(end_column)
+ .InnermostColOrColGroup()) {
// FIXME: We don't account for direction on columns and column groups.
const BorderValue& column_adjoining_border = column->Style()->BorderEnd();
if (column_adjoining_border.Style() == EBorderStyle::kHidden)
@@ -1511,11 +1517,8 @@ LayoutTableCell* LayoutTable::CellAbove(const LayoutTableCell* cell) const {
}
// Look up the cell in the section's grid, which requires effective col index
- if (section) {
- unsigned eff_col =
- AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex());
- return section->PrimaryCellAt(r_above, eff_col);
- }
+ if (section)
+ return section->PrimaryCellAt(r_above, cell->EffectiveColumnIndex());
return nullptr;
}
@@ -1537,33 +1540,27 @@ LayoutTableCell* LayoutTable::CellBelow(const LayoutTableCell* cell) const {
}
// Look up the cell in the section's grid, which requires effective col index
- if (section) {
- unsigned eff_col =
- AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex());
- return section->PrimaryCellAt(r_below, eff_col);
- }
+ if (section)
+ return section->PrimaryCellAt(r_below, cell->EffectiveColumnIndex());
return nullptr;
}
LayoutTableCell* LayoutTable::CellBefore(const LayoutTableCell* cell) const {
RecalcSectionsIfNeeded();
- LayoutTableSection* section = cell->Section();
- unsigned eff_col =
- AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex());
+ unsigned eff_col = cell->EffectiveColumnIndex();
if (!eff_col)
return nullptr;
// If we hit a colspan back up to a real cell.
- return section->PrimaryCellAt(cell->RowIndex(), eff_col - 1);
+ return cell->Section()->PrimaryCellAt(cell->RowIndex(), eff_col - 1);
}
LayoutTableCell* LayoutTable::CellAfter(const LayoutTableCell* cell) const {
RecalcSectionsIfNeeded();
- unsigned eff_col = AbsoluteColumnToEffectiveColumn(
- cell->AbsoluteColumnIndex() + cell->ColSpan());
- return cell->Section()->PrimaryCellAt(cell->RowIndex(), eff_col);
+ return cell->Section()->PrimaryCellAt(
+ cell->RowIndex(), cell->EffectiveColumnIndexOfCellAfter());
}
int LayoutTable::BaselinePosition(FontBaseline baseline_type,
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutTable.h ('k') | third_party/WebKit/Source/core/layout/LayoutTableCell.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698