From 7f6b1281a56792bd5e5e43381bae5a5b7702a6c7 Mon Sep 17 00:00:00 2001 From: Guillaume Ayoub Date: Sat, 25 Nov 2023 18:21:25 +0100 Subject: [PATCH] Reorganize computers of CSS functions --- weasyprint/css/__init__.py | 4 +- weasyprint/css/computed_values.py | 82 +++++++++++++++---------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/weasyprint/css/__init__.py b/weasyprint/css/__init__.py index 794488ee4..2a83d0eaf 100644 --- a/weasyprint/css/__init__.py +++ b/weasyprint/css/__init__.py @@ -23,7 +23,7 @@ from ..logger import LOGGER, PROGRESS_LOGGER from ..urls import URLFetchingError, get_url_attribute, url_join from . import counters, media_queries -from .computed_values import COMPUTER_FUNCTIONS, ZERO_PIXELS, compute_variables +from .computed_values import COMPUTER_FUNCTIONS, ZERO_PIXELS, compute_var from .properties import INHERITED, INITIAL_NOT_COMPUTED, INITIAL_VALUES from .utils import get_url, remove_whitespace from .validation import preprocess_declarations @@ -678,7 +678,7 @@ def __missing__(self, key): if key in self.cascaded: # Property defined in cascaded properties. - keyword, computed = compute_variables(key, self, parent_style) + keyword, computed = compute_var(key, self, parent_style) value = keyword else: # Property not defined in cascaded properties, define as inherited diff --git a/weasyprint/css/computed_values.py b/weasyprint/css/computed_values.py index c0c6c53b5..ad5044c80 100644 --- a/weasyprint/css/computed_values.py +++ b/weasyprint/css/computed_values.py @@ -211,7 +211,7 @@ def decorator(function): return decorator -def compute_variables(name, computed_style, parent_style): +def compute_var(name, computed_style, parent_style): original_values = computed_style.cascaded[name][0] validation_name = name.replace('_', '-') multiple_values = validation_name in MULTIVAL_PROPERTIES @@ -280,6 +280,44 @@ def compute_variables(name, computed_style, parent_style): return values, computed +def compute_attr(style, values): + # TODO: use real token parsing instead of casting with Python types + func_name, value = values + assert func_name == 'attr()' + attr_name, type_or_unit, fallback = value + # style.element sometimes is None + # style.element sometimes is a 'PageType' object without .get() + # so wrapt the .get() into try and return None instead of crashing + try: + attr_value = style.element.get(attr_name, fallback) + if type_or_unit == 'string': + pass # Keep the string + elif type_or_unit == 'url': + if attr_value.startswith('#'): + attr_value = ('internal', unquote(attr_value[1:])) + else: + attr_value = ( + 'external', safe_urljoin(style.base_url, attr_value)) + elif type_or_unit == 'color': + attr_value = parse_color(attr_value.strip()) + elif type_or_unit == 'integer': + attr_value = int(attr_value.strip()) + elif type_or_unit == 'number': + attr_value = float(attr_value.strip()) + elif type_or_unit == '%': + attr_value = Dimension(float(attr_value.strip()), '%') + type_or_unit = 'length' + elif type_or_unit in LENGTH_UNITS: + attr_value = Dimension(float(attr_value.strip()), type_or_unit) + type_or_unit = 'length' + elif type_or_unit in ANGLE_TO_RADIANS: + attr_value = Dimension(float(attr_value.strip()), type_or_unit) + type_or_unit = 'angle' + except Exception: + return + return (type_or_unit, attr_value) + + @register_computer('background-image') def background_image(style, name, values): """Compute lenghts in gradient background-image.""" @@ -473,44 +511,6 @@ def column_gap(style, name, value): return length(style, name, value, pixels_only=True) -def compute_attr_function(style, values): - # TODO: use real token parsing instead of casting with Python types - func_name, value = values - assert func_name == 'attr()' - attr_name, type_or_unit, fallback = value - # style.element sometimes is None - # style.element sometimes is a 'PageType' object without .get() - # so wrapt the .get() into try and return None instead of crashing - try: - attr_value = style.element.get(attr_name, fallback) - if type_or_unit == 'string': - pass # Keep the string - elif type_or_unit == 'url': - if attr_value.startswith('#'): - attr_value = ('internal', unquote(attr_value[1:])) - else: - attr_value = ( - 'external', safe_urljoin(style.base_url, attr_value)) - elif type_or_unit == 'color': - attr_value = parse_color(attr_value.strip()) - elif type_or_unit == 'integer': - attr_value = int(attr_value.strip()) - elif type_or_unit == 'number': - attr_value = float(attr_value.strip()) - elif type_or_unit == '%': - attr_value = Dimension(float(attr_value.strip()), '%') - type_or_unit = 'length' - elif type_or_unit in LENGTH_UNITS: - attr_value = Dimension(float(attr_value.strip()), type_or_unit) - type_or_unit = 'length' - elif type_or_unit in ANGLE_TO_RADIANS: - attr_value = Dimension(float(attr_value.strip()), type_or_unit) - type_or_unit = 'angle' - except Exception: - return - return (type_or_unit, attr_value) - - def _content_list(style, values): computed_values = [] for value in values: @@ -518,7 +518,7 @@ def _content_list(style, values): computed_value = value elif value[0] == 'attr()': assert value[1][1] == 'string' - computed_value = compute_attr_function(style, value) + computed_value = compute_attr(style, value) elif value[0] in ( 'counter()', 'counters()', 'content()', 'element()', 'string()', @@ -531,7 +531,7 @@ def _content_list(style, values): 'target-counter()', 'target-counters()', 'target-text()'): anchor_token = value[1][0] if anchor_token[0] == 'attr()': - attr = compute_attr_function(style, anchor_token) + attr = compute_attr(style, anchor_token) if attr is None: computed_value = None else: