1
1
mirror of https://github.com/Kozea/WeasyPrint.git synced 2024-10-04 16:07:57 +03:00

Fix position of marker box

The marker box is generated by the ::marker pseudo-element of a list item as
the list item’s first child […].

The old behavior was done because of the fuzzy "[With list-style-position:
outside], If the list item is a block container: the marker box is outside the
principal block box […]". Outside here probably means that the box is drawn
outside, not that it's not a child of the list item box.

Related to #945.
This commit is contained in:
Guillaume Ayoub 2019-09-18 14:57:25 +02:00
parent 5f7a104c62
commit fbf3467240
4 changed files with 26 additions and 33 deletions

View File

@ -136,7 +136,6 @@ def element_to_box(element, style_for, get_image_from_uri, base_url,
update_counters(state, style)
outside_markers = []
children = []
# If this elements direct children create new scopes, the counter
@ -146,15 +145,12 @@ def element_to_box(element, style_for, get_image_from_uri, base_url,
box.first_letter_style = style_for(element, 'first-letter')
box.first_line_style = style_for(element, 'first-line')
marker_boxes = []
if style['display'] == 'list-item':
marker_boxes = marker_to_box(
marker_boxes = list(marker_to_box(
element, state, style, style_for, get_image_from_uri,
target_collector)
if marker_boxes:
if style['list_style_position'] == 'outside':
outside_markers.extend(marker_boxes)
else:
children.extend(marker_boxes)
target_collector))
children.extend(marker_boxes)
children.extend(before_after_to_box(
element, 'before', state, style_for, get_image_from_uri,
@ -162,7 +158,7 @@ def element_to_box(element, style_for, get_image_from_uri, base_url,
# collect anchor's counter_values, maybe it's a target.
# to get the spec-conform counter_values we must do it here,
# after the ::before is parsed and befor the ::after is
# after the ::before is parsed and before the ::after is
if style['anchor']:
target_collector.store_target(style['anchor'], counter_values, box)
@ -195,7 +191,7 @@ def element_to_box(element, style_for, get_image_from_uri, base_url,
# calculate string-set and bookmark-label
set_content_lists(element, box, style, counter_values, target_collector)
if outside_markers and not box.children:
if marker_boxes and len(box.children) == 1:
# See https://www.w3.org/TR/css-lists-3/#list-style-position-outside
#
# "The size or contents of the marker box may affect the height of the
@ -207,11 +203,11 @@ def element_to_box(element, style_for, get_image_from_uri, base_url,
# height. Adding text boxes is not the best idea, but it's not a good
# moment to add an empty line box, and the specification lets us do
# almost what we want, so…
box.children = [boxes.TextBox.anonymous_from(box, '')]
if style['list_style_position'] == 'outside':
box.children.append(boxes.TextBox.anonymous_from(box, ''))
# Specific handling for the element. (eg. replaced element)
return outside_markers + html.handle_element(
element, box, get_image_from_uri, base_url)
return html.handle_element(element, box, get_image_from_uri, base_url)
def before_after_to_box(element, pseudo_type, state, style_for,
@ -238,23 +234,18 @@ def before_after_to_box(element, pseudo_type, state, style_for,
children = []
outside_markers = []
if display == 'list-item':
marker_boxes = marker_to_box(
marker_boxes = list(marker_to_box(
element, state, style, style_for, get_image_from_uri,
target_collector)
if marker_boxes:
if style['list_style_position'] == 'outside':
outside_markers.extend(marker_boxes)
else:
children.extend(marker_boxes)
target_collector))
children.extend(marker_boxes)
children.extend(content_to_boxes(
style, box, quote_depth, counter_values, get_image_from_uri,
target_collector))
box.children = children
return outside_markers + [box]
return [box]
def marker_to_box(element, state, parent_style, style_for, get_image_from_uri,
@ -1517,6 +1508,7 @@ def box_text(box):
child.text for child in box.descendants()
if not child.element_tag.endswith('::before') and
not child.element_tag.endswith('::after') and
not child.element_tag.endswith('::marker') and
isinstance(child, boxes.TextBox))
else:
return ''

View File

@ -1113,12 +1113,13 @@ def test_counters_8():
<p></p>
<p></p>'''), 2 * [
('p', 'Block', [
('p::marker', 'Block', [
('p::marker', 'Line', [
('p::marker', 'Text', '')])]),
('p::before', 'Block', [
('p::before', 'Line', [
('p::before', 'Text', 'a')])])])])
('p::marker', 'Block', [
('p::marker', 'Line', [
('p::marker', 'Text', '')])]),
('p::before', 'Block', [
('p::before', 'Line', [
('p::before', 'Text', 'a')])])])])])
@assert_no_logs

View File

@ -35,16 +35,16 @@ def test_lists_style(inside, style, character):
html, = page.children
body, = html.children
unordered_list, = body.children
list_item, = unordered_list.children
if inside:
list_item, = unordered_list.children
line, = list_item.children
marker, content = line.children
marker_text, = marker.children
else:
marker, list_item = unordered_list.children
marker, line_container, = list_item.children
assert marker.position_x == list_item.position_x
assert marker.position_y == list_item.position_y
line, = list_item.children
line, = line_container.children
content, = line.children
marker_line, = marker.children
marker_text, = marker_line.children
@ -68,5 +68,5 @@ def test_lists_empty_item():
html, = page.children
body, = html.children
unordered_list, = body.children
_1, li1, _2, li2, _3, li3 = unordered_list.children
li1, li2, li3 = unordered_list.children
assert li1.position_y != li2.position_y != li3.position_y

View File

@ -129,8 +129,8 @@ def test_ph_lists():
html, = page._page_box.children
body, = html.children
ol, ul = body.children
_1, oli1, _2, oli2, _3, oli3, _4, oli4, _5, oli5 = ol.children
_1, uli1, _2, uli2, _3, uli3 = ul.children
oli1, oli2, oli3, oli4, oli5 = ol.children
uli1, uli2, uli3 = ul.children
assert oli1.style['list_style_type'] == 'upper-alpha'
assert oli2.style['list_style_type'] == 'decimal'
assert oli3.style['list_style_type'] == 'lower-alpha'