Commit 5d810b9f authored by Hidy Han's avatar Hidy Han Committed by Commit Bot

Reland "InspectorDOMSnapshotAgent: expose and book layout nodes owned by...

Reland "InspectorDOMSnapshotAgent: expose and book layout nodes owned by pseudo elements under their owners."

This is a reland of 513a9fad

Original change's description:
> InspectorDOMSnapshotAgent: expose and book layout nodes owned by pseudo elements under their owners.
> 
> Currently, only support before, after and first letter pseudo types.
> 
> Change-Id: Ifb10fecad1dbfb6b987eaa0bd0e7ccb4a222d13f
> Reviewed-on: https://chromium-review.googlesource.com/1125511
> Commit-Queue: Hidy Han <hidyhan@chromium.org>
> Reviewed-by: Pavel Feldman <pfeldman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#575785}

Change-Id: I2117929001edc511d11f2d5386e90327ff1a666d
Reviewed-on: https://chromium-review.googlesource.com/1157305Reviewed-by: default avatarPavel Feldman <pfeldman@chromium.org>
Commit-Queue: Hidy Han <hidyhan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580369}
parent c4e85662
(async function(testRunner) {
var {page, session, dp} = await testRunner.startURL('../resources/dom-snapshot-pseudo-element.html', 'Tests DOMSnapshot.getSnapshot exports layout tree nodes associated with pseudo elements.');
function stabilize(key, value) {
var unstableKeys = ['documentURL', 'baseURL', 'frameId', 'backendNodeId'];
if (unstableKeys.indexOf(key) !== -1)
return '<' + typeof(value) + '>';
return value;
}
var response = await dp.DOMSnapshot.getSnapshot({'computedStyleWhitelist': ['font-weight', 'color'], 'includeEventListeners': true});
if (response.error)
testRunner.log(response);
else
testRunner.log(JSON.stringify(response.result, stabilize, 2));
testRunner.completeTest();
})
<html>
<style>
p {
position: absolute;
height: 200px;
width: 200px;
font: 10px Ahem;
}
.c1::first-letter { font-weight: lighter; color: green; }
.c2::first-letter { font-weight: bold; color: blue; }
.c2::before { counter-increment: square; content: 'square: ' counter(square) url(square.png) '! '; }
</style>
<script src="../../resources/ahem.js"></script>
<body>
<p class='c1'>I have a first letter.</p>
<p class='c1'><span>I have a first letter because of my parent.</span></p>
<p class='c2'>I have some content before me with a first letter.</p>
</body>
</html>
...@@ -361,7 +361,8 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node, ...@@ -361,7 +361,8 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node,
int index = dom_nodes_->length(); int index = dom_nodes_->length();
dom_nodes_->addItem(std::move(owned_value)); dom_nodes_->addItem(std::move(owned_value));
int layoutNodeIndex = VisitLayoutTreeNode(node, index); int layoutNodeIndex =
VisitLayoutTreeNode(node->GetLayoutObject(), node, index);
if (layoutNodeIndex != -1) if (layoutNodeIndex != -1)
value->setLayoutNodeIndex(layoutNodeIndex); value->setLayoutNodeIndex(layoutNodeIndex);
...@@ -430,10 +431,13 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node, ...@@ -430,10 +431,13 @@ int InspectorDOMSnapshotAgent::VisitNode(Node* node,
if (InspectorDOMAgent::GetPseudoElementType(element->GetPseudoId(), if (InspectorDOMAgent::GetPseudoElementType(element->GetPseudoId(),
&pseudo_type)) { &pseudo_type)) {
value->setPseudoType(pseudo_type); value->setPseudoType(pseudo_type);
if (node->GetLayoutObject())
VisitPseudoLayoutChildren(node, index);
} }
} else { } else {
value->setPseudoElementIndexes(VisitPseudoElements( value->setPseudoElementIndexes(
element, include_event_listeners, include_user_agent_shadow_tree)); VisitPseudoElements(element, index, include_event_listeners,
include_user_agent_shadow_tree));
} }
HTMLImageElement* image_element = ToHTMLImageElementOrNull(node); HTMLImageElement* image_element = ToHTMLImageElementOrNull(node);
...@@ -586,7 +590,7 @@ int InspectorDOMSnapshotAgent::VisitNode2(Node* node, int parent_index) { ...@@ -586,7 +590,7 @@ int InspectorDOMSnapshotAgent::VisitNode2(Node* node, int parent_index) {
nodes->getNodeValue(nullptr)->addItem(AddString(node_value)); nodes->getNodeValue(nullptr)->addItem(AddString(node_value));
nodes->getBackendNodeId(nullptr)->addItem(backend_node_id); nodes->getBackendNodeId(nullptr)->addItem(backend_node_id);
nodes->getAttributes(nullptr)->addItem(BuildArrayForElementAttributes2(node)); nodes->getAttributes(nullptr)->addItem(BuildArrayForElementAttributes2(node));
BuildLayoutTreeNode(node, index); BuildLayoutTreeNode(node->GetLayoutObject(), node, index);
if (origin_url_map_ && origin_url_map_->Contains(backend_node_id)) { if (origin_url_map_ && origin_url_map_->Contains(backend_node_id)) {
String origin_url = origin_url_map_->at(backend_node_id); String origin_url = origin_url_map_->at(backend_node_id);
...@@ -636,6 +640,8 @@ int InspectorDOMSnapshotAgent::VisitNode2(Node* node, int parent_index) { ...@@ -636,6 +640,8 @@ int InspectorDOMSnapshotAgent::VisitNode2(Node* node, int parent_index) {
if (InspectorDOMAgent::GetPseudoElementType(element->GetPseudoId(), if (InspectorDOMAgent::GetPseudoElementType(element->GetPseudoId(),
&pseudo_type)) { &pseudo_type)) {
SetRare(nodes->getPseudoType(nullptr), index, pseudo_type); SetRare(nodes->getPseudoType(nullptr), index, pseudo_type);
if (node->GetLayoutObject())
VisitPseudoLayoutChildren2(node, index);
} }
} else { } else {
VisitPseudoElements2(element, index); VisitPseudoElements2(element, index);
...@@ -722,45 +728,54 @@ void InspectorDOMSnapshotAgent::VisitContainerChildren2(Node* container, ...@@ -722,45 +728,54 @@ void InspectorDOMSnapshotAgent::VisitContainerChildren2(Node* container,
} }
} }
void InspectorDOMSnapshotAgent::VisitPseudoLayoutChildren(Node* pseudo_node,
int index) {
for (LayoutObject* child = pseudo_node->GetLayoutObject()->SlowFirstChild();
child; child = child->NextSibling()) {
if (child->IsAnonymous())
VisitLayoutTreeNode(child, pseudo_node, index);
}
}
void InspectorDOMSnapshotAgent::VisitPseudoLayoutChildren2(Node* pseudo_node,
int index) {
for (LayoutObject* child = pseudo_node->GetLayoutObject()->SlowFirstChild();
child; child = child->NextSibling()) {
if (child->IsAnonymous())
BuildLayoutTreeNode(child, pseudo_node, index);
}
}
std::unique_ptr<protocol::Array<int>> std::unique_ptr<protocol::Array<int>>
InspectorDOMSnapshotAgent::VisitPseudoElements( InspectorDOMSnapshotAgent::VisitPseudoElements(
Element* parent, Element* parent,
int index,
bool include_event_listeners, bool include_event_listeners,
bool include_user_agent_shadow_tree) { bool include_user_agent_shadow_tree) {
if (!parent->GetPseudoElement(kPseudoIdBefore) && if (!parent->GetPseudoElement(kPseudoIdFirstLetter) &&
!parent->GetPseudoElement(kPseudoIdBefore) &&
!parent->GetPseudoElement(kPseudoIdAfter)) { !parent->GetPseudoElement(kPseudoIdAfter)) {
return nullptr; return nullptr;
} }
auto pseudo_elements = protocol::Array<int>::create(); auto pseudo_elements = protocol::Array<int>::create();
for (PseudoId pseudo_id :
if (parent->GetPseudoElement(kPseudoIdBefore)) { {kPseudoIdFirstLetter, kPseudoIdBefore, kPseudoIdAfter}) {
pseudo_elements->addItem( if (Node* pseudo_node = parent->GetPseudoElement(pseudo_id)) {
VisitNode(parent->GetPseudoElement(kPseudoIdBefore), pseudo_elements->addItem(VisitNode(pseudo_node, include_event_listeners,
include_event_listeners, include_user_agent_shadow_tree)); include_user_agent_shadow_tree));
} }
if (parent->GetPseudoElement(kPseudoIdAfter)) {
pseudo_elements->addItem(VisitNode(parent->GetPseudoElement(kPseudoIdAfter),
include_event_listeners,
include_user_agent_shadow_tree));
} }
return pseudo_elements; return pseudo_elements;
} }
void InspectorDOMSnapshotAgent::VisitPseudoElements2(Element* parent, void InspectorDOMSnapshotAgent::VisitPseudoElements2(Element* parent,
int parent_index) { int parent_index) {
if (!parent->GetPseudoElement(kPseudoIdBefore) && for (PseudoId pseudo_id :
!parent->GetPseudoElement(kPseudoIdAfter)) { {kPseudoIdFirstLetter, kPseudoIdBefore, kPseudoIdAfter}) {
return; if (Node* pseudo_node = parent->GetPseudoElement(pseudo_id))
VisitNode2(pseudo_node, parent_index);
} }
auto pseudo_elements = protocol::Array<int>::create();
if (parent->GetPseudoElement(kPseudoIdBefore))
VisitNode2(parent->GetPseudoElement(kPseudoIdBefore), parent_index);
if (parent->GetPseudoElement(kPseudoIdAfter))
VisitNode2(parent->GetPseudoElement(kPseudoIdAfter), parent_index);
} }
std::unique_ptr<protocol::Array<protocol::DOMSnapshot::NameValue>> std::unique_ptr<protocol::Array<protocol::DOMSnapshot::NameValue>>
...@@ -792,8 +807,9 @@ InspectorDOMSnapshotAgent::BuildArrayForElementAttributes2(Node* node) { ...@@ -792,8 +807,9 @@ InspectorDOMSnapshotAgent::BuildArrayForElementAttributes2(Node* node) {
return result; return result;
} }
int InspectorDOMSnapshotAgent::VisitLayoutTreeNode(Node* node, int node_index) { int InspectorDOMSnapshotAgent::VisitLayoutTreeNode(LayoutObject* layout_object,
LayoutObject* layout_object = node->GetLayoutObject(); Node* node,
int node_index) {
if (!layout_object) if (!layout_object)
return -1; return -1;
...@@ -846,8 +862,9 @@ int InspectorDOMSnapshotAgent::VisitLayoutTreeNode(Node* node, int node_index) { ...@@ -846,8 +862,9 @@ int InspectorDOMSnapshotAgent::VisitLayoutTreeNode(Node* node, int node_index) {
return index; return index;
} }
int InspectorDOMSnapshotAgent::BuildLayoutTreeNode(Node* node, int node_index) { int InspectorDOMSnapshotAgent::BuildLayoutTreeNode(LayoutObject* layout_object,
LayoutObject* layout_object = node->GetLayoutObject(); Node* node,
int node_index) {
if (!layout_object) if (!layout_object)
return -1; return -1;
auto* layout_tree_snapshot = document_->getLayout(); auto* layout_tree_snapshot = document_->getLayout();
......
...@@ -93,8 +93,14 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final ...@@ -93,8 +93,14 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
bool include_event_listeners, bool include_event_listeners,
bool include_user_agent_shadow_tree); bool include_user_agent_shadow_tree);
void VisitContainerChildren2(Node* container, int parent_index); void VisitContainerChildren2(Node* container, int parent_index);
// Collect LayoutTreeNodes owned by a pseudo element.
void VisitPseudoLayoutChildren(Node* pseudo_node, int index);
void VisitPseudoLayoutChildren2(Node* pseudo_node, int index);
std::unique_ptr<protocol::Array<int>> VisitPseudoElements( std::unique_ptr<protocol::Array<int>> VisitPseudoElements(
Element* parent, Element* parent,
int index,
bool include_event_listeners, bool include_event_listeners,
bool include_user_agent_shadow_tree); bool include_user_agent_shadow_tree);
void VisitPseudoElements2(Element* parent, int parent_index); void VisitPseudoElements2(Element* parent, int parent_index);
...@@ -102,11 +108,11 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final ...@@ -102,11 +108,11 @@ class CORE_EXPORT InspectorDOMSnapshotAgent final
BuildArrayForElementAttributes(Element*); BuildArrayForElementAttributes(Element*);
std::unique_ptr<protocol::Array<int>> BuildArrayForElementAttributes2(Node*); std::unique_ptr<protocol::Array<int>> BuildArrayForElementAttributes2(Node*);
// Adds a LayoutTreeNode for the LayoutObject of the given Node to // Adds a LayoutTreeNode for the LayoutObject to |layout_tree_nodes_| and
// |layout_tree_nodes_| and returns its index. Returns -1 if the Node has no // returns its index. Returns -1 if the Node has no associated LayoutObject.
// associated LayoutObject. // Associates LayoutObjects under a pseudo element with the element.
int VisitLayoutTreeNode(Node*, int node_index); int VisitLayoutTreeNode(LayoutObject*, Node*, int node_index);
int BuildLayoutTreeNode(Node*, int node_index); int BuildLayoutTreeNode(LayoutObject*, Node*, int node_index);
// Returns the index of the ComputedStyle in |computed_styles_| for the given // Returns the index of the ComputedStyle in |computed_styles_| for the given
// Node. Adds a new ComputedStyle if necessary, but ensures no duplicates are // Node. Adds a new ComputedStyle if necessary, but ensures no duplicates are
......
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