mirror of
https://github.com/Kozea/WeasyPrint.git
synced 2024-10-04 16:07:57 +03:00
Get rid of DummyPropertyValue, just use lists.
This commit is contained in:
parent
45edd5c43a
commit
b86a797155
@ -314,18 +314,18 @@ class StyleDict(dict):
|
||||
"""
|
||||
def __getattr__(self, key):
|
||||
try:
|
||||
value = self[key.replace('_', '-')]
|
||||
values = self[key.replace('_', '-')]
|
||||
except KeyError:
|
||||
raise AttributeError(key)
|
||||
if len(value) == 1 and value[0].type == 'DIMENSION' \
|
||||
and value[0].dimension == 'px':
|
||||
if len(values) == 1 and values[0].type == 'DIMENSION' \
|
||||
and values[0].dimension == 'px':
|
||||
# cssutils promises that `DimensionValue.value` is an int or float
|
||||
assert isinstance(value[0].value, (float, int, long))
|
||||
return value[0].value
|
||||
elif len(value) == 1 and value[0].value == 0:
|
||||
assert isinstance(values[0].value, (float, int, long))
|
||||
return values[0].value
|
||||
elif len(values) == 1 and values[0].value == 0:
|
||||
return 0
|
||||
else:
|
||||
return value.value # PropertyValue.value: string representation
|
||||
return ' '.join(value.cssText for value in values)
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
if isinstance(value, (float, int, long)):
|
||||
|
@ -27,7 +27,6 @@ import cssutils.helper
|
||||
from cssutils.css import PropertyValue, DimensionValue, Value
|
||||
|
||||
from .initial_values import INITIAL_VALUES
|
||||
from .shorthands import DummyPropertyValue
|
||||
|
||||
|
||||
# How many CSS pixels is one <unit> ?
|
||||
@ -143,7 +142,7 @@ def compute_font_size(style, parent_style):
|
||||
'Got a non-pixel value for the parent font-size.'
|
||||
else:
|
||||
# root element, no parent
|
||||
parent_value_text = INITIAL_VALUES['font-size'].value
|
||||
parent_value_text = INITIAL_VALUES['font-size'][0].cssText
|
||||
# Initial is medium
|
||||
parent_font_size = FONT_SIZE_KEYWORDS[parent_value_text]
|
||||
|
||||
@ -207,10 +206,8 @@ def compute_lengths(style):
|
||||
"""
|
||||
font_size = style.font_size
|
||||
for name in style:
|
||||
# PropertyValue objects are not mutable, build a new DummyPropertyValue
|
||||
style[name] = DummyPropertyValue(
|
||||
compute_length(value, font_size)
|
||||
for value in style[name])
|
||||
style[name] = [compute_length(value, font_size)
|
||||
for value in style[name]]
|
||||
|
||||
|
||||
def compute_line_height(style):
|
||||
@ -242,10 +239,14 @@ def compute_border_width(style):
|
||||
Set border-*-width to zero if border-*-style is none or hidden.
|
||||
"""
|
||||
for side in ('top', 'right', 'bottom', 'left'):
|
||||
if style['border-%s-style' % side].value in ('none', 'hidden'):
|
||||
values = style['border-%s-style' % side]
|
||||
if len(values) == 1 and values[0].cssText in ('none', 'hidden'):
|
||||
style['border-%s-width' % side] = PropertyValue('0')
|
||||
else:
|
||||
value = style['border-%s-width' % side].value
|
||||
values = style['border-%s-width' % side]
|
||||
if len(values) != 1:
|
||||
return
|
||||
value = values[0].cssText
|
||||
if value in BORDER_WIDTH_KEYWORDS:
|
||||
width = BORDER_WIDTH_KEYWORDS[value]
|
||||
style['border-%s-width' % side] = PropertyValue(
|
||||
@ -351,9 +352,8 @@ def compute_content(element, pseudo_type, style):
|
||||
if style.content == 'normal':
|
||||
style.content = 'none'
|
||||
else:
|
||||
style.content = DummyPropertyValue(
|
||||
compute_content_value(element, value)
|
||||
for value in style['content'])
|
||||
style.content = [compute_content_value(element, value)
|
||||
for value in style['content']]
|
||||
else:
|
||||
# CSS 2.1 says it computes to 'normal' for elements, but does not say
|
||||
# anything for pseudo-elements other than :before and :after
|
||||
|
@ -82,6 +82,10 @@ INHERITED = set("""
|
||||
""".split())
|
||||
|
||||
|
||||
def is_inherit(values):
|
||||
return len(values) == 1 and values[0].cssText == 'inherit'
|
||||
|
||||
|
||||
def handle_inheritance(style, parent_style):
|
||||
"""
|
||||
The specified value is the parent element’s computed value iif one of the
|
||||
@ -90,17 +94,17 @@ def handle_inheritance(style, parent_style):
|
||||
* The the value is the keyword 'inherit'.
|
||||
"""
|
||||
if parent_style is None: # root element
|
||||
for name, value in style.iteritems():
|
||||
for name, values in style.iteritems():
|
||||
# The PropertyValue object has value attribute
|
||||
if value.value == 'inherit':
|
||||
if is_inherit(values):
|
||||
# The root element can not inherit from anything:
|
||||
# use the initial value.
|
||||
style[name] = PropertyValue('initial')
|
||||
else:
|
||||
# The parent appears before in tree order, so we should already have
|
||||
# finished with its computed values.
|
||||
for name, value in style.iteritems():
|
||||
if value.value == 'inherit':
|
||||
for name, values in style.iteritems():
|
||||
if is_inherit(values):
|
||||
style[name] = parent_style[name]
|
||||
for name in INHERITED:
|
||||
# Do not use is_initial() here: only inherit if the property is
|
||||
|
@ -147,7 +147,10 @@ def is_initial(style, name):
|
||||
"""
|
||||
# Explicit 'initial' values are new in CSS3
|
||||
# http://www.w3.org/TR/css3-values/#computed0
|
||||
return name not in style or style[name].value == 'initial'
|
||||
if name not in style:
|
||||
return True
|
||||
values = style[name]
|
||||
return len(values) == 1 and values[0].cssText == 'initial'
|
||||
|
||||
|
||||
def handle_initial_values(style):
|
||||
|
@ -22,16 +22,6 @@
|
||||
"""
|
||||
|
||||
|
||||
class DummyPropertyValue(list):
|
||||
"""
|
||||
A list that quacks like a PropertyValue.
|
||||
"""
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return ' '.join(value.cssText for value in self)
|
||||
|
||||
|
||||
def expand_four_sides(name, values):
|
||||
"""
|
||||
Expand properties that set a value for each of the four sides of a box.
|
||||
@ -140,4 +130,4 @@ def expand_shorthand(prop):
|
||||
"""
|
||||
expander = SHORTHANDS.get(prop.name, expand_noop)
|
||||
for name, value_list in expander(prop.name, list(prop.propertyValue)):
|
||||
yield name, DummyPropertyValue(value_list)
|
||||
yield name, value_list
|
||||
|
@ -58,18 +58,18 @@ def resolve_one_percentage(box, property_name, refer_to):
|
||||
`refer_to` is the length for 100%.
|
||||
"""
|
||||
# box.style has computed values
|
||||
value = box.style[property_name]
|
||||
pixels = pixel_value(value)
|
||||
values = box.style[property_name]
|
||||
pixels = pixel_value(values)
|
||||
if pixels is not None:
|
||||
# Absolute length (was converted to pixels in "computed values")
|
||||
result = pixels
|
||||
else:
|
||||
percentage = percentage_value(value)
|
||||
percentage = percentage_value(values)
|
||||
if percentage is not None:
|
||||
# A percentage
|
||||
result = percentage * refer_to / 100.
|
||||
else:
|
||||
result = value.value
|
||||
result = ' '.join(value.cssText for value in values)
|
||||
# Other than that, only 'auto' is allowed
|
||||
# TODO: it is only allowed on some properties. Check this here?
|
||||
assert result == 'auto'
|
||||
|
@ -70,7 +70,7 @@ def test_find_stylesheets():
|
||||
|
||||
|
||||
def expand_shorthands(declaration_block):
|
||||
return dict(
|
||||
return css.StyleDict(
|
||||
expanded
|
||||
for declaration in declaration_block
|
||||
for expanded in shorthands.expand_shorthand(declaration))
|
||||
@ -89,11 +89,11 @@ def test_expand_shorthands():
|
||||
|
||||
style = expand_shorthands(style)
|
||||
assert 'margin' not in style
|
||||
assert style['margin-top'].value == '2em'
|
||||
assert style['margin-right'].value == '0'
|
||||
assert style['margin-bottom'].value == '2em', \
|
||||
assert style.margin_top == '2em'
|
||||
assert style.margin_right == 0
|
||||
assert style.margin_bottom == '2em', \
|
||||
"3em was before the shorthand, should be masked"
|
||||
assert style['margin-left'].value == '4em', \
|
||||
assert style.margin_left == '4em', \
|
||||
"4em was after the shorthand, should not be masked"
|
||||
|
||||
|
||||
@ -125,23 +125,31 @@ def test_annotate_document():
|
||||
|
||||
assert h1.font_weight == '700'
|
||||
|
||||
sides = ('-top', '-right', '-bottom', '-left')
|
||||
sides = ('_top', '_right', '_bottom', '_left')
|
||||
# 32px = 1em * font-size: 2em * initial 16px
|
||||
for side, expected_value in zip(sides, ('32px', '0', '32px', '0')):
|
||||
assert p['margin' + side].value == expected_value
|
||||
assert p.margin_top == 32
|
||||
assert p.margin_right == 0
|
||||
assert p.margin_bottom == 32
|
||||
assert p.margin_left == 0
|
||||
|
||||
# 32px = 2em * initial 16px
|
||||
for side, expected_value in zip(sides, ('32px', '32px', '32px', '32px')):
|
||||
assert ul['margin' + side].value == expected_value
|
||||
assert ul.margin_top == 32
|
||||
assert ul.margin_right == 32
|
||||
assert ul.margin_bottom == 32
|
||||
assert ul.margin_left == 32
|
||||
|
||||
# thick = 5px, 0.25 inches = 96*.25 = 24px
|
||||
for side, expected_value in zip(sides, ('0', '5px', '0', '24px')):
|
||||
assert ul['border' + side + '-width'].value == expected_value
|
||||
assert ul.border_top_width == 0
|
||||
assert ul.border_right_width == 5
|
||||
assert ul.border_bottom_width == 0
|
||||
assert ul.border_left_width == 24
|
||||
|
||||
# 32px = 2em * initial 16px
|
||||
# 64px = 4em * initial 16px
|
||||
for side, expected_value in zip(sides, ('32px', '0', '32px', '64px')):
|
||||
assert li_0['margin' + side].value == expected_value
|
||||
assert li_0.margin_top == 32
|
||||
assert li_0.margin_right == 0
|
||||
assert li_0.margin_bottom == 32
|
||||
assert li_0.margin_left == 64
|
||||
|
||||
assert a.text_decoration == 'underline'
|
||||
|
||||
|
@ -28,9 +28,9 @@ suite = Tests()
|
||||
|
||||
def expand_to_dict(css):
|
||||
"""Helper to test shorthand properties expander functions."""
|
||||
return dict((name, value.value)
|
||||
return dict((name, ' '.join(value.cssText for value in values))
|
||||
for prop in CSSStyleDeclaration(css)
|
||||
for name, value in expand_shorthand(prop))
|
||||
for name, values in expand_shorthand(prop))
|
||||
|
||||
|
||||
@suite.test
|
||||
|
Loading…
Reference in New Issue
Block a user