Home | History | Annotate | Download | only in inspector
      1 /*
      2  * Copyright (C) 2011 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "InspectorController.h"
     33 
     34 #if ENABLE(INSPECTOR)
     35 
     36 #include "Frame.h"
     37 #include "GraphicsContext.h"
     38 #include "InjectedScriptHost.h"
     39 #include "InjectedScriptManager.h"
     40 #include "InspectorAgent.h"
     41 #include "InspectorBackendDispatcher.h"
     42 #include "InspectorBrowserDebuggerAgent.h"
     43 #include "InspectorDebuggerAgent.h"
     44 #include "InspectorClient.h"
     45 #include "InspectorDOMAgent.h"
     46 #include "InspectorFrontend.h"
     47 #include "InspectorFrontendClient.h"
     48 #include "InspectorInstrumentation.h"
     49 #include "InspectorProfilerAgent.h"
     50 #include "InspectorTimelineAgent.h"
     51 #include "Page.h"
     52 #include "ScriptObject.h"
     53 #include "Settings.h"
     54 
     55 namespace WebCore {
     56 
     57 InspectorController::InspectorController(Page* page, InspectorClient* inspectorClient)
     58     : m_injectedScriptManager(InjectedScriptManager::createForPage())
     59     , m_inspectorAgent(new InspectorAgent(page, inspectorClient, m_injectedScriptManager.get()))
     60     , m_inspectorClient(inspectorClient)
     61     , m_openingFrontend(false)
     62     , m_startUserInitiatedDebuggingWhenFrontedIsConnected(false)
     63 {
     64 }
     65 
     66 InspectorController::~InspectorController()
     67 {
     68 }
     69 
     70 void InspectorController::setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient> inspectorFrontendClient)
     71 {
     72     m_inspectorFrontendClient = inspectorFrontendClient;
     73 }
     74 
     75 bool InspectorController::hasInspectorFrontendClient() const
     76 {
     77     return m_inspectorFrontendClient;
     78 }
     79 
     80 void InspectorController::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
     81 {
     82     if (world != mainThreadNormalWorld())
     83         return;
     84 
     85     // If the page is supposed to serve as InspectorFrontend notify inspector frontend
     86     // client that it's cleared so that the client can expose inspector bindings.
     87     if (m_inspectorFrontendClient && frame == m_inspectorAgent->inspectedPage()->mainFrame())
     88         m_inspectorFrontendClient->windowObjectCleared();
     89 }
     90 
     91 void InspectorController::startTimelineProfiler()
     92 {
     93     ErrorString error;
     94     m_inspectorAgent->timelineAgent()->start(&error);
     95 }
     96 
     97 void InspectorController::stopTimelineProfiler()
     98 {
     99     ErrorString error;
    100     m_inspectorAgent->timelineAgent()->stop(&error);
    101 }
    102 
    103 void InspectorController::connectFrontend()
    104 {
    105     m_openingFrontend = false;
    106     m_inspectorFrontend = new InspectorFrontend(m_inspectorClient);
    107     m_injectedScriptManager->injectedScriptHost()->setFrontend(m_inspectorFrontend.get());
    108     m_inspectorAgent->setFrontend(m_inspectorFrontend.get());
    109 
    110     if (!InspectorInstrumentation::hasFrontends())
    111         ScriptController::setCaptureCallStackForUncaughtExceptions(true);
    112     InspectorInstrumentation::frontendCreated();
    113 
    114     ASSERT(m_inspectorClient);
    115     m_inspectorBackendDispatcher = adoptRef(new InspectorBackendDispatcher(
    116         m_inspectorClient,
    117 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
    118         m_inspectorAgent->applicationCacheAgent(),
    119 #endif
    120 #if ENABLE(JAVASCRIPT_DEBUGGER)
    121         m_inspectorAgent->browserDebuggerAgent(),
    122 #endif
    123         m_inspectorAgent->cssAgent(),
    124         m_inspectorAgent->consoleAgent(),
    125         m_inspectorAgent->domAgent(),
    126 #if ENABLE(DOM_STORAGE)
    127         m_inspectorAgent->domStorageAgent(),
    128 #endif
    129 #if ENABLE(DATABASE)
    130         m_inspectorAgent->databaseAgent(),
    131 #endif
    132 #if ENABLE(JAVASCRIPT_DEBUGGER)
    133         m_inspectorAgent->debuggerAgent(),
    134 #endif
    135         m_inspectorAgent->resourceAgent(),
    136         m_inspectorAgent->pageAgent(),
    137 #if ENABLE(JAVASCRIPT_DEBUGGER)
    138         m_inspectorAgent->profilerAgent(),
    139 #endif
    140         m_inspectorAgent->runtimeAgent(),
    141         m_inspectorAgent->timelineAgent()));
    142 
    143     if (m_startUserInitiatedDebuggingWhenFrontedIsConnected) {
    144         m_inspectorFrontend->inspector()->startUserInitiatedDebugging();
    145         m_startUserInitiatedDebuggingWhenFrontedIsConnected = false;
    146     }
    147 }
    148 
    149 void InspectorController::disconnectFrontend()
    150 {
    151     if (!m_inspectorFrontend)
    152         return;
    153     m_inspectorBackendDispatcher->clearFrontend();
    154     m_inspectorBackendDispatcher.clear();
    155 
    156     m_inspectorAgent->disconnectFrontend();
    157     m_injectedScriptManager->injectedScriptHost()->clearFrontend();
    158 
    159     m_inspectorFrontend.clear();
    160 
    161     InspectorInstrumentation::frontendDeleted();
    162     if (!InspectorInstrumentation::hasFrontends())
    163         ScriptController::setCaptureCallStackForUncaughtExceptions(false);
    164 
    165 }
    166 
    167 void InspectorController::show()
    168 {
    169     if (!enabled())
    170         return;
    171 
    172     if (m_openingFrontend)
    173         return;
    174 
    175     if (m_inspectorFrontend)
    176         m_inspectorFrontend->inspector()->bringToFront();
    177     else {
    178         m_openingFrontend = true;
    179         m_inspectorClient->openInspectorFrontend(this);
    180     }
    181 }
    182 
    183 void InspectorController::close()
    184 {
    185     if (!m_inspectorFrontend)
    186         return;
    187     m_inspectorFrontend->inspector()->disconnectFromBackend();
    188     disconnectFrontend();
    189 }
    190 
    191 void InspectorController::restoreInspectorStateFromCookie(const String& inspectorStateCookie)
    192 {
    193     ASSERT(!m_inspectorFrontend);
    194     connectFrontend();
    195     m_inspectorAgent->restoreInspectorStateFromCookie(inspectorStateCookie);
    196 }
    197 
    198 void InspectorController::evaluateForTestInFrontend(long callId, const String& script)
    199 {
    200     m_inspectorAgent->evaluateForTestInFrontend(callId, script);
    201 }
    202 
    203 void InspectorController::drawNodeHighlight(GraphicsContext& context) const
    204 {
    205     m_inspectorAgent->domAgent()->drawNodeHighlight(context);
    206 }
    207 
    208 void InspectorController::showConsole()
    209 {
    210     if (!enabled())
    211         return;
    212     show();
    213     m_inspectorAgent->showConsole();
    214 }
    215 
    216 void InspectorController::inspect(Node* node)
    217 {
    218     if (!enabled())
    219         return;
    220 
    221     show();
    222 
    223     m_inspectorAgent->domAgent()->inspect(node);
    224 }
    225 
    226 bool InspectorController::enabled() const
    227 {
    228     return m_inspectorAgent->enabled();
    229 }
    230 
    231 Page* InspectorController::inspectedPage() const
    232 {
    233     return m_inspectorAgent->inspectedPage();
    234 }
    235 
    236 bool InspectorController::timelineProfilerEnabled()
    237 {
    238     return m_inspectorAgent->timelineAgent()->started();
    239 }
    240 
    241 void InspectorController::setInspectorExtensionAPI(const String& source)
    242 {
    243     m_inspectorAgent->setInspectorExtensionAPI(source);
    244 }
    245 
    246 void InspectorController::dispatchMessageFromFrontend(const String& message)
    247 {
    248     if (m_inspectorBackendDispatcher)
    249         m_inspectorBackendDispatcher->dispatch(message);
    250 }
    251 
    252 void InspectorController::hideHighlight()
    253 {
    254     ErrorString error;
    255     m_inspectorAgent->domAgent()->hideHighlight(&error);
    256 }
    257 
    258 Node* InspectorController::highlightedNode() const
    259 {
    260     return m_inspectorAgent->domAgent()->highlightedNode();
    261 }
    262 
    263 #if ENABLE(JAVASCRIPT_DEBUGGER)
    264 void InspectorController::enableProfiler()
    265 {
    266     ErrorString error;
    267     m_inspectorAgent->profilerAgent()->enable(&error);
    268 }
    269 
    270 void InspectorController::disableProfiler()
    271 {
    272     ErrorString error;
    273     m_inspectorAgent->profilerAgent()->disable(&error);
    274 }
    275 
    276 bool InspectorController::profilerEnabled()
    277 {
    278     return m_inspectorAgent->profilerAgent()->enabled();
    279 }
    280 
    281 bool InspectorController::debuggerEnabled()
    282 {
    283     return m_inspectorAgent->debuggerAgent()->enabled();
    284 }
    285 
    286 void InspectorController::showAndEnableDebugger()
    287 {
    288     if (!enabled())
    289         return;
    290     show();
    291 
    292     if (m_inspectorFrontend)
    293         m_inspectorFrontend->inspector()->startUserInitiatedDebugging();
    294     else
    295         m_startUserInitiatedDebuggingWhenFrontedIsConnected = true;
    296 }
    297 
    298 void InspectorController::disableDebugger()
    299 {
    300     m_inspectorAgent->debuggerAgent()->disable();
    301 }
    302 
    303 void InspectorController::startUserInitiatedProfiling()
    304 {
    305     m_inspectorAgent->profilerAgent()->startUserInitiatedProfiling();
    306 }
    307 
    308 void InspectorController::stopUserInitiatedProfiling()
    309 {
    310     if (!enabled())
    311         return;
    312     show();
    313     m_inspectorAgent->profilerAgent()->stopUserInitiatedProfiling();
    314     m_inspectorAgent->showProfilesPanel();
    315 }
    316 
    317 bool InspectorController::isRecordingUserInitiatedProfile() const
    318 {
    319     return m_inspectorAgent->profilerAgent()->isRecordingUserInitiatedProfile();
    320 }
    321 
    322 void InspectorController::resume()
    323 {
    324     if (InspectorDebuggerAgent* debuggerAgent = m_inspectorAgent->debuggerAgent()) {
    325         ErrorString error;
    326         debuggerAgent->resume(&error);
    327     }
    328 }
    329 
    330 #endif
    331 
    332 } // namespace WebCore
    333 
    334 #endif // ENABLE(INSPECTOR)
    335