Files
sousa-gecko/testing/web-platform/tests/css/css-multicol/getclientrects-005.html
T
Morten Stenshorne a13ade5309 Bug 1964541 [wpt PR 52350] - Fix MapLocalToAncestor() & co for block fragmentation.,
Automatic update from web-platform-tests
Fix MapLocalToAncestor() & co for block fragmentation.

Get rid of the dependency on LayoutFlowThread and the other legacy
multicol classes for this.

Fix it so that LayoutBox::PhysicalLocation() returns the offset of the
first fragment relatively to the first fragment of its containing block.
No behavior changes unless content is inside block fragmentation. For
block fragmentation, this will affect the behavior of APIs such as
offsetLeft and offsetTop. Previously, when inside block fragmentation,
the offset would be in the internal "stitched" flow thread coordinate
space, where we pretend that all fragmented content is laid out into a
single tall strip. Then we'd convert this to real visual offsets with
help from the flow thread, in some cases, where in others (if both the
element and its offsetParent were inside block fragmentation), the
"stitched" flow thread coordinates would be exposed through APIs such as
offsetLeft and offsetTop.

Apart from this correctness fix, with this CL we're much closer to being
able to remove LayoutFlowThread & co, which are legacy layout objects
that were needed by the legacy layout engine, (and was still required by
the LayoutNG engine, due to this offset calculation stuff, but not by
actual layout).

In order to calculate the offset of the first fragment relatively to the
first fragment of its containing block inside block fragmentation, we
first need to actually finish fragmented layout, since the first
fragment of an element may not be in the same fragmentainer as the first
fragment of its containing block. In case of out-of-flow positioning an
element may even start in an earlier fragmentainer than its containing
block. The code for this machinery is in LayoutBoxUtils. Some of the
logic is copied from the BlockNode code that dealt with this (the
BlockNode parts will be removed when this feature eventually is soldered
to the engine - for now add DCHECKs to make sure that the code is
unreached).

LayoutTableColumn needed some additional fixing. Since table columns
don't generate fragments, there's some code in there to synthesize such
fragments. The new code is based on the logic in
LayoutTableColumn::DeprecatedLocationInternal() (which by the way had
bugs for vertical-rl writing-mode, which are fixed in the new code),
including some checks that never seem to trigger (add TODO).

Prefix old location functions in LayoutBox with "Deprecated", and add
some DCHECKs to ensure that they aren't reached. Also added such DCHECK
to a bunch of LayoutFlowThread, LayoutMultiColumnFlowThread,
LayoutMultiColumnSet functions.

This is behind a runtime-enabled feature flag called
LayoutBoxVisualLocation. For now set it to "experimental". Will flip it
to stable once the feature is complete. Since this CL affects the
behavior of offsetLeft and offsetTop when inside fragmentation, this is
an opportunity to get this to make more sense overall. First of all,
offsetWidth and offsetHeight should be a union of all fragments. It
still uses the stitched block-size. It's not 100% clear how this should
work exactly. See https://github.com/w3c/csswg-drafts/issues/11541

But it seems reasonable that we should be able to walk up the
offsetParent chain from one element `elm`, adding offsetLeft and
offsetTop at each step on the way, and then end up with the same result
as if using `elm.getBoundingClientRect()` (also for width and height).
Will follow up on this.

Many tests that deal with offsetLeft and offsetTop inside block
fragmentation have to be updated because of this change. Also add some
new tests for the improved getClientRects() behavior for table columns
and also for content that overflows the fragmentainers (due to being
tall and monolithic).

Add another PrintContextTest for something that has never worked before:
handling root element margins correctly for PDF URL fragment target
rectangles (this is a corner case all right).

Remove some unit tests (or parts) that are no longer valid because of
this change.

Bug: 40855022
Fuchsia-Binary-Size: shut up.
Change-Id: I0e1fc6cf7717b74b904c825e519ee4694faf87f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6507711
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1456237}

--

wpt-commits: 0a5a7abb801d347601814cd6ffaa1f85ecaa434c
wpt-pr: 52350

Differential Revision: https://phabricator.services.mozilla.com/D248852
2025-05-12 09:22:21 +00:00

140 lines
4.6 KiB
HTML

