fune/testing/web-platform/tests/css/css-transforms/3d-rendering-context-behavior.html
L. David Baron a7a929b30c Bug 1718170 [wpt PR 29494] - Fix layout geometry mapping to do correct 3D scene extension., a=testonly
Automatic update from web-platform-tests
Fix layout geometry mapping to do correct 3D scene extension.

This fixes MapLocalToAncestor (which is used by getBoundingClientRect),
MapAncestorToLocal, and MapVisualRectToContainer (although users of
these APIs should eventually switch to using GeometryMapper, see
https://crbug.com/1222769) to follow the same rules as
PaintPropertyTreeBuilder (which constructs the state that GeometryMapper
uses) for extension of 3D scenes created by transform-style:
preserve-3d.  These rules change under the TransformInterop feature,
since 3D scene extension should be based on DOM elements rather than
containing blocks, and should not extend across nodes that have no
transform.  However, this patch makes changes both with and without
TransformInterop enabled since the existing code did not match the
rendering behavior.

Testing:
* the getBoundingClientRect calls in
  web_tests/external/wpt/css/css-transforms/3d-rendering-context-behavior.html
  test MapLocalToAncestor, as do the
  MapCoordinatesTest.LocalToAbsoluteTransformFlattens* and
  MapCoordinatesTest.Transform3DWithOffset* unittests.
* The MouseEvent.offsetX getters in various tests in
  web_tests/transforms/3d/point-mapping/ (3d-point-mapping-2.html,
  3d-point-mapping-3.html, 3d-point-mapping-deep.html, and
  3d-point-mapping-preserve-3d.html) test MapAncestorToLocal.

Note that the change to MapVisualRectToContainer is untested.

Note that the new test 3d-point-mapping-2-transforminterop.html is a
variant of 3d-point-mapping-2.html that is intended to pass with
TransformInterop enabled.  However, it does not yet pass due to what I
think is a separate bug, likely in the preserve-3d handling in
PaintLayer::HitTestLayer.

Note also that the changes to map_coordinates_test.cc are needed because
the new non-TransformInterop code leaves the transform in a 3D state
where it didn't before (because there are no elements up to the root
that would break a preserve-3d scene).  While an alternative is trying
to fix this up when we reach the root element or the given ancestor, I'm
not aware of problems it causes beyond the unit test, and it seems like
a reasonable result to me.  Fixing the unit test requires either a call
to matrix.FlattenTo2d() or (as I chose) changing the ProjectPoint calls
to MapPoint.  I don't want to add additional flattening beyond this unit
test without evidence that doing so would make things better rather than
worse.

Bug: 1008483
Change-Id: Ibdf34963152e101ab51655a332eec1d4b0ea014f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2981232
Reviewed-by: Chris Harrelson <chrishtr@chromium.org>
Commit-Queue: David Baron <dbaron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#897174}

--

wpt-commits: 44e55d32f155a7e50fe9848c0a62404cfa2508fd
wpt-pr: 29494
2021-06-30 17:34:53 +00:00

126 lines
4 KiB
HTML

<!doctype HTML>
<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
div {
width: 200px;
height: 200px;
}
.rotate45 {
transform: rotateY(45deg)
}
.rotateNeg45 {
transform: rotateY(-45deg)
}
.parent {
transform-style: preserve-3d;
}
.perspective {
perspective: 200px;
}
</style>
<div class="parent rotateNeg45">
<div id=childOfPreserve3D class="child rotate45"></div>
</div>
<div class="parent rotateNeg45">
<div id=absChildOfPreserve3D class="child rotate45" style="position: absolute"></div>
</div>
<div class="parent rotateNeg45">
<div id=fixedChildOfPreserve3D class="child rotate45" style="position: fixed"></div>
</div>
<div class="parent rotateNeg45">
<div>
<div id=childWithIntermediate class="child rotate45"></div>
</div>
</div>
<div class="parent rotateNeg45">
<div>
<div id=absWithIntermediate class="child rotate45" style="position: absolute"></div>
</div>
</div>
<div class="parent rotateNeg45">
<div>
<div id=fixedWithIntermediate class="child rotate45" style="position: fixed"></div>
</div>
</div>
<div class="perspective">
<div id=childWithPerspectiveParent class="child rotate45"></div>
<div id=absWithPerspectiveParent class="child rotate45" style="position: absolute"></div>
<div id=fixedWithPerspectiveParent class="child rotate45" style="position: fixed"></div>
</div>
<div class="perspective">
<div>
<div id=childWithIntermediateAndPerspectiveParent class="child rotate45"></div>
<div id=absWithIntermediateAndPerspectiveParent class="child rotate45" style="position: absolute"></div>
<div id=fixedWithIntermediateAndPerspectiveParent class="child rotate45" style="position: fixed"></div>
</div>
</div>
<script>
test(function() {
assert_equals(childOfPreserve3D.getBoundingClientRect().width, 200);
}, "Direct DOM parent is root of rendering context (normal flow)");
test(function() {
assert_equals(absChildOfPreserve3D.getBoundingClientRect().width, 200);
}, "Direct DOM parent is root of rendering context (absolute)");
test(function() {
assert_equals(fixedChildOfPreserve3D.getBoundingClientRect().width, 200);
}, "Direct DOM parent is root of rendering context (fixed)");
test(function() {
assert_equals(childWithIntermediate.getBoundingClientRect().width, 100);
}, "Intermediate DOM nodes cause rendering context to end (normal flow)");
test(function() {
assert_equals(absWithIntermediate.getBoundingClientRect().width, 100);
}, "Intermediate DOM nodes cause rendering context to end (absolute)");
test(function() {
assert_equals(fixedWithIntermediate.getBoundingClientRect().width, 100);
}, "Intermediate DOM nodes cause rendering context to end (fixed)");
test(function() {
assert_approx_equals(
childWithPerspectiveParent.getBoundingClientRect().width, 161, 1);
}, "Perspective applies to direct DOM normal-flow children");
test(function() {
assert_approx_equals(
absWithPerspectiveParent.getBoundingClientRect().width, 161, 1);
}, "Perspective applies to direct DOM abs-pos children");
test(function() {
assert_approx_equals(
fixedWithPerspectiveParent.getBoundingClientRect().width, 161, 1);
}, "Perspective applies to direct DOM fixed-pos children");
test(function() {
assert_approx_equals(
childWithIntermediateAndPerspectiveParent.getBoundingClientRect().width,
141, 1);
}, "Perspective does not apply to DOM normal-flow grandchildren");
test(function() {
assert_approx_equals(
absWithIntermediateAndPerspectiveParent.getBoundingClientRect().width,
141, 1);
}, "Perspective does not apply to DOM abs-pos grandchildren");
test(function() {
assert_approx_equals(
fixedWithIntermediateAndPerspectiveParent.getBoundingClientRect().width,
141, 1);
}, "Perspective does not apply to DOM fixed-pos grandchildren");
</script>