Skip to content

Commit

Permalink
[css-grid] Preserve auto repeat() in getComputedStyle() for non-grids
Browse files Browse the repository at this point in the history
Usually, the resolved value of grid-template-rows/columns is the used
value, expanding the repeat() notation. But for elements with a non-grid
display, the resolved value is just the computed value, with repeat(),
since the used value doesn't exist.
Before this patch, the repeat() was dropped, and line names after it
appeared at the wrong position or were also dropped. There was also an
assert failure in debug. This patch fixes the serialization for auto
repeat(). Integer repeat() is still expanded at computed-value time, so
it's not preserved in getComputedStyle().

Spec: https://drafts.csswg.org/css-grid/#resolved-track-list

BUG=988516

TEST=external/wpt/css/css-grid/parsing/grid-template-columns-computed-nogrid.html
TEST=external/wpt/css/css-grid/parsing/grid-template-columns-computed.html
TEST=external/wpt/css/css-grid/parsing/grid-template-rows-computed-nogrid.html
TEST=external/wpt/css/css-grid/parsing/grid-template-rows-computed.html

There are some test failures because integer repeat() is still expanded
at computed-value time (http://crbug.com/989004).

Change-Id: Ia262102472f2270cc9fed97a76f2766a1c17e931
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1724517
Commit-Queue: Oriol Brufau <obrufau@igalia.com>
Reviewed-by: Javier Fernandez <jfernandez@igalia.com>
Cr-Commit-Position: refs/heads/master@{#699793}
  • Loading branch information
Loirooriol authored and Commit Bot committed Sep 25, 2019
1 parent b58ecb3 commit f125228
Show file tree
Hide file tree
Showing 9 changed files with 497 additions and 209 deletions.
162 changes: 121 additions & 41 deletions third_party/blink/renderer/core/css/properties/computed_style_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/css/css_font_family_value.h"
#include "third_party/blink/renderer/core/css/css_font_style_range_value.h"
#include "third_party/blink/renderer/core/css/css_function_value.h"
#include "third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h"
#include "third_party/blink/renderer/core/css/css_grid_line_names_value.h"
#include "third_party/blink/renderer/core/css/css_initial_value.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
Expand Down Expand Up @@ -1128,39 +1129,61 @@ class OrderedNamedLinesCollector {
STACK_ALLOCATED();

public:
OrderedNamedLinesCollector(const ComputedStyle& style,
bool is_row_axis,
size_t auto_repeat_tracks_count)
OrderedNamedLinesCollector(const ComputedStyle& style, bool is_row_axis)
: ordered_named_grid_lines_(is_row_axis
? style.OrderedNamedGridColumnLines()
: style.OrderedNamedGridRowLines()),
ordered_named_auto_repeat_grid_lines_(
is_row_axis ? style.AutoRepeatOrderedNamedGridColumnLines()
: style.AutoRepeatOrderedNamedGridRowLines()),
insertion_point_(is_row_axis
? style.GridAutoRepeatColumnsInsertionPoint()
: style.GridAutoRepeatRowsInsertionPoint()),
auto_repeat_total_tracks_(auto_repeat_tracks_count),
auto_repeat_track_list_length_(
is_row_axis ? style.GridAutoRepeatColumns().size()
: style.GridAutoRepeatRows().size()) {}
: style.AutoRepeatOrderedNamedGridRowLines()) {}

bool IsEmpty() const {
return ordered_named_grid_lines_.IsEmpty() &&
ordered_named_auto_repeat_grid_lines_.IsEmpty();
}
void CollectLineNamesForIndex(CSSGridLineNamesValue&, size_t index) const;
virtual void CollectLineNamesForIndex(CSSGridLineNamesValue&,
size_t index) const;

private:
protected:
enum NamedLinesType { kNamedLines, kAutoRepeatNamedLines };
void AppendLines(CSSGridLineNamesValue&, size_t index, NamedLinesType) const;

const OrderedNamedGridLines& ordered_named_grid_lines_;
const OrderedNamedGridLines& ordered_named_auto_repeat_grid_lines_;
DISALLOW_COPY_AND_ASSIGN(OrderedNamedLinesCollector);
};

class OrderedNamedLinesCollectorInsideRepeat
: public OrderedNamedLinesCollector {
public:
OrderedNamedLinesCollectorInsideRepeat(const ComputedStyle& style,
bool is_row_axis)
: OrderedNamedLinesCollector(style, is_row_axis) {}
void CollectLineNamesForIndex(CSSGridLineNamesValue&,
size_t index) const override;
};

class OrderedNamedLinesCollectorInGridLayout
: public OrderedNamedLinesCollector {
public:
OrderedNamedLinesCollectorInGridLayout(const ComputedStyle& style,
bool is_row_axis,
size_t auto_repeat_tracks_count)
: OrderedNamedLinesCollector(style, is_row_axis),
insertion_point_(is_row_axis
? style.GridAutoRepeatColumnsInsertionPoint()
: style.GridAutoRepeatRowsInsertionPoint()),
auto_repeat_total_tracks_(auto_repeat_tracks_count),
auto_repeat_track_list_length_(
is_row_axis ? style.GridAutoRepeatColumns().size()
: style.GridAutoRepeatRows().size()) {}
void CollectLineNamesForIndex(CSSGridLineNamesValue&,
size_t index) const override;

private:
size_t insertion_point_;
size_t auto_repeat_total_tracks_;
size_t auto_repeat_track_list_length_;
DISALLOW_COPY_AND_ASSIGN(OrderedNamedLinesCollector);
};

// RJW
Expand All @@ -1183,11 +1206,25 @@ void OrderedNamedLinesCollector::AppendLines(
}
}

