15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 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
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF 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/InspectorDOMDebuggerAgent.h"
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/InspectorFrontend.h"
35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/events/Event.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorDOMAgent.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorState.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InstrumentingAgents.h"
391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/JSONValues.h"
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace {
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum DOMBreakpointType {
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SubtreeModified = 0,
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    AttributeModified,
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    NodeRemoved,
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    DOMBreakpointTypesCount
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
50f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char listenerEventCategoryType[] = "listener:";
51f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char instrumentationEventCategoryType[] = "instrumentation:";
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t inheritableDOMBreakpointTypesMask = (1 << SubtreeModified);
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const int domBreakpointDerivedTypeShift = 16;
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
58c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
60f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char requestAnimationFrameEventName[] = "requestAnimationFrame";
61f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char cancelAnimationFrameEventName[] = "cancelAnimationFrame";
62f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char animationFrameFiredEventName[] = "animationFrameFired";
63f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char setTimerEventName[] = "setTimer";
64f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char clearTimerEventName[] = "clearTimer";
65f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char timerFiredEventName[] = "timerFired";
667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic const char newPromiseEventName[] = "newPromise";
677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic const char promiseResolvedEventName[] = "promiseResolved";
687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic const char promiseRejectedEventName[] = "promiseRejected";
69c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)static const char windowCloseEventName[] = "close";
7009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static const char customElementCallbackName[] = "customElementCallback";
71f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char webglErrorFiredEventName[] = "webglErrorFired";
72f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char webglWarningFiredEventName[] = "webglWarningFired";
73f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const char webglErrorNameProperty[] = "webglErrorName";
7493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace DOMDebuggerAgentState {
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const char eventListenerBreakpoints[] = "eventListenerBreakpoints";
775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)static const char eventTargetAny[] = "*";
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const char pauseOnAllXHRs[] = "pauseOnAllXHRs";
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const char xhrBreakpoints[] = "xhrBreakpoints";
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
82c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)PassOwnPtrWillBeRawPtr<InspectorDOMDebuggerAgent> InspectorDOMDebuggerAgent::create(InspectorDOMAgent* domAgent, InspectorDebuggerAgent* debuggerAgent)
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
84c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return adoptPtrWillBeNoop(new InspectorDOMDebuggerAgent(domAgent, debuggerAgent));
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(InspectorDOMAgent* domAgent, InspectorDebuggerAgent* debuggerAgent)
8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    : InspectorBaseAgent<InspectorDOMDebuggerAgent>("DOMDebugger")
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_domAgent(domAgent)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_debuggerAgent(debuggerAgent)
91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_pauseInNextEventListener(false)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_debuggerAgent->setListener(this);
94f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    m_domAgent->setListener(this);
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)InspectorDOMDebuggerAgent::~InspectorDOMDebuggerAgent()
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
99c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#if !ENABLE(OILPAN)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_debuggerAgent);
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_instrumentingAgents->inspectorDOMDebuggerAgent());
102c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#endif
103c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
104c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
105c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void InspectorDOMDebuggerAgent::trace(Visitor* visitor)
106c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
107c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    visitor->trace(m_domAgent);
108c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    visitor->trace(m_debuggerAgent);
109c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#if ENABLE(OILPAN)
110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    visitor->trace(m_domBreakpoints);
111c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#endif
112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    InspectorBaseAgent::trace(visitor);
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Browser debugger agent enabled only when JS debugger is enabled.
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::debuggerWasEnabled()
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
118f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (m_domAgent->enabled() && m_debuggerAgent->enabled())
119f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_instrumentingAgents->setInspectorDOMDebuggerAgent(this);
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::debuggerWasDisabled()
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    disable();
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
127f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)void InspectorDOMDebuggerAgent::domAgentWasEnabled()
128f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
129f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (m_domAgent->enabled() && m_debuggerAgent->enabled())
130f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        m_instrumentingAgents->setInspectorDOMDebuggerAgent(this);
131f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
132f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
133f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)void InspectorDOMDebuggerAgent::domAgentWasDisabled()
134f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
135f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    disable();
136f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
137f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorDOMDebuggerAgent::stepInto()
139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_pauseInNextEventListener = true;
141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorDOMDebuggerAgent::didPause()
144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_pauseInNextEventListener = false;
146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void InspectorDOMDebuggerAgent::didProcessTask()
149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_pauseInNextEventListener)
151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (m_debuggerAgent && m_debuggerAgent->runningNestedMessageLoop())
153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_pauseInNextEventListener = false;
155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
156926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::disable()
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_instrumentingAgents->setInspectorDOMDebuggerAgent(0);
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    clear();
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::clearFrontend()
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    disable();
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::discardAgent()
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_debuggerAgent->setListener(0);
171c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    m_debuggerAgent = nullptr;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void InspectorDOMDebuggerAgent::setEventListenerBreakpoint(ErrorString* error, const String& eventName, const String* targetName)
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    setBreakpoint(error, String(listenerEventCategoryType) + eventName, targetName);
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::setInstrumentationBreakpoint(ErrorString* error, const String& eventName)
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    setBreakpoint(error, String(instrumentationEventCategoryType) + eventName, 0);
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)static PassRefPtr<JSONObject> ensurePropertyObject(JSONObject* object, const String& propertyName)
1855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles){
1865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    JSONObject::iterator it = object->find(propertyName);
1875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (it != object->end())
1885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return it->value->asObject();
1895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
1905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    RefPtr<JSONObject> result = JSONObject::create();
1915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    object->setObject(propertyName, result);
1925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    return result.release();
1935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)}
1945d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
1955d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void InspectorDOMDebuggerAgent::setBreakpoint(ErrorString* error, const String& eventName, const String* targetName)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (eventName.isEmpty()) {
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *error = "Event name is empty";
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Backward compatibility. Some extensions expect that DOMDebuggerAgent is always enabled.
2037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // See https://stackoverflow.com/questions/25764336/chrome-extension-domdebugger-api-does-not-work-anymore
2047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!m_domAgent->enabled())
2057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_domAgent->enable(error);
2067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (error->length())
2087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return;
2097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
210591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    RefPtr<JSONObject> eventListenerBreakpoints = m_state->getObject(DOMDebuggerAgentState::eventListenerBreakpoints);
2115d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    RefPtr<JSONObject> breakpointsByTarget = ensurePropertyObject(eventListenerBreakpoints.get(), eventName);
2125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!targetName || targetName->isEmpty())
2135d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        breakpointsByTarget->setBoolean(DOMDebuggerAgentState::eventTargetAny, true);
2145d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    else
2155d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        breakpointsByTarget->setBoolean(targetName->lower(), true);
2165d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_state->setObject(DOMDebuggerAgentState::eventListenerBreakpoints, eventListenerBreakpoints.release());
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void InspectorDOMDebuggerAgent::removeEventListenerBreakpoint(ErrorString* error, const String& eventName, const String* targetName)
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    removeBreakpoint(error, String(listenerEventCategoryType) + eventName, targetName);
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::removeInstrumentationBreakpoint(ErrorString* error, const String& eventName)
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    removeBreakpoint(error, String(instrumentationEventCategoryType) + eventName, 0);
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void InspectorDOMDebuggerAgent::removeBreakpoint(ErrorString* error, const String& eventName, const String* targetName)
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (eventName.isEmpty()) {
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *error = "Event name is empty";
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
236591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    RefPtr<JSONObject> eventListenerBreakpoints = m_state->getObject(DOMDebuggerAgentState::eventListenerBreakpoints);
2375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    RefPtr<JSONObject> breakpointsByTarget = ensurePropertyObject(eventListenerBreakpoints.get(), eventName);
2385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (!targetName || targetName->isEmpty())
2395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        breakpointsByTarget->remove(DOMDebuggerAgentState::eventTargetAny);
2405d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    else
2415d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        breakpointsByTarget->remove(targetName->lower());
2425d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_state->setObject(DOMDebuggerAgentState::eventListenerBreakpoints, eventListenerBreakpoints.release());
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::didInvalidateStyleAttr(Node* node)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasBreakpoint(node, AttributeModified)) {
248591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        RefPtr<JSONObject> eventData = JSONObject::create();
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        descriptionForDOMEvent(node, AttributeModified, false, eventData.get());
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_debuggerAgent->breakProgram(InspectorFrontend::Debugger::Reason::DOM, eventData.release());
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::didInsertDOMNode(Node* node)
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_domBreakpoints.size()) {
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        uint32_t mask = m_domBreakpoints.get(InspectorDOMAgent::innerParentNode(node));
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        uint32_t inheritableTypesMask = (mask | (mask >> domBreakpointDerivedTypeShift)) & inheritableDOMBreakpointTypesMask;
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (inheritableTypesMask)
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            updateSubtreeBreakpoints(node, inheritableTypesMask, true);
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::didRemoveDOMNode(Node* node)
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_domBreakpoints.size()) {
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Remove subtree breakpoints.
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_domBreakpoints.remove(node);
269197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        WillBeHeapVector<RawPtrWillBeMember<Node> > stack(1, InspectorDOMAgent::innerFirstChild(node));
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        do {
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            Node* node = stack.last();
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            stack.removeLast();
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!node)
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                continue;
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_domBreakpoints.remove(node);
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            stack.append(InspectorDOMAgent::innerFirstChild(node));
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            stack.append(InspectorDOMAgent::innerNextSibling(node));
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } while (!stack.isEmpty());
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static int domTypeForName(ErrorString* errorString, const String& typeString)
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (typeString == "subtree-modified")
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return SubtreeModified;
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (typeString == "attribute-modified")
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return AttributeModified;
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (typeString == "node-removed")
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return NodeRemoved;
29093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    *errorString = "Unknown DOM breakpoint type: " + typeString;
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return -1;
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static String domTypeName(int type)
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (type) {
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case SubtreeModified: return "subtree-modified";
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case AttributeModified: return "attribute-modified";
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NodeRemoved: return "node-removed";
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default: break;
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return "";
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::setDOMBreakpoint(ErrorString* errorString, int nodeId, const String& typeString)
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = m_domAgent->assertNode(errorString, nodeId);
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int type = domTypeForName(errorString, typeString);
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (type == -1)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uint32_t rootBit = 1 << type;
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_domBreakpoints.set(node, m_domBreakpoints.get(node) | rootBit);
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (rootBit & inheritableDOMBreakpointTypesMask) {
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (Node* child = InspectorDOMAgent::innerFirstChild(node); child; child = InspectorDOMAgent::innerNextSibling(child))
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            updateSubtreeBreakpoints(child, rootBit, true);
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::removeDOMBreakpoint(ErrorString* errorString, int nodeId, const String& typeString)
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* node = m_domAgent->assertNode(errorString, nodeId);
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!node)
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int type = domTypeForName(errorString, typeString);
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (type == -1)
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uint32_t rootBit = 1 << type;
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uint32_t mask = m_domBreakpoints.get(node) & ~rootBit;
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (mask)
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_domBreakpoints.set(node, mask);
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_domBreakpoints.remove(node);
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if ((rootBit & inheritableDOMBreakpointTypesMask) && !(mask & (rootBit << domBreakpointDerivedTypeShift))) {
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (Node* child = InspectorDOMAgent::innerFirstChild(node); child; child = InspectorDOMAgent::innerNextSibling(child))
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            updateSubtreeBreakpoints(child, rootBit, false);
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::willInsertDOMNode(Node* parent)
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasBreakpoint(parent, SubtreeModified)) {
348591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        RefPtr<JSONObject> eventData = JSONObject::create();
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        descriptionForDOMEvent(parent, SubtreeModified, true, eventData.get());
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_debuggerAgent->breakProgram(InspectorFrontend::Debugger::Reason::DOM, eventData.release());
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::willRemoveDOMNode(Node* node)
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* parentNode = InspectorDOMAgent::innerParentNode(node);
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasBreakpoint(node, NodeRemoved)) {
358591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        RefPtr<JSONObject> eventData = JSONObject::create();
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        descriptionForDOMEvent(node, NodeRemoved, false, eventData.get());
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_debuggerAgent->breakProgram(InspectorFrontend::Debugger::Reason::DOM, eventData.release());
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else if (parentNode && hasBreakpoint(parentNode, SubtreeModified)) {
362591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        RefPtr<JSONObject> eventData = JSONObject::create();
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        descriptionForDOMEvent(node, SubtreeModified, false, eventData.get());
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_debuggerAgent->breakProgram(InspectorFrontend::Debugger::Reason::DOM, eventData.release());
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
36693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    didRemoveDOMNode(node);
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
36953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void InspectorDOMDebuggerAgent::willModifyDOMAttr(Element* element, const AtomicString&, const AtomicString&)
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (hasBreakpoint(element, AttributeModified)) {
372591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        RefPtr<JSONObject> eventData = JSONObject::create();
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        descriptionForDOMEvent(element, AttributeModified, false, eventData.get());
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_debuggerAgent->breakProgram(InspectorFrontend::Debugger::Reason::DOM, eventData.release());
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
378591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid InspectorDOMDebuggerAgent::descriptionForDOMEvent(Node* target, int breakpointType, bool insertion, JSONObject* description)
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(hasBreakpoint(target, breakpointType));
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* breakpointOwner = target;
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if ((1 << breakpointType) & inheritableDOMBreakpointTypesMask) {
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // For inheritable breakpoint types, target node isn't always the same as the node that owns a breakpoint.
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Target node may be unknown to frontend, so we need to push it first.
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RefPtr<TypeBuilder::Runtime::RemoteObject> targetNodeObject = m_domAgent->resolveNode(target, InspectorDebuggerAgent::backtraceObjectGroup);
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        description->setValue("targetNode", targetNodeObject);
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Find breakpoint owner node.
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!insertion)
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            breakpointOwner = InspectorDOMAgent::innerParentNode(target);
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(breakpointOwner);
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (!(m_domBreakpoints.get(breakpointOwner) & (1 << breakpointType))) {
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            Node* parentNode = InspectorDOMAgent::innerParentNode(breakpointOwner);
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!parentNode)
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            breakpointOwner = parentNode;
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (breakpointType == SubtreeModified)
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            description->setBoolean("insertion", insertion);
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int breakpointOwnerNodeId = m_domAgent->boundNodeId(breakpointOwner);
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(breakpointOwnerNodeId);
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    description->setNumber("nodeId", breakpointOwnerNodeId);
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    description->setString("type", domTypeName(breakpointType));
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InspectorDOMDebuggerAgent::hasBreakpoint(Node* node, int type)
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uint32_t rootBit = 1 << type;
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uint32_t derivedBit = rootBit << domBreakpointDerivedTypeShift;
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_domBreakpoints.get(node) & (rootBit | derivedBit);
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::updateSubtreeBreakpoints(Node* node, uint32_t rootMask, bool set)
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uint32_t oldMask = m_domBreakpoints.get(node);
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uint32_t derivedMask = rootMask << domBreakpointDerivedTypeShift;
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uint32_t newMask = set ? oldMask | derivedMask : oldMask & ~derivedMask;
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (newMask)
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_domBreakpoints.set(node, newMask);
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_domBreakpoints.remove(node);
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    uint32_t newRootMask = rootMask & ~newMask;
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!newRootMask)
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (Node* child = InspectorDOMAgent::innerFirstChild(node); child; child = InspectorDOMAgent::innerNextSibling(child))
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updateSubtreeBreakpoints(child, newRootMask, set);
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
435591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid InspectorDOMDebuggerAgent::pauseOnNativeEventIfNeeded(PassRefPtr<JSONObject> eventData, bool synchronous)
436521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
437521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (!eventData)
438521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
439521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (synchronous)
440521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        m_debuggerAgent->breakProgram(InspectorFrontend::Debugger::Reason::EventListener, eventData);
441521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    else
442521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        m_debuggerAgent->schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::EventListener, eventData);
443521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
444521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
445197021e6b966cfb06891637935ef33fff06433d1Ben MurdochPassRefPtr<JSONObject> InspectorDOMDebuggerAgent::preparePauseOnNativeEventData(const String& eventName, const String* targetName)
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    String fullEventName = (targetName ? listenerEventCategoryType : instrumentationEventCategoryType) + eventName;
4485d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (m_pauseInNextEventListener) {
449926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_pauseInNextEventListener = false;
4505d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    } else {
451591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        RefPtr<JSONObject> eventListenerBreakpoints = m_state->getObject(DOMDebuggerAgentState::eventListenerBreakpoints);
4525d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        JSONObject::iterator it = eventListenerBreakpoints->find(fullEventName);
4535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if (it == eventListenerBreakpoints->end())
4545d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            return nullptr;
4555d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        bool match = false;
4565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        RefPtr<JSONObject> breakpointsByTarget = it->value->asObject();
4575d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        breakpointsByTarget->getBoolean(DOMDebuggerAgentState::eventTargetAny, &match);
4585d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if (!match && targetName)
4595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            breakpointsByTarget->getBoolean(targetName->lower(), &match);
4605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if (!match)
461d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return nullptr;
462926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
464591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    RefPtr<JSONObject> eventData = JSONObject::create();
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    eventData->setString("eventName", fullEventName);
4665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (targetName)
4675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        eventData->setString("targetName", *targetName);
468521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return eventData.release();
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
47109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void InspectorDOMDebuggerAgent::didInstallTimer(ExecutionContext*, int, int, bool)
47293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
4735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(setTimerEventName, 0), true);
47493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
47593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
47609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void InspectorDOMDebuggerAgent::didRemoveTimer(ExecutionContext*, int)
47793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
4785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(clearTimerEventName, 0), true);
47993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
48093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
48109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void InspectorDOMDebuggerAgent::willFireTimer(ExecutionContext*, int)
48293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
4835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(timerFiredEventName, 0), false);
48493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
48593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
4867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool InspectorDOMDebuggerAgent::canPauseOnPromiseEvent()
4877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
4887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (m_pauseInNextEventListener)
4897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return true;
4907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RefPtr<JSONObject> eventListenerBreakpoints = m_state->getObject(DOMDebuggerAgentState::eventListenerBreakpoints);
4917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    JSONObject::iterator end = eventListenerBreakpoints->end();
4927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return eventListenerBreakpoints->find(String(instrumentationEventCategoryType) + newPromiseEventName) != end
4937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        || eventListenerBreakpoints->find(String(instrumentationEventCategoryType) + promiseResolvedEventName) != end
4947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        || eventListenerBreakpoints->find(String(instrumentationEventCategoryType) + promiseRejectedEventName) != end;
4957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
4967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
4977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid InspectorDOMDebuggerAgent::didCreatePromise()
4987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
4997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(newPromiseEventName, 0), true);
5007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
5017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
5027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid InspectorDOMDebuggerAgent::didResolvePromise()
5037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
5047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(promiseResolvedEventName, 0), true);
5057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
5067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
5077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid InspectorDOMDebuggerAgent::didRejectPromise()
5087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
5097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(promiseRejectedEventName, 0), true);
5107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
5117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
51209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void InspectorDOMDebuggerAgent::didRequestAnimationFrame(Document*, int)
51393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
5145d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(requestAnimationFrameEventName, 0), true);
51593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
51693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
51709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void InspectorDOMDebuggerAgent::didCancelAnimationFrame(Document*, int)
51893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
5195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(cancelAnimationFrameEventName, 0), true);
52093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
52193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
52209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void InspectorDOMDebuggerAgent::willFireAnimationFrame(Document*, int)
52393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
5245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(animationFrameFiredEventName, 0), false);
52593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
52693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
5275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void InspectorDOMDebuggerAgent::willHandleEvent(EventTarget* target, Event* event, EventListener*, bool)
52893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
529197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Node* node = target->toNode();
530197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    String targetName = node ? node->nodeName() : target->interfaceName();
531197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(event->type(), &targetName), false);
53209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
53309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
534c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void InspectorDOMDebuggerAgent::willCloseWindow()
535c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){
536c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(windowCloseEventName, 0), true);
537c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
538c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
53909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void InspectorDOMDebuggerAgent::willExecuteCustomElementCallback(Element*)
54009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
5415d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(customElementCallbackName, 0), false);
542521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
543521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
544521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void InspectorDOMDebuggerAgent::didFireWebGLError(const String& errorName)
545521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
5465d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    RefPtr<JSONObject> eventData = preparePauseOnNativeEventData(webglErrorFiredEventName, 0);
547521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (!eventData)
548521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return;
549e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (!errorName.isEmpty())
550e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        eventData->setString(webglErrorNameProperty, errorName);
551521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    pauseOnNativeEventIfNeeded(eventData.release(), m_debuggerAgent->canBreakProgram());
55293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
55393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
554e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochvoid InspectorDOMDebuggerAgent::didFireWebGLWarning()
555e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
5565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(webglWarningFiredEventName, 0), m_debuggerAgent->canBreakProgram());
557e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
558e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
559e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochvoid InspectorDOMDebuggerAgent::didFireWebGLErrorOrWarning(const String& message)
560e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
56106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (message.findIgnoringCase("error") != WTF::kNotFound)
562e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        didFireWebGLError(String());
563e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    else
564e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        didFireWebGLWarning();
565e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
566e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::setXHRBreakpoint(ErrorString*, const String& url)
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (url.isEmpty()) {
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_state->setBoolean(DOMDebuggerAgentState::pauseOnAllXHRs, true);
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
574591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    RefPtr<JSONObject> xhrBreakpoints = m_state->getObject(DOMDebuggerAgentState::xhrBreakpoints);
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xhrBreakpoints->setBoolean(url, true);
5765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_state->setObject(DOMDebuggerAgentState::xhrBreakpoints, xhrBreakpoints.release());
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::removeXHRBreakpoint(ErrorString*, const String& url)
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (url.isEmpty()) {
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_state->setBoolean(DOMDebuggerAgentState::pauseOnAllXHRs, false);
5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
586591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    RefPtr<JSONObject> xhrBreakpoints = m_state->getObject(DOMDebuggerAgentState::xhrBreakpoints);
5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    xhrBreakpoints->remove(url);
5885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    m_state->setObject(DOMDebuggerAgentState::xhrBreakpoints, xhrBreakpoints.release());
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::willSendXMLHttpRequest(const String& url)
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String breakpointURL;
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_state->getBoolean(DOMDebuggerAgentState::pauseOnAllXHRs))
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        breakpointURL = "";
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
597591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        RefPtr<JSONObject> xhrBreakpoints = m_state->getObject(DOMDebuggerAgentState::xhrBreakpoints);
598591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        for (JSONObject::iterator it = xhrBreakpoints->begin(); it != xhrBreakpoints->end(); ++it) {
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (url.contains(it->key)) {
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                breakpointURL = it->key;
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (breakpointURL.isNull())
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
609591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    RefPtr<JSONObject> eventData = JSONObject::create();
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    eventData->setString("breakpointURL", breakpointURL);
6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    eventData->setString("url", url);
6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_debuggerAgent->breakProgram(InspectorFrontend::Debugger::Reason::XHR, eventData.release());
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InspectorDOMDebuggerAgent::clear()
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_domBreakpoints.clear();
618926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_pauseInNextEventListener = false;
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
621c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
623