blob: 69bf1634eb66c297b621bf143b414d4ef940fa55 [file] [log] [blame]
[email protected]5cba3bf2012-01-14 02:40:351// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]9fbd3f862011-09-20 23:31:342// 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/shell.h"
6
[email protected]11a65b692012-03-30 11:29:167#include "base/auto_reset.h"
[email protected]efb5f572012-01-29 10:57:338#include "base/command_line.h"
[email protected]9fbd3f862011-09-20 23:31:349#include "base/message_loop.h"
10#include "base/path_service.h"
[email protected]2cd0d332012-08-30 13:16:5411#include "base/stringprintf.h"
[email protected]7c17b6992012-08-09 16:16:3012#include "base/string_number_conversions.h"
[email protected]9fbd3f862011-09-20 23:31:3413#include "base/string_util.h"
[email protected]c272c5b2012-06-06 09:01:0614#include "base/utf_string_conversions.h"
[email protected]7c17b6992012-08-09 16:16:3015#include "content/public/browser/devtools_http_handler.h"
[email protected]aecc085b2012-06-01 18:15:5316#include "content/public/browser/navigation_entry.h"
[email protected]0b659b32012-03-26 21:29:3217#include "content/public/browser/navigation_controller.h"
[email protected]aecc085b2012-06-01 18:15:5318#include "content/public/browser/notification_details.h"
19#include "content/public/browser/notification_source.h"
20#include "content/public/browser/notification_types.h"
[email protected]0b659b32012-03-26 21:29:3221#include "content/public/browser/render_view_host.h"
22#include "content/public/browser/web_contents.h"
[email protected]7c17b6992012-08-09 16:16:3023#include "content/shell/shell_browser_main_parts.h"
24#include "content/shell/shell_content_browser_client.h"
25#include "content/shell/shell_devtools_delegate.h"
[email protected]f2210022012-03-29 00:36:0826#include "content/shell/shell_javascript_dialog_creator.h"
[email protected]efb5f572012-01-29 10:57:3327#include "content/shell/shell_messages.h"
28#include "content/shell/shell_switches.h"
[email protected]2cd0d332012-08-30 13:16:5429#include "content/shell/webkit_test_runner_host.h"
[email protected]9fbd3f862011-09-20 23:31:3430#include "ui/gfx/size.h"
31
[email protected]9fbd3f862011-09-20 23:31:3432// Content area size for newly created windows.
33static const int kTestWindowWidth = 800;
34static const int kTestWindowHeight = 600;
35
36namespace content {
37
[email protected]e99ca5112011-09-26 17:22:5438std::vector<Shell*> Shell::windows_;
[email protected]9e00e6352012-07-30 17:05:1839base::Callback<void(Shell*)> Shell::shell_created_callback_;
[email protected]9fbd3f862011-09-20 23:31:3440
[email protected]11a65b692012-03-30 11:29:1641bool Shell::quit_message_loop_ = true;
42
[email protected]0b659b32012-03-26 21:29:3243Shell::Shell(WebContents* web_contents)
[email protected]99c014c2012-11-27 12:03:4244 : is_fullscreen_(false),
45 window_(NULL),
[email protected]46d04fa2011-10-06 18:32:4346 url_edit_view_(NULL)
[email protected]fa4a45832012-04-12 21:32:4847#if defined(OS_WIN) && !defined(USE_AURA)
[email protected]9fbd3f862011-09-20 23:31:3448 , default_edit_wnd_proc_(0)
49#endif
50 {
[email protected]9e00e6352012-07-30 17:05:1851 registrar_.Add(this, NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
52 Source<WebContents>(web_contents));
53 windows_.push_back(this);
54
55 if (!shell_created_callback_.is_null()) {
56 shell_created_callback_.Run(this);
57 shell_created_callback_.Reset();
58 }
[email protected]9fbd3f862011-09-20 23:31:3459}
60
61Shell::~Shell() {
62 PlatformCleanUp();
[email protected]e99ca5112011-09-26 17:22:5463
64 for (size_t i = 0; i < windows_.size(); ++i) {
65 if (windows_[i] == this) {
66 windows_.erase(windows_.begin() + i);
67 break;
68 }
69 }
[email protected]11a65b692012-03-30 11:29:1670
71 if (windows_.empty() && quit_message_loop_)
72 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
[email protected]9fbd3f862011-09-20 23:31:3473}
74
[email protected]0b659b32012-03-26 21:29:3275Shell* Shell::CreateShell(WebContents* web_contents) {
76 Shell* shell = new Shell(web_contents);
[email protected]3fd84032012-01-12 18:20:1777 shell->PlatformCreateWindow(kTestWindowWidth, kTestWindowHeight);
78
[email protected]0b659b32012-03-26 21:29:3279 shell->web_contents_.reset(web_contents);
80 web_contents->SetDelegate(shell);
[email protected]3fd84032012-01-12 18:20:1781
[email protected]5cba3bf2012-01-14 02:40:3582 shell->PlatformSetContents();
[email protected]3fd84032012-01-12 18:20:1783
84 shell->PlatformResizeSubViews();
85 return shell;
86}
87
[email protected]11a65b692012-03-30 11:29:1688void Shell::CloseAllWindows() {
[email protected]997ec9f2012-11-21 04:44:1489 base::AutoReset<bool> auto_reset(&quit_message_loop_, false);
[email protected]11a65b692012-03-30 11:29:1690 std::vector<Shell*> open_windows(windows_);
91 for (size_t i = 0; i < open_windows.size(); ++i)
92 open_windows[i]->Close();
[email protected]f319ace2012-11-10 19:07:2993 MessageLoop::current()->RunUntilIdle();
[email protected]11a65b692012-03-30 11:29:1694}
95
[email protected]9e00e6352012-07-30 17:05:1896void Shell::SetShellCreatedCallback(
97 base::Callback<void(Shell*)> shell_created_callback) {
98 DCHECK(shell_created_callback_.is_null());
99 shell_created_callback_ = shell_created_callback;
100}
101
[email protected]74830f02012-01-30 22:27:04102Shell* Shell::FromRenderViewHost(RenderViewHost* rvh) {
103 for (size_t i = 0; i < windows_.size(); ++i) {
[email protected]0b659b32012-03-26 21:29:32104 if (windows_[i]->web_contents() &&
105 windows_[i]->web_contents()->GetRenderViewHost() == rvh) {
[email protected]74830f02012-01-30 22:27:04106 return windows_[i];
107 }
108 }
109 return NULL;
110}
111
[email protected]bdcf9152012-07-19 17:43:21112Shell* Shell::CreateNewWindow(BrowserContext* browser_context,
[email protected]e99ca5112011-09-26 17:22:54113 const GURL& url,
114 SiteInstance* site_instance,
115 int routing_id,
[email protected]0b659b32012-03-26 21:29:32116 WebContents* base_web_contents) {
117 WebContents* web_contents = WebContents::Create(
[email protected]9fbd3f862011-09-20 23:31:34118 browser_context,
[email protected]e99ca5112011-09-26 17:22:54119 site_instance,
120 routing_id,
[email protected]d1198fd2012-08-13 22:50:19121 base_web_contents);
[email protected]0b659b32012-03-26 21:29:32122 Shell* shell = CreateShell(web_contents);
[email protected]e99ca5112011-09-26 17:22:54123 if (!url.is_empty())
124 shell->LoadURL(url);
[email protected]9fbd3f862011-09-20 23:31:34125 return shell;
126}
127
128void Shell::LoadURL(const GURL& url) {
[email protected]0b659b32012-03-26 21:29:32129 web_contents_->GetController().LoadURL(
[email protected]9fbd3f862011-09-20 23:31:34130 url,
[email protected]bdcf9152012-07-19 17:43:21131 Referrer(),
[email protected]8d57530e2012-08-20 19:43:58132 static_cast<PageTransition>(
133 PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR),
[email protected]9fbd3f862011-09-20 23:31:34134 std::string());
[email protected]0b659b32012-03-26 21:29:32135 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34136}
137
138void Shell::GoBackOrForward(int offset) {
[email protected]0b659b32012-03-26 21:29:32139 web_contents_->GetController().GoToOffset(offset);
140 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34141}
142
143void Shell::Reload() {
[email protected]0b659b32012-03-26 21:29:32144 web_contents_->GetController().Reload(false);
145 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34146}
147
148void Shell::Stop() {
[email protected]0b659b32012-03-26 21:29:32149 web_contents_->Stop();
150 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34151}
152
153void Shell::UpdateNavigationControls() {
[email protected]0b659b32012-03-26 21:29:32154 int current_index = web_contents_->GetController().GetCurrentEntryIndex();
155 int max_index = web_contents_->GetController().GetEntryCount() - 1;
[email protected]9fbd3f862011-09-20 23:31:34156
157 PlatformEnableUIControl(BACK_BUTTON, current_index > 0);
158 PlatformEnableUIControl(FORWARD_BUTTON, current_index < max_index);
[email protected]0b659b32012-03-26 21:29:32159 PlatformEnableUIControl(STOP_BUTTON, web_contents_->IsLoading());
[email protected]9fbd3f862011-09-20 23:31:34160}
161
[email protected]7c17b6992012-08-09 16:16:30162void Shell::ShowDevTools() {
163 ShellContentBrowserClient* browser_client =
164 static_cast<ShellContentBrowserClient*>(
165 GetContentClient()->browser());
166 ShellDevToolsDelegate* delegate =
167 browser_client->shell_browser_main_parts()->devtools_delegate();
168 GURL url = delegate->devtools_http_handler()->GetFrontendURL(
169 web_contents()->GetRenderViewHost());
170 CreateNewWindow(
171 web_contents()->GetBrowserContext(),
172 url, NULL, MSG_ROUTING_NONE, NULL);
173}
174
[email protected]9fbd3f862011-09-20 23:31:34175gfx::NativeView Shell::GetContentView() {
[email protected]0b659b32012-03-26 21:29:32176 if (!web_contents_.get())
[email protected]9fbd3f862011-09-20 23:31:34177 return NULL;
[email protected]0b659b32012-03-26 21:29:32178 return web_contents_->GetNativeView();
[email protected]9fbd3f862011-09-20 23:31:34179}
180
[email protected]9e00e6352012-07-30 17:05:18181WebContents* Shell::OpenURLFromTab(WebContents* source,
182 const OpenURLParams& params) {
183 // The only one we implement for now.
184 DCHECK(params.disposition == CURRENT_TAB);
185 source->GetController().LoadURL(
186 params.url, params.referrer, params.transition, std::string());
187 return source;
188}
189
[email protected]2a6bc3e2011-12-28 23:51:33190void Shell::LoadingStateChanged(WebContents* source) {
[email protected]e99ca5112011-09-26 17:22:54191 UpdateNavigationControls();
[email protected]15aea412012-01-19 03:18:50192 PlatformSetIsLoading(source->IsLoading());
[email protected]e99ca5112011-09-26 17:22:54193}
194
[email protected]99c014c2012-11-27 12:03:42195void Shell::ToggleFullscreenModeForTab(WebContents* web_contents,
196 bool enter_fullscreen) {
197#if defined(OS_ANDROID)
198 PlatformToggleFullscreenModeForTab(web_contents, enter_fullscreen);
199#endif
200 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
201 return;
202 if (is_fullscreen_ != enter_fullscreen) {
203 is_fullscreen_ = enter_fullscreen;
204 web_contents->GetRenderViewHost()->WasResized();
205 }
206}
207
208bool Shell::IsFullscreenForTabOrPending(const WebContents* web_contents) const {
209#if defined(OS_ANDROID)
210 return PlatformIsFullscreenForTabOrPending(web_contents);
211#else
212 return is_fullscreen_;
213#endif
214}
215
[email protected]f78439002012-11-28 14:45:59216void Shell::RequestToLockMouse(WebContents* web_contents,
217 bool user_gesture,
218 bool last_unlocked_by_target) {
219 web_contents->GotResponseToLockMouseRequest(true);
220}
221
[email protected]9e00e6352012-07-30 17:05:18222void Shell::CloseContents(WebContents* source) {
223 Close();
224}
225
[email protected]067310262012-11-22 14:30:41226bool Shell::CanOverscrollContent() const {
227#if defined(USE_AURA)
228 return true;
229#else
230 return false;
231#endif
232}
233
[email protected]3fd84032012-01-12 18:20:17234void Shell::WebContentsCreated(WebContents* source_contents,
235 int64 source_frame_id,
236 const GURL& target_url,
237 WebContents* new_contents) {
[email protected]0b659b32012-03-26 21:29:32238 CreateShell(new_contents);
[email protected]3fd84032012-01-12 18:20:17239}
240
[email protected]3bbacc5b2012-04-17 17:46:15241void Shell::DidNavigateMainFramePostCommit(WebContents* web_contents) {
242 PlatformSetAddressBarURL(web_contents->GetURL());
[email protected]e99ca5112011-09-26 17:22:54243}
244
[email protected]f2210022012-03-29 00:36:08245JavaScriptDialogCreator* Shell::GetJavaScriptDialogCreator() {
[email protected]f2210022012-03-29 00:36:08246 if (!dialog_creator_.get())
247 dialog_creator_.reset(new ShellJavaScriptDialogCreator());
248 return dialog_creator_.get();
249}
250
[email protected]c272c5b2012-06-06 09:01:06251bool Shell::AddMessageToConsole(WebContents* source,
252 int32 level,
253 const string16& message,
254 int32 line_no,
255 const string16& source_id) {
[email protected]efb5f572012-01-29 10:57:33256 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
[email protected]c272c5b2012-06-06 09:01:06257 return false;
258
[email protected]2cd0d332012-08-30 13:16:54259 std::string buffer("CONSOLE MESSAGE: ");
[email protected]c272c5b2012-06-06 09:01:06260 if (line_no)
[email protected]2cd0d332012-08-30 13:16:54261 buffer += base::StringPrintf("line %d: ", line_no);
262 buffer += UTF16ToUTF8(message);
[email protected]11831062012-09-26 15:20:04263 WebKitTestController::Get()->printer()->AddMessage(buffer);
[email protected]c272c5b2012-06-06 09:01:06264 return true;
[email protected]efb5f572012-01-29 10:57:33265}
266
[email protected]5bf68f22012-08-31 07:38:10267void Shell::RendererUnresponsive(WebContents* source) {
268 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
269 return;
270 WebKitTestController::Get()->RendererUnresponsive();
271}
272
[email protected]aecc085b2012-06-01 18:15:53273void Shell::Observe(int type,
274 const NotificationSource& source,
275 const NotificationDetails& details) {
276 if (type == NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
277 std::pair<NavigationEntry*, bool>* title =
278 Details<std::pair<NavigationEntry*, bool> >(details).ptr();
279
280 if (title->first) {
281 string16 text = title->first->GetTitle();
282 PlatformSetTitle(text);
283 }
284 }
285}
286
[email protected]9fbd3f862011-09-20 23:31:34287} // namespace content