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

Apply |PostLayout| to |LayoutBox| instead of |LayoutBlockFlow|

|PostLayout| was limited to |LayoutBlockFlow| because
crbug.com/965639 could happen only to|LayoutBlockFlow|,
but following conditions have changed:

* Only |LayoutBlockFlow| could be relayout boundary, until
  r772560 <crrev.com/c/2219312>.
* Only |LayoutBlockFlow| was laid out by LayoutNG, until
  |LayoutNGFlexibleBox| inherits from |LayoutBlock|.

This patch changes |PostLayout| to work for |LayoutBox|.

In doing so, two changes were made:
1. |CurrentFragment| is replaced with |GetPhysicalFragment|
   because the former is not available for |LayoutBox|.
2. Stopped checking |IsRelayoutBoundary|. Though it is the
   only case crbug.com/965639 can happen as far as we're
   aware of, checking |NGPhysicalFragment| is more
   essential and sufficient.

The change 1 also helps <crbug.com/1061423>, but we may need
different approach to support block fragmentation.

Bug: 1102151, 965639
Change-Id: Id83be614066392a4c58c8b03bd16ee57ad82e145
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2302984Reviewed-by: default avatarDavid Grogan <dgrogan@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789656}
parent 3fb5ea6e
......@@ -354,15 +354,28 @@ const FragmentData* NGPhysicalFragment::GetFragmentData() const {
}
const NGPhysicalFragment* NGPhysicalFragment::PostLayout() const {
if (IsBox() && !IsInlineBox()) {
if (const auto* block = DynamicTo<LayoutBlockFlow>(GetLayoutObject())) {
if (block->IsRelayoutBoundary()) {
const NGPhysicalFragment* new_fragment = block->CurrentFragment();
if (new_fragment && new_fragment != this)
return new_fragment;
}
const auto* layout_box = ToLayoutBoxOrNull(GetLayoutObject());
if (UNLIKELY(!layout_box))
return nullptr;
DCHECK_GT(layout_box->PhysicalFragmentCount(), 0u);
if (layout_box->PhysicalFragmentCount() == 1) {
const NGPhysicalFragment* post_layout = layout_box->GetPhysicalFragment(0);
DCHECK(post_layout);
if (UNLIKELY(post_layout && post_layout != this)) {
// Relayout boundary is the only case this can happen. crbug.com/829028
DCHECK(layout_box->IsRelayoutBoundary());
return post_layout;
}
} else {
// TODO(crbug.com/829028): Block fragmentation not supported yet.
DCHECK(!layout_box->IsRelayoutBoundary());
}
DCHECK(std::any_of(layout_box->PhysicalFragments().begin(),
layout_box->PhysicalFragments().end(),
[this](const NGPhysicalFragment& fragment) {
return this == &fragment;
}));
return nullptr;
}
......
<!doctype html>
<title>Test `contain: strict` to Flexbox does not crash</title>
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#contain-property">
<link rel="author" href="mailto:kojii@chromium.org">
<style>
body {
contain: strict;
display: flex;
}
html {
outline: 1px auto;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="target"></div>
<div id="log"></div>
<script>
test(() => {
document.body.offsetTop;
target.style.width = '100px';
document.body.offsetTop;
}, "Pass if no crash");
</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