mirror of
https://github.com/Kozea/WeasyPrint.git
synced 2024-10-05 00:21:15 +03:00
Make changes more generic
This commit is contained in:
parent
d08c5b4fd6
commit
db3944c1d9
@ -176,26 +176,11 @@ def register_computer(name):
|
||||
return decorator
|
||||
|
||||
|
||||
def compute(element, pseudo_type, specified, computed, parent_style,
|
||||
root_style, base_url, target_collector):
|
||||
"""Create a dict of computed values.
|
||||
|
||||
:param element: The HTML element these style apply to
|
||||
:param pseudo_type: The type of pseudo-element, eg 'before', None
|
||||
:param specified: A dict of specified values. Should contain
|
||||
values for all properties.
|
||||
:param computed: A dict of already known computed values.
|
||||
Only contains some properties (or none).
|
||||
:param parent_style: A dict of computed values of the parent
|
||||
element (should contain values for all properties),
|
||||
or ``None`` if ``element`` is the root element.
|
||||
:param base_url: The base URL used to resolve relative URLs.
|
||||
:param target_collector: A target collector used to get computed targets.
|
||||
|
||||
"""
|
||||
def compute_variable(value, name, computed, base_url, parent_style):
|
||||
from .validation.properties import PROPERTIES
|
||||
already_computed_value = False
|
||||
|
||||
def resolve_var(value, name, computed):
|
||||
if value and isinstance(value, tuple) and value[0] == 'var()':
|
||||
variable_name, default = value[1]
|
||||
computed_value = _resolve_var(computed, variable_name, default)
|
||||
if computed_value is None:
|
||||
@ -220,11 +205,34 @@ def compute(element, pseudo_type, specified, computed, parent_style,
|
||||
variable_name.replace('_', '-'), name.replace('_', '-'))
|
||||
if name in INHERITED and parent_style:
|
||||
already_computed_value = True
|
||||
return parent_style[name], already_computed_value
|
||||
value = parent_style[name]
|
||||
else:
|
||||
already_computed_value = name not in INITIAL_NOT_COMPUTED
|
||||
return INITIAL_VALUES[name], already_computed_value
|
||||
return new_value, False
|
||||
value = INITIAL_VALUES[name]
|
||||
elif isinstance(new_value, list):
|
||||
value, = new_value
|
||||
else:
|
||||
value = new_value
|
||||
return value, already_computed_value
|
||||
|
||||
|
||||
def compute(element, pseudo_type, specified, computed, parent_style,
|
||||
root_style, base_url, target_collector):
|
||||
"""Create a dict of computed values.
|
||||
|
||||
:param element: The HTML element these style apply to
|
||||
:param pseudo_type: The type of pseudo-element, eg 'before', None
|
||||
:param specified: A dict of specified values. Should contain
|
||||
values for all properties.
|
||||
:param computed: A dict of already known computed values.
|
||||
Only contains some properties (or none).
|
||||
:param parent_style: A dict of computed values of the parent
|
||||
element (should contain values for all properties),
|
||||
or ``None`` if ``element`` is the root element.
|
||||
:param base_url: The base URL used to resolve relative URLs.
|
||||
:param target_collector: A target collector used to get computed targets.
|
||||
|
||||
"""
|
||||
|
||||
computer = {
|
||||
'is_root_element': parent_style is None,
|
||||
@ -249,21 +257,20 @@ def compute(element, pseudo_type, specified, computed, parent_style,
|
||||
function = getter(name)
|
||||
already_computed_value = False
|
||||
|
||||
if value and isinstance(value, list):
|
||||
for i, val in enumerate(value):
|
||||
if not isinstance(val, tuple) or val[0] != 'var()':
|
||||
continue
|
||||
new_value, already_computed_value = \
|
||||
resolve_var(val, name, computed)
|
||||
if name == 'content':
|
||||
new_value = new_value[0]
|
||||
value[i] = new_value
|
||||
elif value and isinstance(value, tuple) and value[0] == 'var()':
|
||||
new_value, already_computed_value = \
|
||||
resolve_var(value, name, computed)
|
||||
if name == 'content':
|
||||
new_value = new_value[0]
|
||||
value = new_value
|
||||
if value:
|
||||
converted_to_list = False
|
||||
|
||||
if not isinstance(value, list):
|
||||
converted_to_list = True
|
||||
value = [value]
|
||||
|
||||
for i, v in enumerate(value):
|
||||
value[i], already_computed_value = \
|
||||
compute_variable(v, name, computed, base_url, parent_style)
|
||||
|
||||
if converted_to_list:
|
||||
value, = value
|
||||
|
||||
|
||||
if function is not None and not already_computed_value:
|
||||
value = function(computer, name, value)
|
||||
|
@ -700,9 +700,9 @@ def get_content_list_token(token, base_url):
|
||||
return string
|
||||
|
||||
# <var>
|
||||
var_function = check_var_function(token)
|
||||
if var_function is not None:
|
||||
return var_function
|
||||
var = check_var_function(token)
|
||||
if var is not None:
|
||||
return var
|
||||
|
||||
# contents
|
||||
if get_keyword(token) == 'contents':
|
||||
|
@ -21,6 +21,7 @@ from ..utils import (
|
||||
PREFIX = '-weasy-'
|
||||
PROPRIETARY = set()
|
||||
UNSTABLE = set()
|
||||
MULTIVAL_PROPERTIES = set()
|
||||
|
||||
# Yes/no validators for non-shorthand properties
|
||||
# Maps property names to functions taking a property name and a value list,
|
||||
@ -33,7 +34,7 @@ PROPERTIES = {}
|
||||
# Validators
|
||||
|
||||
def property(property_name=None, proprietary=False, unstable=False,
|
||||
wants_base_url=False):
|
||||
multiple_values=False, wants_base_url=False):
|
||||
"""Decorator adding a function to the ``PROPERTIES``.
|
||||
|
||||
The name of the property covered by the decorated function is set to
|
||||
@ -69,6 +70,8 @@ def property(property_name=None, proprietary=False, unstable=False,
|
||||
PROPRIETARY.add(name)
|
||||
if unstable:
|
||||
UNSTABLE.add(name)
|
||||
if multiple_values:
|
||||
MULTIVAL_PROPERTIES.add(name)
|
||||
return function
|
||||
return decorator
|
||||
|
||||
@ -89,7 +92,7 @@ def validate_non_shorthand(base_url, name, tokens, required=False):
|
||||
if not required and name not in PROPERTIES:
|
||||
raise InvalidValues('property not supported yet')
|
||||
|
||||
if name != 'content':
|
||||
if name not in MULTIVAL_PROPERTIES:
|
||||
for token in tokens:
|
||||
var_function = check_var_function(token)
|
||||
if var_function:
|
||||
@ -455,7 +458,7 @@ def clip(token):
|
||||
return ()
|
||||
|
||||
|
||||
@property(wants_base_url=True)
|
||||
@property(multiple_values=True, wants_base_url=True)
|
||||
def content(tokens, base_url):
|
||||
"""``content`` property validation."""
|
||||
# See https://www.w3.org/TR/css-content-3/#content-property
|
||||
|
@ -98,7 +98,7 @@ def assert_tree(box, expected):
|
||||
assert isinstance(box, boxes.BlockBox)
|
||||
assert box.element_tag == 'body'
|
||||
|
||||
assert serialize(box.children) == expected
|
||||
assert serialize(box.children) == expected, '%s != %s' % (serialize(box.children), expected,)
|
||||
|
||||
|
||||
def _sanity_checks(box):
|
||||
|
@ -11,6 +11,8 @@ import pytest
|
||||
from ..css.properties import KNOWN_PROPERTIES
|
||||
from .test_boxes import render_pages as parse
|
||||
|
||||
SIDES = ('top', 'right', 'bottom', 'left')
|
||||
|
||||
|
||||
def test_variable_simple():
|
||||
page, = parse('''
|
||||
@ -83,6 +85,23 @@ def test_variable_chain():
|
||||
assert paragraph.width == 10
|
||||
|
||||
|
||||
def test_variable_partial_1():
|
||||
page, = parse('''
|
||||
<style>
|
||||
html { --var: 10px }
|
||||
div { margin: 0 0 0 var(--var) }
|
||||
</style>
|
||||
<div></div>
|
||||
''')
|
||||
html, = page.children
|
||||
body, = html.children
|
||||
div, = body.children
|
||||
assert div.margin_top == 0
|
||||
assert div.margin_right == 0
|
||||
assert div.margin_bottom == 0
|
||||
assert div.margin_left == 10
|
||||
|
||||
|
||||
def test_variable_initial():
|
||||
page, = parse('''
|
||||
<style>
|
||||
|
Loading…
Reference in New Issue
Block a user