blob: 75e2e0444335e7be35e3d3c1aae2b2a65ff7a9d9 [file] [log] [blame]
[email protected]514576a2010-07-01 22:51:251// Copyright (c) 2010 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]7b5dc002010-11-16 23:08:105#include "chrome/browser/ui/browser.h"
[email protected]c61db1d2009-02-06 03:39:186
[email protected]aca02cf2010-05-03 18:56:017#if defined(OS_WIN)
8#include <shellapi.h>
9#include <windows.h>
10#endif // OS_WIN
11
[email protected]5dcbc02f2010-01-26 22:32:0612#include <algorithm>
13#include <string>
14
[email protected]6289beb2009-06-06 10:04:1515#include "app/animation.h"
[email protected]a92b8642009-05-05 23:38:5616#include "app/l10n_util.h"
[email protected]b02d0382009-11-30 21:19:5017#include "base/base_paths.h"
[email protected]8a53ee042009-01-21 16:41:3318#include "base/command_line.h"
[email protected]8a53ee042009-01-21 16:41:3319#include "base/logging.h"
[email protected]835d7c82010-10-14 04:38:3820#include "base/metrics/histogram.h"
[email protected]b02d0382009-11-30 21:19:5021#include "base/path_service.h"
[email protected]8a53ee042009-01-21 16:41:3322#include "base/string_util.h"
[email protected]b689fce72009-03-17 22:45:3423#include "base/thread.h"
[email protected]a8e4b5a82010-10-27 00:05:4724#include "base/thread_restrictions.h"
[email protected]6524385ef2010-08-18 06:34:1325#include "base/utf_string_conversions.h"
[email protected]e0fc2f12010-03-14 23:30:5926#include "gfx/point.h"
[email protected]1a3aba82010-11-08 23:52:5427#include "chrome/app/chrome_command_ids.h"
[email protected]cf28ec52010-04-09 22:56:3428#include "chrome/browser/autofill/autofill_manager.h"
[email protected]a9afddb2009-02-12 17:49:4229#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]b3ac5c82009-10-08 20:56:5430#include "chrome/browser/bookmarks/bookmark_utils.h"
[email protected]8a53ee042009-01-21 16:41:3331#include "chrome/browser/browser_list.h"
[email protected]5c238752009-06-13 10:29:0732#include "chrome/browser/browser_process.h"
[email protected]c61db1d2009-02-06 03:39:1833#include "chrome/browser/browser_shutdown.h"
[email protected]c98fe6f2009-02-25 20:33:2334#include "chrome/browser/browser_window.h"
[email protected]1518b0d2010-04-02 18:38:5335#include "chrome/browser/browser_url_handler.h"
[email protected]40d59ce52009-03-06 23:20:1436#include "chrome/browser/character_encoding.h"
[email protected]40ecc902009-03-16 13:42:4737#include "chrome/browser/debugger/devtools_manager.h"
[email protected]2a8a98122010-07-16 11:58:4838#include "chrome/browser/debugger/devtools_toggle_action.h"
[email protected]8e48e982009-12-25 11:22:4639#include "chrome/browser/debugger/devtools_window.h"
[email protected]f5bf8ccf2010-02-05 18:19:2540#include "chrome/browser/dom_ui/filebrowse_ui.h"
[email protected]01709112010-10-01 19:34:0741#include "chrome/browser/dom_ui/options/content_settings_handler.h"
[email protected]6c69796d2010-07-16 21:41:1642#include "chrome/browser/download/download_item.h"
[email protected]59560e0b2009-06-04 03:30:2243#include "chrome/browser/download/download_item_model.h"
[email protected]69444cc2009-04-09 20:40:0644#include "chrome/browser/download/download_manager.h"
[email protected]59560e0b2009-06-04 03:30:2245#include "chrome/browser/download/download_shelf.h"
46#include "chrome/browser/download/download_started_animation.h"
[email protected]371ed7a2009-08-25 15:22:4647#include "chrome/browser/extensions/crashed_extension_infobar.h"
[email protected]bb461532010-11-26 21:50:2348#include "chrome/browser/extensions/crx_installer.h"
[email protected]9fd542df2009-09-30 07:32:0149#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]0c6da502009-08-14 22:32:3950#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h"
[email protected]6d7a6042010-08-12 20:12:4251#include "chrome/browser/extensions/extension_host.h"
[email protected]10abd192010-09-30 02:03:4952#include "chrome/browser/extensions/extension_prefs.h"
[email protected]9fd542df2009-09-30 07:32:0153#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]f3c88562009-09-30 23:38:4454#include "chrome/browser/extensions/extensions_service.h"
[email protected]820735792010-07-29 23:40:0155#include "chrome/browser/first_run/first_run.h"
[email protected]f7578f52010-08-30 22:22:4956#include "chrome/browser/google/google_url_tracker.h"
57#include "chrome/browser/google/google_util.h"
[email protected]40bd6582009-12-04 23:49:5158#include "chrome/browser/host_zoom_map.h"
[email protected]6b723f82010-10-05 20:14:2759#include "chrome/browser/instant/instant_controller.h"
[email protected]d938aed92009-01-22 19:49:3360#include "chrome/browser/metrics/user_metrics.h"
[email protected]90f39902009-10-03 04:25:3761#include "chrome/browser/net/browser_url_util.h"
[email protected]a239c3f2009-02-17 22:13:1962#include "chrome/browser/net/url_fixer_upper.h"
[email protected]14a000d2010-04-29 21:44:2463#include "chrome/browser/platform_util.h"
[email protected]37858e52010-08-26 00:22:0264#include "chrome/browser/prefs/pref_service.h"
[email protected]02337592010-09-27 18:38:2565#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
[email protected]8ecad5e2010-12-02 21:18:3366#include "chrome/browser/profiles/profile.h"
[email protected]8cb5d5b2010-02-09 11:36:1667#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]14e60c8d2009-06-29 03:56:5168#include "chrome/browser/renderer_host/site_instance.h"
[email protected]85e921fb82009-02-11 23:19:4469#include "chrome/browser/sessions/session_service.h"
[email protected]c61db1d2009-02-06 03:39:1870#include "chrome/browser/sessions/session_types.h"
[email protected]92926d92010-09-02 18:35:0671#include "chrome/browser/sessions/tab_restore_service.h"
[email protected]066629f2009-10-17 00:28:1372#include "chrome/browser/sync/profile_sync_service.h"
[email protected]40f047972009-11-25 03:54:4073#include "chrome/browser/sync/sync_ui_util.h"
[email protected]0b4d3382010-07-14 16:13:0474#include "chrome/browser/tab_closeable_state_watcher.h"
[email protected]a165a052009-02-18 21:43:0075#include "chrome/browser/tab_contents/interstitial_page.h"
[email protected]c61db1d2009-02-06 03:39:1876#include "chrome/browser/tab_contents/navigation_controller.h"
77#include "chrome/browser/tab_contents/navigation_entry.h"
[email protected]57c6a652009-05-04 07:58:3478#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]81af9392009-04-21 02:37:4579#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]c848d3d92010-09-16 21:57:4580#include "chrome/browser/tabs/tab_strip_model.h"
[email protected]339d6dd2010-11-12 00:41:5881#include "chrome/browser/ui/browser_navigator.h"
[email protected]45300ad42010-12-02 15:51:1482#include "chrome/browser/ui/find_bar/find_bar.h"
83#include "chrome/browser/ui/find_bar/find_bar_controller.h"
[email protected]6a3ec2312010-12-02 19:30:1984#include "chrome/browser/ui/omnibox/location_bar.h"
85#include "chrome/browser/ui/options/options_window.h"
86#include "chrome/browser/ui/status_bubble.h"
87#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]9a800652010-12-02 17:08:4488#include "chrome/browser/ui/tabs/dock_info.h"
[email protected]6a3ec2312010-12-02 19:30:1989#include "chrome/browser/ui/tabs/tab_menu_model.h"
[email protected]9a800652010-12-02 17:08:4490#include "chrome/browser/ui/window_sizer.h"
[email protected]b1b73942010-05-26 20:11:5491#include "chrome/browser/upgrade_detector.h"
[email protected]86b54012009-11-19 09:18:5092#include "chrome/browser/web_applications/web_app.h"
[email protected]d938aed92009-01-22 19:49:3393#include "chrome/common/chrome_constants.h"
94#include "chrome/common/chrome_switches.h"
[email protected]9e823662010-10-13 23:36:0095#include "chrome/common/content_restriction.h"
[email protected]5b1a0e22009-05-26 19:00:5896#include "chrome/common/extensions/extension.h"
[email protected]bfd04a62009-02-01 18:16:5697#include "chrome/common/notification_service.h"
[email protected]d938aed92009-01-22 19:49:3398#include "chrome/common/page_transition_types.h"
[email protected]8a53ee042009-01-21 16:41:3399#include "chrome/common/pref_names.h"
[email protected]b689fce72009-03-17 22:45:34100#include "chrome/common/url_constants.h"
[email protected]bb461532010-11-26 21:50:23101#include "chrome/common/web_apps.h"
[email protected]a3e18c42009-03-04 23:36:05102#include "grit/chromium_strings.h"
103#include "grit/generated_resources.h"
104#include "grit/locale_settings.h"
[email protected]8a53ee042009-01-21 16:41:33105#include "net/base/cookie_monster.h"
[email protected]8a53ee042009-01-21 16:41:33106#include "net/base/net_util.h"
107#include "net/base/registry_controlled_domain.h"
[email protected]cb370a0632010-01-30 08:24:12108#include "net/base/static_cookie_policy.h"
[email protected]8a53ee042009-01-21 16:41:33109#include "net/url_request/url_request_context.h"
[email protected]d938aed92009-01-22 19:49:33110#include "webkit/glue/window_open_disposition.h"
[email protected]8a53ee042009-01-21 16:41:33111
[email protected]c848d3d92010-09-16 21:57:45112#if defined(ENABLE_REMOTING)
113#include "chrome/browser/remoting/remoting_setup_flow.h"
114#endif
115
[email protected]8a53ee042009-01-21 16:41:33116#if defined(OS_WIN)
[email protected]4a0765a2009-05-08 23:12:25117#include "app/win_util.h"
[email protected]36d5e5592010-11-15 20:45:59118#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
[email protected]d27893f62010-07-03 05:47:42119#include "chrome/browser/browser_child_process_host.h"
initial.commit09911bf2008-07-26 23:55:29120#include "chrome/browser/cert_store.h"
[email protected]37936ee2008-09-14 01:09:50121#include "chrome/browser/download/save_package.h"
[email protected]3b073b22009-01-16 03:29:03122#include "chrome/browser/ssl/ssl_error_info.h"
[email protected]12f520c2010-01-06 18:11:15123#include "chrome/browser/shell_integration.h"
[email protected]a5d1e1e2010-09-23 19:34:12124#include "chrome/browser/task_manager/task_manager.h"
[email protected]6a3ec2312010-12-02 19:30:19125#include "chrome/browser/ui/view_ids.h"
126#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
[email protected]8a53ee042009-01-21 16:41:33127#endif // OS_WIN
[email protected]e1acf6f2008-10-27 20:43:33128
[email protected]6a4f5af22009-09-23 22:43:00129#if defined(OS_MACOSX)
[email protected]7d791652010-12-01 16:34:49130#include "chrome/browser/ui/cocoa/find_pasteboard.h"
[email protected]6a4f5af22009-09-23 22:43:00131#endif
132
[email protected]b7969202010-05-14 21:29:26133#if defined(OS_CHROMEOS)
[email protected]57b839a2010-10-04 22:49:45134#include <gdk/gdk.h> // For GdkScreen
[email protected]6a2a61d2010-11-22 03:25:35135#include "chrome/browser/chromeos/boot_times_loader.h"
[email protected]965e4c42010-09-07 21:23:35136#include "chrome/browser/chromeos/cros/cros_library.h"
137#include "chrome/browser/chromeos/cros/login_library.h"
[email protected]024617a2010-08-20 05:08:05138#include "chrome/browser/chromeos/options/language_config_view.h"
[email protected]b7969202010-05-14 21:29:26139#endif
140
[email protected]8a53ee042009-01-21 16:41:33141using base::TimeDelta;
initial.commit09911bf2008-07-26 23:55:29142
[email protected]36b6dcb2008-11-12 01:19:57143///////////////////////////////////////////////////////////////////////////////
initial.commit09911bf2008-07-26 23:55:29144
[email protected]505323e22009-01-24 02:47:58145namespace {
146
[email protected]91a79232010-11-10 18:15:08147// The URL to be loaded to display Help.
148#if defined(OS_CHROMEOS)
149const char kHelpContentUrl[] =
[email protected]106104b2010-11-30 19:33:50150 "chrome-extension://oonnajkebngbfpmcpekfdeofeannbapp/main.html";
[email protected]91a79232010-11-10 18:15:08151const char kHelpContentOnlineUrl[] =
152 "http://www.google.com/support/chromeos/";
153#else
154const char kHelpContentUrl[] =
155 "http://www.google.com/support/chrome/";
156#endif
157
158// The URL to be opened when the Help link on the Autofill dialog is clicked.
159const char kAutofillHelpUrl[] =
160#if defined(OS_CHROMEOS)
161 "http://www.google.com/support/chromeos/bin/answer.py?answer=142893";
162#else
163 "http://www.google.com/support/chrome/bin/answer.py?answer=142893";
164#endif
165
166// The URL to be loaded to display the "Report a broken page" form.
167const char kBrokenPageUrl[] =
168 "http://www.google.com/support/chrome/bin/request.py?contact_type="
169 "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2";
170
171// The URL for the privacy dashboard.
172const char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard";
173
174// How long we wait before updating the browser chrome while loading a page.
175const int kUIUpdateCoalescingTimeMS = 200;
176
177const char kHashMark[] = "#";
178
[email protected]57b839a2010-10-04 22:49:45179#if defined(OS_CHROMEOS)
180// If a popup window is bigger than this fraction of the screen on chrome os,
181// turn it into a tab
182const float kPopupMaxWidthFactor = 0.5;
183const float kPopupMaxHeightFactor = 0.6;
184#endif
185
[email protected]505323e22009-01-24 02:47:58186// Returns true if the specified TabContents has unload listeners registered.
187bool TabHasUnloadListener(TabContents* contents) {
[email protected]57c6a652009-05-04 07:58:34188 return contents->notify_disconnection() &&
189 !contents->showing_interstitial_page() &&
190 !contents->render_view_host()->SuddenTerminationAllowed();
[email protected]505323e22009-01-24 02:47:58191}
192
193} // namespace
194
[email protected]e838eaf2010-10-13 18:53:33195extern bool g_log_bug53991;
196
[email protected]36b6dcb2008-11-12 01:19:57197///////////////////////////////////////////////////////////////////////////////
198// Browser, Constructors, Creation, Showing:
initial.commit09911bf2008-07-26 23:55:29199
[email protected]299dabd2008-11-19 02:27:16200Browser::Browser(Type type, Profile* profile)
[email protected]15952e462008-11-14 00:29:05201 : type_(type),
202 profile_(profile),
[email protected]f3e99e32008-07-30 04:48:39203 window_(NULL),
[email protected]ecc523f62010-09-28 22:45:40204 ALLOW_THIS_IN_INITIALIZER_LIST(
205 tab_handler_(TabHandler::CreateTabHandler(this))),
[email protected]1fc025202009-01-20 23:03:14206 command_updater_(this),
initial.commit09911bf2008-07-26 23:55:29207 toolbar_model_(this),
[email protected]15952e462008-11-14 00:29:05208 chrome_updater_factory_(this),
209 is_attempting_to_close_browser_(false),
[email protected]69444cc2009-04-09 20:40:06210 cancel_download_confirmation_state_(NOT_PROMPTED),
[email protected]2e716622009-03-09 21:11:01211 maximized_state_(MAXIMIZED_STATE_DEFAULT),
[email protected]867125a02009-12-10 06:01:48212 method_factory_(this),
213 block_command_execution_(false),
214 last_blocked_command_id_(-1),
[email protected]eabfdae92009-12-11 06:13:51215 last_blocked_command_disposition_(CURRENT_TAB),
[email protected]f075fe0a22010-04-26 04:06:43216 pending_web_app_action_(NONE),
217 extension_app_(NULL) {
[email protected]0cb94102009-05-22 19:51:21218 registrar_.Add(this, NotificationType::SSL_VISIBLE_STATE_CHANGED,
219 NotificationService::AllSources());
[email protected]0c6da502009-08-14 22:32:39220 registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
221 NotificationService::AllSources());
[email protected]ad0c2e1b2010-01-30 00:00:10222 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
223 NotificationService::AllSources());
[email protected]0cb94102009-05-22 19:51:21224 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
225 NotificationService::AllSources());
[email protected]b723ee82009-11-20 16:42:50226 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
227 NotificationService::AllSources());
[email protected]a4ed6282009-12-14 20:51:16228 registrar_.Add(this, NotificationType::EXTENSION_PROCESS_TERMINATED,
[email protected]371ed7a2009-08-25 15:22:46229 NotificationService::AllSources());
[email protected]e001d412009-06-26 20:53:25230 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
231 NotificationService::AllSources());
[email protected]e587a45f2009-10-30 22:34:41232 registrar_.Add(this, NotificationType::PROFILE_ERROR,
[email protected]0e30ef72009-09-05 00:05:08233 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29234
[email protected]91e1bd82009-09-03 22:04:40235 // Need to know when to alert the user of theme install delay.
236 registrar_.Add(this, NotificationType::EXTENSION_READY_FOR_INSTALL,
237 NotificationService::AllSources());
238
[email protected]9e823662010-10-13 23:36:00239 PrefService* local_state = g_browser_process->local_state();
240 if (local_state)
241 printing_enabled_.Init(prefs::kPrintingEnabled, local_state, this);
[email protected]543432ee2010-10-22 16:32:13242 dev_tools_disabled_.Init(prefs::kDevToolsDisabled,
243 profile_->GetPrefs(), this);
[email protected]9e823662010-10-13 23:36:00244
initial.commit09911bf2008-07-26 23:55:29245 InitCommandState();
246 BrowserList::AddBrowser(this);
247
248 encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
249 profile_->GetPrefs(), NULL);
[email protected]b9c505b2010-04-30 15:05:10250 use_vertical_tabs_.Init(prefs::kUseVerticalTabs, profile_->GetPrefs(), this);
[email protected]73de26a2010-10-17 03:23:25251 instant_enabled_.Init(prefs::kInstantEnabled, profile_->GetPrefs(), this);
[email protected]b9c505b2010-04-30 15:05:10252 if (!TabMenuModel::AreVerticalTabsEnabled()) {
253 // If vertical tabs aren't enabled, explicitly turn them off. Otherwise we
254 // might show vertical tabs but not show an option to turn them off.
255 use_vertical_tabs_.SetValue(false);
256 }
[email protected]b3344872010-05-03 15:52:29257 UpdateTabStripModelInsertionPolicy();
[email protected]281918912010-05-27 22:05:13258
259 tab_restore_service_ = profile->GetTabRestoreService();
260 if (tab_restore_service_) {
261 tab_restore_service_->AddObserver(this);
262 TabRestoreServiceChanged(tab_restore_service_);
263 }
[email protected]d3b98c82010-07-14 07:45:59264
265 if (profile_->GetProfileSyncService())
266 profile_->GetProfileSyncService()->AddObserver(this);
[email protected]03bb953d2010-09-14 21:38:30267
[email protected]2031cf9d2010-10-12 05:05:37268 CreateInstantIfNecessary();
initial.commit09911bf2008-07-26 23:55:29269}
270
271Browser::~Browser() {
[email protected]5044da82010-10-27 01:09:16272 VLOG_IF(1, g_log_bug53991) << "~Browser: " << profile_->IsOffTheRecord()
273 << "; stillActive="
274 << BrowserList::IsOffTheRecordSessionActive();
[email protected]e838eaf2010-10-13 18:53:33275
[email protected]d3b98c82010-07-14 07:45:59276 if (profile_->GetProfileSyncService())
277 profile_->GetProfileSyncService()->RemoveObserver(this);
278
initial.commit09911bf2008-07-26 23:55:29279 BrowserList::RemoveBrowser(this);
280
[email protected]fbc947b2009-06-19 13:28:24281#if defined(OS_WIN) || defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:29282 if (!BrowserList::HasBrowserWithProfile(profile_)) {
283 // We're the last browser window with this profile. We need to nuke the
284 // TabRestoreService, which will start the shutdown of the
285 // NavigationControllers and allow for proper shutdown. If we don't do this
286 // chrome won't shutdown cleanly, and may end up crashing when some
287 // thread tries to use the IO thread (or another thread) that is no longer
288 // valid.
[email protected]fbc947b2009-06-19 13:28:24289 // This isn't a valid assumption for Mac OS, as it stays running after
290 // the last browser has closed. The Mac equivalent is in its app
291 // controller.
initial.commit09911bf2008-07-26 23:55:29292 profile_->ResetTabRestoreService();
293 }
[email protected]fbc947b2009-06-19 13:28:24294#endif
initial.commit09911bf2008-07-26 23:55:29295
296 SessionService* session_service = profile_->GetSessionService();
297 if (session_service)
298 session_service->WindowClosed(session_id_);
299
[email protected]d8375fd2008-11-25 22:45:39300 TabRestoreService* tab_restore_service = profile()->GetTabRestoreService();
301 if (tab_restore_service)
302 tab_restore_service->BrowserClosed(this);
303
initial.commit09911bf2008-07-26 23:55:29304 if (profile_->IsOffTheRecord() &&
305 !BrowserList::IsOffTheRecordSessionActive()) {
[email protected]860f55492009-03-27 19:50:59306 // An off-the-record profile is no longer needed, this indirectly
307 // frees its cache and cookies.
308 profile_->GetOriginalProfile()->DestroyOffTheRecordProfile();
initial.commit09911bf2008-07-26 23:55:29309 }
310
311 // There may be pending file dialogs, we need to tell them that we've gone
312 // away so they don't try and call back to us.
313 if (select_file_dialog_.get())
314 select_file_dialog_->ListenerDestroyed();
[email protected]281918912010-05-27 22:05:13315
316 TabRestoreServiceDestroyed(tab_restore_service_);
initial.commit09911bf2008-07-26 23:55:29317}
318
[email protected]15952e462008-11-14 00:29:05319// static
320Browser* Browser::Create(Profile* profile) {
[email protected]299dabd2008-11-19 02:27:16321 Browser* browser = new Browser(TYPE_NORMAL, profile);
[email protected]15952e462008-11-14 00:29:05322 browser->CreateBrowserWindow();
323 return browser;
324}
[email protected]6104acf2008-11-11 22:27:34325
[email protected]15952e462008-11-14 00:29:05326// static
[email protected]1b74d2122010-10-06 16:49:16327Browser* Browser::CreateForPopup(Type type,
328 Profile* profile,
329 TabContents* new_contents,
330 const gfx::Rect& initial_bounds) {
331 DCHECK(type & TYPE_POPUP);
332 Browser* browser = new Browser(type, profile);
333 browser->set_override_bounds(initial_bounds);
334 browser->CreateBrowserWindow();
[email protected]3c9e1872010-11-18 16:17:49335 TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
336 browser->tabstrip_model()->AppendTabContents(wrapper, true);
[email protected]9ee17e8c2010-08-10 19:17:31337 return browser;
338}
339
340// static
341Browser* Browser::CreateForType(Type type, Profile* profile) {
342 Browser* browser = new Browser(type, profile);
[email protected]15952e462008-11-14 00:29:05343 browser->CreateBrowserWindow();
344 return browser;
345}
346
347// static
[email protected]57ecc4b2010-08-11 03:02:51348Browser* Browser::CreateForApp(const std::string& app_name,
[email protected]9adb9692010-10-29 23:14:02349 const Extension* extension,
[email protected]f2989012010-02-04 16:08:29350 Profile* profile,
351 bool is_panel) {
[email protected]f075fe0a22010-04-26 04:06:43352 Browser::Type type = TYPE_APP;
353
[email protected]61a57ce2010-09-24 16:33:03354 if (is_panel) {
355 // TYPE_APP_PANEL is the logical choice. However, the panel UI
356 // is not fully implemented. See crbug/55943.
357 type = TYPE_APP_POPUP;
[email protected]5530ac652010-09-25 05:35:49358 } else if (extension) {
[email protected]af801acd2010-08-20 20:27:44359 type = TYPE_EXTENSION_APP;
[email protected]5530ac652010-09-25 05:35:49360 }
[email protected]f075fe0a22010-04-26 04:06:43361
362 Browser* browser = new Browser(type, profile);
[email protected]15952e462008-11-14 00:29:05363 browser->app_name_ = app_name;
[email protected]f075fe0a22010-04-26 04:06:43364 browser->extension_app_ = extension;
[email protected]605cfad2010-06-22 20:49:35365
[email protected]fbf3da12010-06-25 17:29:58366 if (extension) {
367 gfx::Rect initial_pos(extension->launch_width(),
368 extension->launch_height());
369 if (!initial_pos.IsEmpty())
370 browser->set_override_bounds(initial_pos);
371 }
[email protected]605cfad2010-06-22 20:49:35372
[email protected]15952e462008-11-14 00:29:05373 browser->CreateBrowserWindow();
[email protected]605cfad2010-06-22 20:49:35374
[email protected]15952e462008-11-14 00:29:05375 return browser;
376}
377
[email protected]8e48e982009-12-25 11:22:46378// static
379Browser* Browser::CreateForDevTools(Profile* profile) {
380 Browser* browser = new Browser(TYPE_DEVTOOLS, profile);
381 browser->app_name_ = DevToolsWindow::kDevToolsApp;
382 browser->CreateBrowserWindow();
383 return browser;
384}
385
[email protected]15952e462008-11-14 00:29:05386void Browser::CreateBrowserWindow() {
387 DCHECK(!window_);
[email protected]9c45b7182009-08-04 16:44:43388
[email protected]15952e462008-11-14 00:29:05389 window_ = BrowserWindow::CreateBrowserWindow(this);
390
[email protected]80cf3562009-11-17 08:17:24391#if defined(OS_WIN)
[email protected]45446a52010-11-04 17:41:00392 {
393 // TODO: This might hit the disk
394 // http://code.google.com/p/chromium/issues/detail?id=61638
395 base::ThreadRestrictions::ScopedAllowIO allow_io;
396
397 // Set the app user model id for this application to that of the application
398 // name. See http://crbug.com/7028.
399 win_util::SetAppIdForWindow(
400 type_ & TYPE_APP ?
401 ShellIntegration::GetAppId(UTF8ToWide(app_name_), profile_->GetPath()) :
402 ShellIntegration::GetChromiumAppId(profile_->GetPath()),
403 window()->GetNativeHandle());
404 }
[email protected]80cf3562009-11-17 08:17:24405#endif
406
[email protected]14d8c66e2009-09-22 00:32:52407 NotificationService::current()->Notify(
408 NotificationType::BROWSER_WINDOW_READY,
409 Source<Browser>(this),
410 NotificationService::NoDetails());
411
[email protected]15952e462008-11-14 00:29:05412 // Show the First Run information bubble if we've been told to.
413 PrefService* local_state = g_browser_process->local_state();
[email protected]be3877f2009-01-14 15:51:10414 if (!local_state)
415 return;
[email protected]da6ce5602009-12-07 23:09:32416 if (local_state->FindPreference(prefs::kShouldShowFirstRunBubble) &&
[email protected]15952e462008-11-14 00:29:05417 local_state->GetBoolean(prefs::kShouldShowFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50418 FirstRun::BubbleType bubble_type = FirstRun::LARGE_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07419 if (local_state->
[email protected]da6ce5602009-12-07 23:09:32420 FindPreference(prefs::kShouldUseOEMFirstRunBubble) &&
[email protected]adfe1882010-04-13 23:01:07421 local_state->GetBoolean(prefs::kShouldUseOEMFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50422 bubble_type = FirstRun::OEM_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07423 } else if (local_state->
424 FindPreference(prefs::kShouldUseMinimalFirstRunBubble) &&
425 local_state->GetBoolean(prefs::kShouldUseMinimalFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50426 bubble_type = FirstRun::MINIMAL_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07427 }
[email protected]15952e462008-11-14 00:29:05428 // Reset the preference so we don't show the bubble for subsequent windows.
429 local_state->ClearPref(prefs::kShouldShowFirstRunBubble);
[email protected]adfe1882010-04-13 23:01:07430 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type);
initial.commit09911bf2008-07-26 23:55:29431 }
[email protected]f69c8852010-10-12 02:36:46432 if (local_state->FindPreference(
433 prefs::kAutoFillPersonalDataManagerFirstRun) &&
434 local_state->GetBoolean(prefs::kAutoFillPersonalDataManagerFirstRun)) {
435 // Notify PDM that this is a first run.
436#if defined(OS_WIN)
437 ImportAutofillDataWin(profile_->GetPersonalDataManager());
438#endif // defined(OS_WIN)
439 // Reset the preference so we don't call it again for subsequent windows.
440 local_state->ClearPref(prefs::kAutoFillPersonalDataManagerFirstRun);
441 }
initial.commit09911bf2008-07-26 23:55:29442}
443
[email protected]36b6dcb2008-11-12 01:19:57444///////////////////////////////////////////////////////////////////////////////
[email protected]5c238752009-06-13 10:29:07445// Getters & Setters
446
447const std::vector<std::wstring>& Browser::user_data_dir_profiles() const {
448 return g_browser_process->user_data_dir_profiles();
449}
450
451void Browser::set_user_data_dir_profiles(
452 const std::vector<std::wstring>& profiles) {
453 g_browser_process->user_data_dir_profiles() = profiles;
454}
455
[email protected]b77cb302009-10-29 04:09:17456FindBarController* Browser::GetFindBarController() {
457 if (!find_bar_controller_.get()) {
458 FindBar* find_bar = BrowserWindow::CreateFindBar(this);
459 find_bar_controller_.reset(new FindBarController(find_bar));
460 find_bar->SetFindBarController(find_bar_controller_.get());
461 find_bar_controller_->ChangeTabContents(GetSelectedTabContents());
462 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
463 }
464 return find_bar_controller_.get();
465}
466
[email protected]24db8a072009-10-29 20:35:37467bool Browser::HasFindBarController() const {
468 return find_bar_controller_.get() != NULL;
469}
470
[email protected]5c238752009-06-13 10:29:07471///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57472// Browser, Creation Helpers:
473
474// static
[email protected]15952e462008-11-14 00:29:05475void Browser::OpenEmptyWindow(Profile* profile) {
476 Browser* browser = Browser::Create(profile);
[email protected]36b6dcb2008-11-12 01:19:57477 browser->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:05478 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:29479}
480
[email protected]36b6dcb2008-11-12 01:19:57481// static
[email protected]fbc947b2009-06-19 13:28:24482void Browser::OpenWindowWithRestoredTabs(Profile* profile) {
483 TabRestoreService* service = profile->GetTabRestoreService();
484 if (service)
485 service->RestoreMostRecentEntry(NULL);
486}
487
488// static
[email protected]36b6dcb2008-11-12 01:19:57489void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) {
[email protected]cecc93a2010-10-05 15:58:55490 Browser* browser = GetOrCreateTabbedBrowser(
491 profile->GetOffTheRecordProfile());
492 browser->AddSelectedTabWithURL(url, PageTransition::LINK);
[email protected]15952e462008-11-14 00:29:05493 browser->window()->Show();
[email protected]2baf83d2008-07-30 05:58:17494}
495
[email protected]36b6dcb2008-11-12 01:19:57496// static
[email protected]c28071ad2010-03-12 17:28:56497// TODO(erikkay): There are multiple reasons why this could fail. Should
498// this function return an error reason as well so that callers can show
499// reasonable errors?
[email protected]bbadaa782010-04-28 21:21:53500TabContents* Browser::OpenApplication(Profile* profile,
[email protected]24bf2022010-10-14 16:34:39501 const std::string& app_id,
502 TabContents* existing_tab) {
[email protected]c28071ad2010-03-12 17:28:56503 ExtensionsService* extensions_service = profile->GetExtensionsService();
[email protected]c28071ad2010-03-12 17:28:56504
505 // If the extension with |app_id| could't be found, most likely because it
506 // was uninstalled.
[email protected]9adb9692010-10-29 23:14:02507 const Extension* extension =
508 extensions_service->GetExtensionById(app_id, false);
[email protected]bbadaa782010-04-28 21:21:53509 if (!extension)
510 return NULL;
[email protected]c28071ad2010-03-12 17:28:56511
[email protected]24bf2022010-10-14 16:34:39512 return OpenApplication(profile, extension, extension->launch_container(),
513 existing_tab);
[email protected]bbadaa782010-04-28 21:21:53514}
515
[email protected]e3acb7c2010-05-11 19:23:37516// static
[email protected]d83a5602010-09-16 00:22:48517TabContents* Browser::OpenApplication(
518 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02519 const Extension* extension,
[email protected]24bf2022010-10-14 16:34:39520 extension_misc::LaunchContainer container,
521 TabContents* existing_tab) {
[email protected]56869382010-05-11 21:45:46522 TabContents* tab = NULL;
[email protected]e3acb7c2010-05-11 19:23:37523
[email protected]9b217652010-10-08 22:04:23524 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLaunchContainer", container, 100);
525
[email protected]bbadaa782010-04-28 21:21:53526 switch (container) {
[email protected]d83a5602010-09-16 00:22:48527 case extension_misc::LAUNCH_WINDOW:
[email protected]fa6a9102010-11-22 15:38:50528 tab = Browser::OpenApplicationWindow(profile,
529 extension->GetFullLaunchURL());
530 break;
[email protected]d83a5602010-09-16 00:22:48531 case extension_misc::LAUNCH_PANEL:
[email protected]bbadaa782010-04-28 21:21:53532 tab = Browser::OpenApplicationWindow(profile, extension, container,
[email protected]cecc93a2010-10-05 15:58:55533 GURL());
[email protected]c28071ad2010-03-12 17:28:56534 break;
[email protected]d83a5602010-09-16 00:22:48535 case extension_misc::LAUNCH_TAB: {
[email protected]24bf2022010-10-14 16:34:39536 tab = Browser::OpenApplicationTab(profile, extension, existing_tab);
[email protected]c28071ad2010-03-12 17:28:56537 break;
538 }
539 default:
540 NOTREACHED();
[email protected]bbadaa782010-04-28 21:21:53541 break;
[email protected]c28071ad2010-03-12 17:28:56542 }
[email protected]bbadaa782010-04-28 21:21:53543 return tab;
[email protected]c28071ad2010-03-12 17:28:56544}
545
546// static
[email protected]bbadaa782010-04-28 21:21:53547TabContents* Browser::OpenApplicationWindow(
548 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02549 const Extension* extension,
[email protected]d83a5602010-09-16 00:22:48550 extension_misc::LaunchContainer container,
[email protected]cecc93a2010-10-05 15:58:55551 const GURL& url_input) {
[email protected]f381dfa2010-04-29 04:41:37552 GURL url;
553 if (!url_input.is_empty()) {
554 if (extension)
555 DCHECK(extension->web_extent().ContainsURL(url_input));
556 url = url_input;
557 } else {
558 DCHECK(extension);
559 url = extension->GetFullLaunchURL();
560 }
561
[email protected]bbadaa782010-04-28 21:21:53562 // TODO(erikkay) this can't be correct for extensions
[email protected]57ecc4b2010-08-11 03:02:51563 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
[email protected]36b6dcb2008-11-12 01:19:57564 RegisterAppPrefs(app_name);
[email protected]15952e462008-11-14 00:29:05565
[email protected]d83a5602010-09-16 00:22:48566 bool as_panel = extension && (container == extension_misc::LAUNCH_PANEL);
[email protected]cecc93a2010-10-05 15:58:55567 Browser* browser = Browser::CreateForApp(app_name, extension, profile,
568 as_panel);
[email protected]3c9e1872010-11-18 16:17:49569 TabContentsWrapper* wrapper =
[email protected]cecc93a2010-10-05 15:58:55570 browser->AddSelectedTabWithURL(url, PageTransition::START_PAGE);
[email protected]3c9e1872010-11-18 16:17:49571 TabContents* contents = wrapper->tab_contents();
[email protected]cecc93a2010-10-05 15:58:55572 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
573 contents->render_view_host()->SyncRendererPrefs();
574 browser->window()->Show();
[email protected]bbadaa782010-04-28 21:21:53575
[email protected]68f009f2009-02-26 19:43:35576 // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
577 // focus explicitly.
[email protected]cecc93a2010-10-05 15:58:55578 contents->view()->SetInitialFocus();
[email protected]eabfdae92009-12-11 06:13:51579
[email protected]f45d2a72010-03-08 23:28:35580 if (!as_panel) {
581 // Set UPDATE_SHORTCUT as the pending web app action. This action is picked
582 // up in LoadingStateChanged to schedule a GetApplicationInfo. And when
583 // the web app info is available, TabContents notifies Browser via
[email protected]867a73e12010-03-19 20:45:46584 // OnDidGetApplicationInfo, which calls
585 // web_app::UpdateShortcutForTabContents when it sees UPDATE_SHORTCUT as
586 // pending web app action.
[email protected]cecc93a2010-10-05 15:58:55587 browser->pending_web_app_action_ = UPDATE_SHORTCUT;
[email protected]f45d2a72010-03-08 23:28:35588 }
[email protected]bbadaa782010-04-28 21:21:53589
[email protected]cecc93a2010-10-05 15:58:55590 return contents;
[email protected]d6a3c772009-01-27 19:41:20591}
initial.commit09911bf2008-07-26 23:55:29592
[email protected]1fdff702009-10-22 00:36:18593// static
[email protected]fa6a9102010-11-22 15:38:50594TabContents* Browser::OpenApplicationWindow(Profile* profile, const GURL& url) {
[email protected]d83a5602010-09-16 00:22:48595 return OpenApplicationWindow(profile, NULL, extension_misc::LAUNCH_WINDOW,
[email protected]cecc93a2010-10-05 15:58:55596 url);
[email protected]c28071ad2010-03-12 17:28:56597}
598
599// static
[email protected]bbadaa782010-04-28 21:21:53600TabContents* Browser::OpenApplicationTab(Profile* profile,
[email protected]9adb9692010-10-29 23:14:02601 const Extension* extension,
[email protected]24bf2022010-10-14 16:34:39602 TabContents* existing_tab) {
[email protected]cecc93a2010-10-05 15:58:55603 Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
604 TabContents* contents = NULL;
605 if (!browser || browser->type() != Browser::TYPE_NORMAL)
606 return contents;
[email protected]c28071ad2010-03-12 17:28:56607
[email protected]10abd192010-09-30 02:03:49608 // Check the prefs for overridden mode.
609 ExtensionsService* extensions_service = profile->GetExtensionsService();
610 DCHECK(extensions_service);
[email protected]b283a7532010-08-12 21:24:59611
[email protected]10abd192010-09-30 02:03:49612 ExtensionPrefs::LaunchType launch_type =
[email protected]a3b734b2010-11-30 03:17:11613 extensions_service->extension_prefs()->GetLaunchType(
614 extension->id(), ExtensionPrefs::LAUNCH_REGULAR);
[email protected]9b217652010-10-08 22:04:23615 UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100);
[email protected]10abd192010-09-30 02:03:49616 int add_type = TabStripModel::ADD_SELECTED;
617 if (launch_type == ExtensionPrefs::LAUNCH_PINNED)
618 add_type |= TabStripModel::ADD_PINNED;
619
620 // TODO(erikkay): START_PAGE doesn't seem like the right transition in all
621 // cases.
[email protected]616381f02010-11-02 15:15:33622 browser::NavigateParams params(browser, extension->GetFullLaunchURL(),
623 PageTransition::START_PAGE);
624 params.tabstrip_add_types = add_type;
[email protected]24bf2022010-10-14 16:34:39625
626 // Launch the application in the existing TabContents, if it was supplied.
627 if (existing_tab) {
628 TabStripModel* model = browser->tabstrip_model();
[email protected]3c9e1872010-11-18 16:17:49629 int tab_index = model->GetWrapperIndex(existing_tab);
[email protected]24bf2022010-10-14 16:34:39630
631 existing_tab->OpenURL(extension->GetFullLaunchURL(), existing_tab->GetURL(),
632 CURRENT_TAB, PageTransition::LINK);
[email protected]616381f02010-11-02 15:15:33633 if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) {
[email protected]24bf2022010-10-14 16:34:39634 model->SetTabPinned(tab_index, true);
[email protected]3c9e1872010-11-18 16:17:49635 tab_index = model->GetWrapperIndex(existing_tab);
[email protected]7dfec4212010-11-01 22:12:26636 }
[email protected]616381f02010-11-02 15:15:33637 if (params.tabstrip_add_types & TabStripModel::ADD_SELECTED)
[email protected]24bf2022010-10-14 16:34:39638 model->SelectTabContentsAt(tab_index, true);
639
640 contents = existing_tab;
641 } else {
[email protected]616381f02010-11-02 15:15:33642 params.disposition = NEW_FOREGROUND_TAB;
643 browser::Navigate(&params);
[email protected]3c9e1872010-11-18 16:17:49644 contents = params.target_contents->tab_contents();
[email protected]24bf2022010-10-14 16:34:39645 }
646
[email protected]10abd192010-09-30 02:03:49647 if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN)
[email protected]cecc93a2010-10-05 15:58:55648 browser->window()->SetFullscreen(true);
[email protected]10abd192010-09-30 02:03:49649
[email protected]cecc93a2010-10-05 15:58:55650 return contents;
[email protected]c28071ad2010-03-12 17:28:56651}
652
653// static
[email protected]90a8bf252010-03-12 00:09:47654void Browser::OpenBookmarkManagerWindow(Profile* profile) {
655 Browser* browser = Browser::Create(profile);
656 browser->ShowBookmarkManagerTab();
657 browser->window()->Show();
658}
659
[email protected]057d959a2010-03-12 02:56:20660#if defined(OS_MACOSX)
[email protected]90a8bf252010-03-12 00:09:47661// static
[email protected]91a5b3e2009-10-30 19:32:22662void Browser::OpenHistoryWindow(Profile* profile) {
663 Browser* browser = Browser::Create(profile);
664 browser->ShowHistoryTab();
665 browser->window()->Show();
666}
667
668// static
669void Browser::OpenDownloadsWindow(Profile* profile) {
670 Browser* browser = Browser::Create(profile);
671 browser->ShowDownloadsTab();
672 browser->window()->Show();
673}
674
675// static
[email protected]1fdff702009-10-22 00:36:18676void Browser::OpenHelpWindow(Profile* profile) {
677 Browser* browser = Browser::Create(profile);
678 browser->OpenHelpTab();
679 browser->window()->Show();
680}
[email protected]4a42d272010-06-18 01:29:42681
[email protected]eca258132010-11-15 23:33:08682// static
[email protected]4a42d272010-06-18 01:29:42683void Browser::OpenOptionsWindow(Profile* profile) {
684 Browser* browser = Browser::Create(profile);
[email protected]024617a2010-08-20 05:08:05685 browser->ShowOptionsTab(chrome::kDefaultOptionsSubPage);
[email protected]4a42d272010-06-18 01:29:42686 browser->window()->Show();
687}
[email protected]1fdff702009-10-22 00:36:18688#endif
689
[email protected]ccb55cf52010-03-06 22:02:04690// static
691void Browser::OpenExtensionsWindow(Profile* profile) {
692 Browser* browser = Browser::Create(profile);
693 browser->ShowExtensionsTab();
694 browser->window()->Show();
695}
696
697
[email protected]36b6dcb2008-11-12 01:19:57698///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57699// Browser, State Storage and Retrieval for UI:
700
[email protected]57ecc4b2010-08-11 03:02:51701std::string Browser::GetWindowPlacementKey() const {
702 std::string name(prefs::kBrowserWindowPlacement);
[email protected]36b6dcb2008-11-12 01:19:57703 if (!app_name_.empty()) {
[email protected]57ecc4b2010-08-11 03:02:51704 name.append("_");
[email protected]36b6dcb2008-11-12 01:19:57705 name.append(app_name_);
706 }
[email protected]bc9a5152008-11-15 00:32:04707 return name;
708}
[email protected]36b6dcb2008-11-12 01:19:57709
[email protected]bc9a5152008-11-15 00:32:04710bool Browser::ShouldSaveWindowPlacement() const {
[email protected]25ef2b72009-12-09 05:06:51711 // Only save the window placement of popups if they are restored.
712 return (type() & TYPE_POPUP) == 0 || browser_defaults::kRestorePopups;
[email protected]bc9a5152008-11-15 00:32:04713}
[email protected]36b6dcb2008-11-12 01:19:57714
[email protected]bc9a5152008-11-15 00:32:04715void Browser::SaveWindowPlacement(const gfx::Rect& bounds, bool maximized) {
716 // Save to the session storage service, used when reloading a past session.
717 // Note that we don't want to be the ones who cause lazy initialization of
718 // the session service. This function gets called during initial window
719 // showing, and we don't want to bring in the session service this early.
[email protected]36b6dcb2008-11-12 01:19:57720 if (profile()->HasSessionService()) {
721 SessionService* session_service = profile()->GetSessionService();
722 if (session_service)
723 session_service->SetWindowBounds(session_id_, bounds, maximized);
724 }
725}
726
[email protected]15952e462008-11-14 00:29:05727gfx::Rect Browser::GetSavedWindowBounds() const {
[email protected]bb975362009-01-21 01:00:22728 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]15952e462008-11-14 00:29:05729 bool record_mode = parsed_command_line.HasSwitch(switches::kRecordMode);
730 bool playback_mode = parsed_command_line.HasSwitch(switches::kPlaybackMode);
731 if (record_mode || playback_mode) {
732 // In playback/record mode we always fix the size of the browser and
733 // move it to (0,0). The reason for this is two reasons: First we want
734 // resize/moves in the playback to still work, and Second we want
735 // playbacks to work (as much as possible) on machines w/ different
736 // screen sizes.
737 return gfx::Rect(0, 0, 800, 600);
738 }
739
740 gfx::Rect restored_bounds = override_bounds_;
741 bool maximized;
[email protected]6dfed102009-04-28 03:09:53742 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, NULL,
[email protected]15952e462008-11-14 00:29:05743 &restored_bounds, &maximized);
744 return restored_bounds;
745}
746
747// TODO(beng): obtain maximized state some other way so we don't need to go
748// through all this hassle.
749bool Browser::GetSavedMaximizedState() const {
[email protected]bb975362009-01-21 01:00:22750 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStartMaximized))
[email protected]15952e462008-11-14 00:29:05751 return true;
752
[email protected]2e716622009-03-09 21:11:01753 if (maximized_state_ == MAXIMIZED_STATE_MAXIMIZED)
754 return true;
755 if (maximized_state_ == MAXIMIZED_STATE_UNMAXIMIZED)
756 return false;
757
758 // An explicit maximized state was not set. Query the window sizer.
[email protected]15952e462008-11-14 00:29:05759 gfx::Rect restored_bounds;
[email protected]2e716622009-03-09 21:11:01760 bool maximized = false;
[email protected]6dfed102009-04-28 03:09:53761 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, NULL,
[email protected]15952e462008-11-14 00:29:05762 &restored_bounds, &maximized);
763 return maximized;
[email protected]36b6dcb2008-11-12 01:19:57764}
765
766SkBitmap Browser::GetCurrentPageIcon() const {
[email protected]ce5348a82008-12-18 18:36:23767 TabContents* contents = GetSelectedTabContents();
768 // |contents| can be NULL since GetCurrentPageIcon() is called by the window
769 // during the window's creation (before tabs have been added).
770 return contents ? contents->GetFavIcon() : SkBitmap();
[email protected]36b6dcb2008-11-12 01:19:57771}
772
[email protected]731f8a42009-07-20 22:07:32773string16 Browser::GetWindowTitleForCurrentTab() const {
[email protected]3c9e1872010-11-18 16:17:49774 TabContents* contents = GetSelectedTabContents();
[email protected]dda5dfa32009-07-10 00:33:29775 string16 title;
[email protected]c7c42332008-11-15 01:10:54776
[email protected]731f8a42009-07-20 22:07:32777 // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
778 // window during the window's creation (before tabs have been added).
[email protected]36b6dcb2008-11-12 01:19:57779 if (contents) {
[email protected]dda5dfa32009-07-10 00:33:29780 title = contents->GetTitle();
[email protected]36b6dcb2008-11-12 01:19:57781 FormatTitleForDisplay(&title);
782 }
783 if (title.empty())
[email protected]bbbc1ef2010-02-12 18:03:41784 title = TabContents::GetDefaultTitle();
[email protected]36b6dcb2008-11-12 01:19:57785
[email protected]16779842009-07-08 23:45:29786#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
[email protected]22a3daa2009-11-09 22:03:33787 // On Mac or ChromeOS, we don't want to suffix the page title with
788 // the application name.
[email protected]d904bc82009-07-07 00:41:04789 return title;
790#elif defined(OS_WIN) || defined(OS_LINUX)
[email protected]edb5e6a2009-04-08 23:46:17791 int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
[email protected]dff529732010-04-01 23:50:55792 // Don't append the app name to window titles on app frames and app popups
793 if (type_ & TYPE_APP)
[email protected]edb5e6a2009-04-08 23:46:17794 string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
[email protected]dda5dfa32009-07-10 00:33:29795 return l10n_util::GetStringFUTF16(string_id, title);
[email protected]57e68dba2009-05-15 21:30:50796#endif
[email protected]36b6dcb2008-11-12 01:19:57797}
798
799// static
[email protected]dda5dfa32009-07-10 00:33:29800void Browser::FormatTitleForDisplay(string16* title) {
[email protected]36b6dcb2008-11-12 01:19:57801 size_t current_index = 0;
802 size_t match_index;
[email protected]57ecc4b2010-08-11 03:02:51803 while ((match_index = title->find(L'\n', current_index)) != string16::npos) {
[email protected]810a52ef2010-01-08 01:22:15804 title->replace(match_index, 1, string16());
[email protected]36b6dcb2008-11-12 01:19:57805 current_index = match_index;
806 }
807}
808
809///////////////////////////////////////////////////////////////////////////////
810// Browser, OnBeforeUnload handling:
811
812bool Browser::ShouldCloseWindow() {
[email protected]69444cc2009-04-09 20:40:06813 if (!CanCloseWithInProgressDownloads())
814 return false;
815
816 if (HasCompletedUnloadProcessing())
[email protected]0b4d3382010-07-14 16:13:04817 return IsClosingPermitted();
[email protected]69444cc2009-04-09 20:40:06818
[email protected]36b6dcb2008-11-12 01:19:57819 is_attempting_to_close_browser_ = true;
820
821 for (int i = 0; i < tab_count(); ++i) {
[email protected]505323e22009-01-24 02:47:58822 TabContents* contents = GetTabContentsAt(i);
823 if (TabHasUnloadListener(contents))
824 tabs_needing_before_unload_fired_.insert(contents);
[email protected]36b6dcb2008-11-12 01:19:57825 }
826
827 if (tabs_needing_before_unload_fired_.empty())
[email protected]0b4d3382010-07-14 16:13:04828 return IsClosingPermitted();
[email protected]36b6dcb2008-11-12 01:19:57829
830 ProcessPendingTabs();
831 return false;
832}
833
834void Browser::OnWindowClosing() {
835 if (!ShouldCloseWindow())
836 return;
837
[email protected]911f8152010-03-18 16:46:40838 bool exiting = false;
839
[email protected]c984d9f2010-07-20 20:52:20840 // Application should shutdown on last window close if the user is explicitly
841 // trying to quit, or if there is nothing keeping the browser alive (such as
842 // AppController on the Mac, or BackgroundContentsService for background
843 // pages).
844 bool should_quit_if_last_browser =
845 browser_shutdown::IsTryingToQuit() || !BrowserList::WillKeepAlive();
[email protected]7dc8c6b2010-04-09 17:02:50846
847 if (should_quit_if_last_browser && BrowserList::size() == 1) {
[email protected]36b6dcb2008-11-12 01:19:57848 browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
[email protected]911f8152010-03-18 16:46:40849 exiting = true;
850 }
[email protected]36b6dcb2008-11-12 01:19:57851
852 // Don't use HasSessionService here, we want to force creation of the
853 // session service so that user can restore what was open.
854 SessionService* session_service = profile()->GetSessionService();
855 if (session_service)
856 session_service->WindowClosing(session_id());
857
[email protected]d8375fd2008-11-25 22:45:39858 TabRestoreService* tab_restore_service = profile()->GetTabRestoreService();
859 if (tab_restore_service)
860 tab_restore_service->BrowserClosing(this);
861
[email protected]911f8152010-03-18 16:46:40862 // TODO(sky): convert session/tab restore to use notification.
863 NotificationService::current()->Notify(
864 NotificationType::BROWSER_CLOSING,
865 Source<Browser>(this),
866 Details<bool>(&exiting));
867
[email protected]36b6dcb2008-11-12 01:19:57868 CloseAllTabs();
869}
870
[email protected]69444cc2009-04-09 20:40:06871////////////////////////////////////////////////////////////////////////////////
872// In-progress download termination handling:
873
874void Browser::InProgressDownloadResponse(bool cancel_downloads) {
875 if (cancel_downloads) {
876 cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
877 CloseWindow();
878 return;
879 }
880
881 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
882 // close again we'll show the warning again.
883 cancel_download_confirmation_state_ = NOT_PROMPTED;
884
885 // Show the download page so the user can figure-out what downloads are still
886 // in-progress.
887 ShowDownloadsTab();
888}
889
[email protected]69444cc2009-04-09 20:40:06890////////////////////////////////////////////////////////////////////////////////
[email protected]c848d3d92010-09-16 21:57:45891// Browser, TabStripModel pass-thrus:
892
893int Browser::tab_count() const {
[email protected]ecc523f62010-09-28 22:45:40894 return tab_handler_->GetTabStripModel()->count();
[email protected]c848d3d92010-09-16 21:57:45895}
896
897int Browser::selected_index() const {
[email protected]ecc523f62010-09-28 22:45:40898 return tab_handler_->GetTabStripModel()->selected_index();
[email protected]c848d3d92010-09-16 21:57:45899}
900
901int Browser::GetIndexOfController(
902 const NavigationController* controller) const {
[email protected]ecc523f62010-09-28 22:45:40903 return tab_handler_->GetTabStripModel()->GetIndexOfController(controller);
[email protected]c848d3d92010-09-16 21:57:45904}
905
[email protected]3c9e1872010-11-18 16:17:49906TabContentsWrapper* Browser::GetSelectedTabContentsWrapper() const {
907 return tabstrip_model()->GetSelectedTabContents();
908}
909TabContentsWrapper* Browser::GetTabContentsWrapperAt(int index) const {
910 return tabstrip_model()->GetTabContentsAt(index);
[email protected]c848d3d92010-09-16 21:57:45911}
912
913TabContents* Browser::GetSelectedTabContents() const {
[email protected]3c9e1872010-11-18 16:17:49914 TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
915 if (wrapper)
916 return wrapper->tab_contents();
917 return NULL;
918}
919
920TabContents* Browser::GetTabContentsAt(int index) const {
921 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
922 if (wrapper)
923 return wrapper->tab_contents();
924 return NULL;
[email protected]c848d3d92010-09-16 21:57:45925}
926
927void Browser::SelectTabContentsAt(int index, bool user_gesture) {
[email protected]ecc523f62010-09-28 22:45:40928 tab_handler_->GetTabStripModel()->SelectTabContentsAt(index, user_gesture);
[email protected]c848d3d92010-09-16 21:57:45929}
930
931void Browser::CloseAllTabs() {
[email protected]ecc523f62010-09-28 22:45:40932 tab_handler_->GetTabStripModel()->CloseAllTabs();
[email protected]c848d3d92010-09-16 21:57:45933}
934
935////////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57936// Browser, Tab adding/showing functions:
937
[email protected]b3344872010-05-03 15:52:29938int Browser::GetIndexForInsertionDuringRestore(int relative_index) {
[email protected]ecc523f62010-09-28 22:45:40939 return (tab_handler_->GetTabStripModel()->insertion_policy() ==
940 TabStripModel::INSERT_AFTER) ? tab_count() : relative_index;
[email protected]b3344872010-05-03 15:52:29941}
942
[email protected]3c9e1872010-11-18 16:17:49943TabContentsWrapper* Browser::AddSelectedTabWithURL(const GURL& url,
[email protected]cecc93a2010-10-05 15:58:55944 PageTransition::Type transition) {
[email protected]616381f02010-11-02 15:15:33945 browser::NavigateParams params(this, url, transition);
946 params.disposition = NEW_FOREGROUND_TAB;
947 browser::Navigate(&params);
948 return params.target_contents;
[email protected]36b6dcb2008-11-12 01:19:57949}
950
[email protected]3c9e1872010-11-18 16:17:49951TabContents* Browser::AddTab(TabContentsWrapper* tab_contents,
[email protected]d99cdfd2009-10-08 18:58:11952 PageTransition::Type type) {
[email protected]ecc523f62010-09-28 22:45:40953 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]4a1665442010-06-28 16:09:39954 tab_contents, -1, type, TabStripModel::ADD_SELECTED);
[email protected]3c9e1872010-11-18 16:17:49955 return tab_contents->tab_contents();
[email protected]36b6dcb2008-11-12 01:19:57956}
957
[email protected]e0c7c262009-04-23 23:09:43958void Browser::AddTabContents(TabContents* new_contents,
959 WindowOpenDisposition disposition,
960 const gfx::Rect& initial_pos,
961 bool user_gesture) {
962 AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture);
963}
964
965void Browser::CloseTabContents(TabContents* contents) {
966 CloseContents(contents);
967}
968
969void Browser::BrowserShowHtmlDialog(HtmlDialogUIDelegate* delegate,
[email protected]322f3ff2009-05-22 16:19:54970 gfx::NativeWindow parent_window) {
[email protected]e0c7c262009-04-23 23:09:43971 ShowHtmlDialog(delegate, parent_window);
972}
973
974void Browser::BrowserRenderWidgetShowing() {
975 RenderWidgetShowing();
976}
977
978void Browser::ToolbarSizeChanged(bool is_animating) {
979 ToolbarSizeChanged(NULL, is_animating);
980}
981
[email protected]ce3fa3c2009-04-20 19:55:57982TabContents* Browser::AddRestoredTab(
[email protected]36b6dcb2008-11-12 01:19:57983 const std::vector<TabNavigation>& navigations,
984 int tab_index,
985 int selected_navigation,
[email protected]98aa0b52010-05-06 17:03:08986 const std::string& extension_app_id,
[email protected]5c0e6482009-07-14 20:20:09987 bool select,
[email protected]5e369672009-11-03 23:48:30988 bool pin,
[email protected]6ee12c42010-09-14 09:36:07989 bool from_last_session,
990 SessionStorageNamespace* session_storage_namespace) {
[email protected]3c9e1872010-11-18 16:17:49991 TabContentsWrapper* wrapper = TabContentsFactory(profile(), NULL,
992 MSG_ROUTING_NONE,
993 GetSelectedTabContents(),
[email protected]ecc523f62010-09-28 22:45:40994 session_storage_namespace);
[email protected]3c9e1872010-11-18 16:17:49995 TabContents* new_tab = wrapper->tab_contents();
[email protected]98aa0b52010-05-06 17:03:08996 new_tab->SetExtensionAppById(extension_app_id);
[email protected]5e369672009-11-03 23:48:30997 new_tab->controller().RestoreFromState(navigations, selected_navigation,
998 from_last_session);
[email protected]36b6dcb2008-11-12 01:19:57999
[email protected]5c0e6482009-07-14 20:20:091000 bool really_pin =
[email protected]567ef6b2010-02-05 20:31:331001 (pin && tab_index == tabstrip_model()->IndexOfFirstNonMiniTab());
[email protected]ecc523f62010-09-28 22:45:401002 tab_handler_->GetTabStripModel()->InsertTabContentsAt(
[email protected]3c9e1872010-11-18 16:17:491003 tab_index, wrapper,
[email protected]4a1665442010-06-28 16:09:391004 select ? TabStripModel::ADD_SELECTED : TabStripModel::ADD_NONE);
[email protected]5c0e6482009-07-14 20:20:091005 if (really_pin)
[email protected]ecc523f62010-09-28 22:45:401006 tab_handler_->GetTabStripModel()->SetTabPinned(tab_index, true);
[email protected]c93a9dd2010-04-22 20:25:181007 if (select) {
[email protected]77bc6732009-04-20 22:01:031008 window_->Activate();
[email protected]c93a9dd2010-04-22 20:25:181009 } else {
1010 // We set the size of the view here, before WebKit does its initial
1011 // layout. If we don't, the initial layout of background tabs will be
1012 // performed with a view width of 0, which may cause script outputs and
1013 // anchor link location calculations to be incorrect even after a new
1014 // layout with proper view dimensions. TabStripModel::AddTabContents()
1015 // contains similar logic.
1016 new_tab->view()->SizeContents(window_->GetRestoredBounds().size());
1017 new_tab->HideContents();
1018 }
[email protected]36b6dcb2008-11-12 01:19:571019 if (profile_->HasSessionService()) {
1020 SessionService* session_service = profile_->GetSessionService();
1021 if (session_service)
[email protected]5c0e6482009-07-14 20:20:091022 session_service->TabRestored(&new_tab->controller(), really_pin);
[email protected]36b6dcb2008-11-12 01:19:571023 }
[email protected]ce3fa3c2009-04-20 19:55:571024 return new_tab;
[email protected]36b6dcb2008-11-12 01:19:571025}
1026
1027void Browser::ReplaceRestoredTab(
1028 const std::vector<TabNavigation>& navigations,
[email protected]5e369672009-11-03 23:48:301029 int selected_navigation,
[email protected]fca656c2010-02-10 20:30:101030 bool from_last_session,
[email protected]6ee12c42010-09-14 09:36:071031 const std::string& extension_app_id,
1032 SessionStorageNamespace* session_storage_namespace) {
[email protected]3c9e1872010-11-18 16:17:491033 TabContentsWrapper* wrapper = TabContentsFactory(profile(), NULL,
[email protected]ecc523f62010-09-28 22:45:401034 MSG_ROUTING_NONE,
[email protected]3c9e1872010-11-18 16:17:491035 GetSelectedTabContents(),
[email protected]6ee12c42010-09-14 09:36:071036 session_storage_namespace);
[email protected]3c9e1872010-11-18 16:17:491037 TabContents* replacement = wrapper->tab_contents();
[email protected]98aa0b52010-05-06 17:03:081038 replacement->SetExtensionAppById(extension_app_id);
[email protected]5e369672009-11-03 23:48:301039 replacement->controller().RestoreFromState(navigations, selected_navigation,
1040 from_last_session);
[email protected]36b6dcb2008-11-12 01:19:571041
[email protected]ecc523f62010-09-28 22:45:401042 tab_handler_->GetTabStripModel()->ReplaceNavigationControllerAt(
1043 tab_handler_->GetTabStripModel()->selected_index(),
[email protected]3c9e1872010-11-18 16:17:491044 wrapper);
[email protected]36b6dcb2008-11-12 01:19:571045}
1046
[email protected]a8eff102009-04-14 15:23:431047bool Browser::CanRestoreTab() {
[email protected]281918912010-05-27 22:05:131048 return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB);
[email protected]a8eff102009-04-14 15:23:431049}
1050
[email protected]3698f172010-03-17 20:50:291051bool Browser::NavigateToIndexWithDisposition(int index,
1052 WindowOpenDisposition disp) {
1053 NavigationController& controller =
[email protected]cb84d642010-06-10 00:56:281054 GetOrCloneTabForDisposition(disp)->controller();
1055 if (index < 0 || index >= controller.entry_count())
[email protected]3698f172010-03-17 20:50:291056 return false;
[email protected]cb84d642010-06-10 00:56:281057 controller.GoToIndex(index);
1058 return true;
[email protected]3698f172010-03-17 20:50:291059}
1060
[email protected]bb89e7482010-11-17 18:27:041061void Browser::ShowSingletonTab(const GURL& url, bool ignore_path) {
[email protected]616381f02010-11-02 15:15:331062 browser::NavigateParams params(this, url, PageTransition::AUTO_BOOKMARK);
1063 params.disposition = SINGLETON_TAB;
1064 params.show_window = true;
[email protected]bb89e7482010-11-17 18:27:041065 params.ignore_path = ignore_path;
[email protected]616381f02010-11-02 15:15:331066 browser::Navigate(&params);
[email protected]36b6dcb2008-11-12 01:19:571067}
[email protected]d938aed92009-01-22 19:49:331068
[email protected]ae2622c2009-07-30 23:47:581069void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
[email protected]326464d2010-02-16 22:21:101070#if !defined(OS_MACOSX)
[email protected]ae2622c2009-07-30 23:47:581071 const bool show_main_ui = (type() == TYPE_NORMAL) && !is_fullscreen;
[email protected]326464d2010-02-16 22:21:101072#else
1073 const bool show_main_ui = (type() == TYPE_NORMAL);
1074#endif
[email protected]ae2622c2009-07-30 23:47:581075
[email protected]83548a42010-06-18 13:53:371076 bool main_not_fullscreen_or_popup =
1077 show_main_ui && !is_fullscreen && (type() & TYPE_POPUP) == 0;
1078
[email protected]ae2622c2009-07-30 23:47:581079 // Navigation commands
1080 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
1081
1082 // Window management commands
[email protected]ae2622c2009-07-30 23:47:581083 command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
1084 (type() & TYPE_POPUP) && !is_fullscreen);
1085
1086 // Focus various bits of UI
1087 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
1088 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
1089 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
[email protected]cc824372010-03-31 15:33:011090 command_updater_.UpdateCommandEnabled(
[email protected]83548a42010-06-18 13:53:371091 IDC_FOCUS_MENU_BAR, main_not_fullscreen_or_popup);
1092 command_updater_.UpdateCommandEnabled(
1093 IDC_FOCUS_NEXT_PANE, main_not_fullscreen_or_popup);
1094 command_updater_.UpdateCommandEnabled(
1095 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen_or_popup);
1096 command_updater_.UpdateCommandEnabled(
1097 IDC_FOCUS_BOOKMARKS, main_not_fullscreen_or_popup);
1098 command_updater_.UpdateCommandEnabled(
1099 IDC_FOCUS_CHROMEOS_STATUS, main_not_fullscreen_or_popup);
[email protected]ae2622c2009-07-30 23:47:581100
1101 // Show various bits of UI
1102 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
[email protected]1c41a932010-11-22 23:41:231103 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
[email protected]4a4180a52010-08-23 06:39:481104 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
1105 browser_defaults::bookmarks_enabled && show_main_ui);
[email protected]ae2622c2009-07-30 23:47:581106 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, show_main_ui);
[email protected]d3b98c82010-07-14 07:45:591107 command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
1108 show_main_ui && profile_->IsSyncAccessible());
[email protected]da96e54c2010-08-12 00:18:321109
1110#if defined(ENABLE_REMOTING)
1111 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableRemoting)) {
1112 command_updater_.UpdateCommandEnabled(IDC_REMOTING_SETUP, show_main_ui);
1113 }
1114#endif
1115
[email protected]ae2622c2009-07-30 23:47:581116 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, show_main_ui);
1117 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
1118 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
1119 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
[email protected]fdb98512009-08-26 01:37:101120 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
[email protected]c8b59f92010-05-28 21:45:471121 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, show_main_ui);
[email protected]ae2622c2009-07-30 23:47:581122}
1123
[email protected]36b6dcb2008-11-12 01:19:571124///////////////////////////////////////////////////////////////////////////////
1125// Browser, Assorted browser commands:
1126
[email protected]d497b0782010-03-29 19:19:061127bool Browser::ShouldOpenNewTabForWindowDisposition(
1128 WindowOpenDisposition disposition) {
1129 return (disposition == NEW_FOREGROUND_TAB ||
1130 disposition == NEW_BACKGROUND_TAB);
1131}
1132
[email protected]cb84d642010-06-10 00:56:281133TabContents* Browser::GetOrCloneTabForDisposition(
[email protected]3698f172010-03-17 20:50:291134 WindowOpenDisposition disposition) {
[email protected]3c9e1872010-11-18 16:17:491135 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]d497b0782010-03-29 19:19:061136 if (ShouldOpenNewTabForWindowDisposition(disposition)) {
[email protected]cb84d642010-06-10 00:56:281137 current_tab = current_tab->Clone();
[email protected]ecc523f62010-09-28 22:45:401138 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]4a1665442010-06-28 16:09:391139 current_tab, -1, PageTransition::LINK,
1140 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_SELECTED :
1141 TabStripModel::ADD_NONE);
[email protected]3698f172010-03-17 20:50:291142 }
[email protected]3c9e1872010-11-18 16:17:491143 return current_tab->tab_contents();
[email protected]3698f172010-03-17 20:50:291144}
1145
[email protected]b3344872010-05-03 15:52:291146void Browser::UpdateTabStripModelInsertionPolicy() {
[email protected]ecc523f62010-09-28 22:45:401147 tab_handler_->GetTabStripModel()->SetInsertionPolicy(UseVerticalTabs() ?
[email protected]b3344872010-05-03 15:52:291148 TabStripModel::INSERT_BEFORE : TabStripModel::INSERT_AFTER);
1149}
1150
1151void Browser::UseVerticalTabsChanged() {
1152 UpdateTabStripModelInsertionPolicy();
1153 window()->ToggleTabStripMode();
1154}
1155
[email protected]018cf362010-05-05 22:43:221156bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
1157 bool check_fullscreen) const {
1158 // On Mac, fullscreen mode has most normal things (in a slide-down panel). On
1159 // other platforms, we hide some controls when in fullscreen mode.
1160 bool hide_ui_for_fullscreen = false;
1161#if !defined(OS_MACOSX)
1162 hide_ui_for_fullscreen = check_fullscreen && window_ &&
1163 window_->IsFullscreen();
1164#endif
1165
[email protected]8b8e7c92010-08-19 18:05:561166 unsigned int features = FEATURE_INFOBAR | FEATURE_SIDEBAR;
[email protected]018cf362010-05-05 22:43:221167
1168#if !defined(OS_CHROMEOS)
1169 // Chrome OS opens a FileBrowse pop up instead of using download shelf.
1170 // So FEATURE_DOWNLOADSHELF is only added for non-chromeos platforms.
1171 features |= FEATURE_DOWNLOADSHELF;
1172#endif // !defined(OS_CHROMEOS)
1173
1174 if (type() == TYPE_NORMAL) {
1175 features |= FEATURE_BOOKMARKBAR;
[email protected]018cf362010-05-05 22:43:221176 }
1177
1178 if (!hide_ui_for_fullscreen) {
[email protected]af801acd2010-08-20 20:27:441179 if (type() != TYPE_NORMAL && type() != TYPE_EXTENSION_APP)
[email protected]018cf362010-05-05 22:43:221180 features |= FEATURE_TITLEBAR;
1181
[email protected]af801acd2010-08-20 20:27:441182 if (type() == TYPE_NORMAL || type() == TYPE_EXTENSION_APP)
[email protected]018cf362010-05-05 22:43:221183 features |= FEATURE_TABSTRIP;
1184
[email protected]af801acd2010-08-20 20:27:441185 if (type() == TYPE_NORMAL || type() == TYPE_EXTENSION_APP)
[email protected]018cf362010-05-05 22:43:221186 features |= FEATURE_TOOLBAR;
1187
[email protected]af801acd2010-08-20 20:27:441188 if (type() != TYPE_EXTENSION_APP && (type() & Browser::TYPE_APP) == 0)
[email protected]018cf362010-05-05 22:43:221189 features |= FEATURE_LOCATIONBAR;
1190 }
1191 return !!(features & feature);
1192}
1193
[email protected]0b4d3382010-07-14 16:13:041194bool Browser::IsClosingPermitted() {
1195 TabCloseableStateWatcher* watcher =
1196 g_browser_process->tab_closeable_state_watcher();
1197 bool can_close = !watcher || watcher->CanCloseBrowser(this);
1198 if (!can_close && is_attempting_to_close_browser_)
1199 CancelWindowClose();
1200 return can_close;
1201}
1202
[email protected]485fba42009-03-24 23:27:291203void Browser::GoBack(WindowOpenDisposition disposition) {
[email protected]896220042010-03-23 18:14:281204 UserMetrics::RecordAction(UserMetricsAction("Back"), profile_);
[email protected]fbd77592008-11-12 20:50:271205
[email protected]3c9e1872010-11-18 16:17:491206 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]ce3fa3c2009-04-20 19:55:571207 if (current_tab->controller().CanGoBack()) {
[email protected]cb84d642010-06-10 00:56:281208 TabContents* new_tab = GetOrCloneTabForDisposition(disposition);
[email protected]d497b0782010-03-29 19:19:061209 // If we are on an interstitial page and clone the tab, it won't be copied
1210 // to the new tab, so we don't need to go back.
[email protected]3c9e1872010-11-18 16:17:491211 if (current_tab->tab_contents()->showing_interstitial_page() &&
1212 (new_tab != current_tab->tab_contents()))
[email protected]d497b0782010-03-29 19:19:061213 return;
[email protected]cb84d642010-06-10 00:56:281214 new_tab->controller().GoBack();
[email protected]485fba42009-03-24 23:27:291215 }
[email protected]36b6dcb2008-11-12 01:19:571216}
1217
[email protected]3698f172010-03-17 20:50:291218void Browser::GoForward(WindowOpenDisposition disposition) {
[email protected]896220042010-03-23 18:14:281219 UserMetrics::RecordAction(UserMetricsAction("Forward"), profile_);
[email protected]3c9e1872010-11-18 16:17:491220 if (GetSelectedTabContentsWrapper()->controller().CanGoForward())
[email protected]cb84d642010-06-10 00:56:281221 GetOrCloneTabForDisposition(disposition)->controller().GoForward();
[email protected]36b6dcb2008-11-12 01:19:571222}
1223
[email protected]cb84d642010-06-10 00:56:281224void Browser::Reload(WindowOpenDisposition disposition) {
[email protected]896220042010-03-23 18:14:281225 UserMetrics::RecordAction(UserMetricsAction("Reload"), profile_);
[email protected]cb84d642010-06-10 00:56:281226 ReloadInternal(disposition, false);
[email protected]1ccb3568d2010-02-19 10:51:161227}
[email protected]fbd77592008-11-12 20:50:271228
[email protected]cb84d642010-06-10 00:56:281229void Browser::ReloadIgnoringCache(WindowOpenDisposition disposition) {
[email protected]896220042010-03-23 18:14:281230 UserMetrics::RecordAction(UserMetricsAction("ReloadIgnoringCache"), profile_);
[email protected]cb84d642010-06-10 00:56:281231 ReloadInternal(disposition, true);
[email protected]1ccb3568d2010-02-19 10:51:161232}
1233
[email protected]cb84d642010-06-10 00:56:281234void Browser::ReloadInternal(WindowOpenDisposition disposition,
1235 bool ignore_cache) {
[email protected]36b6dcb2008-11-12 01:19:571236 // If we are showing an interstitial, treat this as an OpenURL.
1237 TabContents* current_tab = GetSelectedTabContents();
[email protected]cb84d642010-06-10 00:56:281238 if (current_tab && current_tab->showing_interstitial_page()) {
1239 NavigationEntry* entry = current_tab->controller().GetActiveEntry();
1240 DCHECK(entry); // Should exist if interstitial is showing.
1241 OpenURL(entry->url(), GURL(), disposition, PageTransition::RELOAD);
1242 return;
[email protected]36b6dcb2008-11-12 01:19:571243 }
[email protected]cb84d642010-06-10 00:56:281244
1245 // As this is caused by a user action, give the focus to the page.
[email protected]3c9e1872010-11-18 16:17:491246 TabContents* tab = GetOrCloneTabForDisposition(disposition);
1247 if (!tab->FocusLocationBarByDefault())
1248 tab->Focus();
[email protected]cb84d642010-06-10 00:56:281249 if (ignore_cache)
[email protected]3c9e1872010-11-18 16:17:491250 tab->controller().ReloadIgnoringCache(true);
[email protected]cb84d642010-06-10 00:56:281251 else
[email protected]3c9e1872010-11-18 16:17:491252 tab->controller().Reload(true);
[email protected]36b6dcb2008-11-12 01:19:571253}
1254
[email protected]485fba42009-03-24 23:27:291255void Browser::Home(WindowOpenDisposition disposition) {
[email protected]896220042010-03-23 18:14:281256 UserMetrics::RecordAction(UserMetricsAction("Home"), profile_);
[email protected]485fba42009-03-24 23:27:291257 OpenURL(GetHomePage(), GURL(), disposition, PageTransition::AUTO_BOOKMARK);
[email protected]36b6dcb2008-11-12 01:19:571258}
1259
[email protected]fbd77592008-11-12 20:50:271260void Browser::OpenCurrentURL() {
[email protected]896220042010-03-23 18:14:281261 UserMetrics::RecordAction(UserMetricsAction("LoadURL"), profile_);
[email protected]7745b822009-01-27 20:15:351262 LocationBar* location_bar = window_->GetLocationBar();
[email protected]9d0306ea2009-09-02 19:38:391263 WindowOpenDisposition open_disposition =
1264 location_bar->GetWindowOpenDisposition();
[email protected]6b723f82010-10-05 20:14:271265 if (OpenInstant(open_disposition))
[email protected]03bb953d2010-09-14 21:38:301266 return;
[email protected]03bb953d2010-09-14 21:38:301267
[email protected]83bf2d142009-11-06 18:19:301268 GURL url(WideToUTF8(location_bar->GetInputString()));
[email protected]616381f02010-11-02 15:15:331269 browser::NavigateParams params(this, url, location_bar->GetPageTransition());
1270 params.disposition = open_disposition;
[email protected]514576a2010-07-01 22:51:251271 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
1272 // inherit the opener. In some cases the tabstrip will determine the group
1273 // should be inherited, in which case the group is inherited instead of the
1274 // opener.
[email protected]616381f02010-11-02 15:15:331275 params.tabstrip_add_types =
1276 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
1277 browser::Navigate(&params);
[email protected]fbd77592008-11-12 20:50:271278}
1279
[email protected]84214982008-12-10 18:49:101280void Browser::Stop() {
[email protected]896220042010-03-23 18:14:281281 UserMetrics::RecordAction(UserMetricsAction("Stop"), profile_);
[email protected]3c9e1872010-11-18 16:17:491282 GetSelectedTabContentsWrapper()->tab_contents()->Stop();
[email protected]84214982008-12-10 18:49:101283}
1284
1285void Browser::NewWindow() {
[email protected]047e7272010-06-03 19:53:351286 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
1287 CommandLine::ForCurrentProcess()->HasSwitch(switches::kIncognito)) {
1288 NewIncognitoWindow();
1289 return;
1290 }
[email protected]896220042010-03-23 18:14:281291 UserMetrics::RecordAction(UserMetricsAction("NewWindow"), profile_);
[email protected]c9b19942010-03-26 15:58:081292 SessionService* session_service =
1293 profile_->GetOriginalProfile()->GetSessionService();
1294 if (!session_service ||
1295 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
1296 Browser::OpenEmptyWindow(profile_->GetOriginalProfile());
1297 }
[email protected]84214982008-12-10 18:49:101298}
1299
1300void Browser::NewIncognitoWindow() {
[email protected]896220042010-03-23 18:14:281301 UserMetrics::RecordAction(UserMetricsAction("NewIncognitoWindow"), profile_);
[email protected]84214982008-12-10 18:49:101302 Browser::OpenEmptyWindow(profile_->GetOffTheRecordProfile());
1303}
1304
[email protected]84214982008-12-10 18:49:101305void Browser::CloseWindow() {
[email protected]896220042010-03-23 18:14:281306 UserMetrics::RecordAction(UserMetricsAction("CloseWindow"), profile_);
[email protected]84214982008-12-10 18:49:101307 window_->Close();
1308}
1309
[email protected]fbd77592008-11-12 20:50:271310void Browser::NewTab() {
[email protected]896220042010-03-23 18:14:281311 UserMetrics::RecordAction(UserMetricsAction("NewTab"), profile_);
[email protected]b7969202010-05-14 21:29:261312
[email protected]299dabd2008-11-19 02:27:161313 if (type() == TYPE_NORMAL) {
[email protected]fbd77592008-11-12 20:50:271314 AddBlankTab(true);
1315 } else {
[email protected]1a6b30a2009-08-19 03:52:111316 Browser* b = GetOrCreateTabbedBrowser(profile_);
[email protected]fbd77592008-11-12 20:50:271317 b->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:051318 b->window()->Show();
[email protected]e54f30d2009-01-14 21:17:111319 // The call to AddBlankTab above did not set the focus to the tab as its
1320 // window was not active, so we have to do it explicitly.
1321 // See http://crbug.com/6380.
[email protected]3c9e1872010-11-18 16:17:491322 b->GetSelectedTabContentsWrapper()->view()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271323 }
1324}
1325
1326void Browser::CloseTab() {
[email protected]896220042010-03-23 18:14:281327 UserMetrics::RecordAction(UserMetricsAction("CloseTab_Accelerator"),
1328 profile_);
[email protected]0b4d3382010-07-14 16:13:041329 if (CanCloseTab()) {
[email protected]ecc523f62010-09-28 22:45:401330 tab_handler_->GetTabStripModel()->CloseTabContentsAt(
1331 tab_handler_->GetTabStripModel()->selected_index(),
[email protected]0b4d3382010-07-14 16:13:041332 TabStripModel::CLOSE_USER_GESTURE |
1333 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
1334 }
[email protected]fbd77592008-11-12 20:50:271335}
1336
[email protected]fbd77592008-11-12 20:50:271337void Browser::SelectNextTab() {
[email protected]896220042010-03-23 18:14:281338 UserMetrics::RecordAction(UserMetricsAction("SelectNextTab"), profile_);
[email protected]ecc523f62010-09-28 22:45:401339 tab_handler_->GetTabStripModel()->SelectNextTab();
[email protected]fbd77592008-11-12 20:50:271340}
1341
1342void Browser::SelectPreviousTab() {
[email protected]896220042010-03-23 18:14:281343 UserMetrics::RecordAction(UserMetricsAction("SelectPrevTab"), profile_);
[email protected]ecc523f62010-09-28 22:45:401344 tab_handler_->GetTabStripModel()->SelectPreviousTab();
[email protected]fbd77592008-11-12 20:50:271345}
1346
[email protected]91ac9202010-07-30 18:32:351347void Browser::OpenTabpose() {
1348#if defined(OS_MACOSX)
1349 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1350 switches::kEnableExposeForTabs)) {
1351 return;
1352 }
1353
1354 UserMetrics::RecordAction(UserMetricsAction("OpenTabpose"), profile_);
1355 window()->OpenTabpose();
1356#else
1357 NOTREACHED();
1358#endif
1359}
1360
[email protected]9ac7fcb2009-09-14 18:22:521361void Browser::MoveTabNext() {
[email protected]896220042010-03-23 18:14:281362 UserMetrics::RecordAction(UserMetricsAction("MoveTabNext"), profile_);
[email protected]ecc523f62010-09-28 22:45:401363 tab_handler_->GetTabStripModel()->MoveTabNext();
[email protected]9ac7fcb2009-09-14 18:22:521364}
1365
1366void Browser::MoveTabPrevious() {
[email protected]896220042010-03-23 18:14:281367 UserMetrics::RecordAction(UserMetricsAction("MoveTabPrevious"), profile_);
[email protected]ecc523f62010-09-28 22:45:401368 tab_handler_->GetTabStripModel()->MoveTabPrevious();
[email protected]9ac7fcb2009-09-14 18:22:521369}
1370
[email protected]fbd77592008-11-12 20:50:271371void Browser::SelectNumberedTab(int index) {
1372 if (index < tab_count()) {
[email protected]896220042010-03-23 18:14:281373 UserMetrics::RecordAction(UserMetricsAction("SelectNumberedTab"),
1374 profile_);
[email protected]ecc523f62010-09-28 22:45:401375 tab_handler_->GetTabStripModel()->SelectTabContentsAt(index, true);
[email protected]fbd77592008-11-12 20:50:271376 }
1377}
1378
1379void Browser::SelectLastTab() {
[email protected]896220042010-03-23 18:14:281380 UserMetrics::RecordAction(UserMetricsAction("SelectLastTab"), profile_);
[email protected]ecc523f62010-09-28 22:45:401381 tab_handler_->GetTabStripModel()->SelectLastTab();
[email protected]fbd77592008-11-12 20:50:271382}
1383
1384void Browser::DuplicateTab() {
[email protected]896220042010-03-23 18:14:281385 UserMetrics::RecordAction(UserMetricsAction("Duplicate"), profile_);
[email protected]fbd77592008-11-12 20:50:271386 DuplicateContentsAt(selected_index());
1387}
1388
1389void Browser::RestoreTab() {
[email protected]896220042010-03-23 18:14:281390 UserMetrics::RecordAction(UserMetricsAction("RestoreTab"), profile_);
[email protected]fbd77592008-11-12 20:50:271391 TabRestoreService* service = profile_->GetTabRestoreService();
1392 if (!service)
1393 return;
1394
[email protected]d8375fd2008-11-25 22:45:391395 service->RestoreMostRecentEntry(this);
[email protected]fbd77592008-11-12 20:50:271396}
1397
[email protected]0c4c3882009-10-01 21:42:141398void Browser::WriteCurrentURLToClipboard() {
1399 // TODO(ericu): There isn't currently a metric for this. Should there be?
1400 // We don't appear to track the action when it comes from the
1401 // RenderContextViewMenu.
[email protected]0c4c3882009-10-01 21:42:141402
1403 TabContents* contents = GetSelectedTabContents();
1404 if (!contents->ShouldDisplayURL())
1405 return;
1406
[email protected]90f39902009-10-03 04:25:371407 chrome_browser_net::WriteURLToClipboard(
[email protected]0c4c3882009-10-01 21:42:141408 contents->GetURL(),
[email protected]9f284f132010-08-31 06:14:171409 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
[email protected]0c4c3882009-10-01 21:42:141410 g_browser_process->clipboard());
1411}
1412
[email protected]fbd77592008-11-12 20:50:271413void Browser::ConvertPopupToTabbedBrowser() {
[email protected]896220042010-03-23 18:14:281414 UserMetrics::RecordAction(UserMetricsAction("ShowAsTab"), profile_);
[email protected]ecc523f62010-09-28 22:45:401415 int tab_strip_index = tab_handler_->GetTabStripModel()->selected_index();
[email protected]3c9e1872010-11-18 16:17:491416 TabContentsWrapper* contents =
[email protected]ecc523f62010-09-28 22:45:401417 tab_handler_->GetTabStripModel()->DetachTabContentsAt(tab_strip_index);
[email protected]15952e462008-11-14 00:29:051418 Browser* browser = Browser::Create(profile_);
1419 browser->tabstrip_model()->AppendTabContents(contents, true);
1420 browser->window()->Show();
[email protected]fbd77592008-11-12 20:50:271421}
1422
[email protected]9282cea2009-02-18 18:49:001423void Browser::ToggleFullscreenMode() {
[email protected]34930432009-11-09 00:12:091424#if !defined(OS_MACOSX)
1425 // In kiosk mode, we always want to be fullscreen. When the browser first
1426 // starts we're not yet fullscreen, so let the initial toggle go through.
1427 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) &&
1428 window_->IsFullscreen())
1429 return;
1430#endif
1431
[email protected]896220042010-03-23 18:14:281432 UserMetrics::RecordAction(UserMetricsAction("ToggleFullscreen"), profile_);
[email protected]9282cea2009-02-18 18:49:001433 window_->SetFullscreen(!window_->IsFullscreen());
[email protected]ae2622c2009-07-30 23:47:581434 // On Linux, setting fullscreen mode is an async call to the X server, which
1435 // may or may not support fullscreen mode.
1436#if !defined(OS_LINUX)
[email protected]9282cea2009-02-18 18:49:001437 UpdateCommandsForFullscreenMode(window_->IsFullscreen());
[email protected]ae2622c2009-07-30 23:47:581438#endif
[email protected]9282cea2009-02-18 18:49:001439}
1440
[email protected]da17b372010-01-22 23:37:221441#if defined(OS_CHROMEOS)
[email protected]f97d7f632010-06-01 21:08:331442void Browser::Search() {
1443 // If the NTP is showing, close it.
1444 if (StartsWithASCII(GetSelectedTabContents()->GetURL().spec(),
1445 chrome::kChromeUINewTabURL, true)) {
1446 CloseTab();
1447 return;
1448 }
[email protected]64559862010-09-23 19:00:161449
1450 // Exit fullscreen to show omnibox.
[email protected]ebdda9092010-10-22 17:59:101451 if (window_->IsFullscreen()) {
[email protected]64559862010-09-23 19:00:161452 ToggleFullscreenMode();
[email protected]ebdda9092010-10-22 17:59:101453 // ToggleFullscreenMode is asynchronous, so we don't have omnibox
1454 // visible at this point. Wait for next event cycle which toggles
1455 // the visibility of omnibox before creating new tab.
1456 MessageLoop::current()->PostTask(
1457 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::Search));
1458 return;
1459 }
[email protected]64559862010-09-23 19:00:161460
[email protected]f97d7f632010-06-01 21:08:331461 // Otherwise just open it.
1462 NewTab();
1463}
[email protected]d14af522010-12-02 03:54:501464
1465void Browser::ShowKeyboardOverlay() {
1466 window_->ShowKeyboardOverlay(window_->GetNativeHandle());
1467}
[email protected]20d17242009-10-26 20:21:051468#endif
1469
[email protected]fbd77592008-11-12 20:50:271470void Browser::Exit() {
[email protected]896220042010-03-23 18:14:281471 UserMetrics::RecordAction(UserMetricsAction("Exit"), profile_);
[email protected]965e4c42010-09-07 21:23:351472#if defined(OS_CHROMEOS)
[email protected]6a2a61d2010-11-22 03:25:351473 chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutStarted", false);
1474 // Write /tmp/uptime-logout-started as well.
1475 const char kLogoutStarted[] = "logout-started";
1476 chromeos::BootTimesLoader::Get()->RecordCurrentStats(kLogoutStarted);
1477
[email protected]965e4c42010-09-07 21:23:351478 if (chromeos::CrosLibrary::Get()->EnsureLoaded()) {
1479 chromeos::CrosLibrary::Get()->GetLoginLibrary()->StopSession("");
1480 return;
1481 }
1482 // If running the Chrome OS build, but we're not on the device, fall through
1483#endif
[email protected]a9324442009-10-12 04:32:141484 BrowserList::CloseAllBrowsersAndExit();
[email protected]fbd77592008-11-12 20:50:271485}
1486
[email protected]36b6dcb2008-11-12 01:19:571487void Browser::BookmarkCurrentPage() {
[email protected]896220042010-03-23 18:14:281488 UserMetrics::RecordAction(UserMetricsAction("Star"), profile_);
[email protected]fbd77592008-11-12 20:50:271489
[email protected]76624fde2009-10-09 18:13:231490 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]36b6dcb2008-11-12 01:19:571491 if (!model || !model->IsLoaded())
1492 return; // Ignore requests until bookmarks are loaded.
1493
[email protected]76624fde2009-10-09 18:13:231494 GURL url;
[email protected]261cd762010-08-20 05:45:371495 string16 title;
[email protected]76624fde2009-10-09 18:13:231496 bookmark_utils::GetURLAndTitleToBookmark(GetSelectedTabContents(), &url,
1497 &title);
[email protected]c50d0d42009-03-03 17:37:441498 bool was_bookmarked = model->IsBookmarked(url);
[email protected]261cd762010-08-20 05:45:371499 model->SetURLStarred(url, title, true);
[email protected]11dbbd22009-11-06 18:55:041500 // Make sure the model actually added a bookmark before showing the star. A
1501 // bookmark isn't created if the url is invalid.
1502 if (window_->IsActive() && model->IsBookmarked(url)) {
[email protected]5f2731c52009-02-28 00:41:271503 // Only show the bubble if the window is active, otherwise we may get into
1504 // weird situations were the bubble is deleted as soon as it is shown.
[email protected]c50d0d42009-03-03 17:37:441505 window_->ShowBookmarkBubble(url, was_bookmarked);
[email protected]5f2731c52009-02-28 00:41:271506 }
[email protected]36b6dcb2008-11-12 01:19:571507}
1508
[email protected]40bdb6d92009-02-25 00:22:271509void Browser::SavePage() {
[email protected]896220042010-03-23 18:14:281510 UserMetrics::RecordAction(UserMetricsAction("SavePage"), profile_);
[email protected]15d04ae2010-10-30 01:04:501511 TabContents* current_tab = GetSelectedTabContents();
1512 if (current_tab && current_tab->contents_mime_type() == "application/pdf")
1513 UserMetrics::RecordAction(UserMetricsAction("PDF.SavePage"), profile_);
[email protected]57c6a652009-05-04 07:58:341514 GetSelectedTabContents()->OnSavePage();
[email protected]40bdb6d92009-02-25 00:22:271515}
1516
[email protected]fbd77592008-11-12 20:50:271517void Browser::ViewSource() {
[email protected]896220042010-03-23 18:14:281518 UserMetrics::RecordAction(UserMetricsAction("ViewSource"), profile_);
[email protected]36b6dcb2008-11-12 01:19:571519
[email protected]36b6dcb2008-11-12 01:19:571520 TabContents* current_tab = GetSelectedTabContents();
[email protected]ce3fa3c2009-04-20 19:55:571521 NavigationEntry* entry = current_tab->controller().GetLastCommittedEntry();
[email protected]fbd77592008-11-12 20:50:271522 if (entry) {
[email protected]76e7da22010-06-18 22:44:491523 OpenURL(GURL(chrome::kViewSourceScheme + std::string(":") +
1524 entry->url().spec()), GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK);
[email protected]36b6dcb2008-11-12 01:19:571525 }
1526}
initial.commit09911bf2008-07-26 23:55:291527
[email protected]4801ecc2009-04-05 04:52:581528void Browser::ShowFindBar() {
[email protected]b77cb302009-10-29 04:09:171529 GetFindBarController()->Show();
[email protected]4801ecc2009-04-05 04:52:581530}
1531
[email protected]a3e18c42009-03-04 23:36:051532bool Browser::SupportsWindowFeature(WindowFeature feature) const {
[email protected]018cf362010-05-05 22:43:221533 return SupportsWindowFeatureImpl(feature, true);
1534}
[email protected]f5bf8ccf2010-02-05 18:19:251535
[email protected]018cf362010-05-05 22:43:221536bool Browser::CanSupportWindowFeature(WindowFeature feature) const {
1537 return SupportsWindowFeatureImpl(feature, false);
[email protected]a3e18c42009-03-04 23:36:051538}
1539
[email protected]89d6e6e2009-12-03 23:06:511540void Browser::EmailPageLocation() {
[email protected]896220042010-03-23 18:14:281541 UserMetrics::RecordAction(UserMetricsAction("EmailPageLocation"), profile_);
[email protected]89d6e6e2009-12-03 23:06:511542 GetSelectedTabContents()->EmailPageLocation();
1543}
1544
[email protected]fbd77592008-11-12 20:50:271545void Browser::Print() {
[email protected]896220042010-03-23 18:14:281546 UserMetrics::RecordAction(UserMetricsAction("PrintPreview"), profile_);
[email protected]57c6a652009-05-04 07:58:341547 GetSelectedTabContents()->PrintPreview();
[email protected]fbd77592008-11-12 20:50:271548}
1549
[email protected]fbd77592008-11-12 20:50:271550void Browser::ToggleEncodingAutoDetect() {
[email protected]896220042010-03-23 18:14:281551 UserMetrics::RecordAction(UserMetricsAction("AutoDetectChange"), profile_);
[email protected]fbd77592008-11-12 20:50:271552 encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue());
[email protected]a697f4c2009-09-14 22:30:181553 // If "auto detect" is turned on, then any current override encoding
1554 // is cleared. This also implicitly performs a reload.
1555 // OTOH, if "auto detect" is turned off, we don't change the currently
1556 // active encoding.
1557 if (encoding_auto_detect_.GetValue()) {
1558 TabContents* contents = GetSelectedTabContents();
1559 if (contents)
[email protected]b2fe07d12010-02-09 14:38:081560 contents->ResetOverrideEncoding();
[email protected]a697f4c2009-09-14 22:30:181561 }
[email protected]fbd77592008-11-12 20:50:271562}
1563
1564void Browser::OverrideEncoding(int encoding_id) {
[email protected]896220042010-03-23 18:14:281565 UserMetrics::RecordAction(UserMetricsAction("OverrideEncoding"), profile_);
[email protected]41fc0322009-09-04 22:23:401566 const std::string selected_encoding =
[email protected]fbd77592008-11-12 20:50:271567 CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id);
[email protected]57c6a652009-05-04 07:58:341568 TabContents* contents = GetSelectedTabContents();
1569 if (!selected_encoding.empty() && contents)
[email protected]b2fe07d12010-02-09 14:38:081570 contents->SetOverrideEncoding(selected_encoding);
[email protected]fbd77592008-11-12 20:50:271571 // Update the list of recently selected encodings.
[email protected]41fc0322009-09-04 22:23:401572 std::string new_selected_encoding_list;
[email protected]ddd231e2010-06-29 20:35:191573 if (CharacterEncoding::UpdateRecentlySelectedEncoding(
1574 profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding),
[email protected]41fc0322009-09-04 22:23:401575 encoding_id,
1576 &new_selected_encoding_list)) {
[email protected]fbd77592008-11-12 20:50:271577 profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding,
[email protected]ddd231e2010-06-29 20:35:191578 new_selected_encoding_list);
[email protected]fbd77592008-11-12 20:50:271579 }
[email protected]36b6dcb2008-11-12 01:19:571580}
1581
[email protected]84214982008-12-10 18:49:101582void Browser::Cut() {
[email protected]896220042010-03-23 18:14:281583 UserMetrics::RecordAction(UserMetricsAction("Cut"), profile_);
[email protected]20012dd42010-01-25 04:46:231584 window()->Cut();
[email protected]36b6dcb2008-11-12 01:19:571585}
1586
[email protected]84214982008-12-10 18:49:101587void Browser::Copy() {
[email protected]896220042010-03-23 18:14:281588 UserMetrics::RecordAction(UserMetricsAction("Copy"), profile_);
[email protected]20012dd42010-01-25 04:46:231589 window()->Copy();
[email protected]36b6dcb2008-11-12 01:19:571590}
1591
[email protected]84214982008-12-10 18:49:101592void Browser::Paste() {
[email protected]896220042010-03-23 18:14:281593 UserMetrics::RecordAction(UserMetricsAction("Paste"), profile_);
[email protected]20012dd42010-01-25 04:46:231594 window()->Paste();
[email protected]84214982008-12-10 18:49:101595}
1596
1597void Browser::Find() {
[email protected]896220042010-03-23 18:14:281598 UserMetrics::RecordAction(UserMetricsAction("Find"), profile_);
[email protected]4f3dc372009-02-24 00:10:291599 FindInPage(false, false);
[email protected]84214982008-12-10 18:49:101600}
1601
1602void Browser::FindNext() {
[email protected]896220042010-03-23 18:14:281603 UserMetrics::RecordAction(UserMetricsAction("FindNext"), profile_);
[email protected]4f3dc372009-02-24 00:10:291604 FindInPage(true, true);
[email protected]84214982008-12-10 18:49:101605}
1606
1607void Browser::FindPrevious() {
[email protected]896220042010-03-23 18:14:281608 UserMetrics::RecordAction(UserMetricsAction("FindPrevious"), profile_);
[email protected]4f3dc372009-02-24 00:10:291609 FindInPage(true, false);
[email protected]84214982008-12-10 18:49:101610}
1611
[email protected]40bd6582009-12-04 23:49:511612void Browser::Zoom(PageZoom::Function zoom_function) {
[email protected]896220042010-03-23 18:14:281613 static const UserMetricsAction kActions[] = {
1614 UserMetricsAction("ZoomMinus"),
1615 UserMetricsAction("ZoomNormal"),
1616 UserMetricsAction("ZoomPlus")
1617 };
1618
1619 UserMetrics::RecordAction(kActions[zoom_function - PageZoom::ZOOM_OUT],
1620 profile_);
[email protected]3c9e1872010-11-18 16:17:491621 TabContentsWrapper* tab_contents = GetSelectedTabContentsWrapper();
[email protected]40bd6582009-12-04 23:49:511622 tab_contents->render_view_host()->Zoom(zoom_function);
[email protected]84214982008-12-10 18:49:101623}
1624
1625void Browser::FocusToolbar() {
[email protected]896220042010-03-23 18:14:281626 UserMetrics::RecordAction(UserMetricsAction("FocusToolbar"), profile_);
[email protected]84214982008-12-10 18:49:101627 window_->FocusToolbar();
1628}
1629
[email protected]bdb7ff62010-07-20 01:56:521630void Browser::FocusAppMenu() {
1631 UserMetrics::RecordAction(UserMetricsAction("FocusAppMenu"), profile_);
1632 window_->FocusAppMenu();
[email protected]cc824372010-03-31 15:33:011633}
1634
[email protected]84214982008-12-10 18:49:101635void Browser::FocusLocationBar() {
[email protected]896220042010-03-23 18:14:281636 UserMetrics::RecordAction(UserMetricsAction("FocusLocation"), profile_);
[email protected]a26dc362010-04-23 01:48:581637 window_->SetFocusToLocationBar(true);
[email protected]84214982008-12-10 18:49:101638}
1639
[email protected]83548a42010-06-18 13:53:371640void Browser::FocusBookmarksToolbar() {
1641 UserMetrics::RecordAction(UserMetricsAction("FocusBookmarksToolbar"),
1642 profile_);
1643 window_->FocusBookmarksToolbar();
1644}
1645
1646void Browser::FocusChromeOSStatus() {
1647 UserMetrics::RecordAction(UserMetricsAction("FocusChromeOSStatus"), profile_);
1648 window_->FocusChromeOSStatus();
1649}
1650
1651void Browser::FocusNextPane() {
1652 UserMetrics::RecordAction(UserMetricsAction("FocusNextPane"), profile_);
1653 window_->RotatePaneFocus(true);
1654}
1655
1656void Browser::FocusPreviousPane() {
1657 UserMetrics::RecordAction(UserMetricsAction("FocusPreviousPane"), profile_);
1658 window_->RotatePaneFocus(false);
1659}
1660
[email protected]84214982008-12-10 18:49:101661void Browser::FocusSearch() {
1662 // TODO(beng): replace this with FocusLocationBar
[email protected]896220042010-03-23 18:14:281663 UserMetrics::RecordAction(UserMetricsAction("FocusSearch"), profile_);
[email protected]7745b822009-01-27 20:15:351664 window_->GetLocationBar()->FocusSearch();
[email protected]84214982008-12-10 18:49:101665}
1666
1667void Browser::OpenFile() {
[email protected]896220042010-03-23 18:14:281668 UserMetrics::RecordAction(UserMetricsAction("OpenFile"), profile_);
[email protected]f59f1162010-04-23 21:19:291669#if defined(OS_CHROMEOS)
1670 FileBrowseUI::OpenPopup(profile_,
1671 "",
1672 FileBrowseUI::kPopupWidth,
1673 FileBrowseUI::kPopupHeight);
1674#else
[email protected]84214982008-12-10 18:49:101675 if (!select_file_dialog_.get())
1676 select_file_dialog_ = SelectFileDialog::Create(this);
1677
[email protected]35896a32010-06-09 08:42:511678 const FilePath directory = profile_->last_selected_directory();
1679
[email protected]84214982008-12-10 18:49:101680 // TODO(beng): figure out how to juggle this.
[email protected]d56bcd22009-03-16 19:51:561681 gfx::NativeWindow parent_window = window_->GetNativeHandle();
[email protected]84214982008-12-10 18:49:101682 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
[email protected]35896a32010-06-09 08:42:511683 string16(), directory,
[email protected]b949f1112009-04-12 20:03:081684 NULL, 0, FILE_PATH_LITERAL(""),
[email protected]d56bcd22009-03-16 19:51:561685 parent_window, NULL);
[email protected]f59f1162010-04-23 21:19:291686#endif
[email protected]84214982008-12-10 18:49:101687}
1688
1689void Browser::OpenCreateShortcutsDialog() {
[email protected]896220042010-03-23 18:14:281690 UserMetrics::RecordAction(UserMetricsAction("CreateShortcut"), profile_);
[email protected]b96aa932009-08-12 21:34:491691#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]3c9e1872010-11-18 16:17:491692 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
1693 DCHECK(current_tab &&
1694 web_app::IsValidUrl(current_tab->tab_contents()->GetURL())) <<
1695 "Menu item should be disabled.";
[email protected]ed5431872009-11-17 08:39:511696
1697 NavigationEntry* entry = current_tab->controller().GetLastCommittedEntry();
1698 if (!entry)
1699 return;
1700
[email protected]eabfdae92009-12-11 06:13:511701 // RVH's GetApplicationInfo should not be called before it returns.
1702 DCHECK(pending_web_app_action_ == NONE);
1703 pending_web_app_action_ = CREATE_SHORTCUT;
1704
[email protected]a2cf65eb2010-01-18 08:20:381705 // Start fetching web app info for CreateApplicationShortcut dialog and show
1706 // the dialog when the data is available in OnDidGetApplicationInfo.
[email protected]ed5431872009-11-17 08:39:511707 current_tab->render_view_host()->GetApplicationInfo(entry->page_id());
[email protected]98f6e022009-06-05 22:49:531708#else
1709 NOTIMPLEMENTED();
1710#endif
[email protected]36b6dcb2008-11-12 01:19:571711}
1712
[email protected]2a8a98122010-07-16 11:58:481713void Browser::ToggleDevToolsWindow(DevToolsToggleAction action) {
1714 std::string uma_string;
1715 switch (action) {
1716 case DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE:
1717 uma_string = "DevTools_ToggleConsole";
1718 break;
1719 case DEVTOOLS_TOGGLE_ACTION_NONE:
1720 case DEVTOOLS_TOGGLE_ACTION_INSPECT:
1721 default:
1722 uma_string = "DevTools_ToggleWindow";
1723 break;
1724 }
1725 UserMetrics::RecordAction(UserMetricsAction(uma_string.c_str()), profile_);
[email protected]3061ccf32009-07-13 14:17:491726 DevToolsManager::GetInstance()->ToggleDevToolsWindow(
[email protected]3c9e1872010-11-18 16:17:491727 GetSelectedTabContentsWrapper()->render_view_host(), action);
[email protected]fbd77592008-11-12 20:50:271728}
1729
[email protected]84214982008-12-10 18:49:101730void Browser::OpenTaskManager() {
[email protected]896220042010-03-23 18:14:281731 UserMetrics::RecordAction(UserMetricsAction("TaskManager"), profile_);
[email protected]8f90afd72009-06-22 22:44:381732 window_->ShowTaskManager();
[email protected]84214982008-12-10 18:49:101733}
1734
[email protected]84214982008-12-10 18:49:101735void Browser::OpenBugReportDialog() {
[email protected]86206622010-05-14 05:45:261736 UserMetrics::RecordAction(UserMetricsAction("ReportBug"), profile_);
1737 window_->ShowReportBugDialog();
[email protected]84214982008-12-10 18:49:101738}
[email protected]44b2c8852009-03-18 00:57:491739
[email protected]84214982008-12-10 18:49:101740void Browser::ToggleBookmarkBar() {
[email protected]896220042010-03-23 18:14:281741 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarksBar"), profile_);
[email protected]84214982008-12-10 18:49:101742 window_->ToggleBookmarkBar();
1743}
1744
[email protected]84214982008-12-10 18:49:101745void Browser::OpenBookmarkManager() {
[email protected]896220042010-03-23 18:14:281746 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarkManager"), profile_);
[email protected]47e532b2010-04-23 17:46:401747 ShowBookmarkManagerTab();
[email protected]84214982008-12-10 18:49:101748}
[email protected]8bf80e922009-03-09 20:56:361749
[email protected]fdb98512009-08-26 01:37:101750void Browser::ShowAppMenu() {
[email protected]896220042010-03-23 18:14:281751 UserMetrics::RecordAction(UserMetricsAction("ShowAppMenu"), profile_);
[email protected]fdb98512009-08-26 01:37:101752 window_->ShowAppMenu();
1753}
1754
[email protected]6404197b2010-03-03 00:40:401755void Browser::ShowBookmarkManagerTab() {
[email protected]04f40d362010-10-11 17:52:451756 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarks"), profile_);
[email protected]bb89e7482010-11-17 18:27:041757 ShowSingletonTab(GURL(chrome::kChromeUIBookmarksURL), false);
[email protected]6404197b2010-03-03 00:40:401758}
1759
[email protected]8bf80e922009-03-09 20:56:361760void Browser::ShowHistoryTab() {
[email protected]896220042010-03-23 18:14:281761 UserMetrics::RecordAction(UserMetricsAction("ShowHistory"), profile_);
[email protected]bb89e7482010-11-17 18:27:041762 ShowSingletonTab(GURL(chrome::kChromeUIHistoryURL), false);
[email protected]8bf80e922009-03-09 20:56:361763}
[email protected]84214982008-12-10 18:49:101764
1765void Browser::ShowDownloadsTab() {
[email protected]896220042010-03-23 18:14:281766 UserMetrics::RecordAction(UserMetricsAction("ShowDownloads"), profile_);
[email protected]bb89e7482010-11-17 18:27:041767 ShowSingletonTab(GURL(chrome::kChromeUIDownloadsURL), false);
[email protected]84214982008-12-10 18:49:101768}
1769
[email protected]34085a32009-11-06 22:49:481770void Browser::ShowExtensionsTab() {
[email protected]896220042010-03-23 18:14:281771 UserMetrics::RecordAction(UserMetricsAction("ShowExtensions"), profile_);
[email protected]bb89e7482010-11-17 18:27:041772 ShowSingletonTab(GURL(chrome::kChromeUIExtensionsURL), false);
[email protected]34085a32009-11-06 22:49:481773}
1774
[email protected]c1bbaa82010-11-08 11:17:051775void Browser::ShowAboutConflictsTab() {
1776 UserMetrics::RecordAction(UserMetricsAction("AboutConflicts"), profile_);
[email protected]bb89e7482010-11-17 18:27:041777 ShowSingletonTab(GURL(chrome::kChromeUIConflictsURL), false);
[email protected]c1bbaa82010-11-08 11:17:051778}
1779
[email protected]10e457c2010-04-29 03:35:231780void Browser::ShowBrokenPageTab(TabContents* contents) {
1781 UserMetrics::RecordAction(UserMetricsAction("ReportBug"), profile_);
1782 string16 page_title = contents->GetTitle();
1783 NavigationEntry* entry = contents->controller().GetActiveEntry();
1784 if (!entry)
1785 return;
1786 std::string page_url = entry->url().spec();
1787 std::vector<std::string> subst;
1788 subst.push_back(UTF16ToASCII(page_title));
1789 subst.push_back(page_url);
1790 std::string report_page_url =
1791 ReplaceStringPlaceholders(kBrokenPageUrl, subst, NULL);
[email protected]bb89e7482010-11-17 18:27:041792 ShowSingletonTab(GURL(report_page_url), false);
[email protected]10e457c2010-04-29 03:35:231793}
1794
[email protected]12e816bde2010-09-14 19:59:291795void Browser::ShowOptionsTab(const std::string& sub_page) {
[email protected]e50eeee2010-09-22 00:33:301796 GURL url(chrome::kChromeUISettingsURL + sub_page);
[email protected]bb89e7482010-11-17 18:27:041797 ShowSingletonTab(url, true);
[email protected]4a42d272010-06-18 01:29:421798}
1799
[email protected]84214982008-12-10 18:49:101800void Browser::OpenClearBrowsingDataDialog() {
[email protected]896220042010-03-23 18:14:281801 UserMetrics::RecordAction(UserMetricsAction("ClearBrowsingData_ShowDlg"),
1802 profile_);
[email protected]0b590b32010-09-13 22:30:561803 if (CommandLine::ForCurrentProcess()->HasSwitch(
1804 switches::kEnableTabbedOptions)) {
[email protected]12e816bde2010-09-14 19:59:291805 ShowOptionsTab(
[email protected]91a79232010-11-10 18:15:081806 chrome::kAdvancedOptionsSubPage + std::string(kHashMark) +
[email protected]12e816bde2010-09-14 19:59:291807 chrome::kClearBrowserDataSubPage);
[email protected]0b590b32010-09-13 22:30:561808 } else {
1809 window_->ShowClearBrowsingDataDialog();
1810 }
[email protected]84214982008-12-10 18:49:101811}
1812
[email protected]84214982008-12-10 18:49:101813void Browser::OpenOptionsDialog() {
[email protected]024617a2010-08-20 05:08:051814 UserMetrics::RecordAction(UserMetricsAction("ShowOptions"), profile_);
[email protected]4a42d272010-06-18 01:29:421815 if (CommandLine::ForCurrentProcess()->HasSwitch(
1816 switches::kEnableTabbedOptions)) {
[email protected]024617a2010-08-20 05:08:051817 ShowOptionsTab(chrome::kDefaultOptionsSubPage);
[email protected]4a42d272010-06-18 01:29:421818 } else {
[email protected]4a42d272010-06-18 01:29:421819 ShowOptionsWindow(OPTIONS_PAGE_DEFAULT, OPTIONS_GROUP_NONE, profile_);
1820 }
[email protected]84214982008-12-10 18:49:101821}
1822
1823void Browser::OpenKeywordEditor() {
[email protected]896220042010-03-23 18:14:281824 UserMetrics::RecordAction(UserMetricsAction("EditSearchEngines"), profile_);
[email protected]024617a2010-08-20 05:08:051825 if (CommandLine::ForCurrentProcess()->HasSwitch(
1826 switches::kEnableTabbedOptions)) {
[email protected]1023c862010-10-21 00:29:101827 ShowOptionsTab(chrome::kSearchEnginesSubPage);
[email protected]024617a2010-08-20 05:08:051828 } else {
1829 window_->ShowSearchEnginesDialog();
1830 }
[email protected]fbd77592008-11-12 20:50:271831}
1832
1833void Browser::OpenPasswordManager() {
[email protected]2d46c842008-11-14 19:24:311834 window_->ShowPasswordManager();
[email protected]fbd77592008-11-12 20:50:271835}
1836
[email protected]1bdf29e2009-05-11 23:45:251837void Browser::OpenImportSettingsDialog() {
[email protected]896220042010-03-23 18:14:281838 UserMetrics::RecordAction(UserMetricsAction("Import_ShowDlg"), profile_);
[email protected]0b590b32010-09-13 22:30:561839 if (CommandLine::ForCurrentProcess()->HasSwitch(
1840 switches::kEnableTabbedOptions)) {
[email protected]12e816bde2010-09-14 19:59:291841 ShowOptionsTab(
[email protected]91a79232010-11-10 18:15:081842 chrome::kPersonalOptionsSubPage + std::string(kHashMark) +
[email protected]12e816bde2010-09-14 19:59:291843 chrome::kImportDataSubPage);
[email protected]0b590b32010-09-13 22:30:561844 } else {
1845 window_->ShowImportDialog();
1846 }
[email protected]1bdf29e2009-05-11 23:45:251847}
[email protected]1bdf29e2009-05-11 23:45:251848
[email protected]ca38d8e2009-08-20 18:08:161849void Browser::OpenSyncMyBookmarksDialog() {
[email protected]40f047972009-11-25 03:54:401850 sync_ui_util::OpenSyncMyBookmarksDialog(
[email protected]46935222009-11-23 22:48:431851 profile_, ProfileSyncService::START_FROM_WRENCH);
[email protected]ca38d8e2009-08-20 18:08:161852}
[email protected]ca38d8e2009-08-20 18:08:161853
[email protected]da96e54c2010-08-12 00:18:321854#if defined(ENABLE_REMOTING)
1855void Browser::OpenRemotingSetupDialog() {
[email protected]61c13e82010-08-31 19:16:181856 RemotingSetupFlow::OpenDialog(profile_);
[email protected]da96e54c2010-08-12 00:18:321857}
1858#endif
1859
[email protected]fbd77592008-11-12 20:50:271860void Browser::OpenAboutChromeDialog() {
[email protected]896220042010-03-23 18:14:281861 UserMetrics::RecordAction(UserMetricsAction("AboutChrome"), profile_);
[email protected]976e69f2010-08-13 18:28:171862#if defined(OS_CHROMEOS)
[email protected]bb89e7482010-11-17 18:27:041863 ShowSingletonTab(GURL(chrome::kChromeUIAboutURL), false);
[email protected]976e69f2010-08-13 18:28:171864#else
[email protected]2d46c842008-11-14 19:24:311865 window_->ShowAboutChromeDialog();
[email protected]976e69f2010-08-13 18:28:171866#endif
[email protected]fbd77592008-11-12 20:50:271867}
1868
[email protected]b1b73942010-05-26 20:11:541869void Browser::OpenUpdateChromeDialog() {
1870 UserMetrics::RecordAction(UserMetricsAction("UpdateChrome"), profile_);
1871 window_->ShowUpdateChromeDialog();
1872}
1873
[email protected]fbd77592008-11-12 20:50:271874void Browser::OpenHelpTab() {
[email protected]0a4a0be2010-11-09 10:42:471875 GURL help_url(kHelpContentUrl);
1876#if defined(OS_CHROMEOS)
1877 // TODO(nkostylev): Always redirect to HelpApp http://crosbug.com/6923
1878 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession))
1879 help_url = GURL(kHelpContentOnlineUrl);
1880#endif
1881 GURL localized_help_url = google_util::AppendGoogleLocaleParam(help_url);
1882 AddSelectedTabWithURL(localized_help_url, PageTransition::AUTO_BOOKMARK);
[email protected]fbd77592008-11-12 20:50:271883}
1884
[email protected]403c14862009-10-28 00:00:491885void Browser::OpenThemeGalleryTabAndActivate() {
[email protected]616381f02010-11-02 15:15:331886 AddSelectedTabWithURL(GURL(l10n_util::GetStringUTF8(IDS_THEMES_GALLERY_URL)),
1887 PageTransition::LINK);
[email protected]403c14862009-10-28 00:00:491888}
1889
[email protected]31cc1c022010-10-15 20:03:471890void Browser::OpenPrivacyDashboardTabAndActivate() {
[email protected]3e0505452010-11-02 21:45:241891 OpenURL(GURL(kPrivacyDashboardUrl), GURL(),
1892 NEW_FOREGROUND_TAB, PageTransition::LINK);
[email protected]31cc1c022010-10-15 20:03:471893 window_->Activate();
1894}
1895
[email protected]bb8fe2d2010-06-28 20:04:221896void Browser::OpenAutoFillHelpTabAndActivate() {
[email protected]91a79232010-11-10 18:15:081897 GURL help_url = google_util::AppendGoogleLocaleParam(GURL(kAutofillHelpUrl));
1898 AddSelectedTabWithURL(help_url, PageTransition::LINK);
[email protected]bb8fe2d2010-06-28 20:04:221899}
1900
[email protected]024617a2010-08-20 05:08:051901void Browser::OpenSearchEngineOptionsDialog() {
1902 if (CommandLine::ForCurrentProcess()->HasSwitch(
1903 switches::kEnableTabbedOptions)) {
1904 OpenKeywordEditor();
1905 } else {
1906 ShowOptionsWindow(OPTIONS_PAGE_GENERAL, OPTIONS_GROUP_DEFAULT_SEARCH,
1907 profile_);
1908 }
1909}
1910
[email protected]16779842009-07-08 23:45:291911#if defined(OS_CHROMEOS)
[email protected]5dcbc02f2010-01-26 22:32:061912void Browser::OpenSystemOptionsDialog() {
[email protected]896220042010-03-23 18:14:281913 UserMetrics::RecordAction(UserMetricsAction("OpenSystemOptionsDialog"),
1914 profile_);
[email protected]024617a2010-08-20 05:08:051915 if (CommandLine::ForCurrentProcess()->HasSwitch(
1916 switches::kEnableTabbedOptions)) {
1917 ShowOptionsTab(chrome::kSystemOptionsSubPage);
1918 } else {
1919 ShowOptionsWindow(OPTIONS_PAGE_SYSTEM, OPTIONS_GROUP_NONE,
1920 profile_);
1921 }
[email protected]5dcbc02f2010-01-26 22:32:061922}
1923
1924void Browser::OpenInternetOptionsDialog() {
[email protected]896220042010-03-23 18:14:281925 UserMetrics::RecordAction(UserMetricsAction("OpenInternetOptionsDialog"),
1926 profile_);
[email protected]024617a2010-08-20 05:08:051927 if (CommandLine::ForCurrentProcess()->HasSwitch(
1928 switches::kEnableTabbedOptions)) {
1929 ShowOptionsTab(chrome::kInternetOptionsSubPage);
1930 } else {
1931 ShowOptionsWindow(OPTIONS_PAGE_INTERNET, OPTIONS_GROUP_DEFAULT_SEARCH,
1932 profile_);
1933 }
1934}
1935
1936void Browser::OpenLanguageOptionsDialog() {
1937 UserMetrics::RecordAction(UserMetricsAction("OpenLanguageOptionsDialog"),
1938 profile_);
1939 if (CommandLine::ForCurrentProcess()->HasSwitch(
1940 switches::kEnableTabbedOptions)) {
1941 ShowOptionsTab(chrome::kLanguageOptionsSubPage);
1942 } else {
1943 chromeos::LanguageConfigView::Show(profile_, NULL);
1944 }
[email protected]be715072009-07-07 15:43:201945}
[email protected]46b92f852010-10-06 13:12:051946
1947void Browser::OpenSystemTabAndActivate() {
1948 OpenURL(GURL(chrome::kChromeUISystemInfoURL), GURL(),
1949 NEW_FOREGROUND_TAB, PageTransition::LINK);
1950 window_->Activate();
1951}
1952
[email protected]38017612010-10-13 18:46:001953void Browser::OpenMobilePlanTabAndActivate() {
1954 OpenURL(GURL(chrome::kChromeUIMobileSetupURL), GURL(),
1955 NEW_FOREGROUND_TAB, PageTransition::LINK);
1956 window_->Activate();
1957}
[email protected]be715072009-07-07 15:43:201958#endif
1959
[email protected]a003d8e2010-10-02 21:03:351960void Browser::OpenPluginsTabAndActivate() {
1961 OpenURL(GURL(chrome::kAboutPluginsURL), GURL(),
1962 NEW_FOREGROUND_TAB, PageTransition::LINK);
1963 window_->Activate();
1964}
1965
[email protected]36b6dcb2008-11-12 01:19:571966///////////////////////////////////////////////////////////////////////////////
1967
1968// static
[email protected]79117172009-08-28 16:11:441969void Browser::SetNewHomePagePrefs(PrefService* prefs) {
[email protected]8fe6e1c2010-05-27 08:21:541970 const PrefService::Preference* home_page_pref =
1971 prefs->FindPreference(prefs::kHomePage);
1972 if (home_page_pref &&
1973 !home_page_pref->IsManaged() &&
[email protected]ddd231e2010-06-29 20:35:191974 !prefs->HasPrefPath(prefs::kHomePage)) {
[email protected]b41eb732009-09-30 16:49:331975 prefs->SetString(prefs::kHomePage,
[email protected]ddd231e2010-06-29 20:35:191976 GoogleURLTracker::kDefaultGoogleHomepage);
1977 }
[email protected]8fe6e1c2010-05-27 08:21:541978 const PrefService::Preference* home_page_is_new_tab_page_pref =
1979 prefs->FindPreference(prefs::kHomePageIsNewTabPage);
1980 if (home_page_is_new_tab_page_pref &&
1981 !home_page_is_new_tab_page_pref->IsManaged() &&
1982 !prefs->HasPrefPath(prefs::kHomePageIsNewTabPage))
[email protected]b41eb732009-09-30 16:49:331983 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
[email protected]79117172009-08-28 16:11:441984}
1985
1986// static
[email protected]36b6dcb2008-11-12 01:19:571987void Browser::RegisterPrefs(PrefService* prefs) {
1988 prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement);
1989 prefs->RegisterIntegerPref(prefs::kOptionsWindowLastTabIndex, 0);
[email protected]749380bb2009-07-20 08:57:551990 prefs->RegisterIntegerPref(prefs::kDevToolsSplitLocation, -1);
[email protected]74ed092b2010-06-03 16:14:161991 prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement);
[email protected]8b8e7c92010-08-19 18:05:561992 prefs->RegisterIntegerPref(prefs::kExtensionSidebarWidth, -1);
[email protected]36b6dcb2008-11-12 01:19:571993}
1994
1995// static
1996void Browser::RegisterUserPrefs(PrefService* prefs) {
[email protected]0d220832009-11-06 00:45:181997 prefs->RegisterStringPref(prefs::kHomePage,
[email protected]20ce516d2010-06-18 02:20:041998 chrome::kChromeUINewTabURL);
[email protected]36b6dcb2008-11-12 01:19:571999 prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage, true);
[email protected]4ef795df2010-02-03 02:35:082000 prefs->RegisterBooleanPref(prefs::kClearSiteDataOnExit, false);
[email protected]36b6dcb2008-11-12 01:19:572001 prefs->RegisterBooleanPref(prefs::kShowHomeButton, false);
[email protected]93a2c7242009-07-07 18:43:092002#if defined(OS_MACOSX)
2003 // This really belongs in platform code, but there's no good place to
2004 // initialize it between the time when the AppController is created
2005 // (where there's no profile) and the time the controller gets another
2006 // crack at the start of the main event loop. By that time, BrowserInit
2007 // has already created the browser window, and it's too late: we need the
2008 // pref to be already initialized. Doing it here also saves us from having
2009 // to hard-code pref registration in the several unit tests that use
2010 // this preference.
2011 prefs->RegisterBooleanPref(prefs::kShowPageOptionsButtons, false);
[email protected]eee9f552009-11-28 22:05:112012 prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar, true);
[email protected]93a2c7242009-07-07 18:43:092013#endif
[email protected]20ce516d2010-06-18 02:20:042014 prefs->RegisterStringPref(prefs::kRecentlySelectedEncoding, "");
[email protected]36b6dcb2008-11-12 01:19:572015 prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory, true);
2016 prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory, true);
2017 prefs->RegisterBooleanPref(prefs::kDeleteCache, true);
2018 prefs->RegisterBooleanPref(prefs::kDeleteCookies, true);
2019 prefs->RegisterBooleanPref(prefs::kDeletePasswords, false);
[email protected]18f92d4f2010-10-19 00:14:582020 prefs->RegisterBooleanPref(prefs::kDeleteFormData, false);
[email protected]36b6dcb2008-11-12 01:19:572021 prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod, 0);
[email protected]48b47ffa2009-05-02 07:18:302022 prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser, true);
[email protected]c8865482009-07-23 20:40:102023 prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint, true);
[email protected]ed5431872009-11-17 08:39:512024 prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop, true);
2025 prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu, true);
2026 prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar, true);
[email protected]b9c505b2010-04-30 15:05:102027 prefs->RegisterBooleanPref(prefs::kUseVerticalTabs, false);
[email protected]0908acd92010-02-26 17:42:132028 prefs->RegisterBooleanPref(prefs::kEnableTranslate, true);
[email protected]e96bf0c52010-08-23 23:20:572029 prefs->RegisterBooleanPref(prefs::kRemotingHasSetupCompleted, false);
[email protected]02337592010-09-27 18:38:252030 prefs->RegisterStringPref(prefs::kCloudPrintEmail, std::string());
[email protected]543432ee2010-10-22 16:32:132031 prefs->RegisterBooleanPref(prefs::kDevToolsDisabled, false);
[email protected]d0b8d092010-10-25 04:05:172032 prefs->RegisterRealPref(prefs::kDefaultZoomLevel, 0.0);
[email protected]36b6dcb2008-11-12 01:19:572033}
2034
2035// static
[email protected]ecc523f62010-09-28 22:45:402036bool Browser::RunUnloadEventsHelper(TabContents* contents) {
2037 // If the TabContents is not connected yet, then there's no unload
2038 // handler we can fire even if the TabContents has an unload listener.
2039 // One case where we hit this is in a tab that has an infinite loop
2040 // before load.
2041 if (TabHasUnloadListener(contents)) {
2042 // If the page has unload listeners, then we tell the renderer to fire
2043 // them. Once they have fired, we'll get a message back saying whether
2044 // to proceed closing the page or not, which sends us back to this method
2045 // with the HasUnloadListener bit cleared.
2046 contents->render_view_host()->FirePageBeforeUnload(false);
2047 return true;
2048 }
2049 return false;
2050}
2051
2052// static
[email protected]36b6dcb2008-11-12 01:19:572053Browser* Browser::GetBrowserForController(
2054 const NavigationController* controller, int* index_result) {
2055 BrowserList::const_iterator it;
2056 for (it = BrowserList::begin(); it != BrowserList::end(); ++it) {
[email protected]ecc523f62010-09-28 22:45:402057 int index = (*it)->tab_handler_->GetTabStripModel()->GetIndexOfController(
2058 controller);
[email protected]36b6dcb2008-11-12 01:19:572059 if (index != TabStripModel::kNoTab) {
2060 if (index_result)
2061 *index_result = index;
2062 return *it;
2063 }
2064 }
2065
2066 return NULL;
2067}
2068
[email protected]485fba42009-03-24 23:27:292069void Browser::ExecuteCommandWithDisposition(
2070 int id, WindowOpenDisposition disposition) {
[email protected]1fc025202009-01-20 23:03:142071 // No commands are enabled if there is not yet any selected tab.
2072 // TODO(pkasting): It seems like we should not need this, because either
2073 // most/all commands should not have been enabled yet anyway or the ones that
2074 // are enabled should be global, or safe themselves against having no selected
2075 // tab. However, Ben says he tried removing this before and got lots of
2076 // crashes, e.g. from Windows sending WM_COMMANDs at random times during
2077 // window construction. This probably could use closer examination someday.
[email protected]3c9e1872010-11-18 16:17:492078 if (!GetSelectedTabContentsWrapper())
[email protected]1fc025202009-01-20 23:03:142079 return;
2080
[email protected]59c9f002010-11-19 00:38:052081 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
2082 << id;
[email protected]36b6dcb2008-11-12 01:19:572083
[email protected]867125a02009-12-10 06:01:482084 // If command execution is blocked then just record the command and return.
2085 if (block_command_execution_) {
2086 // We actually only allow no more than one blocked command, otherwise some
2087 // commands maybe lost.
[email protected]5dcbc02f2010-01-26 22:32:062088 DCHECK_EQ(last_blocked_command_id_, -1);
[email protected]867125a02009-12-10 06:01:482089 last_blocked_command_id_ = id;
2090 last_blocked_command_disposition_ = disposition;
2091 return;
2092 }
2093
[email protected]fbd77592008-11-12 20:50:272094 // The order of commands in this switch statement must match the function
2095 // declaration order in browser.h!
[email protected]36b6dcb2008-11-12 01:19:572096 switch (id) {
[email protected]84214982008-12-10 18:49:102097 // Navigation commands
[email protected]cb84d642010-06-10 00:56:282098 case IDC_BACK: GoBack(disposition); break;
2099 case IDC_FORWARD: GoForward(disposition); break;
2100 case IDC_RELOAD: Reload(disposition); break;
2101 case IDC_RELOAD_IGNORING_CACHE: ReloadIgnoringCache(disposition); break;
2102 case IDC_HOME: Home(disposition); break;
2103 case IDC_OPEN_CURRENT_URL: OpenCurrentURL(); break;
[email protected]cb84d642010-06-10 00:56:282104 case IDC_STOP: Stop(); break;
[email protected]36b6dcb2008-11-12 01:19:572105
[email protected]84214982008-12-10 18:49:102106 // Window management commands
[email protected]cb84d642010-06-10 00:56:282107 case IDC_NEW_WINDOW: NewWindow(); break;
2108 case IDC_NEW_INCOGNITO_WINDOW: NewIncognitoWindow(); break;
[email protected]cb84d642010-06-10 00:56:282109 case IDC_CLOSE_WINDOW: CloseWindow(); break;
2110 case IDC_NEW_TAB: NewTab(); break;
2111 case IDC_CLOSE_TAB: CloseTab(); break;
2112 case IDC_SELECT_NEXT_TAB: SelectNextTab(); break;
2113 case IDC_SELECT_PREVIOUS_TAB: SelectPreviousTab(); break;
[email protected]91ac9202010-07-30 18:32:352114 case IDC_TABPOSE: OpenTabpose(); break;
[email protected]cb84d642010-06-10 00:56:282115 case IDC_MOVE_TAB_NEXT: MoveTabNext(); break;
2116 case IDC_MOVE_TAB_PREVIOUS: MoveTabPrevious(); break;
[email protected]36b6dcb2008-11-12 01:19:572117 case IDC_SELECT_TAB_0:
2118 case IDC_SELECT_TAB_1:
2119 case IDC_SELECT_TAB_2:
2120 case IDC_SELECT_TAB_3:
2121 case IDC_SELECT_TAB_4:
2122 case IDC_SELECT_TAB_5:
2123 case IDC_SELECT_TAB_6:
[email protected]cb525c82008-12-08 23:04:542124 case IDC_SELECT_TAB_7: SelectNumberedTab(id - IDC_SELECT_TAB_0);
[email protected]cb84d642010-06-10 00:56:282125 break;
2126 case IDC_SELECT_LAST_TAB: SelectLastTab(); break;
2127 case IDC_DUPLICATE_TAB: DuplicateTab(); break;
2128 case IDC_RESTORE_TAB: RestoreTab(); break;
2129 case IDC_COPY_URL: WriteCurrentURLToClipboard(); break;
2130 case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break;
2131 case IDC_FULLSCREEN: ToggleFullscreenMode(); break;
2132 case IDC_EXIT: Exit(); break;
2133 case IDC_TOGGLE_VERTICAL_TABS: ToggleUseVerticalTabs(); break;
[email protected]da17b372010-01-22 23:37:222134#if defined(OS_CHROMEOS)
[email protected]cb84d642010-06-10 00:56:282135 case IDC_SEARCH: Search(); break;
[email protected]d14af522010-12-02 03:54:502136 case IDC_SHOW_KEYBOARD_OVERLAY: ShowKeyboardOverlay(); break;
[email protected]20d17242009-10-26 20:21:052137#endif
[email protected]36b6dcb2008-11-12 01:19:572138
[email protected]84214982008-12-10 18:49:102139 // Page-related commands
[email protected]cb84d642010-06-10 00:56:282140 case IDC_SAVE_PAGE: SavePage(); break;
2141 case IDC_BOOKMARK_PAGE: BookmarkCurrentPage(); break;
2142 case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(); break;
2143 case IDC_VIEW_SOURCE: ViewSource(); break;
2144 case IDC_EMAIL_PAGE_LOCATION: EmailPageLocation(); break;
2145 case IDC_PRINT: Print(); break;
2146 case IDC_ENCODING_AUTO_DETECT: ToggleEncodingAutoDetect(); break;
[email protected]36b6dcb2008-11-12 01:19:572147 case IDC_ENCODING_UTF8:
2148 case IDC_ENCODING_UTF16LE:
2149 case IDC_ENCODING_ISO88591:
2150 case IDC_ENCODING_WINDOWS1252:
[email protected]1c5bf632008-12-11 20:30:492151 case IDC_ENCODING_GBK:
[email protected]36b6dcb2008-11-12 01:19:572152 case IDC_ENCODING_GB18030:
2153 case IDC_ENCODING_BIG5HKSCS:
2154 case IDC_ENCODING_BIG5:
2155 case IDC_ENCODING_KOREAN:
2156 case IDC_ENCODING_SHIFTJIS:
2157 case IDC_ENCODING_ISO2022JP:
2158 case IDC_ENCODING_EUCJP:
2159 case IDC_ENCODING_THAI:
2160 case IDC_ENCODING_ISO885915:
2161 case IDC_ENCODING_MACINTOSH:
2162 case IDC_ENCODING_ISO88592:
2163 case IDC_ENCODING_WINDOWS1250:
2164 case IDC_ENCODING_ISO88595:
2165 case IDC_ENCODING_WINDOWS1251:
2166 case IDC_ENCODING_KOI8R:
2167 case IDC_ENCODING_KOI8U:
2168 case IDC_ENCODING_ISO88597:
2169 case IDC_ENCODING_WINDOWS1253:
2170 case IDC_ENCODING_ISO88594:
2171 case IDC_ENCODING_ISO885913:
2172 case IDC_ENCODING_WINDOWS1257:
2173 case IDC_ENCODING_ISO88593:
2174 case IDC_ENCODING_ISO885910:
2175 case IDC_ENCODING_ISO885914:
2176 case IDC_ENCODING_ISO885916:
[email protected]36b6dcb2008-11-12 01:19:572177 case IDC_ENCODING_WINDOWS1254:
2178 case IDC_ENCODING_ISO88596:
2179 case IDC_ENCODING_WINDOWS1256:
2180 case IDC_ENCODING_ISO88598:
[email protected]e13271f2009-03-07 00:26:002181 case IDC_ENCODING_ISO88598I:
[email protected]36b6dcb2008-11-12 01:19:572182 case IDC_ENCODING_WINDOWS1255:
[email protected]cb84d642010-06-10 00:56:282183 case IDC_ENCODING_WINDOWS1258: OverrideEncoding(id); break;
[email protected]36b6dcb2008-11-12 01:19:572184
[email protected]84214982008-12-10 18:49:102185 // Clipboard commands
[email protected]cb84d642010-06-10 00:56:282186 case IDC_CUT: Cut(); break;
2187 case IDC_COPY: Copy(); break;
2188 case IDC_PASTE: Paste(); break;
[email protected]84214982008-12-10 18:49:102189
2190 // Find-in-page
[email protected]cb84d642010-06-10 00:56:282191 case IDC_FIND: Find(); break;
2192 case IDC_FIND_NEXT: FindNext(); break;
2193 case IDC_FIND_PREVIOUS: FindPrevious(); break;
[email protected]84214982008-12-10 18:49:102194
2195 // Zoom
[email protected]cb84d642010-06-10 00:56:282196 case IDC_ZOOM_PLUS: Zoom(PageZoom::ZOOM_IN); break;
2197 case IDC_ZOOM_NORMAL: Zoom(PageZoom::RESET); break;
2198 case IDC_ZOOM_MINUS: Zoom(PageZoom::ZOOM_OUT); break;
[email protected]84214982008-12-10 18:49:102199
2200 // Focus various bits of UI
[email protected]cb84d642010-06-10 00:56:282201 case IDC_FOCUS_TOOLBAR: FocusToolbar(); break;
2202 case IDC_FOCUS_LOCATION: FocusLocationBar(); break;
2203 case IDC_FOCUS_SEARCH: FocusSearch(); break;
[email protected]bdb7ff62010-07-20 01:56:522204 case IDC_FOCUS_MENU_BAR: FocusAppMenu(); break;
[email protected]83548a42010-06-18 13:53:372205 case IDC_FOCUS_BOOKMARKS: FocusBookmarksToolbar(); break;
2206 case IDC_FOCUS_CHROMEOS_STATUS: FocusChromeOSStatus(); break;
2207 case IDC_FOCUS_NEXT_PANE: FocusNextPane(); break;
2208 case IDC_FOCUS_PREVIOUS_PANE: FocusPreviousPane(); break;
[email protected]84214982008-12-10 18:49:102209
2210 // Show various bits of UI
[email protected]cb84d642010-06-10 00:56:282211 case IDC_OPEN_FILE: OpenFile(); break;
2212 case IDC_CREATE_SHORTCUTS: OpenCreateShortcutsDialog(); break;
[email protected]2a8a98122010-07-16 11:58:482213 case IDC_DEV_TOOLS: ToggleDevToolsWindow(
2214 DEVTOOLS_TOGGLE_ACTION_NONE);
2215 break;
2216 case IDC_DEV_TOOLS_CONSOLE: ToggleDevToolsWindow(
2217 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
2218 break;
2219 case IDC_DEV_TOOLS_INSPECT: ToggleDevToolsWindow(
2220 DEVTOOLS_TOGGLE_ACTION_INSPECT);
2221 break;
[email protected]b569c112010-11-22 20:53:442222 case IDC_TASK_MANAGER: // fall through to OpenTaskManager().
2223 case IDC_VIEW_BACKGROUND_PAGES: OpenTaskManager(); break;
[email protected]1c41a932010-11-22 23:41:232224 case IDC_FEEDBACK: OpenBugReportDialog(); break;
[email protected]44b2c8852009-03-18 00:57:492225
[email protected]cb84d642010-06-10 00:56:282226 case IDC_SHOW_BOOKMARK_BAR: ToggleBookmarkBar(); break;
[email protected]44b2c8852009-03-18 00:57:492227
[email protected]cb84d642010-06-10 00:56:282228 case IDC_SHOW_BOOKMARK_MANAGER: OpenBookmarkManager(); break;
2229 case IDC_SHOW_APP_MENU: ShowAppMenu(); break;
[email protected]cb84d642010-06-10 00:56:282230 case IDC_SHOW_HISTORY: ShowHistoryTab(); break;
2231 case IDC_SHOW_DOWNLOADS: ShowDownloadsTab(); break;
2232 case IDC_MANAGE_EXTENSIONS: ShowExtensionsTab(); break;
2233 case IDC_SYNC_BOOKMARKS: OpenSyncMyBookmarksDialog(); break;
[email protected]da96e54c2010-08-12 00:18:322234#if defined(ENABLE_REMOTING)
2235 case IDC_REMOTING_SETUP: OpenRemotingSetupDialog(); break;
2236#endif
[email protected]cb84d642010-06-10 00:56:282237 case IDC_OPTIONS: OpenOptionsDialog(); break;
2238 case IDC_EDIT_SEARCH_ENGINES: OpenKeywordEditor(); break;
2239 case IDC_VIEW_PASSWORDS: OpenPasswordManager(); break;
2240 case IDC_CLEAR_BROWSING_DATA: OpenClearBrowsingDataDialog(); break;
2241 case IDC_IMPORT_SETTINGS: OpenImportSettingsDialog(); break;
[email protected]b21d6912010-08-31 19:22:412242 case IDC_ABOUT: OpenAboutChromeDialog(); break;
2243 case IDC_UPGRADE_DIALOG: OpenUpdateChromeDialog(); break;
[email protected]c1bbaa82010-11-08 11:17:052244 case IDC_VIEW_INCOMPATIBILITIES: ShowAboutConflictsTab(); break;
[email protected]cb84d642010-06-10 00:56:282245 case IDC_HELP_PAGE: OpenHelpTab(); break;
[email protected]16779842009-07-08 23:45:292246#if defined(OS_CHROMEOS)
[email protected]cb84d642010-06-10 00:56:282247 case IDC_SYSTEM_OPTIONS: OpenSystemOptionsDialog(); break;
2248 case IDC_INTERNET_OPTIONS: OpenInternetOptionsDialog(); break;
[email protected]024617a2010-08-20 05:08:052249 case IDC_LANGUAGE_OPTIONS: OpenLanguageOptionsDialog(); break;
[email protected]be715072009-07-07 15:43:202250#endif
[email protected]d938aed92009-01-22 19:49:332251
[email protected]36b6dcb2008-11-12 01:19:572252 default:
[email protected]84214982008-12-10 18:49:102253 LOG(WARNING) << "Received Unimplemented Command: " << id;
[email protected]fbd77592008-11-12 20:50:272254 break;
[email protected]36b6dcb2008-11-12 01:19:572255 }
2256}
2257
[email protected]867125a02009-12-10 06:01:482258bool Browser::IsReservedCommand(int command_id) {
2259 return command_id == IDC_CLOSE_TAB ||
[email protected]867125a02009-12-10 06:01:482260 command_id == IDC_CLOSE_WINDOW ||
2261 command_id == IDC_NEW_INCOGNITO_WINDOW ||
2262 command_id == IDC_NEW_TAB ||
2263 command_id == IDC_NEW_WINDOW ||
2264 command_id == IDC_RESTORE_TAB ||
2265 command_id == IDC_SELECT_NEXT_TAB ||
2266 command_id == IDC_SELECT_PREVIOUS_TAB ||
[email protected]c1d0d812010-07-27 20:21:552267 command_id == IDC_TABPOSE ||
[email protected]f97d7f632010-06-01 21:08:332268 command_id == IDC_EXIT ||
2269 command_id == IDC_SEARCH;
[email protected]867125a02009-12-10 06:01:482270}
2271
2272void Browser::SetBlockCommandExecution(bool block) {
2273 block_command_execution_ = block;
2274 if (block) {
2275 last_blocked_command_id_ = -1;
2276 last_blocked_command_disposition_ = CURRENT_TAB;
2277 }
2278}
2279
2280int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) {
2281 if (disposition)
2282 *disposition = last_blocked_command_disposition_;
2283 return last_blocked_command_id_;
2284}
2285
[email protected]3c9e1872010-11-18 16:17:492286void Browser::UpdateUIForNavigationInTab(TabContentsWrapper* contents,
[email protected]19d9f3a2010-10-14 21:49:362287 PageTransition::Type transition,
2288 bool user_initiated) {
2289 tabstrip_model()->TabNavigating(contents, transition);
2290
[email protected]3c9e1872010-11-18 16:17:492291 bool contents_is_selected = contents == GetSelectedTabContentsWrapper();
[email protected]19d9f3a2010-10-14 21:49:362292 if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
2293 // Forcibly reset the location bar if the url is going to change in the
2294 // current tab, since otherwise it won't discard any ongoing user edits,
2295 // since it doesn't realize this is a user-initiated action.
2296 window()->GetLocationBar()->Revert();
2297 }
2298
2299 if (GetStatusBubble())
2300 GetStatusBubble()->Hide();
2301
2302 // Update the location bar. This is synchronous. We specifically don't
2303 // update the load state since the load hasn't started yet and updating it
2304 // will put it out of sync with the actual state like whether we're
2305 // displaying a favicon, which controls the throbber. If we updated it here,
2306 // the throbber will show the default favicon for a split second when
2307 // navigating away from the new tab page.
[email protected]3c9e1872010-11-18 16:17:492308 ScheduleUIUpdate(contents->tab_contents(), TabContents::INVALIDATE_URL);
[email protected]19d9f3a2010-10-14 21:49:362309
2310 if (contents_is_selected)
[email protected]3c9e1872010-11-18 16:17:492311 contents->tab_contents()->Focus();
[email protected]19d9f3a2010-10-14 21:49:362312}
2313
2314GURL Browser::GetHomePage() const {
2315 // --homepage overrides any preferences.
2316 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2317 if (command_line.HasSwitch(switches::kHomePage)) {
[email protected]a8e4b5a82010-10-27 00:05:472318 // TODO(evanm): clean up usage of DIR_CURRENT.
2319 // http://code.google.com/p/chromium/issues/detail?id=60630
2320 // For now, allow this code to call getcwd().
2321 base::ThreadRestrictions::ScopedAllowIO allow_io;
2322
[email protected]19d9f3a2010-10-14 21:49:362323 FilePath browser_directory;
2324 PathService::Get(base::DIR_CURRENT, &browser_directory);
2325 GURL home_page(URLFixerUpper::FixupRelativeFile(browser_directory,
2326 command_line.GetSwitchValuePath(switches::kHomePage)));
2327 if (home_page.is_valid())
2328 return home_page;
2329 }
2330
2331 if (profile_->GetPrefs()->GetBoolean(prefs::kHomePageIsNewTabPage))
2332 return GURL(chrome::kChromeUINewTabURL);
2333 GURL home_page(URLFixerUpper::FixupURL(
2334 profile_->GetPrefs()->GetString(prefs::kHomePage),
2335 std::string()));
2336 if (!home_page.is_valid())
2337 return GURL(chrome::kChromeUINewTabURL);
2338 return home_page;
2339}
2340
[email protected]36b6dcb2008-11-12 01:19:572341///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:402342// Browser, PageNavigator implementation:
[email protected]19d9f3a2010-10-14 21:49:362343
[email protected]ecc523f62010-09-28 22:45:402344void Browser::OpenURL(const GURL& url, const GURL& referrer,
2345 WindowOpenDisposition disposition,
2346 PageTransition::Type transition) {
2347 OpenURLFromTab(NULL, url, referrer, disposition, transition);
2348}
2349
2350///////////////////////////////////////////////////////////////////////////////
[email protected]485fba42009-03-24 23:27:292351// Browser, CommandUpdater::CommandUpdaterDelegate implementation:
2352
2353void Browser::ExecuteCommand(int id) {
2354 ExecuteCommandWithDisposition(id, CURRENT_TAB);
2355}
2356
2357///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:402358// Browser, TabHandlerDelegate implementation:
2359
2360Profile* Browser::GetProfile() const {
2361 return profile();
2362}
2363
2364Browser* Browser::AsBrowser() {
2365 return this;
2366}
2367
2368///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572369// Browser, TabStripModelDelegate implementation:
2370
[email protected]3c9e1872010-11-18 16:17:492371TabContentsWrapper* Browser::AddBlankTab(bool foreground) {
[email protected]22735af62009-04-07 21:09:582372 return AddBlankTabAt(-1, foreground);
2373}
2374
[email protected]3c9e1872010-11-18 16:17:492375TabContentsWrapper* Browser::AddBlankTabAt(int index, bool foreground) {
[email protected]3f8eb7f2009-10-02 23:58:052376 // Time new tab page creation time. We keep track of the timing data in
2377 // TabContents, but we want to include the time it takes to create the
2378 // TabContents object too.
2379 base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
[email protected]616381f02010-11-02 15:15:332380 browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL),
2381 PageTransition::TYPED);
[email protected]616381f02010-11-02 15:15:332382 params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
2383 params.tabstrip_index = index;
2384 browser::Navigate(&params);
[email protected]3c9e1872010-11-18 16:17:492385 params.target_contents->tab_contents()->set_new_tab_start_time(
2386 new_tab_start_time);
[email protected]616381f02010-11-02 15:15:332387 return params.target_contents;
[email protected]15952e462008-11-14 00:29:052388}
2389
[email protected]3c9e1872010-11-18 16:17:492390Browser* Browser::CreateNewStripWithContents(
2391 TabContentsWrapper* detached_contents,
2392 const gfx::Rect& window_bounds,
2393 const DockInfo& dock_info,
2394 bool maximize) {
[email protected]018cf362010-05-05 22:43:222395 DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP));
[email protected]adf650f2008-12-09 16:10:062396
[email protected]5e495462008-11-20 23:07:412397 gfx::Rect new_window_bounds = window_bounds;
[email protected]5e495462008-11-20 23:07:412398 if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize))
2399 dock_info.AdjustOtherWindowBounds();
2400
[email protected]36b6dcb2008-11-12 01:19:572401 // Create an empty new browser window the same size as the old one.
[email protected]299dabd2008-11-19 02:27:162402 Browser* browser = new Browser(TYPE_NORMAL, profile_);
[email protected]5e495462008-11-20 23:07:412403 browser->set_override_bounds(new_window_bounds);
[email protected]2e716622009-03-09 21:11:012404 browser->set_maximized_state(
2405 maximize ? MAXIMIZED_STATE_MAXIMIZED : MAXIMIZED_STATE_UNMAXIMIZED);
[email protected]15952e462008-11-14 00:29:052406 browser->CreateBrowserWindow();
2407 browser->tabstrip_model()->AppendTabContents(detached_contents, true);
[email protected]159f7762008-12-19 14:58:272408 // Make sure the loading state is updated correctly, otherwise the throbber
2409 // won't start if the page is loading.
[email protected]3c9e1872010-11-18 16:17:492410 browser->LoadingStateChanged(detached_contents->tab_contents());
[email protected]3d1104f2009-03-26 15:30:282411 return browser;
[email protected]36b6dcb2008-11-12 01:19:572412}
2413
2414int Browser::GetDragActions() const {
[email protected]ecc523f62010-09-28 22:45:402415 return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
2416 TabStripModelDelegate::TAB_MOVE_ACTION : 0);
[email protected]36b6dcb2008-11-12 01:19:572417}
2418
[email protected]3c9e1872010-11-18 16:17:492419TabContentsWrapper* Browser::CreateTabContentsForURL(
[email protected]36b6dcb2008-11-12 01:19:572420 const GURL& url, const GURL& referrer, Profile* profile,
2421 PageTransition::Type transition, bool defer_load,
2422 SiteInstance* instance) const {
[email protected]3c9e1872010-11-18 16:17:492423 TabContentsWrapper* contents = TabContentsFactory(profile, instance,
[email protected]ecc523f62010-09-28 22:45:402424 MSG_ROUTING_NONE,
[email protected]3c9e1872010-11-18 16:17:492425 GetSelectedTabContents(), NULL);
[email protected]36b6dcb2008-11-12 01:19:572426 if (!defer_load) {
2427 // Load the initial URL before adding the new tab contents to the tab strip
2428 // so that the tab contents has navigation state.
[email protected]ce3fa3c2009-04-20 19:55:572429 contents->controller().LoadURL(url, referrer, transition);
[email protected]36b6dcb2008-11-12 01:19:572430 }
2431
2432 return contents;
2433}
2434
2435bool Browser::CanDuplicateContentsAt(int index) {
[email protected]ce3fa3c2009-04-20 19:55:572436 NavigationController& nc = GetTabContentsAt(index)->controller();
2437 return nc.tab_contents() && nc.GetLastCommittedEntry();
[email protected]36b6dcb2008-11-12 01:19:572438}
2439
2440void Browser::DuplicateContentsAt(int index) {
[email protected]3c9e1872010-11-18 16:17:492441 TabContentsWrapper* contents = GetTabContentsWrapperAt(index);
[email protected]36b6dcb2008-11-12 01:19:572442 TabContents* new_contents = NULL;
2443 DCHECK(contents);
[email protected]5c0e6482009-07-14 20:20:092444 bool pinned = false;
[email protected]36b6dcb2008-11-12 01:19:572445
[email protected]018cf362010-05-05 22:43:222446 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
[email protected]36b6dcb2008-11-12 01:19:572447 // If this is a tabbed browser, just create a duplicate tab inside the same
2448 // window next to the tab being duplicated.
[email protected]3c9e1872010-11-18 16:17:492449 TabContentsWrapper* wrapper = contents->Clone();
2450 new_contents = wrapper->tab_contents();
[email protected]ecc523f62010-09-28 22:45:402451 pinned = tab_handler_->GetTabStripModel()->IsTabPinned(index);
[email protected]4a1665442010-06-28 16:09:392452 int add_types = TabStripModel::ADD_SELECTED |
2453 TabStripModel::ADD_INHERIT_GROUP |
2454 (pinned ? TabStripModel::ADD_PINNED : 0);
[email protected]ecc523f62010-09-28 22:45:402455 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
[email protected]3c9e1872010-11-18 16:17:492456 wrapper,
[email protected]ecc523f62010-09-28 22:45:402457 add_types);
[email protected]36b6dcb2008-11-12 01:19:572458 } else {
[email protected]15952e462008-11-14 00:29:052459 Browser* browser = NULL;
[email protected]d5fbc002009-02-27 22:12:582460 if (type_ & TYPE_APP) {
[email protected]7e7a62b42010-01-26 22:50:402461 DCHECK((type_ & TYPE_POPUP) == 0);
[email protected]f2989012010-02-04 16:08:292462 DCHECK(type_ != TYPE_APP_PANEL);
[email protected]f075fe0a22010-04-26 04:06:432463 browser = Browser::CreateForApp(app_name_, extension_app_, profile_,
2464 false);
[email protected]299dabd2008-11-19 02:27:162465 } else if (type_ == TYPE_POPUP) {
[email protected]1b74d2122010-10-06 16:49:162466 browser = Browser::CreateForType(TYPE_POPUP, profile_);
[email protected]15952e462008-11-14 00:29:052467 }
[email protected]36b6dcb2008-11-12 01:19:572468
[email protected]b1fed962008-12-18 00:54:082469 // Preserve the size of the original window. The new window has already
2470 // been given an offset by the OS, so we shouldn't copy the old bounds.
2471 BrowserWindow* new_window = browser->window();
[email protected]dae12ee62009-07-29 20:02:052472 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
[email protected]e561e202010-03-24 17:57:122473 window()->GetRestoredBounds().size()));
[email protected]b1fed962008-12-18 00:54:082474
[email protected]36b6dcb2008-11-12 01:19:572475 // We need to show the browser now. Otherwise ContainerWin assumes the
2476 // TabContents is invisible and won't size it.
[email protected]15952e462008-11-14 00:29:052477 browser->window()->Show();
[email protected]36b6dcb2008-11-12 01:19:572478
2479 // The page transition below is only for the purpose of inserting the tab.
[email protected]3c9e1872010-11-18 16:17:492480 new_contents = browser->AddTab(contents->Clone(), PageTransition::LINK);
[email protected]36b6dcb2008-11-12 01:19:572481 }
2482
2483 if (profile_->HasSessionService()) {
2484 SessionService* session_service = profile_->GetSessionService();
2485 if (session_service)
[email protected]5c0e6482009-07-14 20:20:092486 session_service->TabRestored(&new_contents->controller(), pinned);
[email protected]36b6dcb2008-11-12 01:19:572487 }
2488}
2489
[email protected]36b6dcb2008-11-12 01:19:572490void Browser::CloseFrameAfterDragSession() {
[email protected]9aefecc92009-06-10 21:31:322491#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]36b6dcb2008-11-12 01:19:572492 // This is scheduled to run after we return to the message loop because
2493 // otherwise the frame will think the drag session is still active and ignore
2494 // the request.
[email protected]d6a3c772009-01-27 19:41:202495 // TODO(port): figure out what is required here in a cross-platform world
[email protected]0586b0e2010-02-12 21:38:372496 MessageLoop::current()->PostTask(
2497 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame));
[email protected]d6a3c772009-01-27 19:41:202498#endif
initial.commit09911bf2008-07-26 23:55:292499}
2500
[email protected]3c9e1872010-11-18 16:17:492501void Browser::CreateHistoricalTab(TabContentsWrapper* contents) {
[email protected]505323e22009-01-24 02:47:582502 // We don't create historical tabs for incognito windows or windows without
2503 // profiles.
2504 if (!profile() || profile()->IsOffTheRecord() ||
2505 !profile()->GetTabRestoreService()) {
2506 return;
2507 }
2508
[email protected]fb5ff422010-05-03 20:46:102509 // We only create historical tab entries for tabbed browser windows.
[email protected]018cf362010-05-05 22:43:222510 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
[email protected]505323e22009-01-24 02:47:582511 profile()->GetTabRestoreService()->CreateHistoricalTab(
[email protected]ce3fa3c2009-04-20 19:55:572512 &contents->controller());
[email protected]505323e22009-01-24 02:47:582513 }
2514}
2515
[email protected]3c9e1872010-11-18 16:17:492516bool Browser::RunUnloadListenerBeforeClosing(TabContentsWrapper* contents) {
2517 return Browser::RunUnloadEventsHelper(contents->tab_contents());
[email protected]505323e22009-01-24 02:47:582518}
2519
[email protected]8e48e982009-12-25 11:22:462520bool Browser::CanReloadContents(TabContents* source) const {
2521 return type() != TYPE_DEVTOOLS;
2522}
2523
[email protected]940ccb22009-04-30 17:11:102524bool Browser::CanCloseContentsAt(int index) {
[email protected]0b4d3382010-07-14 16:13:042525 if (!CanCloseTab())
2526 return false;
[email protected]ecc523f62010-09-28 22:45:402527 if (tab_handler_->GetTabStripModel()->count() > 1)
[email protected]940ccb22009-04-30 17:11:102528 return true;
2529 // We are closing the last tab for this browser. Make sure to check for
2530 // in-progress downloads.
2531 // Note that the next call when it returns false will ask the user for
2532 // confirmation before closing the browser if the user decides so.
2533 return CanCloseWithInProgressDownloads();
2534}
[email protected]d6a3c772009-01-27 19:41:202535
[email protected]a206b442009-10-08 23:20:202536bool Browser::CanBookmarkAllTabs() const {
2537 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]76624fde2009-10-09 18:13:232538 return (model && model->IsLoaded() && (tab_count() > 1));
[email protected]a206b442009-10-08 23:20:202539}
2540
[email protected]b3ac5c82009-10-08 20:56:542541void Browser::BookmarkAllTabs() {
[email protected]ec12ffe2009-10-16 22:28:442542 BookmarkModel* model = profile()->GetBookmarkModel();
2543 DCHECK(model && model->IsLoaded());
2544
2545 BookmarkEditor::EditDetails details;
2546 details.type = BookmarkEditor::EditDetails::NEW_FOLDER;
2547 bookmark_utils::GetURLsForOpenTabs(this, &(details.urls));
2548 DCHECK(!details.urls.empty());
[email protected]b3ac5c82009-10-08 20:56:542549
[email protected]b3ac5c82009-10-08 20:56:542550 BookmarkEditor::Show(window()->GetNativeHandle(), profile_,
[email protected]ec12ffe2009-10-16 22:28:442551 model->GetParentForNewNodes(), details,
[email protected]97a056462010-04-28 16:46:352552 BookmarkEditor::SHOW_TREE);
[email protected]b3ac5c82009-10-08 20:56:542553}
2554
[email protected]0b4d3382010-07-14 16:13:042555bool Browser::CanCloseTab() const {
2556 TabCloseableStateWatcher* watcher =
2557 g_browser_process->tab_closeable_state_watcher();
2558 return !watcher || watcher->CanCloseTab(this);
2559}
2560
[email protected]b9c505b2010-04-30 15:05:102561void Browser::ToggleUseVerticalTabs() {
2562 use_vertical_tabs_.SetValue(!UseVerticalTabs());
[email protected]b3344872010-05-03 15:52:292563 UseVerticalTabsChanged();
[email protected]b9c505b2010-04-30 15:05:102564}
2565
[email protected]b283a7532010-08-12 21:24:592566bool Browser::LargeIconsPermitted() const {
[email protected]af801acd2010-08-20 20:27:442567 // We don't show the big icons in tabs for TYPE_EXTENSION_APP windows because
2568 // for those windows, we already have a big icon in the top-left outside any
2569 // tab. Having big tab icons too looks kinda redonk.
2570 return TYPE_EXTENSION_APP != type();
[email protected]b283a7532010-08-12 21:24:592571}
2572
[email protected]2d46c842008-11-14 19:24:312573///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572574// Browser, TabStripModelObserver implementation:
2575
[email protected]3c9e1872010-11-18 16:17:492576void Browser::TabInsertedAt(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:572577 int index,
2578 bool foreground) {
[email protected]3c9e1872010-11-18 16:17:492579 contents->tab_contents()->set_delegate(this);
[email protected]ce3fa3c2009-04-20 19:55:572580 contents->controller().SetWindowID(session_id());
[email protected]36b6dcb2008-11-12 01:19:572581
[email protected]c37e3b62010-01-22 00:15:172582 SyncHistoryWithTabs(index);
[email protected]36b6dcb2008-11-12 01:19:572583
[email protected]159f7762008-12-19 14:58:272584 // Make sure the loading state is updated correctly, otherwise the throbber
2585 // won't start if the page is loading.
[email protected]3c9e1872010-11-18 16:17:492586 LoadingStateChanged(contents->tab_contents());
[email protected]159f7762008-12-19 14:58:272587
[email protected]36b6dcb2008-11-12 01:19:572588 // If the tab crashes in the beforeunload or unload handler, it won't be
2589 // able to ack. But we know we can close it.
[email protected]0cb94102009-05-22 19:51:212590 registrar_.Add(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
[email protected]3c9e1872010-11-18 16:17:492591 Source<TabContentsWrapper>(contents));
[email protected]36b6dcb2008-11-12 01:19:572592}
2593
[email protected]f2cc7382010-10-15 18:03:052594void Browser::TabClosingAt(TabStripModel* tab_strip_model,
[email protected]3c9e1872010-11-18 16:17:492595 TabContentsWrapper* contents,
[email protected]f2cc7382010-10-15 18:03:052596 int index) {
[email protected]bfd04a62009-02-01 18:16:562597 NotificationService::current()->Notify(
2598 NotificationType::TAB_CLOSING,
[email protected]ce3fa3c2009-04-20 19:55:572599 Source<NavigationController>(&contents->controller()),
[email protected]bfd04a62009-02-01 18:16:562600 NotificationService::NoDetails());
[email protected]36b6dcb2008-11-12 01:19:572601
2602 // Sever the TabContents' connection back to us.
[email protected]3c9e1872010-11-18 16:17:492603 contents->tab_contents()->set_delegate(NULL);
[email protected]36b6dcb2008-11-12 01:19:572604}
2605
[email protected]3c9e1872010-11-18 16:17:492606void Browser::TabDetachedAt(TabContentsWrapper* contents, int index) {
[email protected]c37e3b62010-01-22 00:15:172607 TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH);
[email protected]36b6dcb2008-11-12 01:19:572608}
2609
[email protected]3c9e1872010-11-18 16:17:492610void Browser::TabDeselectedAt(TabContentsWrapper* contents, int index) {
[email protected]6b723f82010-10-05 20:14:272611 if (instant())
2612 instant()->DestroyPreviewContents();
[email protected]03bb953d2010-09-14 21:38:302613
[email protected]85ff2c42009-05-29 21:22:032614 // Save what the user's currently typing, so it can be restored when we
2615 // switch back to this tab.
[email protected]3c9e1872010-11-18 16:17:492616 window_->GetLocationBar()->SaveStateToContents(contents->tab_contents());
[email protected]85ff2c42009-05-29 21:22:032617}
2618
[email protected]3c9e1872010-11-18 16:17:492619void Browser::TabSelectedAt(TabContentsWrapper* old_contents,
2620 TabContentsWrapper* new_contents,
[email protected]36b6dcb2008-11-12 01:19:572621 int index,
2622 bool user_gesture) {
2623 DCHECK(old_contents != new_contents);
2624
2625 // If we have any update pending, do it now.
2626 if (!chrome_updater_factory_.empty() && old_contents)
2627 ProcessPendingUIUpdates();
2628
[email protected]36b6dcb2008-11-12 01:19:572629 // Propagate the profile to the location bar.
2630 UpdateToolbar(true);
2631
[email protected]943d8122010-06-11 02:13:452632 // Update reload/stop state.
[email protected]3c9e1872010-11-18 16:17:492633 UpdateReloadStopState(new_contents->tab_contents()->is_loading(), true);
[email protected]36b6dcb2008-11-12 01:19:572634
[email protected]84214982008-12-10 18:49:102635 // Update commands to reflect current state.
2636 UpdateCommandsForTabState();
[email protected]36b6dcb2008-11-12 01:19:572637
2638 // Reset the status bubble.
[email protected]be3877f2009-01-14 15:51:102639 StatusBubble* status_bubble = GetStatusBubble();
2640 if (status_bubble) {
2641 status_bubble->Hide();
[email protected]36b6dcb2008-11-12 01:19:572642
[email protected]be3877f2009-01-14 15:51:102643 // Show the loading state (if any).
[email protected]43d259d2010-09-03 21:37:462644 status_bubble->SetStatus(WideToUTF16Hack(
2645 GetSelectedTabContents()->GetStatusText()));
[email protected]be3877f2009-01-14 15:51:102646 }
[email protected]36b6dcb2008-11-12 01:19:572647
[email protected]24db8a072009-10-29 20:35:372648 if (HasFindBarController()) {
[email protected]3c9e1872010-11-18 16:17:492649 find_bar_controller_->ChangeTabContents(new_contents->tab_contents());
[email protected]b77cb302009-10-29 04:09:172650 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
[email protected]4801ecc2009-04-05 04:52:582651 }
2652
[email protected]36b6dcb2008-11-12 01:19:572653 // Update sessions. Don't force creation of sessions. If sessions doesn't
2654 // exist, the change will be picked up by sessions when created.
2655 if (profile_->HasSessionService()) {
2656 SessionService* session_service = profile_->GetSessionService();
[email protected]ecc523f62010-09-28 22:45:402657 if (session_service && !tab_handler_->GetTabStripModel()->closing_all()) {
[email protected]2d46c842008-11-14 19:24:312658 session_service->SetSelectedTabInWindow(
[email protected]ecc523f62010-09-28 22:45:402659 session_id(), tab_handler_->GetTabStripModel()->selected_index());
[email protected]36b6dcb2008-11-12 01:19:572660 }
2661 }
2662}
2663
[email protected]3c9e1872010-11-18 16:17:492664void Browser::TabMoved(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:572665 int from_index,
[email protected]1a242c32010-02-02 21:20:542666 int to_index) {
[email protected]36b6dcb2008-11-12 01:19:572667 DCHECK(from_index >= 0 && to_index >= 0);
2668 // Notify the history service.
2669 SyncHistoryWithTabs(std::min(from_index, to_index));
2670}
2671
[email protected]3c9e1872010-11-18 16:17:492672void Browser::TabReplacedAt(TabContentsWrapper* old_contents,
2673 TabContentsWrapper* new_contents,
[email protected]8a34e6602010-10-02 17:29:432674 int index) {
[email protected]c37e3b62010-01-22 00:15:172675 TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
2676 TabInsertedAt(new_contents, index,
[email protected]ecc523f62010-09-28 22:45:402677 (index == tab_handler_->GetTabStripModel()->selected_index()));
[email protected]c37e3b62010-01-22 00:15:172678
2679 int entry_count = new_contents->controller().entry_count();
2680 if (entry_count > 0) {
2681 // Send out notification so that observers are updated appropriately.
2682 new_contents->controller().NotifyEntryChanged(
2683 new_contents->controller().GetEntryAtIndex(entry_count - 1),
2684 entry_count - 1);
2685 }
[email protected]47e020a2010-10-15 14:43:372686
2687 SessionService* session_service = profile()->GetSessionService();
2688 if (session_service) {
2689 // The new_contents may end up with a different navigation stack. Force
2690 // the session service to update itself.
2691 session_service->TabRestored(
2692 &new_contents->controller(),
2693 tab_handler_->GetTabStripModel()->IsTabPinned(index));
2694 }
[email protected]c37e3b62010-01-22 00:15:172695}
2696
[email protected]3c9e1872010-11-18 16:17:492697void Browser::TabPinnedStateChanged(TabContentsWrapper* contents, int index) {
[email protected]5c0e6482009-07-14 20:20:092698 if (!profile()->HasSessionService())
2699 return;
2700 SessionService* session_service = profile()->GetSessionService();
2701 if (session_service) {
2702 session_service->SetPinnedState(
2703 session_id(),
2704 GetTabContentsAt(index)->controller().session_id(),
[email protected]ecc523f62010-09-28 22:45:402705 tab_handler_->GetTabStripModel()->IsTabPinned(index));
[email protected]5c0e6482009-07-14 20:20:092706 }
2707}
2708
[email protected]36b6dcb2008-11-12 01:19:572709void Browser::TabStripEmpty() {
2710 // Close the frame after we return to the message loop (not immediately,
2711 // otherwise it will destroy this object before the stack has a chance to
2712 // cleanly unwind.)
2713 // Note: This will be called several times if TabStripEmpty is called several
2714 // times. This is because it does not close the window if tabs are
2715 // still present.
2716 // NOTE: If you change to be immediate (no invokeLater) then you'll need to
2717 // update BrowserList::CloseAllBrowsers.
[email protected]0586b0e2010-02-12 21:38:372718 MessageLoop::current()->PostTask(
2719 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame));
[email protected]36b6dcb2008-11-12 01:19:572720}
2721
2722///////////////////////////////////////////////////////////////////////////////
2723// Browser, TabContentsDelegate implementation:
initial.commit09911bf2008-07-26 23:55:292724
2725void Browser::OpenURLFromTab(TabContents* source,
[email protected]1f7d7e92009-06-02 20:55:042726 const GURL& url,
2727 const GURL& referrer,
initial.commit09911bf2008-07-26 23:55:292728 WindowOpenDisposition disposition,
[email protected]e38f40152008-09-12 23:08:302729 PageTransition::Type transition) {
[email protected]616381f02010-11-02 15:15:332730 browser::NavigateParams params(this, url, transition);
[email protected]3c9e1872010-11-18 16:17:492731 params.source_contents =
2732 tabstrip_model()->GetTabContentsAt(
2733 tabstrip_model()->GetWrapperIndex(source));
[email protected]616381f02010-11-02 15:15:332734 params.referrer = referrer;
2735 params.disposition = disposition;
2736 params.tabstrip_add_types = TabStripModel::ADD_NONE;
[email protected]caee0792010-11-19 21:19:362737 params.show_window = true;
[email protected]616381f02010-11-02 15:15:332738 browser::Navigate(&params);
initial.commit09911bf2008-07-26 23:55:292739}
2740
2741void Browser::NavigationStateChanged(const TabContents* source,
2742 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:292743 // Only update the UI when something visible has changed.
[email protected]e83f1682008-09-07 23:57:402744 if (changed_flags)
initial.commit09911bf2008-07-26 23:55:292745 ScheduleUIUpdate(source, changed_flags);
2746
[email protected]84214982008-12-10 18:49:102747 // We don't schedule updates to commands since they will only change once per
2748 // navigation, so we don't have to worry about flickering.
[email protected]e83f1682008-09-07 23:57:402749 if (changed_flags & TabContents::INVALIDATE_URL)
[email protected]84214982008-12-10 18:49:102750 UpdateCommandsForTabState();
initial.commit09911bf2008-07-26 23:55:292751}
2752
initial.commit09911bf2008-07-26 23:55:292753void Browser::AddNewContents(TabContents* source,
2754 TabContents* new_contents,
2755 WindowOpenDisposition disposition,
2756 const gfx::Rect& initial_pos,
2757 bool user_gesture) {
[email protected]616381f02010-11-02 15:15:332758 // No code for this yet
2759 DCHECK(disposition != SAVE_TO_DISK);
2760 // Can't create a new contents for the current tab - invalid case.
2761 DCHECK(disposition != CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:292762
[email protected]616381f02010-11-02 15:15:332763 // TODO(beng): This belongs behind the platform-specific View interface.
2764 // That's why it's there.
[email protected]57b839a2010-10-04 22:49:452765#if defined(OS_CHROMEOS)
[email protected]616381f02010-11-02 15:15:332766 if (disposition == NEW_POPUP) {
2767 // If the popup is bigger than a given factor of the screen, then
2768 // turn it into a foreground tab (on chrome os only)
2769 // Also check for width or height == 0, which would otherwise indicate
2770 // a tab sized popup window.
2771 GdkScreen* screen = gdk_screen_get_default();
2772 int max_width = gdk_screen_get_width(screen) * kPopupMaxWidthFactor;
2773 int max_height = gdk_screen_get_height(screen) * kPopupMaxHeightFactor;
2774 if (initial_pos.width() > max_width || initial_pos.width() == 0 ||
2775 initial_pos.height() > max_height || initial_pos.height() == 0) {
2776 disposition = NEW_FOREGROUND_TAB;
[email protected]57b839a2010-10-04 22:49:452777 }
[email protected]616381f02010-11-02 15:15:332778 }
[email protected]57b839a2010-10-04 22:49:452779#endif
2780
[email protected]3c9e1872010-11-18 16:17:492781 TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
2782 browser::NavigateParams params(this, wrapper);
2783 params.source_contents =
2784 tabstrip_model()->GetTabContentsAt(
2785 tabstrip_model()->GetWrapperIndex(source));
2786 params.disposition = disposition;
2787 params.window_bounds = initial_pos;
[email protected]caee0792010-11-19 21:19:362788 params.show_window = true;
[email protected]3c9e1872010-11-18 16:17:492789 browser::Navigate(&params);
initial.commit09911bf2008-07-26 23:55:292790}
2791
initial.commit09911bf2008-07-26 23:55:292792void Browser::ActivateContents(TabContents* contents) {
[email protected]ecc523f62010-09-28 22:45:402793 tab_handler_->GetTabStripModel()->SelectTabContentsAt(
[email protected]3c9e1872010-11-18 16:17:492794 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents), false);
[email protected]f3e99e32008-07-30 04:48:392795 window_->Activate();
initial.commit09911bf2008-07-26 23:55:292796}
2797
[email protected]ea42e7782010-08-23 23:58:122798void Browser::DeactivateContents(TabContents* contents) {
2799 window_->Deactivate();
2800}
2801
initial.commit09911bf2008-07-26 23:55:292802void Browser::LoadingStateChanged(TabContents* source) {
[email protected]ecc523f62010-09-28 22:45:402803 window_->UpdateLoadingAnimations(
2804 tab_handler_->GetTabStripModel()->TabsAreLoading());
[email protected]f3e99e32008-07-30 04:48:392805 window_->UpdateTitleBar();
initial.commit09911bf2008-07-26 23:55:292806
[email protected]3c9e1872010-11-18 16:17:492807 TabContents* selected_contents = GetSelectedTabContents();
2808 if (source == selected_contents) {
[email protected]943d8122010-06-11 02:13:452809 UpdateReloadStopState(source->is_loading(), false);
[email protected]43d259d2010-09-03 21:37:462810 if (GetStatusBubble()) {
2811 GetStatusBubble()->SetStatus(WideToUTF16(
2812 GetSelectedTabContents()->GetStatusText()));
2813 }
[email protected]eabfdae92009-12-11 06:13:512814
2815 if (!source->is_loading() &&
2816 pending_web_app_action_ == UPDATE_SHORTCUT) {
[email protected]867dff82010-04-23 21:30:332817 // Schedule a shortcut update when web application info is available if
2818 // last committed entry is not NULL. Last committed entry could be NULL
2819 // when an interstitial page is injected (e.g. bad https certificate,
2820 // malware site etc). When this happens, we abort the shortcut update.
[email protected]eabfdae92009-12-11 06:13:512821 NavigationEntry* entry = source->controller().GetLastCommittedEntry();
2822 if (entry) {
2823 source->render_view_host()->GetApplicationInfo(entry->page_id());
2824 } else {
2825 pending_web_app_action_ = NONE;
[email protected]eabfdae92009-12-11 06:13:512826 }
2827 }
initial.commit09911bf2008-07-26 23:55:292828 }
2829}
2830
2831void Browser::CloseContents(TabContents* source) {
[email protected]04b4a6c2008-08-02 00:44:472832 if (is_attempting_to_close_browser_) {
2833 // If we're trying to close the browser, just clear the state related to
[email protected]adf650f2008-12-09 16:10:062834 // waiting for unload to fire. Don't actually try to close the tab as it
[email protected]04b4a6c2008-08-02 00:44:472835 // will go down the slow shutdown path instead of the fast path of killing
2836 // all the renderer processes.
[email protected]8a2ce5a2008-08-11 23:43:082837 ClearUnloadState(source);
[email protected]04b4a6c2008-08-02 00:44:472838 return;
2839 }
2840
[email protected]3c9e1872010-11-18 16:17:492841 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
initial.commit09911bf2008-07-26 23:55:292842 if (index == TabStripModel::kNoTab) {
2843 NOTREACHED() << "CloseContents called for tab not in our strip";
2844 return;
2845 }
[email protected]ecc523f62010-09-28 22:45:402846 tab_handler_->GetTabStripModel()->CloseTabContentsAt(
[email protected]0cce15f2010-05-21 16:58:392847 index,
2848 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
initial.commit09911bf2008-07-26 23:55:292849}
2850
[email protected]15e8abe2008-08-20 22:40:402851void Browser::MoveContents(TabContents* source, const gfx::Rect& pos) {
[email protected]d5fbc002009-02-27 22:12:582852 if ((type() & TYPE_POPUP) == 0) {
initial.commit09911bf2008-07-26 23:55:292853 NOTREACHED() << "moving invalid browser type";
2854 return;
2855 }
[email protected]e561e202010-03-24 17:57:122856 window_->SetBounds(pos);
initial.commit09911bf2008-07-26 23:55:292857}
2858
[email protected]b6c874582009-05-08 19:38:312859void Browser::DetachContents(TabContents* source) {
[email protected]3c9e1872010-11-18 16:17:492860 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
[email protected]b6c874582009-05-08 19:38:312861 if (index >= 0)
[email protected]ecc523f62010-09-28 22:45:402862 tab_handler_->GetTabStripModel()->DetachTabContentsAt(index);
[email protected]b6c874582009-05-08 19:38:312863}
2864
[email protected]be04582b2010-07-26 21:56:562865bool Browser::IsPopup(const TabContents* source) const {
initial.commit09911bf2008-07-26 23:55:292866 // A non-tabbed BROWSER is an unconstrained popup.
[email protected]d6df2e32009-10-31 04:39:452867 return !!(type() & TYPE_POPUP);
initial.commit09911bf2008-07-26 23:55:292868}
2869
[email protected]36b6dcb2008-11-12 01:19:572870void Browser::ToolbarSizeChanged(TabContents* source, bool is_animating) {
2871 if (source == GetSelectedTabContents() || source == NULL) {
2872 // This will refresh the shelf if needed.
2873 window_->SelectedTabToolbarSizeChanged(is_animating);
2874 }
2875}
2876
2877void Browser::URLStarredChanged(TabContents* source, bool starred) {
2878 if (source == GetSelectedTabContents())
[email protected]b7ca4e62009-01-23 20:37:292879 window_->SetStarredState(starred);
[email protected]36b6dcb2008-11-12 01:19:572880}
2881
[email protected]b8595e92009-11-14 01:18:002882void Browser::ContentsMouseEvent(
2883 TabContents* source, const gfx::Point& location, bool motion) {
[email protected]be3877f2009-01-14 15:51:102884 if (!GetStatusBubble())
2885 return;
2886
[email protected]36b6dcb2008-11-12 01:19:572887 if (source == GetSelectedTabContents()) {
[email protected]b8595e92009-11-14 01:18:002888 GetStatusBubble()->MouseMoved(location, !motion);
2889 if (!motion)
[email protected]43d259d2010-09-03 21:37:462890 GetStatusBubble()->SetURL(GURL(), string16());
[email protected]36b6dcb2008-11-12 01:19:572891 }
2892}
2893
2894void Browser::UpdateTargetURL(TabContents* source, const GURL& url) {
[email protected]be3877f2009-01-14 15:51:102895 if (!GetStatusBubble())
2896 return;
2897
[email protected]36b6dcb2008-11-12 01:19:572898 if (source == GetSelectedTabContents()) {
2899 PrefService* prefs = profile_->GetPrefs();
[email protected]ddd231e2010-06-29 20:35:192900 GetStatusBubble()->SetURL(
[email protected]43d259d2010-09-03 21:37:462901 url, UTF8ToUTF16(prefs->GetString(prefs::kAcceptLanguages)));
[email protected]36b6dcb2008-11-12 01:19:572902 }
2903}
2904
[email protected]3a6a3b62009-05-27 21:36:202905void Browser::UpdateDownloadShelfVisibility(bool visible) {
[email protected]9b032bf2009-07-21 17:34:232906 if (GetStatusBubble())
2907 GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
[email protected]3a6a3b62009-05-27 21:36:202908}
2909
[email protected]aa02fff12010-07-21 19:55:252910bool Browser::UseVerticalTabs() const {
2911 return use_vertical_tabs_.GetValue();
2912}
2913
[email protected]36b6dcb2008-11-12 01:19:572914void Browser::ContentsZoomChange(bool zoom_in) {
[email protected]b75b8292010-10-01 07:28:252915 ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
[email protected]36b6dcb2008-11-12 01:19:572916}
2917
[email protected]20ad6a92010-04-21 14:07:242918void Browser::OnContentSettingsChange(TabContents* source) {
[email protected]8cc8d492010-02-02 10:40:492919 if (source == GetSelectedTabContents())
[email protected]352104e2010-03-05 11:40:082920 window_->GetLocationBar()->UpdateContentSettingsIcons();
[email protected]8cc8d492010-02-02 10:40:492921}
2922
[email protected]fa1cf0b82010-01-15 21:49:442923void Browser::SetTabContentBlocked(TabContents* contents, bool blocked) {
[email protected]3c9e1872010-11-18 16:17:492924 int index = tabstrip_model()->GetWrapperIndex(contents);
[email protected]fa1cf0b82010-01-15 21:49:442925 if (index == TabStripModel::kNoTab) {
2926 NOTREACHED();
2927 return;
2928 }
2929 tabstrip_model()->SetTabBlocked(index, blocked);
2930}
2931
[email protected]7e383692009-06-12 19:14:542932void Browser::TabContentsFocused(TabContents* tab_content) {
2933 window_->TabContentsFocused(tab_content);
2934}
2935
[email protected]130efb02009-09-18 18:54:352936bool Browser::TakeFocus(bool reverse) {
2937 NotificationService::current()->Notify(
2938 NotificationType::FOCUS_RETURNED_TO_BROWSER,
2939 Source<Browser>(this),
2940 NotificationService::NoDetails());
2941 return false;
2942}
2943
[email protected]36b6dcb2008-11-12 01:19:572944bool Browser::IsApplication() const {
[email protected]d5fbc002009-02-27 22:12:582945 return (type_ & TYPE_APP) != 0;
[email protected]36b6dcb2008-11-12 01:19:572946}
2947
2948void Browser::ConvertContentsToApplication(TabContents* contents) {
[email protected]ce3fa3c2009-04-20 19:55:572949 const GURL& url = contents->controller().GetActiveEntry()->url();
[email protected]57ecc4b2010-08-11 03:02:512950 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
[email protected]36b6dcb2008-11-12 01:19:572951 RegisterAppPrefs(app_name);
2952
[email protected]b6c874582009-05-08 19:38:312953 DetachContents(contents);
[email protected]f075fe0a22010-04-26 04:06:432954 Browser* browser = Browser::CreateForApp(app_name, NULL, profile_, false);
[email protected]3c9e1872010-11-18 16:17:492955 TabContentsWrapper* wrapper = new TabContentsWrapper(contents);
2956 browser->tabstrip_model()->AppendTabContents(wrapper, true);
2957 TabContents* tab_contents = GetSelectedTabContents();
[email protected]840b1512009-07-21 16:53:462958 tab_contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
2959 tab_contents->render_view_host()->SyncRendererPrefs();
[email protected]15952e462008-11-14 00:29:052960 browser->window()->Show();
[email protected]36b6dcb2008-11-12 01:19:572961}
2962
[email protected]36b6dcb2008-11-12 01:19:572963bool Browser::ShouldDisplayURLField() {
2964 return !IsApplication();
2965}
2966
2967void Browser::BeforeUnloadFired(TabContents* tab,
2968 bool proceed,
2969 bool* proceed_to_fire_unload) {
2970 if (!is_attempting_to_close_browser_) {
2971 *proceed_to_fire_unload = proceed;
[email protected]0cce15f2010-05-21 16:58:392972 if (!proceed)
2973 tab->set_closed_by_user_gesture(false);
[email protected]36b6dcb2008-11-12 01:19:572974 return;
2975 }
2976
2977 if (!proceed) {
2978 CancelWindowClose();
2979 *proceed_to_fire_unload = false;
[email protected]0cce15f2010-05-21 16:58:392980 tab->set_closed_by_user_gesture(false);
[email protected]36b6dcb2008-11-12 01:19:572981 return;
2982 }
2983
[email protected]06b42f032008-12-03 18:43:052984 if (RemoveFromSet(&tabs_needing_before_unload_fired_, tab)) {
[email protected]2d46c842008-11-14 19:24:312985 // Now that beforeunload has fired, put the tab on the queue to fire
2986 // unload.
[email protected]06b42f032008-12-03 18:43:052987 tabs_needing_unload_fired_.insert(tab);
[email protected]36b6dcb2008-11-12 01:19:572988 ProcessPendingTabs();
[email protected]adf650f2008-12-09 16:10:062989 // We want to handle firing the unload event ourselves since we want to
[email protected]36b6dcb2008-11-12 01:19:572990 // fire all the beforeunload events before attempting to fire the unload
2991 // events should the user cancel closing the browser.
2992 *proceed_to_fire_unload = false;
2993 return;
2994 }
2995
2996 *proceed_to_fire_unload = true;
2997}
2998
[email protected]4acc19a62009-04-03 03:05:112999void Browser::ShowHtmlDialog(HtmlDialogUIDelegate* delegate,
[email protected]322f3ff2009-05-22 16:19:543000 gfx::NativeWindow parent_window) {
[email protected]2d46c842008-11-14 19:24:313001 window_->ShowHTMLDialog(delegate, parent_window);
initial.commit09911bf2008-07-26 23:55:293002}
3003
[email protected]a26dc362010-04-23 01:48:583004void Browser::SetFocusToLocationBar(bool select_all) {
[email protected]1a380622009-02-17 17:33:133005 // Two differences between this and FocusLocationBar():
3006 // (1) This doesn't get recorded in user metrics, since it's called
3007 // internally.
3008 // (2) This checks whether the location bar can be focused, and if not, clears
3009 // the focus. FocusLocationBar() is only reached when the location bar is
3010 // focusable, but this may be reached at other times, e.g. while in
3011 // fullscreen mode, where we need to leave focus in a consistent state.
[email protected]a26dc362010-04-23 01:48:583012 window_->SetFocusToLocationBar(select_all);
[email protected]4bcefee2009-01-29 15:57:573013}
3014
[email protected]7d5925a2009-03-03 02:59:123015void Browser::RenderWidgetShowing() {
3016 window_->DisableInactiveFrame();
3017}
[email protected]a239c3f2009-02-17 22:13:193018
[email protected]0a2aeb82009-05-15 21:52:483019int Browser::GetExtraRenderViewHeight() const {
3020 return window_->GetExtraRenderViewHeight();
3021}
3022
[email protected]5b928b62010-08-03 11:46:513023void Browser::OnStartDownload(DownloadItem* download, TabContents* tab) {
[email protected]d0cc9fb52009-06-23 02:26:163024 if (!window())
3025 return;
3026
[email protected]f5bf8ccf2010-02-05 18:19:253027#if defined(OS_CHROMEOS)
[email protected]52c45d62010-06-17 16:26:563028 // Don't show content browser for extension/theme downloads from gallery.
[email protected]d3071992010-10-08 15:24:073029 if (download->is_extension_install()) {
3030 ExtensionsService* service = profile_->GetExtensionsService();
3031 if (service && service->IsDownloadFromGallery(download->url(),
3032 download->referrer_url())) {
3033 return;
3034 }
3035 }
[email protected]52c45d62010-06-17 16:26:563036
[email protected]f5bf8ccf2010-02-05 18:19:253037 // skip the download shelf and just open the file browser in chromeos
3038 std::string arg = download->full_path().DirName().value();
[email protected]467293292010-04-16 19:41:563039 FileBrowseUI::OpenPopup(profile_,
3040 arg,
3041 FileBrowseUI::kPopupWidth,
3042 FileBrowseUI::kPopupHeight);
[email protected]f5bf8ccf2010-02-05 18:19:253043
3044#else
[email protected]d0cc9fb52009-06-23 02:26:163045 // GetDownloadShelf creates the download shelf if it was not yet created.
3046 window()->GetDownloadShelf()->AddDownload(new DownloadItemModel(download));
3047
[email protected]d0cc9fb52009-06-23 02:26:163048 // Don't show the animation for "Save file" downloads.
[email protected]e00778c2009-12-18 02:17:243049 if (download->total_bytes() <= 0)
3050 return;
[email protected]8e48e982009-12-25 11:22:463051
[email protected]e00778c2009-12-18 02:17:243052 // For non-theme extensions, we don't show the download animation.
[email protected]a60c8ae2009-12-25 06:50:573053 if (download->is_extension_install() &&
[email protected]e00778c2009-12-18 02:17:243054 !ExtensionsService::IsDownloadFromMiniGallery(download->url()))
3055 return;
3056
3057 TabContents* current_tab = GetSelectedTabContents();
3058 // We make this check for the case of minimized windows, unit tests, etc.
3059 if (platform_util::IsVisible(current_tab->GetNativeView()) &&
[email protected]f5bf8ccf2010-02-05 18:19:253060 Animation::ShouldRenderRichAnimation()) {
[email protected]e00778c2009-12-18 02:17:243061 DownloadStartedAnimation::Show(current_tab);
[email protected]f5bf8ccf2010-02-05 18:19:253062 }
3063#endif
[email protected]5b928b62010-08-03 11:46:513064
3065 // If the download occurs in a new tab, close it
3066 if (tab->controller().IsInitialNavigation() &&
3067 GetConstrainingContents(tab) == tab && tab_count() > 1) {
3068 CloseContents(tab);
3069 }
[email protected]d0cc9fb52009-06-23 02:26:163070}
3071
[email protected]965c7662010-10-11 22:38:523072void Browser::ConfirmSetDefaultSearchProvider(
3073 TabContents* tab_contents,
3074 TemplateURL* template_url,
3075 TemplateURLModel* template_url_model) {
3076 window()->ConfirmSetDefaultSearchProvider(tab_contents, template_url,
3077 template_url_model);
3078}
[email protected]d0cc9fb52009-06-23 02:26:163079void Browser::ConfirmAddSearchProvider(const TemplateURL* template_url,
3080 Profile* profile) {
3081 window()->ConfirmAddSearchProvider(template_url, profile);
3082}
3083
[email protected]bb678332009-07-21 00:15:503084void Browser::ShowPageInfo(Profile* profile,
[email protected]4d677202009-07-19 07:37:123085 const GURL& url,
3086 const NavigationEntry::SSLStatus& ssl,
3087 bool show_history) {
[email protected]bb678332009-07-21 00:15:503088 window()->ShowPageInfo(profile, url, ssl, show_history);
[email protected]4d677202009-07-19 07:37:123089}
3090
[email protected]867125a02009-12-10 06:01:483091bool Browser::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
3092 bool* is_keyboard_shortcut) {
3093 return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
3094}
[email protected]97df4b332009-10-02 01:25:413095
[email protected]867125a02009-12-10 06:01:483096void Browser::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
3097 window()->HandleKeyboardEvent(event);
[email protected]97df4b332009-10-02 01:25:413098}
3099
[email protected]14f3408a2009-08-31 20:53:533100void Browser::ShowRepostFormWarningDialog(TabContents *tab_contents) {
3101 window()->ShowRepostFormWarningDialog(tab_contents);
3102}
3103
[email protected]63543142010-02-09 23:22:203104void Browser::ShowContentSettingsWindow(ContentSettingsType content_type) {
[email protected]12e816bde2010-09-14 19:59:293105 if (CommandLine::ForCurrentProcess()->HasSwitch(
3106 switches::kEnableTabbedOptions)) {
3107 ShowOptionsTab(
[email protected]91a79232010-11-10 18:15:083108 chrome::kContentSettingsSubPage + std::string(kHashMark) +
[email protected]12e816bde2010-09-14 19:59:293109 ContentSettingsHandler::ContentSettingsTypeToGroupName(content_type));
3110 } else {
3111 window()->ShowContentSettingsWindow(content_type,
3112 profile_->GetOriginalProfile());
3113 }
[email protected]63543142010-02-09 23:22:203114}
3115
[email protected]a503c97c2010-07-16 13:05:483116void Browser::ShowCollectedCookiesDialog(TabContents *tab_contents) {
3117 window()->ShowCollectedCookiesDialog(tab_contents);
3118}
3119
[email protected]ec0b6c42010-08-26 03:16:583120bool Browser::ShouldAddNavigationToHistory(
3121 const history::HistoryAddPageArgs& add_page_args,
3122 NavigationType::Type navigation_type) {
[email protected]2e29d922009-10-22 22:13:353123 // Don't update history if running as app.
3124 return !IsApplication();
3125}
3126
[email protected]ed5431872009-11-17 08:39:513127void Browser::OnDidGetApplicationInfo(TabContents* tab_contents,
3128 int32 page_id) {
3129 TabContents* current_tab = GetSelectedTabContents();
3130 if (current_tab != tab_contents)
3131 return;
3132
3133 NavigationEntry* entry = current_tab->controller().GetLastCommittedEntry();
3134 if (!entry || (entry->page_id() != page_id))
3135 return;
3136
[email protected]eabfdae92009-12-11 06:13:513137 switch (pending_web_app_action_) {
3138 case CREATE_SHORTCUT: {
[email protected]a3b734b2010-11-30 03:17:113139 window()->ShowCreateWebAppShortcutsDialog(current_tab);
[email protected]eabfdae92009-12-11 06:13:513140 break;
3141 }
3142 case UPDATE_SHORTCUT: {
3143 web_app::UpdateShortcutForTabContents(current_tab);
3144 break;
3145 }
3146 default:
3147 NOTREACHED();
3148 break;
3149 }
3150
3151 pending_web_app_action_ = NONE;
[email protected]ed5431872009-11-17 08:39:513152}
3153
[email protected]bb461532010-11-26 21:50:233154void Browser::OnInstallApplication(TabContents* source,
3155 const WebApplicationInfo& web_app) {
3156 ExtensionsService* extensions_service = profile()->GetExtensionsService();
3157 if (!extensions_service)
3158 return;
3159
3160 scoped_refptr<CrxInstaller> installer(
3161 new CrxInstaller(extensions_service,
3162 extensions_service->show_extensions_prompts() ?
3163 new ExtensionInstallUI(profile()) : NULL));
3164 installer->InstallWebApp(web_app);
3165}
3166
[email protected]9e823662010-10-13 23:36:003167void Browser::ContentRestrictionsChanged(TabContents* source) {
3168 UpdateCommandsForContentRestrictionState();
3169}
3170
[email protected]36b6dcb2008-11-12 01:19:573171///////////////////////////////////////////////////////////////////////////////
3172// Browser, SelectFileDialog::Listener implementation:
3173
[email protected]561abe62009-04-06 18:08:343174void Browser::FileSelected(const FilePath& path, int index, void* params) {
[email protected]35896a32010-06-09 08:42:513175 profile_->set_last_selected_directory(path.DirName());
[email protected]72cbd322009-04-07 10:17:123176 GURL file_url = net::FilePathToFileURL(path);
[email protected]36b6dcb2008-11-12 01:19:573177 if (!file_url.is_empty())
3178 OpenURL(file_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
3179}
3180
3181///////////////////////////////////////////////////////////////////////////////
3182// Browser, NotificationObserver implementation:
3183
initial.commit09911bf2008-07-26 23:55:293184void Browser::Observe(NotificationType type,
3185 const NotificationSource& source,
3186 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:563187 switch (type.value) {
[email protected]57c6a652009-05-04 07:58:343188 case NotificationType::TAB_CONTENTS_DISCONNECTED:
[email protected]e83f1682008-09-07 23:57:403189 if (is_attempting_to_close_browser_) {
3190 // Need to do this asynchronously as it will close the tab, which is
3191 // currently on the call stack above us.
[email protected]0586b0e2010-02-12 21:38:373192 MessageLoop::current()->PostTask(
3193 FROM_HERE,
[email protected]e83f1682008-09-07 23:57:403194 method_factory_.NewRunnableMethod(&Browser::ClearUnloadState,
3195 Source<TabContents>(source).ptr()));
3196 }
3197 break;
3198
[email protected]b4a19ea2009-03-17 10:08:243199 case NotificationType::SSL_VISIBLE_STATE_CHANGED:
[email protected]e83f1682008-09-07 23:57:403200 // When the current tab's SSL state changes, we need to update the URL
[email protected]90e8d062008-09-08 02:26:323201 // bar to reflect the new state. Note that it's possible for the selected
3202 // tab contents to be NULL. This is because we listen for all sources
3203 // (NavigationControllers) for convenience, so the notification could
3204 // actually be for a different window while we're doing asynchronous
3205 // closing of this one.
3206 if (GetSelectedTabContents() &&
[email protected]ce3fa3c2009-04-20 19:55:573207 &GetSelectedTabContents()->controller() ==
[email protected]e83f1682008-09-07 23:57:403208 Source<NavigationController>(source).ptr())
[email protected]36b6dcb2008-11-12 01:19:573209 UpdateToolbar(false);
[email protected]e83f1682008-09-07 23:57:403210 break;
3211
[email protected]0c6da502009-08-14 22:32:393212 case NotificationType::EXTENSION_UPDATE_DISABLED: {
[email protected]e6090e42010-03-23 22:44:083213 // Show the UI if the extension was disabled for escalated permissions.
[email protected]24e7a9d2009-11-04 11:11:343214 Profile* profile = Source<Profile>(source).ptr();
[email protected]bc535ee52010-08-31 18:40:323215 if (profile_->IsSameProfile(profile)) {
3216 ExtensionsService* service = profile->GetExtensionsService();
3217 DCHECK(service);
[email protected]9adb9692010-10-29 23:14:023218 const Extension* extension = Details<const Extension>(details).ptr();
[email protected]bc535ee52010-08-31 18:40:323219 if (service->extension_prefs()->DidExtensionEscalatePermissions(
3220 extension->id()))
3221 ShowExtensionDisabledUI(service, profile_, extension);
3222 }
[email protected]0c6da502009-08-14 22:32:393223 break;
3224 }
3225
[email protected]b723ee82009-11-20 16:42:503226 case NotificationType::EXTENSION_UNLOADED:
3227 case NotificationType::EXTENSION_UNLOADED_DISABLED: {
3228 window()->GetLocationBar()->UpdatePageActions();
[email protected]57f71b92009-09-11 19:31:383229
[email protected]894bb502009-05-21 22:39:573230 // Close any tabs from the unloaded extension.
[email protected]9adb9692010-10-29 23:14:023231 const Extension* extension = Details<const Extension>(details).ptr();
[email protected]ecc523f62010-09-28 22:45:403232 TabStripModel* model = tab_handler_->GetTabStripModel();
3233 for (int i = model->count() - 1; i >= 0; --i) {
[email protected]3c9e1872010-11-18 16:17:493234 TabContents* tc = model->GetTabContentsAt(i)->tab_contents();
[email protected]894bb502009-05-21 22:39:573235 if (tc->GetURL().SchemeIs(chrome::kExtensionScheme) &&
3236 tc->GetURL().host() == extension->id()) {
3237 CloseTabContents(tc);
[email protected]894bb502009-05-21 22:39:573238 }
3239 }
[email protected]9fd542df2009-09-30 07:32:013240
[email protected]894bb502009-05-21 22:39:573241 break;
3242 }
3243
[email protected]a4ed6282009-12-14 20:51:163244 case NotificationType::EXTENSION_PROCESS_TERMINATED: {
[email protected]57f71b92009-09-11 19:31:383245 window()->GetLocationBar()->InvalidatePageActions();
3246
[email protected]371ed7a2009-08-25 15:22:463247 TabContents* tab_contents = GetSelectedTabContents();
3248 if (!tab_contents)
3249 break;
3250 ExtensionsService* extensions_service =
[email protected]e8f95f62009-11-12 21:18:493251 Source<Profile>(source).ptr()->GetExtensionsService();
[email protected]371ed7a2009-08-25 15:22:463252 ExtensionHost* extension_host = Details<ExtensionHost>(details).ptr();
3253 tab_contents->AddInfoBar(new CrashedExtensionInfoBarDelegate(
3254 tab_contents, extensions_service, extension_host->extension()));
3255 break;
3256 }
3257
[email protected]ad0c2e1b2010-01-30 00:00:103258 case NotificationType::EXTENSION_LOADED: {
[email protected]26571792010-05-19 21:04:483259 window()->GetLocationBar()->UpdatePageActions();
3260
[email protected]ad0c2e1b2010-01-30 00:00:103261 // If any "This extension has crashed" InfoBarDelegates are around for
3262 // this extension, it means that it has been reloaded in another window
3263 // so just remove the remaining CrashedExtensionInfoBarDelegate objects.
3264 TabContents* tab_contents = GetSelectedTabContents();
3265 if (!tab_contents)
3266 break;
[email protected]9adb9692010-10-29 23:14:023267 const Extension* extension = Details<const Extension>(details).ptr();
[email protected]ad0c2e1b2010-01-30 00:00:103268 CrashedExtensionInfoBarDelegate* delegate = NULL;
[email protected]c755d942010-02-06 00:37:223269 for (int i = 0; i < tab_contents->infobar_delegate_count();) {
[email protected]ad0c2e1b2010-01-30 00:00:103270 delegate = tab_contents->GetInfoBarDelegateAt(i)->
3271 AsCrashedExtensionInfoBarDelegate();
[email protected]c755d942010-02-06 00:37:223272 if (delegate && delegate->extension_id() == extension->id()) {
[email protected]ad0c2e1b2010-01-30 00:00:103273 tab_contents->RemoveInfoBar(delegate);
[email protected]c755d942010-02-06 00:37:223274 continue;
3275 }
3276 // Only increment |i| if we didn't remove an entry.
3277 ++i;
[email protected]ad0c2e1b2010-01-30 00:00:103278 }
3279 break;
3280 }
3281
[email protected]e001d412009-06-26 20:53:253282 case NotificationType::BROWSER_THEME_CHANGED:
3283 window()->UserChangedTheme();
3284 break;
3285
[email protected]91e1bd82009-09-03 22:04:403286 case NotificationType::EXTENSION_READY_FOR_INSTALL: {
[email protected]a65bce4e2010-06-09 16:00:153287 // Handle EXTENSION_READY_FOR_INSTALL for last active normal browser.
3288 if (BrowserList::FindBrowserWithType(profile(),
3289 Browser::TYPE_NORMAL,
[email protected]074e4f42010-06-23 16:12:063290 true) != this)
[email protected]91e1bd82009-09-03 22:04:403291 break;
[email protected]ac025282009-12-16 19:16:383292
3293 // We only want to show the loading dialog for themes, but we don't want
3294 // to wait until unpack to find out an extension is a theme, so we test
3295 // the download_url GURL instead. This means that themes in the extensions
3296 // gallery won't get the loading dialog.
3297 GURL download_url = *(Details<GURL>(details).ptr());
3298 if (ExtensionsService::IsDownloadFromMiniGallery(download_url))
3299 window()->ShowThemeInstallBubble();
[email protected]91e1bd82009-09-03 22:04:403300 break;
3301 }
3302
[email protected]e587a45f2009-10-30 22:34:413303 case NotificationType::PROFILE_ERROR: {
[email protected]0e30ef72009-09-05 00:05:083304 if (BrowserList::GetLastActive() != this)
3305 break;
[email protected]e587a45f2009-10-30 22:34:413306 int* message_id = Details<int>(details).ptr();
3307 window()->ShowProfileErrorDialog(*message_id);
[email protected]0e30ef72009-09-05 00:05:083308 break;
3309 }
[email protected]91e1bd82009-09-03 22:04:403310
[email protected]b9c505b2010-04-30 15:05:103311 case NotificationType::PREF_CHANGED: {
[email protected]2a7e7c152010-10-01 20:12:093312 const std::string& pref_name = *Details<std::string>(details).ptr();
3313 if (pref_name == prefs::kUseVerticalTabs) {
[email protected]b3344872010-05-03 15:52:293314 UseVerticalTabsChanged();
[email protected]2a7e7c152010-10-01 20:12:093315 } else if (pref_name == prefs::kPrintingEnabled) {
[email protected]9e823662010-10-13 23:36:003316 UpdatePrintingState(0);
[email protected]73de26a2010-10-17 03:23:253317 } else if (pref_name == prefs::kInstantEnabled) {
3318 if (!InstantController::IsEnabled(profile())) {
3319 if (instant()) {
3320 instant()->DestroyPreviewContents();
3321 instant_.reset(NULL);
3322 }
3323 } else {
3324 CreateInstantIfNecessary();
3325 }
[email protected]543432ee2010-10-22 16:32:133326 } else if (pref_name == prefs::kDevToolsDisabled) {
3327 UpdateCommandsForDevTools();
3328 if (dev_tools_disabled_.GetValue())
3329 g_browser_process->devtools_manager()->CloseAllClientHosts();
[email protected]2a7e7c152010-10-01 20:12:093330 } else {
[email protected]b9c505b2010-04-30 15:05:103331 NOTREACHED();
[email protected]2a7e7c152010-10-01 20:12:093332 }
[email protected]b9c505b2010-04-30 15:05:103333 break;
3334 }
3335
[email protected]e83f1682008-09-07 23:57:403336 default:
3337 NOTREACHED() << "Got a notification we didn't register for.";
initial.commit09911bf2008-07-26 23:55:293338 }
3339}
3340
[email protected]d3b98c82010-07-14 07:45:593341///////////////////////////////////////////////////////////////////////////////
3342// Browser, ProfileSyncServiceObserver implementation:
3343
3344void Browser::OnStateChanged() {
3345 DCHECK(profile_->GetProfileSyncService());
3346
3347#if !defined(OS_MACOSX)
3348 const bool show_main_ui = (type() == TYPE_NORMAL) && !window_->IsFullscreen();
3349#else
3350 const bool show_main_ui = (type() == TYPE_NORMAL);
3351#endif
3352
3353 command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
3354 show_main_ui && profile_->IsSyncAccessible());
3355}
[email protected]88d74942009-01-21 22:04:443356
[email protected]36b6dcb2008-11-12 01:19:573357///////////////////////////////////////////////////////////////////////////////
[email protected]6b723f82010-10-05 20:14:273358// Browser, InstantDelegate implementation:
[email protected]03bb953d2010-09-14 21:38:303359
[email protected]36d5e5592010-11-15 20:45:593360void Browser::PrepareForInstant() {
3361 window_->PrepareForInstant();
3362}
3363
[email protected]3c9e1872010-11-18 16:17:493364void Browser::ShowInstant(TabContentsWrapper* preview_contents) {
3365 DCHECK(instant_->tab_contents() == GetSelectedTabContentsWrapper());
3366 window_->ShowInstant(preview_contents->tab_contents());
[email protected]03bb953d2010-09-14 21:38:303367}
3368
[email protected]6b723f82010-10-05 20:14:273369void Browser::HideInstant() {
3370 window_->HideInstant();
[email protected]03bb953d2010-09-14 21:38:303371}
3372
[email protected]3c9e1872010-11-18 16:17:493373void Browser::CommitInstant(TabContentsWrapper* preview_contents) {
3374 TabContentsWrapper* tab_contents = instant_->tab_contents();
3375 int index =
3376 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(tab_contents);
3377 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]03bb953d2010-09-14 21:38:303378 preview_contents->controller().CopyStateFromAndPrune(
[email protected]47e020a2010-10-15 14:43:373379 &tab_contents->controller());
[email protected]03bb953d2010-09-14 21:38:303380 // TabStripModel takes ownership of preview_contents.
[email protected]ecc523f62010-09-28 22:45:403381 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(
[email protected]8a34e6602010-10-02 17:29:433382 index, preview_contents);
[email protected]03bb953d2010-09-14 21:38:303383}
3384
3385void Browser::SetSuggestedText(const string16& text) {
3386 window()->GetLocationBar()->SetSuggestedText(text);
3387}
3388
[email protected]6b723f82010-10-05 20:14:273389gfx::Rect Browser::GetInstantBounds() {
3390 return window()->GetInstantBounds();
[email protected]46fe8e92010-09-22 03:32:473391}
3392
[email protected]03bb953d2010-09-14 21:38:303393///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573394// Browser, Command and state updating (private):
3395
3396void Browser::InitCommandState() {
3397 // All browser commands whose state isn't set automagically some other way
3398 // (like Back & Forward with initial page load) must have their state
3399 // initialized here, otherwise they will be forever disabled.
3400
[email protected]84214982008-12-10 18:49:103401 // Navigation commands
[email protected]1fc025202009-01-20 23:03:143402 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
[email protected]1ccb3568d2010-02-19 10:51:163403 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
[email protected]84214982008-12-10 18:49:103404
3405 // Window management commands
[email protected]1fc025202009-01-20 23:03:143406 command_updater_.UpdateCommandEnabled(IDC_NEW_WINDOW, true);
3407 command_updater_.UpdateCommandEnabled(IDC_NEW_INCOGNITO_WINDOW, true);
[email protected]1fc025202009-01-20 23:03:143408 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
3409 command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
3410 command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
3411 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
[email protected]281918912010-05-27 22:05:133412 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
[email protected]1fc025202009-01-20 23:03:143413 command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
[email protected]c8b59f92010-05-28 21:45:473414 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, true);
[email protected]84214982008-12-10 18:49:103415
3416 // Page-related commands
[email protected]89d6e6e2009-12-03 23:06:513417 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
[email protected]1fc025202009-01-20 23:03:143418 command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
3419 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
3420 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
3421 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
3422 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
3423 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
3424 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
3425 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true);
3426 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true);
3427 command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true);
3428 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true);
3429 command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true);
3430 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true);
3431 command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true);
3432 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true);
3433 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true);
3434 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true);
3435 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true);
3436 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true);
3437 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true);
3438 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true);
3439 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true);
3440 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true);
3441 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true);
3442 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true);
3443 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true);
3444 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true);
3445 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true);
3446 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true);
3447 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true);
3448 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true);
3449 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true);
3450 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true);
3451 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true);
3452 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true);
[email protected]e13271f2009-03-07 00:26:003453 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true);
[email protected]1fc025202009-01-20 23:03:143454 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
3455 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
[email protected]84214982008-12-10 18:49:103456
[email protected]63b02932009-06-05 09:40:513457 // Zoom
3458 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
3459 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
3460 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
3461 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
3462
[email protected]84214982008-12-10 18:49:103463 // Show various bits of UI
[email protected]1fc025202009-01-20 23:03:143464 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, true);
3465 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
[email protected]543432ee2010-10-22 16:32:133466 UpdateCommandsForDevTools();
[email protected]1fc025202009-01-20 23:03:143467 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, true);
[email protected]1fc025202009-01-20 23:03:143468 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true);
[email protected]4a4180a52010-08-23 06:39:483469 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER,
3470 browser_defaults::bookmarks_enabled);
[email protected]1fc025202009-01-20 23:03:143471 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
3472 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE, true);
[email protected]4aee5652009-11-19 18:59:213473 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, true);
[email protected]9cd51a02009-10-23 22:30:293474
[email protected]96e34672010-02-09 21:40:293475#if defined(OS_CHROMEOS)
[email protected]f97d7f632010-06-01 21:08:333476 command_updater_.UpdateCommandEnabled(IDC_SEARCH, true);
[email protected]d14af522010-12-02 03:54:503477 command_updater_.UpdateCommandEnabled(IDC_SHOW_KEYBOARD_OVERLAY, true);
[email protected]c8b59f92010-05-28 21:45:473478 command_updater_.UpdateCommandEnabled(IDC_SYSTEM_OPTIONS, true);
3479 command_updater_.UpdateCommandEnabled(IDC_INTERNET_OPTIONS, true);
[email protected]96e34672010-02-09 21:40:293480#endif
[email protected]c8b59f92010-05-28 21:45:473481
[email protected]9cd51a02009-10-23 22:30:293482 ExtensionsService* extensions_service = profile()->GetExtensionsService();
3483 bool enable_extensions =
3484 extensions_service && extensions_service->extensions_enabled();
3485 command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
3486 enable_extensions);
3487
[email protected]64ff7942008-12-17 18:11:233488 // Initialize other commands based on the window type.
[email protected]11f4857282009-11-13 19:56:173489 bool normal_window = type() == TYPE_NORMAL;
[email protected]fc33e9992010-04-08 19:40:133490 bool non_devtools_window = type() != TYPE_DEVTOOLS;
[email protected]64ff7942008-12-17 18:11:233491
[email protected]11f4857282009-11-13 19:56:173492 // Navigation commands
3493 command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
[email protected]64ff7942008-12-17 18:11:233494
[email protected]11f4857282009-11-13 19:56:173495 // Window management commands
[email protected]cf299bc2010-08-12 20:27:093496 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN,
3497 type() != TYPE_APP_PANEL);
[email protected]11f4857282009-11-13 19:56:173498 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
3499 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
3500 normal_window);
3501 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
3502 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
3503 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
3504 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window);
3505 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window);
3506 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window);
3507 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window);
3508 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window);
3509 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window);
3510 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
3511 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
[email protected]c1d0d812010-07-27 20:21:553512#if defined(OS_MACOSX)
3513 command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
3514#endif
[email protected]e662ade2009-06-08 18:20:143515
[email protected]11f4857282009-11-13 19:56:173516 // Page-related commands
[email protected]4a4180a52010-08-23 06:39:483517 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
3518 browser_defaults::bookmarks_enabled && normal_window);
[email protected]76624fde2009-10-09 18:13:233519
[email protected]fc33e9992010-04-08 19:40:133520 // Clipboard commands
3521 command_updater_.UpdateCommandEnabled(IDC_COPY_URL, non_devtools_window);
3522
3523 // Find-in-page
3524 command_updater_.UpdateCommandEnabled(IDC_FIND, non_devtools_window);
3525 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, non_devtools_window);
3526 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, non_devtools_window);
3527
[email protected]cf28ec52010-04-09 22:56:343528 // AutoFill
3529 command_updater_.UpdateCommandEnabled(IDC_AUTOFILL_DEFAULT,
3530 non_devtools_window);
3531
[email protected]11f4857282009-11-13 19:56:173532 // Show various bits of UI
[email protected]fc33e9992010-04-08 19:40:133533 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
[email protected]9282cea2009-02-18 18:49:003534
[email protected]c1bbaa82010-11-08 11:17:053535 // The upgrade entry and the view incompatibility entry should always be
3536 // enabled. Whether they are visible is a separate matter determined on menu
3537 // show.
[email protected]b21d6912010-08-31 19:22:413538 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
[email protected]c1bbaa82010-11-08 11:17:053539 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
[email protected]b21d6912010-08-31 19:22:413540
[email protected]b569c112010-11-22 20:53:443541 // View Background Pages entry is always enabled, but is hidden if there are
3542 // no background pages.
3543 command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true);
3544
[email protected]9282cea2009-02-18 18:49:003545 // Initialize other commands whose state changes based on fullscreen mode.
3546 UpdateCommandsForFullscreenMode(false);
[email protected]9e823662010-10-13 23:36:003547
3548 UpdateCommandsForContentRestrictionState();
[email protected]36b6dcb2008-11-12 01:19:573549}
3550
[email protected]84214982008-12-10 18:49:103551void Browser::UpdateCommandsForTabState() {
[email protected]c7c42332008-11-15 01:10:543552 TabContents* current_tab = GetSelectedTabContents();
[email protected]64ff7942008-12-17 18:11:233553 if (!current_tab) // May be NULL during tab restore.
[email protected]d8375fd2008-11-25 22:45:393554 return;
[email protected]d8375fd2008-11-25 22:45:393555
[email protected]84214982008-12-10 18:49:103556 // Navigation commands
[email protected]ce3fa3c2009-04-20 19:55:573557 NavigationController& nc = current_tab->controller();
3558 command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack());
3559 command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward());
[email protected]fc33e9992010-04-08 19:40:133560 command_updater_.UpdateCommandEnabled(IDC_RELOAD,
3561 CanReloadContents(current_tab));
3562 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE,
3563 CanReloadContents(current_tab));
initial.commit09911bf2008-07-26 23:55:293564
[email protected]84214982008-12-10 18:49:103565 // Window management commands
[email protected]fc33e9992010-04-08 19:40:133566 bool non_app_window = !(type() & TYPE_APP);
[email protected]1fc025202009-01-20 23:03:143567 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
[email protected]fc33e9992010-04-08 19:40:133568 non_app_window && CanDuplicateContentsAt(selected_index()));
[email protected]ad0acc62009-12-15 14:28:313569 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB,
[email protected]fc33e9992010-04-08 19:40:133570 non_app_window && tab_count() > 1);
[email protected]ad0acc62009-12-15 14:28:313571 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
[email protected]fc33e9992010-04-08 19:40:133572 non_app_window && tab_count() > 1);
[email protected]84214982008-12-10 18:49:103573
[email protected]57c6a652009-05-04 07:58:343574 // Page-related commands
[email protected]57c6a652009-05-04 07:58:343575 window_->SetStarredState(current_tab->is_starred());
[email protected]a206b442009-10-08 23:20:203576 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
[email protected]4a4180a52010-08-23 06:39:483577 browser_defaults::bookmarks_enabled && CanBookmarkAllTabs());
[email protected]57c6a652009-05-04 07:58:343578 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
[email protected]31682282010-01-15 18:05:163579 current_tab->controller().CanViewSource());
[email protected]151666e2010-10-21 17:05:253580 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
3581 current_tab->ShouldDisplayURL() && current_tab->GetURL().is_valid());
3582
3583 // Changing the encoding is not possible on Chrome-internal webpages.
[email protected]4d07cdc2009-08-22 16:09:393584 // Instead of using GetURL here, we use url() (which is the "real" url of the
3585 // page) from the NavigationEntry because its reflects their origin rather
3586 // than the display one (returned by GetURL) which may be different (like
3587 // having "view-source:" on the front).
[email protected]fc33e9992010-04-08 19:40:133588 NavigationEntry* active_entry = nc.GetActiveEntry();
[email protected]c0f82ec52010-07-27 14:22:143589 bool is_chrome_internal = (active_entry ?
3590 active_entry->url().SchemeIs(chrome::kChromeUIScheme) : false);
3591 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
3592 !is_chrome_internal && SavePackage::IsSavableContents(
3593 current_tab->contents_mime_type()));
3594
[email protected]57c6a652009-05-04 07:58:343595 // Show various bits of UI
[email protected]c065fa072010-01-20 23:12:253596 // TODO(pinkerton): Disable app-mode in the model until we implement it
3597 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
3598#if !defined(OS_MACOSX)
[email protected]57c6a652009-05-04 07:58:343599 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:233600 web_app::IsValidUrl(current_tab->GetURL()));
[email protected]c065fa072010-01-20 23:12:253601#endif
[email protected]9e823662010-10-13 23:36:003602
3603 UpdateCommandsForContentRestrictionState();
3604}
3605
3606void Browser::UpdateCommandsForContentRestrictionState() {
3607 int restrictions = 0;
3608 TabContents* current_tab = GetSelectedTabContents();
[email protected]151666e2010-10-21 17:05:253609 if (current_tab) {
[email protected]9e823662010-10-13 23:36:003610 restrictions = current_tab->content_restrictions();
[email protected]151666e2010-10-21 17:05:253611 NavigationEntry* active_entry = current_tab->controller().GetActiveEntry();
3612 // See comment in UpdateCommandsForTabState about why we call url().
3613 if (!SavePackage::IsSavableURL(active_entry ? active_entry->url() : GURL()))
3614 restrictions |= CONTENT_RESTRICTION_SAVE;
3615 }
[email protected]9e823662010-10-13 23:36:003616
3617 command_updater_.UpdateCommandEnabled(
3618 IDC_COPY, !(restrictions & CONTENT_RESTRICTION_COPY));
3619 command_updater_.UpdateCommandEnabled(
3620 IDC_CUT, !(restrictions & CONTENT_RESTRICTION_CUT));
3621 command_updater_.UpdateCommandEnabled(
3622 IDC_PASTE, !(restrictions & CONTENT_RESTRICTION_PASTE));
[email protected]151666e2010-10-21 17:05:253623 command_updater_.UpdateCommandEnabled(
3624 IDC_SAVE_PAGE, !(restrictions & CONTENT_RESTRICTION_SAVE));
[email protected]9e823662010-10-13 23:36:003625 UpdatePrintingState(restrictions);
3626}
3627
3628void Browser::UpdatePrintingState(int content_restrictions) {
3629 bool enabled = true;
3630 if (content_restrictions & CONTENT_RESTRICTION_PRINT) {
3631 enabled = false;
3632 } else if (g_browser_process->local_state()) {
3633 enabled = printing_enabled_.GetValue();
3634 }
3635 command_updater_.UpdateCommandEnabled(IDC_PRINT, enabled);
initial.commit09911bf2008-07-26 23:55:293636}
3637
[email protected]943d8122010-06-11 02:13:453638void Browser::UpdateReloadStopState(bool is_loading, bool force) {
3639 window_->UpdateReloadStopState(is_loading, force);
[email protected]1fc025202009-01-20 23:03:143640 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
[email protected]64ff7942008-12-17 18:11:233641}
3642
[email protected]543432ee2010-10-22 16:32:133643void Browser::UpdateCommandsForDevTools() {
3644 bool dev_tools_enabled = !dev_tools_disabled_.GetValue();
3645 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
3646 dev_tools_enabled);
3647 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
3648 dev_tools_enabled);
3649 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
3650 dev_tools_enabled);
3651}
3652
[email protected]36b6dcb2008-11-12 01:19:573653///////////////////////////////////////////////////////////////////////////////
3654// Browser, UI update coalescing and handling (private):
3655
3656void Browser::UpdateToolbar(bool should_restore_state) {
[email protected]3c9e1872010-11-18 16:17:493657 window_->UpdateToolbar(GetSelectedTabContentsWrapper(), should_restore_state);
initial.commit09911bf2008-07-26 23:55:293658}
3659
[email protected]36b6dcb2008-11-12 01:19:573660void Browser::ScheduleUIUpdate(const TabContents* source,
3661 unsigned changed_flags) {
[email protected]a5231662009-09-26 00:56:003662 if (!source)
3663 return;
3664
[email protected]2b4355c2009-04-04 17:55:463665 // Do some synchronous updates.
[email protected]36b6dcb2008-11-12 01:19:573666 if (changed_flags & TabContents::INVALIDATE_URL &&
3667 source == GetSelectedTabContents()) {
3668 // Only update the URL for the current tab. Note that we do not update
3669 // the navigation commands since those would have already been updated
3670 // synchronously by NavigationStateChanged.
3671 UpdateToolbar(false);
[email protected]8030f012009-09-25 18:09:373672 changed_flags &= ~TabContents::INVALIDATE_URL;
[email protected]36b6dcb2008-11-12 01:19:573673 }
[email protected]a5231662009-09-26 00:56:003674 if (changed_flags & TabContents::INVALIDATE_LOAD) {
[email protected]6ebdc9b2010-09-27 16:55:573675 // Update the loading state synchronously. This is so the throbber will
3676 // immediately start/stop, which gives a more snappy feel. We want to do
[email protected]a5231662009-09-26 00:56:003677 // this for any tab so they start & stop quickly.
[email protected]ecc523f62010-09-28 22:45:403678 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
3679 tab_handler_->GetTabStripModel()->GetIndexOfController(
3680 &source->controller()),
[email protected]6ebdc9b2010-09-27 16:55:573681 TabStripModelObserver::LOADING_ONLY);
3682 // The status bubble needs to be updated during INVALIDATE_LOAD too, but
3683 // we do that asynchronously by not stripping INVALIDATE_LOAD from
3684 // changed_flags.
[email protected]8030f012009-09-25 18:09:373685 }
3686
[email protected]f1cd5e82009-10-23 17:19:033687 if (changed_flags & TabContents::INVALIDATE_TITLE && !source->is_loading()) {
3688 // To correctly calculate whether the title changed while not loading
3689 // we need to process the update synchronously. This state only matters for
3690 // the TabStripModel, so we notify the TabStripModel now and notify others
3691 // asynchronously.
[email protected]ecc523f62010-09-28 22:45:403692 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
3693 tab_handler_->GetTabStripModel()->GetIndexOfController(
3694 &source->controller()),
[email protected]f1cd5e82009-10-23 17:19:033695 TabStripModelObserver::TITLE_NOT_LOADING);
3696 }
3697
[email protected]6d7a6042010-08-12 20:12:423698 if (changed_flags & TabContents::INVALIDATE_BOOKMARK_BAR) {
[email protected]8030f012009-09-25 18:09:373699 window()->ShelfVisibilityChanged();
[email protected]6d7a6042010-08-12 20:12:423700 changed_flags &= ~TabContents::INVALIDATE_BOOKMARK_BAR;
[email protected]2b4355c2009-04-04 17:55:463701 }
3702
3703 // If the only updates were synchronously handled above, we're done.
[email protected]8030f012009-09-25 18:09:373704 if (changed_flags == 0)
[email protected]2b4355c2009-04-04 17:55:463705 return;
[email protected]36b6dcb2008-11-12 01:19:573706
3707 // Save the dirty bits.
[email protected]85354982009-09-25 19:58:403708 scheduled_updates_[source] |= changed_flags;
[email protected]36b6dcb2008-11-12 01:19:573709
3710 if (chrome_updater_factory_.empty()) {
3711 // No task currently scheduled, start another.
[email protected]0586b0e2010-02-12 21:38:373712 MessageLoop::current()->PostDelayedTask(
3713 FROM_HERE,
[email protected]36b6dcb2008-11-12 01:19:573714 chrome_updater_factory_.NewRunnableMethod(
3715 &Browser::ProcessPendingUIUpdates),
[email protected]6ebdc9b2010-09-27 16:55:573716 kUIUpdateCoalescingTimeMS);
[email protected]36b6dcb2008-11-12 01:19:573717 }
3718}
3719
3720void Browser::ProcessPendingUIUpdates() {
3721#ifndef NDEBUG
3722 // Validate that all tabs we have pending updates for exist. This is scary
3723 // because the pending list must be kept in sync with any detached or
[email protected]a5231662009-09-26 00:56:003724 // deleted tabs.
[email protected]85354982009-09-25 19:58:403725 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
3726 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:573727 bool found = false;
3728 for (int tab = 0; tab < tab_count(); tab++) {
[email protected]a5231662009-09-26 00:56:003729 if (GetTabContentsAt(tab) == i->first) {
[email protected]36b6dcb2008-11-12 01:19:573730 found = true;
3731 break;
3732 }
3733 }
3734 DCHECK(found);
3735 }
3736#endif
3737
3738 chrome_updater_factory_.RevokeAll();
3739
[email protected]85354982009-09-25 19:58:403740 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
3741 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:573742 // Do not dereference |contents|, it may be out-of-date!
[email protected]85354982009-09-25 19:58:403743 const TabContents* contents = i->first;
3744 unsigned flags = i->second;
[email protected]36b6dcb2008-11-12 01:19:573745
[email protected]a5231662009-09-26 00:56:003746 if (contents == GetSelectedTabContents()) {
3747 // Updates that only matter when the tab is selected go here.
[email protected]f7f3a5f2009-05-01 22:02:343748
[email protected]a5231662009-09-26 00:56:003749 if (flags & TabContents::INVALIDATE_PAGE_ACTIONS)
3750 window()->GetLocationBar()->UpdatePageActions();
3751
[email protected]6ebdc9b2010-09-27 16:55:573752 // Updating the URL happens synchronously in ScheduleUIUpdate.
3753 if (flags & TabContents::INVALIDATE_LOAD && GetStatusBubble())
3754 GetStatusBubble()->SetStatus(WideToUTF16(contents->GetStatusText()));
[email protected]a5231662009-09-26 00:56:003755
[email protected]f1cd5e82009-10-23 17:19:033756 if (flags & (TabContents::INVALIDATE_TAB |
3757 TabContents::INVALIDATE_TITLE)) {
[email protected]c065fa072010-01-20 23:12:253758// TODO(pinkerton): Disable app-mode in the model until we implement it
3759// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
3760#if !defined(OS_MACOSX)
[email protected]a5231662009-09-26 00:56:003761 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:233762 web_app::IsValidUrl(contents->GetURL()));
[email protected]c065fa072010-01-20 23:12:253763#endif
[email protected]a5231662009-09-26 00:56:003764 window_->UpdateTitleBar();
3765 }
[email protected]4d34e2e2009-05-26 22:55:283766 }
[email protected]36b6dcb2008-11-12 01:19:573767
[email protected]a5231662009-09-26 00:56:003768 // Updates that don't depend upon the selected state go here.
[email protected]f1cd5e82009-10-23 17:19:033769 if (flags & (TabContents::INVALIDATE_TAB | TabContents::INVALIDATE_TITLE)) {
[email protected]ecc523f62010-09-28 22:45:403770 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
[email protected]3c9e1872010-11-18 16:17:493771 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents),
[email protected]f1cd5e82009-10-23 17:19:033772 TabStripModelObserver::ALL);
[email protected]36b6dcb2008-11-12 01:19:573773 }
3774
3775 // We don't need to process INVALIDATE_STATE, since that's not visible.
3776 }
3777
3778 scheduled_updates_.clear();
3779}
3780
3781void Browser::RemoveScheduledUpdatesFor(TabContents* contents) {
3782 if (!contents)
3783 return;
3784
[email protected]85354982009-09-25 19:58:403785 UpdateMap::iterator i = scheduled_updates_.find(contents);
3786 if (i != scheduled_updates_.end())
3787 scheduled_updates_.erase(i);
initial.commit09911bf2008-07-26 23:55:293788}
3789
[email protected]d938aed92009-01-22 19:49:333790
[email protected]36b6dcb2008-11-12 01:19:573791///////////////////////////////////////////////////////////////////////////////
3792// Browser, Getters for UI (private):
initial.commit09911bf2008-07-26 23:55:293793
[email protected]36b6dcb2008-11-12 01:19:573794StatusBubble* Browser::GetStatusBubble() {
[email protected]34930432009-11-09 00:12:093795#if !defined(OS_MACOSX)
3796 // In kiosk mode, we want to always hide the status bubble.
3797 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
3798 return NULL;
3799#endif
[email protected]9b032bf2009-07-21 17:34:233800 return window_ ? window_->GetStatusBubble() : NULL;
initial.commit09911bf2008-07-26 23:55:293801}
3802
[email protected]36b6dcb2008-11-12 01:19:573803///////////////////////////////////////////////////////////////////////////////
3804// Browser, Session restore functions (private):
initial.commit09911bf2008-07-26 23:55:293805
3806void Browser::SyncHistoryWithTabs(int index) {
3807 if (!profile()->HasSessionService())
3808 return;
3809 SessionService* session_service = profile()->GetSessionService();
3810 if (session_service) {
3811 for (int i = index; i < tab_count(); ++i) {
3812 TabContents* contents = GetTabContentsAt(i);
3813 if (contents) {
3814 session_service->SetTabIndexInWindow(
[email protected]ce3fa3c2009-04-20 19:55:573815 session_id(), contents->controller().session_id(), i);
[email protected]ecc523f62010-09-28 22:45:403816 session_service->SetPinnedState(
3817 session_id(),
3818 contents->controller().session_id(),
3819 tab_handler_->GetTabStripModel()->IsTabPinned(i));
initial.commit09911bf2008-07-26 23:55:293820 }
3821 }
3822 }
3823}
3824
[email protected]36b6dcb2008-11-12 01:19:573825///////////////////////////////////////////////////////////////////////////////
3826// Browser, OnBeforeUnload handling (private):
initial.commit09911bf2008-07-26 23:55:293827
[email protected]04b4a6c2008-08-02 00:44:473828void Browser::ProcessPendingTabs() {
3829 DCHECK(is_attempting_to_close_browser_);
initial.commit09911bf2008-07-26 23:55:293830
[email protected]04b4a6c2008-08-02 00:44:473831 if (HasCompletedUnloadProcessing()) {
3832 // We've finished all the unload events and can proceed to close the
3833 // browser.
3834 OnWindowClosing();
initial.commit09911bf2008-07-26 23:55:293835 return;
3836 }
3837
[email protected]04b4a6c2008-08-02 00:44:473838 // Process beforeunload tabs first. When that queue is empty, process
3839 // unload tabs.
[email protected]04b4a6c2008-08-02 00:44:473840 if (!tabs_needing_before_unload_fired_.empty()) {
[email protected]06b42f032008-12-03 18:43:053841 TabContents* tab = *(tabs_needing_before_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:243842 // Null check render_view_host here as this gets called on a PostTask and
3843 // the tab's render_view_host may have been nulled out.
3844 if (tab->render_view_host()) {
[email protected]ae23c272009-07-27 20:15:403845 tab->render_view_host()->FirePageBeforeUnload(false);
[email protected]22484622009-06-10 21:17:243846 } else {
3847 ClearUnloadState(tab);
3848 }
[email protected]04b4a6c2008-08-02 00:44:473849 } else if (!tabs_needing_unload_fired_.empty()) {
initial.commit09911bf2008-07-26 23:55:293850 // We've finished firing all beforeunload events and can proceed with unload
3851 // events.
3852 // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting
3853 // somewhere around here so that we have accurate measurements of shutdown
3854 // time.
[email protected]04b4a6c2008-08-02 00:44:473855 // TODO(ojan): We can probably fire all the unload events in parallel and
3856 // get a perf benefit from that in the cases where the tab hangs in it's
3857 // unload handler or takes a long time to page in.
[email protected]06b42f032008-12-03 18:43:053858 TabContents* tab = *(tabs_needing_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:243859 // Null check render_view_host here as this gets called on a PostTask and
3860 // the tab's render_view_host may have been nulled out.
3861 if (tab->render_view_host()) {
[email protected]eb6b87a2009-07-24 15:57:393862 tab->render_view_host()->ClosePage(false, -1, -1);
[email protected]22484622009-06-10 21:17:243863 } else {
3864 ClearUnloadState(tab);
3865 }
initial.commit09911bf2008-07-26 23:55:293866 } else {
[email protected]04b4a6c2008-08-02 00:44:473867 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:293868 }
3869}
3870
[email protected]d043c2cc2009-03-25 18:30:453871bool Browser::HasCompletedUnloadProcessing() const {
[email protected]04b4a6c2008-08-02 00:44:473872 return is_attempting_to_close_browser_ &&
3873 tabs_needing_before_unload_fired_.empty() &&
3874 tabs_needing_unload_fired_.empty();
3875}
3876
3877void Browser::CancelWindowClose() {
[email protected]0b4d3382010-07-14 16:13:043878 // Closing of window can be canceled from:
3879 // - canceling beforeunload
3880 // - disallowing closing from IsClosingPermitted.
[email protected]04b4a6c2008-08-02 00:44:473881 DCHECK(is_attempting_to_close_browser_);
[email protected]8f673f3a2008-08-05 22:34:283882 tabs_needing_before_unload_fired_.clear();
3883 tabs_needing_unload_fired_.clear();
[email protected]04b4a6c2008-08-02 00:44:473884 is_attempting_to_close_browser_ = false;
[email protected]0b4d3382010-07-14 16:13:043885
3886 // Inform TabCloseableStateWatcher that closing of window has been canceled.
3887 TabCloseableStateWatcher* watcher =
3888 g_browser_process->tab_closeable_state_watcher();
3889 if (watcher)
3890 watcher->OnWindowCloseCanceled(this);
[email protected]04b4a6c2008-08-02 00:44:473891}
3892
[email protected]06b42f032008-12-03 18:43:053893bool Browser::RemoveFromSet(UnloadListenerSet* set, TabContents* tab) {
[email protected]04b4a6c2008-08-02 00:44:473894 DCHECK(is_attempting_to_close_browser_);
3895
[email protected]06b42f032008-12-03 18:43:053896 UnloadListenerSet::iterator iter = std::find(set->begin(), set->end(), tab);
3897 if (iter != set->end()) {
3898 set->erase(iter);
3899 return true;
[email protected]04b4a6c2008-08-02 00:44:473900 }
3901 return false;
3902}
initial.commit09911bf2008-07-26 23:55:293903
[email protected]36b6dcb2008-11-12 01:19:573904void Browser::ClearUnloadState(TabContents* tab) {
[email protected]0b4d3382010-07-14 16:13:043905 // Closing of browser could be canceled (via IsClosingPermitted) between the
3906 // time when request was initiated and when this method is called, so check
3907 // for is_attempting_to_close_browser_ flag before proceeding.
3908 if (is_attempting_to_close_browser_) {
3909 RemoveFromSet(&tabs_needing_before_unload_fired_, tab);
3910 RemoveFromSet(&tabs_needing_unload_fired_, tab);
3911 ProcessPendingTabs();
3912 }
initial.commit09911bf2008-07-26 23:55:293913}
3914
[email protected]f7454892009-01-29 19:24:213915
[email protected]36b6dcb2008-11-12 01:19:573916///////////////////////////////////////////////////////////////////////////////
[email protected]69444cc2009-04-09 20:40:063917// Browser, In-progress download termination handling (private):
3918
3919bool Browser::CanCloseWithInProgressDownloads() {
3920 if (cancel_download_confirmation_state_ != NOT_PROMPTED) {
[email protected]7a22201c2009-10-16 16:50:373921 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) {
3922 // We need to hear from the user before we can close.
3923 return false;
3924 }
3925 // RESPONSE_RECEIVED case, the user decided to go along with the closing.
[email protected]69444cc2009-04-09 20:40:063926 return true;
3927 }
[email protected]446295a2010-04-19 23:43:003928 // Indicated that normal (non-incognito) downloads are pending.
3929 bool normal_downloads_are_present = false;
3930 bool incognito_downloads_are_present = false;
[email protected]69444cc2009-04-09 20:40:063931 // If there are no download in-progress, our job is done.
[email protected]7adf0482010-09-23 18:39:423932 DownloadManager* download_manager = NULL;
3933 // But first we need to check for the existance of the download manager, as
3934 // GetDownloadManager() will unnecessarily try to create one if it does not
3935 // exist.
3936 if (profile_->HasCreatedDownloadManager())
3937 download_manager = profile_->GetDownloadManager();
[email protected]446295a2010-04-19 23:43:003938 if (profile_->IsOffTheRecord()) {
3939 // Browser is incognito and so download_manager if present is for incognito
3940 // downloads.
3941 incognito_downloads_are_present =
3942 (download_manager && download_manager->in_progress_count() != 0);
3943 // Check original profile.
[email protected]7adf0482010-09-23 18:39:423944 if (profile_->GetOriginalProfile()->HasCreatedDownloadManager())
3945 download_manager = profile_->GetOriginalProfile()->GetDownloadManager();
[email protected]446295a2010-04-19 23:43:003946 }
3947
3948 normal_downloads_are_present =
3949 (download_manager && download_manager->in_progress_count() != 0);
3950 if (!normal_downloads_are_present && !incognito_downloads_are_present)
3951 return true;
3952
3953 if (is_attempting_to_close_browser_)
3954 return true;
3955
3956 if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) ||
3957 (!incognito_downloads_are_present && profile()->IsOffTheRecord()))
[email protected]69444cc2009-04-09 20:40:063958 return true;
3959
3960 // Let's figure out if we are the last window for our profile.
3961 // Note that we cannot just use BrowserList::GetBrowserCount as browser
3962 // windows closing is delayed and the returned count might include windows
3963 // that are being closed.
[email protected]446295a2010-04-19 23:43:003964 // The browser allowed to be closed only if:
3965 // 1. It is a regular browser and there are no regular downloads present or
3966 // this is not the last regular browser window.
3967 // 2. It is an incognito browser and there are no incognito downloads present
3968 // or this is not the last incognito browser window.
[email protected]69444cc2009-04-09 20:40:063969 int count = 0;
3970 for (BrowserList::const_iterator iter = BrowserList::begin();
3971 iter != BrowserList::end(); ++iter) {
3972 // Don't count this browser window or any other in the process of closing.
3973 if (*iter == this || (*iter)->is_attempting_to_close_browser_)
3974 continue;
3975
[email protected]446295a2010-04-19 23:43:003976 // Verify that this is not the last non-incognito or incognito browser,
3977 // depending on the pending downloads.
3978 if (normal_downloads_are_present && !profile()->IsOffTheRecord() &&
3979 (*iter)->profile()->IsOffTheRecord())
3980 continue;
3981 if (incognito_downloads_are_present && profile()->IsOffTheRecord() &&
3982 !(*iter)->profile()->IsOffTheRecord())
3983 continue;
3984
[email protected]69444cc2009-04-09 20:40:063985 // We test the original profile, because an incognito browser window keeps
3986 // the original profile alive (and its DownloadManager).
3987 // We also need to test explicitly the profile directly so that 2 incognito
3988 // profiles count as a match.
3989 if ((*iter)->profile() == profile() ||
3990 (*iter)->profile()->GetOriginalProfile() == profile())
3991 count++;
3992 }
3993 if (count > 0)
3994 return true;
3995
3996 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
3997 window_->ConfirmBrowserCloseWithPendingDownloads();
3998
3999 // Return false so the browser does not close. We'll close if the user
4000 // confirms in the dialog.
4001 return false;
4002}
4003
4004///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574005// Browser, Assorted utility functions (private):
initial.commit09911bf2008-07-26 23:55:294006
[email protected]1a6b30a2009-08-19 03:52:114007// static
[email protected]de4e7632010-09-01 06:24:044008Browser* Browser::GetTabbedBrowser(Profile* profile, bool match_incognito) {
4009 return BrowserList::FindBrowserWithType(profile, TYPE_NORMAL,
4010 match_incognito);
4011}
4012
4013// static
[email protected]1a6b30a2009-08-19 03:52:114014Browser* Browser::GetOrCreateTabbedBrowser(Profile* profile) {
[email protected]de4e7632010-09-01 06:24:044015 Browser* browser = GetTabbedBrowser(profile, false);
[email protected]15952e462008-11-14 00:29:054016 if (!browser)
[email protected]1a6b30a2009-08-19 03:52:114017 browser = Browser::Create(profile);
initial.commit09911bf2008-07-26 23:55:294018 return browser;
4019}
4020
[email protected]4f3dc372009-02-24 00:10:294021void Browser::FindInPage(bool find_next, bool forward_direction) {
[email protected]4801ecc2009-04-05 04:52:584022 ShowFindBar();
[email protected]4f3dc372009-02-24 00:10:294023 if (find_next) {
[email protected]6a4f5af22009-09-23 22:43:004024 string16 find_text;
4025#if defined(OS_MACOSX)
4026 // We always want to search for the contents of the find pasteboard on OS X.
4027 find_text = GetFindPboardText();
4028#endif
4029 GetSelectedTabContents()->StartFinding(find_text,
[email protected]e491f1c2009-05-22 20:28:124030 forward_direction,
4031 false); // Not case sensitive.
[email protected]4f3dc372009-02-24 00:10:294032 }
[email protected]fbd77592008-11-12 20:50:274033}
[email protected]cb17f7f2009-02-06 18:14:484034
[email protected]36b6dcb2008-11-12 01:19:574035void Browser::CloseFrame() {
4036 window_->Close();
initial.commit09911bf2008-07-26 23:55:294037}
4038
[email protected]3c9e1872010-11-18 16:17:494039void Browser::TabDetachedAtImpl(TabContentsWrapper* contents, int index,
[email protected]c37e3b62010-01-22 00:15:174040 DetachType type) {
4041 if (type == DETACH_TYPE_DETACH) {
[email protected]56580852010-11-17 16:09:154042 // Save the current location bar state, but only if the tab being detached
4043 // is the selected tab. Because saving state can conditionally revert the
4044 // location bar, saving the current tab's location bar state to a
4045 // non-selected tab can corrupt both tabs.
[email protected]3c9e1872010-11-18 16:17:494046 if (contents == GetSelectedTabContentsWrapper())
4047 window_->GetLocationBar()->SaveStateToContents(contents->tab_contents());
[email protected]c37e3b62010-01-22 00:15:174048
[email protected]ecc523f62010-09-28 22:45:404049 if (!tab_handler_->GetTabStripModel()->closing_all())
[email protected]c37e3b62010-01-22 00:15:174050 SyncHistoryWithTabs(0);
4051 }
4052
[email protected]3c9e1872010-11-18 16:17:494053 contents->tab_contents()->set_delegate(NULL);
4054 RemoveScheduledUpdatesFor(contents->tab_contents());
[email protected]c37e3b62010-01-22 00:15:174055
[email protected]ecc523f62010-09-28 22:45:404056 if (find_bar_controller_.get() &&
4057 index == tab_handler_->GetTabStripModel()->selected_index()) {
[email protected]c37e3b62010-01-22 00:15:174058 find_bar_controller_->ChangeTabContents(NULL);
[email protected]ecc523f62010-09-28 22:45:404059 }
[email protected]c37e3b62010-01-22 00:15:174060
4061 registrar_.Remove(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
[email protected]3c9e1872010-11-18 16:17:494062 Source<TabContentsWrapper>(contents));
[email protected]c37e3b62010-01-22 00:15:174063}
4064
initial.commit09911bf2008-07-26 23:55:294065// static
[email protected]57ecc4b2010-08-11 03:02:514066void Browser::RegisterAppPrefs(const std::string& app_name) {
initial.commit09911bf2008-07-26 23:55:294067 // A set of apps that we've already started.
[email protected]57ecc4b2010-08-11 03:02:514068 static std::set<std::string>* g_app_names = NULL;
initial.commit09911bf2008-07-26 23:55:294069
4070 if (!g_app_names)
[email protected]57ecc4b2010-08-11 03:02:514071 g_app_names = new std::set<std::string>;
initial.commit09911bf2008-07-26 23:55:294072
4073 // Only register once for each app name.
4074 if (g_app_names->find(app_name) != g_app_names->end())
4075 return;
4076 g_app_names->insert(app_name);
4077
4078 // We need to register the window position pref.
[email protected]57ecc4b2010-08-11 03:02:514079 std::string window_pref(prefs::kBrowserWindowPlacement);
4080 window_pref.append("_");
initial.commit09911bf2008-07-26 23:55:294081 window_pref.append(app_name);
4082 PrefService* prefs = g_browser_process->local_state();
4083 DCHECK(prefs);
4084
4085 prefs->RegisterDictionaryPref(window_pref.c_str());
4086}
[email protected]5c238752009-06-13 10:29:074087
[email protected]281918912010-05-27 22:05:134088void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
4089 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
4090 !service->entries().empty());
4091}
4092
4093void Browser::TabRestoreServiceDestroyed(TabRestoreService* service) {
4094 if (!tab_restore_service_)
4095 return;
4096
4097 DCHECK_EQ(tab_restore_service_, service);
4098 tab_restore_service_->RemoveObserver(this);
4099 tab_restore_service_ = NULL;
4100}
[email protected]97b6c4f2010-09-27 19:31:264101
[email protected]3c9e1872010-11-18 16:17:494102// Centralized method for creating a TabContents, configuring and installing
4103// all its supporting objects and observers.
4104TabContentsWrapper* Browser::TabContentsFactory(
4105 Profile* profile,
4106 SiteInstance* site_instance,
4107 int routing_id,
4108 const TabContents* base_tab_contents,
4109 SessionStorageNamespace* session_storage_namespace) {
4110 TabContents* new_contents = new TabContents(profile, site_instance,
4111 routing_id, base_tab_contents,
4112 session_storage_namespace);
4113 TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
4114 return wrapper;
4115}
4116
[email protected]6b723f82010-10-05 20:14:274117bool Browser::OpenInstant(WindowOpenDisposition disposition) {
[email protected]0a387472010-10-07 00:18:204118 if (!instant() || !instant()->is_active() || !instant()->IsCurrent())
[email protected]97b6c4f2010-09-27 19:31:264119 return false;
4120
4121 if (disposition == CURRENT_TAB) {
[email protected]6b723f82010-10-05 20:14:274122 instant()->CommitCurrentPreview(INSTANT_COMMIT_PRESSED_ENTER);
[email protected]97b6c4f2010-09-27 19:31:264123 return true;
4124 }
4125 if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) {
[email protected]6b723f82010-10-05 20:14:274126 HideInstant();
[email protected]3c9e1872010-11-18 16:17:494127 TabContentsWrapper* preview_contents = instant()->ReleasePreviewContents(
[email protected]6b723f82010-10-05 20:14:274128 INSTANT_COMMIT_PRESSED_ENTER);
[email protected]97b6c4f2010-09-27 19:31:264129 preview_contents->controller().PruneAllButActive();
[email protected]ecc523f62010-09-28 22:45:404130 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]97b6c4f2010-09-27 19:31:264131 preview_contents,
4132 -1,
[email protected]6b723f82010-10-05 20:14:274133 instant()->last_transition_type(),
[email protected]97b6c4f2010-09-27 19:31:264134 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_SELECTED :
4135 TabStripModel::ADD_NONE);
[email protected]3c9e1872010-11-18 16:17:494136 instant()->CompleteRelease(preview_contents->tab_contents());
[email protected]97b6c4f2010-09-27 19:31:264137 return true;
4138 }
4139 // The omnibox currently doesn't use other dispositions, so we don't attempt
4140 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add
4141 // support for the new disposition.
4142 NOTREACHED();
4143 return false;
4144}
[email protected]2031cf9d2010-10-12 05:05:374145
4146void Browser::CreateInstantIfNecessary() {
[email protected]73de26a2010-10-17 03:23:254147 if (type() == TYPE_NORMAL && InstantController::IsEnabled(profile()) &&
[email protected]2031cf9d2010-10-12 05:05:374148 !profile()->IsOffTheRecord()) {
[email protected]fdf773c52010-11-01 20:58:194149 instant_.reset(new InstantController(profile_, this));
[email protected]2031cf9d2010-10-12 05:05:374150 }
4151}