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"
83 #include "chrome/browser/ui/metro_pin_tab_helper_win.h"
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"
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"
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
;
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(
141 const extensions::Extension
** extension
,
142 extensions::Command
* command
,
143 extensions::CommandService::ExtensionCommandType
* command_type
) {
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
)
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();
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
;
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
);
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();
203 browser
->window()->GetLocationBar()->Revert();
208 void ReloadInternal(Browser
* browser
,
209 WindowOpenDisposition disposition
,
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())
220 if (DevToolsWindow
* devtools
=
221 DevToolsWindow::GetInstanceForInspectedWebContents(new_tab
)) {
222 devtools
->ReloadInspectedWebContents(ignore_cache
);
227 new_tab
->GetController().ReloadIgnoringCache(true);
229 new_tab
->GetController().Reload(true);
232 bool IsShowingWebContentsModalDialog(Browser
* browser
) {
233 WebContents
* web_contents
=
234 browser
->tab_strip_model()->GetActiveWebContents();
238 // TODO(gbillock): This is currently called in production by the CanPrint
239 // method, and may be too restrictive if we allow print preview to overlap.
240 // Re-assess how to queue print preview after we know more about popup
241 // management policy.
242 const web_modal::WebContentsModalDialogManager
* manager
=
243 web_modal::WebContentsModalDialogManager::FromWebContents(web_contents
);
244 return manager
&& manager
->IsDialogActive();
247 #if defined(ENABLE_BASIC_PRINTING)
248 bool PrintPreviewShowing(const Browser
* browser
) {
249 #if defined(ENABLE_PRINT_PREVIEW)
250 WebContents
* contents
= browser
->tab_strip_model()->GetActiveWebContents();
251 printing::PrintPreviewDialogController
* controller
=
252 printing::PrintPreviewDialogController::GetInstance();
253 return controller
&& (controller
->GetPrintPreviewForContents(contents
) ||
254 controller
->is_creating_print_preview_dialog());
259 #endif // ENABLE_BASIC_PRINTING
263 bool IsCommandEnabled(Browser
* browser
, int command
) {
264 return browser
->command_controller()->command_updater()->IsCommandEnabled(
268 bool SupportsCommand(Browser
* browser
, int command
) {
269 return browser
->command_controller()->command_updater()->SupportsCommand(
273 bool ExecuteCommand(Browser
* browser
, int command
) {
274 return browser
->command_controller()->command_updater()->ExecuteCommand(
278 bool ExecuteCommandWithDisposition(Browser
* browser
,
280 WindowOpenDisposition disposition
) {
281 return browser
->command_controller()->command_updater()->
282 ExecuteCommandWithDisposition(command
, disposition
);
285 void UpdateCommandEnabled(Browser
* browser
, int command
, bool enabled
) {
286 browser
->command_controller()->command_updater()->UpdateCommandEnabled(
290 void AddCommandObserver(Browser
* browser
,
292 CommandObserver
* observer
) {
293 browser
->command_controller()->command_updater()->AddCommandObserver(
297 void RemoveCommandObserver(Browser
* browser
,
299 CommandObserver
* observer
) {
300 browser
->command_controller()->command_updater()->RemoveCommandObserver(
304 int GetContentRestrictions(const Browser
* browser
) {
305 int content_restrictions
= 0;
306 WebContents
* current_tab
= browser
->tab_strip_model()->GetActiveWebContents();
308 CoreTabHelper
* core_tab_helper
=
309 CoreTabHelper::FromWebContents(current_tab
);
310 content_restrictions
= core_tab_helper
->content_restrictions();
311 NavigationEntry
* last_committed_entry
=
312 current_tab
->GetController().GetLastCommittedEntry();
313 if (!content::IsSavableURL(
314 last_committed_entry
? last_committed_entry
->GetURL() : GURL()) ||
315 current_tab
->ShowingInterstitialPage())
316 content_restrictions
|= CONTENT_RESTRICTION_SAVE
;
317 if (current_tab
->ShowingInterstitialPage())
318 content_restrictions
|= CONTENT_RESTRICTION_PRINT
;
320 return content_restrictions
;
323 void NewEmptyWindow(Profile
* profile
, HostDesktopType desktop_type
) {
324 bool incognito
= profile
->IsOffTheRecord();
325 PrefService
* prefs
= profile
->GetPrefs();
327 if (IncognitoModePrefs::GetAvailability(prefs
) ==
328 IncognitoModePrefs::DISABLED
) {
331 } else if (profile
->IsGuestSession() ||
332 (browser_defaults::kAlwaysOpenIncognitoWindow
&&
333 IncognitoModePrefs::ShouldLaunchIncognito(
334 *base::CommandLine::ForCurrentProcess(), prefs
))) {
339 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
340 OpenEmptyWindow(profile
->GetOffTheRecordProfile(), desktop_type
);
342 content::RecordAction(UserMetricsAction("NewWindow"));
343 SessionService
* session_service
=
344 SessionServiceFactory::GetForProfileForSessionRestore(
345 profile
->GetOriginalProfile());
346 if (!session_service
||
347 !session_service
->RestoreIfNecessary(std::vector
<GURL
>())) {
348 OpenEmptyWindow(profile
->GetOriginalProfile(), desktop_type
);
353 Browser
* OpenEmptyWindow(Profile
* profile
, HostDesktopType desktop_type
) {
354 Browser
* browser
= new Browser(
355 Browser::CreateParams(Browser::TYPE_TABBED
, profile
, desktop_type
));
356 AddTabAt(browser
, GURL(), -1, true);
357 browser
->window()->Show();
361 void OpenWindowWithRestoredTabs(Profile
* profile
,
362 HostDesktopType host_desktop_type
) {
363 TabRestoreService
* service
= TabRestoreServiceFactory::GetForProfile(profile
);
365 service
->RestoreMostRecentEntry(NULL
, host_desktop_type
);
368 void OpenURLOffTheRecord(Profile
* profile
,
370 chrome::HostDesktopType desktop_type
) {
371 ScopedTabbedBrowserDisplayer
displayer(profile
->GetOffTheRecordProfile(),
373 AddSelectedTabWithURL(displayer
.browser(), url
,
374 ui::PAGE_TRANSITION_LINK
);
377 bool CanGoBack(const Browser
* browser
) {
378 return browser
->tab_strip_model()->GetActiveWebContents()->
379 GetController().CanGoBack();
382 void GoBack(Browser
* browser
, WindowOpenDisposition disposition
) {
383 content::RecordAction(UserMetricsAction("Back"));
385 if (CanGoBack(browser
)) {
386 WebContents
* current_tab
=
387 browser
->tab_strip_model()->GetActiveWebContents();
388 WebContents
* new_tab
= GetTabAndRevertIfNecessary(browser
, disposition
);
389 // If we are on an interstitial page and clone the tab, it won't be copied
390 // to the new tab, so we don't need to go back.
391 if ((new_tab
== current_tab
) || !current_tab
->ShowingInterstitialPage())
392 new_tab
->GetController().GoBack();
396 bool CanGoForward(const Browser
* browser
) {
397 return browser
->tab_strip_model()->GetActiveWebContents()->
398 GetController().CanGoForward();
401 void GoForward(Browser
* browser
, WindowOpenDisposition disposition
) {
402 content::RecordAction(UserMetricsAction("Forward"));
403 if (CanGoForward(browser
)) {
404 GetTabAndRevertIfNecessary(browser
, disposition
)->
405 GetController().GoForward();
409 bool NavigateToIndexWithDisposition(Browser
* browser
,
411 WindowOpenDisposition disposition
) {
412 NavigationController
* controller
=
413 &GetTabAndRevertIfNecessary(browser
, disposition
)->GetController();
414 if (index
< 0 || index
>= controller
->GetEntryCount())
416 controller
->GoToIndex(index
);
420 void Reload(Browser
* browser
, WindowOpenDisposition disposition
) {
421 content::RecordAction(UserMetricsAction("Reload"));
422 ReloadInternal(browser
, disposition
, false);
425 void ReloadIgnoringCache(Browser
* browser
, WindowOpenDisposition disposition
) {
426 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
427 ReloadInternal(browser
, disposition
, true);
430 bool CanReload(const Browser
* browser
) {
431 return !browser
->is_devtools();
434 void Home(Browser
* browser
, WindowOpenDisposition disposition
) {
435 content::RecordAction(UserMetricsAction("Home"));
437 std::string extra_headers
;
438 #if defined(ENABLE_RLZ) && !defined(OS_IOS)
439 // If the home page is a Google home page, add the RLZ header to the request.
440 PrefService
* pref_service
= browser
->profile()->GetPrefs();
442 if (google_util::IsGoogleHomePageUrl(
443 GURL(pref_service
->GetString(prefs::kHomePage
)))) {
444 extra_headers
= rlz::RLZTracker::GetAccessPointHttpHeader(
445 rlz::RLZTracker::ChromeHomePage());
448 #endif // defined(ENABLE_RLZ) && !defined(OS_IOS)
450 GURL url
= browser
->profile()->GetHomePage();
452 #if defined(ENABLE_EXTENSIONS)
453 // With bookmark apps enabled, hosted apps should return to their launch page
454 // when the home button is pressed.
455 if (browser
->is_app()) {
456 const extensions::Extension
* extension
=
457 extensions::ExtensionRegistry::Get(browser
->profile())
459 web_app::GetExtensionIdFromApplicationName(browser
->app_name()),
460 extensions::ExtensionRegistry::EVERYTHING
);
464 url
= extensions::AppLaunchInfo::GetLaunchWebURL(extension
);
468 OpenURLParams
params(
469 url
, Referrer(), disposition
,
470 ui::PageTransitionFromInt(
471 ui::PAGE_TRANSITION_AUTO_BOOKMARK
|
472 ui::PAGE_TRANSITION_HOME_PAGE
),
474 params
.extra_headers
= extra_headers
;
475 browser
->OpenURL(params
);
478 void OpenCurrentURL(Browser
* browser
) {
479 content::RecordAction(UserMetricsAction("LoadURL"));
480 LocationBar
* location_bar
= browser
->window()->GetLocationBar();
484 GURL
url(location_bar
->GetDestinationURL());
486 ui::PageTransition page_transition
= location_bar
->GetPageTransition();
487 ui::PageTransition
page_transition_without_qualifier(
488 ui::PageTransitionStripQualifier(page_transition
));
489 WindowOpenDisposition open_disposition
=
490 location_bar
->GetWindowOpenDisposition();
491 // A PAGE_TRANSITION_TYPED means the user has typed a URL. We do not want to
492 // open URLs with instant_controller since in some cases it disregards it
493 // and performs a search instead. For example, when using CTRL-Enter, the
494 // location_bar is aware of the URL but instant is not.
495 // Instant should also not handle PAGE_TRANSITION_RELOAD because its knowledge
496 // of the omnibox text may be stale if the user focuses in the omnibox and
497 // presses enter without typing anything.
498 if (page_transition_without_qualifier
!= ui::PAGE_TRANSITION_TYPED
&&
499 page_transition_without_qualifier
!= ui::PAGE_TRANSITION_RELOAD
&&
500 browser
->instant_controller() &&
501 browser
->instant_controller()->OpenInstant(open_disposition
, url
))
504 NavigateParams
params(browser
, url
, page_transition
);
505 params
.disposition
= open_disposition
;
506 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
507 // inherit the opener. In some cases the tabstrip will determine the group
508 // should be inherited, in which case the group is inherited instead of the
510 params
.tabstrip_add_types
=
511 TabStripModel::ADD_FORCE_INDEX
| TabStripModel::ADD_INHERIT_OPENER
;
514 #if defined(ENABLE_EXTENSIONS)
515 DCHECK(extensions::ExtensionSystem::Get(
516 browser
->profile())->extension_service());
517 const extensions::Extension
* extension
=
518 extensions::ExtensionRegistry::Get(browser
->profile())
519 ->enabled_extensions().GetAppByURL(url
);
521 extensions::RecordAppLaunchType(extension_misc::APP_LAUNCH_OMNIBOX_LOCATION
,
522 extension
->GetType());
527 void Stop(Browser
* browser
) {
528 content::RecordAction(UserMetricsAction("Stop"));
529 browser
->tab_strip_model()->GetActiveWebContents()->Stop();
532 void NewWindow(Browser
* browser
) {
533 NewEmptyWindow(browser
->profile()->GetOriginalProfile(),
534 browser
->host_desktop_type());
537 void NewIncognitoWindow(Browser
* browser
) {
538 NewEmptyWindow(browser
->profile()->GetOffTheRecordProfile(),
539 browser
->host_desktop_type());
542 void CloseWindow(Browser
* browser
) {
543 content::RecordAction(UserMetricsAction("CloseWindow"));
544 browser
->window()->Close();
547 void NewTab(Browser
* browser
) {
548 content::RecordAction(UserMetricsAction("NewTab"));
549 // TODO(asvitkine): This is invoked programmatically from several places.
550 // Audit the code and change it so that the histogram only gets collected for
551 // user-initiated commands.
552 UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", TabStripModel::NEW_TAB_COMMAND
,
553 TabStripModel::NEW_TAB_ENUM_COUNT
);
555 if (browser
->is_type_tabbed()) {
556 AddTabAt(browser
, GURL(), -1, true);
557 browser
->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
559 ScopedTabbedBrowserDisplayer
displayer(browser
->profile(),
560 browser
->host_desktop_type());
561 Browser
* b
= displayer
.browser();
562 AddTabAt(b
, GURL(), -1, true);
564 // The call to AddBlankTabAt above did not set the focus to the tab as its
565 // window was not active, so we have to do it explicitly.
566 // See http://crbug.com/6380.
567 b
->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
571 void CloseTab(Browser
* browser
) {
572 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
573 browser
->tab_strip_model()->CloseSelectedTabs();
576 bool CanZoomIn(content::WebContents
* contents
) {
577 ui_zoom::ZoomController
* zoom_controller
=
578 ui_zoom::ZoomController::FromWebContents(contents
);
579 return zoom_controller
->GetZoomPercent() != contents
->GetMaximumZoomPercent();
582 bool CanZoomOut(content::WebContents
* contents
) {
583 ui_zoom::ZoomController
* zoom_controller
=
584 ui_zoom::ZoomController::FromWebContents(contents
);
585 return zoom_controller
->GetZoomPercent() !=
586 contents
->GetMinimumZoomPercent();
589 bool CanResetZoom(content::WebContents
* contents
) {
590 ui_zoom::ZoomController
* zoom_controller
=
591 ui_zoom::ZoomController::FromWebContents(contents
);
592 return !zoom_controller
->IsAtDefaultZoom() ||
593 !zoom_controller
->PageScaleFactorIsOne();
596 TabStripModelDelegate::RestoreTabType
GetRestoreTabType(
597 const Browser
* browser
) {
598 TabRestoreService
* service
=
599 TabRestoreServiceFactory::GetForProfile(browser
->profile());
600 if (!service
|| service
->entries().empty())
601 return TabStripModelDelegate::RESTORE_NONE
;
602 if (service
->entries().front()->type
== TabRestoreService::WINDOW
)
603 return TabStripModelDelegate::RESTORE_WINDOW
;
604 return TabStripModelDelegate::RESTORE_TAB
;
607 void SelectNextTab(Browser
* browser
) {
608 content::RecordAction(UserMetricsAction("SelectNextTab"));
609 browser
->tab_strip_model()->SelectNextTab();
612 void SelectPreviousTab(Browser
* browser
) {
613 content::RecordAction(UserMetricsAction("SelectPrevTab"));
614 browser
->tab_strip_model()->SelectPreviousTab();
617 void MoveTabNext(Browser
* browser
) {
618 content::RecordAction(UserMetricsAction("MoveTabNext"));
619 browser
->tab_strip_model()->MoveTabNext();
622 void MoveTabPrevious(Browser
* browser
) {
623 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
624 browser
->tab_strip_model()->MoveTabPrevious();
627 void SelectNumberedTab(Browser
* browser
, int index
) {
628 if (index
< browser
->tab_strip_model()->count()) {
629 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
630 browser
->tab_strip_model()->ActivateTabAt(index
, true);
634 void SelectLastTab(Browser
* browser
) {
635 content::RecordAction(UserMetricsAction("SelectLastTab"));
636 browser
->tab_strip_model()->SelectLastTab();
639 void DuplicateTab(Browser
* browser
) {
640 content::RecordAction(UserMetricsAction("Duplicate"));
641 DuplicateTabAt(browser
, browser
->tab_strip_model()->active_index());
644 bool CanDuplicateTab(const Browser
* browser
) {
645 return CanDuplicateTabAt(browser
, browser
->tab_strip_model()->active_index());
648 WebContents
* DuplicateTabAt(Browser
* browser
, int index
) {
649 WebContents
* contents
= browser
->tab_strip_model()->GetWebContentsAt(index
);
651 WebContents
* contents_dupe
= contents
->Clone();
654 if (browser
->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP
)) {
655 // If this is a tabbed browser, just create a duplicate tab inside the same
656 // window next to the tab being duplicated.
657 int index
= browser
->tab_strip_model()->GetIndexOfWebContents(contents
);
658 pinned
= browser
->tab_strip_model()->IsTabPinned(index
);
659 int add_types
= TabStripModel::ADD_ACTIVE
|
660 TabStripModel::ADD_INHERIT_GROUP
|
661 (pinned
? TabStripModel::ADD_PINNED
: 0);
662 browser
->tab_strip_model()->InsertWebContentsAt(
663 index
+ 1, contents_dupe
, add_types
);
665 Browser
* new_browser
= NULL
;
666 if (browser
->is_app() && !browser
->is_type_popup()) {
667 new_browser
= new Browser(
668 Browser::CreateParams::CreateForApp(browser
->app_name(),
669 browser
->is_trusted_source(),
672 browser
->host_desktop_type()));
674 new_browser
= new Browser(
675 Browser::CreateParams(browser
->type(), browser
->profile(),
676 browser
->host_desktop_type()));
678 // Preserve the size of the original window. The new window has already
679 // been given an offset by the OS, so we shouldn't copy the old bounds.
680 BrowserWindow
* new_window
= new_browser
->window();
681 new_window
->SetBounds(gfx::Rect(new_window
->GetRestoredBounds().origin(),
682 browser
->window()->GetRestoredBounds().size()));
684 // We need to show the browser now. Otherwise ContainerWin assumes the
685 // WebContents is invisible and won't size it.
686 new_browser
->window()->Show();
688 // The page transition below is only for the purpose of inserting the tab.
689 new_browser
->tab_strip_model()->AddWebContents(
691 ui::PAGE_TRANSITION_LINK
,
692 TabStripModel::ADD_ACTIVE
);
695 SessionService
* session_service
=
696 SessionServiceFactory::GetForProfileIfExisting(browser
->profile());
698 session_service
->TabRestored(contents_dupe
, pinned
);
699 return contents_dupe
;
702 bool CanDuplicateTabAt(const Browser
* browser
, int index
) {
703 WebContents
* contents
= browser
->tab_strip_model()->GetWebContentsAt(index
);
704 // If an interstitial is showing, do not allow tab duplication, since
705 // the last committed entry is what would get duplicated and is not
706 // what the user expects to duplicate.
707 return contents
&& !contents
->ShowingInterstitialPage() &&
708 contents
->GetController().GetLastCommittedEntry();
711 void ConvertPopupToTabbedBrowser(Browser
* browser
) {
712 content::RecordAction(UserMetricsAction("ShowAsTab"));
713 TabStripModel
* tab_strip
= browser
->tab_strip_model();
714 WebContents
* contents
=
715 tab_strip
->DetachWebContentsAt(tab_strip
->active_index());
716 Browser
* b
= new Browser(Browser::CreateParams(browser
->profile(),
717 browser
->host_desktop_type()));
718 b
->tab_strip_model()->AppendWebContents(contents
, true);
723 content::RecordAction(UserMetricsAction("Exit"));
724 chrome::AttemptUserExit();
727 void BookmarkCurrentPageIgnoringExtensionOverrides(Browser
* browser
) {
728 content::RecordAction(UserMetricsAction("Star"));
730 BookmarkModel
* model
=
731 BookmarkModelFactory::GetForProfile(browser
->profile());
732 if (!model
|| !model
->loaded())
733 return; // Ignore requests until bookmarks are loaded.
736 base::string16 title
;
737 WebContents
* web_contents
=
738 browser
->tab_strip_model()->GetActiveWebContents();
739 GetURLAndTitleToBookmark(web_contents
, &url
, &title
);
740 bool is_bookmarked_by_any
= model
->IsBookmarked(url
);
741 if (!is_bookmarked_by_any
&&
742 web_contents
->GetBrowserContext()->IsOffTheRecord()) {
743 // If we're incognito the favicon may not have been saved. Save it now
744 // so that bookmarks have an icon for the page.
745 favicon::ContentFaviconDriver::FromWebContents(web_contents
)->SaveFavicon();
747 bool was_bookmarked_by_user
= bookmarks::IsBookmarkedByUser(model
, url
);
748 bookmarks::AddIfNotBookmarked(model
, url
, title
);
749 bool is_bookmarked_by_user
= bookmarks::IsBookmarkedByUser(model
, url
);
750 // Make sure the model actually added a bookmark before showing the star. A
751 // bookmark isn't created if the url is invalid.
752 if (browser
->window()->IsActive() && is_bookmarked_by_user
) {
753 // Only show the bubble if the window is active, otherwise we may get into
754 // weird situations where the bubble is deleted as soon as it is shown.
755 browser
->window()->ShowBookmarkBubble(url
, was_bookmarked_by_user
);
759 void BookmarkCurrentPageAllowingExtensionOverrides(Browser
* browser
) {
760 DCHECK(!chrome::ShouldRemoveBookmarkThisPageUI(browser
->profile()));
762 #if defined(ENABLE_EXTENSIONS)
763 const extensions::Extension
* extension
= NULL
;
764 extensions::Command command
;
765 extensions::CommandService::ExtensionCommandType command_type
;
766 if (GetBookmarkOverrideCommand(browser
->profile(),
770 switch (command_type
) {
771 case extensions::CommandService::NAMED
:
772 browser
->window()->ExecuteExtensionCommand(extension
, command
);
774 case extensions::CommandService::BROWSER_ACTION
:
775 case extensions::CommandService::PAGE_ACTION
:
776 // BookmarkCurrentPage is called through a user gesture, so it is safe
777 // to grant the active tab permission.
778 extensions::ExtensionActionAPI::Get(browser
->profile())->
779 ShowExtensionActionPopup(extension
, browser
, true);
785 BookmarkCurrentPageIgnoringExtensionOverrides(browser
);
788 bool CanBookmarkCurrentPage(const Browser
* browser
) {
789 return CanBookmarkCurrentPageInternal(browser
, true);
792 void BookmarkAllTabs(Browser
* browser
) {
793 content::RecordAction(UserMetricsAction("BookmarkAllTabs"));
794 chrome::ShowBookmarkAllTabsDialog(browser
);
797 bool CanBookmarkAllTabs(const Browser
* browser
) {
798 return browser
->tab_strip_model()->count() > 1 &&
799 !chrome::ShouldRemoveBookmarkOpenPagesUI(browser
->profile()) &&
800 CanBookmarkCurrentPageInternal(browser
, false);
803 void Translate(Browser
* browser
) {
804 if (!browser
->window()->IsActive())
807 WebContents
* web_contents
=
808 browser
->tab_strip_model()->GetActiveWebContents();
809 ChromeTranslateClient
* chrome_translate_client
=
810 ChromeTranslateClient::FromWebContents(web_contents
);
812 translate::TranslateStep step
= translate::TRANSLATE_STEP_BEFORE_TRANSLATE
;
813 if (chrome_translate_client
) {
814 if (chrome_translate_client
->GetLanguageState().translation_pending())
815 step
= translate::TRANSLATE_STEP_TRANSLATING
;
816 else if (chrome_translate_client
->GetLanguageState().IsPageTranslated())
817 step
= translate::TRANSLATE_STEP_AFTER_TRANSLATE
;
819 browser
->window()->ShowTranslateBubble(
820 web_contents
, step
, translate::TranslateErrors::NONE
, true);
823 void ManagePasswordsForPage(Browser
* browser
) {
824 WebContents
* web_contents
=
825 browser
->tab_strip_model()->GetActiveWebContents();
826 ManagePasswordsUIController
* controller
=
827 ManagePasswordsUIController::FromWebContents(web_contents
);
828 TabDialogs::FromWebContents(web_contents
)->ShowManagePasswordsBubble(
829 !controller
->IsAutomaticallyOpeningBubble());
833 void TogglePagePinnedToStartScreen(Browser
* browser
) {
834 MetroPinTabHelper::FromWebContents(
835 browser
->tab_strip_model()->GetActiveWebContents())->
836 TogglePinnedToStartScreen();
840 void SavePage(Browser
* browser
) {
841 content::RecordAction(UserMetricsAction("SavePage"));
842 WebContents
* current_tab
= browser
->tab_strip_model()->GetActiveWebContents();
843 if (current_tab
&& current_tab
->GetContentsMimeType() == "application/pdf")
844 content::RecordAction(UserMetricsAction("PDF.SavePage"));
845 current_tab
->OnSavePage();
848 bool CanSavePage(const Browser
* browser
) {
849 // LocalState can be NULL in tests.
850 if (g_browser_process
->local_state() &&
851 !g_browser_process
->local_state()->GetBoolean(
852 prefs::kAllowFileSelectionDialogs
)) {
855 return !browser
->is_devtools() &&
856 !(GetContentRestrictions(browser
) & CONTENT_RESTRICTION_SAVE
);
859 void ShowFindBar(Browser
* browser
) {
860 browser
->GetFindBarController()->Show();
863 void ShowWebsiteSettings(Browser
* browser
,
864 content::WebContents
* web_contents
,
866 const SSLStatus
& ssl
) {
867 browser
->window()->ShowWebsiteSettings(
868 Profile::FromBrowserContext(web_contents
->GetBrowserContext()),
869 web_contents
, url
, ssl
);
872 void Print(Browser
* browser
) {
873 #if defined(ENABLE_PRINTING)
874 printing::StartPrint(
875 browser
->tab_strip_model()->GetActiveWebContents(),
876 browser
->profile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled
),
878 #endif // defined(ENABLE_PRINTING)
881 bool CanPrint(Browser
* browser
) {
882 // Do not print when printing is disabled via pref or policy.
883 // Do not print when a constrained window is showing. It's confusing.
884 // TODO(gbillock): Need to re-assess the call to
885 // IsShowingWebContentsModalDialog after a popup management policy is
886 // refined -- we will probably want to just queue the print request, not
888 return browser
->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled
) &&
889 !(IsShowingWebContentsModalDialog(browser
) ||
890 GetContentRestrictions(browser
) & CONTENT_RESTRICTION_PRINT
);
893 #if defined(ENABLE_BASIC_PRINTING)
894 void BasicPrint(Browser
* browser
) {
895 printing::StartBasicPrint(browser
->tab_strip_model()->GetActiveWebContents());
898 bool CanBasicPrint(Browser
* browser
) {
899 // If printing is not disabled via pref or policy, it is always possible to
900 // advanced print when the print preview is visible. The exception to this
901 // is under Win8 ash, since showing the advanced print dialog will open it
902 // modally on the Desktop and hang the browser.
904 if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH
)
908 return browser
->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled
) &&
909 (PrintPreviewShowing(browser
) || CanPrint(browser
));
911 #endif // ENABLE_BASIC_PRINTING
913 void EmailPageLocation(Browser
* browser
) {
914 content::RecordAction(UserMetricsAction("EmailPageLocation"));
915 WebContents
* wc
= browser
->tab_strip_model()->GetActiveWebContents();
918 std::string title
= net::EscapeQueryParamValue(
919 base::UTF16ToUTF8(wc
->GetTitle()), false);
920 std::string page_url
= net::EscapeQueryParamValue(wc
->GetURL().spec(), false);
921 std::string mailto
= std::string("mailto:?subject=Fwd:%20") +
922 title
+ "&body=%0A%0A" + page_url
;
923 platform_util::OpenExternal(browser
->profile(), GURL(mailto
));
926 bool CanEmailPageLocation(const Browser
* browser
) {
927 return browser
->toolbar_model()->ShouldDisplayURL() &&
928 browser
->tab_strip_model()->GetActiveWebContents()->GetURL().is_valid();
931 void CutCopyPaste(Browser
* browser
, int command_id
) {
932 if (command_id
== IDC_CUT
)
933 content::RecordAction(UserMetricsAction("Cut"));
934 else if (command_id
== IDC_COPY
)
935 content::RecordAction(UserMetricsAction("Copy"));
937 content::RecordAction(UserMetricsAction("Paste"));
938 browser
->window()->CutCopyPaste(command_id
);
941 void Find(Browser
* browser
) {
942 content::RecordAction(UserMetricsAction("Find"));
943 FindInPage(browser
, false, false);
946 void FindNext(Browser
* browser
) {
947 content::RecordAction(UserMetricsAction("FindNext"));
948 FindInPage(browser
, true, true);
951 void FindPrevious(Browser
* browser
) {
952 content::RecordAction(UserMetricsAction("FindPrevious"));
953 FindInPage(browser
, true, false);
956 void FindInPage(Browser
* browser
, bool find_next
, bool forward_direction
) {
957 ShowFindBar(browser
);
959 base::string16 find_text
;
960 FindTabHelper
* find_helper
= FindTabHelper::FromWebContents(
961 browser
->tab_strip_model()->GetActiveWebContents());
962 #if defined(OS_MACOSX)
963 // We always want to search for the current contents of the find bar on
964 // OS X. For regular profile it's always the current find pboard. For
965 // Incognito window it's the newest value of the find pboard content and
967 FindBar
* find_bar
= browser
->GetFindBarController()->find_bar();
968 find_text
= find_bar
->GetFindText();
970 find_helper
->StartFinding(find_text
, forward_direction
, false);
974 void Zoom(Browser
* browser
, content::PageZoom zoom
) {
975 ui_zoom::PageZoom::Zoom(browser
->tab_strip_model()->GetActiveWebContents(),
979 void FocusToolbar(Browser
* browser
) {
980 content::RecordAction(UserMetricsAction("FocusToolbar"));
981 browser
->window()->FocusToolbar();
984 void FocusLocationBar(Browser
* browser
) {
985 content::RecordAction(UserMetricsAction("FocusLocation"));
986 browser
->window()->SetFocusToLocationBar(true);
989 void FocusSearch(Browser
* browser
) {
990 // TODO(beng): replace this with FocusLocationBar
991 content::RecordAction(UserMetricsAction("FocusSearch"));
992 browser
->window()->GetLocationBar()->FocusSearch();
995 void FocusAppMenu(Browser
* browser
) {
996 content::RecordAction(UserMetricsAction("FocusAppMenu"));
997 browser
->window()->FocusAppMenu();
1000 void FocusBookmarksToolbar(Browser
* browser
) {
1001 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
1002 browser
->window()->FocusBookmarksToolbar();
1005 void FocusInfobars(Browser
* browser
) {
1006 content::RecordAction(UserMetricsAction("FocusInfobars"));
1007 browser
->window()->FocusInfobars();
1010 void FocusNextPane(Browser
* browser
) {
1011 content::RecordAction(UserMetricsAction("FocusNextPane"));
1012 browser
->window()->RotatePaneFocus(true);
1015 void FocusPreviousPane(Browser
* browser
) {
1016 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
1017 browser
->window()->RotatePaneFocus(false);
1020 void ToggleDevToolsWindow(Browser
* browser
, DevToolsToggleAction action
) {
1021 if (action
.type() == DevToolsToggleAction::kShowConsole
)
1022 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
1024 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
1025 DevToolsWindow::ToggleDevToolsWindow(browser
, action
);
1028 bool CanOpenTaskManager() {
1029 #if defined(ENABLE_TASK_MANAGER)
1036 void OpenTaskManager(Browser
* browser
) {
1037 #if defined(ENABLE_TASK_MANAGER)
1038 content::RecordAction(UserMetricsAction("TaskManager"));
1039 chrome::ShowTaskManager(browser
);
1045 void OpenFeedbackDialog(Browser
* browser
) {
1046 content::RecordAction(UserMetricsAction("Feedback"));
1047 chrome::ShowFeedbackPage(browser
, std::string(), std::string());
1050 void ToggleBookmarkBar(Browser
* browser
) {
1051 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
1052 ToggleBookmarkBarWhenVisible(browser
->profile());
1055 void ShowAppMenu(Browser
* browser
) {
1056 // We record the user metric for this event in WrenchMenu::RunMenu.
1057 browser
->window()->ShowAppMenu();
1060 void ShowAvatarMenu(Browser
* browser
) {
1061 browser
->window()->ShowAvatarBubbleFromAvatarButton(
1062 BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT
,
1063 signin::ManageAccountsParams());
1066 void ShowFastUserSwitcher(Browser
* browser
) {
1067 browser
->window()->ShowAvatarBubbleFromAvatarButton(
1068 BrowserWindow::AVATAR_BUBBLE_MODE_FAST_USER_SWITCH
,
1069 signin::ManageAccountsParams());
1072 void OpenUpdateChromeDialog(Browser
* browser
) {
1073 if (UpgradeDetector::GetInstance()->is_outdated_install()) {
1074 content::NotificationService::current()->Notify(
1075 chrome::NOTIFICATION_OUTDATED_INSTALL
,
1076 content::NotificationService::AllSources(),
1077 content::NotificationService::NoDetails());
1078 } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
1079 content::NotificationService::current()->Notify(
1080 chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU
,
1081 content::NotificationService::AllSources(),
1082 content::NotificationService::NoDetails());
1084 content::RecordAction(UserMetricsAction("UpdateChrome"));
1085 browser
->window()->ShowUpdateChromeDialog();
1089 void ToggleSpeechInput(Browser
* browser
) {
1090 SearchTabHelper
* search_tab_helper
=
1091 SearchTabHelper::FromWebContents(
1092 browser
->tab_strip_model()->GetActiveWebContents());
1093 // |search_tab_helper| can be null in unit tests.
1094 if (search_tab_helper
)
1095 search_tab_helper
->ToggleVoiceSearch();
1098 void DistillCurrentPage(Browser
* browser
) {
1099 DistillCurrentPageAndView(browser
->tab_strip_model()->GetActiveWebContents());
1102 bool CanRequestTabletSite(WebContents
* current_tab
) {
1103 return current_tab
&&
1104 current_tab
->GetController().GetLastCommittedEntry() != NULL
;
1107 bool IsRequestingTabletSite(Browser
* browser
) {
1108 WebContents
* current_tab
= browser
->tab_strip_model()->GetActiveWebContents();
1111 content::NavigationEntry
* entry
=
1112 current_tab
->GetController().GetLastCommittedEntry();
1115 return entry
->GetIsOverridingUserAgent();
1118 void ToggleRequestTabletSite(Browser
* browser
) {
1119 WebContents
* current_tab
= browser
->tab_strip_model()->GetActiveWebContents();
1122 NavigationController
& controller
= current_tab
->GetController();
1123 NavigationEntry
* entry
= controller
.GetLastCommittedEntry();
1126 if (entry
->GetIsOverridingUserAgent()) {
1127 entry
->SetIsOverridingUserAgent(false);
1129 entry
->SetIsOverridingUserAgent(true);
1130 std::string product
= version_info::GetProductNameAndVersionForUserAgent();
1131 current_tab
->SetUserAgentOverride(content::BuildUserAgentFromOSAndProduct(
1132 kOsOverrideForTabletSite
, product
));
1134 controller
.ReloadOriginalRequestURL(true);
1137 void ToggleFullscreenMode(Browser
* browser
) {
1139 browser
->exclusive_access_manager()
1140 ->fullscreen_controller()
1141 ->ToggleBrowserFullscreenMode();
1144 void ClearCache(Browser
* browser
) {
1145 BrowsingDataRemover
* remover
=
1146 BrowsingDataRemover::CreateForUnboundedRange(browser
->profile());
1147 remover
->Remove(BrowsingDataRemover::REMOVE_CACHE
,
1148 BrowsingDataHelper::UNPROTECTED_WEB
);
1149 // BrowsingDataRemover takes care of deleting itself when done.
1152 bool IsDebuggerAttachedToCurrentTab(Browser
* browser
) {
1153 WebContents
* contents
= browser
->tab_strip_model()->GetActiveWebContents();
1155 content::DevToolsAgentHost::IsDebuggerAttached(contents
) : false;
1158 void ViewSource(Browser
* browser
, WebContents
* contents
) {
1161 // Use the last committed entry, since the pending entry hasn't loaded yet and
1162 // won't be copied into the cloned tab.
1163 NavigationEntry
* entry
= contents
->GetController().GetLastCommittedEntry();
1167 ViewSource(browser
, contents
, entry
->GetURL(), entry
->GetPageState());
1170 void ViewSource(Browser
* browser
,
1171 WebContents
* contents
,
1173 const content::PageState
& page_state
) {
1174 content::RecordAction(UserMetricsAction("ViewSource"));
1177 WebContents
* view_source_contents
= contents
->Clone();
1178 DCHECK(view_source_contents
->GetController().CanPruneAllButLastCommitted());
1179 view_source_contents
->GetController().PruneAllButLastCommitted();
1180 NavigationEntry
* last_committed_entry
=
1181 view_source_contents
->GetController().GetLastCommittedEntry();
1182 if (!last_committed_entry
)
1185 GURL view_source_url
=
1186 GURL(content::kViewSourceScheme
+ std::string(":") + url
.spec());
1187 last_committed_entry
->SetVirtualURL(view_source_url
);
1189 // Do not restore scroller position.
1190 last_committed_entry
->SetPageState(page_state
.RemoveScrollOffset());
1192 // Do not restore title, derive it from the url.
1193 last_committed_entry
->SetTitle(base::string16());
1195 // Now show view-source entry.
1196 if (browser
->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP
)) {
1197 // If this is a tabbed browser, just create a duplicate tab inside the same
1198 // window next to the tab being duplicated.
1199 int index
= browser
->tab_strip_model()->GetIndexOfWebContents(contents
);
1200 int add_types
= TabStripModel::ADD_ACTIVE
|
1201 TabStripModel::ADD_INHERIT_GROUP
;
1202 browser
->tab_strip_model()->InsertWebContentsAt(
1204 view_source_contents
,
1207 Browser
* b
= new Browser(
1208 Browser::CreateParams(Browser::TYPE_TABBED
, browser
->profile(),
1209 browser
->host_desktop_type()));
1211 // Preserve the size of the original window. The new window has already
1212 // been given an offset by the OS, so we shouldn't copy the old bounds.
1213 BrowserWindow
* new_window
= b
->window();
1214 new_window
->SetBounds(gfx::Rect(new_window
->GetRestoredBounds().origin(),
1215 browser
->window()->GetRestoredBounds().size()));
1217 // We need to show the browser now. Otherwise ContainerWin assumes the
1218 // WebContents is invisible and won't size it.
1219 b
->window()->Show();
1221 // The page transition below is only for the purpose of inserting the tab.
1222 b
->tab_strip_model()->AddWebContents(view_source_contents
, -1,
1223 ui::PAGE_TRANSITION_LINK
,
1224 TabStripModel::ADD_ACTIVE
);
1227 SessionService
* session_service
=
1228 SessionServiceFactory::GetForProfileIfExisting(browser
->profile());
1229 if (session_service
)
1230 session_service
->TabRestored(view_source_contents
, false);
1233 void ViewSelectedSource(Browser
* browser
) {
1234 ViewSource(browser
, browser
->tab_strip_model()->GetActiveWebContents());
1237 bool CanViewSource(const Browser
* browser
) {
1238 return !browser
->is_devtools() &&
1239 browser
->tab_strip_model()->GetActiveWebContents()->GetController().
1243 #if defined(ENABLE_EXTENSIONS)
1244 void CreateApplicationShortcuts(Browser
* browser
) {
1245 content::RecordAction(UserMetricsAction("CreateShortcut"));
1246 extensions::TabHelper::FromWebContents(
1247 browser
->tab_strip_model()->GetActiveWebContents())->
1248 CreateApplicationShortcuts();
1251 void CreateBookmarkAppFromCurrentWebContents(Browser
* browser
) {
1252 content::RecordAction(UserMetricsAction("CreateHostedApp"));
1253 extensions::TabHelper::FromWebContents(
1254 browser
->tab_strip_model()->GetActiveWebContents())->
1255 CreateHostedAppFromWebContents();
1258 bool CanCreateApplicationShortcuts(const Browser
* browser
) {
1259 return extensions::TabHelper::FromWebContents(
1260 browser
->tab_strip_model()->GetActiveWebContents())->
1261 CanCreateApplicationShortcuts();
1264 bool CanCreateBookmarkApp(const Browser
* browser
) {
1265 return extensions::TabHelper::FromWebContents(
1266 browser
->tab_strip_model()->GetActiveWebContents())
1267 ->CanCreateBookmarkApp();
1270 void ConvertTabToAppWindow(Browser
* browser
,
1271 content::WebContents
* contents
) {
1272 const GURL
& url
= contents
->GetController().GetLastCommittedEntry()->GetURL();
1273 std::string app_name
= web_app::GenerateApplicationNameFromURL(url
);
1275 int index
= browser
->tab_strip_model()->GetIndexOfWebContents(contents
);
1277 browser
->tab_strip_model()->DetachWebContentsAt(index
);
1279 Browser
* app_browser
= new Browser(
1280 Browser::CreateParams::CreateForApp(app_name
,
1281 true /* trusted_source */,
1284 browser
->host_desktop_type()));
1285 app_browser
->tab_strip_model()->AppendWebContents(contents
, true);
1287 contents
->GetMutableRendererPrefs()->can_accept_load_drops
= false;
1288 contents
->GetRenderViewHost()->SyncRendererPrefs();
1289 app_browser
->window()->Show();
1291 #endif // defined(ENABLE_EXTENSIONS)
1293 } // namespace chrome