Skip to content

Commit

Permalink
Clean management of variables
Browse files Browse the repository at this point in the history
Fix #2042.
  • Loading branch information
liZe committed Jan 30, 2024
1 parent 3f6775a commit 6e835e2
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 25 deletions.
42 changes: 42 additions & 0 deletions tests/test_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,22 @@ def test_variable_chain_root():
assert html.width == 10


def test_variable_self():
page, = render_pages('''
<style>
html { --var1: var(--var1) }
</style>
''')


def test_variable_loop():
page, = render_pages('''
<style>
html { --var1: var(--var2); --var2: var(--var1) }
</style>
''')


def test_variable_chain_root_missing():
# Regression test for https://github.com/Kozea/WeasyPrint/issues/1656
page, = render_pages('''
Expand Down Expand Up @@ -479,3 +495,29 @@ def test_variable_in_function_missing():
h11, div1, h12, div2 = section.children
assert not div1.children
assert not div2.children


@assert_no_logs
def test_variable_in_function_in_variable():
page, = render_pages('''
<style>
html { --name: title; --counter: counter(var(--name), upper-roman) }
h1 { counter-increment: var(--name) }
div::before { content: var(--counter) }
</style>
<section>
<h1></h1>
<div></div>
<h1></h1>
<div></div>
<h1></h1>
<div style="--counter: counter(var(--name), lower-roman)"></div>
</section>
''')
html, = page.children
body, = html.children
section, = body.children
h11, div1, h12, div2, h13, div3 = section.children
assert div1.children[0].children[0].children[0].text == 'I'
assert div2.children[0].children[0].children[0].text == 'II'
assert div3.children[0].children[0].children[0].text == 'iii'
35 changes: 10 additions & 25 deletions weasyprint/css/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,32 +609,17 @@ def resolve_var(computed, token, parent_style):
token.source_line, token.source_column, token.name, arguments)
return resolve_var(computed, token, parent_style) or (token,)

default = None # just for the linter
known_variable_names = set()
computed_value = (token,)
while (computed_value and
isinstance(computed_value, tuple)
and len(computed_value) == 1):
value = computed_value[0]
if value.type == 'ident' and value.value == 'initial':
args = parse_function(token)[1]
variable_name = args.pop(0).value.replace('-', '_') # first arg is name
default = args # next args are default value
computed_value = []
for value in computed[variable_name]:
resolved = resolve_var(computed, value, parent_style)
computed_value.extend((value,) if resolved is None else resolved)
if len(computed_value) == 1:
token, = computed_value
if token.type == 'ident' and token.value == 'initial':
return default
if check_var_function(value):
args = parse_function(value)[1]
variable_name = args.pop(0).value.replace('-', '_')
if variable_name in known_variable_names:
computed_value = default
break
known_variable_names.add(variable_name)
default = args
computed_value = computed[variable_name]
if computed_value is not None:
continue
if parent_style is None:
computed_value = default
else:
computed_value = parent_style[variable_name] or default
else:
break
return computed_value


Expand Down

0 comments on commit 6e835e2

Please sign in to comment.