Commit 4f101695 authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[FragmentItem] Skip already added children in CreateBoxFragment

FragmentItem keeps all inline items in a flat list. When
inline box fragments are nested, |CreateBoxFragment| handles
the same item twice; once for its parent and another for its
grand parent.

This patch fixes this by skipping non-direct children.

Bug: 1096957
Change-Id: If5acba0c5bd687d156cc4530fbe6123bca9840ab
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2251643Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#780231}
parent 668c2c98
...@@ -623,6 +623,12 @@ NGInlineLayoutStateStack::BoxData::CreateBoxFragment( ...@@ -623,6 +623,12 @@ NGInlineLayoutStateStack::BoxData::CreateBoxFragment(
for (unsigned i = fragment_start; i < fragment_end; i++) { for (unsigned i = fragment_start; i < fragment_end; i++) {
NGLogicalLineItem& child = (*line_box)[i]; NGLogicalLineItem& child = (*line_box)[i];
// If |child| has a fragment created by previous |CreateBoxFragment|, skip
// children that were already added to |child|.
if (child.children_count)
i += child.children_count - 1;
if (child.out_of_flow_positioned_box) { if (child.out_of_flow_positioned_box) {
DCHECK(item->GetLayoutObject()->IsLayoutInline()); DCHECK(item->GetLayoutObject()->IsLayoutInline());
NGBlockNode oof_box(ToLayoutBox(child.out_of_flow_positioned_box)); NGBlockNode oof_box(ToLayoutBox(child.out_of_flow_positioned_box));
......
...@@ -75,6 +75,12 @@ void NGContainerFragmentBuilder::PropagateChildData( ...@@ -75,6 +75,12 @@ void NGContainerFragmentBuilder::PropagateChildData(
IsInlineContainerForNode(descendant.node, inline_container)) IsInlineContainerForNode(descendant.node, inline_container))
new_inline_container = inline_container; new_inline_container = inline_container;
// |oof_positioned_candidates_| should not have duplicated entries.
DCHECK(std::none_of(
oof_positioned_candidates_.begin(), oof_positioned_candidates_.end(),
[&descendant](const NGLogicalOutOfFlowPositionedNode& node) {
return node.node == descendant.node;
}));
oof_positioned_candidates_.emplace_back(descendant.node, static_position, oof_positioned_candidates_.emplace_back(descendant.node, static_position,
new_inline_container); new_inline_container);
} }
......
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css2/visuren.html#propdef-position">
<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div>
<span style="border: 1px solid blue">
<span style="position: relative">
<span style="display: inline-block">
<span style="position: absolute; background: orange; width: 100px; height: 100px"></span>
</span>
</span>
</span>
</div>
<script>
// Test pass if it does not crash.
test(() => {});
</script>
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