1 /*
2 * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
4 * Copyright (C) 2011 Google Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "core/inspector/InspectorAgent.h"
33
34 #include "InspectorFrontend.h"
35 #include "bindings/v8/DOMWrapperWorld.h"
36 #include "bindings/v8/ScriptController.h"
37 #include "core/dom/Document.h"
38 #include "core/inspector/InjectedScriptHost.h"
39 #include "core/inspector/InjectedScriptManager.h"
40 #include "core/inspector/InspectorController.h"
41 #include "core/inspector/InspectorState.h"
42 #include "core/inspector/InstrumentingAgents.h"
43 #include "core/loader/DocumentLoader.h"
44 #include "core/frame/Frame.h"
45 #include "core/page/Page.h"
46 #include "platform/weborigin/SecurityOrigin.h"
47 #include "wtf/text/StringBuilder.h"
48
49 namespace WebCore {
50
51 namespace InspectorAgentState {
52 static const char inspectorAgentEnabled[] = "inspectorAgentEnabled";
53 }
54
InspectorAgent(Page * page,InjectedScriptManager * injectedScriptManager,InstrumentingAgents * instrumentingAgents,InspectorCompositeState * state)55 InspectorAgent::InspectorAgent(Page* page, InjectedScriptManager* injectedScriptManager, InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state)
56 : InspectorBaseAgent<InspectorAgent>("Inspector", instrumentingAgents, state)
57 , m_inspectedPage(page)
58 , m_frontend(0)
59 , m_injectedScriptManager(injectedScriptManager)
60 {
61 ASSERT_ARG(page, page);
62 m_instrumentingAgents->setInspectorAgent(this);
63 }
64
~InspectorAgent()65 InspectorAgent::~InspectorAgent()
66 {
67 m_instrumentingAgents->setInspectorAgent(0);
68 }
69
didClearWindowObjectInWorld(Frame * frame,DOMWrapperWorld * world)70 void InspectorAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
71 {
72 if (world != mainThreadNormalWorld())
73 return;
74
75 if (m_injectedScriptForOrigin.isEmpty())
76 return;
77
78 String origin = frame->document()->securityOrigin()->toRawString();
79 String script = m_injectedScriptForOrigin.get(origin);
80 if (script.isEmpty())
81 return;
82 int injectedScriptId = m_injectedScriptManager->injectedScriptIdFor(mainWorldScriptState(frame));
83 StringBuilder scriptSource;
84 scriptSource.append(script);
85 scriptSource.append("(");
86 scriptSource.appendNumber(injectedScriptId);
87 scriptSource.append(")");
88 frame->script().executeScriptInMainWorld(scriptSource.toString());
89 }
90
setFrontend(InspectorFrontend * inspectorFrontend)91 void InspectorAgent::setFrontend(InspectorFrontend* inspectorFrontend)
92 {
93 m_frontend = inspectorFrontend;
94 }
95
clearFrontend()96 void InspectorAgent::clearFrontend()
97 {
98 m_pendingEvaluateTestCommands.clear();
99 m_frontend = 0;
100 m_injectedScriptManager->discardInjectedScripts();
101 ErrorString error;
102 disable(&error);
103 }
104
didCommitLoad(Frame * frame,DocumentLoader * loader)105 void InspectorAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
106 {
107 if (loader->frame() != frame->page()->mainFrame())
108 return;
109
110 m_injectedScriptManager->discardInjectedScripts();
111 }
112
enable(ErrorString *)113 void InspectorAgent::enable(ErrorString*)
114 {
115 m_state->setBoolean(InspectorAgentState::inspectorAgentEnabled, true);
116
117 if (m_pendingInspectData.first)
118 inspect(m_pendingInspectData.first, m_pendingInspectData.second);
119
120 for (Vector<pair<long, String> >::iterator it = m_pendingEvaluateTestCommands.begin(); m_frontend && it != m_pendingEvaluateTestCommands.end(); ++it)
121 m_frontend->inspector()->evaluateForTestInFrontend(static_cast<int>((*it).first), (*it).second);
122 m_pendingEvaluateTestCommands.clear();
123 }
124
disable(ErrorString *)125 void InspectorAgent::disable(ErrorString*)
126 {
127 m_state->setBoolean(InspectorAgentState::inspectorAgentEnabled, false);
128 }
129
reset(ErrorString *)130 void InspectorAgent::reset(ErrorString*)
131 {
132 m_inspectedPage->inspectorController().reconnectFrontend();
133 }
134
domContentLoadedEventFired(Frame * frame)135 void InspectorAgent::domContentLoadedEventFired(Frame* frame)
136 {
137 if (frame->page()->mainFrame() != frame)
138 return;
139
140 m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects();
141 }
142
evaluateForTestInFrontend(long callId,const String & script)143 void InspectorAgent::evaluateForTestInFrontend(long callId, const String& script)
144 {
145 if (m_state->getBoolean(InspectorAgentState::inspectorAgentEnabled))
146 m_frontend->inspector()->evaluateForTestInFrontend(static_cast<int>(callId), script);
147 else
148 m_pendingEvaluateTestCommands.append(pair<long, String>(callId, script));
149 }
150
setInjectedScriptForOrigin(const String & origin,const String & source)151 void InspectorAgent::setInjectedScriptForOrigin(const String& origin, const String& source)
152 {
153 m_injectedScriptForOrigin.set(origin, source);
154 }
155
inspect(PassRefPtr<TypeBuilder::Runtime::RemoteObject> objectToInspect,PassRefPtr<JSONObject> hints)156 void InspectorAgent::inspect(PassRefPtr<TypeBuilder::Runtime::RemoteObject> objectToInspect, PassRefPtr<JSONObject> hints)
157 {
158 if (m_state->getBoolean(InspectorAgentState::inspectorAgentEnabled) && m_frontend) {
159 m_frontend->inspector()->inspect(objectToInspect, hints);
160 m_pendingInspectData.first = 0;
161 m_pendingInspectData.second = 0;
162 return;
163 }
164 m_pendingInspectData.first = objectToInspect;
165 m_pendingInspectData.second = hints;
166 }
167
168 } // namespace WebCore
169
170