| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/browser.h" | 5 #include "chrome/browser/ui/browser_command_controller.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | |
| 8 #include <windows.h> | |
| 9 #include <shellapi.h> | |
| 10 #endif // OS_WIN | |
| 11 | |
| 12 #include <algorithm> | |
| 13 #include <string> | |
| 14 | |
| 15 #include "base/base_paths.h" | |
| 16 #include "base/bind.h" | |
| 17 #include "base/command_line.h" | |
| 18 #include "base/logging.h" | |
| 19 #include "base/metrics/field_trial.h" | |
| 20 #include "base/metrics/histogram.h" | |
| 21 #include "base/path_service.h" | |
| 22 #include "base/string_number_conversions.h" | |
| 23 #include "base/string_util.h" | |
| 24 #include "base/stringprintf.h" | |
| 25 #include "base/threading/thread.h" | |
| 26 #include "base/threading/thread_restrictions.h" | |
| 27 #include "base/time.h" | |
| 28 #include "base/utf_string_conversions.h" | |
| 29 #include "chrome/app/chrome_command_ids.h" | 7 #include "chrome/app/chrome_command_ids.h" |
| 30 #include "chrome/browser/autofill/personal_data_manager_factory.h" | |
| 31 #include "chrome/browser/background/background_contents_service.h" | |
| 32 #include "chrome/browser/background/background_contents_service_factory.h" | |
| 33 #include "chrome/browser/bookmarks/bookmark_model.h" | |
| 34 #include "chrome/browser/bookmarks/bookmark_utils.h" | |
| 35 #include "chrome/browser/browser_process.h" | 8 #include "chrome/browser/browser_process.h" |
| 36 #include "chrome/browser/browser_shutdown.h" | 9 #include "chrome/browser/defaults.h" |
| 37 #include "chrome/browser/character_encoding.h" | |
| 38 #include "chrome/browser/chrome_page_zoom.h" | |
| 39 #include "chrome/browser/content_settings/host_content_settings_map.h" | |
| 40 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" | |
| 41 #include "chrome/browser/custom_handlers/register_protocol_handler_infobar_deleg
ate.h" | |
| 42 #include "chrome/browser/debugger/devtools_toggle_action.h" | |
| 43 #include "chrome/browser/debugger/devtools_window.h" | |
| 44 #include "chrome/browser/download/download_crx_util.h" | |
| 45 #include "chrome/browser/download/download_item_model.h" | |
| 46 #include "chrome/browser/download/download_service.h" | |
| 47 #include "chrome/browser/download/download_service_factory.h" | |
| 48 #include "chrome/browser/download/download_shelf.h" | |
| 49 #include "chrome/browser/download/download_started_animation.h" | |
| 50 #include "chrome/browser/download/download_util.h" | |
| 51 #include "chrome/browser/extensions/browser_extension_window_controller.h" | |
| 52 #include "chrome/browser/extensions/crx_installer.h" | |
| 53 #include "chrome/browser/extensions/default_apps_trial.h" | |
| 54 #include "chrome/browser/extensions/extension_prefs.h" | |
| 55 #include "chrome/browser/extensions/extension_service.h" | 10 #include "chrome/browser/extensions/extension_service.h" |
| 56 #include "chrome/browser/extensions/extension_tab_helper.h" | |
| 57 #include "chrome/browser/favicon/favicon_tab_helper.h" | |
| 58 #include "chrome/browser/file_select_helper.h" | |
| 59 #include "chrome/browser/first_run/first_run.h" | |
| 60 #include "chrome/browser/google/google_url_tracker.h" | |
| 61 #include "chrome/browser/infobars/infobar_tab_helper.h" | |
| 62 #include "chrome/browser/instant/instant_controller.h" | |
| 63 #include "chrome/browser/instant/instant_unload_handler.h" | |
| 64 #include "chrome/browser/intents/register_intent_handler_infobar_delegate.h" | |
| 65 #include "chrome/browser/intents/web_intents_util.h" | |
| 66 #include "chrome/browser/lifetime/application_lifetime.h" | |
| 67 #include "chrome/browser/media/media_stream_devices_controller.h" | |
| 68 #include "chrome/browser/net/url_fixer_upper.h" | |
| 69 #include "chrome/browser/notifications/notification_ui_manager.h" | |
| 70 #include "chrome/browser/platform_util.h" | |
| 71 #include "chrome/browser/prefs/incognito_mode_prefs.h" | 11 #include "chrome/browser/prefs/incognito_mode_prefs.h" |
| 72 #include "chrome/browser/prefs/pref_service.h" | 12 #include "chrome/browser/prefs/pref_service.h" |
| 73 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h" | |
| 74 #include "chrome/browser/printing/print_preview_tab_controller.h" | 13 #include "chrome/browser/printing/print_preview_tab_controller.h" |
| 75 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
| 76 #include "chrome/browser/profiles/profile_destroyer.h" | |
| 77 #include "chrome/browser/profiles/profile_manager.h" | 15 #include "chrome/browser/profiles/profile_manager.h" |
| 78 #include "chrome/browser/profiles/profile_metrics.h" | |
| 79 #include "chrome/browser/repost_form_warning_controller.h" | |
| 80 #include "chrome/browser/sessions/restore_tab_helper.h" | |
| 81 #include "chrome/browser/sessions/session_service.h" | |
| 82 #include "chrome/browser/sessions/session_service_factory.h" | |
| 83 #include "chrome/browser/sessions/session_types.h" | |
| 84 #include "chrome/browser/sessions/tab_restore_service.h" | 16 #include "chrome/browser/sessions/tab_restore_service.h" |
| 85 #include "chrome/browser/sessions/tab_restore_service_factory.h" | 17 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
| 86 #include "chrome/browser/sync/profile_sync_service.h" | 18 #include "chrome/browser/sync/profile_sync_service.h" |
| 87 #include "chrome/browser/sync/profile_sync_service_factory.h" | 19 #include "chrome/browser/sync/profile_sync_service_factory.h" |
| 88 #include "chrome/browser/sync/sync_ui_util.h" | |
| 89 #include "chrome/browser/tab_contents/background_contents.h" | |
| 90 #include "chrome/browser/tab_contents/retargeting_details.h" | |
| 91 #include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h" | |
| 92 #include "chrome/browser/tab_contents/tab_util.h" | |
| 93 #include "chrome/browser/themes/theme_service.h" | |
| 94 #include "chrome/browser/themes/theme_service_factory.h" | |
| 95 #include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h" | |
| 96 #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" | |
| 97 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" | 20 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" |
| 21 #include "chrome/browser/ui/browser.h" |
| 98 #include "chrome/browser/ui/browser_commands.h" | 22 #include "chrome/browser/ui/browser_commands.h" |
| 99 #include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h" | |
| 100 #include "chrome/browser/ui/browser_dialogs.h" | |
| 101 #include "chrome/browser/ui/browser_finder.h" | |
| 102 #include "chrome/browser/ui/browser_list.h" | |
| 103 #include "chrome/browser/ui/browser_navigator.h" | |
| 104 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h" | |
| 105 #include "chrome/browser/ui/browser_toolbar_model_delegate.h" | |
| 106 #include "chrome/browser/ui/browser_ui_prefs.h" | |
| 107 #include "chrome/browser/ui/browser_window.h" | 23 #include "chrome/browser/ui/browser_window.h" |
| 108 #include "chrome/browser/ui/chrome_pages.h" | 24 #include "chrome/browser/ui/chrome_pages.h" |
| 109 #include "chrome/browser/ui/constrained_window_tab_helper.h" | |
| 110 #include "chrome/browser/ui/extensions/shell_window.h" | |
| 111 #include "chrome/browser/ui/find_bar/find_bar.h" | |
| 112 #include "chrome/browser/ui/find_bar/find_bar_controller.h" | |
| 113 #include "chrome/browser/ui/find_bar/find_tab_helper.h" | |
| 114 #include "chrome/browser/ui/fullscreen_controller.h" | |
| 115 #include "chrome/browser/ui/global_error.h" | |
| 116 #include "chrome/browser/ui/global_error_service.h" | |
| 117 #include "chrome/browser/ui/global_error_service_factory.h" | |
| 118 #include "chrome/browser/ui/hung_plugin_tab_helper.h" | |
| 119 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" | |
| 120 #include "chrome/browser/ui/media_stream_infobar_delegate.h" | |
| 121 #include "chrome/browser/ui/omnibox/location_bar.h" | |
| 122 #include "chrome/browser/ui/panels/panel.h" | |
| 123 #include "chrome/browser/ui/panels/panel_manager.h" | |
| 124 #include "chrome/browser/ui/search/search.h" | |
| 125 #include "chrome/browser/ui/search/search_delegate.h" | |
| 126 #include "chrome/browser/ui/search/search_model.h" | |
| 127 #include "chrome/browser/ui/search_engines/search_engine_tab_helper.h" | |
| 128 #include "chrome/browser/ui/singleton_tabs.h" | |
| 129 #include "chrome/browser/ui/status_bubble.h" | |
| 130 #include "chrome/browser/ui/sync/browser_synced_window_delegate.h" | |
| 131 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" | |
| 132 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 25 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 133 #include "chrome/browser/ui/tabs/dock_info.h" | |
| 134 #include "chrome/browser/ui/tabs/tab_menu_model.h" | |
| 135 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 26 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 136 #include "chrome/browser/ui/web_applications/web_app_ui.h" | 27 #include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h" |
| 137 #include "chrome/browser/ui/webui/feedback_ui.h" | |
| 138 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" | |
| 139 #include "chrome/browser/ui/webui/signin/login_ui_service.h" | |
| 140 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" | |
| 141 #include "chrome/browser/ui/window_sizer.h" | |
| 142 #include "chrome/browser/upgrade_detector.h" | |
| 143 #include "chrome/browser/web_applications/web_app.h" | |
| 144 #include "chrome/common/chrome_constants.h" | |
| 145 #include "chrome/common/chrome_notification_types.h" | 28 #include "chrome/common/chrome_notification_types.h" |
| 146 #include "chrome/common/chrome_switches.h" | |
| 147 #include "chrome/common/custom_handlers/protocol_handler.h" | |
| 148 #include "chrome/common/extensions/extension.h" | |
| 149 #include "chrome/common/extensions/extension_constants.h" | |
| 150 #include "chrome/common/pref_names.h" | 29 #include "chrome/common/pref_names.h" |
| 151 #include "chrome/common/profiling.h" | 30 #include "chrome/common/profiling.h" |
| 152 #include "chrome/common/url_constants.h" | 31 #include "content/public/browser/native_web_keyboard_event.h" |
| 153 #include "chrome/common/web_apps.h" | |
| 154 #include "content/public/browser/color_chooser.h" | |
| 155 #include "content/public/browser/devtools_manager.h" | |
| 156 #include "content/public/browser/download_item.h" | |
| 157 #include "content/public/browser/download_manager.h" | |
| 158 #include "content/public/browser/interstitial_page.h" | |
| 159 #include "content/public/browser/invalidate_type.h" | |
| 160 #include "content/public/browser/navigation_controller.h" | 32 #include "content/public/browser/navigation_controller.h" |
| 161 #include "content/public/browser/navigation_entry.h" | 33 #include "content/public/browser/navigation_entry.h" |
| 162 #include "content/public/browser/notification_details.h" | 34 #include "content/public/browser/notification_details.h" |
| 163 #include "content/public/browser/notification_service.h" | 35 #include "content/public/browser/notification_source.h" |
| 164 #include "content/public/browser/plugin_service.h" | |
| 165 #include "content/public/browser/render_process_host.h" | |
| 166 #include "content/public/browser/render_view_host.h" | |
| 167 #include "content/public/browser/site_instance.h" | |
| 168 #include "content/public/browser/user_metrics.h" | |
| 169 #include "content/public/browser/web_contents.h" | 36 #include "content/public/browser/web_contents.h" |
| 170 #include "content/public/browser/web_contents_view.h" | |
| 171 #include "content/public/browser/web_intents_dispatcher.h" | |
| 172 #include "content/public/common/content_restriction.h" | 37 #include "content/public/common/content_restriction.h" |
| 173 #include "content/public/common/content_switches.h" | 38 #include "content/public/common/url_constants.h" |
| 174 #include "content/public/common/page_zoom.h" | 39 #include "ui/base/keycodes/keyboard_codes.h" |
| 175 #include "content/public/common/renderer_preferences.h" | |
| 176 #include "grit/chromium_strings.h" | |
| 177 #include "grit/generated_resources.h" | |
| 178 #include "grit/locale_settings.h" | |
| 179 #include "grit/theme_resources_standard.h" | |
| 180 #include "net/base/net_util.h" | |
| 181 #include "net/base/registry_controlled_domain.h" | |
| 182 #include "net/cookies/cookie_monster.h" | |
| 183 #include "net/url_request/url_request_context.h" | |
| 184 #include "ui/base/animation/animation.h" | |
| 185 #include "ui/base/l10n/l10n_util.h" | |
| 186 #include "ui/gfx/point.h" | |
| 187 #include "webkit/glue/web_intent_data.h" | |
| 188 #include "webkit/glue/web_intent_service_data.h" | |
| 189 #include "webkit/glue/webkit_glue.h" | |
| 190 #include "webkit/glue/window_open_disposition.h" | |
| 191 #include "webkit/plugins/webplugininfo.h" | |
| 192 | 40 |
| 193 #if defined(OS_WIN) | 41 #if defined(OS_WIN) |
| 194 #include "base/win/metro.h" | 42 #include "base/win/metro.h" |
| 195 #include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h" | |
| 196 #include "chrome/browser/shell_integration.h" | |
| 197 #include "chrome/browser/ssl/ssl_error_info.h" | |
| 198 #include "chrome/browser/task_manager/task_manager.h" | |
| 199 #include "chrome/browser/ui/view_ids.h" | |
| 200 #include "ui/base/win/shell.h" | |
| 201 #endif // OS_WIN | |
| 202 | |
| 203 #if defined(OS_CHROMEOS) | |
| 204 #include "chrome/browser/chromeos/gdata/gdata_util.h" | |
| 205 #endif | 43 #endif |
| 206 | 44 |
| 207 #if defined(USE_ASH) | 45 using content::WebContents; |
| 208 #include "ash/ash_switches.h" | 46 using content::NavigationEntry; |
| 209 #endif | |
| 210 | |
| 211 using base::TimeDelta; | |
| 212 using content::NativeWebKeyboardEvent; | |
| 213 using content::NavigationController; | 47 using content::NavigationController; |
| 214 using content::NavigationEntry; | |
| 215 using content::OpenURLParams; | |
| 216 using content::PluginService; | |
| 217 using content::Referrer; | |
| 218 using content::SiteInstance; | |
| 219 using content::UserMetricsAction; | |
| 220 using content::WebContents; | 48 using content::WebContents; |
| 221 using extensions::Extension; | |
| 222 using ui::WebDialogDelegate; | |
| 223 | |
| 224 /////////////////////////////////////////////////////////////////////////////// | |
| 225 | 49 |
| 226 namespace { | 50 namespace { |
| 227 | 51 |
| 228 // The URL to be loaded to display the "Report a broken page" form. | |
| 229 const char kBrokenPageUrl[] = | |
| 230 "https://www.google.com/support/chrome/bin/request.py?contact_type=" | |
| 231 "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2"; | |
| 232 | |
| 233 // The URL for the privacy dashboard. | |
| 234 const char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard"; | |
| 235 | |
| 236 // How long we wait before updating the browser chrome while loading a page. | |
| 237 const int kUIUpdateCoalescingTimeMS = 200; | |
| 238 | |
| 239 // Returns |true| if entry has an internal chrome:// URL, |false| otherwise. | 52 // Returns |true| if entry has an internal chrome:// URL, |false| otherwise. |
| 240 bool HasInternalURL(const NavigationEntry* entry) { | 53 bool HasInternalURL(const NavigationEntry* entry) { |
| 241 if (!entry) | 54 if (!entry) |
| 242 return false; | 55 return false; |
| 243 | 56 |
| 244 // Check the |virtual_url()| first. This catches regular chrome:// URLs | 57 // Check the |virtual_url()| first. This catches regular chrome:// URLs |
| 245 // including URLs that were rewritten (such as chrome://bookmarks). | 58 // including URLs that were rewritten (such as chrome://bookmarks). |
| 246 if (entry->GetVirtualURL().SchemeIs(chrome::kChromeUIScheme)) | 59 if (entry->GetVirtualURL().SchemeIs(chrome::kChromeUIScheme)) |
| 247 return true; | 60 return true; |
| 248 | 61 |
| 249 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually | 62 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually |
| 250 // view-source: of a chrome:// URL. | 63 // view-source: of a chrome:// URL. |
| 251 if (entry->GetVirtualURL().SchemeIs(chrome::kViewSourceScheme)) | 64 if (entry->GetVirtualURL().SchemeIs(chrome::kViewSourceScheme)) |
| 252 return entry->GetURL().SchemeIs(chrome::kChromeUIScheme); | 65 return entry->GetURL().SchemeIs(chrome::kChromeUIScheme); |
| 253 | 66 |
| 254 return false; | 67 return false; |
| 255 } | 68 } |
| 256 | 69 |
| 257 bool AllowPanels(const std::string& app_name) { | |
| 258 return PanelManager::ShouldUsePanels( | |
| 259 web_app::GetExtensionIdFromApplicationName(app_name)); | |
| 260 } | |
| 261 | |
| 262 } // namespace | 70 } // namespace |
| 263 | 71 |
| 264 //////////////////////////////////////////////////////////////////////////////// | 72 namespace chrome { |
| 265 // Browser, CreateParams: | |
| 266 | |
| 267 Browser::CreateParams::CreateParams() | |
| 268 : type(TYPE_TABBED), | |
| 269 profile(NULL), | |
| 270 initial_show_state(ui::SHOW_STATE_DEFAULT), | |
| 271 is_session_restore(false) { | |
| 272 } | |
| 273 | |
| 274 Browser::CreateParams::CreateParams(Type type, Profile* profile) | |
| 275 : type(type), | |
| 276 profile(profile), | |
| 277 app_type(APP_TYPE_HOST), | |
| 278 initial_show_state(ui::SHOW_STATE_DEFAULT), | |
| 279 is_session_restore(false) { | |
| 280 } | |
| 281 | |
| 282 // static | |
| 283 Browser::CreateParams Browser::CreateParams::CreateForApp( | |
| 284 Type type, | |
| 285 const std::string& app_name, | |
| 286 const gfx::Rect& window_bounds, | |
| 287 Profile* profile) { | |
| 288 DCHECK(type != TYPE_TABBED); | |
| 289 DCHECK(!app_name.empty()); | |
| 290 | |
| 291 if (type == TYPE_PANEL && !AllowPanels(app_name)) | |
| 292 type = TYPE_POPUP; | |
| 293 | |
| 294 CreateParams params(type, profile); | |
| 295 params.app_name = app_name; | |
| 296 params.app_type = APP_TYPE_CHILD; | |
| 297 params.initial_bounds = window_bounds; | |
| 298 | |
| 299 return params; | |
| 300 } | |
| 301 | |
| 302 // static | |
| 303 Browser::CreateParams Browser::CreateParams::CreateForDevTools( | |
| 304 Profile* profile) { | |
| 305 CreateParams params(TYPE_POPUP, profile); | |
| 306 params.app_name = DevToolsWindow::kDevToolsApp; | |
| 307 return params; | |
| 308 } | |
| 309 | 73 |
| 310 /////////////////////////////////////////////////////////////////////////////// | 74 /////////////////////////////////////////////////////////////////////////////// |
| 311 // Browser, Constructors, Creation, Showing: | 75 // BrowserCommandController, public: |
| 312 | 76 |
| 313 Browser::Browser(Type type, Profile* profile) | 77 BrowserCommandController::BrowserCommandController(Browser* browser) |
| 314 : type_(type), | 78 : browser_(browser), |
| 315 profile_(profile), | 79 ALLOW_THIS_IN_INITIALIZER_LIST(command_updater_(this)), |
| 316 window_(NULL), | |
| 317 ALLOW_THIS_IN_INITIALIZER_LIST( | |
| 318 tab_strip_model_(new TabStripModel(this, profile))), | |
| 319 command_updater_(this), | |
| 320 app_type_(APP_TYPE_HOST), | |
| 321 chrome_updater_factory_(this), | |
| 322 is_attempting_to_close_browser_(false), | |
| 323 cancel_download_confirmation_state_(NOT_PROMPTED), | |
| 324 initial_show_state_(ui::SHOW_STATE_DEFAULT), | |
| 325 is_session_restore_(false), | |
| 326 weak_factory_(this), | |
| 327 block_command_execution_(false), | 80 block_command_execution_(false), |
| 328 last_blocked_command_id_(-1), | 81 last_blocked_command_id_(-1), |
| 329 last_blocked_command_disposition_(CURRENT_TAB), | 82 last_blocked_command_disposition_(CURRENT_TAB) { |
| 330 pending_web_app_action_(NONE), | 83 browser_->tab_strip_model()->AddObserver(this); |
| 331 ALLOW_THIS_IN_INITIALIZER_LIST( | |
| 332 content_setting_bubble_model_delegate_( | |
| 333 new BrowserContentSettingBubbleModelDelegate(this))), | |
| 334 ALLOW_THIS_IN_INITIALIZER_LIST( | |
| 335 toolbar_model_delegate_( | |
| 336 new BrowserToolbarModelDelegate(this))), | |
| 337 ALLOW_THIS_IN_INITIALIZER_LIST( | |
| 338 tab_restore_service_delegate_( | |
| 339 new BrowserTabRestoreServiceDelegate(this))), | |
| 340 ALLOW_THIS_IN_INITIALIZER_LIST( | |
| 341 synced_window_delegate_( | |
| 342 new BrowserSyncedWindowDelegate(this))), | |
| 343 bookmark_bar_state_(BookmarkBar::HIDDEN), | |
| 344 window_has_shown_(false) { | |
| 345 tab_strip_model_->AddObserver(this); | |
| 346 | |
| 347 toolbar_model_.reset(new ToolbarModel(toolbar_model_delegate_.get())); | |
| 348 search_model_.reset(new chrome::search::SearchModel(NULL)); | |
| 349 search_delegate_.reset( | |
| 350 new chrome::search::SearchDelegate(search_model_.get())); | |
| 351 | |
| 352 registrar_.Add(this, content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED, | |
| 353 content::NotificationService::AllSources()); | |
| 354 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | |
| 355 content::Source<Profile>(profile_->GetOriginalProfile())); | |
| 356 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | |
| 357 content::Source<Profile>(profile_->GetOriginalProfile())); | |
| 358 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED, | |
| 359 content::Source<Profile>(profile_->GetOriginalProfile())); | |
| 360 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, | |
| 361 content::NotificationService::AllSources()); | |
| 362 #if defined(ENABLE_THEMES) | |
| 363 registrar_.Add( | |
| 364 this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, | |
| 365 content::Source<ThemeService>( | |
| 366 ThemeServiceFactory::GetForProfile(profile_))); | |
| 367 #endif | |
| 368 registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, | |
| 369 content::NotificationService::AllSources()); | |
| 370 | |
| 371 PrefService* local_state = g_browser_process->local_state(); | 84 PrefService* local_state = g_browser_process->local_state(); |
| 372 if (local_state) { | 85 if (local_state) { |
| 373 local_pref_registrar_.Init(local_state); | 86 local_pref_registrar_.Init(local_state); |
| 374 local_pref_registrar_.Add(prefs::kPrintingEnabled, this); | 87 local_pref_registrar_.Add(prefs::kPrintingEnabled, this); |
| 375 local_pref_registrar_.Add(prefs::kAllowFileSelectionDialogs, this); | 88 local_pref_registrar_.Add(prefs::kAllowFileSelectionDialogs, this); |
| 376 local_pref_registrar_.Add(prefs::kInManagedMode, this); | 89 local_pref_registrar_.Add(prefs::kInManagedMode, this); |
| 377 } | 90 } |
| 378 | 91 |
| 379 profile_pref_registrar_.Init(profile_->GetPrefs()); | 92 profile_pref_registrar_.Init(profile()->GetPrefs()); |
| 380 profile_pref_registrar_.Add(prefs::kDevToolsDisabled, this); | 93 profile_pref_registrar_.Add(prefs::kDevToolsDisabled, this); |
| 381 profile_pref_registrar_.Add(prefs::kEditBookmarksEnabled, this); | 94 profile_pref_registrar_.Add(prefs::kEditBookmarksEnabled, this); |
| 382 profile_pref_registrar_.Add(prefs::kShowBookmarkBar, this); | 95 profile_pref_registrar_.Add(prefs::kShowBookmarkBar, this); |
| 383 profile_pref_registrar_.Add(prefs::kHomePage, this); | |
| 384 profile_pref_registrar_.Add(prefs::kInstantEnabled, this); | |
| 385 profile_pref_registrar_.Add(prefs::kIncognitoModeAvailability, this); | 96 profile_pref_registrar_.Add(prefs::kIncognitoModeAvailability, this); |
| 386 | 97 |
| 387 InitCommandState(); | 98 InitCommandState(); |
| 388 BrowserList::AddBrowser(this); | |
| 389 | 99 |
| 390 // NOTE: These prefs all need to be explicitly destroyed in the destructor | 100 TabRestoreService* tab_restore_service = |
| 391 // or you'll get a nasty surprise when you run the incognito tests. | 101 TabRestoreServiceFactory::GetForProfile(profile()); |
| 392 encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector, | 102 if (tab_restore_service) { |
| 393 profile_->GetPrefs(), NULL); | 103 tab_restore_service->AddObserver(this); |
| 394 | 104 TabRestoreServiceChanged(tab_restore_service); |
| 395 tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile); | |
| 396 if (tab_restore_service_) { | |
| 397 tab_restore_service_->AddObserver(this); | |
| 398 TabRestoreServiceChanged(tab_restore_service_); | |
| 399 } | 105 } |
| 400 | 106 |
| 401 ProfileSyncService* service = | 107 ProfileSyncService* service = |
| 402 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_); | 108 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile()); |
| 403 if (service) | 109 if (service) |
| 404 service->AddObserver(this); | 110 service->AddObserver(this); |
| 405 | |
| 406 CreateInstantIfNecessary(); | |
| 407 | |
| 408 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_INIT); | |
| 409 | |
| 410 FilePath profile_path = profile->GetPath(); | |
| 411 ProfileMetrics::LogProfileLaunch(profile_path); | |
| 412 } | 111 } |
| 413 | 112 |
| 414 Browser::~Browser() { | 113 BrowserCommandController::~BrowserCommandController() { |
| 415 ProfileSyncService* service = | 114 ProfileSyncService* service = |
| 416 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_); | 115 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile()); |
| 417 if (service) | 116 if (service) |
| 418 service->RemoveObserver(this); | 117 service->RemoveObserver(this); |
| 419 | 118 |
| 420 // The tab strip should not have any tabs at this point. | |
| 421 if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers()) | |
| 422 DCHECK(tab_strip_model_->empty()); | |
| 423 tab_strip_model_->RemoveObserver(this); | |
| 424 | |
| 425 BrowserList::RemoveBrowser(this); | |
| 426 | |
| 427 SessionService* session_service = | |
| 428 SessionServiceFactory::GetForProfile(profile_); | |
| 429 if (session_service) | |
| 430 session_service->WindowClosed(session_id_); | |
| 431 | |
| 432 TabRestoreService* tab_restore_service = | 119 TabRestoreService* tab_restore_service = |
| 433 TabRestoreServiceFactory::GetForProfile(profile()); | 120 TabRestoreServiceFactory::GetForProfile(profile()); |
| 434 if (tab_restore_service) | 121 if (tab_restore_service) |
| 435 tab_restore_service->BrowserClosed(tab_restore_service_delegate()); | 122 tab_restore_service->RemoveObserver(this); |
| 436 | |
| 437 #if !defined(OS_MACOSX) | |
| 438 if (!browser::GetBrowserCount(profile_)) { | |
| 439 // We're the last browser window with this profile. We need to nuke the | |
| 440 // TabRestoreService, which will start the shutdown of the | |
| 441 // NavigationControllers and allow for proper shutdown. If we don't do this | |
| 442 // chrome won't shutdown cleanly, and may end up crashing when some | |
| 443 // thread tries to use the IO thread (or another thread) that is no longer | |
| 444 // valid. | |
| 445 // This isn't a valid assumption for Mac OS, as it stays running after | |
| 446 // the last browser has closed. The Mac equivalent is in its app | |
| 447 // controller. | |
| 448 TabRestoreServiceFactory::ResetForProfile(profile_); | |
| 449 } | |
| 450 #endif | |
| 451 | |
| 452 profile_pref_registrar_.RemoveAll(); | 123 profile_pref_registrar_.RemoveAll(); |
| 453 local_pref_registrar_.RemoveAll(); | 124 local_pref_registrar_.RemoveAll(); |
| 454 | 125 browser_->tab_strip_model()->RemoveObserver(this); |
| 455 encoding_auto_detect_.Destroy(); | |
| 456 | |
| 457 if (profile_->IsOffTheRecord() && | |
| 458 !BrowserList::IsOffTheRecordSessionActiveForProfile(profile_)) { | |
| 459 // An incognito profile is no longer needed, this indirectly frees | |
| 460 // its cache and cookies once it gets destroyed at the appropriate time. | |
| 461 ProfileDestroyer::DestroyProfileWhenAppropriate(profile_); | |
| 462 } | |
| 463 | |
| 464 // There may be pending file dialogs, we need to tell them that we've gone | |
| 465 // away so they don't try and call back to us. | |
| 466 if (select_file_dialog_.get()) | |
| 467 select_file_dialog_->ListenerDestroyed(); | |
| 468 | |
| 469 TabRestoreServiceDestroyed(tab_restore_service_); | |
| 470 } | 126 } |
| 471 | 127 |
| 472 // static | 128 bool BrowserCommandController::IsReservedCommandOrKey( |
| 473 Browser* Browser::Create(Profile* profile) { | 129 int command_id, |
| 474 Browser* browser = new Browser(TYPE_TABBED, profile); | 130 const content::NativeWebKeyboardEvent& event) { |
| 475 browser->InitBrowserWindow(); | |
| 476 return browser; | |
| 477 } | |
| 478 | |
| 479 // static | |
| 480 Browser* Browser::CreateWithParams(const CreateParams& params) { | |
| 481 if (!params.app_name.empty()) | |
| 482 chrome::RegisterAppPrefs(params.app_name, params.profile); | |
| 483 | |
| 484 Browser* browser = new Browser(params.type, params.profile); | |
| 485 browser->app_name_ = params.app_name; | |
| 486 browser->app_type_ = params.app_type; | |
| 487 browser->set_override_bounds(params.initial_bounds); | |
| 488 browser->set_initial_show_state(params.initial_show_state); | |
| 489 browser->set_is_session_restore(params.is_session_restore); | |
| 490 | |
| 491 browser->InitBrowserWindow(); | |
| 492 return browser; | |
| 493 } | |
| 494 | |
| 495 void Browser::InitBrowserWindow() { | |
| 496 DCHECK(!window_); | |
| 497 | |
| 498 window_ = CreateBrowserWindow(); | |
| 499 fullscreen_controller_ = new FullscreenController(window_, profile_, this); | |
| 500 | |
| 501 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 502 // Set the app user model id for this application to that of the application | |
| 503 // name. See http://crbug.com/7028. | |
| 504 ui::win::SetAppIdForWindow( | |
| 505 is_app() && !is_type_panel() ? | |
| 506 ShellIntegration::GetAppModelIdForProfile(UTF8ToWide(app_name_), | |
| 507 profile_->GetPath()) : | |
| 508 ShellIntegration::GetChromiumModelIdForProfile(profile_->GetPath()), | |
| 509 window()->GetNativeWindow()); | |
| 510 | |
| 511 if (is_type_panel()) { | |
| 512 ui::win::SetAppIconForWindow(ShellIntegration::GetChromiumIconPath(), | |
| 513 window()->GetNativeWindow()); | |
| 514 } | |
| 515 #endif | |
| 516 | |
| 517 // Create the extension window controller before sending notifications. | |
| 518 extension_window_controller_.reset( | |
| 519 new BrowserExtensionWindowController(this)); | |
| 520 | |
| 521 content::NotificationService::current()->Notify( | |
| 522 chrome::NOTIFICATION_BROWSER_WINDOW_READY, | |
| 523 content::Source<Browser>(this), | |
| 524 content::NotificationService::NoDetails()); | |
| 525 | |
| 526 PrefService* local_state = g_browser_process->local_state(); | |
| 527 if (local_state && local_state->FindPreference( | |
| 528 prefs::kAutofillPersonalDataManagerFirstRun) && | |
| 529 local_state->GetBoolean(prefs::kAutofillPersonalDataManagerFirstRun)) { | |
| 530 // Notify PDM that this is a first run. | |
| 531 #if defined(OS_WIN) | |
| 532 ImportAutofillDataWin(PersonalDataManagerFactory::GetForProfile(profile_)); | |
| 533 #endif // defined(OS_WIN) | |
| 534 // Reset the preference so we don't call it again for subsequent windows. | |
| 535 local_state->ClearPref(prefs::kAutofillPersonalDataManagerFirstRun); | |
| 536 } | |
| 537 } | |
| 538 | |
| 539 void Browser::SetWindowForTesting(BrowserWindow* window) { | |
| 540 DCHECK(!window_); | |
| 541 window_ = window; | |
| 542 fullscreen_controller_ = new FullscreenController(window_, profile_, this); | |
| 543 } | |
| 544 | |
| 545 /////////////////////////////////////////////////////////////////////////////// | |
| 546 // Getters & Setters | |
| 547 | |
| 548 FindBarController* Browser::GetFindBarController() { | |
| 549 if (!find_bar_controller_.get()) { | |
| 550 FindBar* find_bar = window_->CreateFindBar(); | |
| 551 find_bar_controller_.reset(new FindBarController(find_bar)); | |
| 552 find_bar->SetFindBarController(find_bar_controller_.get()); | |
| 553 find_bar_controller_->ChangeTabContents(GetActiveTabContents()); | |
| 554 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true); | |
| 555 } | |
| 556 return find_bar_controller_.get(); | |
| 557 } | |
| 558 | |
| 559 bool Browser::HasFindBarController() const { | |
| 560 return find_bar_controller_.get() != NULL; | |
| 561 } | |
| 562 | |
| 563 bool Browser::is_app() const { | |
| 564 return !app_name_.empty(); | |
| 565 } | |
| 566 | |
| 567 bool Browser::is_devtools() const { | |
| 568 return app_name_ == DevToolsWindow::kDevToolsApp; | |
| 569 } | |
| 570 | |
| 571 /////////////////////////////////////////////////////////////////////////////// | |
| 572 // Browser, State Storage and Retrieval for UI: | |
| 573 | |
| 574 SkBitmap Browser::GetCurrentPageIcon() const { | |
| 575 TabContents* contents = GetActiveTabContents(); | |
| 576 // |contents| can be NULL since GetCurrentPageIcon() is called by the window | |
| 577 // during the window's creation (before tabs have been added). | |
| 578 return contents ? contents->favicon_tab_helper()->GetFavicon() : SkBitmap(); | |
| 579 } | |
| 580 | |
| 581 string16 Browser::GetWindowTitleForCurrentTab() const { | |
| 582 WebContents* contents = GetActiveWebContents(); | |
| 583 string16 title; | |
| 584 | |
| 585 // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the | |
| 586 // window during the window's creation (before tabs have been added). | |
| 587 if (contents) { | |
| 588 title = contents->GetTitle(); | |
| 589 FormatTitleForDisplay(&title); | |
| 590 } | |
| 591 if (title.empty()) | |
| 592 title = CoreTabHelper::GetDefaultTitle(); | |
| 593 | |
| 594 #if defined(OS_MACOSX) || defined(USE_ASH) | |
| 595 // On Mac or Ash, we don't want to suffix the page title with | |
| 596 // the application name. | |
| 597 return title; | |
| 598 #else | |
| 599 int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT; | |
| 600 // Don't append the app name to window titles on app frames and app popups | |
| 601 if (is_app()) | |
| 602 string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO; | |
| 603 return l10n_util::GetStringFUTF16(string_id, title); | |
| 604 #endif | |
| 605 } | |
| 606 | |
| 607 // static | |
| 608 void Browser::FormatTitleForDisplay(string16* title) { | |
| 609 size_t current_index = 0; | |
| 610 size_t match_index; | |
| 611 while ((match_index = title->find(L'\n', current_index)) != string16::npos) { | |
| 612 title->replace(match_index, 1, string16()); | |
| 613 current_index = match_index; | |
| 614 } | |
| 615 } | |
| 616 | |
| 617 /////////////////////////////////////////////////////////////////////////////// | |
| 618 // Browser, OnBeforeUnload handling: | |
| 619 | |
| 620 bool Browser::ShouldCloseWindow() { | |
| 621 if (!CanCloseWithInProgressDownloads()) | |
| 622 return false; | |
| 623 | |
| 624 if (HasCompletedUnloadProcessing()) | |
| 625 return true; | |
| 626 | |
| 627 is_attempting_to_close_browser_ = true; | |
| 628 | |
| 629 if (!TabsNeedBeforeUnloadFired()) | |
| 630 return true; | |
| 631 | |
| 632 ProcessPendingTabs(); | |
| 633 return false; | |
| 634 } | |
| 635 | |
| 636 void Browser::OnWindowClosing() { | |
| 637 if (!ShouldCloseWindow()) | |
| 638 return; | |
| 639 | |
| 640 bool exiting = false; | |
| 641 | |
| 642 // Application should shutdown on last window close if the user is explicitly | |
| 643 // trying to quit, or if there is nothing keeping the browser alive (such as | |
| 644 // AppController on the Mac, or BackgroundContentsService for background | |
| 645 // pages). | |
| 646 bool should_quit_if_last_browser = | |
| 647 browser_shutdown::IsTryingToQuit() || !browser::WillKeepAlive(); | |
| 648 | |
| 649 if (should_quit_if_last_browser && BrowserList::size() == 1) { | |
| 650 browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE); | |
| 651 exiting = true; | |
| 652 } | |
| 653 | |
| 654 // Don't use GetForProfileIfExisting here, we want to force creation of the | |
| 655 // session service so that user can restore what was open. | |
| 656 SessionService* session_service = | |
| 657 SessionServiceFactory::GetForProfile(profile()); | |
| 658 if (session_service) | |
| 659 session_service->WindowClosing(session_id()); | |
| 660 | |
| 661 TabRestoreService* tab_restore_service = | |
| 662 TabRestoreServiceFactory::GetForProfile(profile()); | |
| 663 | |
| 664 #if defined(USE_AURA) | |
| 665 if (tab_restore_service && is_app()) | |
| 666 tab_restore_service->BrowserClosing(tab_restore_service_delegate()); | |
| 667 #endif | |
| 668 | |
| 669 if (tab_restore_service && is_type_tabbed() && tab_count()) | |
| 670 tab_restore_service->BrowserClosing(tab_restore_service_delegate()); | |
| 671 | |
| 672 // TODO(sky): convert session/tab restore to use notification. | |
| 673 content::NotificationService::current()->Notify( | |
| 674 chrome::NOTIFICATION_BROWSER_CLOSING, | |
| 675 content::Source<Browser>(this), | |
| 676 content::Details<bool>(&exiting)); | |
| 677 | |
| 678 CloseAllTabs(); | |
| 679 } | |
| 680 | |
| 681 void Browser::OnWindowActivated() { | |
| 682 // On some platforms we want to automatically reload tabs that are | |
| 683 // killed when the user selects them. | |
| 684 WebContents* contents = GetActiveWebContents(); | |
| 685 if (contents && contents->GetCrashedStatus() == | |
| 686 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) { | |
| 687 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 688 switches::kReloadKilledTabs)) { | |
| 689 chrome::Reload(this, CURRENT_TAB); | |
| 690 } | |
| 691 } | |
| 692 } | |
| 693 | |
| 694 //////////////////////////////////////////////////////////////////////////////// | |
| 695 // In-progress download termination handling: | |
| 696 | |
| 697 void Browser::InProgressDownloadResponse(bool cancel_downloads) { | |
| 698 if (cancel_downloads) { | |
| 699 cancel_download_confirmation_state_ = RESPONSE_RECEIVED; | |
| 700 chrome::CloseWindow(this); | |
| 701 return; | |
| 702 } | |
| 703 | |
| 704 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to | |
| 705 // close again we'll show the warning again. | |
| 706 cancel_download_confirmation_state_ = NOT_PROMPTED; | |
| 707 | |
| 708 // Show the download page so the user can figure-out what downloads are still | |
| 709 // in-progress. | |
| 710 chrome::ShowDownloads(this); | |
| 711 } | |
| 712 | |
| 713 Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads( | |
| 714 int* num_downloads_blocking) const { | |
| 715 DCHECK(num_downloads_blocking); | |
| 716 *num_downloads_blocking = 0; | |
| 717 | |
| 718 if (is_attempting_to_close_browser_) | |
| 719 return DOWNLOAD_CLOSE_OK; | |
| 720 | |
| 721 // If we're not running a full browser process with a profile manager | |
| 722 // (testing), it's ok to close the browser. | |
| 723 if (!g_browser_process->profile_manager()) | |
| 724 return DOWNLOAD_CLOSE_OK; | |
| 725 | |
| 726 int total_download_count = DownloadService::DownloadCountAllProfiles(); | |
| 727 if (total_download_count == 0) | |
| 728 return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close. | |
| 729 | |
| 730 // Figure out how many windows are open total, and associated with this | |
| 731 // profile, that are relevant for the ok-to-close decision. | |
| 732 int profile_window_count = 0; | |
| 733 int total_window_count = 0; | |
| 734 for (BrowserList::const_iterator iter = BrowserList::begin(); | |
| 735 iter != BrowserList::end(); ++iter) { | |
| 736 // Don't count this browser window or any other in the process of closing. | |
| 737 Browser* const browser = *iter; | |
| 738 // Check is_attempting_to_close_browser_ as window closing may be | |
| 739 // delayed, and windows that are in the process of closing don't | |
| 740 // count against our totals. | |
| 741 if (browser == this || browser->is_attempting_to_close_browser_) | |
| 742 continue; | |
| 743 | |
| 744 if ((*iter)->profile() == profile()) | |
| 745 profile_window_count++; | |
| 746 total_window_count++; | |
| 747 } | |
| 748 | |
| 749 // If there aren't any other windows, we're at browser shutdown, | |
| 750 // which would cancel all current downloads. | |
| 751 if (total_window_count == 0) { | |
| 752 *num_downloads_blocking = total_download_count; | |
| 753 return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN; | |
| 754 } | |
| 755 | |
| 756 // If there aren't any other windows on our profile, and we're an incognito | |
| 757 // profile, and there are downloads associated with that profile, | |
| 758 // those downloads would be cancelled by our window (-> profile) close. | |
| 759 DownloadService* download_service = | |
| 760 DownloadServiceFactory::GetForProfile(profile()); | |
| 761 if (profile_window_count == 0 && download_service->DownloadCount() > 0 && | |
| 762 profile()->IsOffTheRecord()) { | |
| 763 *num_downloads_blocking = download_service->DownloadCount(); | |
| 764 return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE; | |
| 765 } | |
| 766 | |
| 767 // Those are the only conditions under which we will block shutdown. | |
| 768 return DOWNLOAD_CLOSE_OK; | |
| 769 } | |
| 770 | |
| 771 //////////////////////////////////////////////////////////////////////////////// | |
| 772 // Browser, TabStripModel pass-thrus: | |
| 773 | |
| 774 int Browser::tab_count() const { | |
| 775 return tab_strip_model_->count(); | |
| 776 } | |
| 777 | |
| 778 int Browser::active_index() const { | |
| 779 return tab_strip_model_->active_index(); | |
| 780 } | |
| 781 | |
| 782 int Browser::GetIndexOfController( | |
| 783 const NavigationController* controller) const { | |
| 784 return tab_strip_model_->GetIndexOfController(controller); | |
| 785 } | |
| 786 | |
| 787 TabContents* Browser::GetActiveTabContents() const { | |
| 788 return tab_strip_model_->GetActiveTabContents(); | |
| 789 } | |
| 790 | |
| 791 WebContents* Browser::GetActiveWebContents() const { | |
| 792 TabContents* tab_contents = GetActiveTabContents(); | |
| 793 return tab_contents ? tab_contents->web_contents() : NULL; | |
| 794 } | |
| 795 | |
| 796 TabContents* Browser::GetTabContentsAt(int index) const { | |
| 797 return tab_strip_model_->GetTabContentsAt(index); | |
| 798 } | |
| 799 | |
| 800 WebContents* Browser::GetWebContentsAt(int index) const { | |
| 801 TabContents* tab_contents = GetTabContentsAt(index); | |
| 802 if (tab_contents) | |
| 803 return tab_contents->web_contents(); | |
| 804 return NULL; | |
| 805 } | |
| 806 | |
| 807 void Browser::ActivateTabAt(int index, bool user_gesture) { | |
| 808 tab_strip_model_->ActivateTabAt(index, user_gesture); | |
| 809 } | |
| 810 | |
| 811 bool Browser::IsTabPinned(int index) const { | |
| 812 return tab_strip_model_->IsTabPinned(index); | |
| 813 } | |
| 814 | |
| 815 bool Browser::IsTabDiscarded(int index) const { | |
| 816 return tab_strip_model_->IsTabDiscarded(index); | |
| 817 } | |
| 818 | |
| 819 void Browser::CloseAllTabs() { | |
| 820 tab_strip_model_->CloseAllTabs(); | |
| 821 } | |
| 822 | |
| 823 //////////////////////////////////////////////////////////////////////////////// | |
| 824 // Browser, Tab adding/showing functions: | |
| 825 | |
| 826 bool Browser::IsTabStripEditable() const { | |
| 827 return window()->IsTabStripEditable(); | |
| 828 } | |
| 829 | |
| 830 int Browser::GetIndexForInsertionDuringRestore(int relative_index) { | |
| 831 return (tab_strip_model_->insertion_policy() == TabStripModel::INSERT_AFTER) ? | |
| 832 tab_count() : relative_index; | |
| 833 } | |
| 834 | |
| 835 TabContents* Browser::AddSelectedTabWithURL( | |
| 836 const GURL& url, | |
| 837 content::PageTransition transition) { | |
| 838 browser::NavigateParams params(this, url, transition); | |
| 839 params.disposition = NEW_FOREGROUND_TAB; | |
| 840 browser::Navigate(¶ms); | |
| 841 return params.target_contents; | |
| 842 } | |
| 843 | |
| 844 WebContents* Browser::AddTab(TabContents* tab_contents, | |
| 845 content::PageTransition type) { | |
| 846 tab_strip_model_->AddTabContents(tab_contents, -1, type, | |
| 847 TabStripModel::ADD_ACTIVE); | |
| 848 return tab_contents->web_contents(); | |
| 849 } | |
| 850 | |
| 851 WebContents* Browser::AddRestoredTab( | |
| 852 const std::vector<TabNavigation>& navigations, | |
| 853 int tab_index, | |
| 854 int selected_navigation, | |
| 855 const std::string& extension_app_id, | |
| 856 bool select, | |
| 857 bool pin, | |
| 858 bool from_last_session, | |
| 859 content::SessionStorageNamespace* session_storage_namespace) { | |
| 860 GURL restore_url = navigations.at(selected_navigation).virtual_url(); | |
| 861 TabContents* tab_contents = TabContentsFactory( | |
| 862 profile(), | |
| 863 tab_util::GetSiteInstanceForNewTab(profile_, restore_url), | |
| 864 MSG_ROUTING_NONE, | |
| 865 GetActiveWebContents(), | |
| 866 session_storage_namespace); | |
| 867 WebContents* new_tab = tab_contents->web_contents(); | |
| 868 tab_contents->extension_tab_helper()->SetExtensionAppById(extension_app_id); | |
| 869 std::vector<NavigationEntry*> entries; | |
| 870 TabNavigation::CreateNavigationEntriesFromTabNavigations( | |
| 871 profile_, navigations, &entries); | |
| 872 new_tab->GetController().Restore( | |
| 873 selected_navigation, from_last_session, &entries); | |
| 874 DCHECK_EQ(0u, entries.size()); | |
| 875 | |
| 876 int add_types = select ? TabStripModel::ADD_ACTIVE : | |
| 877 TabStripModel::ADD_NONE; | |
| 878 if (pin) { | |
| 879 int first_mini_tab_idx = tab_strip_model_->IndexOfFirstNonMiniTab(); | |
| 880 tab_index = std::min(tab_index, first_mini_tab_idx); | |
| 881 add_types |= TabStripModel::ADD_PINNED; | |
| 882 } | |
| 883 tab_strip_model_->InsertTabContentsAt(tab_index, tab_contents, add_types); | |
| 884 if (select) { | |
| 885 window_->Activate(); | |
| 886 } else { | |
| 887 // We set the size of the view here, before WebKit does its initial | |
| 888 // layout. If we don't, the initial layout of background tabs will be | |
| 889 // performed with a view width of 0, which may cause script outputs and | |
| 890 // anchor link location calculations to be incorrect even after a new | |
| 891 // layout with proper view dimensions. TabStripModel::AddTabContents() | |
| 892 // contains similar logic. | |
| 893 new_tab->GetView()->SizeContents(window_->GetRestoredBounds().size()); | |
| 894 new_tab->WasHidden(); | |
| 895 } | |
| 896 SessionService* session_service = | |
| 897 SessionServiceFactory::GetForProfileIfExisting(profile_); | |
| 898 if (session_service) | |
| 899 session_service->TabRestored(tab_contents, pin); | |
| 900 return new_tab; | |
| 901 } | |
| 902 | |
| 903 void Browser::AddWebContents(WebContents* new_contents, | |
| 904 WindowOpenDisposition disposition, | |
| 905 const gfx::Rect& initial_pos, | |
| 906 bool user_gesture) { | |
| 907 AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture); | |
| 908 } | |
| 909 | |
| 910 void Browser::CloseTabContents(WebContents* contents) { | |
| 911 CloseContents(contents); | |
| 912 } | |
| 913 | |
| 914 void Browser::ReplaceRestoredTab( | |
| 915 const std::vector<TabNavigation>& navigations, | |
| 916 int selected_navigation, | |
| 917 bool from_last_session, | |
| 918 const std::string& extension_app_id, | |
| 919 content::SessionStorageNamespace* session_storage_namespace) { | |
| 920 GURL restore_url = navigations.at(selected_navigation).virtual_url(); | |
| 921 TabContents* tab_contents = TabContentsFactory( | |
| 922 profile(), | |
| 923 tab_util::GetSiteInstanceForNewTab(profile_, restore_url), | |
| 924 MSG_ROUTING_NONE, | |
| 925 GetActiveWebContents(), | |
| 926 session_storage_namespace); | |
| 927 tab_contents->extension_tab_helper()->SetExtensionAppById(extension_app_id); | |
| 928 WebContents* replacement = tab_contents->web_contents(); | |
| 929 std::vector<NavigationEntry*> entries; | |
| 930 TabNavigation::CreateNavigationEntriesFromTabNavigations( | |
| 931 profile_, navigations, &entries); | |
| 932 replacement->GetController().Restore( | |
| 933 selected_navigation, from_last_session, &entries); | |
| 934 DCHECK_EQ(0u, entries.size()); | |
| 935 | |
| 936 tab_strip_model_->ReplaceNavigationControllerAt(active_index(), tab_contents); | |
| 937 } | |
| 938 | |
| 939 void Browser::WindowFullscreenStateChanged() { | |
| 940 fullscreen_controller_->WindowFullscreenStateChanged(); | |
| 941 FullScreenMode fullscreen_mode = FULLSCREEN_DISABLED; | |
| 942 if (window_->IsFullscreen()) { | |
| 943 #if defined(OS_WIN) | |
| 944 fullscreen_mode = window_->IsInMetroSnapMode() ? FULLSCREEN_METRO_SNAP : | |
| 945 FULLSCREEN_NORMAL; | |
| 946 #else | |
| 947 fullscreen_mode = FULLSCREEN_NORMAL; | |
| 948 #endif | |
| 949 } | |
| 950 UpdateCommandsForFullscreenMode(fullscreen_mode); | |
| 951 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN); | |
| 952 } | |
| 953 | |
| 954 /////////////////////////////////////////////////////////////////////////////// | |
| 955 // Browser, Assorted browser commands: | |
| 956 | |
| 957 void Browser::ToggleFullscreenMode() { | |
| 958 fullscreen_controller_->ToggleFullscreenMode(); | |
| 959 } | |
| 960 | |
| 961 void Browser::ToggleFullscreenModeWithExtension(const GURL& extension_url) { | |
| 962 fullscreen_controller_->ToggleFullscreenModeWithExtension(extension_url); | |
| 963 } | |
| 964 | |
| 965 #if defined(OS_MACOSX) | |
| 966 void Browser::TogglePresentationMode() { | |
| 967 fullscreen_controller_->TogglePresentationMode(); | |
| 968 } | |
| 969 #endif | |
| 970 | |
| 971 bool Browser::SupportsWindowFeature(WindowFeature feature) const { | |
| 972 return SupportsWindowFeatureImpl(feature, true); | |
| 973 } | |
| 974 | |
| 975 bool Browser::CanSupportWindowFeature(WindowFeature feature) const { | |
| 976 return SupportsWindowFeatureImpl(feature, false); | |
| 977 } | |
| 978 | |
| 979 void Browser::ToggleEncodingAutoDetect() { | |
| 980 content::RecordAction(UserMetricsAction("AutoDetectChange")); | |
| 981 encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue()); | |
| 982 // If "auto detect" is turned on, then any current override encoding | |
| 983 // is cleared. This also implicitly performs a reload. | |
| 984 // OTOH, if "auto detect" is turned off, we don't change the currently | |
| 985 // active encoding. | |
| 986 if (encoding_auto_detect_.GetValue()) { | |
| 987 WebContents* contents = GetActiveWebContents(); | |
| 988 if (contents) | |
| 989 contents->ResetOverrideEncoding(); | |
| 990 } | |
| 991 } | |
| 992 | |
| 993 void Browser::OverrideEncoding(int encoding_id) { | |
| 994 content::RecordAction(UserMetricsAction("OverrideEncoding")); | |
| 995 const std::string selected_encoding = | |
| 996 CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id); | |
| 997 WebContents* contents = GetActiveWebContents(); | |
| 998 if (!selected_encoding.empty() && contents) | |
| 999 contents->SetOverrideEncoding(selected_encoding); | |
| 1000 // Update the list of recently selected encodings. | |
| 1001 std::string new_selected_encoding_list; | |
| 1002 if (CharacterEncoding::UpdateRecentlySelectedEncoding( | |
| 1003 profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding), | |
| 1004 encoding_id, | |
| 1005 &new_selected_encoding_list)) { | |
| 1006 profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding, | |
| 1007 new_selected_encoding_list); | |
| 1008 } | |
| 1009 } | |
| 1010 | |
| 1011 void Browser::OpenFile() { | |
| 1012 content::RecordAction(UserMetricsAction("OpenFile")); | |
| 1013 if (!select_file_dialog_.get()) | |
| 1014 select_file_dialog_ = SelectFileDialog::Create(this); | |
| 1015 | |
| 1016 const FilePath directory = profile_->last_selected_directory(); | |
| 1017 | |
| 1018 // TODO(beng): figure out how to juggle this. | |
| 1019 gfx::NativeWindow parent_window = window_->GetNativeWindow(); | |
| 1020 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE, | |
| 1021 string16(), directory, | |
| 1022 NULL, 0, FILE_PATH_LITERAL(""), | |
| 1023 GetActiveWebContents(), | |
| 1024 parent_window, NULL); | |
| 1025 } | |
| 1026 | |
| 1027 void Browser::OpenCreateShortcutsDialog() { | |
| 1028 content::RecordAction(UserMetricsAction("CreateShortcut")); | |
| 1029 #if !defined(OS_MACOSX) | |
| 1030 TabContents* current_tab = GetActiveTabContents(); | |
| 1031 DCHECK(current_tab && | |
| 1032 web_app::IsValidUrl(current_tab->web_contents()->GetURL())) << | |
| 1033 "Menu item should be disabled."; | |
| 1034 | |
| 1035 NavigationEntry* entry = | |
| 1036 current_tab->web_contents()->GetController().GetLastCommittedEntry(); | |
| 1037 if (!entry) | |
| 1038 return; | |
| 1039 | |
| 1040 // RVH's GetApplicationInfo should not be called before it returns. | |
| 1041 DCHECK(pending_web_app_action_ == NONE); | |
| 1042 pending_web_app_action_ = CREATE_SHORTCUT; | |
| 1043 | |
| 1044 // Start fetching web app info for CreateApplicationShortcut dialog and show | |
| 1045 // the dialog when the data is available in OnDidGetApplicationInfo. | |
| 1046 current_tab->extension_tab_helper()->GetApplicationInfo(entry->GetPageID()); | |
| 1047 #else | |
| 1048 NOTIMPLEMENTED(); | |
| 1049 #endif | |
| 1050 } | |
| 1051 | |
| 1052 void Browser::UpdateDownloadShelfVisibility(bool visible) { | |
| 1053 if (GetStatusBubble()) | |
| 1054 GetStatusBubble()->UpdateDownloadShelfVisibility(visible); | |
| 1055 } | |
| 1056 | |
| 1057 bool Browser::OpenInstant(WindowOpenDisposition disposition) { | |
| 1058 if (!instant() || !instant()->PrepareForCommit() || | |
| 1059 disposition == NEW_BACKGROUND_TAB) { | |
| 1060 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't | |
| 1061 // attempt to use the instant preview. | |
| 1062 return false; | |
| 1063 } | |
| 1064 | |
| 1065 if (disposition == CURRENT_TAB) { | |
| 1066 content::NotificationService::current()->Notify( | |
| 1067 chrome::NOTIFICATION_INSTANT_COMMITTED, | |
| 1068 content::Source<TabContents>(instant()->CommitCurrentPreview( | |
| 1069 INSTANT_COMMIT_PRESSED_ENTER)), | |
| 1070 content::NotificationService::NoDetails()); | |
| 1071 return true; | |
| 1072 } | |
| 1073 if (disposition == NEW_FOREGROUND_TAB) { | |
| 1074 TabContents* preview_contents = instant()->ReleasePreviewContents( | |
| 1075 INSTANT_COMMIT_PRESSED_ENTER, NULL); | |
| 1076 // HideInstant is invoked after release so that InstantController is not | |
| 1077 // active when HideInstant asks it for its state. | |
| 1078 HideInstant(); | |
| 1079 preview_contents->web_contents()->GetController().PruneAllButActive(); | |
| 1080 tab_strip_model_->AddTabContents( | |
| 1081 preview_contents, | |
| 1082 -1, | |
| 1083 instant()->last_transition_type(), | |
| 1084 TabStripModel::ADD_ACTIVE); | |
| 1085 instant()->CompleteRelease(preview_contents); | |
| 1086 content::NotificationService::current()->Notify( | |
| 1087 chrome::NOTIFICATION_INSTANT_COMMITTED, | |
| 1088 content::Source<TabContents>(preview_contents), | |
| 1089 content::NotificationService::NoDetails()); | |
| 1090 return true; | |
| 1091 } | |
| 1092 // The omnibox currently doesn't use other dispositions, so we don't attempt | |
| 1093 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add | |
| 1094 // support for the new disposition. | |
| 1095 NOTREACHED(); | |
| 1096 return false; | |
| 1097 } | |
| 1098 | |
| 1099 /////////////////////////////////////////////////////////////////////////////// | |
| 1100 | |
| 1101 // static | |
| 1102 bool Browser::RunUnloadEventsHelper(WebContents* contents) { | |
| 1103 // If the WebContents is not connected yet, then there's no unload | |
| 1104 // handler we can fire even if the WebContents has an unload listener. | |
| 1105 // One case where we hit this is in a tab that has an infinite loop | |
| 1106 // before load. | |
| 1107 if (contents->NeedToFireBeforeUnload()) { | |
| 1108 // If the page has unload listeners, then we tell the renderer to fire | |
| 1109 // them. Once they have fired, we'll get a message back saying whether | |
| 1110 // to proceed closing the page or not, which sends us back to this method | |
| 1111 // with the NeedToFireBeforeUnload bit cleared. | |
| 1112 contents->GetRenderViewHost()->FirePageBeforeUnload(false); | |
| 1113 return true; | |
| 1114 } | |
| 1115 return false; | |
| 1116 } | |
| 1117 | |
| 1118 // static | |
| 1119 void Browser::JSOutOfMemoryHelper(WebContents* web_contents) { | |
| 1120 TabContents* tab_contents = TabContents::FromWebContents(web_contents); | |
| 1121 if (!tab_contents) | |
| 1122 return; | |
| 1123 | |
| 1124 InfoBarTabHelper* infobar_helper = tab_contents->infobar_tab_helper(); | |
| 1125 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate( | |
| 1126 infobar_helper, | |
| 1127 NULL, | |
| 1128 l10n_util::GetStringUTF16(IDS_JS_OUT_OF_MEMORY_PROMPT), | |
| 1129 true)); | |
| 1130 } | |
| 1131 | |
| 1132 // static | |
| 1133 void Browser::RegisterProtocolHandlerHelper(WebContents* web_contents, | |
| 1134 const std::string& protocol, | |
| 1135 const GURL& url, | |
| 1136 const string16& title, | |
| 1137 bool user_gesture) { | |
| 1138 TabContents* tab_contents = TabContents::FromWebContents(web_contents); | |
| 1139 if (!tab_contents || tab_contents->profile()->IsOffTheRecord()) | |
| 1140 return; | |
| 1141 | |
| 1142 ProtocolHandler handler = | |
| 1143 ProtocolHandler::CreateProtocolHandler(protocol, url, title); | |
| 1144 | |
| 1145 ProtocolHandlerRegistry* registry = | |
| 1146 tab_contents->profile()->GetProtocolHandlerRegistry(); | |
| 1147 | |
| 1148 if (!registry->SilentlyHandleRegisterHandlerRequest(handler)) { | |
| 1149 content::RecordAction( | |
| 1150 UserMetricsAction("RegisterProtocolHandler.InfoBar_Shown")); | |
| 1151 InfoBarTabHelper* infobar_helper = tab_contents->infobar_tab_helper(); | |
| 1152 | |
| 1153 RegisterProtocolHandlerInfoBarDelegate* rph_delegate = | |
| 1154 new RegisterProtocolHandlerInfoBarDelegate(infobar_helper, | |
| 1155 registry, | |
| 1156 handler); | |
| 1157 | |
| 1158 for (size_t i = 0; i < infobar_helper->infobar_count(); i++) { | |
| 1159 InfoBarDelegate* delegate = infobar_helper->GetInfoBarDelegateAt(i); | |
| 1160 RegisterProtocolHandlerInfoBarDelegate* cast_delegate = | |
| 1161 delegate->AsRegisterProtocolHandlerInfoBarDelegate(); | |
| 1162 if (cast_delegate != NULL && cast_delegate->IsReplacedBy(rph_delegate)) { | |
| 1163 infobar_helper->ReplaceInfoBar(cast_delegate, rph_delegate); | |
| 1164 rph_delegate = NULL; | |
| 1165 break; | |
| 1166 } | |
| 1167 } | |
| 1168 | |
| 1169 if (rph_delegate != NULL) | |
| 1170 infobar_helper->AddInfoBar(rph_delegate); | |
| 1171 } | |
| 1172 } | |
| 1173 | |
| 1174 // static | |
| 1175 void Browser::FindReplyHelper(WebContents* web_contents, | |
| 1176 int request_id, | |
| 1177 int number_of_matches, | |
| 1178 const gfx::Rect& selection_rect, | |
| 1179 int active_match_ordinal, | |
| 1180 bool final_update) { | |
| 1181 TabContents* tab_contents = TabContents::FromWebContents(web_contents); | |
| 1182 if (!tab_contents || !tab_contents->find_tab_helper()) | |
| 1183 return; | |
| 1184 | |
| 1185 tab_contents->find_tab_helper()->HandleFindReply(request_id, | |
| 1186 number_of_matches, | |
| 1187 selection_rect, | |
| 1188 active_match_ordinal, | |
| 1189 final_update); | |
| 1190 } | |
| 1191 | |
| 1192 void Browser::ExecuteCommand(int id) { | |
| 1193 ExecuteCommandWithDisposition(id, CURRENT_TAB); | |
| 1194 } | |
| 1195 | |
| 1196 void Browser::ExecuteCommand(int id, int event_flags) { | |
| 1197 ExecuteCommandWithDisposition( | |
| 1198 id, browser::DispositionFromEventFlags(event_flags)); | |
| 1199 } | |
| 1200 | |
| 1201 bool Browser::ExecuteCommandIfEnabled(int id) { | |
| 1202 if (command_updater_.SupportsCommand(id) && | |
| 1203 command_updater_.IsCommandEnabled(id)) { | |
| 1204 ExecuteCommand(id); | |
| 1205 return true; | |
| 1206 } | |
| 1207 return false; | |
| 1208 } | |
| 1209 | |
| 1210 bool Browser::IsReservedCommandOrKey(int command_id, | |
| 1211 const NativeWebKeyboardEvent& event) { | |
| 1212 // In Apps mode, no keys are reserved. | 131 // In Apps mode, no keys are reserved. |
| 1213 if (is_app()) | 132 if (browser_->is_app()) |
| 1214 return false; | 133 return false; |
| 1215 | 134 |
| 1216 #if defined(OS_CHROMEOS) | 135 #if defined(OS_CHROMEOS) |
| 1217 // Chrome OS's top row of keys produces F1-10. Make sure that web pages | 136 // Chrome OS's top row of keys produces F1-10. Make sure that web pages |
| 1218 // aren't able to block Chrome from performing the standard actions for F1-F4. | 137 // aren't able to block Chrome from performing the standard actions for F1-F4. |
| 1219 // We should not handle F5-10 here since they are processed by Ash. See also: | 138 // We should not handle F5-10 here since they are processed by Ash. See also: |
| 1220 // crbug.com/127333#c8 | 139 // crbug.com/127333#c8 |
| 1221 ui::KeyboardCode key_code = | 140 ui::KeyboardCode key_code = |
| 1222 static_cast<ui::KeyboardCode>(event.windowsKeyCode); | 141 static_cast<ui::KeyboardCode>(event.windowsKeyCode); |
| 1223 if ((key_code == ui::VKEY_F1 || | 142 if ((key_code == ui::VKEY_F1 || |
| 1224 key_code == ui::VKEY_F2 || | 143 key_code == ui::VKEY_F2 || |
| 1225 key_code == ui::VKEY_F3 || | 144 key_code == ui::VKEY_F3 || |
| 1226 key_code == ui::VKEY_F4) && | 145 key_code == ui::VKEY_F4) && |
| 1227 // Make sure it's a browser shortcut (i.e. not an Ash one like Alt+F4). | 146 // Make sure it's a browser shortcut (i.e. not an Ash one like Alt+F4). |
| 1228 command_id != -1) { | 147 command_id != -1) { |
| 1229 return true; | 148 return true; |
| 1230 } | 149 } |
| 1231 #endif | 150 #endif |
| 1232 | 151 |
| 1233 if (window_->IsFullscreen() && command_id == IDC_FULLSCREEN) | 152 if (window()->IsFullscreen() && command_id == IDC_FULLSCREEN) |
| 1234 return true; | 153 return true; |
| 1235 return command_id == IDC_CLOSE_TAB || | 154 return command_id == IDC_CLOSE_TAB || |
| 1236 command_id == IDC_CLOSE_WINDOW || | 155 command_id == IDC_CLOSE_WINDOW || |
| 1237 command_id == IDC_NEW_INCOGNITO_WINDOW || | 156 command_id == IDC_NEW_INCOGNITO_WINDOW || |
| 1238 command_id == IDC_NEW_TAB || | 157 command_id == IDC_NEW_TAB || |
| 1239 command_id == IDC_NEW_WINDOW || | 158 command_id == IDC_NEW_WINDOW || |
| 1240 command_id == IDC_RESTORE_TAB || | 159 command_id == IDC_RESTORE_TAB || |
| 1241 command_id == IDC_SELECT_NEXT_TAB || | 160 command_id == IDC_SELECT_NEXT_TAB || |
| 1242 command_id == IDC_SELECT_PREVIOUS_TAB || | 161 command_id == IDC_SELECT_PREVIOUS_TAB || |
| 1243 command_id == IDC_TABPOSE || | 162 command_id == IDC_TABPOSE || |
| 1244 command_id == IDC_EXIT || | 163 command_id == IDC_EXIT || |
| 1245 command_id == IDC_SEARCH; | 164 command_id == IDC_SEARCH; |
| 1246 } | 165 } |
| 1247 | 166 |
| 1248 void Browser::SetBlockCommandExecution(bool block) { | 167 void BrowserCommandController::SetBlockCommandExecution(bool block) { |
| 1249 block_command_execution_ = block; | 168 block_command_execution_ = block; |
| 1250 if (block) { | 169 if (block) { |
| 1251 last_blocked_command_id_ = -1; | 170 last_blocked_command_id_ = -1; |
| 1252 last_blocked_command_disposition_ = CURRENT_TAB; | 171 last_blocked_command_disposition_ = CURRENT_TAB; |
| 1253 } | 172 } |
| 1254 } | 173 } |
| 1255 | 174 |
| 1256 int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) { | 175 int BrowserCommandController::GetLastBlockedCommand( |
| 176 WindowOpenDisposition* disposition) { |
| 1257 if (disposition) | 177 if (disposition) |
| 1258 *disposition = last_blocked_command_disposition_; | 178 *disposition = last_blocked_command_disposition_; |
| 1259 return last_blocked_command_id_; | 179 return last_blocked_command_id_; |
| 1260 } | 180 } |
| 1261 | 181 |
| 1262 void Browser::UpdateUIForNavigationInTab(TabContents* contents, | 182 void BrowserCommandController::TabStateChanged() { |
| 1263 content::PageTransition transition, | 183 UpdateCommandsForTabState(); |
| 1264 bool user_initiated) { | |
| 1265 tab_strip_model_->TabNavigating(contents, transition); | |
| 1266 | |
| 1267 bool contents_is_selected = contents == GetActiveTabContents(); | |
| 1268 if (user_initiated && contents_is_selected && window()->GetLocationBar()) { | |
| 1269 // Forcibly reset the location bar if the url is going to change in the | |
| 1270 // current tab, since otherwise it won't discard any ongoing user edits, | |
| 1271 // since it doesn't realize this is a user-initiated action. | |
| 1272 window()->GetLocationBar()->Revert(); | |
| 1273 } | |
| 1274 | |
| 1275 if (GetStatusBubble()) | |
| 1276 GetStatusBubble()->Hide(); | |
| 1277 | |
| 1278 // Update the location bar. This is synchronous. We specifically don't | |
| 1279 // update the load state since the load hasn't started yet and updating it | |
| 1280 // will put it out of sync with the actual state like whether we're | |
| 1281 // displaying a favicon, which controls the throbber. If we updated it here, | |
| 1282 // the throbber will show the default favicon for a split second when | |
| 1283 // navigating away from the new tab page. | |
| 1284 ScheduleUIUpdate(contents->web_contents(), content::INVALIDATE_TYPE_URL); | |
| 1285 | |
| 1286 if (contents_is_selected) | |
| 1287 contents->web_contents()->Focus(); | |
| 1288 } | 184 } |
| 1289 | 185 |
| 1290 /////////////////////////////////////////////////////////////////////////////// | 186 void BrowserCommandController::ContentRestrictionsChanged() { |
| 1291 // Browser, PageNavigator implementation: | 187 UpdateCommandsForContentRestrictionState(); |
| 1292 | |
| 1293 WebContents* Browser::OpenURL(const OpenURLParams& params) { | |
| 1294 return OpenURLFromTab(NULL, params); | |
| 1295 } | 188 } |
| 1296 | 189 |
| 1297 /////////////////////////////////////////////////////////////////////////////// | 190 void BrowserCommandController::FullscreenStateChanged() { |
| 1298 // Browser, CommandUpdater::CommandUpdaterDelegate implementation: | 191 FullScreenMode fullscreen_mode = FULLSCREEN_DISABLED; |
| 192 if (window()->IsFullscreen()) { |
| 193 #if defined(OS_WIN) |
| 194 fullscreen_mode = window()->IsInMetroSnapMode() ? FULLSCREEN_METRO_SNAP : |
| 195 FULLSCREEN_NORMAL; |
| 196 #else |
| 197 fullscreen_mode = FULLSCREEN_NORMAL; |
| 198 #endif |
| 199 } |
| 200 UpdateCommandsForFullscreenMode(fullscreen_mode); |
| 201 } |
| 1299 | 202 |
| 1300 void Browser::ExecuteCommandWithDisposition( | 203 void BrowserCommandController::PrintingStateChanged() { |
| 204 UpdatePrintingState(); |
| 205 } |
| 206 |
| 207 void BrowserCommandController::LoadingStateChanged(bool is_loading, |
| 208 bool force) { |
| 209 UpdateReloadStopState(is_loading, force); |
| 210 } |
| 211 |
| 212 void BrowserCommandController::SendToMobileStateChanged( |
| 213 bool send_to_mobile_available) { |
| 214 command_updater_.UpdateCommandEnabled(IDC_CHROME_TO_MOBILE_PAGE, |
| 215 send_to_mobile_available); |
| 216 } |
| 217 |
| 218 //////////////////////////////////////////////////////////////////////////////// |
| 219 // BrowserCommandController, |
| 220 // CommandUpdater::CommandUpdaterDelegate implementation: |
| 221 |
| 222 void BrowserCommandController::ExecuteCommandWithDisposition( |
| 1301 int id, WindowOpenDisposition disposition) { | 223 int id, WindowOpenDisposition disposition) { |
| 1302 // No commands are enabled if there is not yet any selected tab. | 224 // No commands are enabled if there is not yet any selected tab. |
| 1303 // TODO(pkasting): It seems like we should not need this, because either | 225 // TODO(pkasting): It seems like we should not need this, because either |
| 1304 // most/all commands should not have been enabled yet anyway or the ones that | 226 // most/all commands should not have been enabled yet anyway or the ones that |
| 1305 // are enabled should be global, or safe themselves against having no selected | 227 // are enabled should be global, or safe themselves against having no selected |
| 1306 // tab. However, Ben says he tried removing this before and got lots of | 228 // tab. However, Ben says he tried removing this before and got lots of |
| 1307 // crashes, e.g. from Windows sending WM_COMMANDs at random times during | 229 // crashes, e.g. from Windows sending WM_COMMANDs at random times during |
| 1308 // window construction. This probably could use closer examination someday. | 230 // window construction. This probably could use closer examination someday. |
| 1309 if (!GetActiveTabContents()) | 231 if (!browser_->GetActiveTabContents()) |
| 1310 return; | 232 return; |
| 1311 | 233 |
| 1312 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command " | 234 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command " |
| 1313 << id; | 235 << id; |
| 1314 | 236 |
| 1315 // If command execution is blocked then just record the command and return. | 237 // If command execution is blocked then just record the command and return. |
| 1316 if (block_command_execution_) { | 238 if (block_command_execution_) { |
| 1317 // We actually only allow no more than one blocked command, otherwise some | 239 // We actually only allow no more than one blocked command, otherwise some |
| 1318 // commands maybe lost. | 240 // commands maybe lost. |
| 1319 DCHECK_EQ(last_blocked_command_id_, -1); | 241 DCHECK_EQ(last_blocked_command_id_, -1); |
| 1320 last_blocked_command_id_ = id; | 242 last_blocked_command_id_ = id; |
| 1321 last_blocked_command_disposition_ = disposition; | 243 last_blocked_command_disposition_ = disposition; |
| 1322 return; | 244 return; |
| 1323 } | 245 } |
| 1324 | 246 |
| 1325 // The order of commands in this switch statement must match the function | 247 // The order of commands in this switch statement must match the function |
| 1326 // declaration order in browser.h! | 248 // declaration order in browser.h! |
| 1327 switch (id) { | 249 switch (id) { |
| 1328 // Navigation commands | 250 // Navigation commands |
| 1329 case IDC_BACK: chrome::GoBack(this, disposition);break; | 251 case IDC_BACK: |
| 252 GoBack(browser_, disposition); |
| 253 break; |
| 1330 case IDC_FORWARD: | 254 case IDC_FORWARD: |
| 1331 chrome::GoForward(this, disposition); | 255 GoForward(browser_, disposition); |
| 1332 break; | 256 break; |
| 1333 case IDC_RELOAD: chrome::Reload(this, disposition);break; | 257 case IDC_RELOAD: |
| 258 Reload(browser_, disposition); |
| 259 break; |
| 1334 case IDC_RELOAD_IGNORING_CACHE: | 260 case IDC_RELOAD_IGNORING_CACHE: |
| 1335 chrome::ReloadIgnoringCache(this, disposition); | 261 ReloadIgnoringCache(browser_, disposition); |
| 1336 break; | 262 break; |
| 1337 case IDC_HOME: chrome::Home(this, disposition); break; | 263 case IDC_HOME: |
| 1338 case IDC_OPEN_CURRENT_URL: chrome::OpenCurrentURL(this); break; | 264 Home(browser_, disposition); |
| 1339 case IDC_STOP: chrome::Stop(this); break; | 265 break; |
| 266 case IDC_OPEN_CURRENT_URL: |
| 267 OpenCurrentURL(browser_); |
| 268 break; |
| 269 case IDC_STOP: |
| 270 Stop(browser_); |
| 271 break; |
| 1340 | 272 |
| 1341 // Window management commands | 273 // Window management commands |
| 1342 case IDC_NEW_WINDOW: chrome::NewWindow(this); break; | 274 case IDC_NEW_WINDOW: |
| 1343 case IDC_NEW_INCOGNITO_WINDOW: chrome::NewIncognitoWindow(this); break; | 275 NewWindow(browser_); |
| 1344 case IDC_CLOSE_WINDOW: chrome::CloseWindow(this); break; | 276 break; |
| 1345 case IDC_NEW_TAB: chrome::NewTab(this); break; | 277 case IDC_NEW_INCOGNITO_WINDOW: |
| 1346 case IDC_CLOSE_TAB: chrome::CloseTab(this); break; | 278 NewIncognitoWindow(browser_); |
| 1347 case IDC_SELECT_NEXT_TAB: chrome::SelectNextTab(this); break; | 279 break; |
| 1348 case IDC_SELECT_PREVIOUS_TAB: chrome::SelectPreviousTab(this); break; | 280 case IDC_CLOSE_WINDOW: |
| 1349 case IDC_TABPOSE: chrome::OpenTabpose(this); break; | 281 CloseWindow(browser_); |
| 1350 case IDC_MOVE_TAB_NEXT: chrome::MoveTabNext(this); break; | 282 break; |
| 1351 case IDC_MOVE_TAB_PREVIOUS: chrome::MoveTabPrevious(this); break; | 283 case IDC_NEW_TAB: |
| 284 NewTab(browser_); |
| 285 break; |
| 286 case IDC_CLOSE_TAB: |
| 287 CloseTab(browser_); |
| 288 break; |
| 289 case IDC_SELECT_NEXT_TAB: |
| 290 SelectNextTab(browser_); |
| 291 break; |
| 292 case IDC_SELECT_PREVIOUS_TAB: |
| 293 SelectPreviousTab(browser_); |
| 294 break; |
| 295 case IDC_TABPOSE: |
| 296 OpenTabpose(browser_); |
| 297 break; |
| 298 case IDC_MOVE_TAB_NEXT: |
| 299 MoveTabNext(browser_); |
| 300 break; |
| 301 case IDC_MOVE_TAB_PREVIOUS: |
| 302 MoveTabPrevious(browser_); |
| 303 break; |
| 1352 case IDC_SELECT_TAB_0: | 304 case IDC_SELECT_TAB_0: |
| 1353 case IDC_SELECT_TAB_1: | 305 case IDC_SELECT_TAB_1: |
| 1354 case IDC_SELECT_TAB_2: | 306 case IDC_SELECT_TAB_2: |
| 1355 case IDC_SELECT_TAB_3: | 307 case IDC_SELECT_TAB_3: |
| 1356 case IDC_SELECT_TAB_4: | 308 case IDC_SELECT_TAB_4: |
| 1357 case IDC_SELECT_TAB_5: | 309 case IDC_SELECT_TAB_5: |
| 1358 case IDC_SELECT_TAB_6: | 310 case IDC_SELECT_TAB_6: |
| 1359 case IDC_SELECT_TAB_7: | 311 case IDC_SELECT_TAB_7: |
| 1360 chrome::SelectNumberedTab(this, id - IDC_SELECT_TAB_0); | 312 SelectNumberedTab(browser_, id - IDC_SELECT_TAB_0); |
| 1361 break; | 313 break; |
| 1362 case IDC_SELECT_LAST_TAB: chrome::SelectLastTab(this); break; | 314 case IDC_SELECT_LAST_TAB: |
| 1363 case IDC_DUPLICATE_TAB: chrome::DuplicateTab(this); break; | 315 SelectLastTab(browser_); |
| 1364 case IDC_RESTORE_TAB: RestoreTab(); break; | 316 break; |
| 317 case IDC_DUPLICATE_TAB: |
| 318 DuplicateTab(browser_); |
| 319 break; |
| 320 case IDC_RESTORE_TAB: |
| 321 RestoreTab(browser_); |
| 322 break; |
| 1365 case IDC_COPY_URL: | 323 case IDC_COPY_URL: |
| 1366 chrome::WriteCurrentURLToClipboard(this); | 324 WriteCurrentURLToClipboard(browser_); |
| 1367 break; | 325 break; |
| 1368 case IDC_SHOW_AS_TAB: | 326 case IDC_SHOW_AS_TAB: |
| 1369 chrome::ConvertPopupToTabbedBrowser(this); | 327 ConvertPopupToTabbedBrowser(browser_); |
| 1370 break; | 328 break; |
| 1371 case IDC_FULLSCREEN: ToggleFullscreenMode(); break; | 329 case IDC_FULLSCREEN: |
| 330 browser_->ToggleFullscreenMode(); |
| 331 break; |
| 1372 #if defined(OS_WIN) | 332 #if defined(OS_WIN) |
| 1373 case IDC_METRO_SNAP_ENABLE: SetMetroSnapMode(true); break; | 333 case IDC_METRO_SNAP_ENABLE: |
| 1374 case IDC_METRO_SNAP_DISABLE: SetMetroSnapMode(false); break; | 334 browser_->SetMetroSnapMode(true); |
| 335 break; |
| 336 case IDC_METRO_SNAP_DISABLE: |
| 337 browser_->SetMetroSnapMode(false); |
| 338 break; |
| 1375 #endif | 339 #endif |
| 1376 #if defined(OS_MACOSX) | 340 #if defined(OS_MACOSX) |
| 1377 case IDC_PRESENTATION_MODE: TogglePresentationMode(); break; | 341 case IDC_PRESENTATION_MODE: |
| 342 browser_->TogglePresentationMode(); |
| 343 break; |
| 1378 #endif | 344 #endif |
| 1379 case IDC_EXIT: chrome::Exit(); break; | 345 case IDC_EXIT: |
| 346 Exit(); |
| 347 break; |
| 1380 | 348 |
| 1381 // Page-related commands | 349 // Page-related commands |
| 1382 case IDC_SAVE_PAGE: chrome::SavePage(this); break; | 350 case IDC_SAVE_PAGE: |
| 1383 case IDC_BOOKMARK_PAGE: chrome::BookmarkCurrentPage(this);break; | 351 SavePage(browser_); |
| 352 break; |
| 353 case IDC_BOOKMARK_PAGE: |
| 354 BookmarkCurrentPage(browser_); |
| 355 break; |
| 1384 case IDC_PIN_TO_START_SCREEN: | 356 case IDC_PIN_TO_START_SCREEN: |
| 1385 chrome::PinCurrentPageToStartScreen(this); | 357 PinCurrentPageToStartScreen(browser_); |
| 1386 break; | 358 break; |
| 1387 case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(); break; | 359 case IDC_BOOKMARK_ALL_TABS: |
| 1388 case IDC_VIEW_SOURCE: chrome::ViewSelectedSource(this); break; | 360 BookmarkAllTabs(browser_); |
| 1389 case IDC_EMAIL_PAGE_LOCATION: chrome::EmailPageLocation(this); break; | 361 break; |
| 1390 case IDC_PRINT: chrome::Print(this); break; | 362 case IDC_VIEW_SOURCE: |
| 1391 case IDC_ADVANCED_PRINT: chrome::AdvancedPrint(this); break; | 363 ViewSelectedSource(browser_); |
| 364 break; |
| 365 case IDC_EMAIL_PAGE_LOCATION: |
| 366 EmailPageLocation(browser_); |
| 367 break; |
| 368 case IDC_PRINT: |
| 369 Print(browser_); |
| 370 break; |
| 371 case IDC_ADVANCED_PRINT: |
| 372 AdvancedPrint(browser_); |
| 373 break; |
| 1392 case IDC_CHROME_TO_MOBILE_PAGE: | 374 case IDC_CHROME_TO_MOBILE_PAGE: |
| 1393 chrome::ShowChromeToMobileBubble(this); | 375 ShowChromeToMobileBubble(browser_); |
| 1394 break; | 376 break; |
| 1395 case IDC_ENCODING_AUTO_DETECT: ToggleEncodingAutoDetect(); break; | 377 case IDC_ENCODING_AUTO_DETECT: |
| 378 browser_->ToggleEncodingAutoDetect(); |
| 379 break; |
| 1396 case IDC_ENCODING_UTF8: | 380 case IDC_ENCODING_UTF8: |
| 1397 case IDC_ENCODING_UTF16LE: | 381 case IDC_ENCODING_UTF16LE: |
| 1398 case IDC_ENCODING_ISO88591: | 382 case IDC_ENCODING_ISO88591: |
| 1399 case IDC_ENCODING_WINDOWS1252: | 383 case IDC_ENCODING_WINDOWS1252: |
| 1400 case IDC_ENCODING_GBK: | 384 case IDC_ENCODING_GBK: |
| 1401 case IDC_ENCODING_GB18030: | 385 case IDC_ENCODING_GB18030: |
| 1402 case IDC_ENCODING_BIG5HKSCS: | 386 case IDC_ENCODING_BIG5HKSCS: |
| 1403 case IDC_ENCODING_BIG5: | 387 case IDC_ENCODING_BIG5: |
| 1404 case IDC_ENCODING_KOREAN: | 388 case IDC_ENCODING_KOREAN: |
| 1405 case IDC_ENCODING_SHIFTJIS: | 389 case IDC_ENCODING_SHIFTJIS: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1422 case IDC_ENCODING_ISO88593: | 406 case IDC_ENCODING_ISO88593: |
| 1423 case IDC_ENCODING_ISO885910: | 407 case IDC_ENCODING_ISO885910: |
| 1424 case IDC_ENCODING_ISO885914: | 408 case IDC_ENCODING_ISO885914: |
| 1425 case IDC_ENCODING_ISO885916: | 409 case IDC_ENCODING_ISO885916: |
| 1426 case IDC_ENCODING_WINDOWS1254: | 410 case IDC_ENCODING_WINDOWS1254: |
| 1427 case IDC_ENCODING_ISO88596: | 411 case IDC_ENCODING_ISO88596: |
| 1428 case IDC_ENCODING_WINDOWS1256: | 412 case IDC_ENCODING_WINDOWS1256: |
| 1429 case IDC_ENCODING_ISO88598: | 413 case IDC_ENCODING_ISO88598: |
| 1430 case IDC_ENCODING_ISO88598I: | 414 case IDC_ENCODING_ISO88598I: |
| 1431 case IDC_ENCODING_WINDOWS1255: | 415 case IDC_ENCODING_WINDOWS1255: |
| 1432 case IDC_ENCODING_WINDOWS1258: OverrideEncoding(id); break; | 416 case IDC_ENCODING_WINDOWS1258: |
| 417 browser_->OverrideEncoding(id); |
| 418 break; |
| 1433 | 419 |
| 1434 // Clipboard commands | 420 // Clipboard commands |
| 1435 case IDC_CUT: chrome::Cut(this); break; | 421 case IDC_CUT: |
| 1436 case IDC_COPY: chrome::Copy(this); break; | 422 Cut(browser_); |
| 1437 case IDC_PASTE: chrome::Paste(this); break; | 423 break; |
| 424 case IDC_COPY: |
| 425 Copy(browser_); |
| 426 break; |
| 427 case IDC_PASTE: |
| 428 Paste(browser_); |
| 429 break; |
| 1438 | 430 |
| 1439 // Find-in-page | 431 // Find-in-page |
| 1440 case IDC_FIND: chrome::Find(this); break; | 432 case IDC_FIND: |
| 1441 case IDC_FIND_NEXT: chrome::FindNext(this); break; | 433 Find(browser_); |
| 1442 case IDC_FIND_PREVIOUS: chrome::FindPrevious(this); break; | 434 break; |
| 435 case IDC_FIND_NEXT: |
| 436 FindNext(browser_); |
| 437 break; |
| 438 case IDC_FIND_PREVIOUS: |
| 439 FindPrevious(browser_); |
| 440 break; |
| 1443 | 441 |
| 1444 // Zoom | 442 // Zoom |
| 1445 case IDC_ZOOM_PLUS: | 443 case IDC_ZOOM_PLUS: |
| 1446 chrome::Zoom(this, content::PAGE_ZOOM_IN); | 444 Zoom(browser_, content::PAGE_ZOOM_IN); |
| 1447 break; | 445 break; |
| 1448 case IDC_ZOOM_NORMAL: | 446 case IDC_ZOOM_NORMAL: |
| 1449 chrome::Zoom(this, content::PAGE_ZOOM_RESET); | 447 Zoom(browser_, content::PAGE_ZOOM_RESET); |
| 1450 break; | 448 break; |
| 1451 case IDC_ZOOM_MINUS: | 449 case IDC_ZOOM_MINUS: |
| 1452 chrome::Zoom(this, content::PAGE_ZOOM_OUT); | 450 Zoom(browser_, content::PAGE_ZOOM_OUT); |
| 1453 break; | 451 break; |
| 1454 | 452 |
| 1455 // Focus various bits of UI | 453 // Focus various bits of UI |
| 1456 case IDC_FOCUS_TOOLBAR: chrome::FocusToolbar(this); break; | 454 case IDC_FOCUS_TOOLBAR: |
| 1457 case IDC_FOCUS_LOCATION: chrome::FocusLocationBar(this); break; | 455 FocusToolbar(browser_); |
| 1458 case IDC_FOCUS_SEARCH: chrome::FocusSearch(this); break; | 456 break; |
| 1459 case IDC_FOCUS_MENU_BAR: chrome::FocusAppMenu(this); break; | 457 case IDC_FOCUS_LOCATION: |
| 458 FocusLocationBar(browser_); |
| 459 break; |
| 460 case IDC_FOCUS_SEARCH: |
| 461 FocusSearch(browser_); |
| 462 break; |
| 463 case IDC_FOCUS_MENU_BAR: |
| 464 FocusAppMenu(browser_); |
| 465 break; |
| 1460 case IDC_FOCUS_BOOKMARKS: | 466 case IDC_FOCUS_BOOKMARKS: |
| 1461 chrome::FocusBookmarksToolbar(this); | 467 FocusBookmarksToolbar(browser_); |
| 1462 break; | 468 break; |
| 1463 case IDC_FOCUS_NEXT_PANE: chrome::FocusNextPane(this); break; | 469 case IDC_FOCUS_NEXT_PANE: |
| 1464 case IDC_FOCUS_PREVIOUS_PANE: chrome::FocusPreviousPane(this); break; | 470 FocusNextPane(browser_); |
| 471 break; |
| 472 case IDC_FOCUS_PREVIOUS_PANE: |
| 473 FocusPreviousPane(browser_); |
| 474 break; |
| 1465 | 475 |
| 1466 // Show various bits of UI | 476 // Show various bits of UI |
| 1467 case IDC_OPEN_FILE: OpenFile(); break; | 477 case IDC_OPEN_FILE: |
| 1468 case IDC_CREATE_SHORTCUTS: OpenCreateShortcutsDialog(); break; | 478 browser_->OpenFile(); |
| 479 break; |
| 480 case IDC_CREATE_SHORTCUTS: |
| 481 browser_->OpenCreateShortcutsDialog(); |
| 482 break; |
| 1469 case IDC_DEV_TOOLS: | 483 case IDC_DEV_TOOLS: |
| 1470 chrome::ToggleDevToolsWindow(this, DEVTOOLS_TOGGLE_ACTION_NONE); | 484 ToggleDevToolsWindow(browser_, DEVTOOLS_TOGGLE_ACTION_NONE); |
| 1471 break; | 485 break; |
| 1472 case IDC_DEV_TOOLS_CONSOLE: | 486 case IDC_DEV_TOOLS_CONSOLE: |
| 1473 chrome::ToggleDevToolsWindow(this, DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE); | 487 ToggleDevToolsWindow(browser_, DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE); |
| 1474 break; | 488 break; |
| 1475 case IDC_DEV_TOOLS_INSPECT: | 489 case IDC_DEV_TOOLS_INSPECT: |
| 1476 chrome::ToggleDevToolsWindow(this, DEVTOOLS_TOGGLE_ACTION_INSPECT); | 490 ToggleDevToolsWindow(browser_, DEVTOOLS_TOGGLE_ACTION_INSPECT); |
| 1477 break; | 491 break; |
| 1478 case IDC_TASK_MANAGER: | 492 case IDC_TASK_MANAGER: |
| 1479 chrome::OpenTaskManager(this, false); | 493 OpenTaskManager(browser_, false); |
| 1480 break; | 494 break; |
| 1481 case IDC_VIEW_BACKGROUND_PAGES: | 495 case IDC_VIEW_BACKGROUND_PAGES: |
| 1482 chrome::OpenTaskManager(this, true); | 496 OpenTaskManager(browser_, true); |
| 1483 break; | 497 break; |
| 1484 case IDC_FEEDBACK: | 498 case IDC_FEEDBACK: |
| 1485 chrome::OpenFeedbackDialog(this); | 499 OpenFeedbackDialog(browser_); |
| 1486 break; | 500 break; |
| 1487 | 501 |
| 1488 case IDC_SHOW_BOOKMARK_BAR: chrome::ToggleBookmarkBar(this); break; | 502 case IDC_SHOW_BOOKMARK_BAR: |
| 1489 case IDC_PROFILING_ENABLED: Profiling::Toggle(); break; | 503 ToggleBookmarkBar(browser_); |
| 504 break; |
| 505 case IDC_PROFILING_ENABLED: |
| 506 Profiling::Toggle(); |
| 507 break; |
| 1490 | 508 |
| 1491 case IDC_SHOW_BOOKMARK_MANAGER: chrome::ShowBookmarkManager(this);break; | 509 case IDC_SHOW_BOOKMARK_MANAGER: |
| 1492 case IDC_SHOW_APP_MENU: chrome::ShowAppMenu(this); break; | 510 ShowBookmarkManager(browser_); |
| 1493 case IDC_SHOW_AVATAR_MENU: chrome::ShowAvatarMenu(this); break; | 511 break; |
| 1494 case IDC_SHOW_HISTORY: chrome::ShowHistory(this); break; | 512 case IDC_SHOW_APP_MENU: |
| 1495 case IDC_SHOW_DOWNLOADS: chrome::ShowDownloads(this); break; | 513 ShowAppMenu(browser_); |
| 1496 case IDC_MANAGE_EXTENSIONS: chrome::ShowExtensions(this); break; | 514 break; |
| 1497 case IDC_OPTIONS: chrome::ShowSettings(this); break; | 515 case IDC_SHOW_AVATAR_MENU: |
| 516 ShowAvatarMenu(browser_); |
| 517 break; |
| 518 case IDC_SHOW_HISTORY: |
| 519 ShowHistory(browser_); |
| 520 break; |
| 521 case IDC_SHOW_DOWNLOADS: |
| 522 ShowDownloads(browser_); |
| 523 break; |
| 524 case IDC_MANAGE_EXTENSIONS: |
| 525 ShowExtensions(browser_); |
| 526 break; |
| 527 case IDC_OPTIONS: |
| 528 ShowSettings(browser_); |
| 529 break; |
| 1498 case IDC_EDIT_SEARCH_ENGINES: | 530 case IDC_EDIT_SEARCH_ENGINES: |
| 1499 chrome::ShowSearchEngineSettings(this); | 531 ShowSearchEngineSettings(browser_); |
| 1500 break; | 532 break; |
| 1501 case IDC_VIEW_PASSWORDS: chrome::ShowPasswordManager(this);break; | 533 case IDC_VIEW_PASSWORDS: |
| 534 ShowPasswordManager(browser_); |
| 535 break; |
| 1502 case IDC_CLEAR_BROWSING_DATA: | 536 case IDC_CLEAR_BROWSING_DATA: |
| 1503 chrome::ShowClearBrowsingDataDialog(this); | 537 ShowClearBrowsingDataDialog(browser_); |
| 1504 break; | 538 break; |
| 1505 case IDC_IMPORT_SETTINGS: chrome::ShowImportDialog(this); break; | 539 case IDC_IMPORT_SETTINGS: |
| 1506 case IDC_ABOUT: chrome::ShowAboutChrome(this); break; | 540 ShowImportDialog(browser_); |
| 541 break; |
| 542 case IDC_ABOUT: |
| 543 ShowAboutChrome(browser_); |
| 544 break; |
| 1507 case IDC_UPGRADE_DIALOG: | 545 case IDC_UPGRADE_DIALOG: |
| 1508 chrome::OpenUpdateChromeDialog(this); | 546 OpenUpdateChromeDialog(browser_); |
| 1509 break; | 547 break; |
| 1510 case IDC_VIEW_INCOMPATIBILITIES: | 548 case IDC_VIEW_INCOMPATIBILITIES: |
| 1511 chrome::ShowConflicts(this); | 549 ShowConflicts(browser_); |
| 1512 break; | 550 break; |
| 1513 case IDC_HELP_PAGE_VIA_KEYBOARD: | 551 case IDC_HELP_PAGE_VIA_KEYBOARD: |
| 1514 chrome::ShowHelp(this, chrome::HELP_SOURCE_KEYBOARD); | 552 ShowHelp(browser_, HELP_SOURCE_KEYBOARD); |
| 1515 break; | 553 break; |
| 1516 case IDC_HELP_PAGE_VIA_MENU: | 554 case IDC_HELP_PAGE_VIA_MENU: |
| 1517 chrome::ShowHelp(this, chrome::HELP_SOURCE_MENU); | 555 ShowHelp(browser_, HELP_SOURCE_MENU); |
| 1518 break; | 556 break; |
| 1519 case IDC_SHOW_SYNC_SETUP: | 557 case IDC_SHOW_SYNC_SETUP: |
| 1520 chrome::ShowSyncSetup(this, SyncPromoUI::SOURCE_MENU); | 558 ShowSyncSetup(browser_, SyncPromoUI::SOURCE_MENU); |
| 1521 break; | 559 break; |
| 1522 case IDC_TOGGLE_SPEECH_INPUT: chrome::ToggleSpeechInput(this); break; | 560 case IDC_TOGGLE_SPEECH_INPUT: |
| 561 ToggleSpeechInput(browser_); |
| 562 break; |
| 1523 | 563 |
| 1524 default: | 564 default: |
| 1525 LOG(WARNING) << "Received Unimplemented Command: " << id; | 565 LOG(WARNING) << "Received Unimplemented Command: " << id; |
| 1526 break; | 566 break; |
| 1527 } | 567 } |
| 1528 } | 568 } |
| 1529 | 569 |
| 1530 //////////////////////////////////////////////////////////////////////////////// | 570 //////////////////////////////////////////////////////////////////////////////// |
| 1531 // Browser, TabRestoreServiceObserver: | 571 // BrowserCommandController, content::NotificationObserver implementation: |
| 1532 | 572 |
| 1533 void Browser::TabRestoreServiceChanged(TabRestoreService* service) { | 573 void BrowserCommandController::Observe( |
| 1534 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, | 574 int type, |
| 1535 !service->entries().empty()); | 575 const content::NotificationSource& source, |
| 1536 } | 576 const content::NotificationDetails& details) { |
| 1537 | |
| 1538 void Browser::TabRestoreServiceDestroyed(TabRestoreService* service) { | |
| 1539 if (!tab_restore_service_) | |
| 1540 return; | |
| 1541 | |
| 1542 DCHECK_EQ(tab_restore_service_, service); | |
| 1543 tab_restore_service_->RemoveObserver(this); | |
| 1544 tab_restore_service_ = NULL; | |
| 1545 } | |
| 1546 | |
| 1547 // Centralized method for creating a TabContents, configuring and | |
| 1548 // installing all its supporting objects and observers. | |
| 1549 TabContents* Browser::TabContentsFactory( | |
| 1550 Profile* profile, | |
| 1551 SiteInstance* site_instance, | |
| 1552 int routing_id, | |
| 1553 const WebContents* base_web_contents, | |
| 1554 content::SessionStorageNamespace* session_storage_namespace) { | |
| 1555 WebContents* new_contents = WebContents::Create( | |
| 1556 profile, site_instance, routing_id, base_web_contents, | |
| 1557 session_storage_namespace); | |
| 1558 TabContents* tab_contents = new TabContents(new_contents); | |
| 1559 return tab_contents; | |
| 1560 } | |
| 1561 | |
| 1562 /////////////////////////////////////////////////////////////////////////////// | |
| 1563 // Browser, TabStripModelDelegate implementation: | |
| 1564 | |
| 1565 TabContents* Browser::AddBlankTab(bool foreground) { | |
| 1566 return AddBlankTabAt(-1, foreground); | |
| 1567 } | |
| 1568 | |
| 1569 TabContents* Browser::AddBlankTabAt(int index, bool foreground) { | |
| 1570 // Time new tab page creation time. We keep track of the timing data in | |
| 1571 // WebContents, but we want to include the time it takes to create the | |
| 1572 // WebContents object too. | |
| 1573 base::TimeTicks new_tab_start_time = base::TimeTicks::Now(); | |
| 1574 browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL), | |
| 1575 content::PAGE_TRANSITION_TYPED); | |
| 1576 params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; | |
| 1577 params.tabstrip_index = index; | |
| 1578 browser::Navigate(¶ms); | |
| 1579 params.target_contents->web_contents()->SetNewTabStartTime( | |
| 1580 new_tab_start_time); | |
| 1581 return params.target_contents; | |
| 1582 } | |
| 1583 | |
| 1584 Browser* Browser::CreateNewStripWithContents( | |
| 1585 TabContents* detached_contents, | |
| 1586 const gfx::Rect& window_bounds, | |
| 1587 const DockInfo& dock_info, | |
| 1588 bool maximize) { | |
| 1589 DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP)); | |
| 1590 | |
| 1591 gfx::Rect new_window_bounds = window_bounds; | |
| 1592 if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize)) | |
| 1593 dock_info.AdjustOtherWindowBounds(); | |
| 1594 | |
| 1595 // Create an empty new browser window the same size as the old one. | |
| 1596 Browser* browser = new Browser(TYPE_TABBED, profile_); | |
| 1597 browser->set_override_bounds(new_window_bounds); | |
| 1598 browser->set_initial_show_state( | |
| 1599 maximize ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL); | |
| 1600 browser->InitBrowserWindow(); | |
| 1601 browser->tab_strip_model()->AppendTabContents(detached_contents, true); | |
| 1602 // Make sure the loading state is updated correctly, otherwise the throbber | |
| 1603 // won't start if the page is loading. | |
| 1604 browser->LoadingStateChanged(detached_contents->web_contents()); | |
| 1605 return browser; | |
| 1606 } | |
| 1607 | |
| 1608 int Browser::GetDragActions() const { | |
| 1609 return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ? | |
| 1610 TabStripModelDelegate::TAB_MOVE_ACTION : 0); | |
| 1611 } | |
| 1612 | |
| 1613 TabContents* Browser::CreateTabContentsForURL( | |
| 1614 const GURL& url, const content::Referrer& referrer, Profile* profile, | |
| 1615 content::PageTransition transition, bool defer_load, | |
| 1616 SiteInstance* instance) const { | |
| 1617 TabContents* contents = TabContentsFactory(profile, instance, | |
| 1618 MSG_ROUTING_NONE, GetActiveWebContents(), NULL); | |
| 1619 if (!defer_load) { | |
| 1620 // Load the initial URL before adding the new tab contents to the tab strip | |
| 1621 // so that the tab contents has navigation state. | |
| 1622 contents->web_contents()->GetController().LoadURL( | |
| 1623 url, referrer, transition, std::string()); | |
| 1624 } | |
| 1625 | |
| 1626 return contents; | |
| 1627 } | |
| 1628 | |
| 1629 bool Browser::CanDuplicateContentsAt(int index) { | |
| 1630 NavigationController& nc = GetWebContentsAt(index)->GetController(); | |
| 1631 return nc.GetWebContents() && nc.GetLastCommittedEntry(); | |
| 1632 } | |
| 1633 | |
| 1634 void Browser::DuplicateContentsAt(int index) { | |
| 1635 TabContents* contents = GetTabContentsAt(index); | |
| 1636 CHECK(contents); | |
| 1637 TabContents* contents_dupe = contents->Clone(); | |
| 1638 | |
| 1639 bool pinned = false; | |
| 1640 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) { | |
| 1641 // If this is a tabbed browser, just create a duplicate tab inside the same | |
| 1642 // window next to the tab being duplicated. | |
| 1643 int index = tab_strip_model_->GetIndexOfTabContents(contents); | |
| 1644 pinned = IsTabPinned(index); | |
| 1645 int add_types = TabStripModel::ADD_ACTIVE | | |
| 1646 TabStripModel::ADD_INHERIT_GROUP | | |
| 1647 (pinned ? TabStripModel::ADD_PINNED : 0); | |
| 1648 tab_strip_model_->InsertTabContentsAt(index + 1, contents_dupe, add_types); | |
| 1649 } else { | |
| 1650 Browser* browser = NULL; | |
| 1651 if (is_app()) { | |
| 1652 CHECK(!is_type_popup()); | |
| 1653 CHECK(!is_type_panel()); | |
| 1654 browser = Browser::CreateWithParams( | |
| 1655 Browser::CreateParams::CreateForApp( | |
| 1656 TYPE_POPUP, app_name_, gfx::Rect(),profile_)); | |
| 1657 } else if (is_type_popup()) { | |
| 1658 browser = Browser::CreateWithParams( | |
| 1659 Browser::CreateParams(TYPE_POPUP, profile_)); | |
| 1660 } | |
| 1661 | |
| 1662 // Preserve the size of the original window. The new window has already | |
| 1663 // been given an offset by the OS, so we shouldn't copy the old bounds. | |
| 1664 BrowserWindow* new_window = browser->window(); | |
| 1665 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(), | |
| 1666 window()->GetRestoredBounds().size())); | |
| 1667 | |
| 1668 // We need to show the browser now. Otherwise ContainerWin assumes the | |
| 1669 // WebContents is invisible and won't size it. | |
| 1670 browser->window()->Show(); | |
| 1671 | |
| 1672 // The page transition below is only for the purpose of inserting the tab. | |
| 1673 browser->AddTab(contents_dupe, content::PAGE_TRANSITION_LINK); | |
| 1674 } | |
| 1675 | |
| 1676 SessionService* session_service = | |
| 1677 SessionServiceFactory::GetForProfileIfExisting(profile_); | |
| 1678 if (session_service) | |
| 1679 session_service->TabRestored(contents_dupe, pinned); | |
| 1680 } | |
| 1681 | |
| 1682 void Browser::CloseFrameAfterDragSession() { | |
| 1683 #if !defined(OS_MACOSX) | |
| 1684 // This is scheduled to run after we return to the message loop because | |
| 1685 // otherwise the frame will think the drag session is still active and ignore | |
| 1686 // the request. | |
| 1687 // TODO(port): figure out what is required here in a cross-platform world | |
| 1688 MessageLoop::current()->PostTask( | |
| 1689 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr())); | |
| 1690 #endif | |
| 1691 } | |
| 1692 | |
| 1693 void Browser::CreateHistoricalTab(TabContents* contents) { | |
| 1694 // We don't create historical tabs for incognito windows or windows without | |
| 1695 // profiles. | |
| 1696 if (!profile() || profile()->IsOffTheRecord()) | |
| 1697 return; | |
| 1698 | |
| 1699 // We don't create historical tabs for print preview tabs. | |
| 1700 if (contents->web_contents()->GetURL() == GURL(chrome::kChromeUIPrintURL)) | |
| 1701 return; | |
| 1702 | |
| 1703 TabRestoreService* service = | |
| 1704 TabRestoreServiceFactory::GetForProfile(profile()); | |
| 1705 | |
| 1706 // We only create historical tab entries for tabbed browser windows. | |
| 1707 if (service && CanSupportWindowFeature(FEATURE_TABSTRIP)) { | |
| 1708 service->CreateHistoricalTab(contents->web_contents(), | |
| 1709 tab_strip_model_->GetIndexOfTabContents(contents)); | |
| 1710 } | |
| 1711 } | |
| 1712 | |
| 1713 bool Browser::RunUnloadListenerBeforeClosing(TabContents* contents) { | |
| 1714 return Browser::RunUnloadEventsHelper(contents->web_contents()); | |
| 1715 } | |
| 1716 | |
| 1717 bool Browser::CanBookmarkAllTabs() const { | |
| 1718 BookmarkModel* model = profile()->GetBookmarkModel(); | |
| 1719 return (model && model->IsLoaded()) && | |
| 1720 tab_count() > 1 && | |
| 1721 profile()->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled); | |
| 1722 } | |
| 1723 | |
| 1724 void Browser::BookmarkAllTabs() { | |
| 1725 BookmarkEditor::ShowBookmarkAllTabsDialog(this); | |
| 1726 } | |
| 1727 | |
| 1728 bool Browser::CanRestoreTab() { | |
| 1729 return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB); | |
| 1730 } | |
| 1731 | |
| 1732 void Browser::RestoreTab() { | |
| 1733 content::RecordAction(UserMetricsAction("RestoreTab")); | |
| 1734 TabRestoreService* service = | |
| 1735 TabRestoreServiceFactory::GetForProfile(profile_); | |
| 1736 if (!service) | |
| 1737 return; | |
| 1738 | |
| 1739 service->RestoreMostRecentEntry(tab_restore_service_delegate()); | |
| 1740 } | |
| 1741 | |
| 1742 /////////////////////////////////////////////////////////////////////////////// | |
| 1743 // Browser, TabStripModelObserver implementation: | |
| 1744 | |
| 1745 void Browser::TabInsertedAt(TabContents* contents, | |
| 1746 int index, | |
| 1747 bool foreground) { | |
| 1748 SetAsDelegate(contents, this); | |
| 1749 contents->restore_tab_helper()->SetWindowID(session_id()); | |
| 1750 | |
| 1751 SyncHistoryWithTabs(index); | |
| 1752 | |
| 1753 // Make sure the loading state is updated correctly, otherwise the throbber | |
| 1754 // won't start if the page is loading. | |
| 1755 LoadingStateChanged(contents->web_contents()); | |
| 1756 | |
| 1757 // If the tab crashes in the beforeunload or unload handler, it won't be | |
| 1758 // able to ack. But we know we can close it. | |
| 1759 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | |
| 1760 content::Source<WebContents>(contents->web_contents())); | |
| 1761 | |
| 1762 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED, | |
| 1763 content::Source<WebContents>(contents->web_contents())); | |
| 1764 | |
| 1765 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_DETACHED, | |
| 1766 content::Source<WebContents>(contents->web_contents())); | |
| 1767 } | |
| 1768 | |
| 1769 void Browser::TabClosingAt(TabStripModel* tab_strip_model, | |
| 1770 TabContents* contents, | |
| 1771 int index) { | |
| 1772 fullscreen_controller_->OnTabClosing(contents->web_contents()); | |
| 1773 content::NotificationService::current()->Notify( | |
| 1774 chrome::NOTIFICATION_TAB_CLOSING, | |
| 1775 content::Source<NavigationController>( | |
| 1776 &contents->web_contents()->GetController()), | |
| 1777 content::NotificationService::NoDetails()); | |
| 1778 | |
| 1779 // Sever the WebContents' connection back to us. | |
| 1780 SetAsDelegate(contents, NULL); | |
| 1781 } | |
| 1782 | |
| 1783 void Browser::TabDetachedAt(TabContents* contents, int index) { | |
| 1784 TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH); | |
| 1785 } | |
| 1786 | |
| 1787 void Browser::TabDeactivated(TabContents* contents) { | |
| 1788 fullscreen_controller_->OnTabDeactivated(contents); | |
| 1789 search_delegate_->OnTabDeactivated(contents); | |
| 1790 | |
| 1791 if (instant()) | |
| 1792 instant()->Hide(); | |
| 1793 | |
| 1794 // Save what the user's currently typing, so it can be restored when we | |
| 1795 // switch back to this tab. | |
| 1796 window_->GetLocationBar()->SaveStateToContents(contents->web_contents()); | |
| 1797 } | |
| 1798 | |
| 1799 void Browser::ActiveTabChanged(TabContents* old_contents, | |
| 1800 TabContents* new_contents, | |
| 1801 int index, | |
| 1802 bool user_gesture) { | |
| 1803 // On some platforms we want to automatically reload tabs that are | |
| 1804 // killed when the user selects them. | |
| 1805 bool did_reload = false; | |
| 1806 if (user_gesture && new_contents->web_contents()->GetCrashedStatus() == | |
| 1807 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) { | |
| 1808 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); | |
| 1809 if (parsed_command_line.HasSwitch(switches::kReloadKilledTabs)) { | |
| 1810 LOG(WARNING) << "Reloading killed tab at " << index; | |
| 1811 static int reload_count = 0; | |
| 1812 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 1813 "Tabs.SadTab.ReloadCount", ++reload_count, 1, 1000, 50); | |
| 1814 chrome::Reload(this, CURRENT_TAB); | |
| 1815 did_reload = true; | |
| 1816 } | |
| 1817 } | |
| 1818 | |
| 1819 // Discarded tabs always get reloaded. | |
| 1820 if (!did_reload && IsTabDiscarded(index)) { | |
| 1821 LOG(WARNING) << "Reloading discarded tab at " << index; | |
| 1822 static int reload_count = 0; | |
| 1823 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 1824 "Tabs.Discard.ReloadCount", ++reload_count, 1, 1000, 50); | |
| 1825 chrome::Reload(this, CURRENT_TAB); | |
| 1826 } | |
| 1827 | |
| 1828 // If we have any update pending, do it now. | |
| 1829 if (chrome_updater_factory_.HasWeakPtrs() && old_contents) | |
| 1830 ProcessPendingUIUpdates(); | |
| 1831 | |
| 1832 // Propagate the profile to the location bar. | |
| 1833 UpdateToolbar(true); | |
| 1834 | |
| 1835 // Propagate tab state to toolbar, tab-strip, etc. | |
| 1836 UpdateSearchState(new_contents); | |
| 1837 | |
| 1838 // Update reload/stop state. | |
| 1839 UpdateReloadStopState(new_contents->web_contents()->IsLoading(), true); | |
| 1840 | |
| 1841 // Update commands to reflect current state. | |
| 1842 UpdateCommandsForTabState(); | |
| 1843 | |
| 1844 // Reset the status bubble. | |
| 1845 StatusBubble* status_bubble = GetStatusBubble(); | |
| 1846 if (status_bubble) { | |
| 1847 status_bubble->Hide(); | |
| 1848 | |
| 1849 // Show the loading state (if any). | |
| 1850 status_bubble->SetStatus( | |
| 1851 GetActiveTabContents()->core_tab_helper()->GetStatusText()); | |
| 1852 } | |
| 1853 | |
| 1854 if (HasFindBarController()) { | |
| 1855 find_bar_controller_->ChangeTabContents(new_contents); | |
| 1856 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true); | |
| 1857 } | |
| 1858 | |
| 1859 // Update sessions. Don't force creation of sessions. If sessions doesn't | |
| 1860 // exist, the change will be picked up by sessions when created. | |
| 1861 SessionService* session_service = | |
| 1862 SessionServiceFactory::GetForProfileIfExisting(profile_); | |
| 1863 if (session_service && !tab_strip_model_->closing_all()) { | |
| 1864 session_service->SetSelectedTabInWindow(session_id(), active_index()); | |
| 1865 } | |
| 1866 | |
| 1867 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH); | |
| 1868 } | |
| 1869 | |
| 1870 void Browser::TabMoved(TabContents* contents, | |
| 1871 int from_index, | |
| 1872 int to_index) { | |
| 1873 DCHECK(from_index >= 0 && to_index >= 0); | |
| 1874 // Notify the history service. | |
| 1875 SyncHistoryWithTabs(std::min(from_index, to_index)); | |
| 1876 } | |
| 1877 | |
| 1878 void Browser::TabReplacedAt(TabStripModel* tab_strip_model, | |
| 1879 TabContents* old_contents, | |
| 1880 TabContents* new_contents, | |
| 1881 int index) { | |
| 1882 TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE); | |
| 1883 TabInsertedAt(new_contents, index, (index == active_index())); | |
| 1884 | |
| 1885 int entry_count = | |
| 1886 new_contents->web_contents()->GetController().GetEntryCount(); | |
| 1887 if (entry_count > 0) { | |
| 1888 // Send out notification so that observers are updated appropriately. | |
| 1889 new_contents->web_contents()->GetController().NotifyEntryChanged( | |
| 1890 new_contents->web_contents()->GetController().GetEntryAtIndex( | |
| 1891 entry_count - 1), | |
| 1892 entry_count - 1); | |
| 1893 } | |
| 1894 | |
| 1895 SessionService* session_service = | |
| 1896 SessionServiceFactory::GetForProfile(profile()); | |
| 1897 if (session_service) { | |
| 1898 // The new_contents may end up with a different navigation stack. Force | |
| 1899 // the session service to update itself. | |
| 1900 session_service->TabRestored(new_contents, IsTabPinned(index)); | |
| 1901 } | |
| 1902 | |
| 1903 content::DevToolsManager::GetInstance()->ContentsReplaced( | |
| 1904 old_contents->web_contents(), new_contents->web_contents()); | |
| 1905 } | |
| 1906 | |
| 1907 void Browser::TabPinnedStateChanged(TabContents* contents, int index) { | |
| 1908 SessionService* session_service = | |
| 1909 SessionServiceFactory::GetForProfileIfExisting(profile()); | |
| 1910 if (session_service) { | |
| 1911 session_service->SetPinnedState( | |
| 1912 session_id(), | |
| 1913 GetTabContentsAt(index)->restore_tab_helper()->session_id(), | |
| 1914 IsTabPinned(index)); | |
| 1915 } | |
| 1916 } | |
| 1917 | |
| 1918 void Browser::TabStripEmpty() { | |
| 1919 // Close the frame after we return to the message loop (not immediately, | |
| 1920 // otherwise it will destroy this object before the stack has a chance to | |
| 1921 // cleanly unwind.) | |
| 1922 // Note: This will be called several times if TabStripEmpty is called several | |
| 1923 // times. This is because it does not close the window if tabs are | |
| 1924 // still present. | |
| 1925 MessageLoop::current()->PostTask( | |
| 1926 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr())); | |
| 1927 // Set is_attempting_to_close_browser_ here, so that extensions, etc, do not | |
| 1928 // attempt to add tabs to the browser before it closes. | |
| 1929 is_attempting_to_close_browser_ = true; | |
| 1930 } | |
| 1931 | |
| 1932 bool Browser::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, | |
| 1933 bool* is_keyboard_shortcut) { | |
| 1934 // Escape exits tabbed fullscreen mode. | |
| 1935 // TODO(koz): Write a test for this http://crbug.com/100441. | |
| 1936 if (event.windowsKeyCode == 27 && | |
| 1937 fullscreen_controller_->HandleUserPressedEscape()) { | |
| 1938 return true; | |
| 1939 } | |
| 1940 return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut); | |
| 1941 } | |
| 1942 | |
| 1943 void Browser::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { | |
| 1944 window()->HandleKeyboardEvent(event); | |
| 1945 } | |
| 1946 | |
| 1947 void Browser::OnAcceptFullscreenPermission( | |
| 1948 const GURL& url, | |
| 1949 FullscreenExitBubbleType bubble_type) { | |
| 1950 fullscreen_controller_->OnAcceptFullscreenPermission(url, bubble_type); | |
| 1951 } | |
| 1952 | |
| 1953 void Browser::OnDenyFullscreenPermission(FullscreenExitBubbleType bubble_type) { | |
| 1954 fullscreen_controller_->OnDenyFullscreenPermission(bubble_type); | |
| 1955 } | |
| 1956 | |
| 1957 bool Browser::TabsNeedBeforeUnloadFired() { | |
| 1958 if (tabs_needing_before_unload_fired_.empty()) { | |
| 1959 for (int i = 0; i < tab_count(); ++i) { | |
| 1960 WebContents* contents = GetTabContentsAt(i)->web_contents(); | |
| 1961 if (contents->NeedToFireBeforeUnload()) | |
| 1962 tabs_needing_before_unload_fired_.insert(contents); | |
| 1963 } | |
| 1964 } | |
| 1965 return !tabs_needing_before_unload_fired_.empty(); | |
| 1966 } | |
| 1967 | |
| 1968 bool Browser::IsFullscreenForTabOrPending() const { | |
| 1969 return fullscreen_controller_->IsFullscreenForTabOrPending(); | |
| 1970 } | |
| 1971 | |
| 1972 bool Browser::IsMouseLocked() const { | |
| 1973 return fullscreen_controller_->IsMouseLocked(); | |
| 1974 } | |
| 1975 | |
| 1976 void Browser::OnWindowDidShow() { | |
| 1977 if (window_has_shown_) | |
| 1978 return; | |
| 1979 window_has_shown_ = true; | |
| 1980 | |
| 1981 // Nothing to do for non-tabbed windows. | |
| 1982 if (!is_type_tabbed()) | |
| 1983 return; | |
| 1984 | |
| 1985 // Show any pending global error bubble. | |
| 1986 GlobalErrorService* service = | |
| 1987 GlobalErrorServiceFactory::GetForProfile(profile()); | |
| 1988 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView(); | |
| 1989 if (error) | |
| 1990 error->ShowBubbleView(this); | |
| 1991 } | |
| 1992 | |
| 1993 void Browser::ShowFirstRunBubble() { | |
| 1994 window()->GetLocationBar()->ShowFirstRunBubble(); | |
| 1995 } | |
| 1996 | |
| 1997 /////////////////////////////////////////////////////////////////////////////// | |
| 1998 // Browser, protected: | |
| 1999 | |
| 2000 BrowserWindow* Browser::CreateBrowserWindow() { | |
| 2001 bool create_panel = false; | |
| 2002 #if defined(USE_ASH) | |
| 2003 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 2004 ash::switches::kAuraPanelManager)) | |
| 2005 create_panel = is_type_panel(); | |
| 2006 #elif !defined(OS_CHROMEOS) | |
| 2007 create_panel = is_type_panel(); | |
| 2008 #endif | |
| 2009 if (create_panel) | |
| 2010 return PanelManager::GetInstance()->CreatePanel(this)->browser_window(); | |
| 2011 | |
| 2012 return BrowserWindow::CreateBrowserWindow(this); | |
| 2013 } | |
| 2014 | |
| 2015 /////////////////////////////////////////////////////////////////////////////// | |
| 2016 // Browser, content::WebContentsDelegate implementation: | |
| 2017 | |
| 2018 WebContents* Browser::OpenURLFromTab(WebContents* source, | |
| 2019 const OpenURLParams& params) { | |
| 2020 browser::NavigateParams nav_params(this, params.url, params.transition); | |
| 2021 nav_params.source_contents = GetTabContentsAt( | |
| 2022 tab_strip_model_->GetIndexOfWebContents(source)); | |
| 2023 nav_params.referrer = params.referrer; | |
| 2024 nav_params.disposition = params.disposition; | |
| 2025 nav_params.tabstrip_add_types = TabStripModel::ADD_NONE; | |
| 2026 nav_params.window_action = browser::NavigateParams::SHOW_WINDOW; | |
| 2027 nav_params.user_gesture = true; | |
| 2028 nav_params.override_encoding = params.override_encoding; | |
| 2029 nav_params.is_renderer_initiated = params.is_renderer_initiated; | |
| 2030 nav_params.transferred_global_request_id = | |
| 2031 params.transferred_global_request_id; | |
| 2032 browser::Navigate(&nav_params); | |
| 2033 | |
| 2034 return nav_params.target_contents ? | |
| 2035 nav_params.target_contents->web_contents() : NULL; | |
| 2036 } | |
| 2037 | |
| 2038 void Browser::NavigationStateChanged(const WebContents* source, | |
| 2039 unsigned changed_flags) { | |
| 2040 // Only update the UI when something visible has changed. | |
| 2041 if (changed_flags) | |
| 2042 ScheduleUIUpdate(source, changed_flags); | |
| 2043 | |
| 2044 // We can synchronously update commands since they will only change once per | |
| 2045 // navigation, so we don't have to worry about flickering. We do, however, | |
| 2046 // need to update the command state early on load to always present usable | |
| 2047 // actions in the face of slow-to-commit pages. | |
| 2048 if (changed_flags & (content::INVALIDATE_TYPE_URL | | |
| 2049 content::INVALIDATE_TYPE_LOAD)) | |
| 2050 UpdateCommandsForTabState(); | |
| 2051 } | |
| 2052 | |
| 2053 void Browser::AddNewContents(WebContents* source, | |
| 2054 WebContents* new_contents, | |
| 2055 WindowOpenDisposition disposition, | |
| 2056 const gfx::Rect& initial_pos, | |
| 2057 bool user_gesture) { | |
| 2058 // No code for this yet. | |
| 2059 DCHECK(disposition != SAVE_TO_DISK); | |
| 2060 // Can't create a new contents for the current tab - invalid case. | |
| 2061 DCHECK(disposition != CURRENT_TAB); | |
| 2062 | |
| 2063 TabContents* source_tab_contents = NULL; | |
| 2064 BlockedContentTabHelper* source_blocked_content = NULL; | |
| 2065 TabContents* new_tab_contents = TabContents::FromWebContents(new_contents); | |
| 2066 if (!new_tab_contents) { | |
| 2067 new_tab_contents = new TabContents(new_contents); | |
| 2068 } | |
| 2069 if (source) { | |
| 2070 source_tab_contents = TabContents::FromWebContents(source); | |
| 2071 source_blocked_content = source_tab_contents->blocked_content_tab_helper(); | |
| 2072 } | |
| 2073 | |
| 2074 if (source_tab_contents) { | |
| 2075 // Handle blocking of all contents. | |
| 2076 if (source_blocked_content->all_contents_blocked()) { | |
| 2077 source_blocked_content->AddTabContents(new_tab_contents, | |
| 2078 disposition, | |
| 2079 initial_pos, | |
| 2080 user_gesture); | |
| 2081 return; | |
| 2082 } | |
| 2083 | |
| 2084 // Handle blocking of popups. | |
| 2085 if ((disposition == NEW_POPUP) && !user_gesture && | |
| 2086 !CommandLine::ForCurrentProcess()->HasSwitch( | |
| 2087 switches::kDisablePopupBlocking)) { | |
| 2088 // Unrequested popups from normal pages are constrained unless they're in | |
| 2089 // the whitelist. The popup owner will handle checking this. | |
| 2090 GetConstrainingTabContents(source_tab_contents)-> | |
| 2091 blocked_content_tab_helper()-> | |
| 2092 AddPopup(new_tab_contents, initial_pos, user_gesture); | |
| 2093 return; | |
| 2094 } | |
| 2095 | |
| 2096 new_contents->GetRenderViewHost()->DisassociateFromPopupCount(); | |
| 2097 } | |
| 2098 | |
| 2099 browser::NavigateParams params(this, new_tab_contents); | |
| 2100 params.source_contents = source ? | |
| 2101 GetTabContentsAt(tab_strip_model_->GetIndexOfWebContents(source)): NULL; | |
| 2102 params.disposition = disposition; | |
| 2103 params.window_bounds = initial_pos; | |
| 2104 params.window_action = browser::NavigateParams::SHOW_WINDOW; | |
| 2105 params.user_gesture = user_gesture; | |
| 2106 browser::Navigate(¶ms); | |
| 2107 } | |
| 2108 | |
| 2109 void Browser::ActivateContents(WebContents* contents) { | |
| 2110 ActivateTabAt(tab_strip_model_->GetIndexOfWebContents(contents), false); | |
| 2111 window_->Activate(); | |
| 2112 } | |
| 2113 | |
| 2114 void Browser::DeactivateContents(WebContents* contents) { | |
| 2115 window_->Deactivate(); | |
| 2116 } | |
| 2117 | |
| 2118 void Browser::LoadingStateChanged(WebContents* source) { | |
| 2119 window_->UpdateLoadingAnimations(tab_strip_model_->TabsAreLoading()); | |
| 2120 window_->UpdateTitleBar(); | |
| 2121 | |
| 2122 WebContents* selected_contents = GetActiveWebContents(); | |
| 2123 if (source == selected_contents) { | |
| 2124 bool is_loading = source->IsLoading(); | |
| 2125 UpdateReloadStopState(is_loading, false); | |
| 2126 if (GetStatusBubble()) { | |
| 2127 GetStatusBubble()->SetStatus( | |
| 2128 GetActiveTabContents()->core_tab_helper()->GetStatusText()); | |
| 2129 } | |
| 2130 | |
| 2131 if (!is_loading && pending_web_app_action_ == UPDATE_SHORTCUT) { | |
| 2132 // Schedule a shortcut update when web application info is available if | |
| 2133 // last committed entry is not NULL. Last committed entry could be NULL | |
| 2134 // when an interstitial page is injected (e.g. bad https certificate, | |
| 2135 // malware site etc). When this happens, we abort the shortcut update. | |
| 2136 NavigationEntry* entry = source->GetController().GetLastCommittedEntry(); | |
| 2137 if (entry) { | |
| 2138 TabContents::FromWebContents(source)-> | |
| 2139 extension_tab_helper()->GetApplicationInfo(entry->GetPageID()); | |
| 2140 } else { | |
| 2141 pending_web_app_action_ = NONE; | |
| 2142 } | |
| 2143 } | |
| 2144 } | |
| 2145 } | |
| 2146 | |
| 2147 void Browser::CloseContents(WebContents* source) { | |
| 2148 if (is_attempting_to_close_browser_) { | |
| 2149 // If we're trying to close the browser, just clear the state related to | |
| 2150 // waiting for unload to fire. Don't actually try to close the tab as it | |
| 2151 // will go down the slow shutdown path instead of the fast path of killing | |
| 2152 // all the renderer processes. | |
| 2153 ClearUnloadState(source, true); | |
| 2154 return; | |
| 2155 } | |
| 2156 | |
| 2157 int index = tab_strip_model_->GetIndexOfWebContents(source); | |
| 2158 if (index == TabStripModel::kNoTab) { | |
| 2159 NOTREACHED() << "CloseContents called for tab not in our strip"; | |
| 2160 return; | |
| 2161 } | |
| 2162 tab_strip_model_->CloseTabContentsAt(index, | |
| 2163 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); | |
| 2164 } | |
| 2165 | |
| 2166 void Browser::MoveContents(WebContents* source, const gfx::Rect& pos) { | |
| 2167 if (!IsPopupOrPanel(source)) { | |
| 2168 NOTREACHED() << "moving invalid browser type"; | |
| 2169 return; | |
| 2170 } | |
| 2171 window_->SetBounds(pos); | |
| 2172 } | |
| 2173 | |
| 2174 void Browser::DetachContents(WebContents* source) { | |
| 2175 int index = tab_strip_model_->GetIndexOfWebContents(source); | |
| 2176 if (index >= 0) | |
| 2177 tab_strip_model_->DetachTabContentsAt(index); | |
| 2178 } | |
| 2179 | |
| 2180 bool Browser::IsPopupOrPanel(const WebContents* source) const { | |
| 2181 // A non-tabbed BROWSER is an unconstrained popup. | |
| 2182 return is_type_popup() || is_type_panel(); | |
| 2183 } | |
| 2184 | |
| 2185 void Browser::UpdateTargetURL(WebContents* source, int32 page_id, | |
| 2186 const GURL& url) { | |
| 2187 if (!GetStatusBubble()) | |
| 2188 return; | |
| 2189 | |
| 2190 if (source == GetActiveWebContents()) { | |
| 2191 PrefService* prefs = profile_->GetPrefs(); | |
| 2192 GetStatusBubble()->SetURL(url, prefs->GetString(prefs::kAcceptLanguages)); | |
| 2193 } | |
| 2194 } | |
| 2195 | |
| 2196 void Browser::ContentsMouseEvent( | |
| 2197 WebContents* source, const gfx::Point& location, bool motion) { | |
| 2198 if (!GetStatusBubble()) | |
| 2199 return; | |
| 2200 | |
| 2201 if (source == GetActiveWebContents()) { | |
| 2202 GetStatusBubble()->MouseMoved(location, !motion); | |
| 2203 if (!motion) | |
| 2204 GetStatusBubble()->SetURL(GURL(), std::string()); | |
| 2205 } | |
| 2206 } | |
| 2207 | |
| 2208 void Browser::ContentsZoomChange(bool zoom_in) { | |
| 2209 ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS); | |
| 2210 } | |
| 2211 | |
| 2212 void Browser::WebContentsFocused(WebContents* contents) { | |
| 2213 window_->WebContentsFocused(contents); | |
| 2214 } | |
| 2215 | |
| 2216 bool Browser::TakeFocus(bool reverse) { | |
| 2217 content::NotificationService::current()->Notify( | |
| 2218 chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER, | |
| 2219 content::Source<Browser>(this), | |
| 2220 content::NotificationService::NoDetails()); | |
| 2221 return false; | |
| 2222 } | |
| 2223 | |
| 2224 bool Browser::IsApplication() const { | |
| 2225 return is_app(); | |
| 2226 } | |
| 2227 | |
| 2228 void Browser::ConvertContentsToApplication(WebContents* contents) { | |
| 2229 const GURL& url = contents->GetController().GetActiveEntry()->GetURL(); | |
| 2230 std::string app_name = web_app::GenerateApplicationNameFromURL(url); | |
| 2231 | |
| 2232 DetachContents(contents); | |
| 2233 Browser* app_browser = Browser::CreateWithParams( | |
| 2234 Browser::CreateParams::CreateForApp( | |
| 2235 TYPE_POPUP, app_name, gfx::Rect(), profile_)); | |
| 2236 TabContents* tab_contents = TabContents::FromWebContents(contents); | |
| 2237 if (!tab_contents) | |
| 2238 tab_contents = new TabContents(contents); | |
| 2239 app_browser->tab_strip_model()->AppendTabContents(tab_contents, true); | |
| 2240 | |
| 2241 contents->GetMutableRendererPrefs()->can_accept_load_drops = false; | |
| 2242 contents->GetRenderViewHost()->SyncRendererPrefs(); | |
| 2243 app_browser->window()->Show(); | |
| 2244 } | |
| 2245 | |
| 2246 gfx::Rect Browser::GetRootWindowResizerRect() const { | |
| 2247 return window_->GetRootWindowResizerRect(); | |
| 2248 } | |
| 2249 | |
| 2250 void Browser::BeforeUnloadFired(WebContents* web_contents, | |
| 2251 bool proceed, | |
| 2252 bool* proceed_to_fire_unload) { | |
| 2253 if (!is_attempting_to_close_browser_) { | |
| 2254 *proceed_to_fire_unload = proceed; | |
| 2255 if (!proceed) | |
| 2256 web_contents->SetClosedByUserGesture(false); | |
| 2257 return; | |
| 2258 } | |
| 2259 | |
| 2260 if (!proceed) { | |
| 2261 CancelWindowClose(); | |
| 2262 *proceed_to_fire_unload = false; | |
| 2263 web_contents->SetClosedByUserGesture(false); | |
| 2264 return; | |
| 2265 } | |
| 2266 | |
| 2267 if (RemoveFromSet(&tabs_needing_before_unload_fired_, web_contents)) { | |
| 2268 // Now that beforeunload has fired, put the tab on the queue to fire | |
| 2269 // unload. | |
| 2270 tabs_needing_unload_fired_.insert(web_contents); | |
| 2271 ProcessPendingTabs(); | |
| 2272 // We want to handle firing the unload event ourselves since we want to | |
| 2273 // fire all the beforeunload events before attempting to fire the unload | |
| 2274 // events should the user cancel closing the browser. | |
| 2275 *proceed_to_fire_unload = false; | |
| 2276 return; | |
| 2277 } | |
| 2278 | |
| 2279 *proceed_to_fire_unload = true; | |
| 2280 } | |
| 2281 | |
| 2282 void Browser::SetFocusToLocationBar(bool select_all) { | |
| 2283 // Two differences between this and FocusLocationBar(): | |
| 2284 // (1) This doesn't get recorded in user metrics, since it's called | |
| 2285 // internally. | |
| 2286 // (2) This checks whether the location bar can be focused, and if not, clears | |
| 2287 // the focus. FocusLocationBar() is only reached when the location bar is | |
| 2288 // focusable, but this may be reached at other times, e.g. while in | |
| 2289 // fullscreen mode, where we need to leave focus in a consistent state. | |
| 2290 window_->SetFocusToLocationBar(select_all); | |
| 2291 } | |
| 2292 | |
| 2293 void Browser::RenderWidgetShowing() { | |
| 2294 window_->DisableInactiveFrame(); | |
| 2295 } | |
| 2296 | |
| 2297 int Browser::GetExtraRenderViewHeight() const { | |
| 2298 return window_->GetExtraRenderViewHeight(); | |
| 2299 } | |
| 2300 | |
| 2301 void Browser::OnStartDownload(WebContents* source, | |
| 2302 content::DownloadItem* download) { | |
| 2303 TabContents* tab_contents = TabContents::FromWebContents(source); | |
| 2304 TabContents* constrained = GetConstrainingTabContents(tab_contents); | |
| 2305 if (constrained != tab_contents) { | |
| 2306 // Download in a constrained popup is shown in the tab that opened it. | |
| 2307 WebContents* constrained_tab = constrained->web_contents(); | |
| 2308 constrained_tab->GetDelegate()->OnStartDownload(constrained_tab, download); | |
| 2309 return; | |
| 2310 } | |
| 2311 | |
| 2312 if (!window()) | |
| 2313 return; | |
| 2314 | |
| 2315 // GetDownloadShelf creates the download shelf if it was not yet created. | |
| 2316 DownloadShelf* shelf = window()->GetDownloadShelf(); | |
| 2317 shelf->AddDownload(new DownloadItemModel(download)); | |
| 2318 // Don't show the animation for "Save file" downloads. | |
| 2319 // For non-theme extensions, we don't show the download animation. | |
| 2320 // Show animation in same window as the download shelf. Download shelf | |
| 2321 // may not be in the same window that initiated the download, e.g. | |
| 2322 // Panels. | |
| 2323 // Don't show the animation if the selected tab is not visible (i.e. the | |
| 2324 // window is minimized, we're in a unit test, etc.). | |
| 2325 WebContents* shelf_tab = shelf->browser()->GetActiveWebContents(); | |
| 2326 if ((download->GetTotalBytes() > 0) && | |
| 2327 !download_crx_util::IsExtensionDownload(*download) && | |
| 2328 platform_util::IsVisible(shelf_tab->GetNativeView()) && | |
| 2329 ui::Animation::ShouldRenderRichAnimation()) { | |
| 2330 DownloadStartedAnimation::Show(shelf_tab); | |
| 2331 } | |
| 2332 | |
| 2333 // If the download occurs in a new tab, close it. | |
| 2334 if (source->GetController().IsInitialNavigation() && tab_count() > 1) | |
| 2335 CloseContents(source); | |
| 2336 } | |
| 2337 | |
| 2338 void Browser::ViewSourceForTab(WebContents* source, const GURL& page_url) { | |
| 2339 DCHECK(source); | |
| 2340 TabContents* tab_contents = GetTabContentsAt( | |
| 2341 tab_strip_model_->GetIndexOfWebContents(source)); | |
| 2342 chrome::ViewSource(this, tab_contents); | |
| 2343 } | |
| 2344 | |
| 2345 void Browser::ViewSourceForFrame(WebContents* source, | |
| 2346 const GURL& frame_url, | |
| 2347 const std::string& frame_content_state) { | |
| 2348 DCHECK(source); | |
| 2349 TabContents* tab_contents = GetTabContentsAt( | |
| 2350 tab_strip_model_->GetIndexOfWebContents(source)); | |
| 2351 chrome::ViewSource(this, tab_contents, frame_url, frame_content_state); | |
| 2352 } | |
| 2353 | |
| 2354 void Browser::ShowRepostFormWarningDialog(WebContents* source) { | |
| 2355 browser::ShowTabModalConfirmDialog( | |
| 2356 new RepostFormWarningController(source), | |
| 2357 TabContents::FromWebContents(source)); | |
| 2358 } | |
| 2359 | |
| 2360 bool Browser::ShouldAddNavigationToHistory( | |
| 2361 const history::HistoryAddPageArgs& add_page_args, | |
| 2362 content::NavigationType navigation_type) { | |
| 2363 // Don't update history if running as app. | |
| 2364 return !IsApplication(); | |
| 2365 } | |
| 2366 | |
| 2367 bool Browser::ShouldCreateWebContents( | |
| 2368 WebContents* web_contents, | |
| 2369 int route_id, | |
| 2370 WindowContainerType window_container_type, | |
| 2371 const string16& frame_name, | |
| 2372 const GURL& target_url) { | |
| 2373 if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) { | |
| 2374 // If a BackgroundContents is created, suppress the normal WebContents. | |
| 2375 return !MaybeCreateBackgroundContents( | |
| 2376 route_id, web_contents, frame_name, target_url); | |
| 2377 } | |
| 2378 | |
| 2379 return true; | |
| 2380 } | |
| 2381 | |
| 2382 void Browser::WebContentsCreated(WebContents* source_contents, | |
| 2383 int64 source_frame_id, | |
| 2384 const GURL& target_url, | |
| 2385 WebContents* new_contents) { | |
| 2386 // Create a TabContents now, so all observers are in place, as the network | |
| 2387 // requests for its initial navigation will start immediately. The WebContents | |
| 2388 // will later be inserted into this browser using Browser::Navigate via | |
| 2389 // AddNewContents. The latter will retrieve the newly created TabContents from | |
| 2390 // WebContents object. | |
| 2391 new TabContents(new_contents); | |
| 2392 | |
| 2393 // Notify. | |
| 2394 RetargetingDetails details; | |
| 2395 details.source_web_contents = source_contents; | |
| 2396 details.source_frame_id = source_frame_id; | |
| 2397 details.target_url = target_url; | |
| 2398 details.target_web_contents = new_contents; | |
| 2399 details.not_yet_in_tabstrip = true; | |
| 2400 content::NotificationService::current()->Notify( | |
| 2401 chrome::NOTIFICATION_RETARGETING, | |
| 2402 content::Source<Profile>(profile_), | |
| 2403 content::Details<RetargetingDetails>(&details)); | |
| 2404 } | |
| 2405 | |
| 2406 void Browser::ContentRestrictionsChanged(WebContents* source) { | |
| 2407 UpdateCommandsForContentRestrictionState(); | |
| 2408 } | |
| 2409 | |
| 2410 void Browser::RendererUnresponsive(WebContents* source) { | |
| 2411 // Ignore hangs if print preview is open. | |
| 2412 TabContents* tab_contents = TabContents::FromWebContents(source); | |
| 2413 if (tab_contents) { | |
| 2414 printing::PrintPreviewTabController* controller = | |
| 2415 printing::PrintPreviewTabController::GetInstance(); | |
| 2416 if (controller) { | |
| 2417 TabContents* preview_tab = | |
| 2418 controller->GetPrintPreviewForTab(tab_contents); | |
| 2419 if (preview_tab && preview_tab != tab_contents) { | |
| 2420 return; | |
| 2421 } | |
| 2422 } | |
| 2423 } | |
| 2424 | |
| 2425 browser::ShowHungRendererDialog(source); | |
| 2426 } | |
| 2427 | |
| 2428 void Browser::RendererResponsive(WebContents* source) { | |
| 2429 browser::HideHungRendererDialog(source); | |
| 2430 } | |
| 2431 | |
| 2432 void Browser::WorkerCrashed(WebContents* source) { | |
| 2433 TabContents* tab_contents = TabContents::FromWebContents(source); | |
| 2434 InfoBarTabHelper* infobar_helper = tab_contents->infobar_tab_helper(); | |
| 2435 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate( | |
| 2436 infobar_helper, | |
| 2437 NULL, | |
| 2438 l10n_util::GetStringUTF16(IDS_WEBWORKER_CRASHED_PROMPT), | |
| 2439 true)); | |
| 2440 } | |
| 2441 | |
| 2442 void Browser::DidNavigateMainFramePostCommit(WebContents* web_contents) { | |
| 2443 if (web_contents == GetActiveWebContents()) | |
| 2444 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE); | |
| 2445 } | |
| 2446 | |
| 2447 void Browser::DidNavigateToPendingEntry(WebContents* web_contents) { | |
| 2448 if (web_contents == GetActiveWebContents()) | |
| 2449 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE); | |
| 2450 } | |
| 2451 | |
| 2452 content::JavaScriptDialogCreator* Browser::GetJavaScriptDialogCreator() { | |
| 2453 return GetJavaScriptDialogCreatorInstance(); | |
| 2454 } | |
| 2455 | |
| 2456 content::ColorChooser* Browser::OpenColorChooser(WebContents* web_contents, | |
| 2457 int color_chooser_id, | |
| 2458 SkColor color) { | |
| 2459 #if defined(OS_WIN) | |
| 2460 // On Windows, only create a color chooser if one doesn't exist, because we | |
| 2461 // can't close the old color chooser dialog. | |
| 2462 if (!color_chooser_.get()) | |
| 2463 color_chooser_.reset(content::ColorChooser::Create(color_chooser_id, | |
| 2464 web_contents, | |
| 2465 color)); | |
| 2466 #else | |
| 2467 if (color_chooser_.get()) | |
| 2468 color_chooser_->End(); | |
| 2469 color_chooser_.reset(content::ColorChooser::Create(color_chooser_id, | |
| 2470 web_contents, | |
| 2471 color)); | |
| 2472 #endif | |
| 2473 return color_chooser_.get(); | |
| 2474 } | |
| 2475 | |
| 2476 void Browser::DidEndColorChooser() { | |
| 2477 color_chooser_.reset(); | |
| 2478 } | |
| 2479 | |
| 2480 void Browser::RunFileChooser(WebContents* web_contents, | |
| 2481 const content::FileChooserParams& params) { | |
| 2482 FileSelectHelper::RunFileChooser(web_contents, params); | |
| 2483 } | |
| 2484 | |
| 2485 void Browser::EnumerateDirectory(WebContents* web_contents, | |
| 2486 int request_id, | |
| 2487 const FilePath& path) { | |
| 2488 FileSelectHelper::EnumerateDirectory(web_contents, request_id, path); | |
| 2489 } | |
| 2490 | |
| 2491 void Browser::ToggleFullscreenModeForTab(WebContents* web_contents, | |
| 2492 bool enter_fullscreen) { | |
| 2493 fullscreen_controller_->ToggleFullscreenModeForTab(web_contents, | |
| 2494 enter_fullscreen); | |
| 2495 } | |
| 2496 | |
| 2497 bool Browser::IsFullscreenForTabOrPending( | |
| 2498 const WebContents* web_contents) const { | |
| 2499 return fullscreen_controller_->IsFullscreenForTabOrPending(web_contents); | |
| 2500 } | |
| 2501 | |
| 2502 void Browser::JSOutOfMemory(WebContents* web_contents) { | |
| 2503 JSOutOfMemoryHelper(web_contents); | |
| 2504 } | |
| 2505 | |
| 2506 void Browser::RegisterProtocolHandler(WebContents* web_contents, | |
| 2507 const std::string& protocol, | |
| 2508 const GURL& url, | |
| 2509 const string16& title, | |
| 2510 bool user_gesture) { | |
| 2511 RegisterProtocolHandlerHelper( | |
| 2512 web_contents, protocol, url, title, user_gesture); | |
| 2513 } | |
| 2514 | |
| 2515 void Browser::RegisterIntentHandler( | |
| 2516 WebContents* web_contents, | |
| 2517 const webkit_glue::WebIntentServiceData& data, | |
| 2518 bool user_gesture) { | |
| 2519 RegisterIntentHandlerHelper(web_contents, data, user_gesture); | |
| 2520 } | |
| 2521 | |
| 2522 void Browser::WebIntentDispatch( | |
| 2523 WebContents* web_contents, | |
| 2524 content::WebIntentsDispatcher* intents_dispatcher) { | |
| 2525 if (!web_intents::IsWebIntentsEnabledForProfile(profile_)) | |
| 2526 return; | |
| 2527 | |
| 2528 UMA_HISTOGRAM_COUNTS("WebIntents.Dispatch", 1); | |
| 2529 | |
| 2530 TabContents* tab_contents = TabContents::FromWebContents(web_contents); | |
| 2531 tab_contents->web_intent_picker_controller()->SetIntentsDispatcher( | |
| 2532 intents_dispatcher); | |
| 2533 tab_contents->web_intent_picker_controller()->ShowDialog( | |
| 2534 intents_dispatcher->GetIntent().action, | |
| 2535 intents_dispatcher->GetIntent().type); | |
| 2536 } | |
| 2537 | |
| 2538 void Browser::UpdatePreferredSize(WebContents* source, | |
| 2539 const gfx::Size& pref_size) { | |
| 2540 window_->UpdatePreferredSize(source, pref_size); | |
| 2541 } | |
| 2542 | |
| 2543 void Browser::ResizeDueToAutoResize(WebContents* source, | |
| 2544 const gfx::Size& new_size) { | |
| 2545 window_->ResizeDueToAutoResize(source, new_size); | |
| 2546 } | |
| 2547 | |
| 2548 void Browser::FindReply(WebContents* web_contents, | |
| 2549 int request_id, | |
| 2550 int number_of_matches, | |
| 2551 const gfx::Rect& selection_rect, | |
| 2552 int active_match_ordinal, | |
| 2553 bool final_update) { | |
| 2554 FindReplyHelper(web_contents, request_id, number_of_matches, selection_rect, | |
| 2555 active_match_ordinal, final_update); | |
| 2556 } | |
| 2557 | |
| 2558 void Browser::RequestToLockMouse(WebContents* web_contents, | |
| 2559 bool user_gesture, | |
| 2560 bool last_unlocked_by_target) { | |
| 2561 fullscreen_controller_->RequestToLockMouse(web_contents, | |
| 2562 user_gesture, | |
| 2563 last_unlocked_by_target); | |
| 2564 } | |
| 2565 | |
| 2566 void Browser::LostMouseLock() { | |
| 2567 fullscreen_controller_->LostMouseLock(); | |
| 2568 } | |
| 2569 | |
| 2570 void Browser::RequestMediaAccessPermission( | |
| 2571 content::WebContents* web_contents, | |
| 2572 const content::MediaStreamRequest* request, | |
| 2573 const content::MediaResponseCallback& callback) { | |
| 2574 TabContents* tab = TabContents::FromWebContents(web_contents); | |
| 2575 DCHECK(tab); | |
| 2576 | |
| 2577 scoped_ptr<MediaStreamDevicesController> | |
| 2578 controller(new MediaStreamDevicesController(tab->profile(), | |
| 2579 request, | |
| 2580 callback)); | |
| 2581 if (!controller->DismissInfoBarAndTakeActionOnSettings()) { | |
| 2582 InfoBarTabHelper* infobar_helper = tab->infobar_tab_helper(); | |
| 2583 InfoBarDelegate* old_infobar = NULL; | |
| 2584 for (size_t i = 0; i < infobar_helper->infobar_count(); ++i) { | |
| 2585 old_infobar = infobar_helper->GetInfoBarDelegateAt(i)-> | |
| 2586 AsMediaStreamInfoBarDelegate(); | |
| 2587 if (old_infobar) | |
| 2588 break; | |
| 2589 } | |
| 2590 | |
| 2591 InfoBarDelegate* infobar = | |
| 2592 new MediaStreamInfoBarDelegate(infobar_helper, controller.release()); | |
| 2593 if (old_infobar) | |
| 2594 infobar_helper->ReplaceInfoBar(old_infobar, infobar); | |
| 2595 else | |
| 2596 infobar_helper->AddInfoBar(infobar); | |
| 2597 } | |
| 2598 } | |
| 2599 | |
| 2600 /////////////////////////////////////////////////////////////////////////////// | |
| 2601 // Browser, CoreTabHelperDelegate implementation: | |
| 2602 | |
| 2603 void Browser::SwapTabContents(TabContents* old_tab_contents, | |
| 2604 TabContents* new_tab_contents) { | |
| 2605 int index = tab_strip_model_->GetIndexOfTabContents(old_tab_contents); | |
| 2606 DCHECK_NE(TabStripModel::kNoTab, index); | |
| 2607 tab_strip_model_->ReplaceTabContentsAt(index, new_tab_contents); | |
| 2608 } | |
| 2609 | |
| 2610 bool Browser::CanReloadContents(TabContents* source) const { | |
| 2611 return !is_devtools(); | |
| 2612 } | |
| 2613 | |
| 2614 bool Browser::CanSaveContents(TabContents* source) const { | |
| 2615 return !is_devtools(); | |
| 2616 } | |
| 2617 | |
| 2618 /////////////////////////////////////////////////////////////////////////////// | |
| 2619 // Browser, SearchEngineTabHelperDelegate implementation: | |
| 2620 | |
| 2621 void Browser::ConfirmAddSearchProvider(TemplateURL* template_url, | |
| 2622 Profile* profile) { | |
| 2623 window()->ConfirmAddSearchProvider(template_url, profile); | |
| 2624 } | |
| 2625 | |
| 2626 /////////////////////////////////////////////////////////////////////////////// | |
| 2627 // Browser, ConstrainedWindowTabHelperDelegate implementation: | |
| 2628 | |
| 2629 void Browser::SetTabContentBlocked(TabContents* tab_contents, bool blocked) { | |
| 2630 int index = tab_strip_model_->GetIndexOfTabContents(tab_contents); | |
| 2631 if (index == TabStripModel::kNoTab) { | |
| 2632 NOTREACHED(); | |
| 2633 return; | |
| 2634 } | |
| 2635 tab_strip_model_->SetTabBlocked(index, blocked); | |
| 2636 UpdatePrintingState(tab_contents->web_contents()->GetContentRestrictions()); | |
| 2637 if (!blocked && GetActiveTabContents() == tab_contents) | |
| 2638 tab_contents->web_contents()->Focus(); | |
| 2639 } | |
| 2640 | |
| 2641 /////////////////////////////////////////////////////////////////////////////// | |
| 2642 // Browser, BlockedContentTabHelperDelegate implementation: | |
| 2643 | |
| 2644 TabContents* Browser::GetConstrainingTabContents(TabContents* source) { | |
| 2645 return source; | |
| 2646 } | |
| 2647 | |
| 2648 /////////////////////////////////////////////////////////////////////////////// | |
| 2649 // Browser, BookmarkTabHelperDelegate implementation: | |
| 2650 | |
| 2651 void Browser::URLStarredChanged(TabContents* source, bool starred) { | |
| 2652 if (source == GetActiveTabContents()) | |
| 2653 window_->SetStarredState(starred); | |
| 2654 } | |
| 2655 | |
| 2656 /////////////////////////////////////////////////////////////////////////////// | |
| 2657 // Browser, ZoomObserver implementation: | |
| 2658 | |
| 2659 void Browser::OnZoomIconChanged(TabContents* source, | |
| 2660 ZoomController::ZoomIconState state) { | |
| 2661 if (source == GetActiveTabContents()) | |
| 2662 window_->SetZoomIconState(state); | |
| 2663 } | |
| 2664 | |
| 2665 void Browser::OnZoomChanged(TabContents* source, | |
| 2666 int zoom_percent, | |
| 2667 bool can_show_bubble) { | |
| 2668 if (source == GetActiveTabContents()) { | |
| 2669 window_->SetZoomIconTooltipPercent(zoom_percent); | |
| 2670 | |
| 2671 // Only show the zoom bubble for zoom changes in the active window. | |
| 2672 if (can_show_bubble && window_->IsActive()) | |
| 2673 window_->ShowZoomBubble(zoom_percent); | |
| 2674 } | |
| 2675 } | |
| 2676 | |
| 2677 /////////////////////////////////////////////////////////////////////////////// | |
| 2678 // Browser, ExtensionTabHelperDelegate implementation: | |
| 2679 | |
| 2680 void Browser::OnDidGetApplicationInfo(TabContents* source, | |
| 2681 int32 page_id) { | |
| 2682 if (GetActiveTabContents() != source) | |
| 2683 return; | |
| 2684 | |
| 2685 NavigationEntry* entry = | |
| 2686 source->web_contents()->GetController().GetLastCommittedEntry(); | |
| 2687 if (!entry || (entry->GetPageID() != page_id)) | |
| 2688 return; | |
| 2689 | |
| 2690 switch (pending_web_app_action_) { | |
| 2691 case CREATE_SHORTCUT: { | |
| 2692 window()->ShowCreateWebAppShortcutsDialog(source); | |
| 2693 break; | |
| 2694 } | |
| 2695 case UPDATE_SHORTCUT: { | |
| 2696 web_app::UpdateShortcutForTabContents(source); | |
| 2697 break; | |
| 2698 } | |
| 2699 default: | |
| 2700 NOTREACHED(); | |
| 2701 break; | |
| 2702 } | |
| 2703 | |
| 2704 pending_web_app_action_ = NONE; | |
| 2705 } | |
| 2706 | |
| 2707 void Browser::OnInstallApplication(TabContents* source, | |
| 2708 const WebApplicationInfo& web_app) { | |
| 2709 ExtensionService* extension_service = profile()->GetExtensionService(); | |
| 2710 if (!extension_service) | |
| 2711 return; | |
| 2712 | |
| 2713 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create( | |
| 2714 extension_service, | |
| 2715 extension_service->show_extensions_prompts() ? | |
| 2716 new ExtensionInstallPrompt(this) : NULL)); | |
| 2717 installer->InstallWebApp(web_app); | |
| 2718 } | |
| 2719 | |
| 2720 /////////////////////////////////////////////////////////////////////////////// | |
| 2721 // Browser, SelectFileDialog::Listener implementation: | |
| 2722 | |
| 2723 void Browser::FileSelected(const FilePath& path, int index, void* params) { | |
| 2724 profile_->set_last_selected_directory(path.DirName()); | |
| 2725 GURL file_url = net::FilePathToFileURL(path); | |
| 2726 | |
| 2727 #if defined(OS_CHROMEOS) | |
| 2728 gdata::util::ModifyGDataFileResourceUrl(profile_, path, &file_url); | |
| 2729 #endif | |
| 2730 | |
| 2731 if (file_url.is_empty()) | |
| 2732 return; | |
| 2733 | |
| 2734 OpenURL(OpenURLParams( | |
| 2735 file_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, | |
| 2736 false)); | |
| 2737 } | |
| 2738 | |
| 2739 /////////////////////////////////////////////////////////////////////////////// | |
| 2740 // Browser, content::NotificationObserver implementation: | |
| 2741 | |
| 2742 void Browser::Observe(int type, | |
| 2743 const content::NotificationSource& source, | |
| 2744 const content::NotificationDetails& details) { | |
| 2745 switch (type) { | 577 switch (type) { |
| 2746 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED: | 578 case NOTIFICATION_PREF_CHANGED: { |
| 2747 if (is_attempting_to_close_browser_) { | |
| 2748 // Pass in false so that we delay processing. We need to delay the | |
| 2749 // processing as it may close the tab, which is currently on the call | |
| 2750 // stack above us. | |
| 2751 ClearUnloadState(content::Source<WebContents>(source).ptr(), false); | |
| 2752 } | |
| 2753 break; | |
| 2754 | |
| 2755 case content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED: | |
| 2756 // When the current tab's SSL state changes, we need to update the URL | |
| 2757 // bar to reflect the new state. Note that it's possible for the selected | |
| 2758 // tab contents to be NULL. This is because we listen for all sources | |
| 2759 // (NavigationControllers) for convenience, so the notification could | |
| 2760 // actually be for a different window while we're doing asynchronous | |
| 2761 // closing of this one. | |
| 2762 if (GetActiveWebContents() && | |
| 2763 &GetActiveWebContents()->GetController() == | |
| 2764 content::Source<NavigationController>(source).ptr()) | |
| 2765 UpdateToolbar(false); | |
| 2766 break; | |
| 2767 | |
| 2768 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | |
| 2769 if (window()->GetLocationBar()) | |
| 2770 window()->GetLocationBar()->UpdatePageActions(); | |
| 2771 | |
| 2772 // Close any tabs from the unloaded extension, unless it's terminated, | |
| 2773 // in which case let the sad tabs remain. | |
| 2774 if (content::Details<extensions::UnloadedExtensionInfo>( | |
| 2775 details)->reason != extension_misc::UNLOAD_REASON_TERMINATE) { | |
| 2776 const Extension* extension = | |
| 2777 content::Details<extensions::UnloadedExtensionInfo>( | |
| 2778 details)->extension; | |
| 2779 for (int i = tab_strip_model_->count() - 1; i >= 0; --i) { | |
| 2780 WebContents* tc = | |
| 2781 tab_strip_model_->GetTabContentsAt(i)->web_contents(); | |
| 2782 bool close_tab_contents = | |
| 2783 tc->GetURL().SchemeIs(chrome::kExtensionScheme) && | |
| 2784 tc->GetURL().host() == extension->id(); | |
| 2785 // We want to close all panels originated by the unloaded extension. | |
| 2786 close_tab_contents = close_tab_contents || | |
| 2787 (type_ == TYPE_PANEL && | |
| 2788 (web_app::GetExtensionIdFromApplicationName(app_name_) == | |
| 2789 extension->id())); | |
| 2790 if (close_tab_contents) { | |
| 2791 CloseTabContents(tc); | |
| 2792 } | |
| 2793 } | |
| 2794 } | |
| 2795 break; | |
| 2796 } | |
| 2797 | |
| 2798 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: { | |
| 2799 Profile* profile = content::Source<Profile>(source).ptr(); | |
| 2800 if (profile_->IsSameProfile(profile) && window()->GetLocationBar()) | |
| 2801 window()->GetLocationBar()->InvalidatePageActions(); | |
| 2802 break; | |
| 2803 } | |
| 2804 | |
| 2805 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: | |
| 2806 case chrome::NOTIFICATION_EXTENSION_LOADED: | |
| 2807 // During window creation on Windows we may end up calling into | |
| 2808 // SHAppBarMessage, which internally spawns a nested message loop. This | |
| 2809 // makes it possible for us to end up here before window creation has | |
| 2810 // completed,at which point window_ is NULL. See 94752 for details. | |
| 2811 if (window() && window()->GetLocationBar()) | |
| 2812 window()->GetLocationBar()->UpdatePageActions(); | |
| 2813 break; | |
| 2814 | |
| 2815 #if defined(ENABLE_THEMES) | |
| 2816 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED: | |
| 2817 window()->UserChangedTheme(); | |
| 2818 break; | |
| 2819 #endif | |
| 2820 | |
| 2821 case chrome::NOTIFICATION_PREF_CHANGED: { | |
| 2822 const std::string& pref_name = | 579 const std::string& pref_name = |
| 2823 *content::Details<std::string>(details).ptr(); | 580 *content::Details<std::string>(details).ptr(); |
| 2824 if (pref_name == prefs::kPrintingEnabled) { | 581 if (pref_name == prefs::kPrintingEnabled) { |
| 2825 UpdatePrintingState(GetContentRestrictionsForSelectedTab()); | 582 UpdatePrintingState(); |
| 2826 } else if (pref_name == prefs::kInstantEnabled) { | |
| 2827 if (browser_shutdown::ShuttingDownWithoutClosingBrowsers() || | |
| 2828 !InstantController::IsEnabled(profile())) { | |
| 2829 if (instant()) { | |
| 2830 instant()->DestroyPreviewContents(); | |
| 2831 instant_.reset(); | |
| 2832 instant_unload_handler_.reset(); | |
| 2833 } | |
| 2834 } else { | |
| 2835 CreateInstantIfNecessary(); | |
| 2836 } | |
| 2837 } else if (pref_name == prefs::kIncognitoModeAvailability) { | 583 } else if (pref_name == prefs::kIncognitoModeAvailability) { |
| 2838 UpdateCommandsForIncognitoAvailability(); | 584 UpdateCommandsForIncognitoAvailability(); |
| 2839 } else if (pref_name == prefs::kDevToolsDisabled) { | 585 } else if (pref_name == prefs::kDevToolsDisabled) { |
| 2840 UpdateCommandsForDevTools(); | 586 UpdateCommandsForDevTools(); |
| 2841 if (profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled)) | |
| 2842 content::DevToolsManager::GetInstance()->CloseAllClientHosts(); | |
| 2843 } else if (pref_name == prefs::kEditBookmarksEnabled) { | 587 } else if (pref_name == prefs::kEditBookmarksEnabled) { |
| 2844 UpdateCommandsForBookmarkEditing(); | 588 UpdateCommandsForBookmarkEditing(); |
| 2845 } else if (pref_name == prefs::kShowBookmarkBar) { | 589 } else if (pref_name == prefs::kShowBookmarkBar) { |
| 2846 UpdateCommandsForBookmarkBar(); | 590 UpdateCommandsForBookmarkBar(); |
| 2847 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE); | |
| 2848 } else if (pref_name == prefs::kHomePage) { | |
| 2849 PrefService* pref_service = content::Source<PrefService>(source).ptr(); | |
| 2850 MarkHomePageAsChanged(pref_service); | |
| 2851 } else if (pref_name == prefs::kAllowFileSelectionDialogs) { | 591 } else if (pref_name == prefs::kAllowFileSelectionDialogs) { |
| 2852 UpdateSaveAsState(GetContentRestrictionsForSelectedTab()); | 592 UpdateSaveAsState(); |
| 2853 UpdateOpenFileState(); | 593 UpdateOpenFileState(); |
| 2854 } else if (pref_name == prefs::kInManagedMode) { | 594 } else if (pref_name == prefs::kInManagedMode) { |
| 2855 UpdateCommandsForMultipleProfiles(); | 595 UpdateCommandsForMultipleProfiles(); |
| 2856 } else { | 596 } else { |
| 2857 NOTREACHED(); | 597 NOTREACHED(); |
| 2858 } | 598 } |
| 2859 break; | 599 break; |
| 2860 } | 600 } |
| 2861 | |
| 2862 case chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED: { | |
| 2863 WebContents* web_contents = content::Source<WebContents>(source).ptr(); | |
| 2864 if (web_contents == GetActiveWebContents()) { | |
| 2865 LocationBar* location_bar = window()->GetLocationBar(); | |
| 2866 if (location_bar) | |
| 2867 location_bar->UpdateContentSettingsIcons(); | |
| 2868 } | |
| 2869 break; | |
| 2870 } | |
| 2871 | |
| 2872 case content::NOTIFICATION_INTERSTITIAL_ATTACHED: | 601 case content::NOTIFICATION_INTERSTITIAL_ATTACHED: |
| 2873 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE); | |
| 2874 UpdateCommandsForTabState(); | 602 UpdateCommandsForTabState(); |
| 2875 break; | 603 break; |
| 2876 | 604 |
| 2877 case content::NOTIFICATION_INTERSTITIAL_DETACHED: | 605 case content::NOTIFICATION_INTERSTITIAL_DETACHED: |
| 2878 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE); | |
| 2879 UpdateCommandsForTabState(); | 606 UpdateCommandsForTabState(); |
| 2880 break; | 607 break; |
| 2881 | 608 |
| 2882 default: | 609 default: |
| 2883 NOTREACHED() << "Got a notification we didn't register for."; | 610 NOTREACHED() << "Got a notification we didn't register for."; |
| 2884 } | 611 } |
| 2885 } | 612 } |
| 2886 | 613 |
| 2887 /////////////////////////////////////////////////////////////////////////////// | 614 //////////////////////////////////////////////////////////////////////////////// |
| 2888 // Browser, ProfileSyncServiceObserver implementation: | 615 // BrowserCommandController, TabStripModelObserver implementation: |
| 2889 | 616 |
| 2890 void Browser::OnStateChanged() { | 617 void BrowserCommandController::TabInsertedAt(TabContents* contents, |
| 2891 DCHECK(ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService( | 618 int index, |
| 2892 profile_)); | 619 bool foreground) { |
| 2893 // For unit tests, we don't have a window. | 620 AddInterstitialObservers(contents); |
| 2894 if (!window_) | |
| 2895 return; | |
| 2896 const bool show_main_ui = IsShowingMainUI(window_->IsFullscreen()); | |
| 2897 command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP, | |
| 2898 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible()); | |
| 2899 } | 621 } |
| 2900 | 622 |
| 2901 /////////////////////////////////////////////////////////////////////////////// | 623 void BrowserCommandController::TabDetachedAt(TabContents* contents, int index) { |
| 2902 // Browser, InstantDelegate implementation: | 624 RemoveInterstitialObservers(contents); |
| 2903 | |
| 2904 void Browser::ShowInstant(TabContents* preview_contents) { | |
| 2905 window_->ShowInstant(preview_contents); | |
| 2906 | |
| 2907 // TODO(beng): investigate if we can avoid this and instead rely on the | |
| 2908 // visibility of the WebContentsView | |
| 2909 GetActiveWebContents()->WasHidden(); | |
| 2910 preview_contents->web_contents()->WasRestored(); | |
| 2911 } | 625 } |
| 2912 | 626 |
| 2913 void Browser::HideInstant() { | 627 void BrowserCommandController::TabReplacedAt(TabStripModel* tab_strip_model, |
| 2914 window_->HideInstant(); | 628 TabContents* old_contents, |
| 2915 if (GetActiveWebContents()) | 629 TabContents* new_contents, |
| 2916 GetActiveWebContents()->WasRestored(); | 630 int index) { |
| 2917 if (instant_->GetPreviewContents()) | 631 RemoveInterstitialObservers(old_contents); |
| 2918 instant_->GetPreviewContents()->web_contents()->WasHidden(); | 632 AddInterstitialObservers(new_contents); |
| 2919 } | 633 } |
| 2920 | 634 |
| 2921 void Browser::CommitInstant(TabContents* preview_contents) { | 635 //////////////////////////////////////////////////////////////////////////////// |
| 2922 TabContents* tab_contents = GetActiveTabContents(); | 636 // BrowserCommandController, TabRestoreServiceObserver implementation: |
| 2923 int index = tab_strip_model_->GetIndexOfTabContents(tab_contents); | |
| 2924 DCHECK_NE(TabStripModel::kNoTab, index); | |
| 2925 // TabStripModel takes ownership of preview_contents. | |
| 2926 tab_strip_model_->ReplaceTabContentsAt(index, preview_contents); | |
| 2927 // InstantUnloadHandler takes ownership of tab_contents. | |
| 2928 instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index); | |
| 2929 | 637 |
| 2930 GURL url = preview_contents->web_contents()->GetURL(); | 638 void BrowserCommandController::TabRestoreServiceChanged( |
| 2931 DCHECK(profile_->GetExtensionService()); | 639 TabRestoreService* service) { |
| 2932 if (profile_->GetExtensionService()->IsInstalledApp(url)) { | 640 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, |
| 2933 AppLauncherHandler::RecordAppLaunchType( | 641 CanRestoreTab(browser_)); |
| 2934 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT); | |
| 2935 } | |
| 2936 } | 642 } |
| 2937 | 643 |
| 2938 void Browser::SetSuggestedText(const string16& text, | 644 void BrowserCommandController::TabRestoreServiceDestroyed( |
| 2939 InstantCompleteBehavior behavior) { | 645 TabRestoreService* service) { |
| 2940 if (window()->GetLocationBar()) | 646 service->RemoveObserver(this); |
| 2941 window()->GetLocationBar()->SetSuggestedText(text, behavior); | |
| 2942 } | 647 } |
| 2943 | 648 |
| 2944 gfx::Rect Browser::GetInstantBounds() { | 649 //////////////////////////////////////////////////////////////////////////////// |
| 2945 return window()->GetInstantBounds(); | 650 // BrowserCommandController, ProfileSyncServiceObserver implementation: |
| 651 |
| 652 void BrowserCommandController::OnStateChanged() { |
| 653 DCHECK(ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService( |
| 654 profile())); |
| 655 // For unit tests, we don't have a window. |
| 656 if (!window()) |
| 657 return; |
| 658 const bool show_main_ui = IsShowingMainUI(window()->IsFullscreen()); |
| 659 command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP, |
| 660 show_main_ui && profile()->GetOriginalProfile()->IsSyncAccessible()); |
| 2946 } | 661 } |
| 2947 | 662 |
| 2948 void Browser::InstantPreviewFocused() { | 663 //////////////////////////////////////////////////////////////////////////////// |
| 2949 // NOTE: This is only invoked on aura. | 664 // BrowserCommandController, private: |
| 2950 window_->WebContentsFocused(instant_->GetPreviewContents()->web_contents()); | |
| 2951 } | |
| 2952 | 665 |
| 2953 TabContents* Browser::GetInstantHostTabContents() const { | 666 bool BrowserCommandController::IsShowingMainUI(bool is_fullscreen) { |
| 2954 return GetActiveTabContents(); | |
| 2955 } | |
| 2956 | |
| 2957 /////////////////////////////////////////////////////////////////////////////// | |
| 2958 // Browser, Command and state updating (private): | |
| 2959 | |
| 2960 bool Browser::IsShowingMainUI(bool is_fullscreen) { | |
| 2961 #if !defined(OS_MACOSX) | 667 #if !defined(OS_MACOSX) |
| 2962 return is_type_tabbed() && !is_fullscreen; | 668 return browser_->is_type_tabbed() && !is_fullscreen; |
| 2963 #else | 669 #else |
| 2964 return is_type_tabbed(); | 670 return browser_->is_type_tabbed(); |
| 2965 #endif | 671 #endif |
| 2966 } | 672 } |
| 2967 | 673 |
| 2968 void Browser::InitCommandState() { | 674 void BrowserCommandController::InitCommandState() { |
| 2969 // All browser commands whose state isn't set automagically some other way | 675 // All browser commands whose state isn't set automagically some other way |
| 2970 // (like Back & Forward with initial page load) must have their state | 676 // (like Back & Forward with initial page load) must have their state |
| 2971 // initialized here, otherwise they will be forever disabled. | 677 // initialized here, otherwise they will be forever disabled. |
| 2972 | 678 |
| 2973 // Navigation commands | 679 // Navigation commands |
| 2974 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true); | 680 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true); |
| 2975 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true); | 681 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true); |
| 2976 | 682 |
| 2977 // Window management commands | 683 // Window management commands |
| 2978 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true); | 684 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3027 // Zoom | 733 // Zoom |
| 3028 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true); | 734 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true); |
| 3029 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true); | 735 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true); |
| 3030 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true); | 736 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true); |
| 3031 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true); | 737 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true); |
| 3032 | 738 |
| 3033 // Show various bits of UI | 739 // Show various bits of UI |
| 3034 UpdateOpenFileState(); | 740 UpdateOpenFileState(); |
| 3035 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false); | 741 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false); |
| 3036 UpdateCommandsForDevTools(); | 742 UpdateCommandsForDevTools(); |
| 3037 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, | 743 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, CanOpenTaskManager()); |
| 3038 chrome::CanOpenTaskManager()); | |
| 3039 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true); | 744 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true); |
| 3040 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true); | 745 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true); |
| 3041 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_KEYBOARD, true); | 746 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_KEYBOARD, true); |
| 3042 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_MENU, true); | 747 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_MENU, true); |
| 3043 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, true); | 748 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, true); |
| 3044 | 749 |
| 3045 command_updater_.UpdateCommandEnabled( | 750 command_updater_.UpdateCommandEnabled( |
| 3046 IDC_SHOW_SYNC_SETUP, profile_->GetOriginalProfile()->IsSyncAccessible()); | 751 IDC_SHOW_SYNC_SETUP, profile()->GetOriginalProfile()->IsSyncAccessible()); |
| 3047 | 752 |
| 3048 // Initialize other commands based on the window type. | 753 // Initialize other commands based on the window type. |
| 3049 bool normal_window = is_type_tabbed(); | 754 bool normal_window = browser_->is_type_tabbed(); |
| 3050 | 755 |
| 3051 // Navigation commands | 756 // Navigation commands |
| 3052 command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window); | 757 command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window); |
| 3053 | 758 |
| 3054 // Window management commands | 759 // Window management commands |
| 3055 // TODO(rohitrao): Disable fullscreen on non-Lion? | 760 // TODO(rohitrao): Disable fullscreen on non-Lion? |
| 3056 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN, | 761 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN, |
| 3057 !(is_type_panel() && is_app())); | 762 !(browser_->is_type_panel() && browser_->is_app())); |
| 3058 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window); | 763 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window); |
| 3059 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB, | 764 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB, |
| 3060 normal_window); | 765 normal_window); |
| 3061 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window); | 766 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window); |
| 3062 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window); | 767 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window); |
| 3063 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window); | 768 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window); |
| 3064 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window); | 769 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window); |
| 3065 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window); | 770 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window); |
| 3066 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window); | 771 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window); |
| 3067 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window); | 772 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window); |
| 3068 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window); | 773 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window); |
| 3069 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window); | 774 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window); |
| 3070 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window); | 775 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window); |
| 3071 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window); | 776 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window); |
| 3072 #if defined(OS_WIN) | 777 #if defined(OS_WIN) |
| 3073 const bool metro_mode = base::win::IsMetroProcess(); | 778 const bool metro_mode = base::win::IsMetroProcess(); |
| 3074 command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_ENABLE, metro_mode); | 779 command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_ENABLE, metro_mode); |
| 3075 command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_DISABLE, metro_mode); | 780 command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_DISABLE, metro_mode); |
| 3076 #endif | 781 #endif |
| 3077 #if defined(OS_MACOSX) | 782 #if defined(OS_MACOSX) |
| 3078 command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window); | 783 command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window); |
| 3079 command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE, | 784 command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE, |
| 3080 !(is_type_panel() && is_app())); | 785 !(browser_->is_type_panel() && browser_->is_app())); |
| 3081 #endif | 786 #endif |
| 3082 | 787 |
| 3083 // Clipboard commands | 788 // Clipboard commands |
| 3084 command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !is_devtools()); | 789 command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !browser_->is_devtools()); |
| 3085 | 790 |
| 3086 // Find-in-page | 791 // Find-in-page |
| 3087 command_updater_.UpdateCommandEnabled(IDC_FIND, !is_devtools()); | 792 command_updater_.UpdateCommandEnabled(IDC_FIND, !browser_->is_devtools()); |
| 3088 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, !is_devtools()); | 793 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, |
| 3089 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, !is_devtools()); | 794 !browser_->is_devtools()); |
| 795 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, |
| 796 !browser_->is_devtools()); |
| 3090 | 797 |
| 3091 // Show various bits of UI | 798 // Show various bits of UI |
| 3092 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window); | 799 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window); |
| 3093 | 800 |
| 3094 // The upgrade entry and the view incompatibility entry should always be | 801 // The upgrade entry and the view incompatibility entry should always be |
| 3095 // enabled. Whether they are visible is a separate matter determined on menu | 802 // enabled. Whether they are visible is a separate matter determined on menu |
| 3096 // show. | 803 // show. |
| 3097 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true); | 804 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true); |
| 3098 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true); | 805 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true); |
| 3099 | 806 |
| 3100 // View Background Pages entry is always enabled, but is hidden if there are | 807 // View Background Pages entry is always enabled, but is hidden if there are |
| 3101 // no background pages. | 808 // no background pages. |
| 3102 command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true); | 809 command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true); |
| 3103 | 810 |
| 3104 // Toggle speech input | 811 // Toggle speech input |
| 3105 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true); | 812 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true); |
| 3106 | 813 |
| 3107 // Initialize other commands whose state changes based on fullscreen mode. | 814 // Initialize other commands whose state changes based on fullscreen mode. |
| 3108 UpdateCommandsForFullscreenMode(FULLSCREEN_DISABLED); | 815 UpdateCommandsForFullscreenMode(FULLSCREEN_DISABLED); |
| 3109 | 816 |
| 3110 UpdateCommandsForContentRestrictionState(); | 817 UpdateCommandsForContentRestrictionState(); |
| 3111 | 818 |
| 3112 UpdateCommandsForBookmarkEditing(); | 819 UpdateCommandsForBookmarkEditing(); |
| 3113 | 820 |
| 3114 UpdateCommandsForIncognitoAvailability(); | 821 UpdateCommandsForIncognitoAvailability(); |
| 3115 } | 822 } |
| 3116 | 823 |
| 3117 void Browser::UpdateCommandsForIncognitoAvailability() { | 824 void BrowserCommandController::UpdateCommandsForIncognitoAvailability() { |
| 3118 IncognitoModePrefs::Availability incognito_availability = | 825 IncognitoModePrefs::Availability incognito_availability = |
| 3119 IncognitoModePrefs::GetAvailability(profile_->GetPrefs()); | 826 IncognitoModePrefs::GetAvailability(profile()->GetPrefs()); |
| 3120 command_updater_.UpdateCommandEnabled( | 827 command_updater_.UpdateCommandEnabled( |
| 3121 IDC_NEW_WINDOW, | 828 IDC_NEW_WINDOW, |
| 3122 incognito_availability != IncognitoModePrefs::FORCED); | 829 incognito_availability != IncognitoModePrefs::FORCED); |
| 3123 command_updater_.UpdateCommandEnabled( | 830 command_updater_.UpdateCommandEnabled( |
| 3124 IDC_NEW_INCOGNITO_WINDOW, | 831 IDC_NEW_INCOGNITO_WINDOW, |
| 3125 incognito_availability != IncognitoModePrefs::DISABLED); | 832 incognito_availability != IncognitoModePrefs::DISABLED); |
| 3126 | 833 |
| 3127 // Bookmark manager and settings page/subpages are forced to open in normal | 834 // Bookmark manager and settings page/subpages are forced to open in normal |
| 3128 // mode. For this reason we disable these commands when incognito is forced. | 835 // mode. For this reason we disable these commands when incognito is forced. |
| 3129 const bool command_enabled = | 836 const bool command_enabled = |
| 3130 incognito_availability != IncognitoModePrefs::FORCED; | 837 incognito_availability != IncognitoModePrefs::FORCED; |
| 3131 command_updater_.UpdateCommandEnabled( | 838 command_updater_.UpdateCommandEnabled( |
| 3132 IDC_SHOW_BOOKMARK_MANAGER, | 839 IDC_SHOW_BOOKMARK_MANAGER, |
| 3133 browser_defaults::bookmarks_enabled && command_enabled); | 840 browser_defaults::bookmarks_enabled && command_enabled); |
| 3134 ExtensionService* extension_service = profile()->GetExtensionService(); | 841 ExtensionService* extension_service = profile()->GetExtensionService(); |
| 3135 bool enable_extensions = | 842 bool enable_extensions = |
| 3136 extension_service && extension_service->extensions_enabled(); | 843 extension_service && extension_service->extensions_enabled(); |
| 3137 command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS, | 844 command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS, |
| 3138 enable_extensions && command_enabled); | 845 enable_extensions && command_enabled); |
| 3139 | 846 |
| 3140 const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen()); | 847 const bool show_main_ui = |
| 848 IsShowingMainUI(window() && window()->IsFullscreen()); |
| 3141 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, | 849 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, |
| 3142 show_main_ui && command_enabled); | 850 show_main_ui && command_enabled); |
| 3143 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, | 851 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, |
| 3144 show_main_ui && command_enabled); | 852 show_main_ui && command_enabled); |
| 3145 } | 853 } |
| 3146 | 854 |
| 3147 void Browser::UpdateCommandsForTabState() { | 855 void BrowserCommandController::UpdateCommandsForTabState() { |
| 3148 TabContents* current_tab_contents = GetActiveTabContents(); | 856 TabContents* current_tab_contents = browser_->GetActiveTabContents(); |
| 3149 if (!current_tab_contents) // May be NULL during tab restore. | 857 if (!current_tab_contents) // May be NULL during tab restore. |
| 3150 return; | 858 return; |
| 3151 WebContents* current_web_contents = current_tab_contents->web_contents(); | 859 WebContents* current_web_contents = current_tab_contents->web_contents(); |
| 3152 | 860 |
| 3153 // Navigation commands | 861 // Navigation commands |
| 3154 NavigationController& nc = current_web_contents->GetController(); | 862 command_updater_.UpdateCommandEnabled(IDC_BACK, CanGoBack(browser_)); |
| 3155 command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack()); | 863 command_updater_.UpdateCommandEnabled(IDC_FORWARD, CanGoForward(browser_)); |
| 3156 command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward()); | 864 command_updater_.UpdateCommandEnabled(IDC_RELOAD, CanReload(browser_)); |
| 3157 command_updater_.UpdateCommandEnabled( | 865 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, |
| 3158 IDC_RELOAD, CanReloadContents(current_tab_contents)); | 866 CanReload(browser_)); |
| 3159 command_updater_.UpdateCommandEnabled( | |
| 3160 IDC_RELOAD_IGNORING_CACHE, CanReloadContents(current_tab_contents)); | |
| 3161 | 867 |
| 3162 // Window management commands | 868 // Window management commands |
| 3163 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, | 869 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, |
| 3164 !is_app() && CanDuplicateContentsAt(active_index())); | 870 !browser_->is_app() && CanDuplicateTab(browser_)); |
| 3165 | 871 |
| 3166 // Page-related commands | 872 // Page-related commands |
| 3167 window_->SetStarredState( | 873 window()->SetStarredState( |
| 3168 current_tab_contents->bookmark_tab_helper()->is_starred()); | 874 current_tab_contents->bookmark_tab_helper()->is_starred()); |
| 3169 window_->SetZoomIconState( | 875 window()->SetZoomIconState( |
| 3170 current_tab_contents->zoom_controller()->zoom_icon_state()); | 876 current_tab_contents->zoom_controller()->zoom_icon_state()); |
| 3171 window_->SetZoomIconTooltipPercent( | 877 window()->SetZoomIconTooltipPercent( |
| 3172 current_tab_contents->zoom_controller()->zoom_percent()); | 878 current_tab_contents->zoom_controller()->zoom_percent()); |
| 3173 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE, | 879 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE, |
| 3174 current_web_contents->GetController().CanViewSource()); | 880 CanViewSource(browser_)); |
| 3175 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, | 881 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, |
| 3176 toolbar_model_->ShouldDisplayURL() && | 882 CanEmailPageLocation(browser_)); |
| 3177 current_web_contents->GetURL().is_valid()); | 883 if (browser_->is_devtools()) |
| 3178 if (is_devtools()) | 884 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false); |
| 3179 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false); | |
| 3180 | 885 |
| 3181 // Changing the encoding is not possible on Chrome-internal webpages. | 886 // Changing the encoding is not possible on Chrome-internal webpages. |
| 887 NavigationController& nc = current_web_contents->GetController(); |
| 3182 bool is_chrome_internal = HasInternalURL(nc.GetActiveEntry()) || | 888 bool is_chrome_internal = HasInternalURL(nc.GetActiveEntry()) || |
| 3183 current_web_contents->ShowingInterstitialPage(); | 889 current_web_contents->ShowingInterstitialPage(); |
| 3184 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU, | 890 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU, |
| 3185 !is_chrome_internal && current_web_contents->IsSavable()); | 891 !is_chrome_internal && current_web_contents->IsSavable()); |
| 3186 | 892 |
| 3187 // Show various bits of UI | 893 // Show various bits of UI |
| 3188 // TODO(pinkerton): Disable app-mode in the model until we implement it | 894 // TODO(pinkerton): Disable app-mode in the model until we implement it |
| 3189 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148 | 895 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148 |
| 3190 #if !defined(OS_MACOSX) | 896 #if !defined(OS_MACOSX) |
| 3191 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, | 897 command_updater_.UpdateCommandEnabled( |
| 3192 web_app::IsValidUrl(current_web_contents->GetURL())); | 898 IDC_CREATE_SHORTCUTS, |
| 899 CanCreateApplicationShortcuts(browser_)); |
| 3193 #endif | 900 #endif |
| 3194 | 901 |
| 3195 UpdateCommandsForContentRestrictionState(); | 902 UpdateCommandsForContentRestrictionState(); |
| 3196 UpdateCommandsForBookmarkEditing(); | 903 UpdateCommandsForBookmarkEditing(); |
| 3197 } | 904 } |
| 3198 | 905 |
| 3199 void Browser::UpdateCommandsForContentRestrictionState() { | 906 void BrowserCommandController::UpdateCommandsForContentRestrictionState() { |
| 3200 int restrictions = GetContentRestrictionsForSelectedTab(); | 907 int restrictions = GetContentRestrictions(browser_); |
| 3201 | 908 |
| 3202 command_updater_.UpdateCommandEnabled( | 909 command_updater_.UpdateCommandEnabled( |
| 3203 IDC_COPY, !(restrictions & content::CONTENT_RESTRICTION_COPY)); | 910 IDC_COPY, !(restrictions & content::CONTENT_RESTRICTION_COPY)); |
| 3204 command_updater_.UpdateCommandEnabled( | 911 command_updater_.UpdateCommandEnabled( |
| 3205 IDC_CUT, !(restrictions & content::CONTENT_RESTRICTION_CUT)); | 912 IDC_CUT, !(restrictions & content::CONTENT_RESTRICTION_CUT)); |
| 3206 command_updater_.UpdateCommandEnabled( | 913 command_updater_.UpdateCommandEnabled( |
| 3207 IDC_PASTE, !(restrictions & content::CONTENT_RESTRICTION_PASTE)); | 914 IDC_PASTE, !(restrictions & content::CONTENT_RESTRICTION_PASTE)); |
| 3208 UpdateSaveAsState(restrictions); | 915 UpdateSaveAsState(); |
| 3209 UpdatePrintingState(restrictions); | 916 UpdatePrintingState(); |
| 3210 } | 917 } |
| 3211 | 918 |
| 3212 void Browser::UpdateCommandsForDevTools() { | 919 void BrowserCommandController::UpdateCommandsForDevTools() { |
| 3213 bool dev_tools_enabled = | 920 bool dev_tools_enabled = |
| 3214 !profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled); | 921 !profile()->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled); |
| 3215 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS, | 922 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS, |
| 3216 dev_tools_enabled); | 923 dev_tools_enabled); |
| 3217 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE, | 924 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE, |
| 3218 dev_tools_enabled); | 925 dev_tools_enabled); |
| 3219 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT, | 926 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT, |
| 3220 dev_tools_enabled); | 927 dev_tools_enabled); |
| 3221 } | 928 } |
| 3222 | 929 |
| 3223 void Browser::UpdateCommandsForBookmarkEditing() { | 930 void BrowserCommandController::UpdateCommandsForBookmarkEditing() { |
| 3224 bool enabled = | |
| 3225 profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled) && | |
| 3226 browser_defaults::bookmarks_enabled; | |
| 3227 | |
| 3228 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE, | 931 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE, |
| 3229 enabled && is_type_tabbed()); | 932 CanBookmarkCurrentPage(browser_)); |
| 3230 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS, | 933 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS, |
| 3231 enabled && CanBookmarkAllTabs()); | 934 CanBookmarkAllTabs(browser_)); |
| 3232 command_updater_.UpdateCommandEnabled(IDC_PIN_TO_START_SCREEN, | 935 command_updater_.UpdateCommandEnabled(IDC_PIN_TO_START_SCREEN, |
| 3233 true); | 936 true); |
| 3234 } | 937 } |
| 3235 | 938 |
| 3236 void Browser::UpdateCommandsForBookmarkBar() { | 939 void BrowserCommandController::UpdateCommandsForBookmarkBar() { |
| 3237 const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen()); | 940 const bool show_main_ui = |
| 941 IsShowingMainUI(window() && window()->IsFullscreen()); |
| 3238 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR, | 942 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR, |
| 3239 browser_defaults::bookmarks_enabled && | 943 browser_defaults::bookmarks_enabled && |
| 3240 !profile_->GetPrefs()->IsManagedPreference(prefs::kShowBookmarkBar) && | 944 !profile()->GetPrefs()->IsManagedPreference(prefs::kShowBookmarkBar) && |
| 3241 show_main_ui); | 945 show_main_ui); |
| 3242 } | 946 } |
| 3243 | 947 |
| 3244 void Browser::MarkHomePageAsChanged(PrefService* pref_service) { | 948 void BrowserCommandController::UpdateCommandsForFullscreenMode( |
| 3245 pref_service->SetBoolean(prefs::kHomePageChanged, true); | 949 FullScreenMode fullscreen_mode) { |
| 3246 } | |
| 3247 | |
| 3248 void Browser::UpdateCommandsForFullscreenMode(FullScreenMode fullscreen_mode) { | |
| 3249 const bool show_main_ui = | 950 const bool show_main_ui = |
| 3250 IsShowingMainUI(fullscreen_mode != FULLSCREEN_DISABLED); | 951 IsShowingMainUI(fullscreen_mode != FULLSCREEN_DISABLED); |
| 3251 bool main_not_fullscreen = show_main_ui && | 952 bool main_not_fullscreen = show_main_ui && |
| 3252 (fullscreen_mode == FULLSCREEN_DISABLED); | 953 (fullscreen_mode == FULLSCREEN_DISABLED); |
| 3253 | 954 |
| 3254 // Navigation commands | 955 // Navigation commands |
| 3255 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui); | 956 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui); |
| 3256 | 957 |
| 3257 // Window management commands | 958 // Window management commands |
| 3258 command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB, | 959 command_updater_.UpdateCommandEnabled( |
| 3259 type_ != TYPE_TABBED && (fullscreen_mode == FULLSCREEN_DISABLED)); | 960 IDC_SHOW_AS_TAB, |
| 961 !browser_->is_type_tabbed() && fullscreen_mode == FULLSCREEN_DISABLED); |
| 3260 | 962 |
| 3261 // Focus various bits of UI | 963 // Focus various bits of UI |
| 3262 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui); | 964 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui); |
| 3263 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui); | 965 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui); |
| 3264 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui); | 966 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui); |
| 3265 command_updater_.UpdateCommandEnabled( | 967 command_updater_.UpdateCommandEnabled( |
| 3266 IDC_FOCUS_MENU_BAR, main_not_fullscreen); | 968 IDC_FOCUS_MENU_BAR, main_not_fullscreen); |
| 3267 command_updater_.UpdateCommandEnabled( | 969 command_updater_.UpdateCommandEnabled( |
| 3268 IDC_FOCUS_NEXT_PANE, main_not_fullscreen); | 970 IDC_FOCUS_NEXT_PANE, main_not_fullscreen); |
| 3269 command_updater_.UpdateCommandEnabled( | 971 command_updater_.UpdateCommandEnabled( |
| 3270 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen); | 972 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen); |
| 3271 command_updater_.UpdateCommandEnabled( | 973 command_updater_.UpdateCommandEnabled( |
| 3272 IDC_FOCUS_BOOKMARKS, main_not_fullscreen); | 974 IDC_FOCUS_BOOKMARKS, main_not_fullscreen); |
| 3273 | 975 |
| 3274 // Show various bits of UI | 976 // Show various bits of UI |
| 3275 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui); | 977 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui); |
| 3276 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui); | 978 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui); |
| 3277 command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP, | 979 command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP, |
| 3278 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible()); | 980 show_main_ui && profile()->GetOriginalProfile()->IsSyncAccessible()); |
| 3279 | 981 |
| 3280 // Settings page/subpages are forced to open in normal mode. We disable these | 982 // Settings page/subpages are forced to open in normal mode. We disable these |
| 3281 // commands when incognito is forced. | 983 // commands when incognito is forced. |
| 3282 const bool options_enabled = show_main_ui && | 984 const bool options_enabled = show_main_ui && |
| 3283 IncognitoModePrefs::GetAvailability( | 985 IncognitoModePrefs::GetAvailability( |
| 3284 profile_->GetPrefs()) != IncognitoModePrefs::FORCED; | 986 profile()->GetPrefs()) != IncognitoModePrefs::FORCED; |
| 3285 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled); | 987 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled); |
| 3286 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, options_enabled); | 988 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, options_enabled); |
| 3287 | 989 |
| 3288 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui); | 990 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui); |
| 3289 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui); | 991 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui); |
| 3290 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui); | 992 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui); |
| 3291 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui); | 993 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui); |
| 3292 #if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC) | 994 #if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC) |
| 3293 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui); | 995 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui); |
| 3294 #endif | 996 #endif |
| 3295 | 997 |
| 3296 // Disable explicit fullscreen toggling when in metro snap mode. | 998 // Disable explicit fullscreen toggling when in metro snap mode. |
| 3297 command_updater_.UpdateCommandEnabled( | 999 command_updater_.UpdateCommandEnabled( |
| 3298 IDC_FULLSCREEN, | 1000 IDC_FULLSCREEN, |
| 3299 fullscreen_mode != FULLSCREEN_METRO_SNAP); | 1001 fullscreen_mode != FULLSCREEN_METRO_SNAP); |
| 3300 | 1002 |
| 3301 UpdateCommandsForBookmarkBar(); | 1003 UpdateCommandsForBookmarkBar(); |
| 3302 UpdateCommandsForMultipleProfiles(); | 1004 UpdateCommandsForMultipleProfiles(); |
| 3303 } | 1005 } |
| 3304 | 1006 |
| 3305 void Browser::UpdateCommandsForMultipleProfiles() { | 1007 void BrowserCommandController::UpdateCommandsForMultipleProfiles() { |
| 3306 bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen()); | 1008 bool show_main_ui = IsShowingMainUI(window() && window()->IsFullscreen()); |
| 3307 command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU, | 1009 command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU, |
| 3308 show_main_ui && | 1010 show_main_ui && |
| 3309 !profile()->IsOffTheRecord() && | 1011 !profile()->IsOffTheRecord() && |
| 3310 ProfileManager::IsMultipleProfilesEnabled()); | 1012 ProfileManager::IsMultipleProfilesEnabled()); |
| 3311 } | 1013 } |
| 3312 | 1014 |
| 3313 void Browser::UpdatePrintingState(int content_restrictions) { | 1015 void BrowserCommandController::UpdatePrintingState() { |
| 3314 bool print_enabled = true; | 1016 command_updater_.UpdateCommandEnabled(IDC_PRINT, CanPrint(browser_)); |
| 3315 bool advanced_print_enabled = true; | |
| 3316 if (g_browser_process->local_state()) { | |
| 3317 print_enabled = | |
| 3318 g_browser_process->local_state()->GetBoolean(prefs::kPrintingEnabled); | |
| 3319 advanced_print_enabled = print_enabled; | |
| 3320 } | |
| 3321 if (print_enabled) { | |
| 3322 // Do not print when a constrained window is showing. It's confusing. | |
| 3323 TabContents* tab_contents = GetActiveTabContents(); | |
| 3324 bool has_constrained_window = | |
| 3325 tab_contents && | |
| 3326 tab_contents->constrained_window_tab_helper()-> | |
| 3327 constrained_window_count(); | |
| 3328 if (has_constrained_window || | |
| 3329 content_restrictions & content::CONTENT_RESTRICTION_PRINT) { | |
| 3330 print_enabled = false; | |
| 3331 advanced_print_enabled = false; | |
| 3332 } | |
| 3333 | |
| 3334 // The exception is print preview, | |
| 3335 // where advanced printing is always enabled. | |
| 3336 printing::PrintPreviewTabController* controller = | |
| 3337 printing::PrintPreviewTabController::GetInstance(); | |
| 3338 if (controller && (controller->GetPrintPreviewForTab(tab_contents) || | |
| 3339 controller->is_creating_print_preview_tab())) { | |
| 3340 advanced_print_enabled = true; | |
| 3341 } | |
| 3342 } | |
| 3343 command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled); | |
| 3344 command_updater_.UpdateCommandEnabled(IDC_ADVANCED_PRINT, | 1017 command_updater_.UpdateCommandEnabled(IDC_ADVANCED_PRINT, |
| 3345 advanced_print_enabled); | 1018 CanAdvancedPrint(browser_)); |
| 3346 } | 1019 } |
| 3347 | 1020 |
| 3348 void Browser::UpdateSaveAsState(int content_restrictions) { | 1021 void BrowserCommandController::UpdateSaveAsState() { |
| 3349 bool enabled = !(content_restrictions & content::CONTENT_RESTRICTION_SAVE); | 1022 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, CanSavePage(browser_)); |
| 3350 enabled = enabled && CanSaveContents(GetActiveTabContents()); | |
| 3351 PrefService* state = g_browser_process->local_state(); | |
| 3352 if (state) | |
| 3353 enabled = enabled && state->GetBoolean(prefs::kAllowFileSelectionDialogs); | |
| 3354 | |
| 3355 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, enabled); | |
| 3356 } | 1023 } |
| 3357 | 1024 |
| 3358 void Browser::UpdateOpenFileState() { | 1025 void BrowserCommandController::UpdateOpenFileState() { |
| 3359 bool enabled = true; | 1026 bool enabled = true; |
| 3360 PrefService* local_state = g_browser_process->local_state(); | 1027 PrefService* local_state = g_browser_process->local_state(); |
| 3361 if (local_state) | 1028 if (local_state) |
| 3362 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs); | 1029 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs); |
| 3363 | 1030 |
| 3364 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, enabled); | 1031 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, enabled); |
| 3365 } | 1032 } |
| 3366 | 1033 |
| 3367 void Browser::UpdateReloadStopState(bool is_loading, bool force) { | 1034 void BrowserCommandController::UpdateReloadStopState(bool is_loading, |
| 3368 window_->UpdateReloadStopState(is_loading, force); | 1035 bool force) { |
| 1036 window()->UpdateReloadStopState(is_loading, force); |
| 3369 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading); | 1037 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading); |
| 3370 } | 1038 } |
| 3371 | 1039 |
| 3372 /////////////////////////////////////////////////////////////////////////////// | 1040 void BrowserCommandController::AddInterstitialObservers(TabContents* contents) { |
| 3373 // Browser, UI update coalescing and handling (private): | 1041 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED, |
| 3374 | 1042 content::Source<WebContents>(contents->web_contents())); |
| 3375 void Browser::UpdateToolbar(bool should_restore_state) { | 1043 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_DETACHED, |
| 3376 window_->UpdateToolbar(GetActiveTabContents(), should_restore_state); | 1044 content::Source<WebContents>(contents->web_contents())); |
| 3377 } | 1045 } |
| 3378 | 1046 |
| 3379 void Browser::UpdateSearchState(TabContents* contents) { | 1047 void BrowserCommandController::RemoveInterstitialObservers( |
| 3380 if (chrome::search::IsInstantExtendedAPIEnabled(profile_)) | 1048 TabContents* contents) { |
| 3381 search_delegate_->OnTabActivated(contents); | |
| 3382 } | |
| 3383 | |
| 3384 void Browser::ScheduleUIUpdate(const WebContents* source, | |
| 3385 unsigned changed_flags) { | |
| 3386 if (!source) | |
| 3387 return; | |
| 3388 | |
| 3389 // Do some synchronous updates. | |
| 3390 if (changed_flags & content::INVALIDATE_TYPE_URL && | |
| 3391 source == GetActiveWebContents()) { | |
| 3392 // Only update the URL for the current tab. Note that we do not update | |
| 3393 // the navigation commands since those would have already been updated | |
| 3394 // synchronously by NavigationStateChanged. | |
| 3395 UpdateToolbar(false); | |
| 3396 changed_flags &= ~content::INVALIDATE_TYPE_URL; | |
| 3397 } | |
| 3398 if (changed_flags & content::INVALIDATE_TYPE_LOAD) { | |
| 3399 // Update the loading state synchronously. This is so the throbber will | |
| 3400 // immediately start/stop, which gives a more snappy feel. We want to do | |
| 3401 // this for any tab so they start & stop quickly. | |
| 3402 tab_strip_model_->UpdateTabContentsStateAt( | |
| 3403 GetIndexOfController(&source->GetController()), | |
| 3404 TabStripModelObserver::LOADING_ONLY); | |
| 3405 // The status bubble needs to be updated during INVALIDATE_TYPE_LOAD too, | |
| 3406 // but we do that asynchronously by not stripping INVALIDATE_TYPE_LOAD from | |
| 3407 // changed_flags. | |
| 3408 } | |
| 3409 | |
| 3410 if (changed_flags & content::INVALIDATE_TYPE_TITLE && !source->IsLoading()) { | |
| 3411 // To correctly calculate whether the title changed while not loading | |
| 3412 // we need to process the update synchronously. This state only matters for | |
| 3413 // the TabStripModel, so we notify the TabStripModel now and notify others | |
| 3414 // asynchronously. | |
| 3415 tab_strip_model_->UpdateTabContentsStateAt( | |
| 3416 GetIndexOfController(&source->GetController()), | |
| 3417 TabStripModelObserver::TITLE_NOT_LOADING); | |
| 3418 } | |
| 3419 | |
| 3420 // If the only updates were synchronously handled above, we're done. | |
| 3421 if (changed_flags == 0) | |
| 3422 return; | |
| 3423 | |
| 3424 // Save the dirty bits. | |
| 3425 scheduled_updates_[source] |= changed_flags; | |
| 3426 | |
| 3427 if (!chrome_updater_factory_.HasWeakPtrs()) { | |
| 3428 // No task currently scheduled, start another. | |
| 3429 MessageLoop::current()->PostDelayedTask( | |
| 3430 FROM_HERE, | |
| 3431 base::Bind(&Browser::ProcessPendingUIUpdates, | |
| 3432 chrome_updater_factory_.GetWeakPtr()), | |
| 3433 base::TimeDelta::FromMilliseconds(kUIUpdateCoalescingTimeMS)); | |
| 3434 } | |
| 3435 } | |
| 3436 | |
| 3437 void Browser::ProcessPendingUIUpdates() { | |
| 3438 #ifndef NDEBUG | |
| 3439 // Validate that all tabs we have pending updates for exist. This is scary | |
| 3440 // because the pending list must be kept in sync with any detached or | |
| 3441 // deleted tabs. | |
| 3442 for (UpdateMap::const_iterator i = scheduled_updates_.begin(); | |
| 3443 i != scheduled_updates_.end(); ++i) { | |
| 3444 bool found = false; | |
| 3445 for (int tab = 0; tab < tab_count(); tab++) { | |
| 3446 if (GetWebContentsAt(tab) == i->first) { | |
| 3447 found = true; | |
| 3448 break; | |
| 3449 } | |
| 3450 } | |
| 3451 DCHECK(found); | |
| 3452 } | |
| 3453 #endif | |
| 3454 | |
| 3455 chrome_updater_factory_.InvalidateWeakPtrs(); | |
| 3456 | |
| 3457 for (UpdateMap::const_iterator i = scheduled_updates_.begin(); | |
| 3458 i != scheduled_updates_.end(); ++i) { | |
| 3459 // Do not dereference |contents|, it may be out-of-date! | |
| 3460 const WebContents* contents = i->first; | |
| 3461 unsigned flags = i->second; | |
| 3462 | |
| 3463 if (contents == GetActiveWebContents()) { | |
| 3464 // Updates that only matter when the tab is selected go here. | |
| 3465 | |
| 3466 if (flags & content::INVALIDATE_TYPE_PAGE_ACTIONS) { | |
| 3467 LocationBar* location_bar = window()->GetLocationBar(); | |
| 3468 if (location_bar) | |
| 3469 location_bar->UpdatePageActions(); | |
| 3470 } | |
| 3471 // Updating the URL happens synchronously in ScheduleUIUpdate. | |
| 3472 if (flags & content::INVALIDATE_TYPE_LOAD && GetStatusBubble()) { | |
| 3473 GetStatusBubble()->SetStatus( | |
| 3474 GetActiveTabContents()-> | |
| 3475 core_tab_helper()->GetStatusText()); | |
| 3476 } | |
| 3477 | |
| 3478 if (flags & (content::INVALIDATE_TYPE_TAB | | |
| 3479 content::INVALIDATE_TYPE_TITLE)) { | |
| 3480 // TODO(pinkerton): Disable app-mode in the model until we implement it | |
| 3481 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148 | |
| 3482 #if !defined(OS_MACOSX) | |
| 3483 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, | |
| 3484 web_app::IsValidUrl(contents->GetURL())); | |
| 3485 #endif | |
| 3486 window_->UpdateTitleBar(); | |
| 3487 } | |
| 3488 } | |
| 3489 | |
| 3490 // Updates that don't depend upon the selected state go here. | |
| 3491 if (flags & | |
| 3492 (content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) { | |
| 3493 tab_strip_model_->UpdateTabContentsStateAt( | |
| 3494 tab_strip_model_->GetIndexOfWebContents(contents), | |
| 3495 TabStripModelObserver::ALL); | |
| 3496 } | |
| 3497 | |
| 3498 // We don't need to process INVALIDATE_STATE, since that's not visible. | |
| 3499 } | |
| 3500 | |
| 3501 scheduled_updates_.clear(); | |
| 3502 } | |
| 3503 | |
| 3504 void Browser::RemoveScheduledUpdatesFor(WebContents* contents) { | |
| 3505 if (!contents) | |
| 3506 return; | |
| 3507 | |
| 3508 UpdateMap::iterator i = scheduled_updates_.find(contents); | |
| 3509 if (i != scheduled_updates_.end()) | |
| 3510 scheduled_updates_.erase(i); | |
| 3511 } | |
| 3512 | |
| 3513 | |
| 3514 /////////////////////////////////////////////////////////////////////////////// | |
| 3515 // Browser, Getters for UI (private): | |
| 3516 | |
| 3517 StatusBubble* Browser::GetStatusBubble() { | |
| 3518 #if !defined(OS_MACOSX) | |
| 3519 // In kiosk mode, we want to always hide the status bubble. | |
| 3520 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) | |
| 3521 return NULL; | |
| 3522 #endif | |
| 3523 return window_ ? window_->GetStatusBubble() : NULL; | |
| 3524 } | |
| 3525 | |
| 3526 /////////////////////////////////////////////////////////////////////////////// | |
| 3527 // Browser, Session restore functions (private): | |
| 3528 | |
| 3529 void Browser::SyncHistoryWithTabs(int index) { | |
| 3530 SessionService* session_service = | |
| 3531 SessionServiceFactory::GetForProfileIfExisting(profile()); | |
| 3532 if (session_service) { | |
| 3533 for (int i = index; i < tab_count(); ++i) { | |
| 3534 TabContents* tab = GetTabContentsAt(i); | |
| 3535 if (tab) { | |
| 3536 session_service->SetTabIndexInWindow( | |
| 3537 session_id(), tab->restore_tab_helper()->session_id(), i); | |
| 3538 session_service->SetPinnedState( | |
| 3539 session_id(), | |
| 3540 tab->restore_tab_helper()->session_id(), | |
| 3541 IsTabPinned(i)); | |
| 3542 } | |
| 3543 } | |
| 3544 } | |
| 3545 } | |
| 3546 | |
| 3547 /////////////////////////////////////////////////////////////////////////////// | |
| 3548 // Browser, OnBeforeUnload handling (private): | |
| 3549 | |
| 3550 void Browser::ProcessPendingTabs() { | |
| 3551 if (!is_attempting_to_close_browser_) { | |
| 3552 // Because we might invoke this after a delay it's possible for the value of | |
| 3553 // is_attempting_to_close_browser_ to have changed since we scheduled the | |
| 3554 // task. | |
| 3555 return; | |
| 3556 } | |
| 3557 | |
| 3558 if (HasCompletedUnloadProcessing()) { | |
| 3559 // We've finished all the unload events and can proceed to close the | |
| 3560 // browser. | |
| 3561 OnWindowClosing(); | |
| 3562 return; | |
| 3563 } | |
| 3564 | |
| 3565 // Process beforeunload tabs first. When that queue is empty, process | |
| 3566 // unload tabs. | |
| 3567 if (!tabs_needing_before_unload_fired_.empty()) { | |
| 3568 WebContents* web_contents = *(tabs_needing_before_unload_fired_.begin()); | |
| 3569 // Null check render_view_host here as this gets called on a PostTask and | |
| 3570 // the tab's render_view_host may have been nulled out. | |
| 3571 if (web_contents->GetRenderViewHost()) { | |
| 3572 web_contents->GetRenderViewHost()->FirePageBeforeUnload(false); | |
| 3573 } else { | |
| 3574 ClearUnloadState(web_contents, true); | |
| 3575 } | |
| 3576 } else if (!tabs_needing_unload_fired_.empty()) { | |
| 3577 // We've finished firing all beforeunload events and can proceed with unload | |
| 3578 // events. | |
| 3579 // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting | |
| 3580 // somewhere around here so that we have accurate measurements of shutdown | |
| 3581 // time. | |
| 3582 // TODO(ojan): We can probably fire all the unload events in parallel and | |
| 3583 // get a perf benefit from that in the cases where the tab hangs in it's | |
| 3584 // unload handler or takes a long time to page in. | |
| 3585 WebContents* web_contents = *(tabs_needing_unload_fired_.begin()); | |
| 3586 // Null check render_view_host here as this gets called on a PostTask and | |
| 3587 // the tab's render_view_host may have been nulled out. | |
| 3588 if (web_contents->GetRenderViewHost()) { | |
| 3589 web_contents->GetRenderViewHost()->ClosePage(); | |
| 3590 } else { | |
| 3591 ClearUnloadState(web_contents, true); | |
| 3592 } | |
| 3593 } else { | |
| 3594 NOTREACHED(); | |
| 3595 } | |
| 3596 } | |
| 3597 | |
| 3598 bool Browser::HasCompletedUnloadProcessing() const { | |
| 3599 return is_attempting_to_close_browser_ && | |
| 3600 tabs_needing_before_unload_fired_.empty() && | |
| 3601 tabs_needing_unload_fired_.empty(); | |
| 3602 } | |
| 3603 | |
| 3604 void Browser::CancelWindowClose() { | |
| 3605 // Closing of window can be canceled from a beforeunload handler. | |
| 3606 DCHECK(is_attempting_to_close_browser_); | |
| 3607 tabs_needing_before_unload_fired_.clear(); | |
| 3608 tabs_needing_unload_fired_.clear(); | |
| 3609 is_attempting_to_close_browser_ = false; | |
| 3610 | |
| 3611 content::NotificationService::current()->Notify( | |
| 3612 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, | |
| 3613 content::Source<Browser>(this), | |
| 3614 content::NotificationService::NoDetails()); | |
| 3615 } | |
| 3616 | |
| 3617 bool Browser::RemoveFromSet(UnloadListenerSet* set, WebContents* web_contents) { | |
| 3618 DCHECK(is_attempting_to_close_browser_); | |
| 3619 | |
| 3620 UnloadListenerSet::iterator iter = | |
| 3621 std::find(set->begin(), set->end(), web_contents); | |
| 3622 if (iter != set->end()) { | |
| 3623 set->erase(iter); | |
| 3624 return true; | |
| 3625 } | |
| 3626 return false; | |
| 3627 } | |
| 3628 | |
| 3629 void Browser::ClearUnloadState(WebContents* web_contents, bool process_now) { | |
| 3630 if (is_attempting_to_close_browser_) { | |
| 3631 RemoveFromSet(&tabs_needing_before_unload_fired_, web_contents); | |
| 3632 RemoveFromSet(&tabs_needing_unload_fired_, web_contents); | |
| 3633 if (process_now) { | |
| 3634 ProcessPendingTabs(); | |
| 3635 } else { | |
| 3636 MessageLoop::current()->PostTask( | |
| 3637 FROM_HERE, | |
| 3638 base::Bind(&Browser::ProcessPendingTabs, weak_factory_.GetWeakPtr())); | |
| 3639 } | |
| 3640 } | |
| 3641 } | |
| 3642 | |
| 3643 /////////////////////////////////////////////////////////////////////////////// | |
| 3644 // Browser, In-progress download termination handling (private): | |
| 3645 | |
| 3646 bool Browser::CanCloseWithInProgressDownloads() { | |
| 3647 // If we've prompted, we need to hear from the user before we | |
| 3648 // can close. | |
| 3649 if (cancel_download_confirmation_state_ != NOT_PROMPTED) | |
| 3650 return cancel_download_confirmation_state_ != WAITING_FOR_RESPONSE; | |
| 3651 | |
| 3652 int num_downloads_blocking; | |
| 3653 if (DOWNLOAD_CLOSE_OK == | |
| 3654 OkToCloseWithInProgressDownloads(&num_downloads_blocking)) | |
| 3655 return true; | |
| 3656 | |
| 3657 // Closing this window will kill some downloads; prompt to make sure | |
| 3658 // that's ok. | |
| 3659 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; | |
| 3660 window_->ConfirmBrowserCloseWithPendingDownloads(); | |
| 3661 | |
| 3662 // Return false so the browser does not close. We'll close if the user | |
| 3663 // confirms in the dialog. | |
| 3664 return false; | |
| 3665 } | |
| 3666 | |
| 3667 /////////////////////////////////////////////////////////////////////////////// | |
| 3668 // Browser, Assorted utility functions (private): | |
| 3669 | |
| 3670 void Browser::SetAsDelegate(TabContents* tab, Browser* delegate) { | |
| 3671 // WebContents... | |
| 3672 tab->web_contents()->SetDelegate(delegate); | |
| 3673 | |
| 3674 // ...and all the helpers. | |
| 3675 tab->blocked_content_tab_helper()->set_delegate(delegate); | |
| 3676 tab->bookmark_tab_helper()->set_delegate(delegate); | |
| 3677 tab->zoom_controller()->set_observer(delegate); | |
| 3678 tab->constrained_window_tab_helper()->set_delegate(delegate); | |
| 3679 tab->core_tab_helper()->set_delegate(delegate); | |
| 3680 tab->extension_tab_helper()->set_delegate(delegate); | |
| 3681 tab->search_engine_tab_helper()->set_delegate(delegate); | |
| 3682 } | |
| 3683 | |
| 3684 void Browser::CloseFrame() { | |
| 3685 window_->Close(); | |
| 3686 } | |
| 3687 | |
| 3688 void Browser::TabDetachedAtImpl(TabContents* contents, int index, | |
| 3689 DetachType type) { | |
| 3690 if (type == DETACH_TYPE_DETACH) { | |
| 3691 // Save the current location bar state, but only if the tab being detached | |
| 3692 // is the selected tab. Because saving state can conditionally revert the | |
| 3693 // location bar, saving the current tab's location bar state to a | |
| 3694 // non-selected tab can corrupt both tabs. | |
| 3695 if (contents == GetActiveTabContents()) { | |
| 3696 LocationBar* location_bar = window()->GetLocationBar(); | |
| 3697 if (location_bar) | |
| 3698 location_bar->SaveStateToContents(contents->web_contents()); | |
| 3699 } | |
| 3700 | |
| 3701 if (!tab_strip_model_->closing_all()) | |
| 3702 SyncHistoryWithTabs(0); | |
| 3703 } | |
| 3704 | |
| 3705 SetAsDelegate(contents, NULL); | |
| 3706 RemoveScheduledUpdatesFor(contents->web_contents()); | |
| 3707 | |
| 3708 if (find_bar_controller_.get() && index == active_index()) { | |
| 3709 find_bar_controller_->ChangeTabContents(NULL); | |
| 3710 } | |
| 3711 | |
| 3712 if (is_attempting_to_close_browser_) { | |
| 3713 // If this is the last tab with unload handlers, then ProcessPendingTabs | |
| 3714 // would call back into the TabStripModel (which is invoking this method on | |
| 3715 // us). Avoid that by passing in false so that the call to | |
| 3716 // ProcessPendingTabs is delayed. | |
| 3717 ClearUnloadState(contents->web_contents(), false); | |
| 3718 } | |
| 3719 | |
| 3720 // Stop observing search model changes for this tab. | |
| 3721 search_delegate_->OnTabDetached(contents); | |
| 3722 | |
| 3723 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED, | 1049 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED, |
| 3724 content::Source<WebContents>(contents->web_contents())); | 1050 content::Source<WebContents>(contents->web_contents())); |
| 3725 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_DETACHED, | 1051 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_DETACHED, |
| 3726 content::Source<WebContents>(contents->web_contents())); | 1052 content::Source<WebContents>(contents->web_contents())); |
| 3727 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | |
| 3728 content::Source<WebContents>(contents->web_contents())); | |
| 3729 } | 1053 } |
| 3730 | 1054 |
| 3731 bool Browser::SupportsWindowFeatureImpl(WindowFeature feature, | 1055 BrowserWindow* BrowserCommandController::window() { |
| 3732 bool check_fullscreen) const { | 1056 return browser_->window(); |
| 3733 // On Mac, fullscreen mode has most normal things (in a slide-down panel). On | |
| 3734 // other platforms, we hide some controls when in fullscreen mode. | |
| 3735 bool hide_ui_for_fullscreen = false; | |
| 3736 #if !defined(OS_MACOSX) | |
| 3737 hide_ui_for_fullscreen = check_fullscreen && window_ && | |
| 3738 window_->IsFullscreen(); | |
| 3739 #endif | |
| 3740 | |
| 3741 unsigned int features = FEATURE_INFOBAR | FEATURE_DOWNLOADSHELF; | |
| 3742 | |
| 3743 if (is_type_tabbed()) | |
| 3744 features |= FEATURE_BOOKMARKBAR; | |
| 3745 | |
| 3746 if (!hide_ui_for_fullscreen) { | |
| 3747 if (!is_type_tabbed()) | |
| 3748 features |= FEATURE_TITLEBAR; | |
| 3749 | |
| 3750 if (is_type_tabbed()) | |
| 3751 features |= FEATURE_TABSTRIP; | |
| 3752 | |
| 3753 if (is_type_tabbed()) | |
| 3754 features |= FEATURE_TOOLBAR; | |
| 3755 | |
| 3756 if (!is_app()) | |
| 3757 features |= FEATURE_LOCATIONBAR; | |
| 3758 } | |
| 3759 return !!(features & feature); | |
| 3760 } | 1057 } |
| 3761 | 1058 |
| 3762 void Browser::CreateInstantIfNecessary() { | 1059 Profile* BrowserCommandController::profile() { |
| 3763 if (is_type_tabbed() && InstantController::IsEnabled(profile()) && | 1060 return browser_->profile(); |
| 3764 !profile()->IsOffTheRecord()) { | |
| 3765 instant_.reset(new InstantController(this, InstantController::INSTANT)); | |
| 3766 instant_unload_handler_.reset(new InstantUnloadHandler(this)); | |
| 3767 } | |
| 3768 } | 1061 } |
| 3769 | 1062 |
| 3770 int Browser::GetContentRestrictionsForSelectedTab() { | 1063 } // namespace chrome |
| 3771 int content_restrictions = 0; | |
| 3772 WebContents* current_tab = GetActiveWebContents(); | |
| 3773 if (current_tab) { | |
| 3774 content_restrictions = current_tab->GetContentRestrictions(); | |
| 3775 NavigationEntry* active_entry = | |
| 3776 current_tab->GetController().GetActiveEntry(); | |
| 3777 // See comment in UpdateCommandsForTabState about why we call url(). | |
| 3778 if (!download_util::IsSavableURL( | |
| 3779 active_entry ? active_entry->GetURL() : GURL()) | |
| 3780 || current_tab->ShowingInterstitialPage()) | |
| 3781 content_restrictions |= content::CONTENT_RESTRICTION_SAVE; | |
| 3782 if (current_tab->ShowingInterstitialPage()) | |
| 3783 content_restrictions |= content::CONTENT_RESTRICTION_PRINT; | |
| 3784 } | |
| 3785 return content_restrictions; | |
| 3786 } | |
| 3787 | |
| 3788 void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) { | |
| 3789 BookmarkBar::State state; | |
| 3790 // The bookmark bar is hidden in fullscreen mode, unless on the new tab page. | |
| 3791 if (browser_defaults::bookmarks_enabled && | |
| 3792 profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) && | |
| 3793 (!window_ || !window_->IsFullscreen())) { | |
| 3794 state = BookmarkBar::SHOW; | |
| 3795 } else { | |
| 3796 TabContents* tab = GetActiveTabContents(); | |
| 3797 if (tab && tab->bookmark_tab_helper()->ShouldShowBookmarkBar()) | |
| 3798 state = BookmarkBar::DETACHED; | |
| 3799 else | |
| 3800 state = BookmarkBar::HIDDEN; | |
| 3801 } | |
| 3802 | |
| 3803 // Only allow the bookmark bar to be shown in default mode. | |
| 3804 if (!search_model_->mode().is_default()) | |
| 3805 state = BookmarkBar::HIDDEN; | |
| 3806 | |
| 3807 if (state == bookmark_bar_state_) | |
| 3808 return; | |
| 3809 | |
| 3810 bookmark_bar_state_ = state; | |
| 3811 | |
| 3812 if (!window_) | |
| 3813 return; // This is called from the constructor when window_ is NULL. | |
| 3814 | |
| 3815 if (reason == BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH) { | |
| 3816 // Don't notify BrowserWindow on a tab switch as at the time this is invoked | |
| 3817 // BrowserWindow hasn't yet switched tabs. The BrowserWindow implementations | |
| 3818 // end up querying state once they process the tab switch. | |
| 3819 return; | |
| 3820 } | |
| 3821 | |
| 3822 BookmarkBar::AnimateChangeType animate_type = | |
| 3823 (reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE) ? | |
| 3824 BookmarkBar::ANIMATE_STATE_CHANGE : | |
| 3825 BookmarkBar::DONT_ANIMATE_STATE_CHANGE; | |
| 3826 window_->BookmarkBarStateChanged(animate_type); | |
| 3827 } | |
| 3828 | |
| 3829 bool Browser::MaybeCreateBackgroundContents(int route_id, | |
| 3830 WebContents* opener_web_contents, | |
| 3831 const string16& frame_name, | |
| 3832 const GURL& target_url) { | |
| 3833 GURL opener_url = opener_web_contents->GetURL(); | |
| 3834 ExtensionService* extensions_service = profile_->GetExtensionService(); | |
| 3835 | |
| 3836 if (!opener_url.is_valid() || | |
| 3837 frame_name.empty() || | |
| 3838 !extensions_service || | |
| 3839 !extensions_service->is_ready()) | |
| 3840 return false; | |
| 3841 | |
| 3842 // Only hosted apps have web extents, so this ensures that only hosted apps | |
| 3843 // can create BackgroundContents. We don't have to check for background | |
| 3844 // permission as that is checked in RenderMessageFilter when the CreateWindow | |
| 3845 // message is processed. | |
| 3846 const Extension* extension = | |
| 3847 extensions_service->extensions()->GetHostedAppByURL( | |
| 3848 ExtensionURLInfo(opener_url)); | |
| 3849 if (!extension) | |
| 3850 return false; | |
| 3851 | |
| 3852 // No BackgroundContents allowed if BackgroundContentsService doesn't exist. | |
| 3853 BackgroundContentsService* service = | |
| 3854 BackgroundContentsServiceFactory::GetForProfile(profile_); | |
| 3855 if (!service) | |
| 3856 return false; | |
| 3857 | |
| 3858 // Ensure that we're trying to open this from the extension's process. | |
| 3859 SiteInstance* opener_site_instance = opener_web_contents->GetSiteInstance(); | |
| 3860 extensions::ProcessMap* process_map = extensions_service->process_map(); | |
| 3861 if (!opener_site_instance->GetProcess() || | |
| 3862 !process_map->Contains( | |
| 3863 extension->id(), opener_site_instance->GetProcess()->GetID())) { | |
| 3864 return false; | |
| 3865 } | |
| 3866 | |
| 3867 // Only allow a single background contents per app. | |
| 3868 bool allow_js_access = extension->allow_background_js_access(); | |
| 3869 BackgroundContents* existing = | |
| 3870 service->GetAppBackgroundContents(ASCIIToUTF16(extension->id())); | |
| 3871 if (existing) { | |
| 3872 // For non-scriptable background contents, ignore the request altogether, | |
| 3873 // (returning true, so that a regular WebContents isn't created either). | |
| 3874 if (!allow_js_access) | |
| 3875 return true; | |
| 3876 // For scriptable background pages, if one already exists, close it (even | |
| 3877 // if it was specified in the manifest). | |
| 3878 DLOG(INFO) << "Closing existing BackgroundContents for " << opener_url; | |
| 3879 delete existing; | |
| 3880 } | |
| 3881 | |
| 3882 // If script access is not allowed, create the the background contents in a | |
| 3883 // new SiteInstance, so that a separate process is used. | |
| 3884 scoped_refptr<content::SiteInstance> site_instance = | |
| 3885 allow_js_access ? | |
| 3886 opener_site_instance : | |
| 3887 content::SiteInstance::Create(opener_web_contents->GetBrowserContext()); | |
| 3888 | |
| 3889 // Passed all the checks, so this should be created as a BackgroundContents. | |
| 3890 BackgroundContents* contents = service->CreateBackgroundContents( | |
| 3891 site_instance, | |
| 3892 route_id, | |
| 3893 profile_, | |
| 3894 frame_name, | |
| 3895 ASCIIToUTF16(extension->id())); | |
| 3896 | |
| 3897 // When a separate process is used, the original renderer cannot access the | |
| 3898 // new window later, thus we need to navigate the window now. | |
| 3899 if (contents && !allow_js_access) { | |
| 3900 contents->web_contents()->GetController().LoadURL( | |
| 3901 target_url, | |
| 3902 content::Referrer(), | |
| 3903 content::PAGE_TRANSITION_LINK, | |
| 3904 std::string()); // No extra headers. | |
| 3905 } | |
| 3906 | |
| 3907 return contents != NULL; | |
| 3908 } | |
| OLD | NEW |