Commit b7136165 authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Fix list markers not to overlap with previous blocks

This patch fixes when list marker is taller than the content of the
list item, list markers not to intrude previous blocks.

This behavior is not defined, but Blink, WebKit, and Edge do this
by including list marker height into the first line box. This turned
out to require a bit complex propagation. Instead, this patch
includes list marker height into the list item.

This is being tracked in
https://github.com/w3c/csswg-drafts/issues/2418
but I think this patch has close enough behavior and turns following
tests good enough to rebaseline.

  fast/css/first-child-pseudo-class.html
  fast/css/first-of-type-pseudo-class.html
  fast/css/last-child-pseudo-class.html
  fast/css/last-of-type-pseudo-class.html
  fast/css/only-child-pseudo-class.html
  fast/css/only-of-type-pseudo-class.html

Bug: 725277
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: Ic911a96f7804a91d6dccf2bf64bc6fd49169e8cb
Reviewed-on: https://chromium-review.googlesource.com/994915Reviewed-by: default avatarcathie chen <cathiechen@tencent.com>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#549843}
parent f7fd2525
......@@ -53,7 +53,7 @@ scoped_refptr<NGLayoutResult> NGUnpositionedListMarker::Layout(
bool NGUnpositionedListMarker::AddToBox(
const NGConstraintSpace& space,
const NGPhysicalFragment& content,
NGLogicalOffset offset,
NGLogicalOffset* content_offset,
NGFragmentBuilder* container_builder) const {
// Compute the baseline of the child content.
FontBaseline baseline_type = IsHorizontalWritingMode(space.GetWritingMode())
......@@ -84,20 +84,25 @@ bool NGUnpositionedListMarker::AddToBox(
// Compute the inline offset of the marker.
NGBoxFragment marker_fragment(space.GetWritingMode(),
marker_physical_fragment);
offset.inline_offset = InlineOffset(marker_fragment.InlineSize());
NGLogicalSize maker_size = marker_fragment.Size();
NGLogicalOffset marker_offset(InlineOffset(maker_size.inline_size),
content_offset->block_offset);
// Compute the block offset of the marker by aligning the baseline of the
// marker to the first baseline of the content.
// Adjust the block offset to align baselines of the marker and the content.
NGLineHeightMetrics marker_metrics = marker_fragment.BaselineMetrics(
{NGBaselineAlgorithmType::kAtomicInline, baseline_type}, space);
// |offset.block_offset| is at the top of the content. Adjust it to the top of
// the list marker by adding the differences of the ascent between content's
// first line and the list marker.
offset.block_offset += content_metrics.ascent - marker_metrics.ascent;
LayoutUnit baseline_adjust = content_metrics.ascent - marker_metrics.ascent;
if (baseline_adjust >= 0) {
marker_offset.block_offset += baseline_adjust;
} else {
// If the ascent of the marker is taller than the ascent of the content,
// push the content down.
content_offset->block_offset -= baseline_adjust;
}
DCHECK(container_builder);
container_builder->AddChild(std::move(marker_layout_result), offset);
container_builder->AddChild(std::move(marker_layout_result), marker_offset);
return true;
}
......
......@@ -45,8 +45,8 @@ class CORE_EXPORT NGUnpositionedListMarker final {
// that the child content does not have a baseline to align to, and that
// caller should try next child, or "WithoutLineBoxes" version.
bool AddToBox(const NGConstraintSpace&,
const NGPhysicalFragment&,
NGLogicalOffset,
const NGPhysicalFragment& content,
NGLogicalOffset* content_offset,
NGFragmentBuilder*) const;
// Add a fragment for an outside list marker when the list item has no line
......
......@@ -730,12 +730,12 @@ bool NGBlockLayoutAlgorithm::HandleNewFormattingContext(
container_builder_.SetPreviousBreakAfter(break_after);
}
PositionOrPropagateListMarker(*layout_result, &logical_offset);
intrinsic_block_size_ =
std::max(intrinsic_block_size_,
logical_offset.block_offset + fragment.BlockSize());
PositionListMarker(*layout_result, logical_offset);
container_builder_.AddChild(layout_result, logical_offset);
container_builder_.PropagateBreak(layout_result);
......@@ -1058,6 +1058,8 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
container_builder_.SetPreviousBreakAfter(break_after);
}
PositionOrPropagateListMarker(*layout_result, &logical_offset);
// Only modify intrinsic_block_size_ if the fragment is non-empty block.
//
// Empty blocks don't immediately contribute to our size, instead we wait to
......@@ -1073,8 +1075,6 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
logical_offset.block_offset + fragment.BlockSize());
}
PositionListMarker(*layout_result, logical_offset);
container_builder_.AddChild(layout_result, logical_offset);
if (child.IsBlock())
container_builder_.PropagateBreak(layout_result);
......@@ -1838,13 +1838,14 @@ LayoutUnit NGBlockLayoutAlgorithm::CalculateMinimumBlockSize(
return NGSizeIndefinite;
}
void NGBlockLayoutAlgorithm::PositionListMarker(
void NGBlockLayoutAlgorithm::PositionOrPropagateListMarker(
const NGLayoutResult& layout_result,
const NGLogicalOffset& content_offset) {
NGLogicalOffset* content_offset) {
// If this is not a list-item, propagate unpositioned list markers to
// ancestors.
if (!node_.IsListItem()) {
if (layout_result.UnpositionedListMarker()) {
DCHECK(!container_builder_.UnpositionedListMarker());
container_builder_.SetUnpositionedListMarker(
layout_result.UnpositionedListMarker());
}
......
......@@ -188,7 +188,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
void AddPositionedFloats(const Vector<NGPositionedFloat>& positioned_floats);
// Positions a list marker for the specified block content.
void PositionListMarker(const NGLayoutResult&, const NGLogicalOffset&);
void PositionOrPropagateListMarker(const NGLayoutResult&, NGLogicalOffset*);
// Positions a list marker when the block does not have any line boxes.
void PositionListMarkerWithoutLineBoxes();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment