Elim cr-checkbox
[chromium-blink-merge.git] / chrome / browser / ui / browser_commands.cc
blobcb8a4dc1a3bbd9776bbd3d171e4b6b0c7c39b657
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_factory.h"
26 #include "chrome/browser/translate/chrome_translate_client.h"
27 #include "chrome/browser/ui/accelerator_utils.h"
28 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
29 #include "chrome/browser/ui/browser.h"
30 #include "chrome/browser/ui/browser_command_controller.h"
31 #include "chrome/browser/ui/browser_dialogs.h"
32 #include "chrome/browser/ui/browser_instant_controller.h"
33 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
34 #include "chrome/browser/ui/browser_tabstrip.h"
35 #include "chrome/browser/ui/browser_window.h"
36 #include "chrome/browser/ui/chrome_pages.h"
37 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
38 #include "chrome/browser/ui/find_bar/find_bar.h"
39 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
40 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
41 #include "chrome/browser/ui/location_bar/location_bar.h"
42 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
43 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
44 #include "chrome/browser/ui/search/search_tab_helper.h"
45 #include "chrome/browser/ui/status_bubble.h"
46 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
47 #include "chrome/browser/ui/tab_dialogs.h"
48 #include "chrome/browser/ui/tabs/tab_strip_model.h"
49 #include "chrome/browser/upgrade_detector.h"
50 #include "chrome/common/chrome_switches.h"
51 #include "chrome/common/content_restriction.h"
52 #include "chrome/common/pref_names.h"
53 #include "components/bookmarks/browser/bookmark_model.h"
54 #include "components/bookmarks/browser/bookmark_utils.h"
55 #include "components/favicon/content/content_favicon_driver.h"
56 #include "components/google/core/browser/google_util.h"
57 #include "components/sessions/core/tab_restore_service.h"
58 #include "components/sessions/core/tab_restore_service_delegate.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::WebContents;
122 namespace chrome {
123 namespace {
125 bool CanBookmarkCurrentPageInternal(const Browser* browser,
126 bool check_remove_bookmark_ui) {
127 BookmarkModel* model =
128 BookmarkModelFactory::GetForProfile(browser->profile());
129 return browser_defaults::bookmarks_enabled &&
130 browser->profile()->GetPrefs()->GetBoolean(
131 bookmarks::prefs::kEditBookmarksEnabled) &&
132 model && model->loaded() && browser->is_type_tabbed() &&
133 (!check_remove_bookmark_ui ||
134 !chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
137 #if defined(ENABLE_EXTENSIONS)
138 bool GetBookmarkOverrideCommand(
139 Profile* profile,
140 const extensions::Extension** extension,
141 extensions::Command* command,
142 extensions::CommandService::ExtensionCommandType* command_type) {
143 DCHECK(extension);
144 DCHECK(command);
145 DCHECK(command_type);
147 ui::Accelerator bookmark_page_accelerator =
148 chrome::GetPrimaryChromeAcceleratorForCommandId(IDC_BOOKMARK_PAGE);
149 if (bookmark_page_accelerator.key_code() == ui::VKEY_UNKNOWN)
150 return false;
152 extensions::CommandService* command_service =
153 extensions::CommandService::Get(profile);
154 const extensions::ExtensionSet& extension_set =
155 extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
156 for (extensions::ExtensionSet::const_iterator i = extension_set.begin();
157 i != extension_set.end();
158 ++i) {
159 extensions::Command prospective_command;
160 extensions::CommandService::ExtensionCommandType prospective_command_type;
161 if (command_service->GetSuggestedExtensionCommand(
162 (*i)->id(), bookmark_page_accelerator, &prospective_command,
163 &prospective_command_type)) {
164 *extension = i->get();
165 *command = prospective_command;
166 *command_type = prospective_command_type;
167 return true;
170 return false;
172 #endif
174 // Based on |disposition|, creates a new tab as necessary, and returns the
175 // appropriate tab to navigate. If that tab is the current tab, reverts the
176 // location bar contents, since all browser-UI-triggered navigations should
177 // revert any omnibox edits in the current tab.
178 WebContents* GetTabAndRevertIfNecessary(Browser* browser,
179 WindowOpenDisposition disposition) {
180 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
181 switch (disposition) {
182 case NEW_FOREGROUND_TAB:
183 case NEW_BACKGROUND_TAB: {
184 WebContents* new_tab = current_tab->Clone();
185 browser->tab_strip_model()->AddWebContents(
186 new_tab, -1, ui::PAGE_TRANSITION_LINK,
187 (disposition == NEW_FOREGROUND_TAB) ?
188 TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE);
189 return new_tab;
191 case NEW_WINDOW: {
192 WebContents* new_tab = current_tab->Clone();
193 Browser* new_browser = new Browser(Browser::CreateParams(
194 browser->profile(), browser->host_desktop_type()));
195 new_browser->tab_strip_model()->AddWebContents(
196 new_tab, -1, ui::PAGE_TRANSITION_LINK,
197 TabStripModel::ADD_ACTIVE);
198 new_browser->window()->Show();
199 return new_tab;
201 default:
202 browser->window()->GetLocationBar()->Revert();
203 return current_tab;
207 void ReloadInternal(Browser* browser,
208 WindowOpenDisposition disposition,
209 bool ignore_cache) {
210 // As this is caused by a user action, give the focus to the page.
212 // Also notify RenderViewHostDelegate of the user gesture; this is
213 // normally done in Browser::Navigate, but a reload bypasses Navigate.
214 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
215 new_tab->UserGestureDone();
216 if (!new_tab->FocusLocationBarByDefault())
217 new_tab->Focus();
219 if (DevToolsWindow* devtools =
220 DevToolsWindow::GetInstanceForInspectedWebContents(new_tab)) {
221 devtools->ReloadInspectedWebContents(ignore_cache);
222 return;
225 if (ignore_cache)
226 new_tab->GetController().ReloadIgnoringCache(true);
227 else
228 new_tab->GetController().Reload(true);
231 bool IsShowingWebContentsModalDialog(Browser* browser) {
232 WebContents* web_contents =
233 browser->tab_strip_model()->GetActiveWebContents();
234 if (!web_contents)
235 return false;
237 // TODO(gbillock): This is currently called in production by the CanPrint
238 // method, and may be too restrictive if we allow print preview to overlap.
239 // Re-assess how to queue print preview after we know more about popup
240 // management policy.
241 const web_modal::WebContentsModalDialogManager* manager =
242 web_modal::WebContentsModalDialogManager::FromWebContents(web_contents);
243 return manager && manager->IsDialogActive();
246 #if defined(ENABLE_BASIC_PRINTING)
247 bool PrintPreviewShowing(const Browser* browser) {
248 #if defined(ENABLE_PRINT_PREVIEW)
249 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
250 printing::PrintPreviewDialogController* controller =
251 printing::PrintPreviewDialogController::GetInstance();
252 return controller && (controller->GetPrintPreviewForContents(contents) ||
253 controller->is_creating_print_preview_dialog());
254 #else
255 return false;
256 #endif
258 #endif // ENABLE_BASIC_PRINTING
260 } // namespace
262 bool IsCommandEnabled(Browser* browser, int command) {
263 return browser->command_controller()->command_updater()->IsCommandEnabled(
264 command);
267 bool SupportsCommand(Browser* browser, int command) {
268 return browser->command_controller()->command_updater()->SupportsCommand(
269 command);
272 bool ExecuteCommand(Browser* browser, int command) {
273 return browser->command_controller()->command_updater()->ExecuteCommand(
274 command);
277 bool ExecuteCommandWithDisposition(Browser* browser,
278 int command,
279 WindowOpenDisposition disposition) {
280 return browser->command_controller()->command_updater()->
281 ExecuteCommandWithDisposition(command, disposition);
284 void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
285 browser->command_controller()->command_updater()->UpdateCommandEnabled(
286 command, enabled);
289 void AddCommandObserver(Browser* browser,
290 int command,
291 CommandObserver* observer) {
292 browser->command_controller()->command_updater()->AddCommandObserver(
293 command, observer);
296 void RemoveCommandObserver(Browser* browser,
297 int command,
298 CommandObserver* observer) {
299 browser->command_controller()->command_updater()->RemoveCommandObserver(
300 command, observer);
303 int GetContentRestrictions(const Browser* browser) {
304 int content_restrictions = 0;
305 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
306 if (current_tab) {
307 CoreTabHelper* core_tab_helper =
308 CoreTabHelper::FromWebContents(current_tab);
309 content_restrictions = core_tab_helper->content_restrictions();
310 NavigationEntry* last_committed_entry =
311 current_tab->GetController().GetLastCommittedEntry();
312 if (!content::IsSavableURL(
313 last_committed_entry ? last_committed_entry->GetURL() : GURL()) ||
314 current_tab->ShowingInterstitialPage())
315 content_restrictions |= CONTENT_RESTRICTION_SAVE;
316 if (current_tab->ShowingInterstitialPage())
317 content_restrictions |= CONTENT_RESTRICTION_PRINT;
319 return content_restrictions;
322 void NewEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
323 bool incognito = profile->IsOffTheRecord();
324 PrefService* prefs = profile->GetPrefs();
325 if (incognito) {
326 if (IncognitoModePrefs::GetAvailability(prefs) ==
327 IncognitoModePrefs::DISABLED) {
328 incognito = false;
330 } else if (profile->IsGuestSession() ||
331 (browser_defaults::kAlwaysOpenIncognitoWindow &&
332 IncognitoModePrefs::ShouldLaunchIncognito(
333 *base::CommandLine::ForCurrentProcess(), prefs))) {
334 incognito = true;
337 if (incognito) {
338 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
339 OpenEmptyWindow(profile->GetOffTheRecordProfile(), desktop_type);
340 } else {
341 content::RecordAction(UserMetricsAction("NewWindow"));
342 SessionService* session_service =
343 SessionServiceFactory::GetForProfileForSessionRestore(
344 profile->GetOriginalProfile());
345 if (!session_service ||
346 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
347 OpenEmptyWindow(profile->GetOriginalProfile(), desktop_type);
352 Browser* OpenEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
353 Browser* browser = new Browser(
354 Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
355 AddTabAt(browser, GURL(), -1, true);
356 browser->window()->Show();
357 return browser;
360 void OpenWindowWithRestoredTabs(Profile* profile,
361 HostDesktopType host_desktop_type) {
362 sessions::TabRestoreService* service =
363 TabRestoreServiceFactory::GetForProfile(profile);
364 if (service)
365 service->RestoreMostRecentEntry(NULL, host_desktop_type);
368 void OpenURLOffTheRecord(Profile* profile,
369 const GURL& url,
370 chrome::HostDesktopType desktop_type) {
371 ScopedTabbedBrowserDisplayer displayer(profile->GetOffTheRecordProfile(),
372 desktop_type);
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,
410 int index,
411 WindowOpenDisposition disposition) {
412 NavigationController* controller =
413 &GetTabAndRevertIfNecessary(browser, disposition)->GetController();
414 if (index < 0 || index >= controller->GetEntryCount())
415 return false;
416 controller->GoToIndex(index);
417 return true;
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();
441 if (pref_service) {
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())
458 ->GetExtensionById(
459 web_app::GetExtensionIdFromApplicationName(browser->app_name()),
460 extensions::ExtensionRegistry::EVERYTHING);
461 if (!extension)
462 return;
464 url = extensions::AppLaunchInfo::GetLaunchWebURL(extension);
466 #endif
468 OpenURLParams params(
469 url, Referrer(), disposition,
470 ui::PageTransitionFromInt(
471 ui::PAGE_TRANSITION_AUTO_BOOKMARK |
472 ui::PAGE_TRANSITION_HOME_PAGE),
473 false);
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();
481 if (!location_bar)
482 return;
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))
502 return;
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
509 // opener.
510 params.tabstrip_add_types =
511 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
512 Navigate(&params);
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);
520 if (extension) {
521 extensions::RecordAppLaunchType(extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
522 extension->GetType());
524 #endif
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();
558 } else {
559 ScopedTabbedBrowserDisplayer displayer(browser->profile(),
560 browser->host_desktop_type());
561 Browser* b = displayer.browser();
562 AddTabAt(b, GURL(), -1, true);
563 b->window()->Show();
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 sessions::TabRestoreService* service =
599 TabRestoreServiceFactory::GetForProfile(browser->profile());
600 if (!service || service->entries().empty())
601 return TabStripModelDelegate::RESTORE_NONE;
602 if (service->entries().front()->type == sessions::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);
650 CHECK(contents);
651 WebContents* contents_dupe = contents->Clone();
653 bool pinned = false;
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);
664 } else {
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(),
670 gfx::Rect(),
671 browser->profile(),
672 browser->host_desktop_type()));
673 } else {
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(
690 contents_dupe, -1,
691 ui::PAGE_TRANSITION_LINK,
692 TabStripModel::ADD_ACTIVE);
695 SessionService* session_service =
696 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
697 if (session_service)
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);
719 b->window()->Show();
722 void Exit() {
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.
735 GURL url;
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(),
767 &extension,
768 &command,
769 &command_type)) {
770 switch (command_type) {
771 case extensions::CommandService::NAMED:
772 browser->window()->ExecuteExtensionCommand(extension, command);
773 break;
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);
780 break;
782 return;
784 #endif
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())
805 return;
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());
832 #if defined(OS_WIN)
833 void TogglePagePinnedToStartScreen(Browser* browser) {
834 MetroPinTabHelper::FromWebContents(
835 browser->tab_strip_model()->GetActiveWebContents())->
836 TogglePinnedToStartScreen();
838 #endif
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)) {
853 return false;
855 return !browser->is_devtools() &&
856 !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
859 void ShowFindBar(Browser* browser) {
860 browser->GetFindBarController()->Show();
863 void ShowWebsiteSettings(
864 Browser* browser,
865 content::WebContents* web_contents,
866 const GURL& url,
867 const SecurityStateModel::SecurityInfo& security_info) {
868 browser->window()->ShowWebsiteSettings(
869 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
870 web_contents, url, security_info);
873 void Print(Browser* browser) {
874 #if defined(ENABLE_PRINTING)
875 printing::StartPrint(
876 browser->tab_strip_model()->GetActiveWebContents(),
877 browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled),
878 false);
879 #endif // defined(ENABLE_PRINTING)
882 bool CanPrint(Browser* browser) {
883 // Do not print when printing is disabled via pref or policy.
884 // Do not print when a constrained window is showing. It's confusing.
885 // TODO(gbillock): Need to re-assess the call to
886 // IsShowingWebContentsModalDialog after a popup management policy is
887 // refined -- we will probably want to just queue the print request, not
888 // block it.
889 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
890 !(IsShowingWebContentsModalDialog(browser) ||
891 GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
894 #if defined(ENABLE_BASIC_PRINTING)
895 void BasicPrint(Browser* browser) {
896 printing::StartBasicPrint(browser->tab_strip_model()->GetActiveWebContents());
899 bool CanBasicPrint(Browser* browser) {
900 // If printing is not disabled via pref or policy, it is always possible to
901 // advanced print when the print preview is visible. The exception to this
902 // is under Win8 ash, since showing the advanced print dialog will open it
903 // modally on the Desktop and hang the browser.
904 #if defined(OS_WIN)
905 if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH)
906 return false;
907 #endif
909 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
910 (PrintPreviewShowing(browser) || CanPrint(browser));
912 #endif // ENABLE_BASIC_PRINTING
914 void EmailPageLocation(Browser* browser) {
915 content::RecordAction(UserMetricsAction("EmailPageLocation"));
916 WebContents* wc = browser->tab_strip_model()->GetActiveWebContents();
917 DCHECK(wc);
919 std::string title = net::EscapeQueryParamValue(
920 base::UTF16ToUTF8(wc->GetTitle()), false);
921 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
922 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
923 title + "&body=%0A%0A" + page_url;
924 platform_util::OpenExternal(browser->profile(), GURL(mailto));
927 bool CanEmailPageLocation(const Browser* browser) {
928 return browser->toolbar_model()->ShouldDisplayURL() &&
929 browser->tab_strip_model()->GetActiveWebContents()->GetURL().is_valid();
932 void CutCopyPaste(Browser* browser, int command_id) {
933 if (command_id == IDC_CUT)
934 content::RecordAction(UserMetricsAction("Cut"));
935 else if (command_id == IDC_COPY)
936 content::RecordAction(UserMetricsAction("Copy"));
937 else
938 content::RecordAction(UserMetricsAction("Paste"));
939 browser->window()->CutCopyPaste(command_id);
942 void Find(Browser* browser) {
943 content::RecordAction(UserMetricsAction("Find"));
944 FindInPage(browser, false, false);
947 void FindNext(Browser* browser) {
948 content::RecordAction(UserMetricsAction("FindNext"));
949 FindInPage(browser, true, true);
952 void FindPrevious(Browser* browser) {
953 content::RecordAction(UserMetricsAction("FindPrevious"));
954 FindInPage(browser, true, false);
957 void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
958 ShowFindBar(browser);
959 if (find_next) {
960 base::string16 find_text;
961 FindTabHelper* find_helper = FindTabHelper::FromWebContents(
962 browser->tab_strip_model()->GetActiveWebContents());
963 #if defined(OS_MACOSX)
964 // We always want to search for the current contents of the find bar on
965 // OS X. For regular profile it's always the current find pboard. For
966 // Incognito window it's the newest value of the find pboard content and
967 // user-typed text.
968 FindBar* find_bar = browser->GetFindBarController()->find_bar();
969 find_text = find_bar->GetFindText();
970 #endif
971 find_helper->StartFinding(find_text, forward_direction, false);
975 void Zoom(Browser* browser, content::PageZoom zoom) {
976 ui_zoom::PageZoom::Zoom(browser->tab_strip_model()->GetActiveWebContents(),
977 zoom);
980 void FocusToolbar(Browser* browser) {
981 content::RecordAction(UserMetricsAction("FocusToolbar"));
982 browser->window()->FocusToolbar();
985 void FocusLocationBar(Browser* browser) {
986 content::RecordAction(UserMetricsAction("FocusLocation"));
987 browser->window()->SetFocusToLocationBar(true);
990 void FocusSearch(Browser* browser) {
991 // TODO(beng): replace this with FocusLocationBar
992 content::RecordAction(UserMetricsAction("FocusSearch"));
993 browser->window()->GetLocationBar()->FocusSearch();
996 void FocusAppMenu(Browser* browser) {
997 content::RecordAction(UserMetricsAction("FocusAppMenu"));
998 browser->window()->FocusAppMenu();
1001 void FocusBookmarksToolbar(Browser* browser) {
1002 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
1003 browser->window()->FocusBookmarksToolbar();
1006 void FocusInfobars(Browser* browser) {
1007 content::RecordAction(UserMetricsAction("FocusInfobars"));
1008 browser->window()->FocusInfobars();
1011 void FocusNextPane(Browser* browser) {
1012 content::RecordAction(UserMetricsAction("FocusNextPane"));
1013 browser->window()->RotatePaneFocus(true);
1016 void FocusPreviousPane(Browser* browser) {
1017 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
1018 browser->window()->RotatePaneFocus(false);
1021 void ToggleDevToolsWindow(Browser* browser, DevToolsToggleAction action) {
1022 if (action.type() == DevToolsToggleAction::kShowConsole)
1023 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
1024 else
1025 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
1026 DevToolsWindow::ToggleDevToolsWindow(browser, action);
1029 bool CanOpenTaskManager() {
1030 #if defined(ENABLE_TASK_MANAGER)
1031 return true;
1032 #else
1033 return false;
1034 #endif
1037 void OpenTaskManager(Browser* browser) {
1038 #if defined(ENABLE_TASK_MANAGER)
1039 content::RecordAction(UserMetricsAction("TaskManager"));
1040 chrome::ShowTaskManager(browser);
1041 #else
1042 NOTREACHED();
1043 #endif
1046 void OpenFeedbackDialog(Browser* browser) {
1047 content::RecordAction(UserMetricsAction("Feedback"));
1048 chrome::ShowFeedbackPage(browser, std::string(), std::string());
1051 void ToggleBookmarkBar(Browser* browser) {
1052 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
1053 ToggleBookmarkBarWhenVisible(browser->profile());
1056 void ShowAppMenu(Browser* browser) {
1057 // We record the user metric for this event in WrenchMenu::RunMenu.
1058 browser->window()->ShowAppMenu();
1061 void ShowAvatarMenu(Browser* browser) {
1062 browser->window()->ShowAvatarBubbleFromAvatarButton(
1063 BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT,
1064 signin::ManageAccountsParams());
1067 void ShowFastUserSwitcher(Browser* browser) {
1068 browser->window()->ShowAvatarBubbleFromAvatarButton(
1069 BrowserWindow::AVATAR_BUBBLE_MODE_FAST_USER_SWITCH,
1070 signin::ManageAccountsParams());
1073 void OpenUpdateChromeDialog(Browser* browser) {
1074 if (UpgradeDetector::GetInstance()->is_outdated_install()) {
1075 content::NotificationService::current()->Notify(
1076 chrome::NOTIFICATION_OUTDATED_INSTALL,
1077 content::NotificationService::AllSources(),
1078 content::NotificationService::NoDetails());
1079 } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
1080 content::NotificationService::current()->Notify(
1081 chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU,
1082 content::NotificationService::AllSources(),
1083 content::NotificationService::NoDetails());
1084 } else {
1085 content::RecordAction(UserMetricsAction("UpdateChrome"));
1086 browser->window()->ShowUpdateChromeDialog();
1090 void ToggleSpeechInput(Browser* browser) {
1091 SearchTabHelper* search_tab_helper =
1092 SearchTabHelper::FromWebContents(
1093 browser->tab_strip_model()->GetActiveWebContents());
1094 // |search_tab_helper| can be null in unit tests.
1095 if (search_tab_helper)
1096 search_tab_helper->ToggleVoiceSearch();
1099 void DistillCurrentPage(Browser* browser) {
1100 DistillCurrentPageAndView(browser->tab_strip_model()->GetActiveWebContents());
1103 bool CanRequestTabletSite(WebContents* current_tab) {
1104 return current_tab &&
1105 current_tab->GetController().GetLastCommittedEntry() != NULL;
1108 bool IsRequestingTabletSite(Browser* browser) {
1109 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1110 if (!current_tab)
1111 return false;
1112 content::NavigationEntry* entry =
1113 current_tab->GetController().GetLastCommittedEntry();
1114 if (!entry)
1115 return false;
1116 return entry->GetIsOverridingUserAgent();
1119 void ToggleRequestTabletSite(Browser* browser) {
1120 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1121 if (!current_tab)
1122 return;
1123 NavigationController& controller = current_tab->GetController();
1124 NavigationEntry* entry = controller.GetLastCommittedEntry();
1125 if (!entry)
1126 return;
1127 if (entry->GetIsOverridingUserAgent()) {
1128 entry->SetIsOverridingUserAgent(false);
1129 } else {
1130 entry->SetIsOverridingUserAgent(true);
1131 std::string product = version_info::GetProductNameAndVersionForUserAgent();
1132 current_tab->SetUserAgentOverride(content::BuildUserAgentFromOSAndProduct(
1133 kOsOverrideForTabletSite, product));
1135 controller.ReloadOriginalRequestURL(true);
1138 void ToggleFullscreenMode(Browser* browser) {
1139 DCHECK(browser);
1140 browser->exclusive_access_manager()
1141 ->fullscreen_controller()
1142 ->ToggleBrowserFullscreenMode();
1145 void ClearCache(Browser* browser) {
1146 BrowsingDataRemover* remover =
1147 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
1148 remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
1149 BrowsingDataHelper::UNPROTECTED_WEB);
1150 // BrowsingDataRemover takes care of deleting itself when done.
1153 bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
1154 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
1155 return contents ?
1156 content::DevToolsAgentHost::IsDebuggerAttached(contents) : false;
1159 void ViewSource(Browser* browser, WebContents* contents) {
1160 DCHECK(contents);
1162 // Use the last committed entry, since the pending entry hasn't loaded yet and
1163 // won't be copied into the cloned tab.
1164 NavigationEntry* entry = contents->GetController().GetLastCommittedEntry();
1165 if (!entry)
1166 return;
1168 ViewSource(browser, contents, entry->GetURL(), entry->GetPageState());
1171 void ViewSource(Browser* browser,
1172 WebContents* contents,
1173 const GURL& url,
1174 const content::PageState& page_state) {
1175 content::RecordAction(UserMetricsAction("ViewSource"));
1176 DCHECK(contents);
1178 WebContents* view_source_contents = contents->Clone();
1179 DCHECK(view_source_contents->GetController().CanPruneAllButLastCommitted());
1180 view_source_contents->GetController().PruneAllButLastCommitted();
1181 NavigationEntry* last_committed_entry =
1182 view_source_contents->GetController().GetLastCommittedEntry();
1183 if (!last_committed_entry)
1184 return;
1186 GURL view_source_url =
1187 GURL(content::kViewSourceScheme + std::string(":") + url.spec());
1188 last_committed_entry->SetVirtualURL(view_source_url);
1190 // Do not restore scroller position.
1191 last_committed_entry->SetPageState(page_state.RemoveScrollOffset());
1193 // Do not restore title, derive it from the url.
1194 last_committed_entry->SetTitle(base::string16());
1196 // Now show view-source entry.
1197 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
1198 // If this is a tabbed browser, just create a duplicate tab inside the same
1199 // window next to the tab being duplicated.
1200 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1201 int add_types = TabStripModel::ADD_ACTIVE |
1202 TabStripModel::ADD_INHERIT_GROUP;
1203 browser->tab_strip_model()->InsertWebContentsAt(
1204 index + 1,
1205 view_source_contents,
1206 add_types);
1207 } else {
1208 Browser* b = new Browser(
1209 Browser::CreateParams(Browser::TYPE_TABBED, browser->profile(),
1210 browser->host_desktop_type()));
1212 // Preserve the size of the original window. The new window has already
1213 // been given an offset by the OS, so we shouldn't copy the old bounds.
1214 BrowserWindow* new_window = b->window();
1215 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
1216 browser->window()->GetRestoredBounds().size()));
1218 // We need to show the browser now. Otherwise ContainerWin assumes the
1219 // WebContents is invisible and won't size it.
1220 b->window()->Show();
1222 // The page transition below is only for the purpose of inserting the tab.
1223 b->tab_strip_model()->AddWebContents(view_source_contents, -1,
1224 ui::PAGE_TRANSITION_LINK,
1225 TabStripModel::ADD_ACTIVE);
1228 SessionService* session_service =
1229 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
1230 if (session_service)
1231 session_service->TabRestored(view_source_contents, false);
1234 void ViewSelectedSource(Browser* browser) {
1235 ViewSource(browser, browser->tab_strip_model()->GetActiveWebContents());
1238 bool CanViewSource(const Browser* browser) {
1239 return !browser->is_devtools() &&
1240 browser->tab_strip_model()->GetActiveWebContents()->GetController().
1241 CanViewSource();
1244 #if defined(ENABLE_EXTENSIONS)
1245 void CreateApplicationShortcuts(Browser* browser) {
1246 content::RecordAction(UserMetricsAction("CreateShortcut"));
1247 extensions::TabHelper::FromWebContents(
1248 browser->tab_strip_model()->GetActiveWebContents())->
1249 CreateApplicationShortcuts();
1252 void CreateBookmarkAppFromCurrentWebContents(Browser* browser) {
1253 content::RecordAction(UserMetricsAction("CreateHostedApp"));
1254 extensions::TabHelper::FromWebContents(
1255 browser->tab_strip_model()->GetActiveWebContents())->
1256 CreateHostedAppFromWebContents();
1259 bool CanCreateApplicationShortcuts(const Browser* browser) {
1260 return extensions::TabHelper::FromWebContents(
1261 browser->tab_strip_model()->GetActiveWebContents())->
1262 CanCreateApplicationShortcuts();
1265 bool CanCreateBookmarkApp(const Browser* browser) {
1266 return extensions::TabHelper::FromWebContents(
1267 browser->tab_strip_model()->GetActiveWebContents())
1268 ->CanCreateBookmarkApp();
1271 void ConvertTabToAppWindow(Browser* browser,
1272 content::WebContents* contents) {
1273 const GURL& url = contents->GetController().GetLastCommittedEntry()->GetURL();
1274 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
1276 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1277 if (index >= 0)
1278 browser->tab_strip_model()->DetachWebContentsAt(index);
1280 Browser* app_browser = new Browser(
1281 Browser::CreateParams::CreateForApp(app_name,
1282 true /* trusted_source */,
1283 gfx::Rect(),
1284 browser->profile(),
1285 browser->host_desktop_type()));
1286 app_browser->tab_strip_model()->AppendWebContents(contents, true);
1288 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
1289 contents->GetRenderViewHost()->SyncRendererPrefs();
1290 app_browser->window()->Show();
1292 #endif // defined(ENABLE_EXTENSIONS)
1294 } // namespace chrome