<!DOCTYPE html>
<title>getClientRects on fragmented table-column and table-column-group</title>
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-getclientrects">
<link rel="help" href="https://drafts.csswg.org/css-multicol/">
<style>
body {
margin: 8px;
}
</style>
<div style="columns:6; gap:20px; inline-size:580px; column-rule:solid; column-fill:auto; block-size:100px; background:yellow;">
<div style="block-size:110px;"></div>
<div style="display:table; inline-size:100%; border-spacing:5px; border:2px solid; background:pink;">
<div style="display:table-caption; block-size:100px;"></div>
<div style="display:table-caption; caption-side:bottom; block-size:100px;"></div>
<div id="col1" style="display:table-column; inline-size:15px; background:blue;"></div>
<div id="col2" style="display:table-column; background:lime;"></div>
<div id="group" style="display:table-column-group;">
<div id="col3" style="display:table-column; inline-size:20px; background:hotpink;"></div>
<div id="col4" style="display:table-column; inline-size:10px; background:cyan;" id="col2"></div>
</div>
<div style="display:table-row-group;">
<div style="display:table-cell;">
<div style="block-size:5px;"></div>
</div>
</div>
<div style="display:table-row-group;">
<div style="display:table-cell;">
<div style="block-size:240px;"></div>
</div>
<div style="display:table-cell;"></div>
<div style="display:table-cell;"></div>
<div style="display:table-cell;"></div>
</div>
</div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
test(()=> {
let rects = col1.getClientRects();
assert_equals(rects.length, 3);
assert_equals(rects[0].left, 215);
assert_equals(rects[0].top, 25);
assert_equals(rects[0].width, 15);
assert_equals(rects[0].height, 83);
assert_equals(rects[1].left, 315);
assert_equals(rects[1].top, 8);
assert_equals(rects[1].width, 15);
assert_equals(rects[1].height, 100);
assert_equals(rects[2].left, 415);
assert_equals(rects[2].top, 8);
assert_equals(rects[2].width, 15);
assert_equals(rects[2].height, 67);
}, "#col1");
test(()=> {
let rects = col2.getClientRects();
assert_equals(rects.length, 3);
assert_equals(rects[0].left, 235);
assert_equals(rects[0].top, 25);
assert_equals(rects[0].width, 10);
assert_equals(rects[0].height, 83);
assert_equals(rects[1].left, 335);
assert_equals(rects[1].top, 8);
assert_equals(rects[1].width, 10);
assert_equals(rects[1].height, 100);
assert_equals(rects[2].left, 435);
assert_equals(rects[2].top, 8);
assert_equals(rects[2].width, 10);
assert_equals(rects[2].height, 67);
}, "#col2");
test(()=> {
let rects = col3.getClientRects();
assert_equals(rects.length, 3);
assert_equals(rects[0].left, 250);
assert_equals(rects[0].top, 25);
assert_equals(rects[0].width, 20);
assert_equals(rects[0].height, 83);
assert_equals(rects[1].left, 350);
assert_equals(rects[1].top, 8);
assert_equals(rects[1].width, 20);
assert_equals(rects[1].height, 100);
assert_equals(rects[2].left, 450);
assert_equals(rects[2].top, 8);
assert_equals(rects[2].width, 20);
assert_equals(rects[2].height, 67);
}, "#col3");
test(()=> {
let rects = col4.getClientRects();
assert_equals(rects.length, 3);
assert_equals(rects[0].left, 275);
assert_equals(rects[0].top, 25);
assert_equals(rects[0].width, 10);
assert_equals(rects[0].height, 83);
assert_equals(rects[1].left, 375);
assert_equals(rects[1].top, 8);
assert_equals(rects[1].width, 10);
assert_equals(rects[1].height, 100);
assert_equals(rects[2].left, 475);
assert_equals(rects[2].top, 8);
assert_equals(rects[2].width, 10);
assert_equals(rects[2].height, 67);
}, "#col4");
test(()=> {
let rects = group.getClientRects();
assert_equals(rects.length, 3);
assert_equals(rects[0].left, 250);
assert_equals(rects[0].top, 25);
assert_equals(rects[0].width, 35);
assert_equals(rects[0].height, 83);
assert_equals(rects[1].left, 350);
assert_equals(rects[1].top, 8);
assert_equals(rects[1].width, 35);
assert_equals(rects[1].height, 100);
assert_equals(rects[2].left, 450);
assert_equals(rects[2].top, 8);
assert_equals(rects[2].width, 35);
assert_equals(rects[2].height, 67);
}, "#group");
</script>