From 9026b06917b31a4bb3285647a99f4157bbf1f841 Mon Sep 17 00:00:00 2001 From: Guillaume Ayoub Date: Sun, 17 Mar 2024 17:31:32 +0100 Subject: [PATCH] Use parse_blocks_contents() --- tests/css/test_descriptors.py | 12 ++++++------ tests/css/test_expanders.py | 2 +- tests/css/test_validation.py | 2 +- weasyprint/css/__init__.py | 13 +++++++------ weasyprint/css/validation/__init__.py | 16 ++++++++++------ weasyprint/svg/css.py | 2 +- 6 files changed, 26 insertions(+), 21 deletions(-) diff --git a/tests/css/test_descriptors.py b/tests/css/test_descriptors.py index 0f7a4c38..0ee38b84 100644 --- a/tests/css/test_descriptors.py +++ b/tests/css/test_descriptors.py @@ -19,7 +19,7 @@ def test_font_face_1(): assert at_rule.at_keyword == 'font-face' font_family, src = list(preprocess_descriptors( 'font-face', 'https://weasyprint.org/foo/', - tinycss2.parse_declaration_list(at_rule.content))) + tinycss2.parse_blocks_contents(at_rule.content))) assert font_family == ('font_family', 'Gentium Hard') assert src == ( 'src', (('external', 'https://example.com/fonts/Gentium.woff'),)) @@ -40,7 +40,7 @@ def test_font_face_2(): font_family, src, font_style, font_weight, font_stretch = list( preprocess_descriptors( 'font-face', 'https://weasyprint.org/foo/', - tinycss2.parse_declaration_list(at_rule.content))) + tinycss2.parse_blocks_contents(at_rule.content))) assert font_family == ('font_family', 'Fonty Smiley') assert src == ( 'src', (('external', 'https://weasyprint.org/foo/Fonty-Smiley.woff'),)) @@ -60,7 +60,7 @@ def test_font_face_3(): assert at_rule.at_keyword == 'font-face' font_family, src = list(preprocess_descriptors( 'font-face', 'https://weasyprint.org/foo/', - tinycss2.parse_declaration_list(at_rule.content))) + tinycss2.parse_blocks_contents(at_rule.content))) assert font_family == ('font_family', 'Gentium Hard') assert src == ('src', (('local', None),)) @@ -77,7 +77,7 @@ def test_font_face_4(): assert at_rule.at_keyword == 'font-face' font_family, src = list(preprocess_descriptors( 'font-face', 'https://weasyprint.org/foo/', - tinycss2.parse_declaration_list(at_rule.content))) + tinycss2.parse_blocks_contents(at_rule.content))) assert font_family == ('font_family', 'Gentium Hard') assert src == ('src', (('local', 'Gentium Hard'),)) @@ -96,7 +96,7 @@ def test_font_face_5(): with capture_logs() as logs: font_family, src = list(preprocess_descriptors( 'font-face', 'https://weasyprint.org/foo/', - tinycss2.parse_declaration_list(at_rule.content))) + tinycss2.parse_blocks_contents(at_rule.content))) assert font_family == ('font_family', 'Gentium Hard') assert src == ('src', (('local', 'Gentium Hard'),)) assert len(logs) == 1 @@ -119,7 +119,7 @@ def test_font_face_bad_1(): font_family, src, font_stretch = list( preprocess_descriptors( 'font-face', 'https://weasyprint.org/foo/', - tinycss2.parse_declaration_list(at_rule.content))) + tinycss2.parse_blocks_contents(at_rule.content))) assert font_family == ('font_family', 'Bad Font') assert src == ( 'src', (('external', 'https://weasyprint.org/foo/BadFont.woff'),)) diff --git a/tests/css/test_expanders.py b/tests/css/test_expanders.py index d780fc9a..f7c2c2e0 100644 --- a/tests/css/test_expanders.py +++ b/tests/css/test_expanders.py @@ -12,7 +12,7 @@ from ..testing_utils import assert_no_logs, capture_logs def expand_to_dict(css, expected_error=None): """Helper to test shorthand properties expander functions.""" - declarations = tinycss2.parse_declaration_list(css) + declarations = tinycss2.parse_blocks_contents(css) with capture_logs() as logs: base_url = 'https://weasyprint.org/foo/' diff --git a/tests/css/test_validation.py b/tests/css/test_validation.py index 64316630..f3308a99 100644 --- a/tests/css/test_validation.py +++ b/tests/css/test_validation.py @@ -12,7 +12,7 @@ from ..testing_utils import assert_no_logs, capture_logs def get_value(css, expected_error=None): - declarations = tinycss2.parse_declaration_list(css) + declarations = tinycss2.parse_blocks_contents(css) with capture_logs() as logs: base_url = 'https://weasyprint.org/foo/' diff --git a/weasyprint/css/__init__.py b/weasyprint/css/__init__.py index e31a68ae..9cbaa823 100644 --- a/weasyprint/css/__init__.py +++ b/weasyprint/css/__init__.py @@ -298,7 +298,7 @@ def find_style_attributes(tree, presentational_hints=False, base_url=None): """ def check_style_attribute(element, style_attribute): - declarations = tinycss2.parse_declaration_list(style_attribute) + declarations = tinycss2.parse_blocks_contents(style_attribute) return element, declarations, base_url for element in tree.iter(): @@ -924,7 +924,7 @@ def preprocess_stylesheet(device_media_type, base_url, stylesheet_rules, logger_level = WARNING selectors_declarations = list( preprocess_declarations( - base_url, tinycss2.parse_declaration_list(rule.content), + base_url, tinycss2.parse_blocks_contents(rule.content), rule.prelude)) if selectors_declarations: @@ -933,6 +933,7 @@ def preprocess_stylesheet(device_media_type, base_url, stylesheet_rules, for selectors, declarations in selectors_declarations: declarations = [ declaration[1] for declaration in declarations] + print(selectors, declarations) for selector in selectors: matcher.add_selector(selector, declarations) if selector.pseudo_element not in PSEUDO_ELEMENTS: @@ -1036,7 +1037,7 @@ def preprocess_stylesheet(device_media_type, base_url, stylesheet_rules, for page_type in data: specificity = page_type.pop('specificity') page_type = PageType(**page_type) - content = tinycss2.parse_declaration_list(rule.content) + content = tinycss2.parse_blocks_contents(rule.content) declarations = list(preprocess_declarations(base_url, content)) if declarations: @@ -1049,7 +1050,7 @@ def preprocess_stylesheet(device_media_type, base_url, stylesheet_rules, continue declarations = list(preprocess_declarations( base_url, - tinycss2.parse_declaration_list(margin_rule.content))) + tinycss2.parse_blocks_contents(margin_rule.content))) if declarations: selector_list = [( specificity, f'@{margin_rule.lower_at_keyword}', @@ -1059,7 +1060,7 @@ def preprocess_stylesheet(device_media_type, base_url, stylesheet_rules, elif rule.type == 'at-rule' and rule.lower_at_keyword == 'font-face': ignore_imports = True - content = tinycss2.parse_declaration_list(rule.content) + content = tinycss2.parse_blocks_contents(rule.content) rule_descriptors = dict( preprocess_descriptors('font-face', base_url, content)) for key in ('src', 'font_family'): @@ -1086,7 +1087,7 @@ def preprocess_stylesheet(device_media_type, base_url, stylesheet_rules, continue ignore_imports = True - content = tinycss2.parse_declaration_list(rule.content) + content = tinycss2.parse_blocks_contents(rule.content) counter = { 'system': None, 'negative': None, diff --git a/weasyprint/css/validation/__init__.py b/weasyprint/css/validation/__init__.py index 5113588e..abe5b34e 100644 --- a/weasyprint/css/validation/__init__.py +++ b/weasyprint/css/validation/__init__.py @@ -2,7 +2,7 @@ from cssselect2 import SelectorError, compile_selector_list -from tinycss2 import parse_declaration_list, serialize +from tinycss2 import parse_blocks_contents, serialize from tinycss2.ast import FunctionBlock, LiteralToken from ... import LOGGER @@ -116,6 +116,12 @@ def preprocess_declarations(base_url, declarations, prelude=None): Return a iterable of ``(name, value, important)`` tuples. """ + if prelude is not None: + try: + selectors = compile_selector_list(prelude) + except SelectorError as exc: + raise SelectorError(f"'{serialize(prelude)}'") + for declaration in declarations: if declaration.type == 'error': LOGGER.warning( @@ -124,6 +130,8 @@ def preprocess_declarations(base_url, declarations, prelude=None): declaration.source_line, declaration.source_column) if declaration.type == 'qualified-rule': + if prelude is None: + continue declaration_prelude = declaration.prelude if LiteralToken(1, 1, '&') in declaration.prelude: is_token = LiteralToken(1, 1, ':'), FunctionBlock(1, 1, 'is', prelude) @@ -134,7 +142,7 @@ def preprocess_declarations(base_url, declarations, prelude=None): else: declaration_prelude.append(token) yield from preprocess_declarations( - base_url, parse_declaration_list(declaration.content), + base_url, parse_blocks_contents(declaration.content), declaration_prelude) if declaration.type != 'declaration': @@ -200,10 +208,6 @@ def preprocess_declarations(base_url, declarations, prelude=None): important = declaration.important for long_name, value in result: if prelude is not None: - try: - selectors = compile_selector_list(prelude) - except SelectorError as exc: - raise SelectorError(f"'{serialize(prelude)}'") declaration = (long_name.replace('-', '_'), value, important) yield selectors, declaration else: diff --git a/weasyprint/svg/css.py b/weasyprint/svg/css.py index 6a4c1800..39d61ec7 100644 --- a/weasyprint/svg/css.py +++ b/weasyprint/svg/css.py @@ -35,7 +35,7 @@ def parse_declarations(input): """Parse declarations in a given rule content.""" normal_declarations = [] important_declarations = [] - for declaration in tinycss2.parse_declaration_list(input): + for declaration in tinycss2.parse_blocks_contents(input): # TODO: warn on error # if declaration.type == 'error': if (declaration.type == 'declaration' and