Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / inspector / InspectorDOMAgent.cpp
index 89f4a0b..d209579 100644 (file)
@@ -31,8 +31,8 @@
 #include "config.h"
 #include "core/inspector/InspectorDOMAgent.h"
 
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ScriptEventListener.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/ScriptEventListener.h"
 #include "core/dom/Attr.h"
 #include "core/dom/CharacterData.h"
 #include "core/dom/ContainerNode.h"
@@ -42,7 +42,6 @@
 #include "core/dom/DocumentType.h"
 #include "core/dom/Element.h"
 #include "core/dom/Node.h"
-#include "core/dom/NodeTraversal.h"
 #include "core/dom/PseudoElement.h"
 #include "core/dom/StaticNodeList.h"
 #include "core/dom/Text.h"
@@ -83,7 +82,7 @@
 #include "wtf/text/CString.h"
 #include "wtf/text/WTFString.h"
 
-namespace WebCore {
+namespace blink {
 
 using namespace HTMLNames;
 
@@ -180,18 +179,19 @@ static Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformTouchEvent& ev
     return hoveredNodeForPoint(frame, roundedIntPoint(points[0].pos()), ignorePointerEventsNone);
 }
 
-class RevalidateStyleAttributeTask {
-    WTF_MAKE_FAST_ALLOCATED;
+class RevalidateStyleAttributeTask FINAL : public NoBaseWillBeGarbageCollectedFinalized<RevalidateStyleAttributeTask> {
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
-    RevalidateStyleAttributeTask(InspectorDOMAgent*);
+    explicit RevalidateStyleAttributeTask(InspectorDOMAgent*);
     void scheduleFor(Element*);
     void reset() { m_timer.stop(); }
     void onTimer(Timer<RevalidateStyleAttributeTask>*);
+    void trace(Visitor*);
 
 private:
-    InspectorDOMAgent* m_domAgent;
+    RawPtrWillBeMember<InspectorDOMAgent> m_domAgent;
     Timer<RevalidateStyleAttributeTask> m_timer;
-    WillBePersistentHeapHashSet<RefPtrWillBeMember<Element> > m_elements;
+    WillBeHeapHashSet<RefPtrWillBeMember<Element> > m_elements;
 };
 
 RevalidateStyleAttributeTask::RevalidateStyleAttributeTask(InspectorDOMAgent* domAgent)
@@ -218,6 +218,14 @@ void RevalidateStyleAttributeTask::onTimer(Timer<RevalidateStyleAttributeTask>*)
     m_elements.clear();
 }
 
+void RevalidateStyleAttributeTask::trace(Visitor* visitor)
+{
+    visitor->trace(m_domAgent);
+#if ENABLE(OILPAN)
+    visitor->trace(m_elements);
+#endif
+}
+
 String InspectorDOMAgent::toErrorString(ExceptionState& exceptionState)
 {
     if (exceptionState.hadException())
@@ -231,19 +239,21 @@ InspectorDOMAgent::InspectorDOMAgent(InspectorPageAgent* pageAgent, InjectedScri
     , m_injectedScriptManager(injectedScriptManager)
     , m_overlay(overlay)
     , m_frontend(0)
-    , m_domListener(0)
+    , m_domListener(nullptr)
     , m_documentNodeToIdMap(adoptPtrWillBeNoop(new NodeToIdMap()))
     , m_lastNodeId(1)
     , m_searchingForNode(NotSearching)
     , m_suppressAttributeModifiedEvent(false)
-    , m_listener(0)
+    , m_listener(nullptr)
 {
 }
 
 InspectorDOMAgent::~InspectorDOMAgent()
 {
+#if !ENABLE(OILPAN)
     reset();
     ASSERT(m_searchingForNode == NotSearching);
+#endif
 }
 
 void InspectorDOMAgent::setFrontend(InspectorFrontend* frontend)
@@ -276,14 +286,15 @@ void InspectorDOMAgent::clearFrontend()
 
 void InspectorDOMAgent::restore()
 {
-    // Reset document to avoid early return from setDocument.
-    m_document = nullptr;
-    setDocument(m_pageAgent->mainFrame()->document());
+    if (!enabled())
+        return;
+    innerEnable();
+    notifyDocumentUpdated();
 }
 
-Vector<Document*> InspectorDOMAgent::documents()
+WillBeHeapVector<RawPtrWillBeMember<Document> > InspectorDOMAgent::documents()
 {
-    Vector<Document*> result;
+    WillBeHeapVector<RawPtrWillBeMember<Document> > result;
     for (Frame* frame = m_document->frame(); frame; frame = frame->tree().traverseNext()) {
         if (!frame->isLocalFrame())
             continue;
@@ -467,6 +478,18 @@ Node* InspectorDOMAgent::assertEditableNode(ErrorString* errorString, int nodeId
     return node;
 }
 
+Node* InspectorDOMAgent::assertEditableChildNode(ErrorString* errorString, Element* parentElement, int nodeId)
+{
+    Node* node = assertEditableNode(errorString, nodeId);
+    if (!node)
+        return 0;
+    if (node->parentNode() != parentElement) {
+        *errorString = "Anchor node must be child of the target element";
+        return 0;
+    }
+    return node;
+}
+
 Element* InspectorDOMAgent::assertEditableElement(ErrorString* errorString, int nodeId)
 {
     Element* element = assertElement(errorString, nodeId);
@@ -486,15 +509,27 @@ Element* InspectorDOMAgent::assertEditableElement(ErrorString* errorString, int
     return element;
 }
 
-void InspectorDOMAgent::enable(ErrorString*)
+void InspectorDOMAgent::innerEnable()
 {
-    if (enabled())
-        return;
     m_state->setBoolean(DOMAgentState::domAgentEnabled, true);
     if (m_listener)
         m_listener->domAgentWasEnabled();
 }
 
+void InspectorDOMAgent::enable(ErrorString*)
+{
+    if (enabled())
+        return;
+    innerEnable();
+    notifyDocumentUpdated();
+}
+
+void InspectorDOMAgent::notifyDocumentUpdated()
+{
+    m_document = nullptr;
+    setDocument(m_pageAgent->mainFrame()->document());
+}
+
 bool InspectorDOMAgent::enabled() const
 {
     return m_state->getBoolean(DOMAgentState::domAgentEnabled);
@@ -513,7 +548,8 @@ void InspectorDOMAgent::disable(ErrorString*)
 void InspectorDOMAgent::getDocument(ErrorString* errorString, RefPtr<TypeBuilder::DOM::Node>& root)
 {
     // Backward compatibility. Mark agent as enabled when it requests document.
-    enable(errorString);
+    if (!enabled())
+        innerEnable();
 
     if (!m_document) {
         *errorString = "Document is not available";
@@ -621,7 +657,7 @@ void InspectorDOMAgent::querySelectorAll(ErrorString* errorString, int nodeId, c
         return;
 
     TrackExceptionState exceptionState;
-    RefPtrWillBeRawPtr<StaticNodeList> nodes = toContainerNode(node)->querySelectorAll(AtomicString(selectors), exceptionState);
+    RefPtrWillBeRawPtr<StaticElementList> elements = toContainerNode(node)->querySelectorAll(AtomicString(selectors), exceptionState);
     if (exceptionState.hadException()) {
         *errorString = "DOM Error while querying";
         return;
@@ -629,8 +665,8 @@ void InspectorDOMAgent::querySelectorAll(ErrorString* errorString, int nodeId, c
 
     result = TypeBuilder::Array<int>::create();
 
-    for (unsigned i = 0; i < nodes->length(); ++i)
-        result->addItem(pushNodePathToFrontend(nodes->item(i)));
+    for (unsigned i = 0; i < elements->length(); ++i)
+        result->addItem(pushNodePathToFrontend(elements->item(i)));
 }
 
 int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
@@ -639,8 +675,7 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
 
     if (!m_document)
         return 0;
-    // FIXME: Oilpan: .get will be unnecessary if m_document is a Member<>.
-    if (!m_documentNodeToIdMap->contains(m_document.get()))
+    if (!m_documentNodeToIdMap->contains(m_document))
         return 0;
 
     // Return id in case the node is known.
@@ -649,7 +684,7 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
         return result;
 
     Node* node = nodeToPush;
-    Vector<Node*> path;
+    WillBeHeapVector<RawPtrWillBeMember<Node> > path;
     NodeToIdMap* danglingMap = 0;
 
     while (true) {
@@ -673,7 +708,7 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
 
     NodeToIdMap* map = danglingMap ? danglingMap : m_documentNodeToIdMap.get();
     for (int i = path.size() - 1; i >= 0; --i) {
-        int nodeId = map->get(path.at(i));
+        int nodeId = map->get(path.at(i).get());
         ASSERT(nodeId);
         pushChildNodesToFrontend(nodeId);
     }
@@ -718,15 +753,15 @@ void InspectorDOMAgent::setAttributesAsText(ErrorString* errorString, int elemen
 
     String caseAdjustedName = name ? (shouldIgnoreCase ? name->lower() : *name) : String();
 
-    if (!parsedElement->hasAttributes() && name) {
+    AttributeCollection attributes = parsedElement->attributes();
+    if (attributes.isEmpty() && name) {
         m_domEditor->removeAttribute(element, caseAdjustedName, errorString);
         return;
     }
 
     bool foundOriginalAttribute = false;
-    AttributeCollection attributes = parsedElement->attributes();
-    AttributeCollection::const_iterator end = attributes.end();
-    for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+    AttributeCollection::iterator end = attributes.end();
+    for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
         // Add attribute pair
         String attributeName = it->name().toString();
         if (shouldIgnoreCase)
@@ -781,8 +816,7 @@ void InspectorDOMAgent::setNodeName(ErrorString* errorString, int nodeId, const
     newElem->cloneAttributesFromElement(*toElement(oldNode));
 
     // Copy over the original node's children.
-    Node* child;
-    while ((child = oldNode->firstChild())) {
+    for (Node* child = oldNode->firstChild(); child; child = oldNode->firstChild()) {
         if (!m_domEditor->insertBefore(newElem.get(), child, 0, errorString))
             return;
     }
@@ -926,13 +960,50 @@ void InspectorDOMAgent::getEventListeners(EventTarget* target, Vector<EventListe
     }
 }
 
-void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrimmedQuery, String* searchId, int* resultCount)
+static Node* nextNodeWithShadowDOMInMind(const Node& current, const Node* stayWithin, bool includeUserAgentShadowDOM)
+{
+    // At first traverse the subtree.
+    if (current.isElementNode()) {
+        const Element& element = toElement(current);
+        ElementShadow* elementShadow = element.shadow();
+        if (elementShadow) {
+            ShadowRoot* shadowRoot = elementShadow->youngestShadowRoot();
+            if (shadowRoot) {
+                if (shadowRoot->type() == ShadowRoot::AuthorShadowRoot || includeUserAgentShadowDOM)
+                    return shadowRoot;
+            }
+        }
+    }
+    if (current.hasChildren())
+        return current.firstChild();
+
+    // Then traverse siblings of the node itself and its ancestors.
+    const Node* node = &current;
+    do {
+        if (node == stayWithin)
+            return 0;
+        if (node->isShadowRoot()) {
+            const ShadowRoot* shadowRoot = toShadowRoot(node);
+            if (shadowRoot->olderShadowRoot())
+                return shadowRoot->olderShadowRoot();
+        }
+        if (node->nextSibling())
+            return node->nextSibling();
+        node = node->isShadowRoot() ? toShadowRoot(node)->host() : node->parentNode();
+    } while (node);
+
+    return 0;
+}
+
+void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrimmedQuery, const bool* optionalIncludeUserAgentShadowDOM, String* searchId, int* resultCount)
 {
     // FIXME: Few things are missing here:
     // 1) Search works with node granularity - number of matches within node is not calculated.
     // 2) There is no need to push all search results to the front-end at a time, pushing next / previous result
     //    is sufficient.
 
+    bool includeUserAgentShadowDOM = optionalIncludeUserAgentShadowDOM ? *optionalIncludeUserAgentShadowDOM : false;
+
     unsigned queryLength = whitespaceTrimmedQuery.length();
     bool startTagFound = !whitespaceTrimmedQuery.find('<');
     bool endTagFound = whitespaceTrimmedQuery.reverseFind('>') + 1 == queryLength;
@@ -951,17 +1022,18 @@ void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrim
     if (endQuoteFound)
         attributeQuery = attributeQuery.left(attributeQuery.length() - 1);
 
-    Vector<Document*> docs = documents();
-    ListHashSet<Node*> resultCollector;
+    WillBeHeapVector<RawPtrWillBeMember<Document> > docs = documents();
+    WillBeHeapListHashSet<RawPtrWillBeMember<Node> > resultCollector;
 
-    for (Vector<Document*>::iterator it = docs.begin(); it != docs.end(); ++it) {
+    for (WillBeHeapVector<RawPtrWillBeMember<Document> >::iterator it = docs.begin(); it != docs.end(); ++it) {
         Document* document = *it;
-        Node* node = document->documentElement();
+        Node* documentElement = document->documentElement();
+        Node* node = documentElement;
         if (!node)
             continue;
 
         // Manual plain text search.
-        while ((node = NodeTraversal::next(*node, document->documentElement()))) {
+        for (node = nextNodeWithShadowDOMInMind(*node, documentElement, includeUserAgentShadowDOM); node; node = nextNodeWithShadowDOMInMind(*node, documentElement, includeUserAgentShadowDOM)) {
             switch (node->nodeType()) {
             case Node::TEXT_NODE:
             case Node::COMMENT_NODE:
@@ -981,12 +1053,9 @@ void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrim
                 }
                 // Go through all attributes and serialize them.
                 const Element* element = toElement(node);
-                if (!element->hasAttributes())
-                    break;
-
                 AttributeCollection attributes = element->attributes();
-                AttributeCollection::const_iterator end = attributes.end();
-                for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+                AttributeCollection::iterator end = attributes.end();
+                for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
                     // Add attribute pair
                     if (it->localName().find(whitespaceTrimmedQuery, 0, false) != kNotFound) {
                         resultCollector.add(node);
@@ -1008,7 +1077,7 @@ void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrim
         }
 
         // XPath evaluation
-        for (Vector<Document*>::iterator it = docs.begin(); it != docs.end(); ++it) {
+        for (WillBeHeapVector<RawPtrWillBeMember<Document> >::iterator it = docs.begin(); it != docs.end(); ++it) {
             Document* document = *it;
             ASSERT(document);
             TrackExceptionState exceptionState;
@@ -1029,23 +1098,23 @@ void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrim
         }
 
         // Selector evaluation
-        for (Vector<Document*>::iterator it = docs.begin(); it != docs.end(); ++it) {
+        for (WillBeHeapVector<RawPtrWillBeMember<Document> >::iterator it = docs.begin(); it != docs.end(); ++it) {
             Document* document = *it;
             TrackExceptionState exceptionState;
-            RefPtrWillBeRawPtr<StaticNodeList> nodeList = document->querySelectorAll(AtomicString(whitespaceTrimmedQuery), exceptionState);
-            if (exceptionState.hadException() || !nodeList)
+            RefPtrWillBeRawPtr<StaticElementList> elementList = document->querySelectorAll(AtomicString(whitespaceTrimmedQuery), exceptionState);
+            if (exceptionState.hadException() || !elementList)
                 continue;
 
-            unsigned size = nodeList->length();
+            unsigned size = elementList->length();
             for (unsigned i = 0; i < size; ++i)
-                resultCollector.add(nodeList->item(i));
+                resultCollector.add(elementList->item(i));
         }
     }
 
     *searchId = IdentifiersFactory::createIdentifier();
     WillBeHeapVector<RefPtrWillBeMember<Node> >* resultsIt = &m_searchResults.add(*searchId, WillBeHeapVector<RefPtrWillBeMember<Node> >()).storedValue->value;
 
-    for (ListHashSet<Node*>::iterator it = resultCollector.begin(); it != resultCollector.end(); ++it)
+    for (WillBeHeapListHashSet<RawPtrWillBeMember<Node> >::iterator it = resultCollector.begin(); it != resultCollector.end(); ++it)
         resultsIt->append(*it);
 
     *resultCount = resultsIt->size();
@@ -1130,13 +1199,13 @@ void InspectorDOMAgent::inspect(Node* inspectedNode)
         m_frontend->inspectNodeRequested(nodeId);
 }
 
-void InspectorDOMAgent::handleMouseMove(LocalFrame* frame, const PlatformMouseEvent& event)
+bool InspectorDOMAgent::handleMouseMove(LocalFrame* frame, const PlatformMouseEvent& event)
 {
     if (m_searchingForNode == NotSearching)
-        return;
+        return false;
 
     if (!frame->view() || !frame->contentRenderer())
-        return;
+        return true;
     Node* node = hoveredNodeForEvent(frame, event, event.shiftKey());
 
     // Do not highlight within UA shadow root unless requested.
@@ -1151,7 +1220,7 @@ void InspectorDOMAgent::handleMouseMove(LocalFrame* frame, const PlatformMouseEv
         node = node->parentOrShadowHostNode();
 
     if (!node)
-        return;
+        return true;
 
     Node* eventTarget = event.shiftKey() ? hoveredNodeForEvent(frame, event, false) : 0;
     if (eventTarget == node)
@@ -1159,6 +1228,7 @@ void InspectorDOMAgent::handleMouseMove(LocalFrame* frame, const PlatformMouseEv
 
     if (node && m_inspectModeHighlightConfig)
         m_overlay->highlightNode(node, eventTarget, *m_inspectModeHighlightConfig, event.ctrlKey() || event.metaKey());
+    return true;
 }
 
 void InspectorDOMAgent::setSearchingForNode(ErrorString* errorString, SearchMode searchMode, JSONObject* highlightInspectorObject)
@@ -1190,12 +1260,18 @@ PassOwnPtr<HighlightConfig> InspectorDOMAgent::highlightConfigFromInspectorObjec
     bool showRulers = false; // Default: false (do not show rulers).
     highlightInspectorObject->getBoolean("showRulers", &showRulers);
     highlightConfig->showRulers = showRulers;
+    bool showExtensionLines = false; // Default: false (do not show extension lines).
+    highlightInspectorObject->getBoolean("showExtensionLines", &showExtensionLines);
+    highlightConfig->showExtensionLines = showExtensionLines;
     highlightConfig->content = parseConfigColor("contentColor", highlightInspectorObject);
     highlightConfig->contentOutline = parseConfigColor("contentOutlineColor", highlightInspectorObject);
     highlightConfig->padding = parseConfigColor("paddingColor", highlightInspectorObject);
     highlightConfig->border = parseConfigColor("borderColor", highlightInspectorObject);
     highlightConfig->margin = parseConfigColor("marginColor", highlightInspectorObject);
     highlightConfig->eventTarget = parseConfigColor("eventTargetColor", highlightInspectorObject);
+    highlightConfig->shape = parseConfigColor("shapeColor", highlightInspectorObject);
+    highlightConfig->shapeMargin = parseConfigColor("shapeMarginColor", highlightInspectorObject);
+
     return highlightConfig.release();
 }
 
@@ -1203,7 +1279,7 @@ void InspectorDOMAgent::setInspectModeEnabled(ErrorString* errorString, bool ena
 {
     if (enabled && !pushDocumentUponHandlelessOperation(errorString))
         return;
-    SearchMode searchMode = enabled ? (inspectUAShadowDOM && *inspectUAShadowDOM ? SearchingForUAShadow : SearchingForNormal) : NotSearching;
+    SearchMode searchMode = enabled ? (asBool(inspectUAShadowDOM) ? SearchingForUAShadow : SearchingForNormal) : NotSearching;
     setSearchingForNode(errorString, searchMode, highlightConfig ? highlightConfig->get() : 0);
 }
 
@@ -1276,7 +1352,7 @@ void InspectorDOMAgent::hideHighlight(ErrorString*)
     m_overlay->hideHighlight();
 }
 
-void InspectorDOMAgent::moveTo(ErrorString* errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId)
+void InspectorDOMAgent::copyTo(ErrorString* errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId)
 {
     Node* node = assertEditableNode(errorString, nodeId);
     if (!node)
@@ -1288,13 +1364,47 @@ void InspectorDOMAgent::moveTo(ErrorString* errorString, int nodeId, int targetE
 
     Node* anchorNode = 0;
     if (anchorNodeId && *anchorNodeId) {
-        anchorNode = assertEditableNode(errorString, *anchorNodeId);
+        anchorNode = assertEditableChildNode(errorString, targetElement, *anchorNodeId);
         if (!anchorNode)
             return;
-        if (anchorNode->parentNode() != targetElement) {
-            *errorString = "Anchor node must be child of the target element";
+    }
+
+    // The clone is deep by default.
+    RefPtrWillBeRawPtr<Node> clonedNode = node->cloneNode(true);
+    if (!clonedNode) {
+        *errorString = "Failed to clone node";
+        return;
+    }
+    if (!m_domEditor->insertBefore(targetElement, clonedNode, anchorNode, errorString))
+        return;
+
+    *newNodeId = pushNodePathToFrontend(clonedNode.get());
+}
+
+void InspectorDOMAgent::moveTo(ErrorString* errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId)
+{
+    Node* node = assertEditableNode(errorString, nodeId);
+    if (!node)
+        return;
+
+    Element* targetElement = assertEditableElement(errorString, targetElementId);
+    if (!targetElement)
+        return;
+
+    Node* current = targetElement;
+    while (current) {
+        if (current == node) {
+            *errorString = "Unable to move node into self or descendant";
             return;
         }
+        current = current->parentNode();
+    }
+
+    Node* anchorNode = 0;
+    if (anchorNodeId && *anchorNodeId) {
+        anchorNode = assertEditableChildNode(errorString, targetElement, *anchorNodeId);
+        if (!anchorNode)
+            return;
     }
 
     if (!m_domEditor->insertBefore(targetElement, node, anchorNode, errorString))
@@ -1358,58 +1468,28 @@ void InspectorDOMAgent::setFileInputFiles(ErrorString* errorString, int nodeId,
     toHTMLInputElement(node)->setFiles(fileList);
 }
 
-static RefPtr<TypeBuilder::Array<double> > buildArrayForQuad(const FloatQuad& quad)
-{
-    RefPtr<TypeBuilder::Array<double> > array = TypeBuilder::Array<double>::create();
-    array->addItem(quad.p1().x());
-    array->addItem(quad.p1().y());
-    array->addItem(quad.p2().x());
-    array->addItem(quad.p2().y());
-    array->addItem(quad.p3().x());
-    array->addItem(quad.p3().y());
-    array->addItem(quad.p4().x());
-    array->addItem(quad.p4().y());
-    return array.release();
-}
-
 void InspectorDOMAgent::getBoxModel(ErrorString* errorString, int nodeId, RefPtr<TypeBuilder::DOM::BoxModel>& model)
 {
     Node* node = assertNode(errorString, nodeId);
     if (!node)
         return;
 
-    Vector<FloatQuad> quads;
-    bool isInlineOrBox = m_overlay->getBoxModel(node, &quads);
-    if (!isInlineOrBox) {
+    bool result = m_overlay->getBoxModel(node, model);
+    if (!result)
         *errorString = "Could not compute box model.";
-        return;
-    }
-
-    RenderObject* renderer = node->renderer();
-    LocalFrame* frame = node->document().frame();
-    FrameView* view = frame->view();
-
-    IntRect boundingBox = pixelSnappedIntRect(view->contentsToRootView(renderer->absoluteBoundingBoxRect()));
-    RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : 0;
-    RefPtr<TypeBuilder::DOM::ShapeOutsideInfo> shapeOutsideInfo = m_overlay->buildObjectForShapeOutside(node);
 
-    model = TypeBuilder::DOM::BoxModel::create()
-        .setContent(buildArrayForQuad(quads.at(3)))
-        .setPadding(buildArrayForQuad(quads.at(2)))
-        .setBorder(buildArrayForQuad(quads.at(1)))
-        .setMargin(buildArrayForQuad(quads.at(0)))
-        .setWidth(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetWidth(), modelObject) : boundingBox.width())
-        .setHeight(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetHeight(), modelObject) : boundingBox.height());
-    if (shapeOutsideInfo)
-        model->setShapeOutside(shapeOutsideInfo);
 }
 
 void InspectorDOMAgent::getNodeForLocation(ErrorString* errorString, int x, int y, int* nodeId)
 {
     if (!pushDocumentUponHandlelessOperation(errorString))
         return;
-
-    Node* node = hoveredNodeForPoint(m_document->frame(), IntPoint(x, y), false);
+    HitTestRequest request(HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::AllowChildFrameContent);
+    HitTestResult result(IntPoint(x, y));
+    m_document->frame()->contentRenderer()->hitTest(request, result);
+    Node* node = result.innerPossiblyPseudoNode();
+    while (node && node->nodeType() == Node::TEXT_NODE)
+        node = node->parentNode();
     if (!node) {
         *errorString = "No node found at given location";
         return;
@@ -1598,11 +1678,9 @@ PassRefPtr<TypeBuilder::Array<String> > InspectorDOMAgent::buildArrayForElementA
 {
     RefPtr<TypeBuilder::Array<String> > attributesValue = TypeBuilder::Array<String>::create();
     // Go through all attributes and serialize them.
-    if (!element->hasAttributes())
-        return attributesValue.release();
     AttributeCollection attributes = element->attributes();
-    AttributeCollection::const_iterator end = attributes.end();
-    for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+    AttributeCollection::iterator end = attributes.end();
+    for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
         // Add attribute pair
         attributesValue->addItem(it->name().toString());
         attributesValue->addItem(it->value());
@@ -1914,7 +1992,7 @@ void InspectorDOMAgent::didInvalidateStyleAttr(Node* node)
         return;
 
     if (!m_revalidateStyleAttrTask)
-        m_revalidateStyleAttrTask = adoptPtr(new RevalidateStyleAttributeTask(this));
+        m_revalidateStyleAttrTask = adoptPtrWillBeNoop(new RevalidateStyleAttributeTask(this));
     m_revalidateStyleAttrTask->scheduleFor(toElement(node));
 }
 
@@ -2008,7 +2086,7 @@ Node* InspectorDOMAgent::nodeForPath(const String& path)
 
     Node* node = m_document.get();
     Vector<String> pathTokens;
-    path.split(",", false, pathTokens);
+    path.split(',', pathTokens);
     if (!pathTokens.size())
         return 0;
     for (size_t i = 0; i < pathTokens.size() - 1; i += 2) {
@@ -2094,8 +2172,7 @@ PassRefPtr<TypeBuilder::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(No
 
 bool InspectorDOMAgent::pushDocumentUponHandlelessOperation(ErrorString* errorString)
 {
-    // FIXME: Oilpan: .get will be unnecessary if m_document is a Member<>.
-    if (!m_documentNodeToIdMap->contains(m_document.get())) {
+    if (!m_documentNodeToIdMap->contains(m_document)) {
         RefPtr<TypeBuilder::DOM::Node> root;
         getDocument(errorString, root);
         return errorString->isEmpty();
@@ -2103,5 +2180,25 @@ bool InspectorDOMAgent::pushDocumentUponHandlelessOperation(ErrorString* errorSt
     return true;
 }
 
-} // namespace WebCore
+void InspectorDOMAgent::trace(Visitor* visitor)
+{
+    visitor->trace(m_domListener);
+    visitor->trace(m_pageAgent);
+    visitor->trace(m_injectedScriptManager);
+#if ENABLE(OILPAN)
+    visitor->trace(m_documentNodeToIdMap);
+    visitor->trace(m_danglingNodeToIdMaps);
+    visitor->trace(m_idToNode);
+    visitor->trace(m_idToNodesMap);
+    visitor->trace(m_document);
+    visitor->trace(m_revalidateStyleAttrTask);
+    visitor->trace(m_searchResults);
+#endif
+    visitor->trace(m_history);
+    visitor->trace(m_domEditor);
+    visitor->trace(m_listener);
+    InspectorBaseAgent::trace(visitor);
+}
+
+} // namespace blink