Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp

Issue 2346853002: Add a DOM.getLayoutTreeNodes devtools command (Closed)
Patch Set: Make it work with iframes Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Copyright (C) 2009 Joseph Pecoraro 4 * Copyright (C) 2009 Joseph Pecoraro
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 9 *
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 #include "core/html/imports/HTMLImportChild.h" 60 #include "core/html/imports/HTMLImportChild.h"
61 #include "core/html/imports/HTMLImportLoader.h" 61 #include "core/html/imports/HTMLImportLoader.h"
62 #include "core/inspector/DOMEditor.h" 62 #include "core/inspector/DOMEditor.h"
63 #include "core/inspector/DOMPatchSupport.h" 63 #include "core/inspector/DOMPatchSupport.h"
64 #include "core/inspector/IdentifiersFactory.h" 64 #include "core/inspector/IdentifiersFactory.h"
65 #include "core/inspector/InspectedFrames.h" 65 #include "core/inspector/InspectedFrames.h"
66 #include "core/inspector/InspectorHighlight.h" 66 #include "core/inspector/InspectorHighlight.h"
67 #include "core/inspector/InspectorHistory.h" 67 #include "core/inspector/InspectorHistory.h"
68 #include "core/inspector/V8InspectorString.h" 68 #include "core/inspector/V8InspectorString.h"
69 #include "core/layout/HitTestResult.h" 69 #include "core/layout/HitTestResult.h"
70 #include "core/layout/LayoutInline.h"
70 #include "core/layout/api/LayoutViewItem.h" 71 #include "core/layout/api/LayoutViewItem.h"
72 #include "core/layout/line/InlineTextBox.h"
71 #include "core/loader/DocumentLoader.h" 73 #include "core/loader/DocumentLoader.h"
72 #include "core/page/FrameTree.h" 74 #include "core/page/FrameTree.h"
73 #include "core/page/Page.h" 75 #include "core/page/Page.h"
74 #include "core/xml/DocumentXPathEvaluator.h" 76 #include "core/xml/DocumentXPathEvaluator.h"
75 #include "core/xml/XPathResult.h" 77 #include "core/xml/XPathResult.h"
76 #include "platform/PlatformGestureEvent.h" 78 #include "platform/PlatformGestureEvent.h"
77 #include "platform/PlatformMouseEvent.h" 79 #include "platform/PlatformMouseEvent.h"
78 #include "platform/PlatformTouchEvent.h" 80 #include "platform/PlatformTouchEvent.h"
79 #include "wtf/ListHashSet.h" 81 #include "wtf/ListHashSet.h"
80 #include "wtf/PtrUtil.h" 82 #include "wtf/PtrUtil.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 } 131 }
130 132
131 v8::Local<v8::Value> nodeV8Value(v8::Local<v8::Context> context, Node* node) 133 v8::Local<v8::Value> nodeV8Value(v8::Local<v8::Context> context, Node* node)
132 { 134 {
133 v8::Isolate* isolate = context->GetIsolate(); 135 v8::Isolate* isolate = context->GetIsolate();
134 if (!node || !BindingSecurity::shouldAllowAccessTo(currentDOMWindow(isolate) , node, BindingSecurity::ErrorReportOption::DoNotReport)) 136 if (!node || !BindingSecurity::shouldAllowAccessTo(currentDOMWindow(isolate) , node, BindingSecurity::ErrorReportOption::DoNotReport))
135 return v8::Null(isolate); 137 return v8::Null(isolate);
136 return toV8(node, context->Global(), isolate); 138 return toV8(node, context->Global(), isolate);
137 } 139 }
138 140
141 std::unique_ptr<protocol::DOM::Rect> buildRectForFloatRect(const FloatRect& rect )
142 {
143 return protocol::DOM::Rect::create()
144 .setX(rect.x())
145 .setY(rect.y())
146 .setWidth(rect.width())
147 .setHeight(rect.height())
148 .build();
149 }
150
151 FloatRect buildAbsoluteBoundingBox(LayoutObject* layoutObject)
esprehn 2016/09/28 04:02:49 I think you want to use boundsInViewport() from th
alex clarke (OOO till 29th) 2016/09/28 17:15:20 Done.
152 {
153 if (layoutObject->isText()) {
154 FloatRect localRect(toLayoutText(layoutObject)->linesBoundingBox());
155 return layoutObject->localToAbsoluteQuad(localRect).boundingBox();
156 }
157 if (layoutObject->isLayoutInline()) {
158 FloatRect localRect(toLayoutInline(layoutObject)->linesBoundingBox());
159 return layoutObject->localToAbsoluteQuad(localRect).boundingBox();
160 }
161 if (layoutObject->isBox()) {
162 FloatRect localRect(toLayoutBox(layoutObject)->borderBoxRect());
163 return layoutObject->localToAbsoluteQuad(localRect).boundingBox();
164 }
165 return layoutObject->absoluteBoundingBoxRect();
166 }
167
139 } // namespace 168 } // namespace
140 169
170
141 class InspectorRevalidateDOMTask final : public GarbageCollectedFinalized<Inspec torRevalidateDOMTask> { 171 class InspectorRevalidateDOMTask final : public GarbageCollectedFinalized<Inspec torRevalidateDOMTask> {
142 public: 172 public:
143 explicit InspectorRevalidateDOMTask(InspectorDOMAgent*); 173 explicit InspectorRevalidateDOMTask(InspectorDOMAgent*);
144 void scheduleStyleAttrRevalidationFor(Element*); 174 void scheduleStyleAttrRevalidationFor(Element*);
145 void reset() { m_timer.stop(); } 175 void reset() { m_timer.stop(); }
146 void onTimer(TimerBase*); 176 void onTimer(TimerBase*);
147 DECLARE_TRACE(); 177 DECLARE_TRACE();
148 178
149 private: 179 private:
150 Member<InspectorDOMAgent> m_domAgent; 180 Member<InspectorDOMAgent> m_domAgent;
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 if (!m_document) { 552 if (!m_document) {
523 *errorString = "Document is not available"; 553 *errorString = "Document is not available";
524 return; 554 return;
525 } 555 }
526 556
527 discardFrontendBindings(); 557 discardFrontendBindings();
528 558
529 *root = buildObjectForNode(m_document.get(), 2, m_documentNodeToIdMap.get()) ; 559 *root = buildObjectForNode(m_document.get(), 2, m_documentNodeToIdMap.get()) ;
530 } 560 }
531 561
562 void InspectorDOMAgent::getLayoutTreeNodes(ErrorString* errorString, std::unique _ptr<protocol::Array<protocol::DOM::LayoutTreeNode>>* layoutTreeNodes)
563 {
564 layoutTreeNodes->reset(new protocol::Array<protocol::DOM::LayoutTreeNode>);
565
566 std::vector<Node*> unvisited; // Neither WTF::Vector or HeapVector allow Nod e* :(
esprehn 2016/09/28 04:02:49 HeapVector<Member<Node>>, you probably want a big
alex clarke (OOO till 29th) 2016/09/28 17:15:20 Done.
567 unvisited.push_back(m_document.get());
568
569 while (!unvisited.empty()) {
esprehn 2016/09/28 04:02:49 this is very strange to put everything into a vect
alex clarke (OOO till 29th) 2016/09/28 17:15:20 Done.
570 Node* node = unvisited.back();
571 unvisited.pop_back();
572
573 // Visit shadow dom nodes.
574 if (node->isElementNode()) {
575 const Element* element = toElement(node);
576 ElementShadow* elementShadow = element->shadow();
577 if (elementShadow)
578 unvisited.push_back(&elementShadow->youngestShadowRoot());
579 }
580
581 // Pierce iframe boundaries.
582 if (node->isFrameOwnerElement()) {
583 unvisited.push_back(toHTMLFrameOwnerElement(node)->contentDocument() ->documentElement());
584 }
585
586 for (Node* child = innerFirstChild(node); child; child = innerNextSiblin g(child)) {
587 unvisited.push_back(child);
588 }
589
590 LayoutObject* layoutObject = node->layoutObject();
591 if (!layoutObject)
592 continue;
593
594 int backendNodeId = DOMNodeIds::idForNode(node);
595 std::unique_ptr<protocol::DOM::LayoutTreeNode> layoutTreeNode =
596 protocol::DOM::LayoutTreeNode::create()
597 .setBackendNodeId(backendNodeId)
598 .setBoundingBox(buildRectForFloatRect(buildAbsoluteBoundingBox(l ayoutObject)))
599 .build();
600
601 if (layoutObject->isText()) {
602 LayoutText* layoutText = toLayoutText(layoutObject);
603 layoutTreeNode->setLayoutText(layoutText->text());
604 if (layoutText->hasTextBoxes()) {
605 std::unique_ptr<protocol::Array<protocol::DOM::InlineTextBox>> i nlineTextNodes(new protocol::Array<protocol::DOM::InlineTextBox>());
606 for (const InlineTextBox* itb = layoutText->firstTextBox(); itb; itb = itb->nextTextBox()) {
esprehn 2016/09/28 04:02:49 box or textBox
alex clarke (OOO till 29th) 2016/09/28 17:15:20 Done.
607 FloatRect localItbRect(itb->calculateBoundaries());
608 FloatRect absoluteItbRect = layoutObject->localToAbsoluteQua d(localItbRect).boundingBox();
esprehn 2016/09/28 04:02:49 what is Itb? Don't abbreciate in blink
alex clarke (OOO till 29th) 2016/09/28 17:15:20 Done.
609 inlineTextNodes->addItem(
610 protocol::DOM::InlineTextBox::create()
611 .setText(layoutText->text().substring(itb->start(), itb->len()).utf8().data())
esprehn 2016/09/28 04:02:49 this is allocating tons of strings and will be slo
alex clarke (OOO till 29th) 2016/09/28 17:15:20 We don't really need the substring, the offset and
612 .setBoundingBox(buildRectForFloatRect(absoluteItbRec t))
613 .build());
614 }
615 layoutTreeNode->setInlineTextNodes(std::move(inlineTextNodes));
616 }
617 }
618
619 (*layoutTreeNodes)->addItem(std::move(layoutTreeNode));
620 }
621 }
622
532 void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth) 623 void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth)
533 { 624 {
534 Node* node = nodeForId(nodeId); 625 Node* node = nodeForId(nodeId);
535 if (!node || (!node->isElementNode() && !node->isDocumentNode() && !node->is DocumentFragment())) 626 if (!node || (!node->isElementNode() && !node->isDocumentNode() && !node->is DocumentFragment()))
536 return; 627 return;
537 628
538 NodeToIdMap* nodeMap = m_idToNodesMap.get(nodeId); 629 NodeToIdMap* nodeMap = m_idToNodesMap.get(nodeId);
539 630
540 if (m_childrenRequested.contains(nodeId)) { 631 if (m_childrenRequested.contains(nodeId)) {
541 if (depth <= 1) 632 if (depth <= 1)
(...skipping 1587 matching lines...) Expand 10 before | Expand all | Expand 10 after
2129 visitor->trace(m_idToNodesMap); 2220 visitor->trace(m_idToNodesMap);
2130 visitor->trace(m_document); 2221 visitor->trace(m_document);
2131 visitor->trace(m_revalidateTask); 2222 visitor->trace(m_revalidateTask);
2132 visitor->trace(m_searchResults); 2223 visitor->trace(m_searchResults);
2133 visitor->trace(m_history); 2224 visitor->trace(m_history);
2134 visitor->trace(m_domEditor); 2225 visitor->trace(m_domEditor);
2135 InspectorBaseAgent::trace(visitor); 2226 InspectorBaseAgent::trace(visitor);
2136 } 2227 }
2137 2228
2138 } // namespace blink 2229 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698