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. 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 56 ShellDevToolsFrontend* ShellDevToolsFrontend::Show( 57 WebContents* inspected_contents) { 58 return ShellDevToolsFrontend::Show(inspected_contents, "", ""); 59 } 60 61 // static 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 88 void ShellDevToolsFrontend::Activate() { 89 frontend_shell_->ActivateContents(web_contents()); 90 } 91 92 void ShellDevToolsFrontend::Focus() { 93 web_contents()->Focus(); 94 } 95 96 void ShellDevToolsFrontend::InspectElementAt(int x, int y) { 97 agent_host_->InspectElement(x, y); 98 } 99 100 void ShellDevToolsFrontend::Close() { 101 frontend_shell_->Close(); 102 } 103 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 113 ShellDevToolsFrontend::~ShellDevToolsFrontend() { 114 } 115 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 125 void ShellDevToolsFrontend::DocumentOnLoadCompletedInMainFrame() { 126 web_contents()->GetMainFrame()->ExecuteJavaScript( 127 base::ASCIIToUTF16("InspectorFrontendAPI.setUseSoftMenu(true);")); 128 } 129 130 void ShellDevToolsFrontend::WebContentsDestroyed() { 131 DevToolsManager::GetInstance()->ClientHostClosing(frontend_host_.get()); 132 delete this; 133 } 134 135 void ShellDevToolsFrontend::RenderProcessGone(base::TerminationStatus status) { 136 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) 137 WebKitTestController::Get()->DevToolsProcessCrashed(); 138 } 139 140 void ShellDevToolsFrontend::InspectedContentsClosing() { 141 frontend_shell_->Close(); 142 } 143 144 } // namespace content 145