15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Google Inc. All rights reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Joseph Pecoraro
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     documentation and/or other materials provided with the distribution.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     its contributors may be used to endorse or promote products derived
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     from this software without specific prior written permission.
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorDOMAgent.h"
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h"
35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptEventListener.h"
367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/InputTypeNames.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Attr.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/CharacterData.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ContainerNode.h"
40591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/dom/DOMException.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/DocumentFragment.h"
4353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/DocumentType.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Element.h"
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Node.h"
469bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)#include "core/dom/PseudoElement.h"
4776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include "core/dom/StaticNodeList.h"
4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Text.h"
49e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/ElementShadow.h"
50e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/ShadowRoot.h"
51e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/editing/markup.h"
5276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include "core/events/EventListener.h"
5376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include "core/events/EventTarget.h"
5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/File.h"
5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/fileapi/FileList.h"
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
5753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLFrameOwnerElement.h"
5853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLInputElement.h"
5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/html/HTMLLinkElement.h"
6053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLTemplateElement.h"
61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/html/imports/HTMLImportChild.h"
626f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch#include "core/html/imports/HTMLImportLoader.h"
6353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/DOMEditor.h"
6453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/DOMPatchSupport.h"
6553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/IdentifiersFactory.h"
6653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorHistory.h"
67323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#include "core/inspector/InspectorNodeIds.h"
6853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorOverlay.h"
6953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorPageAgent.h"
7053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorState.h"
7153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InstrumentingAgents.h"
7293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "core/loader/DocumentLoader.h"
7353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/FrameTree.h"
7453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/Page.h"
7553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/HitTestResult.h"
7653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h"
77e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "core/xml/DocumentXPathEvaluator.h"
7853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/XPathResult.h"
791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/PlatformGestureEvent.h"
801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/PlatformMouseEvent.h"
811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/PlatformTouchEvent.h"
82e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/ListHashSet.h"
83e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/text/CString.h"
84e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/text/WTFString.h"
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
86c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace DOMAgentState {
91f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)static const char domAgentEnabled[] = "domAgentEnabled";
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const size_t maxTextSize = 10000;
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const UChar ellipsisUChar[] = { 0x2026, 0 };
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
97591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic Color parseColor(const RefPtr<JSONObject>* colorObject)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!colorObject || !(*colorObject))
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return Color::transparent;
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int r;
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int g;
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int b;
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool success = (*colorObject)->getNumber("r", &r);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    success |= (*colorObject)->getNumber("g", &g);
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    success |= (*colorObject)->getNumber("b", &b);
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!success)
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return Color::transparent;
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double a;
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    success = (*colorObject)->getNumber("a", &a);
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!success)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return Color(r, g, b);
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Clamp alpha to the [0..1] range.
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (a < 0)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        a = 0;
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else if (a > 1)
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        a = 1;
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return Color(r, g, b, static_cast<int>(a * 255));
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
125591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic Color parseConfigColor(const String& fieldName, JSONObject* configObject)
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
127591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    const RefPtr<JSONObject> colorObject = configObject->getObject(fieldName);
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return parseColor(&colorObject);
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
131591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic bool parseQuad(const RefPtr<JSONArray>& quadArray, FloatQuad* quad)
13253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
13353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!quadArray)
13453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return false;
13553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const size_t coordinatesInQuad = 8;
13653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    double coordinates[coordinatesInQuad];
13753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (quadArray->length() != coordinatesInQuad)
13853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return false;
13953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    for (size_t i = 0; i < coordinatesInQuad; ++i) {
14053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        if (!quadArray->get(i)->asNumber(coordinates + i))
14153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            return false;
14253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
14353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    quad->setP1(FloatPoint(coordinates[0], coordinates[1]));
14453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    quad->setP2(FloatPoint(coordinates[2], coordinates[3]));
14553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    quad->setP3(FloatPoint(coordinates[4], coordinates[5]));
14653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    quad->setP4(FloatPoint(coordinates[6], coordinates[7]));
14753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
14853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return true;
14953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
15053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static Node* hoveredNodeForPoint(LocalFrame* frame, const IntPoint& point, bool ignorePointerEventsNone)
15253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
15353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::AllowChildFrameContent;
15453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (ignorePointerEventsNone)
15553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        hitType |= HitTestRequest::IgnorePointerEventsNone;
15653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    HitTestRequest request(hitType);
15753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    HitTestResult result(frame->view()->windowToContents(point));
15853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    frame->contentRenderer()->hitTest(request, result);
1591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    Node* node = result.innerPossiblyPseudoNode();
16053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    while (node && node->nodeType() == Node::TEXT_NODE)
16153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        node = node->parentNode();
16253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return node;
16353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
16453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
165d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformGestureEvent& event, bool ignorePointerEventsNone)
166e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
167e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return hoveredNodeForPoint(frame, event.position(), ignorePointerEventsNone);
168e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
169e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
170d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformMouseEvent& event, bool ignorePointerEventsNone)
17153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
17253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    return hoveredNodeForPoint(frame, event.position(), ignorePointerEventsNone);
17353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
17453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformTouchEvent& event, bool ignorePointerEventsNone)
17653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
17753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    const Vector<PlatformTouchPoint>& points = event.touchPoints();
17853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!points.size())
17953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return 0;
1805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    return hoveredNodeForPoint(frame, roundedIntPoint(points[0].pos()), ignorePointerEventsNone);
18153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
18253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
183c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class RevalidateStyleAttributeTask FINAL : public NoBaseWillBeGarbageCollectedFinalized<RevalidateStyleAttributeTask> {
184c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
186c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    explicit RevalidateStyleAttributeTask(InspectorDOMAgent*);
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void scheduleFor(Element*);
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void reset() { m_timer.stop(); }
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void onTimer(Timer<RevalidateStyleAttributeTask>*);
190c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void trace(Visitor*);
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
193c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RawPtrWillBeMember<InspectorDOMAgent> m_domAgent;
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Timer<RevalidateStyleAttributeTask> m_timer;
195c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    WillBeHeapHashSet<RefPtrWillBeMember<Element> > m_elements;
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RevalidateStyleAttributeTask::RevalidateStyleAttributeTask(InspectorDOMAgent* domAgent)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_domAgent(domAgent)
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_timer(this, &RevalidateStyleAttributeTask::onTimer)
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RevalidateStyleAttributeTask::scheduleFor(Element* element)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_elements.add(element);
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_timer.isActive())
208d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_timer.startOneShot(0, FROM_HERE);
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RevalidateStyleAttributeTask::onTimer(Timer<RevalidateStyleAttributeTask>*)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The timer is stopped on m_domAgent destruction, so this method will never be called after m_domAgent has been destroyed.
214f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    WillBeHeapVector<RawPtrWillBeMember<Element> > elements;
215f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (WillBePersistentHeapHashSet<RefPtrWillBeMember<Element> >::iterator it = m_elements.begin(), end = m_elements.end(); it != end; ++it)
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        elements.append(it->get());
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_domAgent->styleAttributeInvalidated(elements);
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_elements.clear();
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
222c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void RevalidateStyleAttributeTask::trace(Visitor* visitor)
223c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
224c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    visitor->trace(m_domAgent);
225c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#if ENABLE(OILPAN)
226c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    visitor->trace(m_elements);
227c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#endif
228c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
229c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
23051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)String InspectorDOMAgent::toErrorString(ExceptionState& exceptionState)
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
23251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
233d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return DOMException::getErrorName(exceptionState.code()) + " " + exceptionState.message();
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return "";
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
23709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)InspectorDOMAgent::InspectorDOMAgent(InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
23809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    : InspectorBaseAgent<InspectorDOMAgent>("DOM")
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_pageAgent(pageAgent)
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_injectedScriptManager(injectedScriptManager)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_overlay(overlay)
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_frontend(0)
243c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    , m_domListener(nullptr)
244f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    , m_documentNodeToIdMap(adoptPtrWillBeNoop(new NodeToIdMap()))
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_lastNodeId(1)
246e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    , m_searchingForNode(NotSearching)
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_suppressAttributeModifiedEvent(false)
248c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    , m_listener(nullptr)
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InspectorDOMAgent::~InspectorDOMAgent()
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
254c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#if !ENABLE(OILPAN)
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    reset();
256e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    ASSERT(m_searchingForNode == NotSearching);
257c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#endif
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::setFrontend(InspectorFrontend* frontend)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_frontend);
2635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_history = adoptPtrWillBeNoop(new InspectorHistory());
2645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_domEditor = adoptPtrWillBeNoop(new DOMEditor(m_history.get()));
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_frontend = frontend->dom();
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_instrumentingAgents->setInspectorDOMAgent(this);
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_document = m_pageAgent->mainFrame()->document();
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::clearFrontend()
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_frontend);
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_history.clear();
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_domEditor.clear();
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ErrorString error;
279e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    setSearchingForNode(&error, NotSearching, 0);
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    hideHighlight(&error);
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_frontend = 0;
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_instrumentingAgents->setInspectorDOMAgent(0);
284f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    disable(0);
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    reset();
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::restore()
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
290197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!enabled())
291197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return;
292197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    innerEnable();
293197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    notifyDocumentUpdated();
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
296c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)WillBeHeapVector<RawPtrWillBeMember<Document> > InspectorDOMAgent::documents()
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
298c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    WillBeHeapVector<RawPtrWillBeMember<Document> > result;
299f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (Frame* frame = m_document->frame(); frame; frame = frame->tree().traverseNext()) {
300f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (!frame->isLocalFrame())
301f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            continue;
302f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        Document* document = toLocalFrame(frame)->document();
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!document)
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.append(document);
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result;
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::reset()
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
312e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    discardFrontendBindings();
313d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_document = nullptr;
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::setDOMListener(DOMListener* listener)
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_domListener = listener;
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::setDocument(Document* doc)
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (doc == m_document.get())
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    reset();
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_document = doc;
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
330f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (!enabled())
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Immediately communicate 0 document or document that has finished loading.
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!doc || !doc->parsing())
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_frontend->documentUpdated();
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::releaseDanglingNodes()
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_danglingNodeToIdMaps.clear();
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int InspectorDOMAgent::bind(Node* node, NodeToIdMap* nodesMap)
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int id = nodesMap->get(node);
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (id)
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return id;
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    id = m_lastNodeId++;
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    nodesMap->set(node, id);
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_idToNode.set(id, node);
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_idToNodesMap.set(id, nodesMap);
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return id;
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap)
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int id = nodesMap->get(node);
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!id)
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_idToNode.remove(id);
362f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_idToNodesMap.remove(id);
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node->isFrameOwnerElement()) {
365e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        Document* contentDocument = toHTMLFrameOwnerElement(node)->contentDocument();
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_domListener)
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_domListener->didRemoveDocument(contentDocument);
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (contentDocument)
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            unbind(contentDocument, nodesMap);
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
372f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
373f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        unbind(root, nodesMap);
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3759bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (node->isElementNode()) {
3769bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        Element* element = toElement(node);
3779bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        if (element->pseudoElement(BEFORE))
3789bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            unbind(element->pseudoElement(BEFORE), nodesMap);
3799bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        if (element->pseudoElement(AFTER))
3809bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            unbind(element->pseudoElement(AFTER), nodesMap);
38109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
382d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (isHTMLLinkElement(*element)) {
383d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            HTMLLinkElement& linkElement = toHTMLLinkElement(*element);
384d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (linkElement.isImport() && linkElement.import())
385d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                unbind(linkElement.import(), nodesMap);
38609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
3879bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
3889bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    nodesMap->remove(node);
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_domListener)
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_domListener->didRemoveDOMNode(node);
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool childrenRequested = m_childrenRequested.contains(id);
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (childrenRequested) {
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Unbind subtree known to client recursively.
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_childrenRequested.remove(id);
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node* child = innerFirstChild(node);
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (child) {
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            unbind(child, nodesMap);
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            child = innerNextSibling(child);
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
403f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (nodesMap == m_documentNodeToIdMap.get())
404d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_cachedChildCount.remove(id);
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* InspectorDOMAgent::assertNode(ErrorString* errorString, int nodeId)
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = nodeForId(nodeId);
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node) {
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "Could not find node with given id";
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node;
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Document* InspectorDOMAgent::assertDocument(ErrorString* errorString, int nodeId)
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertNode(errorString, nodeId);
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!(node->isDocumentNode())) {
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "Document is not available";
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
427926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return toDocument(node);
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element* InspectorDOMAgent::assertElement(ErrorString* errorString, int nodeId)
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertNode(errorString, nodeId);
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
436f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (!node->isElementNode()) {
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "Node is not an Element";
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return toElement(node);
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
44343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)static ShadowRoot* userAgentShadowRoot(Node* node)
44443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles){
44543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    if (!node || !node->isInShadowTree())
44643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        return 0;
44743e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
44843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    Node* candidate = node;
44943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    while (candidate && !candidate->isShadowRoot())
45043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        candidate = candidate->parentOrShadowHostNode();
45143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    ASSERT(candidate);
45243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    ShadowRoot* shadowRoot = toShadowRoot(candidate);
45343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
45443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    return shadowRoot->type() == ShadowRoot::UserAgentShadowRoot ? shadowRoot : 0;
45543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)}
45643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* InspectorDOMAgent::assertEditableNode(ErrorString* errorString, int nodeId)
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertNode(errorString, nodeId);
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node->isInShadowTree()) {
464d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (node->isShadowRoot()) {
465d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            *errorString = "Cannot edit shadow roots";
466d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return 0;
467d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
46843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        if (userAgentShadowRoot(node)) {
469d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            *errorString = "Cannot edit nodes from user-agent shadow trees";
470d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return 0;
471d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
4729bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
4739bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
4749bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (node->isPseudoElement()) {
4759bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        *errorString = "Cannot edit pseudo elements";
4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node;
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
482c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)Node* InspectorDOMAgent::assertEditableChildNode(ErrorString* errorString, Element* parentElement, int nodeId)
483c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
484c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Node* node = assertEditableNode(errorString, nodeId);
485c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!node)
486c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return 0;
487c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (node->parentNode() != parentElement) {
488c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        *errorString = "Anchor node must be child of the target element";
489c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return 0;
490c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
491c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return node;
492c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
493c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element* InspectorDOMAgent::assertEditableElement(ErrorString* errorString, int nodeId)
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* element = assertElement(errorString, nodeId);
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!element)
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
50007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    if (element->isInShadowTree() && userAgentShadowRoot(element)) {
50107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        *errorString = "Cannot edit elements from user-agent shadow trees";
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5049bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
5059bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (element->isPseudoElement()) {
5069bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        *errorString = "Cannot edit pseudo elements";
5079bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        return 0;
5089bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
5099bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return element;
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
513197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid InspectorDOMAgent::innerEnable()
514f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
515f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_state->setBoolean(DOMAgentState::domAgentEnabled, true);
516f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (m_listener)
517f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_listener->domAgentWasEnabled();
518f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
519f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
520197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid InspectorDOMAgent::enable(ErrorString*)
521197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
522197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (enabled())
523197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return;
524197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    innerEnable();
525197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    notifyDocumentUpdated();
526197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
527197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
528197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid InspectorDOMAgent::notifyDocumentUpdated()
529197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
530197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_document = nullptr;
531197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    setDocument(m_pageAgent->mainFrame()->document());
532197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
533197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
534f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)bool InspectorDOMAgent::enabled() const
535f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
536f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    return m_state->getBoolean(DOMAgentState::domAgentEnabled);
537f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
538f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
5397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid InspectorDOMAgent::disable(ErrorString* errorString)
540f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
5417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!enabled()) {
5427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (errorString)
5437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            *errorString = "DOM agent hasn't been enabled";
544f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        return;
5457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
546f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_state->setBoolean(DOMAgentState::domAgentEnabled, false);
547f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    reset();
548f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (m_listener)
549f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_listener->domAgentWasDisabled();
550f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
551f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::getDocument(ErrorString* errorString, RefPtr<TypeBuilder::DOM::Node>& root)
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
554f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    // Backward compatibility. Mark agent as enabled when it requests document.
555197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!enabled())
556197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        innerEnable();
5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_document) {
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "Document is not available";
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
563e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    discardFrontendBindings();
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
565f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    root = buildObjectForNode(m_document.get(), 2, m_documentNodeToIdMap.get());
5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
568926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth)
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = nodeForId(nodeId);
571f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (!node || (!node->isElementNode() && !node->isDocumentNode() && !node->isDocumentFragment()))
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    NodeToIdMap* nodeMap = m_idToNodesMap.get(nodeId);
575926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
576926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_childrenRequested.contains(nodeId)) {
577926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (depth <= 1)
578926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return;
579926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
580926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        depth--;
581926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
582926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        for (node = innerFirstChild(node); node; node = innerNextSibling(node)) {
583926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            int childNodeId = nodeMap->get(node);
584926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ASSERT(childNodeId);
585926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            pushChildNodesToFrontend(childNodeId, depth);
586926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
587926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
588926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
589926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
590926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
591926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = buildArrayForContainerChildren(node, depth, nodeMap);
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_frontend->setChildNodes(nodeId, children.release());
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
595e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void InspectorDOMAgent::discardFrontendBindings()
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
597e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    if (m_history)
598e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        m_history->reset();
599e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    m_searchResults.clear();
600f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_documentNodeToIdMap->clear();
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_idToNode.clear();
602f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_idToNodesMap.clear();
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    releaseDanglingNodes();
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_childrenRequested.clear();
605d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_cachedChildCount.clear();
606e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    if (m_revalidateStyleAttrTask)
607e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        m_revalidateStyleAttrTask->reset();
608e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)}
609e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* InspectorDOMAgent::nodeForId(int id)
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!id)
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
615f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    WillBeHeapHashMap<int, RawPtrWillBeMember<Node> >::iterator it = m_idToNode.find(id);
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (it != m_idToNode.end())
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return it->value;
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
621926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorDOMAgent::requestChildNodes(ErrorString* errorString, int nodeId, const int* depth)
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
623926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    int sanitizedDepth;
624926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
625926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!depth)
626926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        sanitizedDepth = 1;
627926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    else if (*depth == -1)
628926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        sanitizedDepth = INT_MAX;
629926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    else if (*depth > 0)
630926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        sanitizedDepth = *depth;
631926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    else {
632926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        *errorString = "Please provide a positive integer as a depth or -1 for entire subtree";
633926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
634926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
635926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
636926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    pushChildNodesToFrontend(nodeId, sanitizedDepth);
6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::querySelector(ErrorString* errorString, int nodeId, const String& selectors, int* elementId)
6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *elementId = 0;
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertNode(errorString, nodeId);
64309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!node || !node->isContainerNode())
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
64651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    TrackExceptionState exceptionState;
647f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<Element> element = toContainerNode(node)->querySelector(AtomicString(selectors), exceptionState);
64851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException()) {
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "DOM Error while querying";
6505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (element)
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *elementId = pushNodePathToFrontend(element.get());
6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::querySelectorAll(ErrorString* errorString, int nodeId, const String& selectors, RefPtr<TypeBuilder::Array<int> >& result)
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertNode(errorString, nodeId);
66009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!node || !node->isContainerNode())
6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
66351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    TrackExceptionState exceptionState;
664e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RefPtrWillBeRawPtr<StaticElementList> elements = toContainerNode(node)->querySelectorAll(AtomicString(selectors), exceptionState);
66551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException()) {
6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "DOM Error while querying";
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result = TypeBuilder::Array<int>::create();
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
672e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    for (unsigned i = 0; i < elements->length(); ++i)
673e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        result->addItem(pushNodePathToFrontend(elements->item(i)));
6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(nodeToPush);  // Invalid input
6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_document)
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
682c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!m_documentNodeToIdMap->contains(m_document))
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Return id in case the node is known.
686f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int result = m_documentNodeToIdMap->get(nodeToPush);
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (result)
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return result;
6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = nodeToPush;
691197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    WillBeHeapVector<RawPtrWillBeMember<Node> > path;
6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    NodeToIdMap* danglingMap = 0;
6935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (true) {
6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node* parent = innerParentNode(node);
6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!parent) {
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Node being pushed is detached -> push subtree root.
698f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            OwnPtrWillBeRawPtr<NodeToIdMap> newMap = adoptPtrWillBeNoop(new NodeToIdMap);
6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            danglingMap = newMap.get();
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_danglingNodeToIdMaps.append(newMap.release());
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = TypeBuilder::Array<TypeBuilder::DOM::Node>::create();
7025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            children->addItem(buildObjectForNode(node, 0, danglingMap));
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_frontend->setChildNodes(0, children);
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            path.append(parent);
707f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            if (m_documentNodeToIdMap->get(parent))
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
709f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            node = parent;
7105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
713f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    NodeToIdMap* map = danglingMap ? danglingMap : m_documentNodeToIdMap.get();
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (int i = path.size() - 1; i >= 0; --i) {
715197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        int nodeId = map->get(path.at(i).get());
7165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(nodeId);
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pushChildNodesToFrontend(nodeId);
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return map->get(nodeToPush);
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int InspectorDOMAgent::boundNodeId(Node* node)
7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
724f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    return m_documentNodeToIdMap->get(node);
7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::setAttributeValue(ErrorString* errorString, int elementId, const String& name, const String& value)
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* element = assertEditableElement(errorString, elementId);
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!element)
7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_domEditor->setAttribute(element, name, value, errorString);
7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::setAttributesAsText(ErrorString* errorString, int elementId, const String& text, const String* const name)
7375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* element = assertEditableElement(errorString, elementId);
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!element)
7405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
742e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    String markup = "<span " + text + "></span>";
743d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<DocumentFragment> fragment = element->document().createDocumentFragment();
744521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
7458abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    bool shouldIgnoreCase = element->document().isHTMLDocument() && element->isHTMLElement();
746521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // Not all elements can represent the context (i.e. IFRAME), hence using document.body.
7478abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (shouldIgnoreCase && element->document().body())
74809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        fragment->parseHTML(markup, element->document().body(), AllowScriptingContent);
749521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    else
75009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        fragment->parseXML(markup, 0, AllowScriptingContent);
7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
752e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    Element* parsedElement = fragment->firstChild() && fragment->firstChild()->isElementNode() ? toElement(fragment->firstChild()) : 0;
753e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    if (!parsedElement) {
7545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "Could not parse value as attributes";
7555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
7565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
758e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    String caseAdjustedName = name ? (shouldIgnoreCase ? name->lower() : *name) : String();
759e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)
760c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    AttributeCollection attributes = parsedElement->attributes();
761c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (attributes.isEmpty() && name) {
762e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        m_domEditor->removeAttribute(element, caseAdjustedName, errorString);
7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool foundOriginalAttribute = false;
767e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    AttributeCollection::iterator end = attributes.end();
768e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Add attribute pair
770f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        String attributeName = it->name().toString();
771e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        if (shouldIgnoreCase)
772e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)            attributeName = attributeName.lower();
773e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        foundOriginalAttribute |= name && attributeName == caseAdjustedName;
774f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (!m_domEditor->setAttribute(element, attributeName, it->value(), errorString))
7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!foundOriginalAttribute && name && !name->stripWhiteSpace().isEmpty())
779e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        m_domEditor->removeAttribute(element, caseAdjustedName, errorString);
7805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::removeAttribute(ErrorString* errorString, int elementId, const String& name)
7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* element = assertEditableElement(errorString, elementId);
7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!element)
7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_domEditor->removeAttribute(element, name, errorString);
7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::removeNode(ErrorString* errorString, int nodeId)
7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertEditableNode(errorString, nodeId);
7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ContainerNode* parentNode = node->parentNode();
7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!parentNode) {
7999bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        *errorString = "Cannot remove detached node";
8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_domEditor->removeChild(parentNode, node, errorString);
8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::setNodeName(ErrorString* errorString, int nodeId, const String& tagName, int* newId)
8075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *newId = 0;
8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* oldNode = nodeForId(nodeId);
8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!oldNode || !oldNode->isElementNode())
8125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
81451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    TrackExceptionState exceptionState;
815d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RefPtrWillBeRawPtr<Element> newElem = oldNode->document().createElement(AtomicString(tagName), exceptionState);
81651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Copy over the original node's attributes.
8205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    newElem->cloneAttributesFromElement(*toElement(oldNode));
8215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Copy over the original node's children.
823197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    for (Node* child = oldNode->firstChild(); child; child = oldNode->firstChild()) {
8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!m_domEditor->insertBefore(newElem.get(), child, 0, errorString))
8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Replace the old node with the new node
8295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ContainerNode* parent = oldNode->parentNode();
8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_domEditor->insertBefore(parent, newElem.get(), oldNode->nextSibling(), errorString))
8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_domEditor->removeChild(parent, oldNode, errorString))
8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *newId = pushNodePathToFrontend(newElem.get());
8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_childrenRequested.contains(nodeId))
8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pushChildNodesToFrontend(*newId);
8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::getOuterHTML(ErrorString* errorString, int nodeId, WTF::String* outerHTML)
8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertNode(errorString, nodeId);
8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
8445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *outerHTML = createMarkup(node);
8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const String& outerHTML)
8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!nodeId) {
8528abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        ASSERT(m_document);
8538abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        DOMPatchSupport domPatchSupport(m_domEditor.get(), *m_document.get());
8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        domPatchSupport.patchDocument(outerHTML);
8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertEditableNode(errorString, nodeId);
8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
862926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Document* document = node->isDocumentNode() ? toDocument(node) : node->ownerDocument();
86309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!document || (!document->isHTMLDocument() && !document->isXMLDocument())) {
86453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        *errorString = "Not an HTML/XML document";
8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* newNode = 0;
8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_domEditor->setOuterHTML(node, outerHTML, &newNode, errorString))
8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!newNode) {
8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The only child node has been deleted.
8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int newId = pushNodePathToFrontend(newNode);
8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool childrenRequested = m_childrenRequested.contains(nodeId);
8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (childrenRequested)
8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        pushChildNodesToFrontend(newId);
8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::setNodeValue(ErrorString* errorString, int nodeId, const String& value)
8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertEditableNode(errorString, nodeId);
8875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node->nodeType() != Node::TEXT_NODE) {
8915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "Can only set value of text nodes";
8925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
8935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_domEditor->replaceWholeText(toText(node), value, errorString);
8965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
8975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
898926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorDOMAgent::getEventListenersForNode(ErrorString* errorString, int nodeId, const String* objectGroup, RefPtr<TypeBuilder::Array<TypeBuilder::DOM::EventListener> >& listenersArray)
8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    listenersArray = TypeBuilder::Array<TypeBuilder::DOM::EventListener>::create();
9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertNode(errorString, nodeId);
9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
9035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
9045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<EventListenerInfo> eventInformation;
9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    getEventListeners(node, eventInformation, true);
9065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Get Capturing Listeners (in this order)
9085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    size_t eventInformationLength = eventInformation.size();
9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < eventInformationLength; ++i) {
9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const EventListenerInfo& info = eventInformation[i];
9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const EventListenerVector& vector = info.eventListenerVector;
9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t j = 0; j < vector.size(); ++j) {
9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            const RegisteredEventListener& listener = vector[j];
91409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (listener.useCapture) {
91509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                RefPtr<TypeBuilder::DOM::EventListener> listenerObject = buildObjectForEventListener(listener, info.eventType, info.eventTarget->toNode(), objectGroup);
91609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (listenerObject)
91709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    listenersArray->addItem(listenerObject);
91809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Get Bubbling Listeners (reverse order)
9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = eventInformationLength; i; --i) {
9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const EventListenerInfo& info = eventInformation[i - 1];
9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const EventListenerVector& vector = info.eventListenerVector;
9265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t j = 0; j < vector.size(); ++j) {
9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            const RegisteredEventListener& listener = vector[j];
92809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!listener.useCapture) {
92909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                RefPtr<TypeBuilder::DOM::EventListener> listenerObject = buildObjectForEventListener(listener, info.eventType, info.eventTarget->toNode(), objectGroup);
93009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (listenerObject)
93109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    listenersArray->addItem(listenerObject);
93209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
93709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void InspectorDOMAgent::getEventListeners(EventTarget* target, Vector<EventListenerInfo>& eventInformation, bool includeAncestors)
9385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
9395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The Node's Ancestors including self.
94009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    Vector<EventTarget*> ancestors;
94109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ancestors.append(target);
9425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (includeAncestors) {
94309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Node* node = target->toNode();
94409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (ContainerNode* ancestor = node ? node->parentOrShadowHostNode() : 0; ancestor; ancestor = ancestor->parentOrShadowHostNode())
9455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ancestors.append(ancestor);
9465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Nodes and their Listeners for the concerned event types (order is top to bottom)
9495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = ancestors.size(); i; --i) {
95009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        EventTarget* ancestor = ancestors[i - 1];
95109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Vector<AtomicString> eventTypes = ancestor->eventTypes();
9525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t j = 0; j < eventTypes.size(); ++j) {
9535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            AtomicString& type = eventTypes[j];
9545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            const EventListenerVector& listeners = ancestor->getEventListeners(type);
9555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            EventListenerVector filteredListeners;
9565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            filteredListeners.reserveCapacity(listeners.size());
9575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (size_t k = 0; k < listeners.size(); ++k) {
9585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (listeners[k].listener->type() == EventListener::JSEventListenerType)
9595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    filteredListeners.append(listeners[k]);
9605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
9615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!filteredListeners.isEmpty())
9625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                eventInformation.append(EventListenerInfo(ancestor, type, filteredListeners));
9635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
967c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)static Node* nextNodeWithShadowDOMInMind(const Node& current, const Node* stayWithin, bool includeUserAgentShadowDOM)
968c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
969c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // At first traverse the subtree.
970c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (current.isElementNode()) {
971c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        const Element& element = toElement(current);
972c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ElementShadow* elementShadow = element.shadow();
973c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (elementShadow) {
974c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            ShadowRoot* shadowRoot = elementShadow->youngestShadowRoot();
975c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (shadowRoot) {
976c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                if (shadowRoot->type() == ShadowRoot::AuthorShadowRoot || includeUserAgentShadowDOM)
977c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                    return shadowRoot;
978c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            }
979c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
980c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
981c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (current.hasChildren())
982c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return current.firstChild();
983c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
984c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // Then traverse siblings of the node itself and its ancestors.
985c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    const Node* node = &current;
986c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    do {
987c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (node == stayWithin)
988c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return 0;
989c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (node->isShadowRoot()) {
990c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            const ShadowRoot* shadowRoot = toShadowRoot(node);
991c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (shadowRoot->olderShadowRoot())
992c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                return shadowRoot->olderShadowRoot();
993fdbb120d0a4a87db74bcb608de226c85a7d1c920Ben Murdoch            Node* host = shadowRoot->host();
994fdbb120d0a4a87db74bcb608de226c85a7d1c920Ben Murdoch            if (host && host->hasChildren())
995fdbb120d0a4a87db74bcb608de226c85a7d1c920Ben Murdoch                return host->firstChild();
996c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        }
997c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (node->nextSibling())
998c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return node->nextSibling();
999c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        node = node->isShadowRoot() ? toShadowRoot(node)->host() : node->parentNode();
1000c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    } while (node);
1001c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1002c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return 0;
1003c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
1004c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1005c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrimmedQuery, const bool* optionalIncludeUserAgentShadowDOM, String* searchId, int* resultCount)
10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Few things are missing here:
10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // 1) Search works with node granularity - number of matches within node is not calculated.
10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // 2) There is no need to push all search results to the front-end at a time, pushing next / previous result
10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //    is sufficient.
10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1012c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool includeUserAgentShadowDOM = optionalIncludeUserAgentShadowDOM ? *optionalIncludeUserAgentShadowDOM : false;
1013c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned queryLength = whitespaceTrimmedQuery.length();
10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool startTagFound = !whitespaceTrimmedQuery.find('<');
10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool endTagFound = whitespaceTrimmedQuery.reverseFind('>') + 1 == queryLength;
10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool startQuoteFound = !whitespaceTrimmedQuery.find('"');
10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool endQuoteFound = whitespaceTrimmedQuery.reverseFind('"') + 1 == queryLength;
10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool exactAttributeMatch = startQuoteFound && endQuoteFound;
10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String tagNameQuery = whitespaceTrimmedQuery;
10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String attributeQuery = whitespaceTrimmedQuery;
10235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (startTagFound)
10245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        tagNameQuery = tagNameQuery.right(tagNameQuery.length() - 1);
10255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (endTagFound)
10265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        tagNameQuery = tagNameQuery.left(tagNameQuery.length() - 1);
10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (startQuoteFound)
10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        attributeQuery = attributeQuery.right(attributeQuery.length() - 1);
10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (endQuoteFound)
10305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        attributeQuery = attributeQuery.left(attributeQuery.length() - 1);
10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1032c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    WillBeHeapVector<RawPtrWillBeMember<Document> > docs = documents();
1033197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    WillBeHeapListHashSet<RawPtrWillBeMember<Node> > resultCollector;
10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1035c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    for (WillBeHeapVector<RawPtrWillBeMember<Document> >::iterator it = docs.begin(); it != docs.end(); ++it) {
10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Document* document = *it;
1037c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        Node* documentElement = document->documentElement();
1038c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        Node* node = documentElement;
10395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!node)
10405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Manual plain text search.
1043c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        for (node = nextNodeWithShadowDOMInMind(*node, documentElement, includeUserAgentShadowDOM); node; node = nextNodeWithShadowDOMInMind(*node, documentElement, includeUserAgentShadowDOM)) {
10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            switch (node->nodeType()) {
10455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            case Node::TEXT_NODE:
10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            case Node::COMMENT_NODE:
10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            case Node::CDATA_SECTION_NODE: {
10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                String text = node->nodeValue();
104906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                if (text.findIgnoringCase(whitespaceTrimmedQuery) != kNotFound)
10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    resultCollector.add(node);
10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            case Node::ELEMENT_NODE: {
105406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                if ((!startTagFound && !endTagFound && (node->nodeName().findIgnoringCase(tagNameQuery) != kNotFound))
1055926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    || (startTagFound && endTagFound && equalIgnoringCase(node->nodeName(), tagNameQuery))
1056926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    || (startTagFound && !endTagFound && node->nodeName().startsWith(tagNameQuery, false))
1057926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    || (!startTagFound && endTagFound && node->nodeName().endsWith(tagNameQuery, false))) {
10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    resultCollector.add(node);
10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    break;
10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Go through all attributes and serialize them.
10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                const Element* element = toElement(node);
106376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)                AttributeCollection attributes = element->attributes();
1064e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                AttributeCollection::iterator end = attributes.end();
1065e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // Add attribute pair
1067f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                    if (it->localName().find(whitespaceTrimmedQuery, 0, false) != kNotFound) {
10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        resultCollector.add(node);
10695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        break;
10705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
1071f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                    size_t foundPosition = it->value().find(attributeQuery, 0, false);
107206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    if (foundPosition != kNotFound) {
1073f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                        if (!exactAttributeMatch || (!foundPosition && it->value().length() == attributeQuery.length())) {
10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            resultCollector.add(node);
10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            break;
10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        }
10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            default:
10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
10835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // XPath evaluation
1087c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        for (WillBeHeapVector<RawPtrWillBeMember<Document> >::iterator it = docs.begin(); it != docs.end(); ++it) {
10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            Document* document = *it;
1089d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            ASSERT(document);
109051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            TrackExceptionState exceptionState;
1091d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            RefPtrWillBeRawPtr<XPathResult> result = DocumentXPathEvaluator::evaluate(*document, whitespaceTrimmedQuery, document, nullptr, XPathResult::ORDERED_NODE_SNAPSHOT_TYPE, 0, exceptionState);
109251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (exceptionState.hadException() || !result)
10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
109551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            unsigned long size = result->snapshotLength(exceptionState);
109651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            for (unsigned long i = 0; !exceptionState.hadException() && i < size; ++i) {
109751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                Node* node = result->snapshotItem(i, exceptionState);
109851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (exceptionState.hadException())
10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    break;
11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (node->nodeType() == Node::ATTRIBUTE_NODE)
1102591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch                    node = toAttr(node)->ownerElement();
11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                resultCollector.add(node);
11045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
11065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Selector evaluation
1108c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        for (WillBeHeapVector<RawPtrWillBeMember<Document> >::iterator it = docs.begin(); it != docs.end(); ++it) {
11095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            Document* document = *it;
111051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            TrackExceptionState exceptionState;
1111e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            RefPtrWillBeRawPtr<StaticElementList> elementList = document->querySelectorAll(AtomicString(whitespaceTrimmedQuery), exceptionState);
1112e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            if (exceptionState.hadException() || !elementList)
11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1115e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            unsigned size = elementList->length();
11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (unsigned i = 0; i < size; ++i)
1117e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                resultCollector.add(elementList->item(i));
11185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
11195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *searchId = IdentifiersFactory::createIdentifier();
1122f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    WillBeHeapVector<RefPtrWillBeMember<Node> >* resultsIt = &m_searchResults.add(*searchId, WillBeHeapVector<RefPtrWillBeMember<Node> >()).storedValue->value;
11235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1124197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    for (WillBeHeapListHashSet<RawPtrWillBeMember<Node> >::iterator it = resultCollector.begin(); it != resultCollector.end(); ++it)
112509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        resultsIt->append(*it);
11265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
112709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    *resultCount = resultsIt->size();
11285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::getSearchResults(ErrorString* errorString, const String& searchId, int fromIndex, int toIndex, RefPtr<TypeBuilder::Array<int> >& nodeIds)
11315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SearchResults::iterator it = m_searchResults.find(searchId);
11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (it == m_searchResults.end()) {
11345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "No search session with given id found";
11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int size = it->value.size();
11395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (fromIndex < 0 || toIndex > size || fromIndex >= toIndex) {
11405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "Invalid search result range";
11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    nodeIds = TypeBuilder::Array<int>::create();
11455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (int i = fromIndex; i < toIndex; ++i)
11465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nodeIds->addItem(pushNodePathToFrontend((it->value)[i].get()));
11475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::discardSearchResults(ErrorString*, const String& searchId)
11505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_searchResults.remove(searchId);
11525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorDOMAgent::handleMousePress()
11555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1156e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (m_searchingForNode == NotSearching)
11575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
11585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (Node* node = m_overlay->highlightedNode()) {
11605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        inspect(node);
11615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
11625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1166d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool InspectorDOMAgent::handleGestureEvent(LocalFrame* frame, const PlatformGestureEvent& event)
1167e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
1168e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (m_searchingForNode == NotSearching || event.type() != PlatformEvent::GestureTap)
1169e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        return false;
1170e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    Node* node = hoveredNodeForEvent(frame, event, false);
1171e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    if (node && m_inspectModeHighlightConfig) {
117210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        m_overlay->highlightNode(node, 0 /* eventTarget */, *m_inspectModeHighlightConfig, false);
1173e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        inspect(node);
1174e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        return true;
1175e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
1176e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return false;
1177e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
1178e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
1179d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool InspectorDOMAgent::handleTouchEvent(LocalFrame* frame, const PlatformTouchEvent& event)
11805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1181e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (m_searchingForNode == NotSearching)
11825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
118353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Node* node = hoveredNodeForEvent(frame, event, false);
11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node && m_inspectModeHighlightConfig) {
118510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        m_overlay->highlightNode(node, 0 /* eventTarget */, *m_inspectModeHighlightConfig, false);
11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        inspect(node);
11875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
11885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::inspect(Node* inspectedNode)
11935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11945267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (!m_frontend || !inspectedNode)
11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
119753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Node* node = inspectedNode;
1198f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    while (node && !node->isElementNode() && !node->isDocumentNode() && !node->isDocumentFragment())
119943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        node = node->parentOrShadowHostNode();
120043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
120143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    if (!node)
120243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        return;
12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
120453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    int nodeId = pushNodePathToFrontend(node);
120553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (nodeId)
120653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        m_frontend->inspectNodeRequested(nodeId);
12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1209c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool InspectorDOMAgent::handleMouseMove(LocalFrame* frame, const PlatformMouseEvent& event)
12105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1211e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (m_searchingForNode == NotSearching)
1212c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return false;
12135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
121453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!frame->view() || !frame->contentRenderer())
1215c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return true;
121653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Node* node = hoveredNodeForEvent(frame, event, event.shiftKey());
1217e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
121843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    // Do not highlight within UA shadow root unless requested.
121943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    if (m_searchingForNode != SearchingForUAShadow) {
122043e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        ShadowRoot* uaShadowRoot = userAgentShadowRoot(node);
122143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        if (uaShadowRoot)
122243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            node = uaShadowRoot->host();
122343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    }
122443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
122543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    // Shadow roots don't have boxes - use host element instead.
122643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    if (node && node->isShadowRoot())
1227e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        node = node->parentOrShadowHostNode();
1228e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
122943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    if (!node)
1230c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return true;
123143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)
123253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    Node* eventTarget = event.shiftKey() ? hoveredNodeForEvent(frame, event, false) : 0;
123353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (eventTarget == node)
123453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        eventTarget = 0;
123553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
12365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node && m_inspectModeHighlightConfig)
123710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        m_overlay->highlightNode(node, eventTarget, *m_inspectModeHighlightConfig, event.ctrlKey() || event.metaKey());
1238c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return true;
12395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1241e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochvoid InspectorDOMAgent::setSearchingForNode(ErrorString* errorString, SearchMode searchMode, JSONObject* highlightInspectorObject)
12425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1243e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (m_searchingForNode == searchMode)
12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
12451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1246e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    m_searchingForNode = searchMode;
1247e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    m_overlay->setInspectModeEnabled(searchMode != NotSearching);
1248e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (searchMode != NotSearching) {
12495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_inspectModeHighlightConfig = highlightConfigFromInspectorObject(errorString, highlightInspectorObject);
12505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!m_inspectModeHighlightConfig)
12515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
12525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
12535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        hideHighlight(errorString);
12545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1256591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochPassOwnPtr<HighlightConfig> InspectorDOMAgent::highlightConfigFromInspectorObject(ErrorString* errorString, JSONObject* highlightInspectorObject)
12575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!highlightInspectorObject) {
12595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *errorString = "Internal error: highlight configuration parameter is missing";
12605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return nullptr;
12615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
12625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
12635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
12645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool showInfo = false; // Default: false (do not show a tooltip).
12655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightInspectorObject->getBoolean("showInfo", &showInfo);
12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightConfig->showInfo = showInfo;
12675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool showRulers = false; // Default: false (do not show rulers).
12685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightInspectorObject->getBoolean("showRulers", &showRulers);
12695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightConfig->showRulers = showRulers;
1270197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    bool showExtensionLines = false; // Default: false (do not show extension lines).
1271197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    highlightInspectorObject->getBoolean("showExtensionLines", &showExtensionLines);
1272197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    highlightConfig->showExtensionLines = showExtensionLines;
12735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightConfig->content = parseConfigColor("contentColor", highlightInspectorObject);
12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightConfig->contentOutline = parseConfigColor("contentOutlineColor", highlightInspectorObject);
12755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightConfig->padding = parseConfigColor("paddingColor", highlightInspectorObject);
12765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightConfig->border = parseConfigColor("borderColor", highlightInspectorObject);
12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightConfig->margin = parseConfigColor("marginColor", highlightInspectorObject);
127853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    highlightConfig->eventTarget = parseConfigColor("eventTargetColor", highlightInspectorObject);
1279c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    highlightConfig->shape = parseConfigColor("shapeColor", highlightInspectorObject);
1280c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    highlightConfig->shapeMargin = parseConfigColor("shapeMarginColor", highlightInspectorObject);
1281c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
12825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return highlightConfig.release();
12835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
128543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)void InspectorDOMAgent::setInspectModeEnabled(ErrorString* errorString, bool enabled, const bool* inspectUAShadowDOM, const RefPtr<JSONObject>* highlightConfig)
12865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
12871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (enabled && !pushDocumentUponHandlelessOperation(errorString))
12881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return;
1289c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    SearchMode searchMode = enabled ? (asBool(inspectUAShadowDOM) ? SearchingForUAShadow : SearchingForNormal) : NotSearching;
1290e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    setSearchingForNode(errorString, searchMode, highlightConfig ? highlightConfig->get() : 0);
12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1293591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid InspectorDOMAgent::highlightRect(ErrorString*, int x, int y, int width, int height, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor)
12945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
129553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    OwnPtr<FloatQuad> quad = adoptPtr(new FloatQuad(FloatRect(x, y, width, height)));
129653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    innerHighlightQuad(quad.release(), color, outlineColor);
129753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
129853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1299591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid InspectorDOMAgent::highlightQuad(ErrorString* errorString, const RefPtr<JSONArray>& quadArray, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor)
130053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
130153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    OwnPtr<FloatQuad> quad = adoptPtr(new FloatQuad());
130253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    if (!parseQuad(quadArray, quad.get())) {
130353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        *errorString = "Invalid Quad format";
130453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        return;
130553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    }
130653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    innerHighlightQuad(quad.release(), color, outlineColor);
130753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)}
130853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
1309591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid InspectorDOMAgent::innerHighlightQuad(PassOwnPtr<FloatQuad> quad, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor)
131053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){
13115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
13125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightConfig->content = parseColor(color);
13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    highlightConfig->contentOutline = parseColor(outlineColor);
131453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)    m_overlay->highlightQuad(quad, *highlightConfig);
13155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1317591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid InspectorDOMAgent::highlightNode(ErrorString* errorString, const RefPtr<JSONObject>& highlightInspectorObject, const int* nodeId, const String* objectId)
13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1319926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Node* node = 0;
1320926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (nodeId) {
1321926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        node = assertNode(errorString, *nodeId);
1322926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    } else if (objectId) {
1323926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(*objectId);
1324926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        node = injectedScript.nodeForObjectId(*objectId);
1325926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!node)
1326926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            *errorString = "Node for given objectId not found";
1327926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    } else
1328926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        *errorString = "Either nodeId or objectId must be specified";
1329926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
13305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
13315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
13325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    OwnPtr<HighlightConfig> highlightConfig = highlightConfigFromInspectorObject(errorString, highlightInspectorObject.get());
13345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!highlightConfig)
13355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
13365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
133710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_overlay->highlightNode(node, 0 /* eventTarget */, *highlightConfig, false);
13385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::highlightFrame(
13415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ErrorString*,
13425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const String& frameId,
1343591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    const RefPtr<JSONObject>* color,
1344591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    const RefPtr<JSONObject>* outlineColor)
13455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1346d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    LocalFrame* frame = m_pageAgent->frameForId(frameId);
1347f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    // FIXME: Inspector doesn't currently work cross process.
1348f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (frame && frame->deprecatedLocalOwner()) {
13495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
13505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        highlightConfig->showInfo = true; // Always show tooltips for frames.
13515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        highlightConfig->content = parseColor(color);
13525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        highlightConfig->contentOutline = parseColor(outlineColor);
1353f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_overlay->highlightNode(frame->deprecatedLocalOwner(), 0 /* eventTarget */, *highlightConfig, false);
13545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
13555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::hideHighlight(ErrorString*)
13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_overlay->hideHighlight();
13605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
13615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1362c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void InspectorDOMAgent::copyTo(ErrorString* errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId)
13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
13645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = assertEditableNode(errorString, nodeId);
13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
13665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* targetElement = assertEditableElement(errorString, targetElementId);
13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!targetElement)
13705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* anchorNode = 0;
13735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (anchorNodeId && *anchorNodeId) {
1374c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        anchorNode = assertEditableChildNode(errorString, targetElement, *anchorNodeId);
13755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!anchorNode)
13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
1377c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
1378c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1379c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // The clone is deep by default.
1380c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefPtrWillBeRawPtr<Node> clonedNode = node->cloneNode(true);
1381c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!clonedNode) {
1382c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        *errorString = "Failed to clone node";
1383c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return;
1384c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
1385c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!m_domEditor->insertBefore(targetElement, clonedNode, anchorNode, errorString))
1386c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return;
1387c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1388c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    *newNodeId = pushNodePathToFrontend(clonedNode.get());
1389c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
1390c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1391c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void InspectorDOMAgent::moveTo(ErrorString* errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId)
1392c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
1393c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Node* node = assertEditableNode(errorString, nodeId);
1394c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!node)
1395c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return;
1396c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1397c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Element* targetElement = assertEditableElement(errorString, targetElementId);
1398c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!targetElement)
1399c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        return;
1400c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1401c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Node* current = targetElement;
1402c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    while (current) {
1403c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (current == node) {
1404c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            *errorString = "Unable to move node into self or descendant";
14055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
14065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1407c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        current = current->parentNode();
1408c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
1409c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
1410c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    Node* anchorNode = 0;
1411c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (anchorNodeId && *anchorNodeId) {
1412c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        anchorNode = assertEditableChildNode(errorString, targetElement, *anchorNodeId);
1413c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (!anchorNode)
1414c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            return;
14155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_domEditor->insertBefore(targetElement, node, anchorNode, errorString))
14185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
14195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    *newNodeId = pushNodePathToFrontend(node);
14215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::undo(ErrorString* errorString)
14245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
142551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    TrackExceptionState exceptionState;
142651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_history->undo(exceptionState);
142751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    *errorString = InspectorDOMAgent::toErrorString(exceptionState);
14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::redo(ErrorString* errorString)
14315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
143251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    TrackExceptionState exceptionState;
143351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_history->redo(exceptionState);
143451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    *errorString = InspectorDOMAgent::toErrorString(exceptionState);
14355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::markUndoableState(ErrorString*)
14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
14395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_history->markUndoableState();
14405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
14415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1442926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorDOMAgent::focus(ErrorString* errorString, int nodeId)
1443926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1444926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Element* element = assertElement(errorString, nodeId);
1445926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!element)
1446926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
144709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
144809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    element->document().updateLayoutIgnorePendingStylesheets();
1449926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!element->isFocusable()) {
1450926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        *errorString = "Element is not focusable";
1451926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
1452926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1453926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    element->focus();
1454926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
1455926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1456591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid InspectorDOMAgent::setFileInputFiles(ErrorString* errorString, int nodeId, const RefPtr<JSONArray>& files)
1457926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
1458926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Node* node = assertNode(errorString, nodeId);
1459926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!node)
1460926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
14617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!isHTMLInputElement(*node) || toHTMLInputElement(*node).type() != InputTypeNames::file) {
1462926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        *errorString = "Node is not a file input element";
1463926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
1464926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1465926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1466d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtrWillBeRawPtr<FileList> fileList = FileList::create();
1467591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    for (JSONArray::const_iterator iter = files->begin(); iter != files->end(); ++iter) {
1468926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        String path;
1469926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!(*iter)->asString(&path)) {
1470926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            *errorString = "Files must be strings";
1471926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return;
1472926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1473926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        fileList->append(File::create(path));
1474926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
1475521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    toHTMLInputElement(node)->setFiles(fileList);
1476926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
1477926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1478c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)void InspectorDOMAgent::getBoxModel(ErrorString* errorString, int nodeId, RefPtr<TypeBuilder::DOM::BoxModel>& model)
1479c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles){
1480c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    Node* node = assertNode(errorString, nodeId);
1481c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (!node)
1482c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        return;
1483c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
1484c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool result = m_overlay->getBoxModel(node, model);
1485c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!result)
1486c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        *errorString = "Could not compute box model.";
1487c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
14888abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
14898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
14908abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)void InspectorDOMAgent::getNodeForLocation(ErrorString* errorString, int x, int y, int* nodeId)
14918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){
14921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (!pushDocumentUponHandlelessOperation(errorString))
14931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return;
1494197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HitTestRequest request(HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::AllowChildFrameContent);
1495197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    HitTestResult result(IntPoint(x, y));
1496197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_document->frame()->contentRenderer()->hitTest(request, result);
1497197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Node* node = result.innerPossiblyPseudoNode();
1498197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    while (node && node->nodeType() == Node::TEXT_NODE)
1499197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        node = node->parentNode();
15008abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (!node) {
15018abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        *errorString = "No node found at given location";
15028abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        return;
15038abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
15048abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    *nodeId = pushNodePathToFrontend(node);
1505c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)}
1506c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)
1507926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorDOMAgent::resolveNode(ErrorString* errorString, int nodeId, const String* const objectGroup, RefPtr<TypeBuilder::Runtime::RemoteObject>& result)
15085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String objectGroupName = objectGroup ? *objectGroup : "";
15105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = nodeForId(nodeId);
15115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node) {
1512926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        *errorString = "No node with given id found";
15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
15145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::Runtime::RemoteObject> object = resolveNode(node, objectGroupName);
15165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!object) {
1517926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        *errorString = "Node with given id does not belong to the document";
15185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result = object;
15215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::getAttributes(ErrorString* errorString, int nodeId, RefPtr<TypeBuilder::Array<String> >& result)
15245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* element = assertElement(errorString, nodeId);
15265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!element)
15275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
15285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result = buildArrayForElementAttributes(element);
15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::requestNode(ErrorString*, const String& objectId, int* nodeId)
15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = injectedScript.nodeForObjectId(objectId);
15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node)
15375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *nodeId = pushNodePathToFrontend(node);
15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *nodeId = 0;
15405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// static
15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String InspectorDOMAgent::documentURLString(Document* document)
15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!document || document->url().isNull())
15465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return "";
15475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return document->url().string();
15485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static String documentBaseURLString(Document* document)
15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return document->completeURL("").string();
15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
15545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
155551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static TypeBuilder::DOM::ShadowRootType::Enum shadowRootType(ShadowRoot* shadowRoot)
155651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
155751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    switch (shadowRoot->type()) {
155851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case ShadowRoot::UserAgentShadowRoot:
155951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return TypeBuilder::DOM::ShadowRootType::User_agent;
156051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case ShadowRoot::AuthorShadowRoot:
156151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return TypeBuilder::DOM::ShadowRootType::Author;
156251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
156351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT_NOT_REACHED();
156451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return TypeBuilder::DOM::ShadowRootType::User_agent;
156551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
156651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
15675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap)
15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
15695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int id = bind(node, nodesMap);
15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String nodeName;
15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String localName;
15725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String nodeValue;
15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (node->nodeType()) {
15755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case Node::TEXT_NODE:
15765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case Node::COMMENT_NODE:
15775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case Node::CDATA_SECTION_NODE:
15785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nodeValue = node->nodeValue();
157909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (nodeValue.length() > maxTextSize)
158009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            nodeValue = nodeValue.left(maxTextSize) + ellipsisUChar;
15815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
15825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case Node::ATTRIBUTE_NODE:
15835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        localName = node->localName();
15845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
15855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case Node::DOCUMENT_FRAGMENT_NODE:
15865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case Node::DOCUMENT_NODE:
15875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case Node::ELEMENT_NODE:
15885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
15895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nodeName = node->nodeName();
15905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        localName = node->localName();
15915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
15925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
15935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::DOM::Node> value = TypeBuilder::DOM::Node::create()
15955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setNodeId(id)
15965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setNodeType(static_cast<int>(node->nodeType()))
15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setNodeName(nodeName)
15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setLocalName(localName)
15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setNodeValue(nodeValue);
16005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16015267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    bool forcePushChildren = false;
16025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node->isElementNode()) {
1603926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        Element* element = toElement(node);
16045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value->setAttributes(buildArrayForElementAttributes(element));
160509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
16065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (node->isFrameOwnerElement()) {
1607e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(node);
160807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            LocalFrame* frame = (frameOwner->contentFrame() && frameOwner->contentFrame()->isLocalFrame()) ? toLocalFrame(frameOwner->contentFrame()) : 0;
160907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            if (frame)
1610926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                value->setFrameId(m_pageAgent->frameId(frame));
1611e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            if (Document* doc = frameOwner->contentDocument())
16125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                value->setContentDocument(buildObjectForNode(doc, 0, nodesMap));
16135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
16145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ElementShadow* shadow = element->shadow();
16165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (shadow) {
16175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > shadowRoots = TypeBuilder::Array<TypeBuilder::DOM::Node>::create();
16185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (ShadowRoot* root = shadow->youngestShadowRoot(); root; root = root->olderShadowRoot())
16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                shadowRoots->addItem(buildObjectForNode(root, 0, nodesMap));
16205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            value->setShadowRoots(shadowRoots);
16215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            forcePushChildren = true;
16225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1623926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1624d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (isHTMLLinkElement(*element)) {
1625d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            HTMLLinkElement& linkElement = toHTMLLinkElement(*element);
1626d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (linkElement.isImport() && linkElement.import() && innerParentNode(linkElement.import()) == linkElement)
1627d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                value->setImportedDocument(buildObjectForNode(linkElement.import(), 0, nodesMap));
162809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            forcePushChildren = true;
162909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
163009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
1631d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (isHTMLTemplateElement(*element)) {
1632d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            value->setTemplateContent(buildObjectForNode(toHTMLTemplateElement(*element).content(), 0, nodesMap));
16335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            forcePushChildren = true;
16345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        }
16359bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
16369bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        switch (element->pseudoId()) {
16379bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        case BEFORE:
16389bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            value->setPseudoType(TypeBuilder::DOM::PseudoType::Before);
16399bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            break;
16409bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        case AFTER:
16419bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            value->setPseudoType(TypeBuilder::DOM::PseudoType::After);
16429bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            break;
16439bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        default: {
16449bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > pseudoElements = buildArrayForPseudoElements(element, nodesMap);
16459bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            if (pseudoElements) {
16469bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                value->setPseudoElements(pseudoElements.release());
16479bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                forcePushChildren = true;
16489bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            }
16499bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)            break;
16509bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        }
16519bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        }
16525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else if (node->isDocumentNode()) {
1653926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        Document* document = toDocument(node);
16545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value->setDocumentURL(documentURLString(document));
16555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value->setBaseURL(documentBaseURLString(document));
16565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value->setXmlVersion(document->xmlVersion());
165709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    } else if (node->isDocumentTypeNode()) {
16588abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        DocumentType* docType = toDocumentType(node);
16595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value->setPublicId(docType->publicId());
16605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value->setSystemId(docType->systemId());
16615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else if (node->isAttributeNode()) {
1662591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        Attr* attribute = toAttr(node);
16635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value->setName(attribute->name());
16645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        value->setValue(attribute->value());
166551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    } else if (node->isShadowRoot()) {
166651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        value->setShadowRootType(shadowRootType(toShadowRoot(node)));
16675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
16685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
16695267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (node->isContainerNode()) {
16705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        int nodeCount = innerChildNodeCount(node);
16715267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        value->setChildNodeCount(nodeCount);
1672f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (nodesMap == m_documentNodeToIdMap)
1673d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            m_cachedChildCount.set(id, nodeCount);
16745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (forcePushChildren && !depth)
16755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            depth = 1;
16765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = buildArrayForContainerChildren(node, depth, nodesMap);
16775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (children->length() > 0 || depth) // Push children along with shadow in any case.
16785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            value->setChildren(children.release());
16795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
16805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
16815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return value.release();
16825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<TypeBuilder::Array<String> > InspectorDOMAgent::buildArrayForElementAttributes(Element* element)
16855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
16865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::Array<String> > attributesValue = TypeBuilder::Array<String>::create();
16875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Go through all attributes and serialize them.
168876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    AttributeCollection attributes = element->attributes();
1689e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    AttributeCollection::iterator end = attributes.end();
1690e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
16915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Add attribute pair
1692f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        attributesValue->addItem(it->name().toString());
1693f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        attributesValue->addItem(it->value());
16945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
16955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return attributesValue.release();
16965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
16975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > InspectorDOMAgent::buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap)
16995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = TypeBuilder::Array<TypeBuilder::DOM::Node>::create();
17015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (depth == 0) {
17025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Special-case the only text child - pretend that container's children have been requested.
17035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node* firstChild = container->firstChild();
17045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (firstChild && firstChild->nodeType() == Node::TEXT_NODE && !firstChild->nextSibling()) {
17055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            children->addItem(buildObjectForNode(firstChild, 0, nodesMap));
17065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_childrenRequested.add(bind(container, nodesMap));
17075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
17085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return children.release();
17095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
17105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* child = innerFirstChild(container);
17125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    depth--;
17135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_childrenRequested.add(bind(container, nodesMap));
17145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (child) {
17165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        children->addItem(buildObjectForNode(child, depth, nodesMap));
17175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        child = innerNextSibling(child);
17185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
17195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return children.release();
17205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1722926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)PassRefPtr<TypeBuilder::DOM::EventListener> InspectorDOMAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node, const String* objectGroupId)
17235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<EventListener> eventListener = registeredEventListener.listener;
172509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    String sourceName;
172609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    String scriptId;
172709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    int lineNumber;
17287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    int columnNumber;
17297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!eventListenerHandlerLocation(&node->document(), eventListener.get(), sourceName, scriptId, lineNumber, columnNumber))
1730d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
173109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
17328abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    Document& document = node->document();
173309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create()
173409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        .setScriptId(scriptId)
173509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        .setLineNumber(lineNumber);
17367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    location->setColumnNumber(columnNumber);
17375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::DOM::EventListener> value = TypeBuilder::DOM::EventListener::create()
17385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setType(eventType)
17395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setUseCapture(registeredEventListener.useCapture)
17405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setIsAttribute(eventListener->isAttribute())
17415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        .setNodeId(pushNodePathToFrontend(node))
174209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        .setHandlerBody(eventListenerHandlerBody(&document, eventListener.get()))
174309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        .setLocation(location);
1744926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (objectGroupId) {
17458abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        ScriptValue functionValue = eventListenerHandler(&document, eventListener.get());
174610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        if (!functionValue.isEmpty()) {
1747d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            LocalFrame* frame = document.frame();
1748926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (frame) {
1749926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                ScriptState* scriptState = eventListenerHandlerScriptState(frame, eventListener.get());
1750926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (scriptState) {
1751926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
175210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                    if (!injectedScript.isEmpty()) {
1753926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        RefPtr<TypeBuilder::Runtime::RemoteObject> valueJson = injectedScript.wrapObject(functionValue, *objectGroupId);
1754926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        value->setHandler(valueJson);
1755926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    }
1756926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                }
1757926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
1758926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1759926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
176009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!sourceName.isEmpty())
176109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        value->setSourceName(sourceName);
17625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return value.release();
17635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17659bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)PassRefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > InspectorDOMAgent::buildArrayForPseudoElements(Element* element, NodeToIdMap* nodesMap)
17669bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
17679bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (!element->pseudoElement(BEFORE) && !element->pseudoElement(AFTER))
1768d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
17699bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
17709bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > pseudoElements = TypeBuilder::Array<TypeBuilder::DOM::Node>::create();
17719bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (element->pseudoElement(BEFORE))
17729bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        pseudoElements->addItem(buildObjectForNode(element->pseudoElement(BEFORE), 0, nodesMap));
17739bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (element->pseudoElement(AFTER))
17749bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        pseudoElements->addItem(buildObjectForNode(element->pseudoElement(AFTER), 0, nodesMap));
17759bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    return pseudoElements.release();
17769bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)}
17779bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
17785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* InspectorDOMAgent::innerFirstChild(Node* node)
17795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    node = node->firstChild();
17815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (isWhitespace(node))
17825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        node = node->nextSibling();
17835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node;
17845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* InspectorDOMAgent::innerNextSibling(Node* node)
17875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    do {
17895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        node = node->nextSibling();
17905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } while (isWhitespace(node));
17915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node;
17925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
17935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* InspectorDOMAgent::innerPreviousSibling(Node* node)
17955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
17965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    do {
17975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        node = node->previousSibling();
17985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } while (isWhitespace(node));
17995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node;
18005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned InspectorDOMAgent::innerChildNodeCount(Node* node)
18035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned count = 0;
18055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* child = innerFirstChild(node);
18065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (child) {
18075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        count++;
18085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        child = innerNextSibling(child);
18095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
18105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return count;
18115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node* InspectorDOMAgent::innerParentNode(Node* node)
18145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (node->isDocumentNode()) {
1816926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        Document* document = toDocument(node);
18176f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        if (HTMLImportLoader* loader = document->importLoader())
18186f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch            return loader->firstImport()->link();
18195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return document->ownerElement();
18205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
18215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return node->parentOrShadowHostNode();
18225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorDOMAgent::isWhitespace(Node* node)
18255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //TODO: pull ignoreWhitespace setting from the frontend and use here.
18275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return node && node->nodeType() == Node::TEXT_NODE && node->nodeValue().stripWhiteSpace().length() == 0;
18285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1830d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void InspectorDOMAgent::domContentLoadedEventFired(LocalFrame* frame)
18315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
183209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!frame->isMainFrame())
183393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
183493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
18355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Re-push document once it is loaded.
1836e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    discardFrontendBindings();
1837f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (enabled())
18385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_frontend->documentUpdated();
18395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1841d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void InspectorDOMAgent::invalidateFrameOwnerElement(LocalFrame* frame)
18425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18439e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    HTMLFrameOwnerElement* frameOwner = frame->document()->ownerElement();
18445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!frameOwner)
18455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
18465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1847f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int frameOwnerId = m_documentNodeToIdMap->get(frameOwner);
18485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!frameOwnerId)
18495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
18505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Re-add frame owner element together with its new children.
1852f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int parentId = m_documentNodeToIdMap->get(innerParentNode(frameOwner));
18535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_frontend->childNodeRemoved(parentId, frameOwnerId);
1854f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    unbind(frameOwner, m_documentNodeToIdMap.get());
18555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1856f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtr<TypeBuilder::DOM::Node> value = buildObjectForNode(frameOwner, 0, m_documentNodeToIdMap.get());
18575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* previousSibling = innerPreviousSibling(frameOwner);
1858f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int prevId = previousSibling ? m_documentNodeToIdMap->get(previousSibling) : 0;
18595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_frontend->childNodeInserted(parentId, prevId, value.release());
18605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
18615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1862d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void InspectorDOMAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
186393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
186409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // FIXME: If "frame" is always guarenteed to be in the same Page as loader->frame()
186509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // then all we need to check here is loader->frame()->isMainFrame()
186609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // and we don't need "frame" at all.
18675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!frame->page()->mainFrame()->isLocalFrame())
18685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return;
18695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    LocalFrame* mainFrame = frame->page()->deprecatedLocalMainFrame();
1870bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    if (loader->frame() != mainFrame) {
1871bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        invalidateFrameOwnerElement(loader->frame());
187293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
1873bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
187493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
187593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    setDocument(mainFrame->document());
187693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
187793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
18785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::didInsertDOMNode(Node* node)
18795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
18805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isWhitespace(node))
18815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
18825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We could be attaching existing subtree. Forget the bindings.
1884f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    unbind(node, m_documentNodeToIdMap.get());
18855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ContainerNode* parent = node->parentNode();
18875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!parent)
18885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1889f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int parentId = m_documentNodeToIdMap->get(parent);
18905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Return if parent is not mapped yet.
18915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!parentId)
18925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
18935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_childrenRequested.contains(parentId)) {
1895d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // No children are mapped yet -> only notify on changes of child count.
1896d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        int count = m_cachedChildCount.get(parentId) + 1;
1897d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_cachedChildCount.set(parentId, count);
1898d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_frontend->childNodeCountUpdated(parentId, count);
18995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
19005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Children have been requested -> return value of a new child.
19015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node* prevSibling = innerPreviousSibling(node);
1902f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        int prevId = prevSibling ? m_documentNodeToIdMap->get(prevSibling) : 0;
1903f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        RefPtr<TypeBuilder::DOM::Node> value = buildObjectForNode(node, 0, m_documentNodeToIdMap.get());
19045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_frontend->childNodeInserted(parentId, prevId, value.release());
19055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
19065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
190893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void InspectorDOMAgent::willRemoveDOMNode(Node* node)
19095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
19105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isWhitespace(node))
19115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
19125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ContainerNode* parent = node->parentNode();
19145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If parent is not mapped yet -> ignore the event.
1916f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (!m_documentNodeToIdMap->contains(parent))
19175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
19185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1919f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int parentId = m_documentNodeToIdMap->get(parent);
19205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_childrenRequested.contains(parentId)) {
1922d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // No children are mapped yet -> only notify on changes of child count.
1923d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        int count = m_cachedChildCount.get(parentId) - 1;
1924d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_cachedChildCount.set(parentId, count);
1925d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_frontend->childNodeCountUpdated(parentId, count);
1926d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else {
1927f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_frontend->childNodeRemoved(parentId, m_documentNodeToIdMap->get(node));
1928d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
1929f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    unbind(node, m_documentNodeToIdMap.get());
19305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::willModifyDOMAttr(Element*, const AtomicString& oldValue, const AtomicString& newValue)
19335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
19345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_suppressAttributeModifiedEvent = (oldValue == newValue);
19355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::didModifyDOMAttr(Element* element, const AtomicString& name, const AtomicString& value)
19385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
19395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool shouldSuppressEvent = m_suppressAttributeModifiedEvent;
19405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_suppressAttributeModifiedEvent = false;
19415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (shouldSuppressEvent)
19425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
19435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int id = boundNodeId(element);
19455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If node is not mapped yet -> ignore the event.
19465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!id)
19475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
19485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_domListener)
19505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_domListener->didModifyDOMAttr(element);
19515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_frontend->attributeModified(id, name, value);
19535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::didRemoveDOMAttr(Element* element, const AtomicString& name)
19565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
19575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int id = boundNodeId(element);
19585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If node is not mapped yet -> ignore the event.
19595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!id)
19605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
19615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_domListener)
19635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_domListener->didModifyDOMAttr(element);
19645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_frontend->attributeRemoved(id, name);
19665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1968f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)void InspectorDOMAgent::styleAttributeInvalidated(const WillBeHeapVector<RawPtrWillBeMember<Element> >& elements)
19695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
19705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<TypeBuilder::Array<int> > nodeIds = TypeBuilder::Array<int>::create();
19715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (unsigned i = 0, size = elements.size(); i < size; ++i) {
19725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Element* element = elements.at(i);
19735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int id = boundNodeId(element);
19745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If node is not mapped yet -> ignore the event.
19755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!id)
19765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
19775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_domListener)
19795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_domListener->didModifyDOMAttr(element);
19805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nodeIds->addItem(id);
19815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
19825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_frontend->inlineStyleInvalidated(nodeIds.release());
19835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::characterDataModified(CharacterData* characterData)
19865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1987f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int id = m_documentNodeToIdMap->get(characterData);
19885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!id) {
19895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Push text node if it is being created.
19905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        didInsertDOMNode(characterData);
19915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
19925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
19935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_frontend->characterDataModified(id, characterData->data());
19945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
19955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::didInvalidateStyleAttr(Node* node)
19975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1998f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int id = m_documentNodeToIdMap->get(node);
19995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If node is not mapped yet -> ignore the event.
20005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!id)
20015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
20025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_revalidateStyleAttrTask)
2004c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_revalidateStyleAttrTask = adoptPtrWillBeNoop(new RevalidateStyleAttributeTask(this));
2005926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_revalidateStyleAttrTask->scheduleFor(toElement(node));
20065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::didPushShadowRoot(Element* host, ShadowRoot* root)
20095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
201093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!host->ownerDocument())
201193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
201293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
2013f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int hostId = m_documentNodeToIdMap->get(host);
20149bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (!hostId)
20159bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        return;
20169bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
20179bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    pushChildNodesToFrontend(hostId, 1);
2018f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_frontend->shadowRootPushed(hostId, buildObjectForNode(root, 0, m_documentNodeToIdMap.get()));
20195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMAgent::willPopShadowRoot(Element* host, ShadowRoot* root)
20225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
202393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!host->ownerDocument())
202493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
202593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
2026f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int hostId = m_documentNodeToIdMap->get(host);
2027f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int rootId = m_documentNodeToIdMap->get(root);
20285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hostId && rootId)
20295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_frontend->shadowRootPopped(hostId, rootId);
20305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
20315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2032d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void InspectorDOMAgent::frameDocumentUpdated(LocalFrame* frame)
2033926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
2034926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Document* document = frame->document();
2035926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!document)
2036926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
2037926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2038926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    Page* page = frame->page();
2039926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT(page);
2040926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (frame != page->mainFrame())
2041926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
2042926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2043926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // Only update the main frame document, nested frame document updates are not required
2044bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // (will be handled by invalidateFrameOwnerElement()).
2045926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    setDocument(document);
2046926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
2047926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
20489bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)void InspectorDOMAgent::pseudoElementCreated(PseudoElement* pseudoElement)
20499bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
20509bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    Element* parent = pseudoElement->parentOrShadowHostElement();
20519bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (!parent)
20529bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        return;
2053f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int parentId = m_documentNodeToIdMap->get(parent);
20549bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (!parentId)
20559bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        return;
20569bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
20579bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    pushChildNodesToFrontend(parentId, 1);
2058f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_frontend->pseudoElementAdded(parentId, buildObjectForNode(pseudoElement, 0, m_documentNodeToIdMap.get()));
20599bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)}
20609bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
20619bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)void InspectorDOMAgent::pseudoElementDestroyed(PseudoElement* pseudoElement)
20629bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
2063f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int pseudoElementId = m_documentNodeToIdMap->get(pseudoElement);
20649bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (!pseudoElementId)
20659bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        return;
20669bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
20679bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    // If a PseudoElement is bound, its parent element must be bound, too.
20689bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    Element* parent = pseudoElement->parentOrShadowHostElement();
20699bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    ASSERT(parent);
2070f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    int parentId = m_documentNodeToIdMap->