fune/testing/web-platform/tests/css/css-break/inline-with-float-003.html
Morten Stenshorne 5b7faecc90 Bug 1854470 [wpt PR 42067] - Correct fragmentation of floats inside inlines., a=testonly
Automatic update from web-platform-tests
Correct fragmentation of floats inside inlines.

If layout decided to fragment a float, or break before it, and this
float was inside an inline formatting context, it would "escape" the
inline formatting context for subsequent fragments, and be laid out as a
direct float child of the containing block. This would cause paint and
hit testing issues, because the actual inline ancestors of the float
would have no effect on the float, so that e.g. a SPAN with relative
positioning or opacity would only affect the first fragment of the
float. Furthermore, the fact that we were not keeping the float inside
the inline formatting context could also result in a non-contiguous
FragmentData range for a LayoutInline, and, if this LayoutInline
established a PaintLayer,  we would get confused and fail to paint /
hit-test anything in a after a tall float.

We already had code to propagate float breaks to the containing block
layout algorithm. The fix is to wrap the break tokens of such floats
inside an inline break token, and resume such inline break tokens as
parallel fragmentation flows.

We had code in PrePaint as an attempt to cope with escaping float
fragments, to some extent, which is no longer required, so I removed it.
It should be noted that this did by no means work in all situations. If
a float was a child of a PaintLayer-establishing LayoutInline, PrePaint
would get confused as to which PaintLayer was the containing layer of
the float.

More cleanup is possible after this. For now, added a note to
NGBoxFragmentPainter::PaintFloatingChildren(). We should now be able to
assume non-contiguous ranges of physical fragments that have fragment
items. Previously, a tall and fragmented float could prevent some of the
containing physical fragments from getting items.

Update two unit tests. DumpFragmentTree() unfortunately doesn't dump the
contents of a line box, so now that resumed floats also end up inside
lines, they aren't dumped. This was already the case for the first
fragment of any float in an inline formatting context, but now it also
happens to subsequent fragments.

Bug: 1113185, 1327322
Change-Id: Ie81791892d68ffccd0aec92ee6439de4b03326dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4874801
Reviewed-by: Koji Ishii <kojii@chromium.org>
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1199277}

--

wpt-commits: 3f1830341fa1459c67e4c5d5c9a90c97b0ca498c
wpt-pr: 42067
2023-09-28 14:58:15 +00:00

42 lines
1.5 KiB
HTML

<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1113185">
<style>
.ib {
display: inline-block;
width: 100%;
vertical-align: top;
}
body { margin: 0; }
</style>
<div style="columns:5; gap:0; column-fill:auto; width:100px; height:100px; orphans:1; widows:1;">
<div style="height:170px;"></div>
<span style="position:relative;">
<div id="ib1" class="ib" style="height:30px;"></div>
<div id="ib2" class="ib" style="height:20px;"></div>
<div id="floater" style="position:relative; float:left; width:100%; height:200px;"></div>
<div id="ib3" class="ib" style="height:80px;"></div>
</span>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
test(()=> {
assert_equals(document.elementFromPoint(20, 70), ib1);
}, "Hit first inline-block");
test(()=> {
assert_equals(document.elementFromPoint(40, 0), ib2);
}, "Hit second inline-block");
test(()=> {
assert_equals(document.elementFromPoint(40, 20), floater);
}, "Hit first float fragment");
test(()=> {
assert_equals(document.elementFromPoint(60, 0), floater);
}, "Hit second float fragment");
test(()=> {
assert_equals(document.elementFromPoint(80, 0), floater);
}, "Hit third float fragment");
test(()=> {
assert_equals(document.elementFromPoint(80, 20), ib3);
}, "Hit third inline-block");
</script>