OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "Document.h" | 9 #include "Document.h" |
10 #include "EventListener.h" | 10 #include "EventListener.h" |
11 #include "InspectorController.h" | 11 #include "InspectorController.h" |
| 12 #include "InspectorFrontend.h" |
| 13 #include "InspectorResource.h" |
12 #include "Node.h" | 14 #include "Node.h" |
13 #include "Page.h" | 15 #include "Page.h" |
14 #include "PlatformString.h" | 16 #include "PlatformString.h" |
| 17 #include "ScriptObject.h" |
| 18 #include "ScriptState.h" |
15 #include "ScriptValue.h" | 19 #include "ScriptValue.h" |
16 #include "v8_proxy.h" | 20 #include "v8_proxy.h" |
17 #include <wtf/OwnPtr.h> | 21 #include <wtf/OwnPtr.h> |
18 #undef LOG | 22 #undef LOG |
19 | 23 |
| 24 #include "V8Binding.h" |
20 #include "base/values.h" | 25 #include "base/values.h" |
| 26 #include "webkit/glue/devtools/bound_object.h" |
21 #include "webkit/glue/devtools/debugger_agent_impl.h" | 27 #include "webkit/glue/devtools/debugger_agent_impl.h" |
22 #include "webkit/glue/devtools/debugger_agent_manager.h" | 28 #include "webkit/glue/devtools/debugger_agent_manager.h" |
23 #include "webkit/glue/devtools/dom_agent_impl.h" | 29 #include "webkit/glue/devtools/dom_agent_impl.h" |
24 #include "webkit/glue/devtools/net_agent_impl.h" | |
25 #include "webkit/glue/glue_util.h" | 30 #include "webkit/glue/glue_util.h" |
26 #include "webkit/glue/webdatasource.h" | 31 #include "webkit/glue/webdatasource.h" |
27 #include "webkit/glue/webdevtoolsagent_delegate.h" | 32 #include "webkit/glue/webdevtoolsagent_delegate.h" |
28 #include "webkit/glue/webdevtoolsagent_impl.h" | 33 #include "webkit/glue/webdevtoolsagent_impl.h" |
29 #include "webkit/glue/weburlrequest.h" | 34 #include "webkit/glue/weburlrequest.h" |
30 #include "webkit/glue/webview_impl.h" | 35 #include "webkit/glue/webview_impl.h" |
31 | 36 |
32 using WebCore::Document; | 37 using WebCore::Document; |
33 using WebCore::InspectorController; | 38 using WebCore::InspectorController; |
| 39 using WebCore::InspectorFrontend; |
| 40 using WebCore::InspectorResource; |
34 using WebCore::Node; | 41 using WebCore::Node; |
35 using WebCore::Page; | 42 using WebCore::Page; |
36 using WebCore::ScriptValue; | 43 using WebCore::ScriptValue; |
37 using WebCore::String; | 44 using WebCore::String; |
38 | 45 |
39 // Maximum size of the console message cache. | |
40 static const size_t kMaxConsoleMessages = 200; | |
41 | |
42 WebDevToolsAgentImpl::WebDevToolsAgentImpl( | 46 WebDevToolsAgentImpl::WebDevToolsAgentImpl( |
43 WebViewImpl* web_view_impl, | 47 WebViewImpl* web_view_impl, |
44 WebDevToolsAgentDelegate* delegate) | 48 WebDevToolsAgentDelegate* delegate) |
45 : host_id_(delegate->GetHostId()), | 49 : host_id_(delegate->GetHostId()), |
46 delegate_(delegate), | 50 delegate_(delegate), |
47 web_view_impl_(web_view_impl), | 51 web_view_impl_(web_view_impl), |
48 document_(NULL), | 52 document_(NULL), |
49 attached_(false) { | 53 attached_(false) { |
50 debugger_agent_delegate_stub_.set(new DebuggerAgentDelegateStub(this)); | 54 debugger_agent_delegate_stub_.set(new DebuggerAgentDelegateStub(this)); |
51 dom_agent_delegate_stub_.set(new DomAgentDelegateStub(this)); | 55 dom_agent_delegate_stub_.set(new DomAgentDelegateStub(this)); |
52 net_agent_delegate_stub_.set(new NetAgentDelegateStub(this)); | |
53 tools_agent_delegate_stub_.set(new ToolsAgentDelegateStub(this)); | 56 tools_agent_delegate_stub_.set(new ToolsAgentDelegateStub(this)); |
54 | |
55 // Sniff for requests from the beginning, do not wait for attach. | |
56 net_agent_impl_.set(new NetAgentImpl(net_agent_delegate_stub_.get())); | |
57 } | 57 } |
58 | 58 |
59 WebDevToolsAgentImpl::~WebDevToolsAgentImpl() { | 59 WebDevToolsAgentImpl::~WebDevToolsAgentImpl() { |
60 DebuggerAgentManager::OnWebViewClosed(web_view_impl_); | 60 DebuggerAgentManager::OnWebViewClosed(web_view_impl_); |
61 if (!utility_context_.IsEmpty()) { | 61 if (!utility_context_.IsEmpty()) { |
62 utility_context_.Dispose(); | 62 utility_context_.Dispose(); |
63 utility_context_.Clear(); | 63 utility_context_.Clear(); |
64 } | 64 } |
65 } | 65 } |
66 | 66 |
(...skipping 10 matching lines...) Expand all Loading... |
77 // We are potentially attaching to the running page -> init agents with | 77 // We are potentially attaching to the running page -> init agents with |
78 // Document if any. | 78 // Document if any. |
79 Page* page = web_view_impl_->page(); | 79 Page* page = web_view_impl_->page(); |
80 Document* doc = page->mainFrame()->document(); | 80 Document* doc = page->mainFrame()->document(); |
81 if (doc) { | 81 if (doc) { |
82 // Reuse existing context in case detached/attached. | 82 // Reuse existing context in case detached/attached. |
83 if (utility_context_.IsEmpty()) { | 83 if (utility_context_.IsEmpty()) { |
84 debugger_agent_impl_->ResetUtilityContext(doc, &utility_context_); | 84 debugger_agent_impl_->ResetUtilityContext(doc, &utility_context_); |
85 } | 85 } |
86 dom_agent_impl_->SetDocument(doc); | 86 dom_agent_impl_->SetDocument(doc); |
87 net_agent_impl_->SetDocument(doc); | 87 web_inspector_stub_.set( |
| 88 new BoundObject(utility_context_, this, "RemoteWebInspector")); |
| 89 web_inspector_stub_->AddProtoFunction( |
| 90 "dispatch", |
| 91 WebDevToolsAgentImpl::JsDispatchOnClient); |
| 92 web_inspector_stub_->Build(); |
| 93 |
| 94 InspectorController* ic = web_view_impl_->page()->inspectorController(); |
| 95 v8::HandleScope scope; |
| 96 ic->setFrontendProxyObject( |
| 97 scriptStateFromPage(web_view_impl_->page()), |
| 98 utility_context_->Global()); |
| 99 // Allow controller to send messages to the frontend. |
| 100 ic->setWindowVisible(true, false); |
88 } | 101 } |
89 | |
90 // Populate console. | |
91 for (Vector<ConsoleMessage>::iterator it = console_log_.begin(); | |
92 it != console_log_.end(); ++it) { | |
93 DictionaryValue message; | |
94 Serialize(*it, &message); | |
95 tools_agent_delegate_stub_->AddMessageToConsole(message); | |
96 } | |
97 | |
98 net_agent_impl_->Attach(); | |
99 attached_ = true; | 102 attached_ = true; |
100 } | 103 } |
101 | 104 |
102 void WebDevToolsAgentImpl::Detach() { | 105 void WebDevToolsAgentImpl::Detach() { |
| 106 // Prevent controller from sending messages to the frontend. |
| 107 InspectorController* ic = web_view_impl_->page()->inspectorController(); |
| 108 ic->setWindowVisible(false, false); |
103 HideDOMNodeHighlight(); | 109 HideDOMNodeHighlight(); |
| 110 web_inspector_stub_.set(NULL); |
104 debugger_agent_impl_.set(NULL); | 111 debugger_agent_impl_.set(NULL); |
105 dom_agent_impl_.set(NULL); | 112 dom_agent_impl_.set(NULL); |
106 net_agent_impl_->Detach(); | |
107 attached_ = false; | 113 attached_ = false; |
108 } | 114 } |
109 | 115 |
110 void WebDevToolsAgentImpl::SetMainFrameDocumentReady(bool ready) { | 116 void WebDevToolsAgentImpl::SetMainFrameDocumentReady(bool ready) { |
111 if (!attached_) { | 117 if (!attached_) { |
112 return; | 118 return; |
113 } | 119 } |
114 | 120 |
115 // We were attached prior to the page load -> init agents with Document. | 121 // We were attached prior to the page load -> init agents with Document. |
116 Document* doc; | 122 Document* doc; |
117 if (ready) { | 123 if (ready) { |
118 Page* page = web_view_impl_->page(); | 124 Page* page = web_view_impl_->page(); |
119 doc = page->mainFrame()->document(); | 125 doc = page->mainFrame()->document(); |
120 } else { | 126 } else { |
121 doc = NULL; | 127 doc = NULL; |
122 } | 128 } |
123 debugger_agent_impl_->ResetUtilityContext(doc, &utility_context_); | 129 debugger_agent_impl_->ResetUtilityContext(doc, &utility_context_); |
124 dom_agent_impl_->SetDocument(doc); | 130 dom_agent_impl_->SetDocument(doc); |
125 net_agent_impl_->SetDocument(doc); | |
126 } | 131 } |
127 | 132 |
128 void WebDevToolsAgentImpl::DidCommitLoadForFrame( | 133 void WebDevToolsAgentImpl::DidCommitLoadForFrame( |
129 WebViewImpl* webview, | 134 WebViewImpl* webview, |
130 WebFrame* frame, | 135 WebFrame* frame, |
131 bool is_new_navigation) { | 136 bool is_new_navigation) { |
132 if (webview->GetMainFrame() == frame) { | |
133 net_agent_impl_->DidCommitMainResourceLoad(); | |
134 } | |
135 if (!attached_) { | 137 if (!attached_) { |
136 return; | 138 return; |
137 } | 139 } |
138 WebDataSource* ds = frame->GetDataSource(); | 140 WebDataSource* ds = frame->GetDataSource(); |
139 const WebRequest& request = ds->GetRequest(); | 141 const WebRequest& request = ds->GetRequest(); |
140 GURL url = ds->HasUnreachableURL() ? | 142 GURL url = ds->HasUnreachableURL() ? |
141 ds->GetUnreachableURL() : | 143 ds->GetUnreachableURL() : |
142 request.GetURL(); | 144 request.GetURL(); |
143 tools_agent_delegate_stub_->FrameNavigate( | 145 tools_agent_delegate_stub_->FrameNavigate( |
144 url.possibly_invalid_spec(), | 146 url.possibly_invalid_spec(), |
145 webview->GetMainFrame() == frame); | 147 webview->GetMainFrame() == frame); |
146 } | 148 } |
147 | 149 |
148 void WebDevToolsAgentImpl::AddMessageToConsole( | |
149 int source, | |
150 int level, | |
151 const String& text, | |
152 unsigned int line_no, | |
153 const String& source_id) { | |
154 ConsoleMessage cm(source, level, text, line_no, source_id); | |
155 console_log_.append(cm); | |
156 if (console_log_.size() >= kMaxConsoleMessages) { | |
157 // Batch shifts to save ticks. | |
158 console_log_.remove(0, kMaxConsoleMessages / 5); | |
159 } | |
160 if (attached_) { | |
161 DictionaryValue message; | |
162 Serialize(cm, &message); | |
163 tools_agent_delegate_stub_->AddMessageToConsole(message); | |
164 } | |
165 } | |
166 | |
167 void WebDevToolsAgentImpl::WindowObjectCleared(WebFrameImpl* webframe) { | 150 void WebDevToolsAgentImpl::WindowObjectCleared(WebFrameImpl* webframe) { |
168 DebuggerAgentManager::SetHostId(webframe, host_id_); | 151 DebuggerAgentManager::SetHostId(webframe, host_id_); |
169 } | 152 } |
170 | 153 |
171 void WebDevToolsAgentImpl::ForceRepaint() { | 154 void WebDevToolsAgentImpl::ForceRepaint() { |
172 delegate_->ForceRepaint(); | 155 delegate_->ForceRepaint(); |
173 } | 156 } |
174 | 157 |
175 void WebDevToolsAgentImpl::HighlightDOMNode(int node_id) { | 158 void WebDevToolsAgentImpl::HighlightDOMNode(int node_id) { |
176 if (!attached_) { | 159 if (!attached_) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 String exception; | 202 String exception; |
220 if (node) { | 203 if (node) { |
221 result = debugger_agent_impl_->ExecuteUtilityFunction(utility_context_, | 204 result = debugger_agent_impl_->ExecuteUtilityFunction(utility_context_, |
222 function_name, node, json_args, &exception); | 205 function_name, node, json_args, &exception); |
223 } | 206 } |
224 tools_agent_delegate_stub_->DidExecuteUtilityFunction(call_id, | 207 tools_agent_delegate_stub_->DidExecuteUtilityFunction(call_id, |
225 result, exception); | 208 result, exception); |
226 } | 209 } |
227 | 210 |
228 void WebDevToolsAgentImpl::ClearConsoleMessages() { | 211 void WebDevToolsAgentImpl::ClearConsoleMessages() { |
229 console_log_.clear(); | 212 Page* page = web_view_impl_->page(); |
| 213 if (page) { |
| 214 page->inspectorController()->clearConsoleMessages(); |
| 215 } |
| 216 } |
| 217 |
| 218 void WebDevToolsAgentImpl::GetResourceContent( |
| 219 int call_id, |
| 220 int identifier) { |
| 221 Page* page = web_view_impl_->page(); |
| 222 if (!page) { |
| 223 return; |
| 224 } |
| 225 RefPtr<InspectorResource> resource = |
| 226 page->inspectorController()->resources().get(identifier); |
| 227 if (resource.get()) { |
| 228 tools_agent_delegate_stub_->DidGetResourceContent(call_id, |
| 229 resource->sourceString()); |
| 230 } |
230 } | 231 } |
231 | 232 |
232 void WebDevToolsAgentImpl::DispatchMessageFromClient( | 233 void WebDevToolsAgentImpl::DispatchMessageFromClient( |
233 const std::string& raw_msg) { | 234 const std::string& raw_msg) { |
234 OwnPtr<ListValue> message( | 235 OwnPtr<ListValue> message( |
235 static_cast<ListValue*>(DevToolsRpc::ParseMessage(raw_msg))); | 236 static_cast<ListValue*>(DevToolsRpc::ParseMessage(raw_msg))); |
236 if (ToolsAgentDispatch::Dispatch(this, *message.get())) { | 237 if (ToolsAgentDispatch::Dispatch(this, *message.get())) { |
237 return; | 238 return; |
238 } | 239 } |
239 | 240 |
240 if (!attached_) { | 241 if (!attached_) { |
241 return; | 242 return; |
242 } | 243 } |
243 | 244 |
244 if (debugger_agent_impl_.get() && | 245 if (debugger_agent_impl_.get() && |
245 DebuggerAgentDispatch::Dispatch( | 246 DebuggerAgentDispatch::Dispatch( |
246 debugger_agent_impl_.get(), | 247 debugger_agent_impl_.get(), |
247 *message.get())) { | 248 *message.get())) { |
248 return; | 249 return; |
249 } | 250 } |
250 | 251 |
251 if (DomAgentDispatch::Dispatch(dom_agent_impl_.get(), *message.get())) { | 252 if (DomAgentDispatch::Dispatch(dom_agent_impl_.get(), *message.get())) { |
252 return; | 253 return; |
253 } | 254 } |
254 if (NetAgentDispatch::Dispatch(net_agent_impl_.get(), *message.get())) { | |
255 return; | |
256 } | |
257 } | 255 } |
258 | 256 |
259 void WebDevToolsAgentImpl::InspectElement(int x, int y) { | 257 void WebDevToolsAgentImpl::InspectElement(int x, int y) { |
260 Node* node = web_view_impl_->GetNodeForWindowPos(x, y); | 258 Node* node = web_view_impl_->GetNodeForWindowPos(x, y); |
261 if (!node) { | 259 if (!node) { |
262 return; | 260 return; |
263 } | 261 } |
264 | 262 |
265 int node_id = dom_agent_impl_->PushNodePathToClient(node); | 263 int node_id = dom_agent_impl_->PushNodePathToClient(node); |
266 tools_agent_delegate_stub_->UpdateFocusedNode(node_id); | 264 tools_agent_delegate_stub_->UpdateFocusedNode(node_id); |
267 } | 265 } |
268 | 266 |
269 void WebDevToolsAgentImpl::SendRpcMessage(const std::string& raw_msg) { | 267 void WebDevToolsAgentImpl::SendRpcMessage(const std::string& raw_msg) { |
270 delegate_->SendMessageToClient(raw_msg); | 268 delegate_->SendMessageToClient(raw_msg); |
271 } | 269 } |
272 | 270 |
273 // static | 271 // static |
274 void WebDevToolsAgentImpl::Serialize(const ConsoleMessage& message, | 272 v8::Handle<v8::Value> WebDevToolsAgentImpl::JsDispatchOnClient( |
275 DictionaryValue* value) { | 273 const v8::Arguments& args) { |
276 value->SetInteger(L"source", message.source); | 274 v8::TryCatch exception_catcher; |
277 value->SetInteger(L"level", message.level); | 275 String message = WebCore::toWebCoreStringWithNullCheck(args[0]); |
278 value->SetString(L"text", webkit_glue::StringToStdString(message.text)); | 276 if (message.isEmpty() || exception_catcher.HasCaught()) { |
279 value->SetString(L"sourceId", | 277 return v8::Undefined(); |
280 webkit_glue::StringToStdString(message.source_id)); | 278 } |
281 value->SetInteger(L"line", message.line_no); | 279 WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>( |
| 280 v8::External::Cast(*args.Data())->Value()); |
| 281 agent->tools_agent_delegate_stub_->DispatchOnClient(message); |
| 282 return v8::Undefined(); |
282 } | 283 } |
283 | 284 |
284 // static | 285 // static |
285 void WebDevToolsAgent::ExecuteDebuggerCommand( | 286 void WebDevToolsAgent::ExecuteDebuggerCommand( |
286 const std::string& command, | 287 const std::string& command, |
287 int caller_id) { | 288 int caller_id) { |
288 DebuggerAgentManager::ExecuteDebuggerCommand(command, caller_id); | 289 DebuggerAgentManager::ExecuteDebuggerCommand(command, caller_id); |
289 } | 290 } |
290 | 291 |
291 // static | 292 // static |
292 void WebDevToolsAgent::SetMessageLoopDispatchHandler( | 293 void WebDevToolsAgent::SetMessageLoopDispatchHandler( |
293 MessageLoopDispatchHandler handler) { | 294 MessageLoopDispatchHandler handler) { |
294 DebuggerAgentManager::SetMessageLoopDispatchHandler(handler); | 295 DebuggerAgentManager::SetMessageLoopDispatchHandler(handler); |
295 } | 296 } |
OLD | NEW |