Skip to content

Commit

Permalink
Merge pull request #2162 from Kozea/grid-auto-flow-column
Browse files Browse the repository at this point in the history
Support grid-auto-flow: column
  • Loading branch information
liZe authored Jun 3, 2024
2 parents 21829a2 + f29ff1c commit bcf779d
Show file tree
Hide file tree
Showing 4 changed files with 465 additions and 208 deletions.
106 changes: 106 additions & 0 deletions tests/css/test_expanders.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,112 @@ def test_grid_area_invalid(rule):
assert_invalid(f'grid-area: {rule}')


@assert_no_logs
@pytest.mark.parametrize('rule, result', (
('none', {
'rows': 'none', 'columns': 'none', 'areas': 'none',
}),
('subgrid / [outer-edge] 20px [main-start]', {
'rows': ('subgrid', ()),
'columns': (('outer-edge',), (20, 'px'), ('main-start',)),
'areas': 'none',
}),
('repeat(2, [e] 40px) repeat(5, auto) / subgrid [a] repeat(auto-fill, [b])', {
'rows': (
(), ('repeat()', 2, (('e',), (40, 'px'), ())), (),
('repeat()', 5, ((), 'auto', ())), ()),
'columns': ('subgrid', (('a',), ('repeat()', 'auto-fill', (('b',),)))),
'areas': 'none',
}),
# TODO: support last syntax
# ('[a b] "x y y" [c] [d] "x y y" 1fr [e] / auto 2fr auto', {
# 'rows': 'none', 'columns': 'none', 'areas': 'none',
# }),
# ('[a b c] "x x x" 2fr', {
# 'rows': 'none', 'columns': 'none', 'areas': 'none',
# }),
))
def test_grid_template(rule, result):
assert expand_to_dict(f'grid-template: {rule}') == dict(
(f'grid_template_{key}', value) for key, value in result.items())

@assert_no_logs
@pytest.mark.parametrize('rule', (
'none none',
'auto',
'subgrid / subgrid / subgrid',
'[a] 1px [b] / none /',
'[a] 1px [b] // none',
'[a] 1px [b] none',
))
def test_grid_template_invalid(rule):
assert_invalid(f'grid-template: {rule}')


@assert_no_logs
@pytest.mark.parametrize('rule, result', (
('none', {
'template_rows': 'none', 'template_columns': 'none',
'template_areas': 'none',
'auto_rows': ('auto',), 'auto_columns': ('auto',),
'auto_flow': ('row',),
}),
('subgrid / [outer-edge] 20px [main-start]', {
'template_rows': ('subgrid', ()),
'template_columns': (('outer-edge',), (20, 'px'), ('main-start',)),
'template_areas': 'none',
'auto_rows': ('auto',), 'auto_columns': ('auto',),
'auto_flow': ('row',),
}),
('repeat(2, [e] 40px) repeat(5, auto) / subgrid [a] repeat(auto-fill, [b])', {
'template_rows': (
(), ('repeat()', 2, (('e',), (40, 'px'), ())), (),
('repeat()', 5, ((), 'auto', ())), ()),
'template_columns': ('subgrid', (('a',), ('repeat()', 'auto-fill', (('b',),)))),
'template_areas': 'none',
'auto_rows': ('auto',), 'auto_columns': ('auto',),
'auto_flow': ('row',),
}),
('auto-flow 1fr / 100px', {
'template_rows': 'none', 'template_columns': ((), (100, 'px'), ()),
'template_areas': 'none',
'auto_rows': ((1, 'fr'),), 'auto_columns': ('auto',),
'auto_flow': ('row',),
}),
('none / dense auto-flow 1fr', {
'template_rows': 'none', 'template_columns': 'none',
'template_areas': 'none',
'auto_rows': ('auto',), 'auto_columns': ((1, 'fr'),),
'auto_flow': ('column', 'dense'),
}),
# TODO: support last grid-template syntax
# ('[a b] "x y y" [c] [d] "x y y" 1fr [e] / auto 2fr auto', {
# }),
# ('[a b c] "x x x" 2fr', {
# }),
))
def test_grid(rule, result):
assert expand_to_dict(f'grid: {rule}') == dict(
(f'grid_{key}', value) for key, value in result.items())


@assert_no_logs
@pytest.mark.parametrize('rule', (
'none none',
'auto',
'subgrid / subgrid / subgrid',
'[a] 1px [b] / none /',
'[a] 1px [b] // none',
'[a] 1px [b] none',
'none / auto-flow 1fr dense',
'none / dense 1fr auto-flow',
'100px auto-flow / none',
'dense 100px / auto-flow 1fr'
))
def test_grid_invalid(rule):
assert_invalid(f'grid: {rule}')


