Skip to content

Commit

Permalink
Correctly apply cascade and CSS management to use tags
Browse files Browse the repository at this point in the history
Related to #2234.
  • Loading branch information
liZe committed Aug 21, 2024
1 parent cf72dfc commit b75e683
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 55 deletions.
97 changes: 48 additions & 49 deletions weasyprint/svg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,69 +130,68 @@ def visible(self):
"""Whether node is visible."""
return self.display and self.get('visibility') != 'hidden'

def cascade(self, child):
"""Apply CSS cascade and other related operations to given child."""
wrapper = child._wrapper

# Cascade
for key, value in self.attrib.items():
if key not in NOT_INHERITED_ATTRIBUTES:
if key not in child.attrib:
child.attrib[key] = value

# Apply style attribute
if style_attr := child.get('style'):
normal_attr, important_attr = parse_declarations(style_attr)
else:
normal_attr, important_attr = [], []
normal_matcher, important_matcher = self._style
normal = [rule[-1] for rule in normal_matcher.match(wrapper)]
important = [rule[-1] for rule in important_matcher.match(wrapper)]
for declarations_list in (normal, [normal_attr], important, [important_attr]):
for declarations in declarations_list:
for name, value in declarations:
child.attrib[name] = value.strip()

# Replace 'currentColor' value
for key in COLOR_ATTRIBUTES:
if child.get(key) == 'currentColor':
child.attrib[key] = child.get('color', 'black')

# Handle 'inherit' values
for key, value in child.attrib.copy().items():
if value == 'inherit':
value = self.get(key)
if value is None:
del child.attrib[key]
else:
child.attrib[key] = value

# Fix text in text tags
if child.tag in ('text', 'textPath', 'a'):
children, _ = child.text_children(
wrapper, trailing_space=True, text_root=True)
child._wrapper.etree_children = [
child._etree_node for child in children]


def __iter__(self):
"""Yield node children, handling cascade."""
for wrapper in self._wrapper:
child = Node(wrapper, self._style)

# Cascade
for key, value in self.attrib.items():
if key not in NOT_INHERITED_ATTRIBUTES:
if key not in child.attrib:
child.attrib[key] = value

# Apply style attribute
style_attr = child.get('style')
if style_attr:
normal_attr, important_attr = parse_declarations(style_attr)
else:
normal_attr, important_attr = [], []
normal_matcher, important_matcher = self._style
normal = [rule[-1] for rule in normal_matcher.match(wrapper)]
important = [rule[-1] for rule in important_matcher.match(wrapper)]
declarations_lists = (
normal, [normal_attr], important, [important_attr])
for declarations_list in declarations_lists:
for declarations in declarations_list:
for name, value in declarations:
child.attrib[name] = value.strip()

# Replace 'currentColor' value
for key in COLOR_ATTRIBUTES:
if child.get(key) == 'currentColor':
child.attrib[key] = child.get('color', 'black')

# Handle 'inherit' values
for key, value in child.attrib.copy().items():
if value == 'inherit':
value = self.get(key)
if value is None:
del child.attrib[key]
else:
child.attrib[key] = value

# Fix text in text tags
if child.tag in ('text', 'textPath', 'a'):
children, _ = child.text_children(
wrapper, trailing_space=True, text_root=True)
child._wrapper.etree_children = [
child._etree_node for child in children]

self.cascade(child)
yield child

def get_viewbox(self):
"""Get node viewBox as a tuple of floats."""
viewbox = self.get('viewBox')
if viewbox:
return tuple(
float(number) for number in normalize(viewbox).split())
return tuple(float(number) for number in normalize(viewbox).split())

def get_href(self, base_url):
"""Get the href attribute, with or without a namespace."""
for attr_name in ('{http://www.w3.org/1999/xlink}href', 'href'):
url = get_url_attribute(
self, attr_name, base_url, allow_relative=True)
if url:
if url := get_url_attribute(self, attr_name, base_url, allow_relative=True):
return url

def del_href(self):
Expand Down
7 changes: 1 addition & 6 deletions weasyprint/svg/defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,7 @@ def use(svg, node, font_size):
tree.attrib['height'] = box[3]
tree._etree_node.tag = 'svg'

# Cascade
for key, value in node.attrib.items():
if key not in NOT_INHERITED_ATTRIBUTES:
if key not in tree.attrib:
tree.attrib[key] = value

node.cascade(tree)
node.override_iter(iter((tree,)))
svg.stream.transform(e=x, f=y)

Expand Down

0 comments on commit b75e683

Please sign in to comment.