Bug 1761995 - Skip `content-visibility: hidden` content in display lists r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D142341
This commit is contained in:
Martin Robinson 2022-04-05 09:10:42 +00:00
Родитель 30ca834b74
Коммит b24fd95192
44 изменённых файлов: 162 добавлений и 73 удалений

Просмотреть файл

@ -513,6 +513,12 @@ void nsHTMLCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
DisplayBorderBackgroundOutline(aBuilder, aLists);
if (IsContentHidden()) {
DisplaySelectionOverlay(aBuilder, aLists.Content(),
nsISelectionDisplay::DISPLAY_IMAGES);
return;
}
uint32_t clipFlags =
nsStyleUtil::ObjectPropsMightCauseOverflow(StylePosition())
? 0

Просмотреть файл

@ -4130,6 +4130,10 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
return;
}
if (IsContentHidden()) {
return;
}
// If we're generating a display list for printing, include Link items for
// frames that correspond to HTML link elements so that we can have active
// links in saved PDF output. Note that the state of "within a link" is
@ -6952,6 +6956,14 @@ bool nsIFrame::IsContentDisabled() const {
return element && element->IsDisabled();
}
bool nsIFrame::IsContentHidden() const {
if (!StyleDisplay()->IsContentVisibilityHidden()) {
return false;
}
return IsFrameOfType(nsIFrame::eReplaced) || !StyleDisplay()->IsInlineFlow();
}
nsresult nsIFrame::CharacterDataChanged(const CharacterDataChangeInfo&) {
MOZ_ASSERT_UNREACHABLE("should only be called for text frames");
return NS_OK;

Просмотреть файл

@ -3155,6 +3155,11 @@ class nsIFrame : public nsQueryFrame {
*/
bool IsContentDisabled() const;
/**
* Whether the content is hidden via the `content-visibilty` property.
*/
bool IsContentHidden() const;
/**
* Get the "type" of the frame.
*

Просмотреть файл

@ -2288,6 +2288,12 @@ void nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
DisplayBorderBackgroundOutline(aBuilder, aLists);
if (IsContentHidden()) {
DisplaySelectionOverlay(aBuilder, aLists.Content(),
nsISelectionDisplay::DISPLAY_IMAGES);
return;
}
uint32_t clipFlags =
nsStyleUtil::ObjectPropsMightCauseOverflow(StylePosition())
? 0

Просмотреть файл

@ -351,6 +351,10 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
return;
}
if (IsContentHidden()) {
return;
}
// If we're passing pointer events to children then we have to descend into
// subdocuments no matter what, to determine which parts are transparent for
// hit-testing or event regions.

Просмотреть файл

@ -662,6 +662,10 @@ void nsVideoFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
DisplayBorderBackgroundOutline(aBuilder, aLists);
if (IsContentHidden()) {
return;
}
const bool shouldDisplayPoster = ShouldDisplayPoster();
// NOTE: If we're displaying a poster image (instead of video data), we can

Просмотреть файл

@ -2478,7 +2478,7 @@ nsChangeHint nsStyleDisplay::CalcDifference(
// FIXME(mrobinson): Depending on how this is implemented this may need a
// different set of change hints. See bug 1758490.
if (mContentVisibility != aNewData.mContentVisibility) {
hint |= nsChangeHint_NeedReflow;
hint |= nsChangeHint_RepaintFrame;
}
if (mScrollbarGutter != aNewData.mScrollbarGutter) {

Просмотреть файл

@ -1563,6 +1563,10 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
!IsInnerTableStyle();
}
bool IsContentVisibilityHidden() const {
return mContentVisibility == mozilla::StyleContentVisibility::Hidden;
}
/* Returns whether the element has the transform property or a related
* property. */
bool HasTransformStyle() const {

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -1,4 +0,0 @@
[content-visibility-015.html]
[Content Visibility: hit testing]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[content-visibility-016.html]
[Content Visibility: hit testing (composited)]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[content-visibility-017.html]
[Content Visibility: hit testing (composited child)]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[content-visibility-018.html]
[Content Visibility: hit testing (composited with a composited child)]
expected: FAIL

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -1,4 +1,3 @@
[content-visibility-029.html]
[innerText on locked element.]
expected: FAIL

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -1,8 +1,7 @@
[content-visibility-035.html]
expected:
if (os == "win") and not debug: ["OK", "TIMEOUT"]
if (os == "win") and not debug: [OK, TIMEOUT]
[Testing focus and force layout on element with hidden flat-tree ancestor]
expected:
if (os == "win") and not debug: ["FAIL", "TIMEOUT"]
if (os == "win") and not debug: [FAIL, TIMEOUT]
FAIL

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -1,2 +0,0 @@
[element-reassigned-to-skipped-slot.html]
expected: FAIL

Просмотреть файл

@ -1,2 +0,0 @@
[element-reassigned-to-slot-in-skipped-subtree.html]
expected: FAIL

Просмотреть файл

@ -0,0 +1,17 @@
<!doctype HTML>
<html>
<meta charset="utf8">
<title>Content Visibility: hidden canvas (reference)</title>
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
<style>
div {
width: 200px;
height: 200px;
background: green;
border: 1px solid black;
}
</style>
<div></div>

Просмотреть файл

@ -0,0 +1,43 @@
<!doctype HTML>
<html class="reftest-wait">
<meta charset="utf8">
<title>Content Visibility: hidden canvas</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="content-visibility-canvas-ref.html">
<meta name="assert" content="content-visibility hidden canvas element does not paint replaced content">
<script src="/common/reftest-wait.js"></script>
<style>
canvas {
width: 200px;
height: 200px;
background: green;
border: 1px solid black;
}
.hidden {
content-visibility: hidden;
}
</style>
<canvas id="canvas">
</canvas>
<script>
async function runTest() {
var context = canvas.getContext("2d");
context.fillStyle = "red";
context.fillRect(0, 0, canvas.width, canvas.height);
canvas.classList.add("hidden");
requestAnimationFrame(takeScreenshot);
}
window.onload = () => {
requestAnimationFrame(() => {
requestAnimationFrame(runTest);
});
};
</script>
</html>

Просмотреть файл

@ -0,0 +1,17 @@
<!doctype HTML>
<html>
<meta charset="utf8">
<title>Content Visibility: hidden video (reference)</title>
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
<style>
div {
width: 200px;
height: 200px;
background: green;
border: 1px solid black;
}
</style>
<div></div>

Просмотреть файл

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html class="reftest-wait">
<meta charset="utf-8">
<title>Content Visibility: hidden video</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="content-visibility-video-ref.html">
<meta name="assert" content="content-visibility hidden video element does not paint replaced content">
<script src="/common/reftest-wait.js"></script>
<style>
video {
width: 200px;
height: 200px;
background: green;
border: 1px solid black;
}
.hidden {
content-visibility: hidden;
}
</style>
<body>
<video id="video" poster="../support/blue-100x100.png" src="../support/white.webm" controls></video>
</body>
<script>
async function runTest() {
video.classList.add("hidden");
video.play();
requestAnimationFrame(takeScreenshot);
}
window.onload = () => {
requestAnimationFrame(() => {
requestAnimationFrame(runTest);
});
};
</script>
</html>