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