165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch/*
265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2011 Google Inc. All rights reserved.
365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Redistribution and use in source and binary forms, with or without
565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * modification, are permitted provided that the following conditions are
665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * met:
765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *     * Redistributions of source code must retain the above copyright
965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * notice, this list of conditions and the following disclaimer.
1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *     * Redistributions in binary form must reproduce the above
1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * copyright notice, this list of conditions and the following disclaimer
1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * in the documentation and/or other materials provided with the
1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * distribution.
1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *     * Neither the name of Google Inc. nor the names of its
1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * contributors may be used to endorse or promote products derived from
1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * this software without specific prior written permission.
1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */
3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "config.h"
3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "InspectorBrowserDebuggerAgent.h"
3465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#if ENABLE(INSPECTOR) && ENABLE(JAVASCRIPT_DEBUGGER)
3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "HTMLElement.h"
382bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "InspectorAgent.h"
3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "InspectorDOMAgent.h"
4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "InspectorDebuggerAgent.h"
4165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "InspectorState.h"
4281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "InspectorValues.h"
4381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "InstrumentingAgents.h"
442bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/text/StringConcatenate.h>
4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace {
4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochenum DOMBreakpointType {
4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    SubtreeModified = 0,
5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    AttributeModified,
5165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    NodeRemoved,
5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    DOMBreakpointTypesCount
5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch};
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const char* const domNativeBreakpointType = "DOM";
5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const char* const eventListenerNativeBreakpointType = "EventListener";
5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const char* const xhrNativeBreakpointType = "XHR";
5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst uint32_t inheritableDOMBreakpointTypesMask = (1 << SubtreeModified);
6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochconst int domBreakpointDerivedTypeShift = 16;
6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace WebCore {
6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
662fc2651226baac27029e38c9d6ef883fa32084dbSteve Blocknamespace BrowserDebuggerAgentState {
672bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char eventListenerBreakpoints[] = "eventListenerBreakpoints";
682bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char pauseOnAllXHRs[] = "pauseOnAllXHRs";
692bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const char xhrBreakpoints[] = "xhrBreakpoints";
702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochPassOwnPtr<InspectorBrowserDebuggerAgent> InspectorBrowserDebuggerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorState* inspectorState, InspectorDOMAgent* domAgent, InspectorDebuggerAgent* debuggerAgent, InspectorAgent* inspectorAgent)
732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return adoptPtr(new InspectorBrowserDebuggerAgent(instrumentingAgents, inspectorState, domAgent, debuggerAgent, inspectorAgent));
752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
7781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochInspectorBrowserDebuggerAgent::InspectorBrowserDebuggerAgent(InstrumentingAgents* instrumentingAgents, InspectorState* inspectorState, InspectorDOMAgent* domAgent, InspectorDebuggerAgent* debuggerAgent, InspectorAgent* inspectorAgent)
7881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    : m_instrumentingAgents(instrumentingAgents)
7981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_inspectorState(inspectorState)
8081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_domAgent(domAgent)
8181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_debuggerAgent(debuggerAgent)
8281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_inspectorAgent(inspectorAgent)
8365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
8481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_debuggerAgent->setListener(this);
8565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochInspectorBrowserDebuggerAgent::~InspectorBrowserDebuggerAgent()
8865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
8981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_debuggerAgent->setListener(0);
9081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(!m_instrumentingAgents->inspectorBrowserDebuggerAgent());
9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
9265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch// Browser debugger agent enabled only when JS debugger is enabled.
9481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorBrowserDebuggerAgent::debuggerWasEnabled()
952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
9681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_instrumentingAgents->setInspectorBrowserDebuggerAgent(this);
9781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
9881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
9981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorBrowserDebuggerAgent::debuggerWasDisabled()
10081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
10181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    disable();
10281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
10381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
10481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorBrowserDebuggerAgent::disable()
10581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
10681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_instrumentingAgents->setInspectorBrowserDebuggerAgent(0);
10781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    clear();
10881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
10981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
11081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorBrowserDebuggerAgent::clearFrontend()
11181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
11281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    disable();
11381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
11481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1152bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorBrowserDebuggerAgent::discardBindings()
116ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
1172bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_domBreakpoints.clear();
118ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
119ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
1202bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorBrowserDebuggerAgent::setEventListenerBreakpoint(ErrorString* error, const String& eventName)
121ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
1222bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (eventName.isEmpty()) {
1232bde8e466a4451c7319e3a072d118917957d6554Steve Block        *error = "Event name is empty";
124ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        return;
125ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    }
126ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
1272bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<InspectorObject> eventListenerBreakpoints = m_inspectorState->getObject(BrowserDebuggerAgentState::eventListenerBreakpoints);
1282bde8e466a4451c7319e3a072d118917957d6554Steve Block    eventListenerBreakpoints->setBoolean(eventName, true);
1292bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_inspectorState->setObject(BrowserDebuggerAgentState::eventListenerBreakpoints, eventListenerBreakpoints);
13065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
13165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1322bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorBrowserDebuggerAgent::removeEventListenerBreakpoint(ErrorString* error, const String& eventName)
13365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
1342bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (eventName.isEmpty()) {
1352bde8e466a4451c7319e3a072d118917957d6554Steve Block        *error = "Event name is empty";
1362bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1372bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
13865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1392bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<InspectorObject> eventListenerBreakpoints = m_inspectorState->getObject(BrowserDebuggerAgentState::eventListenerBreakpoints);
1402bde8e466a4451c7319e3a072d118917957d6554Steve Block    eventListenerBreakpoints->remove(eventName);
1412bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_inspectorState->setObject(BrowserDebuggerAgentState::eventListenerBreakpoints, eventListenerBreakpoints);
14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
14365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid InspectorBrowserDebuggerAgent::didInsertDOMNode(Node* node)
14565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
146ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    if (m_domBreakpoints.size()) {
147ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        uint32_t mask = m_domBreakpoints.get(InspectorDOMAgent::innerParentNode(node));
14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        uint32_t inheritableTypesMask = (mask | (mask >> domBreakpointDerivedTypeShift)) & inheritableDOMBreakpointTypesMask;
14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (inheritableTypesMask)
15065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            updateSubtreeBreakpoints(node, inheritableTypesMask, true);
15165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
15265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
15365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
15465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid InspectorBrowserDebuggerAgent::didRemoveDOMNode(Node* node)
15565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
156ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    if (m_domBreakpoints.size()) {
15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Remove subtree breakpoints.
158ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        m_domBreakpoints.remove(node);
15965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        Vector<Node*> stack(1, InspectorDOMAgent::innerFirstChild(node));
16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        do {
16165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            Node* node = stack.last();
16265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            stack.removeLast();
16365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            if (!node)
16465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                continue;
165ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch            m_domBreakpoints.remove(node);
16665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            stack.append(InspectorDOMAgent::innerFirstChild(node));
16765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            stack.append(InspectorDOMAgent::innerNextSibling(node));
16865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        } while (!stack.isEmpty());
16965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
17065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
17165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1722bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorBrowserDebuggerAgent::setDOMBreakpoint(ErrorString*, int nodeId, int type)
17365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
17481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Node* node = m_domAgent->nodeForId(nodeId);
17565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!node)
17665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
17765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
17865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint32_t rootBit = 1 << type;
179ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    m_domBreakpoints.set(node, m_domBreakpoints.get(node) | rootBit);
18065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (rootBit & inheritableDOMBreakpointTypesMask) {
18165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (Node* child = InspectorDOMAgent::innerFirstChild(node); child; child = InspectorDOMAgent::innerNextSibling(child))
18265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            updateSubtreeBreakpoints(child, rootBit, true);
18365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
18465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
18565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1862bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorBrowserDebuggerAgent::removeDOMBreakpoint(ErrorString*, int nodeId, int type)
18765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
18881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    Node* node = m_domAgent->nodeForId(nodeId);
18965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!node)
19065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
19165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
19265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint32_t rootBit = 1 << type;
193ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    uint32_t mask = m_domBreakpoints.get(node) & ~rootBit;
19465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (mask)
195ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        m_domBreakpoints.set(node, mask);
19665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    else
197ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        m_domBreakpoints.remove(node);
19865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
19965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if ((rootBit & inheritableDOMBreakpointTypesMask) && !(mask & (rootBit << domBreakpointDerivedTypeShift))) {
20065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (Node* child = InspectorDOMAgent::innerFirstChild(node); child; child = InspectorDOMAgent::innerNextSibling(child))
20165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            updateSubtreeBreakpoints(child, rootBit, false);
20265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
20365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
20465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
20565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid InspectorBrowserDebuggerAgent::willInsertDOMNode(Node*, Node* parent)
20665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
20781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    InspectorDebuggerAgent* debuggerAgent = m_debuggerAgent;
20865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!debuggerAgent)
20965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
21065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (hasBreakpoint(parent, SubtreeModified)) {
21265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RefPtr<InspectorObject> eventData = InspectorObject::create();
21365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        descriptionForDOMEvent(parent, SubtreeModified, true, eventData.get());
21465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        eventData->setString("breakpointType", domNativeBreakpointType);
21565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData.release());
21665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
21765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
21865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid InspectorBrowserDebuggerAgent::willRemoveDOMNode(Node* node)
22065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
22181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    InspectorDebuggerAgent* debuggerAgent = m_debuggerAgent;
22265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!debuggerAgent)
22365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
22465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2252bde8e466a4451c7319e3a072d118917957d6554Steve Block    Node* parentNode = InspectorDOMAgent::innerParentNode(node);
22665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (hasBreakpoint(node, NodeRemoved)) {
22765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RefPtr<InspectorObject> eventData = InspectorObject::create();
22865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        descriptionForDOMEvent(node, NodeRemoved, false, eventData.get());
22965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        eventData->setString("breakpointType", domNativeBreakpointType);
23065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData.release());
2312bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else if (parentNode && hasBreakpoint(parentNode, SubtreeModified)) {
23265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RefPtr<InspectorObject> eventData = InspectorObject::create();
23365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        descriptionForDOMEvent(node, SubtreeModified, false, eventData.get());
23465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        eventData->setString("breakpointType", domNativeBreakpointType);
23565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData.release());
23665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
23765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
23865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
23965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid InspectorBrowserDebuggerAgent::willModifyDOMAttr(Element* element)
24065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
24181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    InspectorDebuggerAgent* debuggerAgent = m_debuggerAgent;
24265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!debuggerAgent)
24365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
24465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
24565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (hasBreakpoint(element, AttributeModified)) {
24665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RefPtr<InspectorObject> eventData = InspectorObject::create();
24765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        descriptionForDOMEvent(element, AttributeModified, false, eventData.get());
24865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        eventData->setString("breakpointType", domNativeBreakpointType);
24965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData.release());
25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
25265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2532bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InspectorBrowserDebuggerAgent::descriptionForDOMEvent(Node* target, int breakpointType, bool insertion, InspectorObject* description)
25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
25565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT(hasBreakpoint(target, breakpointType));
25665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
25765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Node* breakpointOwner = target;
25865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if ((1 << breakpointType) & inheritableDOMBreakpointTypesMask) {
25965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // For inheritable breakpoint types, target node isn't always the same as the node that owns a breakpoint.
26065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Target node may be unknown to frontend, so we need to push it first.
2612bde8e466a4451c7319e3a072d118917957d6554Steve Block        RefPtr<InspectorObject> targetNodeObject = m_domAgent->resolveNode(target);
26281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        description->setObject("targetNode", targetNodeObject);
26365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
26465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Find breakpoint owner node.
26565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!insertion)
26665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            breakpointOwner = InspectorDOMAgent::innerParentNode(target);
26765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        ASSERT(breakpointOwner);
268ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        while (!(m_domBreakpoints.get(breakpointOwner) & (1 << breakpointType))) {
26965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            breakpointOwner = InspectorDOMAgent::innerParentNode(breakpointOwner);
27065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            ASSERT(breakpointOwner);
27165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
27265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
27365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (breakpointType == SubtreeModified)
27465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            description->setBoolean("insertion", insertion);
27565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
27665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2772bde8e466a4451c7319e3a072d118917957d6554Steve Block    int breakpointOwnerNodeId = m_domAgent->boundNodeId(breakpointOwner);
27865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT(breakpointOwnerNodeId);
27965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    description->setNumber("nodeId", breakpointOwnerNodeId);
28065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    description->setNumber("type", breakpointType);
28165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
28265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2832bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool InspectorBrowserDebuggerAgent::hasBreakpoint(Node* node, int type)
28465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
28565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint32_t rootBit = 1 << type;
28665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint32_t derivedBit = rootBit << domBreakpointDerivedTypeShift;
287ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    return m_domBreakpoints.get(node) & (rootBit | derivedBit);
28865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
28965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
29065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid InspectorBrowserDebuggerAgent::updateSubtreeBreakpoints(Node* node, uint32_t rootMask, bool set)
29165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
292ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    uint32_t oldMask = m_domBreakpoints.get(node);
29365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint32_t derivedMask = rootMask << domBreakpointDerivedTypeShift;
29465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint32_t newMask = set ? oldMask | derivedMask : oldMask & ~derivedMask;
29565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (newMask)
296ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        m_domBreakpoints.set(node, newMask);
29765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    else
298ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        m_domBreakpoints.remove(node);
29965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
30065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    uint32_t newRootMask = rootMask & ~newMask;
30165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!newRootMask)
30265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
30365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
30465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (Node* child = InspectorDOMAgent::innerFirstChild(node); child; child = InspectorDOMAgent::innerNextSibling(child))
30565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        updateSubtreeBreakpoints(child, newRootMask, set);
30665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
30765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
30865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid InspectorBrowserDebuggerAgent::pauseOnNativeEventIfNeeded(const String& categoryType, const String& eventName, bool synchronous)
30965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
31081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    InspectorDebuggerAgent* debuggerAgent = m_debuggerAgent;
31165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!debuggerAgent)
31265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
31365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3142bde8e466a4451c7319e3a072d118917957d6554Steve Block    String fullEventName = makeString(categoryType, ":", eventName);
3152bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<InspectorObject> eventListenerBreakpoints = m_inspectorState->getObject(BrowserDebuggerAgentState::eventListenerBreakpoints);
3162bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (eventListenerBreakpoints->find(fullEventName) == eventListenerBreakpoints->end())
31765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
31865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
31965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    RefPtr<InspectorObject> eventData = InspectorObject::create();
32065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    eventData->setString("breakpointType", eventListenerNativeBreakpointType);
32165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    eventData->setString("eventName", fullEventName);
32265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (synchronous)
32365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData.release());
32465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    else
32565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        debuggerAgent->schedulePauseOnNextStatement(NativeBreakpointDebuggerEventType, eventData.release());
32665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
32765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
32881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorBrowserDebuggerAgent::setXHRBreakpoint(ErrorString*, const String& url)
32965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
3302bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (url.isEmpty()) {
3312bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_inspectorState->setBoolean(BrowserDebuggerAgentState::pauseOnAllXHRs, true);
3322bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
3332bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3342bde8e466a4451c7319e3a072d118917957d6554Steve Block
3352bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<InspectorObject> xhrBreakpoints = m_inspectorState->getObject(BrowserDebuggerAgentState::xhrBreakpoints);
3362bde8e466a4451c7319e3a072d118917957d6554Steve Block    xhrBreakpoints->setBoolean(url, true);
3372bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_inspectorState->setObject(BrowserDebuggerAgentState::xhrBreakpoints, xhrBreakpoints);
33865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
33965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
34081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorBrowserDebuggerAgent::removeXHRBreakpoint(ErrorString*, const String& url)
34165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
3422bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (url.isEmpty()) {
3432bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_inspectorState->setBoolean(BrowserDebuggerAgentState::pauseOnAllXHRs, false);
3442bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
3452bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3462bde8e466a4451c7319e3a072d118917957d6554Steve Block
3472bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<InspectorObject> xhrBreakpoints = m_inspectorState->getObject(BrowserDebuggerAgentState::xhrBreakpoints);
3482bde8e466a4451c7319e3a072d118917957d6554Steve Block    xhrBreakpoints->remove(url);
3492bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_inspectorState->setObject(BrowserDebuggerAgentState::xhrBreakpoints, xhrBreakpoints);
35065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
35165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
35265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid InspectorBrowserDebuggerAgent::willSendXMLHttpRequest(const String& url)
35365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
35481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    InspectorDebuggerAgent* debuggerAgent = m_debuggerAgent;
35565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!debuggerAgent)
35665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
35765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
35865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    String breakpointURL;
3592bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_inspectorState->getBoolean(BrowserDebuggerAgentState::pauseOnAllXHRs))
36065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        breakpointURL = "";
36165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    else {
3622bde8e466a4451c7319e3a072d118917957d6554Steve Block        RefPtr<InspectorObject> xhrBreakpoints = m_inspectorState->getObject(BrowserDebuggerAgentState::xhrBreakpoints);
3632bde8e466a4451c7319e3a072d118917957d6554Steve Block        for (InspectorObject::iterator it = xhrBreakpoints->begin(); it != xhrBreakpoints->end(); ++it) {
3642bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (url.contains(it->first)) {
3652bde8e466a4451c7319e3a072d118917957d6554Steve Block                breakpointURL = it->first;
36665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                break;
36765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            }
36865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
36965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
37065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
37165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (breakpointURL.isNull())
37265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
37365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
37465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    RefPtr<InspectorObject> eventData = InspectorObject::create();
37565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    eventData->setString("breakpointType", xhrNativeBreakpointType);
37665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    eventData->setString("breakpointURL", breakpointURL);
37765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    eventData->setString("url", url);
37865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    debuggerAgent->breakProgram(NativeBreakpointDebuggerEventType, eventData.release());
37965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
38065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
38181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid InspectorBrowserDebuggerAgent::clear()
38281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
38381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_domBreakpoints.clear();
38481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
38581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
38665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace WebCore
38765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
38865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif // ENABLE(INSPECTOR) && ENABLE(JAVASCRIPT_DEBUGGER)
389