Support SizeClassIdiom on iOS7.
[chromium-blink-merge.git] / chrome / browser / ui / browser_commands.cc
blobf74bb759321d48e9e441789c7bcedf57f0ae410e
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/browser_commands.h"
7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/app/chrome_command_ids.h"
12 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/browsing_data/browsing_data_helper.h"
15 #include "chrome/browser/browsing_data/browsing_data_remover.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/devtools/devtools_window.h"
18 #include "chrome/browser/dom_distiller/tab_utils.h"
19 #include "chrome/browser/lifetime/application_lifetime.h"
20 #include "chrome/browser/platform_util.h"
21 #include "chrome/browser/prefs/incognito_mode_prefs.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/search/search.h"
24 #include "chrome/browser/sessions/session_service_factory.h"
25 #include "chrome/browser/sessions/tab_restore_service.h"
26 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
27 #include "chrome/browser/sessions/tab_restore_service_factory.h"
28 #include "chrome/browser/translate/chrome_translate_client.h"
29 #include "chrome/browser/ui/accelerator_utils.h"
30 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
31 #include "chrome/browser/ui/browser.h"
32 #include "chrome/browser/ui/browser_command_controller.h"
33 #include "chrome/browser/ui/browser_dialogs.h"
34 #include "chrome/browser/ui/browser_instant_controller.h"
35 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
36 #include "chrome/browser/ui/browser_tabstrip.h"
37 #include "chrome/browser/ui/browser_window.h"
38 #include "chrome/browser/ui/chrome_pages.h"
39 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
40 #include "chrome/browser/ui/find_bar/find_bar.h"
41 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
42 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
43 #include "chrome/browser/ui/location_bar/location_bar.h"
44 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
45 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
46 #include "chrome/browser/ui/search/search_tab_helper.h"
47 #include "chrome/browser/ui/status_bubble.h"
48 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
49 #include "chrome/browser/ui/tab_dialogs.h"
50 #include "chrome/browser/ui/tabs/tab_strip_model.h"
51 #include "chrome/browser/upgrade_detector.h"
52 #include "chrome/common/chrome_switches.h"
53 #include "chrome/common/content_restriction.h"
54 #include "chrome/common/pref_names.h"
55 #include "components/bookmarks/browser/bookmark_model.h"
56 #include "components/bookmarks/browser/bookmark_utils.h"
57 #include "components/favicon/content/content_favicon_driver.h"
58 #include "components/google/core/browser/google_util.h"
59 #include "components/signin/core/browser/signin_header_helper.h"
60 #include "components/translate/core/browser/language_state.h"
61 #include "components/ui/zoom/page_zoom.h"
62 #include "components/ui/zoom/zoom_controller.h"
63 #include "components/version_info/version_info.h"
64 #include "components/web_modal/web_contents_modal_dialog_manager.h"
65 #include "content/public/browser/devtools_agent_host.h"
66 #include "content/public/browser/navigation_controller.h"
67 #include "content/public/browser/navigation_entry.h"
68 #include "content/public/browser/notification_service.h"
69 #include "content/public/browser/page_navigator.h"
70 #include "content/public/browser/render_view_host.h"
71 #include "content/public/browser/render_widget_host_view.h"
72 #include "content/public/browser/user_metrics.h"
73 #include "content/public/browser/web_contents.h"
74 #include "content/public/common/page_state.h"
75 #include "content/public/common/renderer_preferences.h"
76 #include "content/public/common/url_constants.h"
77 #include "content/public/common/url_utils.h"
78 #include "content/public/common/user_agent.h"
79 #include "net/base/escape.h"
80 #include "ui/events/keycodes/keyboard_codes.h"
82 #if defined(OS_WIN)
83 #include "chrome/browser/ui/metro_pin_tab_helper_win.h"
84 #endif
86 #if defined(ENABLE_EXTENSIONS)
87 #include "chrome/browser/extensions/api/commands/command_service.h"
88 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
89 #include "chrome/browser/extensions/tab_helper.h"
90 #include "chrome/browser/web_applications/web_app.h"
91 #include "chrome/common/extensions/extension_metrics.h"
92 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
93 #include "extensions/browser/extension_registry.h"
94 #include "extensions/browser/extension_system.h"
95 #include "extensions/common/extension.h"
96 #include "extensions/common/extension_set.h"
97 #endif
99 #if defined(ENABLE_PRINTING)
100 #include "chrome/browser/printing/print_view_manager_common.h"
101 #if defined(ENABLE_PRINT_PREVIEW)
102 #include "chrome/browser/printing/print_preview_dialog_controller.h"
103 #endif // defined(ENABLE_PRINT_PREVIEW)
104 #endif // defined(ENABLE_PRINTING)
106 #if defined(ENABLE_RLZ)
107 #include "components/rlz/rlz_tracker.h"
108 #endif
110 namespace {
111 const char kOsOverrideForTabletSite[] = "Linux; Android 4.0.3";
114 using base::UserMetricsAction;
115 using bookmarks::BookmarkModel;
116 using content::NavigationController;
117 using content::NavigationEntry;
118 using content::OpenURLParams;
119 using content::Referrer;
120 using content::SSLStatus;
121 using content::WebContents;
123 namespace chrome {
124 namespace {
126 bool CanBookmarkCurrentPageInternal(const Browser* browser,
127 bool check_remove_bookmark_ui) {
128 BookmarkModel* model =
129 BookmarkModelFactory::GetForProfile(browser->profile());
130 return browser_defaults::bookmarks_enabled &&
131 browser->profile()->GetPrefs()->GetBoolean(
132 bookmarks::prefs::kEditBookmarksEnabled) &&
133 model && model->loaded() && browser->is_type_tabbed() &&
134 (!check_remove_bookmark_ui ||
135 !chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
138 #if defined(ENABLE_EXTENSIONS)
139 bool GetBookmarkOverrideCommand(
140 Profile* profile,
141 const extensions::Extension** extension,
142 extensions::Command* command,
143 extensions::CommandService::ExtensionCommandType* command_type) {
144 DCHECK(extension);
145 DCHECK(command);
146 DCHECK(command_type);
148 ui::Accelerator bookmark_page_accelerator =
149 chrome::GetPrimaryChromeAcceleratorForCommandId(IDC_BOOKMARK_PAGE);
150 if (bookmark_page_accelerator.key_code() == ui::VKEY_UNKNOWN)
151 return false;
153 extensions::CommandService* command_service =
154 extensions::CommandService::Get(profile);
155 const extensions::ExtensionSet& extension_set =
156 extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
157 for (extensions::ExtensionSet::const_iterator i = extension_set.begin();
158 i != extension_set.end();
159 ++i) {
160 extensions::Command prospective_command;
161 extensions::CommandService::ExtensionCommandType prospective_command_type;
162 if (command_service->GetSuggestedExtensionCommand(
163 (*i)->id(), bookmark_page_accelerator, &prospective_command,
164 &prospective_command_type)) {
165 *extension = i->get();
166 *command = prospective_command;
167 *command_type = prospective_command_type;
168 return true;
171 return false;
173 #endif
175 // Based on |disposition|, creates a new tab as necessary, and returns the
176 // appropriate tab to navigate. If that tab is the current tab, reverts the
177 // location bar contents, since all browser-UI-triggered navigations should
178 // revert any omnibox edits in the current tab.
179 WebContents* GetTabAndRevertIfNecessary(Browser* browser,
180 WindowOpenDisposition disposition) {
181 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
182 switch (disposition) {
183 case NEW_FOREGROUND_TAB:
184 case NEW_BACKGROUND_TAB: {
185 WebContents* new_tab = current_tab->Clone();
186 browser->tab_strip_model()->AddWebContents(
187 new_tab, -1, ui::PAGE_TRANSITION_LINK,
188 (disposition == NEW_FOREGROUND_TAB) ?
189 TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE);
190 return new_tab;
192 case NEW_WINDOW: {
193 WebContents* new_tab = current_tab->Clone();
194 Browser* new_browser = new Browser(Browser::CreateParams(
195 browser->profile(), browser->host_desktop_type()));
196 new_browser->tab_strip_model()->AddWebContents(
197 new_tab, -1, ui::PAGE_TRANSITION_LINK,
198 TabStripModel::ADD_ACTIVE);
199 new_browser->window()->Show();
200 return new_tab;
202 default:
203 browser->window()->GetLocationBar()->Revert();
204 return current_tab;
208 void ReloadInternal(Browser* browser,
209 WindowOpenDisposition disposition,
210 bool ignore_cache) {
211 // As this is caused by a user action, give the focus to the page.
213 // Also notify RenderViewHostDelegate of the user gesture; this is
214 // normally done in Browser::Navigate, but a reload bypasses Navigate.
215 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
216 new_tab->UserGestureDone();
217 if (!new_tab->FocusLocationBarByDefault())
218 new_tab->Focus();
219 if (ignore_cache)
220 new_tab->GetController().ReloadIgnoringCache(true);
221 else
222 new_tab->GetController().Reload(true);
225 bool IsShowingWebContentsModalDialog(Browser* browser) {
226 WebContents* web_contents =
227 browser->tab_strip_model()->GetActiveWebContents();
228 if (!web_contents)
229 return false;
231 // TODO(gbillock): This is currently called in production by the CanPrint
232 // method, and may be too restrictive if we allow print preview to overlap.
233 // Re-assess how to queue print preview after we know more about popup
234 // management policy.
235 const web_modal::WebContentsModalDialogManager* manager =
236 web_modal::WebContentsModalDialogManager::FromWebContents(web_contents);
237 return manager && manager->IsDialogActive();
240 #if defined(ENABLE_BASIC_PRINTING)
241 bool PrintPreviewShowing(const Browser* browser) {
242 #if defined(ENABLE_PRINT_PREVIEW)
243 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
244 printing::PrintPreviewDialogController* controller =
245 printing::PrintPreviewDialogController::GetInstance();
246 return controller && (controller->GetPrintPreviewForContents(contents) ||
247 controller->is_creating_print_preview_dialog());
248 #else
249 return false;
250 #endif
252 #endif // ENABLE_BASIC_PRINTING
254 } // namespace
256 bool IsCommandEnabled(Browser* browser, int command) {
257 return browser->command_controller()->command_updater()->IsCommandEnabled(
258 command);
261 bool SupportsCommand(Browser* browser, int command) {
262 return browser->command_controller()->command_updater()->SupportsCommand(
263 command);
266 bool ExecuteCommand(Browser* browser, int command) {
267 return browser->command_controller()->command_updater()->ExecuteCommand(
268 command);
271 bool ExecuteCommandWithDisposition(Browser* browser,
272 int command,
273 WindowOpenDisposition disposition) {
274 return browser->command_controller()->command_updater()->
275 ExecuteCommandWithDisposition(command, disposition);
278 void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
279 browser->command_controller()->command_updater()->UpdateCommandEnabled(
280 command, enabled);
283 void AddCommandObserver(Browser* browser,
284 int command,
285 CommandObserver* observer) {
286 browser->command_controller()->command_updater()->AddCommandObserver(
287 command, observer);
290 void RemoveCommandObserver(Browser* browser,
291 int command,
292 CommandObserver* observer) {
293 browser->command_controller()->command_updater()->RemoveCommandObserver(
294 command, observer);
297 int GetContentRestrictions(const Browser* browser) {
298 int content_restrictions = 0;
299 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
300 if (current_tab) {
301 CoreTabHelper* core_tab_helper =
302 CoreTabHelper::FromWebContents(current_tab);
303 content_restrictions = core_tab_helper->content_restrictions();
304 NavigationEntry* last_committed_entry =
305 current_tab->GetController().GetLastCommittedEntry();
306 if (!content::IsSavableURL(
307 last_committed_entry ? last_committed_entry->GetURL() : GURL()) ||
308 current_tab->ShowingInterstitialPage())
309 content_restrictions |= CONTENT_RESTRICTION_SAVE;
310 if (current_tab->ShowingInterstitialPage())
311 content_restrictions |= CONTENT_RESTRICTION_PRINT;
313 return content_restrictions;
316 void NewEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
317 bool incognito = profile->IsOffTheRecord();
318 PrefService* prefs = profile->GetPrefs();
319 if (incognito) {
320 if (IncognitoModePrefs::GetAvailability(prefs) ==
321 IncognitoModePrefs::DISABLED) {
322 incognito = false;
324 } else if (profile->IsGuestSession() ||
325 (browser_defaults::kAlwaysOpenIncognitoWindow &&
326 IncognitoModePrefs::ShouldLaunchIncognito(
327 *base::CommandLine::ForCurrentProcess(), prefs))) {
328 incognito = true;
331 if (incognito) {
332 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
333 OpenEmptyWindow(profile->GetOffTheRecordProfile(), desktop_type);
334 } else {
335 content::RecordAction(UserMetricsAction("NewWindow"));
336 SessionService* session_service =
337 SessionServiceFactory::GetForProfileForSessionRestore(
338 profile->GetOriginalProfile());
339 if (!session_service ||
340 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
341 OpenEmptyWindow(profile->GetOriginalProfile(), desktop_type);
346 Browser* OpenEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
347 Browser* browser = new Browser(
348 Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
349 AddTabAt(browser, GURL(), -1, true);
350 browser->window()->Show();
351 return browser;
354 void OpenWindowWithRestoredTabs(Profile* profile,
355 HostDesktopType host_desktop_type) {
356 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
357 if (service)
358 service->RestoreMostRecentEntry(NULL, host_desktop_type);
361 void OpenURLOffTheRecord(Profile* profile,
362 const GURL& url,
363 chrome::HostDesktopType desktop_type) {
364 ScopedTabbedBrowserDisplayer displayer(profile->GetOffTheRecordProfile(),
365 desktop_type);
366 AddSelectedTabWithURL(displayer.browser(), url,
367 ui::PAGE_TRANSITION_LINK);
370 bool CanGoBack(const Browser* browser) {
371 return browser->tab_strip_model()->GetActiveWebContents()->
372 GetController().CanGoBack();
375 void GoBack(Browser* browser, WindowOpenDisposition disposition) {
376 content::RecordAction(UserMetricsAction("Back"));
378 if (CanGoBack(browser)) {
379 WebContents* current_tab =
380 browser->tab_strip_model()->GetActiveWebContents();
381 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
382 // If we are on an interstitial page and clone the tab, it won't be copied
383 // to the new tab, so we don't need to go back.
384 if ((new_tab == current_tab) || !current_tab->ShowingInterstitialPage())
385 new_tab->GetController().GoBack();
389 bool CanGoForward(const Browser* browser) {
390 return browser->tab_strip_model()->GetActiveWebContents()->
391 GetController().CanGoForward();
394 void GoForward(Browser* browser, WindowOpenDisposition disposition) {
395 content::RecordAction(UserMetricsAction("Forward"));
396 if (CanGoForward(browser)) {
397 GetTabAndRevertIfNecessary(browser, disposition)->
398 GetController().GoForward();
402 bool NavigateToIndexWithDisposition(Browser* browser,
403 int index,
404 WindowOpenDisposition disposition) {
405 NavigationController* controller =
406 &GetTabAndRevertIfNecessary(browser, disposition)->GetController();
407 if (index < 0 || index >= controller->GetEntryCount())
408 return false;
409 controller->GoToIndex(index);
410 return true;
413 void Reload(Browser* browser, WindowOpenDisposition disposition) {
414 content::RecordAction(UserMetricsAction("Reload"));
415 ReloadInternal(browser, disposition, false);
418 void ReloadIgnoringCache(Browser* browser, WindowOpenDisposition disposition) {
419 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
420 ReloadInternal(browser, disposition, true);
423 bool CanReload(const Browser* browser) {
424 return !browser->is_devtools();
427 void Home(Browser* browser, WindowOpenDisposition disposition) {
428 content::RecordAction(UserMetricsAction("Home"));
430 std::string extra_headers;
431 #if defined(ENABLE_RLZ) && !defined(OS_IOS)
432 // If the home page is a Google home page, add the RLZ header to the request.
433 PrefService* pref_service = browser->profile()->GetPrefs();
434 if (pref_service) {
435 if (google_util::IsGoogleHomePageUrl(
436 GURL(pref_service->GetString(prefs::kHomePage)))) {
437 extra_headers = rlz::RLZTracker::GetAccessPointHttpHeader(
438 rlz::RLZTracker::ChromeHomePage());
441 #endif // defined(ENABLE_RLZ) && !defined(OS_IOS)
443 GURL url = browser->profile()->GetHomePage();
445 #if defined(ENABLE_EXTENSIONS)
446 // With bookmark apps enabled, hosted apps should return to their launch page
447 // when the home button is pressed.
448 if (browser->is_app()) {
449 const extensions::Extension* extension =
450 extensions::ExtensionRegistry::Get(browser->profile())
451 ->GetExtensionById(
452 web_app::GetExtensionIdFromApplicationName(browser->app_name()),
453 extensions::ExtensionRegistry::EVERYTHING);
454 if (!extension)
455 return;
457 url = extensions::AppLaunchInfo::GetLaunchWebURL(extension);
459 #endif
461 OpenURLParams params(
462 url, Referrer(), disposition,
463 ui::PageTransitionFromInt(
464 ui::PAGE_TRANSITION_AUTO_BOOKMARK |
465 ui::PAGE_TRANSITION_HOME_PAGE),
466 false);
467 params.extra_headers = extra_headers;
468 browser->OpenURL(params);
471 void OpenCurrentURL(Browser* browser) {
472 content::RecordAction(UserMetricsAction("LoadURL"));
473 LocationBar* location_bar = browser->window()->GetLocationBar();
474 if (!location_bar)
475 return;
477 GURL url(location_bar->GetDestinationURL());
479 ui::PageTransition page_transition = location_bar->GetPageTransition();
480 ui::PageTransition page_transition_without_qualifier(
481 ui::PageTransitionStripQualifier(page_transition));
482 WindowOpenDisposition open_disposition =
483 location_bar->GetWindowOpenDisposition();
484 // A PAGE_TRANSITION_TYPED means the user has typed a URL. We do not want to
485 // open URLs with instant_controller since in some cases it disregards it
486 // and performs a search instead. For example, when using CTRL-Enter, the
487 // location_bar is aware of the URL but instant is not.
488 // Instant should also not handle PAGE_TRANSITION_RELOAD because its knowledge
489 // of the omnibox text may be stale if the user focuses in the omnibox and
490 // presses enter without typing anything.
491 if (page_transition_without_qualifier != ui::PAGE_TRANSITION_TYPED &&
492 page_transition_without_qualifier != ui::PAGE_TRANSITION_RELOAD &&
493 browser->instant_controller() &&
494 browser->instant_controller()->OpenInstant(open_disposition, url))
495 return;
497 NavigateParams params(browser, url, page_transition);
498 params.disposition = open_disposition;
499 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
500 // inherit the opener. In some cases the tabstrip will determine the group
501 // should be inherited, in which case the group is inherited instead of the
502 // opener.
503 params.tabstrip_add_types =
504 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
505 Navigate(&params);
507 #if defined(ENABLE_EXTENSIONS)
508 DCHECK(extensions::ExtensionSystem::Get(
509 browser->profile())->extension_service());
510 const extensions::Extension* extension =
511 extensions::ExtensionRegistry::Get(browser->profile())
512 ->enabled_extensions().GetAppByURL(url);
513 if (extension) {
514 extensions::RecordAppLaunchType(extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
515 extension->GetType());
517 #endif
520 void Stop(Browser* browser) {
521 content::RecordAction(UserMetricsAction("Stop"));
522 browser->tab_strip_model()->GetActiveWebContents()->Stop();
525 void NewWindow(Browser* browser) {
526 NewEmptyWindow(browser->profile()->GetOriginalProfile(),
527 browser->host_desktop_type());
530 void NewIncognitoWindow(Browser* browser) {
531 NewEmptyWindow(browser->profile()->GetOffTheRecordProfile(),
532 browser->host_desktop_type());
535 void CloseWindow(Browser* browser) {
536 content::RecordAction(UserMetricsAction("CloseWindow"));
537 browser->window()->Close();
540 void NewTab(Browser* browser) {
541 content::RecordAction(UserMetricsAction("NewTab"));
542 // TODO(asvitkine): This is invoked programmatically from several places.
543 // Audit the code and change it so that the histogram only gets collected for
544 // user-initiated commands.
545 UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", TabStripModel::NEW_TAB_COMMAND,
546 TabStripModel::NEW_TAB_ENUM_COUNT);
548 if (browser->is_type_tabbed()) {
549 AddTabAt(browser, GURL(), -1, true);
550 browser->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
551 } else {
552 ScopedTabbedBrowserDisplayer displayer(browser->profile(),
553 browser->host_desktop_type());
554 Browser* b = displayer.browser();
555 AddTabAt(b, GURL(), -1, true);
556 b->window()->Show();
557 // The call to AddBlankTabAt above did not set the focus to the tab as its
558 // window was not active, so we have to do it explicitly.
559 // See http://crbug.com/6380.
560 b->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
564 void CloseTab(Browser* browser) {
565 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
566 browser->tab_strip_model()->CloseSelectedTabs();
569 bool CanZoomIn(content::WebContents* contents) {
570 ui_zoom::ZoomController* zoom_controller =
571 ui_zoom::ZoomController::FromWebContents(contents);
572 return zoom_controller->GetZoomPercent() != contents->GetMaximumZoomPercent();
575 bool CanZoomOut(content::WebContents* contents) {
576 ui_zoom::ZoomController* zoom_controller =
577 ui_zoom::ZoomController::FromWebContents(contents);
578 return zoom_controller->GetZoomPercent() !=
579 contents->GetMinimumZoomPercent();
582 bool CanResetZoom(content::WebContents* contents) {
583 ui_zoom::ZoomController* zoom_controller =
584 ui_zoom::ZoomController::FromWebContents(contents);
585 return !zoom_controller->IsAtDefaultZoom() ||
586 !zoom_controller->PageScaleFactorIsOne();
589 TabStripModelDelegate::RestoreTabType GetRestoreTabType(
590 const Browser* browser) {
591 TabRestoreService* service =
592 TabRestoreServiceFactory::GetForProfile(browser->profile());
593 if (!service || service->entries().empty())
594 return TabStripModelDelegate::RESTORE_NONE;
595 if (service->entries().front()->type == TabRestoreService::WINDOW)
596 return TabStripModelDelegate::RESTORE_WINDOW;
597 return TabStripModelDelegate::RESTORE_TAB;
600 void SelectNextTab(Browser* browser) {
601 content::RecordAction(UserMetricsAction("SelectNextTab"));
602 browser->tab_strip_model()->SelectNextTab();
605 void SelectPreviousTab(Browser* browser) {
606 content::RecordAction(UserMetricsAction("SelectPrevTab"));
607 browser->tab_strip_model()->SelectPreviousTab();
610 void MoveTabNext(Browser* browser) {
611 content::RecordAction(UserMetricsAction("MoveTabNext"));
612 browser->tab_strip_model()->MoveTabNext();
615 void MoveTabPrevious(Browser* browser) {
616 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
617 browser->tab_strip_model()->MoveTabPrevious();
620 void SelectNumberedTab(Browser* browser, int index) {
621 if (index < browser->tab_strip_model()->count()) {
622 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
623 browser->tab_strip_model()->ActivateTabAt(index, true);
627 void SelectLastTab(Browser* browser) {
628 content::RecordAction(UserMetricsAction("SelectLastTab"));
629 browser->tab_strip_model()->SelectLastTab();
632 void DuplicateTab(Browser* browser) {
633 content::RecordAction(UserMetricsAction("Duplicate"));
634 DuplicateTabAt(browser, browser->tab_strip_model()->active_index());
637 bool CanDuplicateTab(const Browser* browser) {
638 return CanDuplicateTabAt(browser, browser->tab_strip_model()->active_index());
641 WebContents* DuplicateTabAt(Browser* browser, int index) {
642 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(index);
643 CHECK(contents);
644 WebContents* contents_dupe = contents->Clone();
646 bool pinned = false;
647 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
648 // If this is a tabbed browser, just create a duplicate tab inside the same
649 // window next to the tab being duplicated.
650 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
651 pinned = browser->tab_strip_model()->IsTabPinned(index);
652 int add_types = TabStripModel::ADD_ACTIVE |
653 TabStripModel::ADD_INHERIT_GROUP |
654 (pinned ? TabStripModel::ADD_PINNED : 0);
655 browser->tab_strip_model()->InsertWebContentsAt(
656 index + 1, contents_dupe, add_types);
657 } else {
658 Browser* new_browser = NULL;
659 if (browser->is_app() && !browser->is_type_popup()) {
660 new_browser = new Browser(
661 Browser::CreateParams::CreateForApp(browser->app_name(),
662 browser->is_trusted_source(),
663 gfx::Rect(),
664 browser->profile(),
665 browser->host_desktop_type()));
666 } else {
667 new_browser = new Browser(
668 Browser::CreateParams(browser->type(), browser->profile(),
669 browser->host_desktop_type()));
671 // Preserve the size of the original window. The new window has already
672 // been given an offset by the OS, so we shouldn't copy the old bounds.
673 BrowserWindow* new_window = new_browser->window();
674 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
675 browser->window()->GetRestoredBounds().size()));
677 // We need to show the browser now. Otherwise ContainerWin assumes the
678 // WebContents is invisible and won't size it.
679 new_browser->window()->Show();
681 // The page transition below is only for the purpose of inserting the tab.
682 new_browser->tab_strip_model()->AddWebContents(
683 contents_dupe, -1,
684 ui::PAGE_TRANSITION_LINK,
685 TabStripModel::ADD_ACTIVE);
688 SessionService* session_service =
689 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
690 if (session_service)
691 session_service->TabRestored(contents_dupe, pinned);
692 return contents_dupe;
695 bool CanDuplicateTabAt(const Browser* browser, int index) {
696 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(index);
697 // If an interstitial is showing, do not allow tab duplication, since
698 // the last committed entry is what would get duplicated and is not
699 // what the user expects to duplicate.
700 return contents && !contents->ShowingInterstitialPage() &&
701 contents->GetController().GetLastCommittedEntry();
704 void ConvertPopupToTabbedBrowser(Browser* browser) {
705 content::RecordAction(UserMetricsAction("ShowAsTab"));
706 TabStripModel* tab_strip = browser->tab_strip_model();
707 WebContents* contents =
708 tab_strip->DetachWebContentsAt(tab_strip->active_index());
709 Browser* b = new Browser(Browser::CreateParams(browser->profile(),
710 browser->host_desktop_type()));
711 b->tab_strip_model()->AppendWebContents(contents, true);
712 b->window()->Show();
715 void Exit() {
716 content::RecordAction(UserMetricsAction("Exit"));
717 chrome::AttemptUserExit();
720 void BookmarkCurrentPageIgnoringExtensionOverrides(Browser* browser) {
721 content::RecordAction(UserMetricsAction("Star"));
723 BookmarkModel* model =
724 BookmarkModelFactory::GetForProfile(browser->profile());
725 if (!model || !model->loaded())
726 return; // Ignore requests until bookmarks are loaded.
728 GURL url;
729 base::string16 title;
730 WebContents* web_contents =
731 browser->tab_strip_model()->GetActiveWebContents();
732 GetURLAndTitleToBookmark(web_contents, &url, &title);
733 bool is_bookmarked_by_any = model->IsBookmarked(url);
734 if (!is_bookmarked_by_any &&
735 web_contents->GetBrowserContext()->IsOffTheRecord()) {
736 // If we're incognito the favicon may not have been saved. Save it now
737 // so that bookmarks have an icon for the page.
738 favicon::ContentFaviconDriver::FromWebContents(web_contents)->SaveFavicon();
740 bool was_bookmarked_by_user = bookmarks::IsBookmarkedByUser(model, url);
741 bookmarks::AddIfNotBookmarked(model, url, title);
742 bool is_bookmarked_by_user = bookmarks::IsBookmarkedByUser(model, url);
743 // Make sure the model actually added a bookmark before showing the star. A
744 // bookmark isn't created if the url is invalid.
745 if (browser->window()->IsActive() && is_bookmarked_by_user) {
746 // Only show the bubble if the window is active, otherwise we may get into
747 // weird situations where the bubble is deleted as soon as it is shown.
748 browser->window()->ShowBookmarkBubble(url, was_bookmarked_by_user);
752 void BookmarkCurrentPageAllowingExtensionOverrides(Browser* browser) {
753 DCHECK(!chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
755 #if defined(ENABLE_EXTENSIONS)
756 const extensions::Extension* extension = NULL;
757 extensions::Command command;
758 extensions::CommandService::ExtensionCommandType command_type;
759 if (GetBookmarkOverrideCommand(browser->profile(),
760 &extension,
761 &command,
762 &command_type)) {
763 switch (command_type) {
764 case extensions::CommandService::NAMED:
765 browser->window()->ExecuteExtensionCommand(extension, command);
766 break;
767 case extensions::CommandService::BROWSER_ACTION:
768 case extensions::CommandService::PAGE_ACTION:
769 // BookmarkCurrentPage is called through a user gesture, so it is safe
770 // to grant the active tab permission.
771 extensions::ExtensionActionAPI::Get(browser->profile())->
772 ShowExtensionActionPopup(extension, browser, true);
773 break;
775 return;
777 #endif
778 BookmarkCurrentPageIgnoringExtensionOverrides(browser);
781 bool CanBookmarkCurrentPage(const Browser* browser) {
782 return CanBookmarkCurrentPageInternal(browser, true);
785 void BookmarkAllTabs(Browser* browser) {
786 content::RecordAction(UserMetricsAction("BookmarkAllTabs"));
787 chrome::ShowBookmarkAllTabsDialog(browser);
790 bool CanBookmarkAllTabs(const Browser* browser) {
791 return browser->tab_strip_model()->count() > 1 &&
792 !chrome::ShouldRemoveBookmarkOpenPagesUI(browser->profile()) &&
793 CanBookmarkCurrentPageInternal(browser, false);
796 void Translate(Browser* browser) {
797 if (!browser->window()->IsActive())
798 return;
800 WebContents* web_contents =
801 browser->tab_strip_model()->GetActiveWebContents();
802 ChromeTranslateClient* chrome_translate_client =
803 ChromeTranslateClient::FromWebContents(web_contents);
805 translate::TranslateStep step = translate::TRANSLATE_STEP_BEFORE_TRANSLATE;
806 if (chrome_translate_client) {
807 if (chrome_translate_client->GetLanguageState().translation_pending())
808 step = translate::TRANSLATE_STEP_TRANSLATING;
809 else if (chrome_translate_client->GetLanguageState().IsPageTranslated())
810 step = translate::TRANSLATE_STEP_AFTER_TRANSLATE;
812 browser->window()->ShowTranslateBubble(
813 web_contents, step, translate::TranslateErrors::NONE, true);
816 void ManagePasswordsForPage(Browser* browser) {
817 WebContents* web_contents =
818 browser->tab_strip_model()->GetActiveWebContents();
819 ManagePasswordsUIController* controller =
820 ManagePasswordsUIController::FromWebContents(web_contents);
821 TabDialogs::FromWebContents(web_contents)->ShowManagePasswordsBubble(
822 !controller->IsAutomaticallyOpeningBubble());
825 #if defined(OS_WIN)
826 void TogglePagePinnedToStartScreen(Browser* browser) {
827 MetroPinTabHelper::FromWebContents(
828 browser->tab_strip_model()->GetActiveWebContents())->
829 TogglePinnedToStartScreen();
831 #endif
833 void SavePage(Browser* browser) {
834 content::RecordAction(UserMetricsAction("SavePage"));
835 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
836 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
837 content::RecordAction(UserMetricsAction("PDF.SavePage"));
838 current_tab->OnSavePage();
841 bool CanSavePage(const Browser* browser) {
842 // LocalState can be NULL in tests.
843 if (g_browser_process->local_state() &&
844 !g_browser_process->local_state()->GetBoolean(
845 prefs::kAllowFileSelectionDialogs)) {
846 return false;
848 return !browser->is_devtools() &&
849 !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
852 void ShowFindBar(Browser* browser) {
853 browser->GetFindBarController()->Show();
856 void ShowWebsiteSettings(Browser* browser,
857 content::WebContents* web_contents,
858 const GURL& url,
859 const SSLStatus& ssl) {
860 browser->window()->ShowWebsiteSettings(
861 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
862 web_contents, url, ssl);
865 void Print(Browser* browser) {
866 #if defined(ENABLE_PRINTING)
867 printing::StartPrint(
868 browser->tab_strip_model()->GetActiveWebContents(),
869 browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled),
870 false);
871 #endif // defined(ENABLE_PRINTING)
874 bool CanPrint(Browser* browser) {
875 // Do not print when printing is disabled via pref or policy.
876 // Do not print when a constrained window is showing. It's confusing.
877 // TODO(gbillock): Need to re-assess the call to
878 // IsShowingWebContentsModalDialog after a popup management policy is
879 // refined -- we will probably want to just queue the print request, not
880 // block it.
881 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
882 !(IsShowingWebContentsModalDialog(browser) ||
883 GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
886 #if defined(ENABLE_BASIC_PRINTING)
887 void BasicPrint(Browser* browser) {
888 printing::StartBasicPrint(browser->tab_strip_model()->GetActiveWebContents());
891 bool CanBasicPrint(Browser* browser) {
892 // If printing is not disabled via pref or policy, it is always possible to
893 // advanced print when the print preview is visible. The exception to this
894 // is under Win8 ash, since showing the advanced print dialog will open it
895 // modally on the Desktop and hang the browser.
896 #if defined(OS_WIN)
897 if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH)
898 return false;
899 #endif
901 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
902 (PrintPreviewShowing(browser) || CanPrint(browser));
904 #endif // ENABLE_BASIC_PRINTING
906 void EmailPageLocation(Browser* browser) {
907 content::RecordAction(UserMetricsAction("EmailPageLocation"));
908 WebContents* wc = browser->tab_strip_model()->GetActiveWebContents();
909 DCHECK(wc);
911 std::string title = net::EscapeQueryParamValue(
912 base::UTF16ToUTF8(wc->GetTitle()), false);
913 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
914 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
915 title + "&body=%0A%0A" + page_url;
916 platform_util::OpenExternal(browser->profile(), GURL(mailto));
919 bool CanEmailPageLocation(const Browser* browser) {
920 return browser->toolbar_model()->ShouldDisplayURL() &&
921 browser->tab_strip_model()->GetActiveWebContents()->GetURL().is_valid();
924 void CutCopyPaste(Browser* browser, int command_id) {
925 if (command_id == IDC_CUT)
926 content::RecordAction(UserMetricsAction("Cut"));
927 else if (command_id == IDC_COPY)
928 content::RecordAction(UserMetricsAction("Copy"));
929 else
930 content::RecordAction(UserMetricsAction("Paste"));
931 browser->window()->CutCopyPaste(command_id);
934 void Find(Browser* browser) {
935 content::RecordAction(UserMetricsAction("Find"));
936 FindInPage(browser, false, false);
939 void FindNext(Browser* browser) {
940 content::RecordAction(UserMetricsAction("FindNext"));
941 FindInPage(browser, true, true);
944 void FindPrevious(Browser* browser) {
945 content::RecordAction(UserMetricsAction("FindPrevious"));
946 FindInPage(browser, true, false);
949 void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
950 ShowFindBar(browser);
951 if (find_next) {
952 base::string16 find_text;
953 FindTabHelper* find_helper = FindTabHelper::FromWebContents(
954 browser->tab_strip_model()->GetActiveWebContents());
955 #if defined(OS_MACOSX)
956 // We always want to search for the current contents of the find bar on
957 // OS X. For regular profile it's always the current find pboard. For
958 // Incognito window it's the newest value of the find pboard content and
959 // user-typed text.
960 FindBar* find_bar = browser->GetFindBarController()->find_bar();
961 find_text = find_bar->GetFindText();
962 #endif
963 find_helper->StartFinding(find_text, forward_direction, false);
967 void Zoom(Browser* browser, content::PageZoom zoom) {
968 ui_zoom::PageZoom::Zoom(browser->tab_strip_model()->GetActiveWebContents(),
969 zoom);
972 void FocusToolbar(Browser* browser) {
973 content::RecordAction(UserMetricsAction("FocusToolbar"));
974 browser->window()->FocusToolbar();
977 void FocusLocationBar(Browser* browser) {
978 content::RecordAction(UserMetricsAction("FocusLocation"));
979 browser->window()->SetFocusToLocationBar(true);
982 void FocusSearch(Browser* browser) {
983 // TODO(beng): replace this with FocusLocationBar
984 content::RecordAction(UserMetricsAction("FocusSearch"));
985 browser->window()->GetLocationBar()->FocusSearch();
988 void FocusAppMenu(Browser* browser) {
989 content::RecordAction(UserMetricsAction("FocusAppMenu"));
990 browser->window()->FocusAppMenu();
993 void FocusBookmarksToolbar(Browser* browser) {
994 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
995 browser->window()->FocusBookmarksToolbar();
998 void FocusInfobars(Browser* browser) {
999 content::RecordAction(UserMetricsAction("FocusInfobars"));
1000 browser->window()->FocusInfobars();
1003 void FocusNextPane(Browser* browser) {
1004 content::RecordAction(UserMetricsAction("FocusNextPane"));
1005 browser->window()->RotatePaneFocus(true);
1008 void FocusPreviousPane(Browser* browser) {
1009 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
1010 browser->window()->RotatePaneFocus(false);
1013 void ToggleDevToolsWindow(Browser* browser, DevToolsToggleAction action) {
1014 if (action.type() == DevToolsToggleAction::kShowConsole)
1015 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
1016 else
1017 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
1018 DevToolsWindow::ToggleDevToolsWindow(browser, action);
1021 bool CanOpenTaskManager() {
1022 #if defined(ENABLE_TASK_MANAGER)
1023 return true;
1024 #else
1025 return false;
1026 #endif
1029 void OpenTaskManager(Browser* browser) {
1030 #if defined(ENABLE_TASK_MANAGER)
1031 content::RecordAction(UserMetricsAction("TaskManager"));
1032 chrome::ShowTaskManager(browser);
1033 #else
1034 NOTREACHED();
1035 #endif
1038 void OpenFeedbackDialog(Browser* browser) {
1039 content::RecordAction(UserMetricsAction("Feedback"));
1040 chrome::ShowFeedbackPage(browser, std::string(), std::string());
1043 void ToggleBookmarkBar(Browser* browser) {
1044 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
1045 ToggleBookmarkBarWhenVisible(browser->profile());
1048 void ShowAppMenu(Browser* browser) {
1049 // We record the user metric for this event in WrenchMenu::RunMenu.
1050 browser->window()->ShowAppMenu();
1053 void ShowAvatarMenu(Browser* browser) {
1054 browser->window()->ShowAvatarBubbleFromAvatarButton(
1055 BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT,
1056 signin::ManageAccountsParams());
1059 void ShowFastUserSwitcher(Browser* browser) {
1060 browser->window()->ShowAvatarBubbleFromAvatarButton(
1061 BrowserWindow::AVATAR_BUBBLE_MODE_FAST_USER_SWITCH,
1062 signin::ManageAccountsParams());
1065 void OpenUpdateChromeDialog(Browser* browser) {
1066 if (UpgradeDetector::GetInstance()->is_outdated_install()) {
1067 content::NotificationService::current()->Notify(
1068 chrome::NOTIFICATION_OUTDATED_INSTALL,
1069 content::NotificationService::AllSources(),
1070 content::NotificationService::NoDetails());
1071 } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
1072 content::NotificationService::current()->Notify(
1073 chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU,
1074 content::NotificationService::AllSources(),
1075 content::NotificationService::NoDetails());
1076 } else {
1077 content::RecordAction(UserMetricsAction("UpdateChrome"));
1078 browser->window()->ShowUpdateChromeDialog();
1082 void ToggleSpeechInput(Browser* browser) {
1083 SearchTabHelper* search_tab_helper =
1084 SearchTabHelper::FromWebContents(
1085 browser->tab_strip_model()->GetActiveWebContents());
1086 // |search_tab_helper| can be null in unit tests.
1087 if (search_tab_helper)
1088 search_tab_helper->ToggleVoiceSearch();
1091 void DistillCurrentPage(Browser* browser) {
1092 DistillCurrentPageAndView(browser->tab_strip_model()->GetActiveWebContents());
1095 bool CanRequestTabletSite(WebContents* current_tab) {
1096 return current_tab &&
1097 current_tab->GetController().GetLastCommittedEntry() != NULL;
1100 bool IsRequestingTabletSite(Browser* browser) {
1101 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1102 if (!current_tab)
1103 return false;
1104 content::NavigationEntry* entry =
1105 current_tab->GetController().GetLastCommittedEntry();
1106 if (!entry)
1107 return false;
1108 return entry->GetIsOverridingUserAgent();
1111 void ToggleRequestTabletSite(Browser* browser) {
1112 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1113 if (!current_tab)
1114 return;
1115 NavigationController& controller = current_tab->GetController();
1116 NavigationEntry* entry = controller.GetLastCommittedEntry();
1117 if (!entry)
1118 return;
1119 if (entry->GetIsOverridingUserAgent()) {
1120 entry->SetIsOverridingUserAgent(false);
1121 } else {
1122 entry->SetIsOverridingUserAgent(true);
1123 std::string product = version_info::GetProductNameAndVersionForUserAgent();
1124 current_tab->SetUserAgentOverride(content::BuildUserAgentFromOSAndProduct(
1125 kOsOverrideForTabletSite, product));
1127 controller.ReloadOriginalRequestURL(true);
1130 void ToggleFullscreenMode(Browser* browser) {
1131 DCHECK(browser);
1132 browser->exclusive_access_manager()
1133 ->fullscreen_controller()
1134 ->ToggleBrowserFullscreenMode();
1137 void ClearCache(Browser* browser) {
1138 BrowsingDataRemover* remover =
1139 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
1140 remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
1141 BrowsingDataHelper::UNPROTECTED_WEB);
1142 // BrowsingDataRemover takes care of deleting itself when done.
1145 bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
1146 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
1147 return contents ?
1148 content::DevToolsAgentHost::IsDebuggerAttached(contents) : false;
1151 void ViewSource(Browser* browser, WebContents* contents) {
1152 DCHECK(contents);
1154 // Use the last committed entry, since the pending entry hasn't loaded yet and
1155 // won't be copied into the cloned tab.
1156 NavigationEntry* entry = contents->GetController().GetLastCommittedEntry();
1157 if (!entry)
1158 return;
1160 ViewSource(browser, contents, entry->GetURL(), entry->GetPageState());
1163 void ViewSource(Browser* browser,
1164 WebContents* contents,
1165 const GURL& url,
1166 const content::PageState& page_state) {
1167 content::RecordAction(UserMetricsAction("ViewSource"));
1168 DCHECK(contents);
1170 WebContents* view_source_contents = contents->Clone();
1171 DCHECK(view_source_contents->GetController().CanPruneAllButLastCommitted());
1172 view_source_contents->GetController().PruneAllButLastCommitted();
1173 NavigationEntry* last_committed_entry =
1174 view_source_contents->GetController().GetLastCommittedEntry();
1175 if (!last_committed_entry)
1176 return;
1178 GURL view_source_url =
1179 GURL(content::kViewSourceScheme + std::string(":") + url.spec());
1180 last_committed_entry->SetVirtualURL(view_source_url);
1182 // Do not restore scroller position.
1183 last_committed_entry->SetPageState(page_state.RemoveScrollOffset());
1185 // Do not restore title, derive it from the url.
1186 last_committed_entry->SetTitle(base::string16());
1188 // Now show view-source entry.
1189 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
1190 // If this is a tabbed browser, just create a duplicate tab inside the same
1191 // window next to the tab being duplicated.
1192 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1193 int add_types = TabStripModel::ADD_ACTIVE |
1194 TabStripModel::ADD_INHERIT_GROUP;
1195 browser->tab_strip_model()->InsertWebContentsAt(
1196 index + 1,
1197 view_source_contents,
1198 add_types);
1199 } else {
1200 Browser* b = new Browser(
1201 Browser::CreateParams(Browser::TYPE_TABBED, browser->profile(),
1202 browser->host_desktop_type()));
1204 // Preserve the size of the original window. The new window has already
1205 // been given an offset by the OS, so we shouldn't copy the old bounds.
1206 BrowserWindow* new_window = b->window();
1207 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
1208 browser->window()->GetRestoredBounds().size()));
1210 // We need to show the browser now. Otherwise ContainerWin assumes the
1211 // WebContents is invisible and won't size it.
1212 b->window()->Show();
1214 // The page transition below is only for the purpose of inserting the tab.
1215 b->tab_strip_model()->AddWebContents(view_source_contents, -1,
1216 ui::PAGE_TRANSITION_LINK,
1217 TabStripModel::ADD_ACTIVE);
1220 SessionService* session_service =
1221 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
1222 if (session_service)
1223 session_service->TabRestored(view_source_contents, false);
1226 void ViewSelectedSource(Browser* browser) {
1227 ViewSource(browser, browser->tab_strip_model()->GetActiveWebContents());
1230 bool CanViewSource(const Browser* browser) {
1231 return !browser->is_devtools() &&
1232 browser->tab_strip_model()->GetActiveWebContents()->GetController().
1233 CanViewSource();
1236 #if defined(ENABLE_EXTENSIONS)
1237 void CreateApplicationShortcuts(Browser* browser) {
1238 content::RecordAction(UserMetricsAction("CreateShortcut"));
1239 extensions::TabHelper::FromWebContents(
1240 browser->tab_strip_model()->GetActiveWebContents())->
1241 CreateApplicationShortcuts();
1244 void CreateBookmarkAppFromCurrentWebContents(Browser* browser) {
1245 content::RecordAction(UserMetricsAction("CreateHostedApp"));
1246 extensions::TabHelper::FromWebContents(
1247 browser->tab_strip_model()->GetActiveWebContents())->
1248 CreateHostedAppFromWebContents();
1251 bool CanCreateApplicationShortcuts(const Browser* browser) {
1252 return extensions::TabHelper::FromWebContents(
1253 browser->tab_strip_model()->GetActiveWebContents())->
1254 CanCreateApplicationShortcuts();
1257 bool CanCreateBookmarkApp(const Browser* browser) {
1258 return extensions::TabHelper::FromWebContents(
1259 browser->tab_strip_model()->GetActiveWebContents())
1260 ->CanCreateBookmarkApp();
1263 void ConvertTabToAppWindow(Browser* browser,
1264 content::WebContents* contents) {
1265 const GURL& url = contents->GetController().GetLastCommittedEntry()->GetURL();
1266 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
1268 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1269 if (index >= 0)
1270 browser->tab_strip_model()->DetachWebContentsAt(index);
1272 Browser* app_browser = new Browser(
1273 Browser::CreateParams::CreateForApp(app_name,
1274 true /* trusted_source */,
1275 gfx::Rect(),
1276 browser->profile(),
1277 browser->host_desktop_type()));
1278 app_browser->tab_strip_model()->AppendWebContents(contents, true);
1280 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
1281 contents->GetRenderViewHost()->SyncRendererPrefs();
1282 app_browser->window()->Show();
1284 #endif // defined(ENABLE_EXTENSIONS)
1286 } // namespace chrome