// RJW
void OrderedNamedLinesCollector::CollectLineNamesForIndex(
CSSGridLineNamesValue& line_names_value,
size_t i) const {
DCHECK(!IsEmpty());
AppendLines(line_names_value, i, kNamedLines);
}

void OrderedNamedLinesCollectorInsideRepeat::CollectLineNamesForIndex(
CSSGridLineNamesValue& line_names_value,
size_t i) const {
DCHECK(!IsEmpty());
AppendLines(line_names_value, i, kAutoRepeatNamedLines);
}

// RJW
void OrderedNamedLinesCollectorInGridLayout::CollectLineNamesForIndex(
CSSGridLineNamesValue& line_names_value,
size_t i) const {
DCHECK(!IsEmpty());
if (ordered_named_auto_repeat_grid_lines_.IsEmpty() || i < insertion_point_) {
AppendLines(line_names_value, i, kNamedLines);
return;
Expand Down Expand Up @@ -1249,6 +1286,31 @@ CSSValue* ComputedStyleUtils::ValueForGridTrackSizeList(
return list;
}

template <typename T, typename F>
void PopulateGridTrackList(CSSValueList* list,
OrderedNamedLinesCollector& collector,
const Vector<T>& tracks,
F getTrackSize,
wtf_size_t start,
wtf_size_t end,
size_t offset = 0) {
DCHECK_LE(end, tracks.size());
for (wtf_size_t i = start; i < end; ++i) {
AddValuesForNamedGridLinesAtIndex(collector, i + offset, *list);
list->Append(*getTrackSize(tracks[i]));
}
AddValuesForNamedGridLinesAtIndex(collector, end + offset, *list);
}

template <typename T, typename F>
void PopulateGridTrackList(CSSValueList* list,
OrderedNamedLinesCollector& collector,
const Vector<T>& tracks,
F getTrackSize) {
PopulateGridTrackList<T>(list, collector, tracks, getTrackSize, 0,
tracks.size());
}

CSSValue* ComputedStyleUtils::ValueForGridTrackList(
GridTrackSizingDirection direction,
const LayoutObject* layout_object,
Expand All @@ -1275,36 +1337,54 @@ CSSValue* ComputedStyleUtils::ValueForGridTrackList(
if (track_list_is_empty)
return CSSIdentifierValue::Create(CSSValueID::kNone);

size_t auto_repeat_total_tracks =
is_layout_grid
? ToLayoutGrid(layout_object)->AutoRepeatCountForDirection(direction)
: 0;
OrderedNamedLinesCollector collector(style, is_row_axis,
auto_repeat_total_tracks);
CSSValueList* list = CSSValueList::CreateSpaceSeparated();
wtf_size_t insertion_index;

// If the element is a grid container, the resolved value is the used value,
// specifying track sizes in pixels and expanding the repeat() notation.
if (is_layout_grid) {
const auto* grid = ToLayoutGrid(layout_object);
Vector<LayoutUnit> computed_track_sizes =
grid->TrackSizesForComputedStyle(direction);
wtf_size_t num_tracks = computed_track_sizes.size();

for (wtf_size_t i = 0; i < num_tracks; ++i) {
AddValuesForNamedGridLinesAtIndex(collector, i, *list);
list->Append(*ZoomAdjustedPixelValue(computed_track_sizes[i], style));
}
AddValuesForNamedGridLinesAtIndex(collector, num_tracks + 1, *list);
OrderedNamedLinesCollectorInGridLayout collector(
style, is_row_axis, grid->AutoRepeatCountForDirection(direction));
PopulateGridTrackList(
list, collector, grid->TrackSizesForComputedStyle(direction),
[&](const LayoutUnit& v) { return ZoomAdjustedPixelValue(v, style); });
return list;
}

// Otherwise, the resolved value is the computed value, preserving repeat().
OrderedNamedLinesCollector collector(style, is_row_axis);
auto getTrackSize = [&](const GridTrackSize& v) {
return SpecifiedValueForGridTrackSize(v, style);
};

insertion_index = num_tracks;
} else {
for (wtf_size_t i = 0; i < track_sizes.size(); ++i) {
AddValuesForNamedGridLinesAtIndex(collector, i, *list);
list->Append(*SpecifiedValueForGridTrackSize(track_sizes[i], style));
}
insertion_index = track_sizes.size();
}
// Those are the trailing <string>* allowed in the syntax.
AddValuesForNamedGridLinesAtIndex(collector, insertion_index, *list);
if (auto_repeat_track_sizes.IsEmpty()) {
// If there's no auto repeat(), just add all the line names and track sizes.
PopulateGridTrackList(list, collector, track_sizes, getTrackSize);
return list;
}

// Add the line names and track sizes that precede the auto repeat().
size_t auto_repeat_insertion_point =
is_row_axis ? style.GridAutoRepeatColumnsInsertionPoint()
: style.GridAutoRepeatRowsInsertionPoint();
PopulateGridTrackList(list, collector, track_sizes, getTrackSize, 0,
auto_repeat_insertion_point);

// Add a CSSGridAutoRepeatValue with the contents of the auto repeat().
AutoRepeatType auto_repeat_type = is_row_axis
? style.GridAutoRepeatColumnsType()
: style.GridAutoRepeatRowsType();
CSSValueList* repeated_values = MakeGarbageCollected<CSSGridAutoRepeatValue>(
auto_repeat_type == AutoRepeatType::kAutoFill ? CSSValueID::kAutoFill
: CSSValueID::kAutoFit);
OrderedNamedLinesCollectorInsideRepeat repeat_collector(style, is_row_axis);
PopulateGridTrackList(repeated_values, repeat_collector,
auto_repeat_track_sizes, getTrackSize);
list->Append(*repeated_values);

// Add the line names and track sizes that follow the auto repeat().
PopulateGridTrackList(list, collector, track_sizes, getTrackSize,
auto_repeat_insertion_point, track_sizes.size(), 1);
return list;
}

Expand Down
Loading

0 comments on commit f125228

Please sign in to comment.