Skip to content

Commit

Permalink
Fix URL handling with tinycss2
Browse files Browse the repository at this point in the history
URLs used to be dedicated tokens in the CSS specification, but it’s now a
common function unless its value isn’t quoted.

tinycss2 1.1.0 includes this change, and WeasyPrint has to take care of these
two different tokens.
  • Loading branch information
liZe committed Oct 30, 2020
1 parent 77dbcb7 commit 238e214
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 20 deletions.
26 changes: 17 additions & 9 deletions weasyprint/css/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,12 +564,12 @@ def get_image(token, base_url):
"""Parse an <image> token."""
from ..images import LinearGradient, RadialGradient

parsed_url = get_url(token, base_url)
if parsed_url:
assert parsed_url[0] == 'url'
if parsed_url[1][0] == 'external':
return 'url', parsed_url[1][1]
if token.type != 'function':
parsed_url = get_url(token, base_url)
if parsed_url:
assert parsed_url[0] == 'url'
if parsed_url[1][0] == 'external':
return 'url', parsed_url[1][1]
return
arguments = split_on_comma(remove_whitespace(token.arguments))
name = token.lower_name
Expand All @@ -594,16 +594,24 @@ def get_image(token, base_url):
shape, size, position, 'repeating' in name)


def _get_url_tuple(string, base_url):
if string.startswith('#'):
return ('url', ('internal', unquote(string[1:])))
else:
return ('url', ('external', safe_urljoin(base_url, string)))


def get_url(token, base_url):
"""Parse an <url> token."""
if token.type == 'url':
if token.value.startswith('#'):
return ('url', ('internal', unquote(token.value[1:])))
else:
return ('url', ('external', safe_urljoin(base_url, token.value)))
return _get_url_tuple(token.value, base_url)
elif token.type == 'function':
if token.name == 'attr':
return check_attr_function(token, 'url')
elif token.name == 'url' and len(token.arguments) in (1, 2):
# Ignore url modifiers
# See https://drafts.csswg.org/css-values-3/#urls
return _get_url_tuple(token.arguments[0].value, base_url)


def get_quote(token):
Expand Down
7 changes: 3 additions & 4 deletions weasyprint/css/validation/descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,9 @@ def pad(tokens, base_url):
values[0] = token.int_value
elif token.type in ('string', 'ident'):
values[1] = ('string', token.value)
elif token.type == 'function':
url = get_url(token, base_url)
if url is not None and url[0] == 'url':
values[1] = ('url', url[1])
url = get_url(token, base_url)
if url is not None and url[0] == 'url':
values[1] = ('url', url[1])

if None not in values:
return tuple(values)
Expand Down
13 changes: 6 additions & 7 deletions weasyprint/css/validation/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,12 @@ def background_image(token, base_url):
@single_token
def list_style_image(token, base_url):
"""``list-style-image`` property validation."""
if token.type != 'function':
if get_keyword(token) == 'none':
return 'none', None
parsed_url = get_url(token, base_url)
if parsed_url:
if parsed_url[0] == 'url' and parsed_url[1][0] == 'external':
return 'url', parsed_url[1][1]
if get_keyword(token) == 'none':
return 'none', None
parsed_url = get_url(token, base_url)
if parsed_url:
if parsed_url[0] == 'url' and parsed_url[1][0] == 'external':
return 'url', parsed_url[1][1]


@property()
Expand Down

0 comments on commit 238e214

Please sign in to comment.