Skip to content

Commit

Permalink
Don't crash when fixed boxes are nested
Browse files Browse the repository at this point in the history
Fix #728.
  • Loading branch information
liZe committed Mar 7, 2019
1 parent bc1f59c commit 1eea5a4
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 7 deletions.
19 changes: 13 additions & 6 deletions weasyprint/layout/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

from collections import defaultdict

from .absolute import absolute_box_layout
from .absolute import absolute_box_layout, absolute_layout
from .backgrounds import layout_backgrounds
from .pages import make_all_pages, make_margin_boxes
from ..formatting_structure import boxes
Expand Down Expand Up @@ -85,13 +85,20 @@ def layout_fixed_boxes(context, pages, containing_page):
for box in page.fixed_boxes:
# As replaced boxes are never copied during layout, ensure that we
# have different boxes (with a possibly different layout) for
# each pages
# each pages.
if isinstance(box, boxes.ReplacedBox):
box = box.copy()
# Use an empty list as last argument because the fixed boxes in the
# fixed box has already been added to page.fixed_boxes, we don't
# want to get them again
yield absolute_box_layout(context, box, containing_page, [])
# Absolute boxes in fixed boxes are rendered as fixed boxes'
# children, even when they are fixed themselves.
absolute_boxes = []
yield absolute_box_layout(
context, box, containing_page, absolute_boxes)
while absolute_boxes:
new_absolute_boxes = []
for box in absolute_boxes:
absolute_layout(
context, box, containing_page, new_absolute_boxes)
absolute_boxes = new_absolute_boxes


def layout_document(enable_hinting, style_for, get_image_from_uri, root_box,
Expand Down
36 changes: 35 additions & 1 deletion weasyprint/tests/test_layout/test_position.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,6 @@ def test_fixed_positioning_regression_1():
@page { size: 200px 100px; margin: 0 }
article { break-after: page }
.fixed { position: fixed; top: 10px; width: 20px }
ul { }
</style>
<ul class="fixed" style="right: 0"><li>a</li></ul>
<img class="fixed" style="right: 20px" src="pattern.png" />
Expand All @@ -353,3 +352,38 @@ def test_fixed_positioning_regression_1():
assert (div.position_x, div.position_y) == (140, 10)
assert (article.position_x, article.position_y) == (0, 0)
assert 160 < ul.children[0].outside_list_marker.position_x < 170


@assert_no_logs
def test_fixed_positioning_regression_2():
# Regression test for https://github.com/Kozea/WeasyPrint/issues/728
page_1, page_2 = parse('''
<style>
@page { size: 100px 100px }
section { break-after: page }
.fixed { position: fixed; top: 10px; left: 15px; width: 20px }
</style>
<div class="fixed">
<article class="fixed" style="top: 20px">
<header class="fixed" style="left: 5px"></header>
</article>
</div>
<section></section>
<pre></pre>
''')
html, = page_1.children
body, = html.children
div, section = body.children
assert (div.position_x, div.position_y) == (15, 10)
article, = div.children
assert (article.position_x, article.position_y) == (15, 20)
header, = article.children
assert (header.position_x, header.position_y) == (5, 10)

html, = page_2.children
div, body, = html.children
assert (div.position_x, div.position_y) == (15, 10)
article, = div.children
assert (article.position_x, article.position_y) == (15, 20)
header, = article.children
assert (header.position_x, header.position_y) == (5, 10)

0 comments on commit 1eea5a4

Please sign in to comment.