1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/shell/browser/shell_devtools_frontend.h"
6
7 #include "base/command_line.h"
8 #include "base/path_service.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/public/browser/devtools_http_handler.h"
12 #include "content/public/browser/devtools_manager.h"
13 #include "content/public/browser/render_frame_host.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/common/content_client.h"
17 #include "content/shell/browser/shell.h"
18 #include "content/shell/browser/shell_browser_context.h"
19 #include "content/shell/browser/shell_browser_main_parts.h"
20 #include "content/shell/browser/shell_content_browser_client.h"
21 #include "content/shell/browser/shell_devtools_delegate.h"
22 #include "content/shell/browser/webkit_test_controller.h"
23 #include "content/shell/common/shell_switches.h"
24 #include "net/base/filename_util.h"
25
26 namespace content {
27
28 // DevTools frontend path for inspector LayoutTests.
GetDevToolsPathAsURL(const std::string & settings,const std::string & frontend_url)29 GURL GetDevToolsPathAsURL(const std::string& settings,
30 const std::string& frontend_url) {
31 if (!frontend_url.empty())
32 return GURL(frontend_url);
33 base::FilePath dir_exe;
34 if (!PathService::Get(base::DIR_EXE, &dir_exe)) {
35 NOTREACHED();
36 return GURL();
37 }
38 #if defined(OS_MACOSX)
39 // On Mac, the executable is in
40 // out/Release/Content Shell.app/Contents/MacOS/Content Shell.
41 // We need to go up 3 directories to get to out/Release.
42 dir_exe = dir_exe.AppendASCII("../../..");
43 #endif
44 base::FilePath dev_tools_path = dir_exe.AppendASCII(
45 "resources/inspector/devtools.html");
46
47 GURL result = net::FilePathToFileURL(dev_tools_path);
48 if (!settings.empty())
49 result = GURL(base::StringPrintf("%s?settings=%s",
50 result.spec().c_str(),
51 settings.c_str()));
52 return result;
53 }
54
55 // static
Show(WebContents * inspected_contents)56 ShellDevToolsFrontend* ShellDevToolsFrontend::Show(
57 WebContents* inspected_contents) {
58 return ShellDevToolsFrontend::Show(inspected_contents, "", "");
59 }
60
61 // static
Show(WebContents * inspected_contents,const std::string & settings,const std::string & frontend_url)62 ShellDevToolsFrontend* ShellDevToolsFrontend::Show(
63 WebContents* inspected_contents,
64 const std::string& settings,
65 const std::string& frontend_url) {
66 scoped_refptr<DevToolsAgentHost> agent(
67 DevToolsAgentHost::GetOrCreateFor(
68 inspected_contents->GetRenderViewHost()));
69 Shell* shell = Shell::CreateNewWindow(inspected_contents->GetBrowserContext(),
70 GURL(),
71 NULL,
72 MSG_ROUTING_NONE,
73 gfx::Size());
74 ShellDevToolsFrontend* devtools_frontend = new ShellDevToolsFrontend(
75 shell,
76 agent.get());
77
78 ShellDevToolsDelegate* delegate = ShellContentBrowserClient::Get()->
79 shell_browser_main_parts()->devtools_delegate();
80 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
81 shell->LoadURL(GetDevToolsPathAsURL(settings, frontend_url));
82 else
83 shell->LoadURL(delegate->devtools_http_handler()->GetFrontendURL());
84
85 return devtools_frontend;
86 }
87
Activate()88 void ShellDevToolsFrontend::Activate() {
89 frontend_shell_->ActivateContents(web_contents());
90 }
91
Focus()92 void ShellDevToolsFrontend::Focus() {
93 web_contents()->Focus();
94 }
95
InspectElementAt(int x,int y)96 void ShellDevToolsFrontend::InspectElementAt(int x, int y) {
97 agent_host_->InspectElement(x, y);
98 }
99
Close()100 void ShellDevToolsFrontend::Close() {
101 frontend_shell_->Close();
102 }
103
ShellDevToolsFrontend(Shell * frontend_shell,DevToolsAgentHost * agent_host)104 ShellDevToolsFrontend::ShellDevToolsFrontend(Shell* frontend_shell,
105 DevToolsAgentHost* agent_host)
106 : WebContentsObserver(frontend_shell->web_contents()),
107 frontend_shell_(frontend_shell),
108 agent_host_(agent_host) {
109 frontend_host_.reset(
110 DevToolsClientHost::CreateDevToolsFrontendHost(web_contents(), this));
111 }
112
~ShellDevToolsFrontend()113 ShellDevToolsFrontend::~ShellDevToolsFrontend() {
114 }
115
RenderViewCreated(RenderViewHost * render_view_host)116 void ShellDevToolsFrontend::RenderViewCreated(
117 RenderViewHost* render_view_host) {
118 DevToolsClientHost::SetupDevToolsFrontendClient(
119 web_contents()->GetRenderViewHost());
120 DevToolsManager* manager = DevToolsManager::GetInstance();
121 manager->RegisterDevToolsClientHostFor(agent_host_.get(),
122 frontend_host_.get());
123 }
124
DocumentOnLoadCompletedInMainFrame()125 void ShellDevToolsFrontend::DocumentOnLoadCompletedInMainFrame() {
126 web_contents()->GetMainFrame()->ExecuteJavaScript(
127 base::ASCIIToUTF16("InspectorFrontendAPI.setUseSoftMenu(true);"));
128 }
129
WebContentsDestroyed()130 void ShellDevToolsFrontend::WebContentsDestroyed() {
131 DevToolsManager::GetInstance()->ClientHostClosing(frontend_host_.get());
132 delete this;
133 }
134
RenderProcessGone(base::TerminationStatus status)135 void ShellDevToolsFrontend::RenderProcessGone(base::TerminationStatus status) {
136 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
137 WebKitTestController::Get()->DevToolsProcessCrashed();
138 }
139
InspectedContentsClosing()140 void ShellDevToolsFrontend::InspectedContentsClosing() {
141 frontend_shell_->Close();
142 }
143
144 } // namespace content
145