Commit 2d16c564 authored by Vladimir Levin's avatar Vladimir Levin Committed by Commit Bot

content-visibility: Fix inspector DCHECK when inspecting cv iframe contents

This patch changes the content-visibility check in the inspector code
to make sure that we consider ancestor frames as locked as well.

R=chrishtr@chromium.org

Bug: 1128790
Change-Id: Ie8a4dfebb694bbe50e8c5179ccd9e8cdcc57c35b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2422244Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Commit-Queue: vmpstr <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809180}
parent 66c48ad7
...@@ -24,7 +24,7 @@ namespace { ...@@ -24,7 +24,7 @@ namespace {
// Returns the frame owner node for the frame that contains the given child, if // Returns the frame owner node for the frame that contains the given child, if
// one exists. Returns nullptr otherwise. // one exists. Returns nullptr otherwise.
const Node* GetFrameOwnerNode(const Node* child) { Node* GetFrameOwnerNode(const Node* child) {
if (!child || !child->GetDocument().GetFrame() || if (!child || !child->GetDocument().GetFrame() ||
!child->GetDocument().GetFrame()->OwnerLayoutObject()) { !child->GetDocument().GetFrame()->OwnerLayoutObject()) {
return nullptr; return nullptr;
...@@ -320,40 +320,53 @@ Element* DisplayLockUtilities::NearestLockedExclusiveAncestor( ...@@ -320,40 +320,53 @@ Element* DisplayLockUtilities::NearestLockedExclusiveAncestor(
Element* DisplayLockUtilities::HighestLockedInclusiveAncestor( Element* DisplayLockUtilities::HighestLockedInclusiveAncestor(
const Node& node) { const Node& node) {
if (!RuntimeEnabledFeatures::CSSContentVisibilityEnabled() || if (!RuntimeEnabledFeatures::CSSContentVisibilityEnabled() ||
node.GetDocument()
.GetDisplayLockDocumentState()
.LockedDisplayLockCount() == 0 ||
!node.CanParticipateInFlatTree()) { !node.CanParticipateInFlatTree()) {
return nullptr; return nullptr;
} }
const_cast<Node*>(&node)->UpdateDistributionForFlatTreeTraversal(); auto* node_ptr = const_cast<Node*>(&node);
Element* locked_ancestor = nullptr; node_ptr->UpdateDistributionForFlatTreeTraversal();
for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(node)) { // If the exclusive result exists, then that's higher than this node, so
auto* ancestor_node = DynamicTo<Element>(ancestor); // return it.
if (!ancestor_node) if (auto* result = HighestLockedExclusiveAncestor(node))
continue; return result;
if (auto* context = ancestor_node->GetDisplayLockContext()) {
if (context->IsLocked()) // Otherwise, we know the node is not in a locked subtree, so the only
locked_ancestor = ancestor_node; // other possibility is that the node itself is locked.
} auto* element = DynamicTo<Element>(node_ptr);
if (element && element->GetDisplayLockContext() &&
element->GetDisplayLockContext()->IsLocked()) {
return element;
} }
return locked_ancestor; return nullptr;
} }
Element* DisplayLockUtilities::HighestLockedExclusiveAncestor( Element* DisplayLockUtilities::HighestLockedExclusiveAncestor(
const Node& node) { const Node& node) {
if (!RuntimeEnabledFeatures::CSSContentVisibilityEnabled() || if (!RuntimeEnabledFeatures::CSSContentVisibilityEnabled() ||
node.GetDocument()
.GetDisplayLockDocumentState()
.LockedDisplayLockCount() == 0 ||
!node.CanParticipateInFlatTree()) { !node.CanParticipateInFlatTree()) {
return nullptr; return nullptr;
} }
const_cast<Node*>(&node)->UpdateDistributionForFlatTreeTraversal(); const_cast<Node*>(&node)->UpdateDistributionForFlatTreeTraversal();
if (Node* parent = FlatTreeTraversal::Parent(node)) Node* parent = FlatTreeTraversal::Parent(node);
return HighestLockedInclusiveAncestor(*parent); Element* locked_ancestor = nullptr;
return nullptr; while (parent) {
auto* locked_candidate = NearestLockedInclusiveAncestor(*parent);
auto* last_node = parent;
if (locked_candidate) {
locked_ancestor = locked_candidate;
parent = FlatTreeTraversal::Parent(*parent);
} else {
parent = nullptr;
}
if (!parent) {
parent = GetFrameOwnerNode(last_node);
if (parent)
parent->UpdateDistributionForFlatTreeTraversal();
}
}
return locked_ancestor;
} }
Element* DisplayLockUtilities::NearestLockedInclusiveAncestor( Element* DisplayLockUtilities::NearestLockedInclusiveAncestor(
......
...@@ -118,11 +118,10 @@ class CORE_EXPORT DisplayLockUtilities { ...@@ -118,11 +118,10 @@ class CORE_EXPORT DisplayLockUtilities {
// locked. // locked.
static Element* NearestLockedExclusiveAncestor(const Node& node); static Element* NearestLockedExclusiveAncestor(const Node& node);
// Returns the highest inclusive ancestor of |node| that is display locked.
static Element* HighestLockedInclusiveAncestor(const Node& node);
// Returns the highest exclusive ancestor of |node| that is display locked. // Returns the highest exclusive ancestor of |node| that is display locked.
// Note that this function crosses local frames.
static Element* HighestLockedExclusiveAncestor(const Node& node); static Element* HighestLockedExclusiveAncestor(const Node& node);
static Element* HighestLockedInclusiveAncestor(const Node& node);
// LayoutObject versions of the NearestLocked* ancestor functions. // LayoutObject versions of the NearestLocked* ancestor functions.
static Element* NearestLockedInclusiveAncestor(const LayoutObject& object); static Element* NearestLockedInclusiveAncestor(const LayoutObject& object);
......
Tests highlights for display locking in a frame.
container{
"paths": [
{
"path": [
"M",
10,
10,
"L",
20,
10,
"L",
20,
20,
"L",
10,
20,
"Z"
],
"fillColor": "rgba(255, 0, 0, 0)",
"outlineColor": "rgba(128, 0, 0, 0)",
"name": "content"
},
{
"path": [
"M",
10,
10,
"L",
20,
10,
"L",
20,
20,
"L",
10,
20,
"Z"
],
"fillColor": "rgba(0, 255, 0, 0)",
"name": "padding"
},
{
"path": [
"M",
8,
8,
"L",
22,
8,
"L",
22,
22,
"L",
8,
22,
"Z"
],
"fillColor": "rgba(0, 0, 255, 0)",
"name": "border"
},
{
"path": [
"M",
8,
8,
"L",
22,
8,
"L",
22,
22,
"L",
8,
22,
"Z"
],
"fillColor": "rgba(255, 255, 255, 0)",
"name": "margin"
}
],
"showRulers": true,
"showExtensionLines": true,
"showAccessibilityInfo": true,
"colorFormat": "hex",
"elementInfo": {
"tagName": "iframe",
"idValue": "container",
"nodeWidth": "14",
"nodeHeight": "14",
"isKeyboardFocusable": false,
"accessibleName": "",
"accessibleRole": "",
"layoutObjectName": "LayoutIFrame",
"showAccessibilityInfo": true
}
}
child{
"paths": [
{
"path": [
"M",
10,
10,
"L",
20,
10,
"L",
20,
20,
"L",
10,
20,
"Z"
],
"fillColor": "rgba(255, 0, 0, 0)",
"outlineColor": "rgba(128, 0, 0, 0)",
"name": "content"
},
{
"path": [
"M",
10,
10,
"L",
20,
10,
"L",
20,
20,
"L",
10,
20,
"Z"
],
"fillColor": "rgba(0, 255, 0, 0)",
"name": "padding"
},
{
"path": [
"M",
8,
8,
"L",
22,
8,
"L",
22,
22,
"L",
8,
22,
"Z"
],
"fillColor": "rgba(0, 0, 255, 0)",
"name": "border"
},
{
"path": [
"M",
8,
8,
"L",
22,
8,
"L",
22,
22,
"L",
8,
22,
"Z"
],
"fillColor": "rgba(255, 255, 255, 0)",
"name": "margin"
}
],
"showRulers": true,
"showExtensionLines": true,
"showAccessibilityInfo": true,
"colorFormat": "hex",
"elementInfo": {
"tagName": "iframe",
"idValue": "container",
"nodeWidth": "14",
"nodeHeight": "14",
"isKeyboardFocusable": false,
"accessibleName": "",
"accessibleRole": "",
"layoutObjectName": "LayoutIFrame",
"isLockedAncestor": "true",
"showAccessibilityInfo": true
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(async function() {
TestRunner.addResult(`Tests highlights for display locking in a frame.\n`);
await TestRunner.loadModule('elements_test_runner');
await TestRunner.loadModule('console_test_runner');
await TestRunner.showPanel('elements');
await TestRunner.loadHTML(`
<iframe id="container" style="content-visibility: hidden; contain-intrinsic-size: 10px;"
srcdoc='<div id="child" style="width: 50px; height: 50px; background: blue">Text</div>'
</iframe>
`);
function dumpChild() {
ElementsTestRunner.dumpInspectorHighlightJSON('child', TestRunner.completeTest.bind(TestRunner));
}
function dumpContainerAndChild() {
ElementsTestRunner.dumpInspectorHighlightJSON('container', dumpChild);
}
dumpContainerAndChild();
})();
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