@assert_no_logs
@pytest.mark.parametrize('rule, result', (
('page-break-after: left', {'break_after': 'left'}),
Expand Down
120 changes: 109 additions & 11 deletions tests/layout/test_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ def test_grid_rows():
assert div_a.position_x == div_b.position_x == div_c.position_x == 0
assert div_a.position_y < div_b.position_y < div_c.position_y
assert div_a.height == div_b.height == div_c.height
assert article.width == html.width
assert div_a.width == div_b.width == div_c.width == html.width
assert div_a.width == div_b.width == div_c.width == html.width == article.width


@assert_no_logs
Expand Down Expand Up @@ -357,6 +356,7 @@ def test_grid_template_areas_extra_span_dense():
assert div_a.width == div_b.width == div_c.width == div_f.width == 3
assert div_d.width == div_e.width == 6
assert {div.height for div in article.children} == {2}
assert article.height == 6
assert article.width == 9


Expand Down Expand Up @@ -509,19 +509,50 @@ def test_grid_shorthand_auto_flow_rows_fr_size():
assert article.width == 10


def test_grid_shorthand_auto_flow_columns_none_dense():
@assert_no_logs
def test_grid_template_fr_too_large():
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
article {
display: grid;
font-family: weasyprint;
font-size: 2px;
grid: none / auto-flow 1fr dense;
grid-template-columns: 1fr 1fr;
line-height: 1;
width: 10px;
}
</style>
<article>
<div>a</div><div>bbb</div>
</article>
''')
html, = page.children
body, = html.children
article, = body.children
div_a, div_b = article.children
assert div_a.position_x == 0
assert div_b.position_x == 4
assert div_a.position_y == div_b.position_y == 0
assert div_a.height == div_b.height == 2
assert div_a.width == 4
assert div_b.width == 6
assert article.width == 10


def test_grid_shorthand_auto_flow_columns_none_dense():
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
article {
display: grid;
font-family: weasyprint;
font-size: 2px;
grid: none / auto-flow dense 1fr;
line-height: 1;
width: 12px;
}
</style>
<article>
<div>a</div>
<div>b</div>
Expand All @@ -532,13 +563,13 @@ def test_grid_shorthand_auto_flow_columns_none_dense():
body, = html.children
article, = body.children
div_a, div_b, div_c = article.children
assert div_a.position_x == div_b.position_x == div_c.position_x == 0
assert div_a.position_y == 0
assert div_b.position_y == 2
assert div_c.position_y == 4
assert div_a.width == div_b.width == div_c.width == 10
assert {div.height for div in article.children} == {2}
assert article.width == 10
assert div_a.position_x == 0
assert div_b.position_x == 4
assert div_c.position_x == 8
assert div_a.position_y == div_b.position_y == div_c.position_y == 0
assert div_a.height == div_b.height == div_c.height == 2
assert {div.width for div in article.children} == {4}
assert article.width == 12


@assert_no_logs
Expand Down Expand Up @@ -856,3 +887,70 @@ def test_grid_item_margin():
article, = body.children
div_a, div_b = article.children
# TODO: Test auto margin values.


@assert_no_logs
def test_grid_auto_flow_column():
page, = render_pages('''
<article style="display: grid; grid-auto-flow: column">
<div>a</div>
<div>a</div>
<div>a</div>
</article>
''')
html, = page.children
body, = html.children
article, = body.children
div_a, div_b, div_c = article.children
assert div_a.position_x < div_b.position_x < div_c.position_x
assert div_a.position_y == div_b.position_y == div_c.position_y == 0
assert div_a.width == div_b.width == div_c.width
assert div_a.height == div_b.height == div_c.height == html.height == article.height


@assert_no_logs
def test_grid_template_areas_extra_span_column_dense():
page, = render_pages('''
<style>
@font-face { src: url(weasyprint.otf); font-family: weasyprint }
article {
display: grid;
font-family: weasyprint;
font-size: 2px;
grid-auto-flow: column dense;
grid-template-areas: 'a . b' 'c d d';
line-height: 1;
width: 12px;
}
</style>
<article>
<div style="grid-area: a">a</div>
<div style="grid-area: b">b</div>
<div style="grid-area: c">c</div>
<div style="grid-area: d">d</div>
<div style="grid-row: span 2">e</div>
<div>f</div>
</article>
''')
html, = page.children
body, = html.children
article, = body.children
div_a, div_b, div_c, div_d, div_e, div_f = article.children
assert div_a.position_x == div_c.position_x == 0
assert div_d.position_x == div_f.position_x == 3
assert div_b.position_x == 6
assert div_e.position_x == 9
assert (
div_a.position_y == div_b.position_y ==
div_e.position_y == div_f.position_y == 0)
assert div_c.position_y == div_d.position_y == 2
assert (
div_a.width == div_b.width == div_c.width ==
div_e.width == div_f.width == 3)
assert div_d.width == 6
assert (
div_a.height == div_b.height == div_c.height ==
div_d.height == div_f.height == 2)
assert div_e.height == 4
assert article.height == 4
assert article.width == 12
9 changes: 7 additions & 2 deletions weasyprint/css/validation/expanders.py
Original file line number Diff line number Diff line change
Expand Up @@ -830,17 +830,22 @@ def expand_grid(tokens, name):
templates = {'row': [], 'column': []}
iterable = zip(split_tokens, templates.items())
for tokens, (track, track_templates) in iterable:
auto_flow_token = False
for token in tokens:
if get_keyword(token) == 'dense':
if dense or (auto_track and auto_track != track):
raise InvalidValues
dense = token
auto_track = track
elif get_keyword(token) == 'auto-flow':
if auto_track:
if auto_flow_token or (auto_track and auto_track != track):
raise InvalidValues
auto_flow_token = True
auto_track = track
else:
elif token == tokens[-1]:
track_templates.append(token)
else:
raise InvalidValues
if not auto_track:
raise InvalidValues
non_auto_track = 'row' if auto_track == 'column' else 'column'
Expand Down
Loading

0 comments on commit bcf779d

Please sign in to comment.