Bug 1762407 - Do not scroll content with content-visibility: hidden ancestors into view r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D142563
This commit is contained in:
Martin Robinson 2022-04-07 10:38:27 +00:00
parent 2b39c9ff18
commit 2893cfed87
11 changed files with 167 additions and 9 deletions

View File

@ -3654,7 +3654,7 @@ void PresShell::DoScrollContentIntoView() {
NS_ASSERTION(mDidInitialize, "should have done initial reflow by now");
nsIFrame* frame = mContentToScrollTo->GetPrimaryFrame();
if (!frame) {
if (!frame || frame->AncestorHidesContent()) {
mContentToScrollTo->RemoveProperty(nsGkAtoms::scrolling);
mContentToScrollTo = nullptr;
return;
@ -3725,6 +3725,10 @@ bool PresShell::ScrollFrameRectIntoView(nsIFrame* aFrame, const nsRect& aRect,
ScrollAxis aVertical,
ScrollAxis aHorizontal,
ScrollFlags aScrollFlags) {
if (aFrame->AncestorHidesContent()) {
return false;
}
bool didScroll = false;
// This function needs to work even if rect has a width or height of 0.
nsRect rect = aRect;

View File

@ -6964,6 +6964,20 @@ bool nsIFrame::IsContentHidden() const {
return IsFrameOfType(nsIFrame::eReplaced) || !StyleDisplay()->IsInlineFlow();
}
bool nsIFrame::AncestorHidesContent() const {
if (!StaticPrefs::layout_css_content_visibility_enabled()) {
return false;
}
for (nsIFrame* cur = GetInFlowParent(); cur; cur = cur->GetInFlowParent()) {
if (cur->IsContentHidden()) {
return true;
}
}
return false;
}
nsresult nsIFrame::CharacterDataChanged(const CharacterDataChangeInfo&) {
MOZ_ASSERT_UNREACHABLE("should only be called for text frames");
return NS_OK;

View File

@ -3160,6 +3160,12 @@ class nsIFrame : public nsQueryFrame {
*/
bool IsContentHidden() const;
/**
* Returns true if this frame is entirely hidden due the `content-visibility`
* property on an ancestor.
*/
bool AncestorHidesContent() const;
/**
* Get the "type" of the frame.
*

View File

@ -1,2 +0,0 @@
[content-visibility-056.html]
expected: FAIL

View File

@ -1,2 +0,0 @@
[content-visibility-067.html]
expected: FAIL

View File

@ -1,2 +0,0 @@
[content-visibility-083.html]
expected: FAIL

View File

@ -1,2 +0,0 @@
[content-visibility-084.html]
expected: FAIL

View File

@ -0,0 +1,34 @@
<!doctype HTML>
<html class="reftest-wait">
<meta charset="utf8">
<title>Content Visibility: scrollIntoView should scroll when target has content-visibility: hidden</title>
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
<script src="/common/reftest-wait.js"></script>
<style>
.spacer {
width: 150px;
height: 3000px;
background: lightblue;
}
#target {
width: 150px;
height: 150px;
background: lightgreen;
}
</style>
<div class="spacer"></div>
<div id="target"></div>
<script>
function runTest() {
document.getElementById("target").scrollIntoView();
requestAnimationFrame(takeScreenshot);
}
window.onload = () => { requestAnimationFrame(runTest); };
</script>
</html>

View File

@ -0,0 +1,37 @@
<!doctype HTML>
<html class="reftest-wait">
<meta charset="utf8">
<title>Content Visibility: scrollIntoView should scroll when target has content-visibility: hidden</title>
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
<link rel="match" href="scrollIntoView-target-with-contents-hidden-ref.html">
<meta name="assert" content="scrollIntoView works properly when used on target with content-visibility: hidden">
<script src="/common/reftest-wait.js"></script>
<style>
.spacer {
width: 150px;
height: 3000px;
background: lightblue;
}
#target {
width: 150px;
height: 150px;
background: lightgreen;
content-visibility: hidden;
}
</style>
<div class="spacer"></div>
<div id="target">hidden content</div>
<script>
function runTest() {
document.getElementById("target").scrollIntoView();
requestAnimationFrame(takeScreenshot);
}
window.onload = () => { requestAnimationFrame(runTest); };
</script>
</html>

View File

@ -0,0 +1,34 @@
<!doctype HTML>
<html class="reftest-wait">
<meta charset="utf8">
<title>Content Visibility: scrollIntoView should scroll when target has content-visibility: hidden</title>
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
<script src="/common/reftest-wait.js"></script>
<style>
.spacer {
width: 150px;
height: 3000px;
background: lightblue;
}
#target {
width: 150px;
height: 150px;
background: lightgreen;
}
</style>
<div class="spacer"></div>
<div id="target" tabindex="0"></div>
<script>
function runTest() {
document.getElementById("target").focus();
requestAnimationFrame(takeScreenshot);
}
window.onload = () => { requestAnimationFrame(runTest); };
</script>
</html>

View File

@ -0,0 +1,37 @@
<!doctype HTML>
<html class="reftest-wait">
<meta charset="utf8">
<title>Content Visibility: scrollIntoView triggered by focus() should scroll when target has content-visibility: hidden</title>
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
<link rel="match" href="scrollIntoView-with-focus-target-with-contents-hidden-ref.html">
<meta name="assert" content="scrollIntoView triggered by focus() works properly when used on target with content-visibility: hidden">
<script src="/common/reftest-wait.js"></script>
<style>
.spacer {
width: 150px;
height: 3000px;
background: lightblue;
}
#target {
width: 150px;
height: 150px;
background: lightgreen;
content-visibility: hidden;
}
</style>
<div class="spacer"></div>
<div id="target" tabindex="0">hidden content</div>
<script>
function runTest() {
document.getElementById("target").focus();
requestAnimationFrame(takeScreenshot);
}
window.onload = () => { requestAnimationFrame(runTest); };
</script>
</html>