Commit 5d6edb4f authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Fix scrollIntoView(...) for SVG elements

AbsoluteBoundingBoxRectForScrollIntoView and associated helpers did not
compute the correct bounding box for SVG shapes (or anything but the SVG
root.)
Compute the bounding rect using the stroke bounding box.

Bug: 803440
Change-Id: If25ca98b686f17a0db699e569460cb4c276f06a0
Reviewed-on: https://chromium-review.googlesource.com/1238458Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#593306}
parent 4c185c15
<!DOCTYPE HTML>
<title>scrollIntoView on an SVG shape element</title>
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollintoview">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<svg width="8000" height="8000">
<rect width="100" height="100" fill="blue" y="1950" id="geometry"/>
<rect width="100" height="100" fill="blue" transform="translate(0, 2950)"
id="translated"/>
<rect width="100" height="100" fill="blue" transform="rotate(45, 50, 3950)"
id="rotated"/>
</svg>
<script>
add_completion_callback(() => {
document.querySelector("svg").remove();
window.scrollTo(0, 0);
});
for (let id of [ "geometry", "translated", "rotated" ]) {
test(t => {
let target = document.getElementById(id);
window.scrollTo(0, 0);
let bounds = target.getBoundingClientRect();
let expected = { x: bounds.left, y: bounds.top };
assert_not_equals(window.scrollX, expected.x, "x before scroll");
assert_not_equals(window.scrollY, expected.y, "y before scroll");
target.scrollIntoView({ block: "start", inline: "start" });
assert_approx_equals(window.scrollX, expected.x, 1, "x after scroll");
assert_approx_equals(window.scrollY, expected.y, 1, "y after scroll");
}, document.title + ", " + id);
}
</script>
...@@ -1179,6 +1179,14 @@ inline const LayoutObject* EndOfContinuations( ...@@ -1179,6 +1179,14 @@ inline const LayoutObject* EndOfContinuations(
bool LayoutObject::GetUpperLeftCorner(ExpandScrollMargin expand, bool LayoutObject::GetUpperLeftCorner(ExpandScrollMargin expand,
FloatPoint& point) const { FloatPoint& point) const {
if (IsSVGChild()) {
point = LocalToAbsoluteQuad(StrokeBoundingBox(), kUseTransforms)
.BoundingBox()
.MinXMinYCorner();
if (expand == ExpandScrollMargin::kExpand)
MovePointByScrollMargin(this, MarginCorner::kTopLeft, point);
return true;
}
if (!IsInline() || IsAtomicInlineLevel()) { if (!IsInline() || IsAtomicInlineLevel()) {
point = LocalToAbsolute(FloatPoint(), kUseTransforms); point = LocalToAbsolute(FloatPoint(), kUseTransforms);
if (expand == ExpandScrollMargin::kExpand) if (expand == ExpandScrollMargin::kExpand)
...@@ -1259,6 +1267,14 @@ bool LayoutObject::GetUpperLeftCorner(ExpandScrollMargin expand, ...@@ -1259,6 +1267,14 @@ bool LayoutObject::GetUpperLeftCorner(ExpandScrollMargin expand,
bool LayoutObject::GetLowerRightCorner(ExpandScrollMargin expand, bool LayoutObject::GetLowerRightCorner(ExpandScrollMargin expand,
FloatPoint& point) const { FloatPoint& point) const {
if (IsSVGChild()) {
point = LocalToAbsoluteQuad(StrokeBoundingBox(), kUseTransforms)
.BoundingBox()
.MaxXMaxYCorner();
if (expand == ExpandScrollMargin::kExpand)
MovePointByScrollMargin(this, MarginCorner::kBottomRight, point);
return true;
}
if (!IsInline() || IsAtomicInlineLevel()) { if (!IsInline() || IsAtomicInlineLevel()) {
const LayoutBox* box = ToLayoutBox(this); const LayoutBox* box = ToLayoutBox(this);
point = LocalToAbsolute(FloatPoint(box->Size()), kUseTransforms); point = LocalToAbsolute(FloatPoint(box->Size()), kUseTransforms);
......
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