blob: 7fe9722c1a60c1f3a48edadf3c4fe86e317411d3 [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]7c17b6992012-08-09 16:16:3011#include "base/string_number_conversions.h"
[email protected]9fbd3f862011-09-20 23:31:3412#include "base/string_util.h"
[email protected]c272c5b2012-06-06 09:01:0613#include "base/utf_string_conversions.h"
[email protected]7c17b6992012-08-09 16:16:3014#include "content/public/browser/devtools_http_handler.h"
[email protected]aecc085b2012-06-01 18:15:5315#include "content/public/browser/navigation_entry.h"
[email protected]0b659b32012-03-26 21:29:3216#include "content/public/browser/navigation_controller.h"
[email protected]aecc085b2012-06-01 18:15:5317#include "content/public/browser/notification_details.h"
18#include "content/public/browser/notification_source.h"
19#include "content/public/browser/notification_types.h"
[email protected]0b659b32012-03-26 21:29:3220#include "content/public/browser/render_view_host.h"
21#include "content/public/browser/web_contents.h"
[email protected]7c17b6992012-08-09 16:16:3022#include "content/shell/shell_browser_main_parts.h"
23#include "content/shell/shell_content_browser_client.h"
24#include "content/shell/shell_devtools_delegate.h"
[email protected]f2210022012-03-29 00:36:0825#include "content/shell/shell_javascript_dialog_creator.h"
[email protected]efb5f572012-01-29 10:57:3326#include "content/shell/shell_messages.h"
27#include "content/shell/shell_switches.h"
[email protected]9fbd3f862011-09-20 23:31:3428#include "ui/gfx/size.h"
29
[email protected]9fbd3f862011-09-20 23:31:3430// Content area size for newly created windows.
31static const int kTestWindowWidth = 800;
32static const int kTestWindowHeight = 600;
33
34namespace content {
35
[email protected]e99ca5112011-09-26 17:22:5436std::vector<Shell*> Shell::windows_;
[email protected]9e00e6352012-07-30 17:05:1837base::Callback<void(Shell*)> Shell::shell_created_callback_;
[email protected]9fbd3f862011-09-20 23:31:3438
[email protected]11a65b692012-03-30 11:29:1639bool Shell::quit_message_loop_ = true;
40
[email protected]0b659b32012-03-26 21:29:3241Shell::Shell(WebContents* web_contents)
[email protected]c272c5b2012-06-06 09:01:0642 : window_(NULL),
[email protected]46d04fa2011-10-06 18:32:4343 url_edit_view_(NULL)
[email protected]fa4a45832012-04-12 21:32:4844#if defined(OS_WIN) && !defined(USE_AURA)
[email protected]9fbd3f862011-09-20 23:31:3445 , default_edit_wnd_proc_(0)
46#endif
47 {
[email protected]9e00e6352012-07-30 17:05:1848 registrar_.Add(this, NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
49 Source<WebContents>(web_contents));
50 windows_.push_back(this);
51
52 if (!shell_created_callback_.is_null()) {
53 shell_created_callback_.Run(this);
54 shell_created_callback_.Reset();
55 }
[email protected]9fbd3f862011-09-20 23:31:3456}
57
58Shell::~Shell() {
59 PlatformCleanUp();
[email protected]e99ca5112011-09-26 17:22:5460
61 for (size_t i = 0; i < windows_.size(); ++i) {
62 if (windows_[i] == this) {
63 windows_.erase(windows_.begin() + i);
64 break;
65 }
66 }
[email protected]11a65b692012-03-30 11:29:1667
68 if (windows_.empty() && quit_message_loop_)
69 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
[email protected]9fbd3f862011-09-20 23:31:3470}
71
[email protected]0b659b32012-03-26 21:29:3272Shell* Shell::CreateShell(WebContents* web_contents) {
73 Shell* shell = new Shell(web_contents);
[email protected]3fd84032012-01-12 18:20:1774 shell->PlatformCreateWindow(kTestWindowWidth, kTestWindowHeight);
75
[email protected]0b659b32012-03-26 21:29:3276 shell->web_contents_.reset(web_contents);
77 web_contents->SetDelegate(shell);
[email protected]3fd84032012-01-12 18:20:1778
[email protected]5cba3bf2012-01-14 02:40:3579 shell->PlatformSetContents();
[email protected]3fd84032012-01-12 18:20:1780
81 shell->PlatformResizeSubViews();
82 return shell;
83}
84
[email protected]11a65b692012-03-30 11:29:1685void Shell::CloseAllWindows() {
86 AutoReset<bool> auto_reset(&quit_message_loop_, false);
87 std::vector<Shell*> open_windows(windows_);
88 for (size_t i = 0; i < open_windows.size(); ++i)
89 open_windows[i]->Close();
90 MessageLoop::current()->RunAllPending();
91}
92
[email protected]9e00e6352012-07-30 17:05:1893void Shell::SetShellCreatedCallback(
94 base::Callback<void(Shell*)> shell_created_callback) {
95 DCHECK(shell_created_callback_.is_null());
96 shell_created_callback_ = shell_created_callback;
97}
98
[email protected]74830f02012-01-30 22:27:0499Shell* Shell::FromRenderViewHost(RenderViewHost* rvh) {
100 for (size_t i = 0; i < windows_.size(); ++i) {
[email protected]0b659b32012-03-26 21:29:32101 if (windows_[i]->web_contents() &&
102 windows_[i]->web_contents()->GetRenderViewHost() == rvh) {
[email protected]74830f02012-01-30 22:27:04103 return windows_[i];
104 }
105 }
106 return NULL;
107}
108
[email protected]bdcf9152012-07-19 17:43:21109Shell* Shell::CreateNewWindow(BrowserContext* browser_context,
[email protected]e99ca5112011-09-26 17:22:54110 const GURL& url,
111 SiteInstance* site_instance,
112 int routing_id,
[email protected]0b659b32012-03-26 21:29:32113 WebContents* base_web_contents) {
114 WebContents* web_contents = WebContents::Create(
[email protected]9fbd3f862011-09-20 23:31:34115 browser_context,
[email protected]e99ca5112011-09-26 17:22:54116 site_instance,
117 routing_id,
[email protected]0b659b32012-03-26 21:29:32118 base_web_contents,
[email protected]3fd84032012-01-12 18:20:17119 NULL);
[email protected]0b659b32012-03-26 21:29:32120 Shell* shell = CreateShell(web_contents);
[email protected]e99ca5112011-09-26 17:22:54121 if (!url.is_empty())
122 shell->LoadURL(url);
[email protected]9fbd3f862011-09-20 23:31:34123 return shell;
124}
125
126void Shell::LoadURL(const GURL& url) {
[email protected]0b659b32012-03-26 21:29:32127 web_contents_->GetController().LoadURL(
[email protected]9fbd3f862011-09-20 23:31:34128 url,
[email protected]bdcf9152012-07-19 17:43:21129 Referrer(),
130 PAGE_TRANSITION_TYPED,
[email protected]9fbd3f862011-09-20 23:31:34131 std::string());
[email protected]0b659b32012-03-26 21:29:32132 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34133}
134
135void Shell::GoBackOrForward(int offset) {
[email protected]0b659b32012-03-26 21:29:32136 web_contents_->GetController().GoToOffset(offset);
137 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34138}
139
140void Shell::Reload() {
[email protected]0b659b32012-03-26 21:29:32141 web_contents_->GetController().Reload(false);
142 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34143}
144
145void Shell::Stop() {
[email protected]0b659b32012-03-26 21:29:32146 web_contents_->Stop();
147 web_contents_->Focus();
[email protected]9fbd3f862011-09-20 23:31:34148}
149
150void Shell::UpdateNavigationControls() {
[email protected]0b659b32012-03-26 21:29:32151 int current_index = web_contents_->GetController().GetCurrentEntryIndex();
152 int max_index = web_contents_->GetController().GetEntryCount() - 1;
[email protected]9fbd3f862011-09-20 23:31:34153
154 PlatformEnableUIControl(BACK_BUTTON, current_index > 0);
155 PlatformEnableUIControl(FORWARD_BUTTON, current_index < max_index);
[email protected]0b659b32012-03-26 21:29:32156 PlatformEnableUIControl(STOP_BUTTON, web_contents_->IsLoading());
[email protected]9fbd3f862011-09-20 23:31:34157}
158
[email protected]7c17b6992012-08-09 16:16:30159void Shell::ShowDevTools() {
160 ShellContentBrowserClient* browser_client =
161 static_cast<ShellContentBrowserClient*>(
162 GetContentClient()->browser());
163 ShellDevToolsDelegate* delegate =
164 browser_client->shell_browser_main_parts()->devtools_delegate();
165 GURL url = delegate->devtools_http_handler()->GetFrontendURL(
166 web_contents()->GetRenderViewHost());
167 CreateNewWindow(
168 web_contents()->GetBrowserContext(),
169 url, NULL, MSG_ROUTING_NONE, NULL);
170}
171
[email protected]9fbd3f862011-09-20 23:31:34172gfx::NativeView Shell::GetContentView() {
[email protected]0b659b32012-03-26 21:29:32173 if (!web_contents_.get())
[email protected]9fbd3f862011-09-20 23:31:34174 return NULL;
[email protected]0b659b32012-03-26 21:29:32175 return web_contents_->GetNativeView();
[email protected]9fbd3f862011-09-20 23:31:34176}
177
[email protected]9e00e6352012-07-30 17:05:18178WebContents* Shell::OpenURLFromTab(WebContents* source,
179 const OpenURLParams& params) {
180 // The only one we implement for now.
181 DCHECK(params.disposition == CURRENT_TAB);
182 source->GetController().LoadURL(
183 params.url, params.referrer, params.transition, std::string());
184 return source;
185}
186
[email protected]2a6bc3e2011-12-28 23:51:33187void Shell::LoadingStateChanged(WebContents* source) {
[email protected]e99ca5112011-09-26 17:22:54188 UpdateNavigationControls();
[email protected]15aea412012-01-19 03:18:50189 PlatformSetIsLoading(source->IsLoading());
[email protected]e99ca5112011-09-26 17:22:54190}
191
[email protected]9e00e6352012-07-30 17:05:18192void Shell::CloseContents(WebContents* source) {
193 Close();
194}
195
[email protected]3fd84032012-01-12 18:20:17196void Shell::WebContentsCreated(WebContents* source_contents,
197 int64 source_frame_id,
198 const GURL& target_url,
199 WebContents* new_contents) {
[email protected]0b659b32012-03-26 21:29:32200 CreateShell(new_contents);
[email protected]3fd84032012-01-12 18:20:17201}
202
[email protected]3bbacc5b2012-04-17 17:46:15203void Shell::DidNavigateMainFramePostCommit(WebContents* web_contents) {
204 PlatformSetAddressBarURL(web_contents->GetURL());
[email protected]e99ca5112011-09-26 17:22:54205}
206
[email protected]f2210022012-03-29 00:36:08207JavaScriptDialogCreator* Shell::GetJavaScriptDialogCreator() {
[email protected]f2210022012-03-29 00:36:08208 if (!dialog_creator_.get())
209 dialog_creator_.reset(new ShellJavaScriptDialogCreator());
210 return dialog_creator_.get();
211}
212
[email protected]c272c5b2012-06-06 09:01:06213bool Shell::AddMessageToConsole(WebContents* source,
214 int32 level,
215 const string16& message,
216 int32 line_no,
217 const string16& source_id) {
[email protected]efb5f572012-01-29 10:57:33218 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
[email protected]c272c5b2012-06-06 09:01:06219 return false;
220
[email protected]0d108edbf2012-07-02 17:41:04221 printf("CONSOLE MESSAGE: ");
[email protected]c272c5b2012-06-06 09:01:06222 if (line_no)
[email protected]0d108edbf2012-07-02 17:41:04223 printf("line %d: ", line_no);
224 printf("%s\n", UTF16ToUTF8(message).c_str());
[email protected]c272c5b2012-06-06 09:01:06225 return true;
[email protected]efb5f572012-01-29 10:57:33226}
227
[email protected]aecc085b2012-06-01 18:15:53228void Shell::Observe(int type,
229 const NotificationSource& source,
230 const NotificationDetails& details) {
231 if (type == NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
232 std::pair<NavigationEntry*, bool>* title =
233 Details<std::pair<NavigationEntry*, bool> >(details).ptr();
234
235 if (title->first) {
236 string16 text = title->first->GetTitle();
237 PlatformSetTitle(text);
238 }
239 }
240}
241
[email protected]9fbd3f862011-09-20 23:31:34242} // namespace content