Commit 4869ebff authored by Hidy Han's avatar Hidy Han Committed by Commit Bot

Support excluding user agent shadow tree when creating a dom snapshot.

Change-Id: Ifee3b9eb5710bb1a873016015563cd33c3d9576e
Reviewed-on: https://chromium-review.googlesource.com/1008734Reviewed-by: default avatarHayato Ito <hayato@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Reviewed-by: default avatarAndrey Kosyakov <caseq@chromium.org>
Commit-Queue: Hidy Han <hidyhan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551053}
parent 931a5833
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
return value; return value;
} }
var response = await dp.DOMSnapshot.getSnapshot({'computedStyleWhitelist': []}); var response = await dp.DOMSnapshot.getSnapshot({'computedStyleWhitelist': [], 'includeUserAgentShadowTree': true});
if (response.error) if (response.error)
testRunner.log(response); testRunner.log(response);
else else
......
Tests DOMSnapshot.getSnapshot method with includeUserAgentShadowTree defaulted to false.
{
"domNodes": [
{
"nodeType": 9,
"nodeName": "#document",
"nodeValue": "",
"backendNodeId": "<number>",
"childNodeIndexes": [
1
],
"layoutNodeIndex": 0,
"documentURL": "<string>",
"baseURL": "<string>",
"documentEncoding": "windows-1252",
"frameId": "<string>"
},
{
"nodeType": 1,
"nodeName": "HTML",
"nodeValue": "",
"backendNodeId": "<number>",
"childNodeIndexes": [
2,
3
],
"layoutNodeIndex": 1,
"frameId": "<string>"
},
{
"nodeType": 1,
"nodeName": "HEAD",
"nodeValue": "",
"backendNodeId": "<number>"
},
{
"nodeType": 1,
"nodeName": "BODY",
"nodeValue": "",
"backendNodeId": "<number>",
"childNodeIndexes": [
4,
5,
8,
9,
11
],
"layoutNodeIndex": 2
},
{
"nodeType": 3,
"nodeName": "#text",
"nodeValue": "\n",
"backendNodeId": "<number>"
},
{
"nodeType": 1,
"nodeName": "DIV",
"nodeValue": "",
"backendNodeId": "<number>",
"childNodeIndexes": [
6,
7
],
"attributes": [
{
"name": "id",
"value": "shadow-host"
}
],
"layoutNodeIndex": 3
},
{
"nodeType": 1,
"nodeName": "TEXTAREA",
"nodeValue": "",
"textValue": "hello hello!",
"backendNodeId": "<number>",
"layoutNodeIndex": 4,
"shadowRootType": "open"
},
{
"nodeType": 1,
"nodeName": "VIDEO",
"nodeValue": "",
"backendNodeId": "<number>",
"attributes": [
{
"name": "src",
"value": "test.webm"
}
],
"layoutNodeIndex": 5,
"shadowRootType": "open"
},
{
"nodeType": 3,
"nodeName": "#text",
"nodeValue": "\n",
"backendNodeId": "<number>"
},
{
"nodeType": 1,
"nodeName": "TEXTAREA",
"nodeValue": "",
"textValue": "This textarea has a child text node!",
"backendNodeId": "<number>",
"childNodeIndexes": [
10
],
"layoutNodeIndex": 6
},
{
"nodeType": 3,
"nodeName": "#text",
"nodeValue": "This textarea has a child text node!",
"backendNodeId": "<number>"
},
{
"nodeType": 3,
"nodeName": "#text",
"nodeValue": "\n\n\n\n",
"backendNodeId": "<number>",
"layoutNodeIndex": 7
}
],
"layoutTreeNodes": "<object>",
"computedStyles": []
}
(async function(testRunner) {
var {page, session, dp} = await testRunner.startURL('../resources/dom-snapshot-ua-shadow-tree.html', 'Tests DOMSnapshot.getSnapshot method with includeUserAgentShadowTree defaulted to false.');
await session.evaluate(`
var shadowroot = document.querySelector('#shadow-host').attachShadow({mode: 'open'});
var textarea = document.createElement('textarea');
textarea.value = 'hello hello!';
var video = document.createElement('video');
video.src = 'test.webm';
shadowroot.appendChild(textarea);
shadowroot.appendChild(video);
`);
function stabilize(key, value) {
var unstableKeys = ['documentURL', 'baseURL', 'frameId', 'backendNodeId', 'layoutTreeNodes'];
if (unstableKeys.indexOf(key) !== -1)
return '<' + typeof(value) + '>';
return value;
}
var response = await dp.DOMSnapshot.getSnapshot({'computedStyleWhitelist': [], 'includeEventListeners': true});
if (response.error)
testRunner.log(response);
else
testRunner.log(JSON.stringify(response.result, stabilize, 2));
testRunner.completeTest();
})
<html>
<body>
<div id="shadow-host"></div>
<textarea>This textarea has a child text node!</textarea>
</div>
</body>
</html>
...@@ -118,6 +118,7 @@ Response InspectorDOMSnapshotAgent::getSnapshot( ...@@ -118,6 +118,7 @@ Response InspectorDOMSnapshotAgent::getSnapshot(
std::unique_ptr<protocol::Array<String>> style_whitelist, std::unique_ptr<protocol::Array<String>> style_whitelist,
protocol::Maybe<bool> include_event_listeners, protocol::Maybe<bool> include_event_listeners,
protocol::Maybe<bool> include_paint_order, protocol::Maybe<bool> include_paint_order,
protocol::Maybe<bool> include_user_agent_shadow_tree,
std::unique_ptr<protocol::Array<protocol::DOMSnapshot::DOMNode>>* dom_nodes, std::unique_ptr<protocol::Array<protocol::DOMSnapshot::DOMNode>>* dom_nodes,
std::unique_ptr<protocol::Array<protocol::DOMSnapshot::LayoutTreeNode>>* std::unique_ptr<protocol::Array<protocol::DOMSnapshot::LayoutTreeNode>>*
layout_tree_nodes, layout_tree_nodes,
...@@ -154,7 +155,8 @@ Response InspectorDOMSnapshotAgent::getSnapshot( ...@@ -154,7 +155,8 @@ Response InspectorDOMSnapshotAgent::getSnapshot(
} }
// Actual traversal. // Actual traversal.
VisitNode(document, include_event_listeners.fromMaybe(false)); VisitNode(document, include_event_listeners.fromMaybe(false),
include_user_agent_shadow_tree.fromMaybe(false));
// Extract results from state and reset. // Extract results from state and reset.
*dom_nodes = std::move(dom_nodes_); *dom_nodes = std::move(dom_nodes_);
...@@ -167,7 +169,8 @@ Response InspectorDOMSnapshotAgent::getSnapshot( ...@@ -167,7 +169,8 @@ Response InspectorDOMSnapshotAgent::getSnapshot(
} }
int InspectorDOMSnapshotAgent::VisitNode(Node* node, int InspectorDOMSnapshotAgent::VisitNode(Node* node,
bool include_event_listeners) { bool include_event_listeners,
bool include_user_agent_shadow_tree) {
// Update layout tree before traversal of document so that we inspect a // Update layout tree before traversal of document so that we inspect a
// current and consistent state of all trees. No need to do this if paint // current and consistent state of all trees. No need to do this if paint
// order was calculated, since layout trees were already updated during // order was calculated, since layout trees were already updated during
...@@ -240,7 +243,8 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node, ...@@ -240,7 +243,8 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node,
value->setFrameId(IdentifiersFactory::FrameId(frame)); value->setFrameId(IdentifiersFactory::FrameId(frame));
} }
if (Document* doc = frame_owner->contentDocument()) { if (Document* doc = frame_owner->contentDocument()) {
value->setContentDocumentIndex(VisitNode(doc, include_event_listeners)); value->setContentDocumentIndex(VisitNode(
doc, include_event_listeners, include_user_agent_shadow_tree));
} }
} }
...@@ -255,13 +259,15 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node, ...@@ -255,13 +259,15 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node,
InspectorDOMAgent::InnerParentNode(link_element->import()) == InspectorDOMAgent::InnerParentNode(link_element->import()) ==
link_element) { link_element) {
value->setImportedDocumentIndex( value->setImportedDocumentIndex(
VisitNode(link_element->import(), include_event_listeners)); VisitNode(link_element->import(), include_event_listeners,
include_user_agent_shadow_tree));
} }
} }
if (auto* template_element = ToHTMLTemplateElementOrNull(*element)) { if (auto* template_element = ToHTMLTemplateElementOrNull(*element)) {
value->setTemplateContentIndex( value->setTemplateContentIndex(VisitNode(template_element->content(),
VisitNode(template_element->content(), include_event_listeners)); include_event_listeners,
include_user_agent_shadow_tree));
} }
if (auto* textarea_element = ToHTMLTextAreaElementOrNull(*element)) if (auto* textarea_element = ToHTMLTextAreaElementOrNull(*element))
...@@ -285,8 +291,8 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node, ...@@ -285,8 +291,8 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node,
value->setPseudoType(pseudo_type); value->setPseudoType(pseudo_type);
} }
} else { } else {
value->setPseudoElementIndexes( value->setPseudoElementIndexes(VisitPseudoElements(
VisitPseudoElements(element, include_event_listeners)); element, include_event_listeners, include_user_agent_shadow_tree));
} }
HTMLImageElement* image_element = ToHTMLImageElementOrNull(node); HTMLImageElement* image_element = ToHTMLImageElementOrNull(node);
...@@ -312,33 +318,76 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node, ...@@ -312,33 +318,76 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node,
} }
if (node->IsContainerNode()) { if (node->IsContainerNode()) {
value->setChildNodeIndexes( value->setChildNodeIndexes(VisitContainerChildren(
VisitContainerChildren(node, include_event_listeners)); node, include_event_listeners, include_user_agent_shadow_tree));
} }
return index; return index;
} }
Node* InspectorDOMSnapshotAgent::FirstChild(
const Node& node,
bool include_user_agent_shadow_tree) {
DCHECK(include_user_agent_shadow_tree || !node.IsInUserAgentShadowRoot());
if (!include_user_agent_shadow_tree) {
ShadowRoot* shadow_root = node.GetShadowRoot();
if (shadow_root && shadow_root->GetType() == ShadowRootType::kUserAgent) {
Node* child = node.firstChild();
while (child && !child->CanParticipateInFlatTree())
child = child->nextSibling();
return child;
}
}
return FlatTreeTraversal::FirstChild(node);
}
bool InspectorDOMSnapshotAgent::HasChildren(
const Node& node,
bool include_user_agent_shadow_tree) {
return FirstChild(node, include_user_agent_shadow_tree);
}
Node* InspectorDOMSnapshotAgent::NextSibling(
const Node& node,
bool include_user_agent_shadow_tree) {
DCHECK(include_user_agent_shadow_tree || !node.IsInUserAgentShadowRoot());
if (!include_user_agent_shadow_tree) {
if (node.ParentElementShadowRoot() &&
node.ParentElementShadowRoot()->GetType() ==
ShadowRootType::kUserAgent) {
Node* sibling = node.nextSibling();
while (sibling && !sibling->CanParticipateInFlatTree())
sibling = sibling->nextSibling();
return sibling;
}
}
return FlatTreeTraversal::NextSibling(node);
}
std::unique_ptr<protocol::Array<int>> std::unique_ptr<protocol::Array<int>>
InspectorDOMSnapshotAgent::VisitContainerChildren( InspectorDOMSnapshotAgent::VisitContainerChildren(
Node* container, Node* container,
bool include_event_listeners) { bool include_event_listeners,
bool include_user_agent_shadow_tree) {
auto children = protocol::Array<int>::create(); auto children = protocol::Array<int>::create();
if (!FlatTreeTraversal::HasChildren(*container)) if (!HasChildren(*container, include_user_agent_shadow_tree))
return nullptr; return nullptr;
Node* child = FlatTreeTraversal::FirstChild(*container); Node* child = FirstChild(*container, include_user_agent_shadow_tree);
while (child) { while (child) {
children->addItem(VisitNode(child, include_event_listeners)); children->addItem(VisitNode(child, include_event_listeners,
child = FlatTreeTraversal::NextSibling(*child); include_user_agent_shadow_tree));
child = NextSibling(*child, include_user_agent_shadow_tree);
} }
return children; return children;
} }
std::unique_ptr<protocol::Array<int>> std::unique_ptr<protocol::Array<int>>
InspectorDOMSnapshotAgent::VisitPseudoElements(Element* parent, InspectorDOMSnapshotAgent::VisitPseudoElements(
bool include_event_listeners) { Element* parent,
bool include_event_listeners,
bool include_user_agent_shadow_tree) {
if (!parent->GetPseudoElement(kPseudoIdBefore) && if (!parent->GetPseudoElement(kPseudoIdBefore) &&
!parent->GetPseudoElement(kPseudoIdAfter)) { !parent->GetPseudoElement(kPseudoIdAfter)) {
return nullptr; return nullptr;
...@@ -347,12 +396,14 @@ InspectorDOMSnapshotAgent::VisitPseudoElements(Element* parent, ...@@ -347,12 +396,14 @@ InspectorDOMSnapshotAgent::VisitPseudoElements(Element* parent,
auto pseudo_elements = protocol::Array<int>::create(); auto pseudo_elements = protocol::Array<int>::create();
if (parent->GetPseudoElement(kPseudoIdBefore)) { if (parent->GetPseudoElement(kPseudoIdBefore)) {
pseudo_elements->addItem(VisitNode( pseudo_elements->addItem(
parent->GetPseudoElement(kPseudoIdBefore), include_event_listeners)); VisitNode(parent->GetPseudoElement(kPseudoIdBefore),
include_event_listeners, include_user_agent_shadow_tree));
} }
if (parent->GetPseudoElement(kPseudoIdAfter)) { if (parent->GetPseudoElement(kPseudoIdAfter)) {
pseudo_elements->addItem(VisitNode(parent->GetPseudoElement(kPseudoIdAfter), pseudo_elements->addItem(VisitNode(parent->GetPseudoElement(kPseudoIdAfter),
include_event_listeners)); include_event_listeners,
include_user_agent_shadow_tree));
} }
return pseudo_elements; return pseudo_elements;
......
...@@ -36,6 +36,7 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final ...@@ -36,6 +36,7 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
std::unique_ptr<protocol::Array<String>> style_whitelist, std::unique_ptr<protocol::Array<String>> style_whitelist,
protocol::Maybe<bool> include_event_listeners, protocol::Maybe<bool> include_event_listeners,
protocol::Maybe<bool> include_paint_order, protocol::Maybe<bool> include_paint_order,
protocol::Maybe<bool> include_user_agent_shadow_tree,
std::unique_ptr<protocol::Array<protocol::DOMSnapshot::DOMNode>>* std::unique_ptr<protocol::Array<protocol::DOMSnapshot::DOMNode>>*
dom_nodes, dom_nodes,
std::unique_ptr<protocol::Array<protocol::DOMSnapshot::LayoutTreeNode>>* std::unique_ptr<protocol::Array<protocol::DOMSnapshot::LayoutTreeNode>>*
...@@ -47,13 +48,26 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final ...@@ -47,13 +48,26 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
InspectorDOMSnapshotAgent(InspectedFrames*, InspectorDOMDebuggerAgent*); InspectorDOMSnapshotAgent(InspectedFrames*, InspectorDOMDebuggerAgent*);
// Adds a DOMNode for the given Node to |dom_nodes_| and returns its index. // Adds a DOMNode for the given Node to |dom_nodes_| and returns its index.
int VisitNode(Node*, bool include_event_listeners); int VisitNode(Node*,
bool include_event_listeners,
bool include_user_agent_shadow_tree);
// Helpers for VisitContainerChildren.
static Node* FirstChild(const Node& node,
bool include_user_agent_shadow_tree);
static bool HasChildren(const Node& node,
bool include_user_agent_shadow_tree);
static Node* NextSibling(const Node& node,
bool include_user_agent_shadow_tree);
std::unique_ptr<protocol::Array<int>> VisitContainerChildren( std::unique_ptr<protocol::Array<int>> VisitContainerChildren(
Node* container, Node* container,
bool include_event_listeners); bool include_event_listeners,
bool include_user_agent_shadow_tree);
std::unique_ptr<protocol::Array<int>> VisitPseudoElements( std::unique_ptr<protocol::Array<int>> VisitPseudoElements(
Element* parent, Element* parent,
bool include_event_listeners); bool include_event_listeners,
bool include_user_agent_shadow_tree);
std::unique_ptr<protocol::Array<protocol::DOMSnapshot::NameValue>> std::unique_ptr<protocol::Array<protocol::DOMSnapshot::NameValue>>
BuildArrayForElementAttributes(Element*); BuildArrayForElementAttributes(Element*);
......
...@@ -4563,6 +4563,12 @@ ...@@ -4563,6 +4563,12 @@
"description": "Whether to determine and include the paint order index of LayoutTreeNodes (default false).", "description": "Whether to determine and include the paint order index of LayoutTreeNodes (default false).",
"optional": true, "optional": true,
"type": "boolean" "type": "boolean"
},
{
"name": "includeUserAgentShadowTree",
"description": "Whether to include UA shadow tree in the snapshot (default false).",
"optional": true,
"type": "boolean"
} }
], ],
"returns": [ "returns": [
......
...@@ -2086,6 +2086,8 @@ experimental domain DOMSnapshot ...@@ -2086,6 +2086,8 @@ experimental domain DOMSnapshot
optional boolean includeEventListeners optional boolean includeEventListeners
# Whether to determine and include the paint order index of LayoutTreeNodes (default false). # Whether to determine and include the paint order index of LayoutTreeNodes (default false).
optional boolean includePaintOrder optional boolean includePaintOrder
# Whether to include UA shadow tree in the snapshot (default false).
optional boolean includeUserAgentShadowTree
returns returns
# The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document. # The nodes in the DOM tree. The DOMNode at index 0 corresponds to the root document.
array of DOMNode domNodes array of DOMNode domNodes
......
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