Commit 0ae74b0c authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[FragmentItem] Include floats in associated LayoutObject

This patch changes to associate floating |LayoutObject|s to
|NGFragmentItem| using |FirstInlineFragmentItemIndex|.

The index is used for many purposes, but one of them is to
mark destroyed or moved |LayoutObject| in |NGFragmentItem|.
Because floating objects are stored in |NGFragmentItem|,
they need to be indexed to mark correctly.

Also changes |LayoutBlockFlow::
SetShouldDoFullPaintInvalidationForFirstLine| to skip items
for destroyed or moved |LayoutObject| because it may be
called on dirty tree.

Bug: 1100900
Change-Id: If35bf2c77b9a46a9ba598e6785926f6b0e1c5455
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2275373
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: default avatarAleks Totic <atotic@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#784297}
parent ec3c8ec2
...@@ -2806,8 +2806,12 @@ void LayoutBlockFlow::SetShouldDoFullPaintInvalidationForFirstLine() { ...@@ -2806,8 +2806,12 @@ void LayoutBlockFlow::SetShouldDoFullPaintInvalidationForFirstLine() {
// Mark all descendants of the first line if first-line style. // Mark all descendants of the first line if first-line style.
for (NGInlineCursor descendants = first_line.CursorForDescendants(); for (NGInlineCursor descendants = first_line.CursorForDescendants();
descendants; descendants.MoveToNext()) { descendants; descendants.MoveToNext()) {
LayoutObject* layout_object = const NGFragmentItem* item = descendants.Current().Item();
descendants.Current()->GetMutableLayoutObject(); if (UNLIKELY(item->IsLayoutObjectDestroyedOrMoved())) {
descendants.MoveToNextSkippingChildren();
continue;
}
LayoutObject* layout_object = item->GetMutableLayoutObject();
DCHECK(layout_object); DCHECK(layout_object);
layout_object->StyleRef().ClearCachedPseudoElementStyles(); layout_object->StyleRef().ClearCachedPseudoElementStyles();
layout_object->SetShouldDoFullPaintInvalidation(); layout_object->SetShouldDoFullPaintInvalidation();
......
...@@ -833,7 +833,6 @@ LayoutBox* LayoutObject::EnclosingBox() const { ...@@ -833,7 +833,6 @@ LayoutBox* LayoutObject::EnclosingBox() const {
} }
LayoutBlockFlow* LayoutObject::RootInlineFormattingContext() const { LayoutBlockFlow* LayoutObject::RootInlineFormattingContext() const {
DCHECK(IsInline());
for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) { for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) {
if (auto* block_flow = DynamicTo<LayoutBlockFlow>(parent)) { if (auto* block_flow = DynamicTo<LayoutBlockFlow>(parent)) {
// Skip |LayoutFlowThread| because it is skipped when finding the first // Skip |LayoutFlowThread| because it is skipped when finding the first
...@@ -847,7 +846,6 @@ LayoutBlockFlow* LayoutObject::RootInlineFormattingContext() const { ...@@ -847,7 +846,6 @@ LayoutBlockFlow* LayoutObject::RootInlineFormattingContext() const {
} }
LayoutBlockFlow* LayoutObject::FragmentItemsContainer() const { LayoutBlockFlow* LayoutObject::FragmentItemsContainer() const {
DCHECK(IsInline());
for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) { for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) {
if (auto* block_flow = DynamicTo<LayoutBlockFlow>(parent)) if (auto* block_flow = DynamicTo<LayoutBlockFlow>(parent))
return block_flow; return block_flow;
......
...@@ -62,10 +62,6 @@ void NGFragmentItems::FinalizeAfterLayout( ...@@ -62,10 +62,6 @@ void NGFragmentItems::FinalizeAfterLayout(
continue; continue;
} }
LayoutObject* const layout_object = item.GetMutableLayoutObject(); LayoutObject* const layout_object = item.GetMutableLayoutObject();
if (UNLIKELY(layout_object->IsFloating())) {
DCHECK_EQ(item.DeltaToNextForSameLayoutObject(), 0u);
continue;
}
DCHECK(!layout_object->IsOutOfFlowPositioned()); DCHECK(!layout_object->IsOutOfFlowPositioned());
DCHECK(layout_object->IsInLayoutNGInlineFormattingContext()); DCHECK(layout_object->IsInLayoutNGInlineFormattingContext());
...@@ -109,7 +105,7 @@ void NGFragmentItems::ClearAssociatedFragments(LayoutObject* container) { ...@@ -109,7 +105,7 @@ void NGFragmentItems::ClearAssociatedFragments(LayoutObject* container) {
for (LayoutObject* child = container->SlowFirstChild(); child; for (LayoutObject* child = container->SlowFirstChild(); child;
child = child->NextSibling()) { child = child->NextSibling()) {
if (UNLIKELY(!child->IsInLayoutNGInlineFormattingContext() || if (UNLIKELY(!child->IsInLayoutNGInlineFormattingContext() ||
child->IsFloatingOrOutOfFlowPositioned())) child->IsOutOfFlowPositioned()))
continue; continue;
child->ClearFirstInlineFragmentItemIndex(); child->ClearFirstInlineFragmentItemIndex();
......
...@@ -1410,7 +1410,7 @@ void NGInlineCursor::MoveToPreviousSiblingPaintFragment() { ...@@ -1410,7 +1410,7 @@ void NGInlineCursor::MoveToPreviousSiblingPaintFragment() {
void NGInlineCursor::MoveTo(const LayoutObject& layout_object) { void NGInlineCursor::MoveTo(const LayoutObject& layout_object) {
DCHECK(layout_object.IsInLayoutNGInlineFormattingContext()); DCHECK(layout_object.IsInLayoutNGInlineFormattingContext());
DCHECK(!layout_object.IsFloatingOrOutOfFlowPositioned()); DCHECK(!layout_object.IsOutOfFlowPositioned());
if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) { if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) {
// If this cursor is rootless, find the root of the inline formatting // If this cursor is rootless, find the root of the inline formatting
......
<!DOCTYPE html>
<title>Removing floats in ::first-line should not crash</title>
<link rel="author" href="kojii@chromium.org">
<link rel="help" href="https://crbug.com/1100900">
<meta name="assert" content="Removing floats in ::first-line should not crash">
<style>
#container {
display: flow-root;
}
#container::first-line {
background: orange;
}
#float {
float: left;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<div id="container">text<span id="float"></span></div>
</body>
<script>
test(() => {
document.body.offsetTop;
let float = document.getElementById('float');
float.remove();
let container = document.getElementById('container');
container.style.color = 'blue';
}, 'No crash or DCHECK failure');
</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