| Index: third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
|
| diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
|
| index 0f5b4712fe0ab5954057bacea35eee015f31bd09..e55ae0c3ff4aef2a96c635db3a1ff1ac1476181f 100644
|
| --- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
|
| +++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
|
| @@ -66,7 +66,9 @@
|
| #include "core/inspector/InspectorHistory.h"
|
| #include "core/inspector/V8InspectorString.h"
|
| #include "core/layout/HitTestResult.h"
|
| +#include "core/layout/LayoutInline.h"
|
| #include "core/layout/api/LayoutViewItem.h"
|
| +#include "core/layout/line/InlineTextBox.h"
|
| #include "core/loader/DocumentLoader.h"
|
| #include "core/page/FrameTree.h"
|
| #include "core/page/Page.h"
|
| @@ -135,8 +137,36 @@ v8::Local<v8::Value> nodeV8Value(v8::Local<v8::Context> context, Node* node)
|
| return toV8(node, context->Global(), isolate);
|
| }
|
|
|
| +std::unique_ptr<protocol::DOM::Rect> buildRectForFloatRect(const FloatRect& rect)
|
| +{
|
| + return protocol::DOM::Rect::create()
|
| + .setX(rect.x())
|
| + .setY(rect.y())
|
| + .setWidth(rect.width())
|
| + .setHeight(rect.height())
|
| + .build();
|
| +}
|
| +
|
| +FloatRect buildAbsoluteBoundingBox(LayoutObject* layoutObject)
|
| +{
|
| + if (layoutObject->isText()) {
|
| + FloatRect localRect(toLayoutText(layoutObject)->linesBoundingBox());
|
| + return layoutObject->localToAbsoluteQuad(localRect).boundingBox();
|
| + }
|
| + if (layoutObject->isLayoutInline()) {
|
| + FloatRect localRect(toLayoutInline(layoutObject)->linesBoundingBox());
|
| + return layoutObject->localToAbsoluteQuad(localRect).boundingBox();
|
| + }
|
| + if (layoutObject->isBox()) {
|
| + FloatRect localRect(toLayoutBox(layoutObject)->borderBoxRect());
|
| + return layoutObject->localToAbsoluteQuad(localRect).boundingBox();
|
| + }
|
| + return layoutObject->absoluteBoundingBoxRect();
|
| +}
|
| +
|
| } // namespace
|
|
|
| +
|
| class InspectorRevalidateDOMTask final : public GarbageCollectedFinalized<InspectorRevalidateDOMTask> {
|
| public:
|
| explicit InspectorRevalidateDOMTask(InspectorDOMAgent*);
|
| @@ -528,6 +558,60 @@ void InspectorDOMAgent::getDocument(ErrorString* errorString, std::unique_ptr<pr
|
| *root = buildObjectForNode(m_document.get(), 2, m_documentNodeToIdMap.get());
|
| }
|
|
|
| +void InspectorDOMAgent::getRenderTreeNodes(ErrorString* errorString, std::unique_ptr<protocol::Array<protocol::DOM::RenderTreeNode>>* renderTreeNodes)
|
| +{
|
| + renderTreeNodes->reset(new protocol::Array<protocol::DOM::RenderTreeNode>);
|
| +
|
| + std::vector<Node*> unvisited; // Neither WTF::Vector or HeapVector allow Node* :(
|
| + unvisited.push_back(m_document.get());
|
| +
|
| + while (!unvisited.empty()) {
|
| + Node* node = unvisited.back();
|
| + unvisited.pop_back();
|
| +
|
| + if (node->isElementNode()) {
|
| + const Element* element = toElement(node);
|
| + ElementShadow* elementShadow = element->shadow();
|
| + if (elementShadow)
|
| + unvisited.push_back(&elementShadow->youngestShadowRoot());
|
| + }
|
| + for (Node* child = innerFirstChild(node); child; child = innerNextSibling(child)) {
|
| + unvisited.push_back(child);
|
| + }
|
| +
|
| + LayoutObject* layoutObject = node->layoutObject();
|
| + if (!layoutObject)
|
| + continue;
|
| +
|
| + int backendNodeId = DOMNodeIds::idForNode(node);
|
| + std::unique_ptr<protocol::DOM::RenderTreeNode> renderTreeNode =
|
| + protocol::DOM::RenderTreeNode::create()
|
| + .setBackendNodeId(backendNodeId)
|
| + .setBoundingBox(buildRectForFloatRect(buildAbsoluteBoundingBox(layoutObject)))
|
| + .build();
|
| +
|
| + if (layoutObject->isText()) {
|
| + LayoutText* layoutText = toLayoutText(layoutObject);
|
| + renderTreeNode->setLayoutText(layoutText->text());
|
| + if (layoutText->hasTextBoxes()) {
|
| + std::unique_ptr<protocol::Array<protocol::DOM::InlineTextBox>> inlineTextNodes(new protocol::Array<protocol::DOM::InlineTextBox>());
|
| + for (const InlineTextBox* itb = layoutText->firstTextBox(); itb; itb = itb->nextTextBox()) {
|
| + FloatRect localItbRect(itb->calculateBoundaries());
|
| + FloatRect absoluteItbRect = layoutObject->localToAbsoluteQuad(localItbRect).boundingBox();
|
| + inlineTextNodes->addItem(
|
| + protocol::DOM::InlineTextBox::create()
|
| + .setText(layoutText->text().substring(itb->start(), itb->len()).utf8().data())
|
| + .setBoundingBox(buildRectForFloatRect(absoluteItbRect))
|
| + .build());
|
| + }
|
| + renderTreeNode->setInlineTextNodes(std::move(inlineTextNodes));
|
| + }
|
| + }
|
| +
|
| + (*renderTreeNodes)->addItem(std::move(renderTreeNode));
|
| + }
|
| +}
|
| +
|
| void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth)
|
| {
|
| Node* node = nodeForId(nodeId);
|
|
|