blob: 8886b03e0ae20b39c133193aee51da1eee2bd7c1 [file] [log] [blame]
[email protected]e41982a72012-11-20 07:16:511// Copyright 2012 The Chromium Authors. All rights reserved.
[email protected]a37d4b02012-06-25 21:56:102// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/browser_commands.h"
6
7#include "base/command_line.h"
8#include "base/metrics/histogram.h"
9#include "base/utf_string_conversions.h"
10#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]4f7490ef2012-07-31 08:49:0311#include "chrome/browser/bookmarks/bookmark_model_factory.h"
[email protected]a37d4b02012-06-25 21:56:1012#include "chrome/browser/bookmarks/bookmark_utils.h"
13#include "chrome/browser/browser_process.h"
[email protected]b0cb5e82012-07-19 19:22:4714#include "chrome/browser/browsing_data/browsing_data_helper.h"
15#include "chrome/browser/browsing_data/browsing_data_remover.h"
[email protected]a37d4b02012-06-25 21:56:1016#include "chrome/browser/chrome_page_zoom.h"
17#include "chrome/browser/debugger/devtools_window.h"
[email protected]5d98294912012-06-27 22:57:4018#include "chrome/browser/download/download_util.h"
[email protected]a37d4b02012-06-25 21:56:1019#include "chrome/browser/extensions/extension_service.h"
[email protected]a6394ae2012-07-16 20:58:4320#include "chrome/browser/extensions/tab_helper.h"
[email protected]a37d4b02012-06-25 21:56:1021#include "chrome/browser/favicon/favicon_tab_helper.h"
[email protected]72ea827d2012-09-28 01:30:5522#include "chrome/browser/google/google_util.h"
[email protected]a37d4b02012-06-25 21:56:1023#include "chrome/browser/lifetime/application_lifetime.h"
24#include "chrome/browser/platform_util.h"
25#include "chrome/browser/prefs/incognito_mode_prefs.h"
26#include "chrome/browser/prefs/pref_service.h"
[email protected]5d98294912012-06-27 22:57:4027#include "chrome/browser/printing/print_preview_tab_controller.h"
[email protected]a37d4b02012-06-25 21:56:1028#include "chrome/browser/printing/print_view_manager.h"
29#include "chrome/browser/profiles/profile.h"
[email protected]72ea827d2012-09-28 01:30:5530#include "chrome/browser/rlz/rlz.h"
[email protected]a37d4b02012-06-25 21:56:1031#include "chrome/browser/sessions/session_service_factory.h"
[email protected]a37d4b02012-06-25 21:56:1032#include "chrome/browser/sessions/tab_restore_service.h"
[email protected]5d98294912012-06-27 22:57:4033#include "chrome/browser/sessions/tab_restore_service_delegate.h"
[email protected]78e2edc2012-07-01 23:32:2834#include "chrome/browser/sessions/tab_restore_service_factory.h"
[email protected]195c99c2012-10-31 06:24:5135#include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
[email protected]345d7d32012-10-03 23:10:1836#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
[email protected]a37d4b02012-06-25 21:56:1037#include "chrome/browser/ui/browser.h"
[email protected]5d98294912012-06-27 22:57:4038#include "chrome/browser/ui/browser_command_controller.h"
[email protected]a37d4b02012-06-25 21:56:1039#include "chrome/browser/ui/browser_finder.h"
[email protected]7acfaf92012-07-11 15:51:5940#include "chrome/browser/ui/browser_instant_controller.h"
[email protected]5d98294912012-06-27 22:57:4041#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
[email protected]52877dbc62012-06-29 22:22:0342#include "chrome/browser/ui/browser_tabstrip.h"
[email protected]a37d4b02012-06-25 21:56:1043#include "chrome/browser/ui/browser_window.h"
[email protected]7a19ea22012-08-02 14:39:3944#include "chrome/browser/ui/chrome_pages.h"
[email protected]5d98294912012-06-27 22:57:4045#include "chrome/browser/ui/constrained_window_tab_helper.h"
[email protected]a37d4b02012-06-25 21:56:1046#include "chrome/browser/ui/find_bar/find_bar_controller.h"
47#include "chrome/browser/ui/find_bar/find_tab_helper.h"
[email protected]3f32b9b2012-07-09 16:59:2848#include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
[email protected]a37d4b02012-06-25 21:56:1049#include "chrome/browser/ui/omnibox/location_bar.h"
[email protected]43aafff2012-06-29 21:20:4950#include "chrome/browser/ui/search/search.h"
51#include "chrome/browser/ui/search/search_model.h"
[email protected]a37d4b02012-06-25 21:56:1052#include "chrome/browser/ui/status_bubble.h"
53#include "chrome/browser/ui/tab_contents/tab_contents.h"
54#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]a37d4b02012-06-25 21:56:1055#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
[email protected]5d98294912012-06-27 22:57:4056#include "chrome/browser/web_applications/web_app.h"
[email protected]a37d4b02012-06-25 21:56:1057#include "chrome/common/chrome_switches.h"
[email protected]a37d4b02012-06-25 21:56:1058#include "chrome/common/pref_names.h"
[email protected]d3446bda2012-07-12 14:24:3959#include "content/public/browser/devtools_agent_host_registry.h"
[email protected]a37d4b02012-06-25 21:56:1060#include "content/public/browser/navigation_controller.h"
61#include "content/public/browser/navigation_entry.h"
62#include "content/public/browser/page_navigator.h"
63#include "content/public/browser/render_view_host.h"
64#include "content/public/browser/user_metrics.h"
65#include "content/public/browser/web_contents.h"
66#include "content/public/browser/web_contents_view.h"
[email protected]6c2d6eb2012-09-01 00:06:3167#include "content/public/browser/web_intents_dispatcher.h"
[email protected]9b7ab882012-09-10 23:46:3668#include "content/public/common/content_client.h"
[email protected]78e2edc2012-07-01 23:32:2869#include "content/public/common/content_restriction.h"
70#include "content/public/common/renderer_preferences.h"
[email protected]2cd4fde2012-06-26 03:10:2671#include "content/public/common/url_constants.h"
[email protected]a37d4b02012-06-25 21:56:1072#include "net/base/escape.h"
[email protected]bb0e79472012-10-23 04:36:3473#include "webkit/glue/glue_serialize.h"
[email protected]6c2d6eb2012-09-01 00:06:3174#include "webkit/glue/web_intent_data.h"
[email protected]9b7ab882012-09-10 23:46:3675#include "webkit/user_agent/user_agent_util.h"
[email protected]a37d4b02012-06-25 21:56:1076
77#if defined(OS_MACOSX)
78#include "ui/base/cocoa/find_pasteboard.h"
79#endif
80
81#if defined(OS_WIN)
82#include "base/win/metro.h"
[email protected]b0bcd9be2012-10-24 22:51:5683#include "chrome/browser/ui/metro_pin_tab_helper_win.h"
[email protected]a37d4b02012-06-25 21:56:1084#endif
85
[email protected]9b7ab882012-09-10 23:46:3686namespace {
87const char kOsOverrideForTabletSite[] = "Linux; Android 4.0.3";
88}
89
[email protected]a37d4b02012-06-25 21:56:1090using content::NavigationController;
91using content::NavigationEntry;
92using content::OpenURLParams;
93using content::Referrer;
94using content::SSLStatus;
95using content::UserMetricsAction;
96using content::WebContents;
97
[email protected]f250fd52012-08-27 20:09:3798// TODO(avi): Kill this when TabContents goes away.
99class BrowserCommandsTabContentsCreator {
100 public:
[email protected]f250fd52012-08-27 20:09:37101 static TabContents* CloneTabContents(TabContents* contents) {
102 return TabContents::Factory::CloneTabContents(contents);
103 }
104};
105
[email protected]a37d4b02012-06-25 21:56:10106namespace chrome {
107namespace {
108
[email protected]195c99c2012-10-31 06:24:51109void BookmarkCurrentPageInternal(Browser* browser, bool from_star) {
110 content::RecordAction(UserMetricsAction("Star"));
111
112 BookmarkModel* model =
113 BookmarkModelFactory::GetForProfile(browser->profile());
114 if (!model || !model->IsLoaded())
115 return; // Ignore requests until bookmarks are loaded.
116
117 GURL url;
118 string16 title;
119 WebContents* web_contents = GetActiveWebContents(browser);
120 GetURLAndTitleToBookmark(web_contents, &url, &title);
121 bool was_bookmarked = model->IsBookmarked(url);
122 if (!was_bookmarked && web_contents->GetBrowserContext()->IsOffTheRecord()) {
123 // If we're incognito the favicon may not have been saved. Save it now
124 // so that bookmarks have an icon for the page.
125 FaviconTabHelper::FromWebContents(web_contents)->SaveFavicon();
126 }
127 bookmark_utils::AddIfNotBookmarked(model, url, title);
128 if (from_star && !was_bookmarked)
129 BookmarkPromptController::AddedBookmark(browser, url);
130 // Make sure the model actually added a bookmark before showing the star. A
131 // bookmark isn't created if the url is invalid.
132 if (browser->window()->IsActive() && model->IsBookmarked(url)) {
133 // Only show the bubble if the window is active, otherwise we may get into
134 // weird situations where the bubble is deleted as soon as it is shown.
135 browser->window()->ShowBookmarkBubble(url, was_bookmarked);
136 }
137}
138
[email protected]a37d4b02012-06-25 21:56:10139WebContents* GetOrCloneTabForDisposition(Browser* browser,
140 WindowOpenDisposition disposition) {
[email protected]59253a652012-11-20 00:17:26141 TabContents* current_tab = browser->tab_strip_model()->GetActiveTabContents();
[email protected]a37d4b02012-06-25 21:56:10142 switch (disposition) {
143 case NEW_FOREGROUND_TAB:
144 case NEW_BACKGROUND_TAB: {
[email protected]f250fd52012-08-27 20:09:37145 current_tab =
146 BrowserCommandsTabContentsCreator::CloneTabContents(current_tab);
[email protected]a37d4b02012-06-25 21:56:10147 browser->tab_strip_model()->AddTabContents(
148 current_tab, -1, content::PAGE_TRANSITION_LINK,
149 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
150 TabStripModel::ADD_NONE);
151 break;
152 }
153 case NEW_WINDOW: {
[email protected]f250fd52012-08-27 20:09:37154 current_tab =
155 BrowserCommandsTabContentsCreator::CloneTabContents(current_tab);
[email protected]a4fe67012012-07-25 20:14:29156 Browser* b = new Browser(Browser::CreateParams(browser->profile()));
[email protected]a37d4b02012-06-25 21:56:10157 b->tab_strip_model()->AddTabContents(
158 current_tab, -1, content::PAGE_TRANSITION_LINK,
159 TabStripModel::ADD_ACTIVE);
160 b->window()->Show();
161 break;
162 }
163 default:
164 break;
165 }
166 return current_tab->web_contents();
167}
168
169void ReloadInternal(Browser* browser,
170 WindowOpenDisposition disposition,
171 bool ignore_cache) {
[email protected]a37d4b02012-06-25 21:56:10172 // As this is caused by a user action, give the focus to the page.
173 //
174 // Also notify RenderViewHostDelegate of the user gesture; this is
175 // normally done in Browser::Navigate, but a reload bypasses Navigate.
176 WebContents* web_contents = GetOrCloneTabForDisposition(browser, disposition);
177 web_contents->UserGestureDone();
178 if (!web_contents->FocusLocationBarByDefault())
179 web_contents->Focus();
180 if (ignore_cache)
181 web_contents->GetController().ReloadIgnoringCache(true);
182 else
183 web_contents->GetController().Reload(true);
184}
185
[email protected]5d98294912012-06-27 22:57:40186bool HasConstrainedWindow(const Browser* browser) {
[email protected]c6464ad2012-10-03 00:27:28187 WebContents* web_contents = GetActiveWebContents(browser);
188 if (!web_contents)
189 return false;
190
191 ConstrainedWindowTabHelper* constrained_window_tab_helper =
192 ConstrainedWindowTabHelper::FromWebContents(web_contents);
193 return constrained_window_tab_helper->constrained_window_count() > 0;
[email protected]5d98294912012-06-27 22:57:40194}
195
196bool PrintPreviewShowing(const Browser* browser) {
[email protected]59253a652012-11-20 00:17:26197 TabContents* contents = browser->tab_strip_model()->GetActiveTabContents();
[email protected]5d98294912012-06-27 22:57:40198 printing::PrintPreviewTabController* controller =
199 printing::PrintPreviewTabController::GetInstance();
200 return controller && (controller->GetPrintPreviewForTab(contents) ||
201 controller->is_creating_print_preview_tab());
202}
203
[email protected]db9747252012-07-02 19:28:00204bool IsNTPModeForInstantExtendedAPI(const Browser* browser) {
205 return browser->search_model() &&
[email protected]855370052012-07-10 19:30:32206 search::IsInstantExtendedAPIEnabled(browser->profile()) &&
207 browser->search_model()->mode().is_ntp();
[email protected]db9747252012-07-02 19:28:00208}
209
[email protected]a37d4b02012-06-25 21:56:10210} // namespace
211
[email protected]5d98294912012-06-27 22:57:40212bool IsCommandEnabled(Browser* browser, int command) {
213 return browser->command_controller()->command_updater()->IsCommandEnabled(
214 command);
215}
216
217bool SupportsCommand(Browser* browser, int command) {
218 return browser->command_controller()->command_updater()->SupportsCommand(
219 command);
220}
221
222bool ExecuteCommand(Browser* browser, int command) {
223 return browser->command_controller()->command_updater()->ExecuteCommand(
224 command);
225}
226
227bool ExecuteCommandWithDisposition(Browser* browser,
228 int command,
229 WindowOpenDisposition disposition) {
230 return browser->command_controller()->command_updater()->
231 ExecuteCommandWithDisposition(command, disposition);
232}
233
234void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
235 browser->command_controller()->command_updater()->UpdateCommandEnabled(
236 command, enabled);
237}
238
239void AddCommandObserver(Browser* browser,
240 int command,
241 CommandObserver* observer) {
242 browser->command_controller()->command_updater()->AddCommandObserver(
243 command, observer);
244}
245
246void RemoveCommandObserver(Browser* browser,
247 int command,
248 CommandObserver* observer) {
249 browser->command_controller()->command_updater()->RemoveCommandObserver(
250 command, observer);
251}
252
253int GetContentRestrictions(const Browser* browser) {
254 int content_restrictions = 0;
[email protected]52877dbc62012-06-29 22:22:03255 WebContents* current_tab = GetActiveWebContents(browser);
[email protected]5d98294912012-06-27 22:57:40256 if (current_tab) {
257 content_restrictions = current_tab->GetContentRestrictions();
258 NavigationEntry* active_entry =
259 current_tab->GetController().GetActiveEntry();
260 // See comment in UpdateCommandsForTabState about why we call url().
261 if (!download_util::IsSavableURL(
262 active_entry ? active_entry->GetURL() : GURL()) ||
263 current_tab->ShowingInterstitialPage())
264 content_restrictions |= content::CONTENT_RESTRICTION_SAVE;
265 if (current_tab->ShowingInterstitialPage())
266 content_restrictions |= content::CONTENT_RESTRICTION_PRINT;
267 }
268 return content_restrictions;
269}
270
[email protected]5fdb45b2012-10-23 20:26:28271void NewEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
[email protected]a37d4b02012-06-25 21:56:10272 bool incognito = profile->IsOffTheRecord();
273 PrefService* prefs = profile->GetPrefs();
274 if (incognito) {
275 if (IncognitoModePrefs::GetAvailability(prefs) ==
276 IncognitoModePrefs::DISABLED) {
277 incognito = false;
278 }
279 } else {
280 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
281 IncognitoModePrefs::ShouldLaunchIncognito(
282 *CommandLine::ForCurrentProcess(), prefs)) {
283 incognito = true;
284 }
285 }
286
287 if (incognito) {
288 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
[email protected]5fdb45b2012-10-23 20:26:28289 OpenEmptyWindow(profile->GetOffTheRecordProfile(), desktop_type);
[email protected]a37d4b02012-06-25 21:56:10290 } else {
291 content::RecordAction(UserMetricsAction("NewWindow"));
292 SessionService* session_service =
293 SessionServiceFactory::GetForProfile(profile->GetOriginalProfile());
294 if (!session_service ||
295 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
[email protected]5fdb45b2012-10-23 20:26:28296 OpenEmptyWindow(profile->GetOriginalProfile(), desktop_type);
[email protected]a37d4b02012-06-25 21:56:10297 }
298 }
299}
300
[email protected]5fdb45b2012-10-23 20:26:28301void NewEmptyWindow(Profile* profile) {
302 NewEmptyWindow(profile, HOST_DESKTOP_TYPE_NATIVE);
303}
304
305Browser* OpenEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
[email protected]d8f10042012-11-14 01:10:46306 // TODO(scottmg): http://crbug.com/128578
307 // This is necessary because WebContentsViewAura doesn't have enough context
308 // to get the right StackingClient (and therefore parent window) otherwise.
309 ScopedForceDesktopType force_desktop_type(desktop_type);
[email protected]5fdb45b2012-10-23 20:26:28310 Browser* browser = new Browser(
311 Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
[email protected]686221c2012-11-08 07:30:10312 AddBlankTabAt(browser, -1, true);
[email protected]a37d4b02012-06-25 21:56:10313 browser->window()->Show();
314 return browser;
315}
316
[email protected]5fdb45b2012-10-23 20:26:28317Browser* OpenEmptyWindow(Profile* profile) {
318 return OpenEmptyWindow(profile, HOST_DESKTOP_TYPE_NATIVE);
319}
320
[email protected]a37d4b02012-06-25 21:56:10321void OpenWindowWithRestoredTabs(Profile* profile) {
322 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
323 if (service)
324 service->RestoreMostRecentEntry(NULL);
325}
326
[email protected]3b14b7f22012-10-04 01:29:09327void OpenURLOffTheRecord(Profile* profile,
328 const GURL& url,
329 chrome::HostDesktopType desktop_type) {
[email protected]a37d4b02012-06-25 21:56:10330 Browser* browser = browser::FindOrCreateTabbedBrowser(
[email protected]3b14b7f22012-10-04 01:29:09331 profile->GetOffTheRecordProfile(), desktop_type);
[email protected]52877dbc62012-06-29 22:22:03332 AddSelectedTabWithURL(browser, url, content::PAGE_TRANSITION_LINK);
[email protected]a37d4b02012-06-25 21:56:10333 browser->window()->Show();
334}
335
[email protected]5d98294912012-06-27 22:57:40336bool CanGoBack(const Browser* browser) {
[email protected]52877dbc62012-06-29 22:22:03337 return GetActiveWebContents(browser)->GetController().CanGoBack();
[email protected]a37d4b02012-06-25 21:56:10338}
339
340void GoBack(Browser* browser, WindowOpenDisposition disposition) {
341 content::RecordAction(UserMetricsAction("Back"));
342
[email protected]59253a652012-11-20 00:17:26343 TabContents* current_tab = browser->tab_strip_model()->GetActiveTabContents();
[email protected]a37d4b02012-06-25 21:56:10344 if (CanGoBack(browser)) {
345 WebContents* new_tab = GetOrCloneTabForDisposition(browser, disposition);
346 // If we are on an interstitial page and clone the tab, it won't be copied
347 // to the new tab, so we don't need to go back.
348 if (current_tab->web_contents()->ShowingInterstitialPage() &&
349 (new_tab != current_tab->web_contents()))
350 return;
351 new_tab->GetController().GoBack();
352 }
353}
354
[email protected]5d98294912012-06-27 22:57:40355bool CanGoForward(const Browser* browser) {
[email protected]52877dbc62012-06-29 22:22:03356 return GetActiveWebContents(browser)->GetController().CanGoForward();
[email protected]a37d4b02012-06-25 21:56:10357}
358
359void GoForward(Browser* browser, WindowOpenDisposition disposition) {
360 content::RecordAction(UserMetricsAction("Forward"));
361 if (CanGoForward(browser)) {
362 GetOrCloneTabForDisposition(browser, disposition)->
363 GetController().GoForward();
364 }
365}
366
367bool NavigateToIndexWithDisposition(Browser* browser,
368 int index,
369 WindowOpenDisposition disp) {
370 NavigationController& controller =
371 GetOrCloneTabForDisposition(browser, disp)->GetController();
372 if (index < 0 || index >= controller.GetEntryCount())
373 return false;
374 controller.GoToIndex(index);
375 return true;
376}
377
378void Reload(Browser* browser, WindowOpenDisposition disposition) {
379 content::RecordAction(UserMetricsAction("Reload"));
380 ReloadInternal(browser, disposition, false);
381}
382
383void ReloadIgnoringCache(Browser* browser, WindowOpenDisposition disposition) {
384 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
385 ReloadInternal(browser, disposition, true);
386}
387
[email protected]5d98294912012-06-27 22:57:40388bool CanReload(const Browser* browser) {
[email protected]db9747252012-07-02 19:28:00389 return !browser->is_devtools() && !IsNTPModeForInstantExtendedAPI(browser);
[email protected]5d98294912012-06-27 22:57:40390}
391
[email protected]a37d4b02012-06-25 21:56:10392void Home(Browser* browser, WindowOpenDisposition disposition) {
393 content::RecordAction(UserMetricsAction("Home"));
[email protected]72ea827d2012-09-28 01:30:55394
395 std::string extra_headers;
396#if defined(ENABLE_RLZ)
397 // If the home page is a Google home page, add the RLZ header to the request.
398 PrefService* pref_service = browser->profile()->GetPrefs();
399 if (pref_service) {
400 std::string home_page = pref_service->GetString(prefs::kHomePage);
401 if (google_util::IsGoogleHomePageUrl(home_page)) {
402 extra_headers = RLZTracker::GetAccessPointHttpHeader(
[email protected]7e6f4ed5c2012-10-31 21:10:34403 RLZTracker::CHROME_HOME_PAGE);
[email protected]72ea827d2012-09-28 01:30:55404 }
405 }
406#endif
407
408 OpenURLParams params(
[email protected]a37d4b02012-06-25 21:56:10409 browser->profile()->GetHomePage(), Referrer(), disposition,
410 content::PageTransitionFromInt(
411 content::PAGE_TRANSITION_AUTO_BOOKMARK |
412 content::PAGE_TRANSITION_HOME_PAGE),
[email protected]72ea827d2012-09-28 01:30:55413 false);
414 params.extra_headers = extra_headers;
415 browser->OpenURL(params);
[email protected]a37d4b02012-06-25 21:56:10416}
417
418void OpenCurrentURL(Browser* browser) {
419 content::RecordAction(UserMetricsAction("LoadURL"));
420 LocationBar* location_bar = browser->window()->GetLocationBar();
421 if (!location_bar)
422 return;
423
424 WindowOpenDisposition open_disposition =
425 location_bar->GetWindowOpenDisposition();
[email protected]e41982a72012-11-20 07:16:51426 if (browser->instant_controller() &&
427 browser->instant_controller()->OpenInstant(open_disposition))
[email protected]a37d4b02012-06-25 21:56:10428 return;
429
430 GURL url(location_bar->GetInputString());
431
[email protected]855370052012-07-10 19:30:32432 NavigateParams params(browser, url, location_bar->GetPageTransition());
[email protected]a37d4b02012-06-25 21:56:10433 params.disposition = open_disposition;
434 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
435 // inherit the opener. In some cases the tabstrip will determine the group
436 // should be inherited, in which case the group is inherited instead of the
437 // opener.
438 params.tabstrip_add_types =
439 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
[email protected]855370052012-07-10 19:30:32440 Navigate(&params);
[email protected]a37d4b02012-06-25 21:56:10441
442 DCHECK(browser->profile()->GetExtensionService());
443 if (browser->profile()->GetExtensionService()->IsInstalledApp(url)) {
444 AppLauncherHandler::RecordAppLaunchType(
445 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION);
446 }
447}
448
449void Stop(Browser* browser) {
450 content::RecordAction(UserMetricsAction("Stop"));
[email protected]52877dbc62012-06-29 22:22:03451 GetActiveWebContents(browser)->Stop();
[email protected]a37d4b02012-06-25 21:56:10452}
453
454#if !defined(OS_WIN)
455void NewWindow(Browser* browser) {
456 NewEmptyWindow(browser->profile()->GetOriginalProfile());
457}
458
459void NewIncognitoWindow(Browser* browser) {
460 NewEmptyWindow(browser->profile()->GetOffTheRecordProfile());
461}
462#endif // OS_WIN
463
464void CloseWindow(Browser* browser) {
465 content::RecordAction(UserMetricsAction("CloseWindow"));
466 browser->window()->Close();
467}
468
469void NewTab(Browser* browser) {
470 content::RecordAction(UserMetricsAction("NewTab"));
471 // TODO(asvitkine): This is invoked programmatically from several places.
472 // Audit the code and change it so that the histogram only gets collected for
473 // user-initiated commands.
474 UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", TabStripModel::NEW_TAB_COMMAND,
475 TabStripModel::NEW_TAB_ENUM_COUNT);
476
477 if (browser->is_type_tabbed()) {
[email protected]686221c2012-11-08 07:30:10478 AddBlankTabAt(browser, -1, true);
[email protected]52877dbc62012-06-29 22:22:03479 GetActiveWebContents(browser)->GetView()->RestoreFocus();
[email protected]a37d4b02012-06-25 21:56:10480 } else {
[email protected]3b14b7f22012-10-04 01:29:09481 Browser* b =
482 browser::FindOrCreateTabbedBrowser(browser->profile(),
483 browser->host_desktop_type());
[email protected]686221c2012-11-08 07:30:10484 AddBlankTabAt(b, -1, true);
[email protected]a37d4b02012-06-25 21:56:10485 b->window()->Show();
[email protected]686221c2012-11-08 07:30:10486 // The call to AddBlankTabAt above did not set the focus to the tab as its
[email protected]a37d4b02012-06-25 21:56:10487 // window was not active, so we have to do it explicitly.
488 // See http://crbug.com/6380.
[email protected]855370052012-07-10 19:30:32489 GetActiveWebContents(b)->GetView()->RestoreFocus();
[email protected]a37d4b02012-06-25 21:56:10490 }
491}
492
493void CloseTab(Browser* browser) {
494 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
495 browser->tab_strip_model()->CloseSelectedTabs();
496}
497
[email protected]5d98294912012-06-27 22:57:40498void RestoreTab(Browser* browser) {
499 content::RecordAction(UserMetricsAction("RestoreTab"));
500 TabRestoreService* service =
501 TabRestoreServiceFactory::GetForProfile(browser->profile());
502 if (service)
503 service->RestoreMostRecentEntry(browser->tab_restore_service_delegate());
504}
505
506bool CanRestoreTab(const Browser* browser) {
507 TabRestoreService* service =
508 TabRestoreServiceFactory::GetForProfile(browser->profile());
509 return service && !service->entries().empty();
510}
511
[email protected]a37d4b02012-06-25 21:56:10512void SelectNextTab(Browser* browser) {
513 content::RecordAction(UserMetricsAction("SelectNextTab"));
514 browser->tab_strip_model()->SelectNextTab();
515}
516
517void SelectPreviousTab(Browser* browser) {
518 content::RecordAction(UserMetricsAction("SelectPrevTab"));
519 browser->tab_strip_model()->SelectPreviousTab();
520}
521
522void OpenTabpose(Browser* browser) {
523#if defined(OS_MACOSX)
524 if (!CommandLine::ForCurrentProcess()->HasSwitch(
525 switches::kEnableExposeForTabs)) {
526 return;
527 }
528
529 content::RecordAction(UserMetricsAction("OpenTabpose"));
530 browser->window()->OpenTabpose();
531#else
532 NOTREACHED();
533#endif
534}
535
536void MoveTabNext(Browser* browser) {
537 content::RecordAction(UserMetricsAction("MoveTabNext"));
538 browser->tab_strip_model()->MoveTabNext();
539}
540
541void MoveTabPrevious(Browser* browser) {
542 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
543 browser->tab_strip_model()->MoveTabPrevious();
544}
545
546void SelectNumberedTab(Browser* browser, int index) {
547 if (index < browser->tab_count()) {
548 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
[email protected]52877dbc62012-06-29 22:22:03549 ActivateTabAt(browser, index, true);
[email protected]a37d4b02012-06-25 21:56:10550 }
551}
552
553void SelectLastTab(Browser* browser) {
554 content::RecordAction(UserMetricsAction("SelectLastTab"));
555 browser->tab_strip_model()->SelectLastTab();
556}
557
558void DuplicateTab(Browser* browser) {
559 content::RecordAction(UserMetricsAction("Duplicate"));
[email protected]855370052012-07-10 19:30:32560 DuplicateTabAt(browser, browser->active_index());
[email protected]a37d4b02012-06-25 21:56:10561}
562
[email protected]5d98294912012-06-27 22:57:40563bool CanDuplicateTab(const Browser* browser) {
[email protected]52877dbc62012-06-29 22:22:03564 WebContents* contents = GetActiveWebContents(browser);
[email protected]5d98294912012-06-27 22:57:40565 return contents && contents->GetController().GetLastCommittedEntry();
566}
567
[email protected]37bb5822012-09-10 15:09:57568TabContents* DuplicateTabAt(Browser* browser, int index) {
[email protected]59253a652012-11-20 00:17:26569 TabContents* contents = browser->tab_strip_model()->GetTabContentsAt(index);
[email protected]855370052012-07-10 19:30:32570 CHECK(contents);
[email protected]f250fd52012-08-27 20:09:37571 TabContents* contents_dupe =
572 BrowserCommandsTabContentsCreator::CloneTabContents(contents);
[email protected]855370052012-07-10 19:30:32573
574 bool pinned = false;
575 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
576 // If this is a tabbed browser, just create a duplicate tab inside the same
577 // window next to the tab being duplicated.
578 int index = browser->tab_strip_model()->GetIndexOfTabContents(contents);
579 pinned = browser->tab_strip_model()->IsTabPinned(index);
580 int add_types = TabStripModel::ADD_ACTIVE |
581 TabStripModel::ADD_INHERIT_GROUP |
582 (pinned ? TabStripModel::ADD_PINNED : 0);
[email protected]976702b2012-11-26 20:08:41583 browser->tab_strip_model()->InsertWebContentsAt(
584 index + 1, contents_dupe->web_contents(), add_types);
[email protected]855370052012-07-10 19:30:32585 } else {
586 Browser* browser = NULL;
587 if (browser->is_app()) {
588 CHECK(!browser->is_type_popup());
589 CHECK(!browser->is_type_panel());
[email protected]a4fe67012012-07-25 20:14:29590 browser = new Browser(
[email protected]855370052012-07-10 19:30:32591 Browser::CreateParams::CreateForApp(Browser::TYPE_POPUP,
592 browser->app_name(),
593 gfx::Rect(),
594 browser->profile()));
595 } else if (browser->is_type_popup()) {
[email protected]a4fe67012012-07-25 20:14:29596 browser = new Browser(
[email protected]855370052012-07-10 19:30:32597 Browser::CreateParams(Browser::TYPE_POPUP, browser->profile()));
598 }
599
600 // Preserve the size of the original window. The new window has already
601 // been given an offset by the OS, so we shouldn't copy the old bounds.
602 BrowserWindow* new_window = browser->window();
603 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
604 browser->window()->GetRestoredBounds().size()));
605
606 // We need to show the browser now. Otherwise ContainerWin assumes the
607 // WebContents is invisible and won't size it.
608 browser->window()->Show();
609
610 // The page transition below is only for the purpose of inserting the tab.
[email protected]0d56fa7212012-11-15 23:34:02611 browser->tab_strip_model()->AddTabContents(contents_dupe, -1,
612 content::PAGE_TRANSITION_LINK,
613 TabStripModel::ADD_ACTIVE);
[email protected]855370052012-07-10 19:30:32614 }
615
616 SessionService* session_service =
617 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
618 if (session_service)
[email protected]b624ddc2012-11-15 18:04:13619 session_service->TabRestored(contents_dupe->web_contents(), pinned);
[email protected]37bb5822012-09-10 15:09:57620 return contents_dupe;
[email protected]855370052012-07-10 19:30:32621}
622
623bool CanDuplicateTabAt(Browser* browser, int index) {
624 content::NavigationController& nc =
625 GetWebContentsAt(browser, index)->GetController();
626 return nc.GetWebContents() && nc.GetLastCommittedEntry();
627}
628
[email protected]a37d4b02012-06-25 21:56:10629void ConvertPopupToTabbedBrowser(Browser* browser) {
630 content::RecordAction(UserMetricsAction("ShowAsTab"));
631 TabContents* contents =
632 browser->tab_strip_model()->DetachTabContentsAt(browser->active_index());
[email protected]a4fe67012012-07-25 20:14:29633 Browser* b = new Browser(Browser::CreateParams(browser->profile()));
[email protected]ea01ff22012-11-27 20:35:15634 b->tab_strip_model()->AppendWebContents(contents->web_contents(), true);
[email protected]a37d4b02012-06-25 21:56:10635 b->window()->Show();
636}
637
638void Exit() {
639 content::RecordAction(UserMetricsAction("Exit"));
640 browser::AttemptUserExit();
641}
642
643void BookmarkCurrentPage(Browser* browser) {
[email protected]195c99c2012-10-31 06:24:51644 BookmarkCurrentPageInternal(browser, false);
645}
[email protected]a37d4b02012-06-25 21:56:10646
[email protected]195c99c2012-10-31 06:24:51647void BookmarkCurrentPageFromStar(Browser* browser) {
648 BookmarkCurrentPageInternal(browser, true);
[email protected]a37d4b02012-06-25 21:56:10649}
650
[email protected]5d98294912012-06-27 22:57:40651bool CanBookmarkCurrentPage(const Browser* browser) {
[email protected]4f7490ef2012-07-31 08:49:03652 BookmarkModel* model =
653 BookmarkModelFactory::GetForProfile(browser->profile());
[email protected]5d98294912012-06-27 22:57:40654 return browser_defaults::bookmarks_enabled &&
655 browser->profile()->GetPrefs()->GetBoolean(
656 prefs::kEditBookmarksEnabled) &&
657 model && model->IsLoaded() && browser->is_type_tabbed();
658}
659
660void BookmarkAllTabs(Browser* browser) {
[email protected]345d7d32012-10-03 23:10:18661 chrome::ShowBookmarkAllTabsDialog(browser);
[email protected]5d98294912012-06-27 22:57:40662}
663
664bool CanBookmarkAllTabs(const Browser* browser) {
665 return browser->tab_count() > 1 && CanBookmarkCurrentPage(browser);
666}
667
[email protected]ffe6de62012-07-19 00:02:35668void TogglePagePinnedToStartScreen(Browser* browser) {
[email protected]b0bcd9be2012-10-24 22:51:56669#if defined(OS_WIN)
[email protected]5ab8d622012-09-07 18:00:48670 MetroPinTabHelper::FromWebContents(GetActiveWebContents(browser))->
[email protected]ffe6de62012-07-19 00:02:35671 TogglePinnedToStartScreen();
[email protected]b0bcd9be2012-10-24 22:51:56672#endif
[email protected]a37d4b02012-06-25 21:56:10673}
[email protected]a37d4b02012-06-25 21:56:10674
675void SavePage(Browser* browser) {
676 content::RecordAction(UserMetricsAction("SavePage"));
[email protected]52877dbc62012-06-29 22:22:03677 WebContents* current_tab = GetActiveWebContents(browser);
[email protected]a37d4b02012-06-25 21:56:10678 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
679 content::RecordAction(UserMetricsAction("PDF.SavePage"));
680 current_tab->OnSavePage();
681}
682
[email protected]5d98294912012-06-27 22:57:40683bool CanSavePage(const Browser* browser) {
684 // LocalState can be NULL in tests.
685 if (g_browser_process->local_state() &&
686 !g_browser_process->local_state()->GetBoolean(
687 prefs::kAllowFileSelectionDialogs)) {
688 return false;
689 }
690 return !browser->is_devtools() &&
691 !(GetContentRestrictions(browser) & content::CONTENT_RESTRICTION_SAVE);
692}
693
[email protected]a37d4b02012-06-25 21:56:10694void ShowFindBar(Browser* browser) {
695 browser->GetFindBarController()->Show();
696}
697
698void ShowPageInfo(Browser* browser,
699 content::WebContents* web_contents,
700 const GURL& url,
701 const SSLStatus& ssl,
702 bool show_history) {
703 Profile* profile = Profile::FromBrowserContext(
704 web_contents->GetBrowserContext());
[email protected]a37d4b02012-06-25 21:56:10705 if (CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]9a8e9352012-08-24 00:45:17706 switches::kDisableWebsiteSettings)) {
707 browser->window()->ShowPageInfo(web_contents, url, ssl, show_history);
708 } else {
[email protected]a37d4b02012-06-25 21:56:10709 browser->window()->ShowWebsiteSettings(
[email protected]36ad4aa82012-11-21 19:20:48710 profile, web_contents, url, ssl, show_history);
[email protected]a37d4b02012-06-25 21:56:10711 }
712}
713
714void ShowChromeToMobileBubble(Browser* browser) {
715 // Only show the bubble if the window is active, otherwise we may get into
716 // weird situations where the bubble is deleted as soon as it is shown.
717 if (browser->window()->IsActive())
718 browser->window()->ShowChromeToMobileBubble();
719}
720
721void Print(Browser* browser) {
[email protected]e3a7e6f2012-09-18 22:44:31722 printing::PrintViewManager* print_view_manager =
723 printing::PrintViewManager::FromWebContents(
724 GetActiveWebContents(browser));
[email protected]0045b0f42012-07-26 11:52:08725 if (browser->profile()->GetPrefs()->GetBoolean(
[email protected]e3a7e6f2012-09-18 22:44:31726 prefs::kPrintPreviewDisabled))
727 print_view_manager->PrintNow();
728 else
729 print_view_manager->PrintPreviewNow();
[email protected]a37d4b02012-06-25 21:56:10730}
731
[email protected]5d98294912012-06-27 22:57:40732bool CanPrint(const Browser* browser) {
[email protected]0045b0f42012-07-26 11:52:08733 // Do not print when printing is disabled via pref or policy.
[email protected]5d98294912012-06-27 22:57:40734 // Do not print when a constrained window is showing. It's confusing.
[email protected]db9747252012-07-02 19:28:00735 // Do not print if instant extended API is enabled and mode is NTP.
[email protected]0045b0f42012-07-26 11:52:08736 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
737 !(HasConstrainedWindow(browser) ||
[email protected]db9747252012-07-02 19:28:00738 GetContentRestrictions(browser) & content::CONTENT_RESTRICTION_PRINT ||
739 IsNTPModeForInstantExtendedAPI(browser));
[email protected]5d98294912012-06-27 22:57:40740}
741
[email protected]a37d4b02012-06-25 21:56:10742void AdvancedPrint(Browser* browser) {
[email protected]e3a7e6f2012-09-18 22:44:31743 printing::PrintViewManager* print_view_manager =
744 printing::PrintViewManager::FromWebContents(
745 GetActiveWebContents(browser));
746 print_view_manager->AdvancedPrintNow();
[email protected]a37d4b02012-06-25 21:56:10747}
748
[email protected]5d98294912012-06-27 22:57:40749bool CanAdvancedPrint(const Browser* browser) {
[email protected]0045b0f42012-07-26 11:52:08750 // If printing is not disabled via pref or policy, it is always possible to
751 // advanced print when the print preview is visible.
752 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
753 (PrintPreviewShowing(browser) || CanPrint(browser));
[email protected]5d98294912012-06-27 22:57:40754}
755
[email protected]d53e4032012-06-29 18:58:34756void PrintToDestination(Browser* browser) {
[email protected]e3a7e6f2012-09-18 22:44:31757 printing::PrintViewManager* print_view_manager =
758 printing::PrintViewManager::FromWebContents(
759 GetActiveWebContents(browser));
760 print_view_manager->PrintToDestination();
[email protected]d53e4032012-06-29 18:58:34761}
762
[email protected]a37d4b02012-06-25 21:56:10763void EmailPageLocation(Browser* browser) {
764 content::RecordAction(UserMetricsAction("EmailPageLocation"));
[email protected]52877dbc62012-06-29 22:22:03765 WebContents* wc = GetActiveWebContents(browser);
[email protected]a37d4b02012-06-25 21:56:10766 DCHECK(wc);
767
768 std::string title = net::EscapeQueryParamValue(
769 UTF16ToUTF8(wc->GetTitle()), false);
770 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
771 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
772 title + "&body=%0A%0A" + page_url;
773 platform_util::OpenExternal(GURL(mailto));
774}
775
[email protected]5d98294912012-06-27 22:57:40776bool CanEmailPageLocation(const Browser* browser) {
777 return browser->toolbar_model()->ShouldDisplayURL() &&
[email protected]52877dbc62012-06-29 22:22:03778 GetActiveWebContents(browser)->GetURL().is_valid();
[email protected]5d98294912012-06-27 22:57:40779}
780
[email protected]a37d4b02012-06-25 21:56:10781void Cut(Browser* browser) {
782 content::RecordAction(UserMetricsAction("Cut"));
783 browser->window()->Cut();
784}
785
786void Copy(Browser* browser) {
787 content::RecordAction(UserMetricsAction("Copy"));
788 browser->window()->Copy();
789}
790
791void Paste(Browser* browser) {
792 content::RecordAction(UserMetricsAction("Paste"));
793 browser->window()->Paste();
794}
795
796void Find(Browser* browser) {
797 content::RecordAction(UserMetricsAction("Find"));
798 FindInPage(browser, false, false);
799}
800
801void FindNext(Browser* browser) {
802 content::RecordAction(UserMetricsAction("FindNext"));
803 FindInPage(browser, true, true);
804}
805
806void FindPrevious(Browser* browser) {
807 content::RecordAction(UserMetricsAction("FindPrevious"));
808 FindInPage(browser, true, false);
809}
810
811void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
812 ShowFindBar(browser);
813 if (find_next) {
814 string16 find_text;
815#if defined(OS_MACOSX)
816 // We always want to search for the contents of the find pasteboard on OS X.
817 find_text = GetFindPboardText();
818#endif
[email protected]bc852c932012-09-29 21:38:34819 FindTabHelper::FromWebContents(GetActiveWebContents(browser))->
820 StartFinding(find_text,
821 forward_direction,
822 false); // Not case sensitive.
[email protected]a37d4b02012-06-25 21:56:10823 }
824}
825
826void Zoom(Browser* browser, content::PageZoom zoom) {
827 if (browser->is_devtools())
828 return;
829
[email protected]8233cbc2012-07-13 16:14:52830 chrome_page_zoom::Zoom(GetActiveWebContents(browser), zoom);
[email protected]a37d4b02012-06-25 21:56:10831}
832
833void FocusToolbar(Browser* browser) {
834 content::RecordAction(UserMetricsAction("FocusToolbar"));
835 browser->window()->FocusToolbar();
836}
837
838void FocusLocationBar(Browser* browser) {
839 content::RecordAction(UserMetricsAction("FocusLocation"));
840 browser->window()->SetFocusToLocationBar(true);
841}
842
843void FocusSearch(Browser* browser) {
844 // TODO(beng): replace this with FocusLocationBar
845 content::RecordAction(UserMetricsAction("FocusSearch"));
846 browser->window()->GetLocationBar()->FocusSearch();
847}
848
849void FocusAppMenu(Browser* browser) {
850 content::RecordAction(UserMetricsAction("FocusAppMenu"));
851 browser->window()->FocusAppMenu();
852}
853
854void FocusBookmarksToolbar(Browser* browser) {
855 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
856 browser->window()->FocusBookmarksToolbar();
857}
858
859void FocusNextPane(Browser* browser) {
860 content::RecordAction(UserMetricsAction("FocusNextPane"));
861 browser->window()->RotatePaneFocus(true);
862}
863
864void FocusPreviousPane(Browser* browser) {
865 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
866 browser->window()->RotatePaneFocus(false);
867}
868
869void ToggleDevToolsWindow(Browser* browser, DevToolsToggleAction action) {
870 if (action == DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE)
871 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
872 else
873 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
[email protected]d16657c2012-09-03 14:25:10874 DevToolsWindow::ToggleDevToolsWindow(browser, action);
[email protected]a37d4b02012-06-25 21:56:10875}
876
877bool CanOpenTaskManager() {
878#if defined(OS_WIN)
879 // In metro we can't display the task manager, as it is a native window.
880 return !base::win::IsMetroProcess();
881#else
882 return true;
883#endif
884}
885
886void OpenTaskManager(Browser* browser, bool highlight_background_resources) {
887 content::RecordAction(UserMetricsAction("TaskManager"));
888 if (highlight_background_resources)
889 browser->window()->ShowBackgroundPages();
890 else
891 browser->window()->ShowTaskManager();
892}
893
894void OpenFeedbackDialog(Browser* browser) {
895 content::RecordAction(UserMetricsAction("Feedback"));
[email protected]7a19ea22012-08-02 14:39:39896 chrome::ShowFeedbackPage(browser, std::string(), std::string());
[email protected]a37d4b02012-06-25 21:56:10897}
898
899void ToggleBookmarkBar(Browser* browser) {
900 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
901 browser->window()->ToggleBookmarkBar();
902}
903
904void ShowAppMenu(Browser* browser) {
905 // We record the user metric for this event in WrenchMenu::RunMenu.
906 browser->window()->ShowAppMenu();
907}
908
909void ShowAvatarMenu(Browser* browser) {
910 browser->window()->ShowAvatarBubbleFromAvatarButton();
911}
912
913void OpenUpdateChromeDialog(Browser* browser) {
914 content::RecordAction(UserMetricsAction("UpdateChrome"));
915 browser->window()->ShowUpdateChromeDialog();
916}
917
918void ToggleSpeechInput(Browser* browser) {
[email protected]52877dbc62012-06-29 22:22:03919 GetActiveWebContents(browser)->GetRenderViewHost()->ToggleSpeechInput();
[email protected]a37d4b02012-06-25 21:56:10920}
921
[email protected]9b7ab882012-09-10 23:46:36922bool CanRequestTabletSite(WebContents* current_tab) {
923 if (!current_tab)
924 return false;
925 return current_tab->GetController().GetActiveEntry() != NULL;
926}
927
928bool IsRequestingTabletSite(Browser* browser) {
929 WebContents* current_tab = chrome::GetActiveWebContents(browser);
930 if (!current_tab)
931 return false;
932 content::NavigationEntry* entry =
933 current_tab->GetController().GetActiveEntry();
934 if (!entry)
935 return false;
936 return entry->GetIsOverridingUserAgent();
937}
938
939void ToggleRequestTabletSite(Browser* browser) {
940 WebContents* current_tab = GetActiveWebContents(browser);
941 if (!current_tab)
942 return;
943 NavigationController& controller = current_tab->GetController();
944 NavigationEntry* entry = controller.GetActiveEntry();
945 if (!entry)
946 return;
947 if (entry->GetIsOverridingUserAgent()) {
948 entry->SetIsOverridingUserAgent(false);
949 } else {
950 entry->SetIsOverridingUserAgent(true);
951 current_tab->SetUserAgentOverride(
952 webkit_glue::BuildUserAgentFromOSAndProduct(
953 kOsOverrideForTabletSite,
954 content::GetContentClient()->GetProduct()));
955 }
956 controller.ReloadOriginalRequestURL(true);
957}
958
[email protected]3f32b9b2012-07-09 16:59:28959void ToggleFullscreenMode(Browser* browser) {
960 browser->fullscreen_controller()->ToggleFullscreenMode();
961}
962
[email protected]d3446bda2012-07-12 14:24:39963void ClearCache(Browser* browser) {
[email protected]38b892b42012-09-04 13:25:47964 BrowsingDataRemover* remover =
965 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
[email protected]d3446bda2012-07-12 14:24:39966 remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
967 BrowsingDataHelper::UNPROTECTED_WEB);
968 // BrowsingDataRemover takes care of deleting itself when done.
969}
970
971bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
972 WebContents* contents = chrome::GetActiveWebContents(browser);
973 return contents ?
974 content::DevToolsAgentHostRegistry::IsDebuggerAttached(contents) : false;
975}
976
[email protected]2cd4fde2012-06-26 03:10:26977void ViewSource(Browser* browser, TabContents* contents) {
978 DCHECK(contents);
979
[email protected]8fcc7bf2012-08-14 18:14:50980 // Use the last committed entry, since the pending entry hasn't loaded yet and
981 // won't be copied into the cloned tab.
982 NavigationEntry* entry =
983 contents->web_contents()->GetController().GetLastCommittedEntry();
984 if (!entry)
[email protected]2cd4fde2012-06-26 03:10:26985 return;
986
[email protected]8fcc7bf2012-08-14 18:14:50987 ViewSource(browser, contents, entry->GetURL(), entry->GetContentState());
[email protected]2cd4fde2012-06-26 03:10:26988}
989
990void ViewSource(Browser* browser,
991 TabContents* contents,
992 const GURL& url,
993 const std::string& content_state) {
994 content::RecordAction(UserMetricsAction("ViewSource"));
995 DCHECK(contents);
996
[email protected]8fcc7bf2012-08-14 18:14:50997 // Note that Clone does not copy the pending or transient entries, so the
998 // active entry in view_source_contents will be the last committed entry.
[email protected]f250fd52012-08-27 20:09:37999 TabContents* view_source_contents =
1000 BrowserCommandsTabContentsCreator::CloneTabContents(contents);
[email protected]2cd4fde2012-06-26 03:10:261001 view_source_contents->web_contents()->GetController().PruneAllButActive();
1002 NavigationEntry* active_entry =
1003 view_source_contents->web_contents()->GetController().GetActiveEntry();
1004 if (!active_entry)
1005 return;
1006
[email protected]52877dbc62012-06-29 22:22:031007 GURL view_source_url = GURL(kViewSourceScheme + std::string(":") +
[email protected]2cd4fde2012-06-26 03:10:261008 url.spec());
1009 active_entry->SetVirtualURL(view_source_url);
1010
1011 // Do not restore scroller position.
1012 active_entry->SetContentState(
1013 webkit_glue::RemoveScrollOffsetFromHistoryState(content_state));
1014
1015 // Do not restore title, derive it from the url.
1016 active_entry->SetTitle(string16());
1017
1018 // Now show view-source entry.
1019 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
1020 // If this is a tabbed browser, just create a duplicate tab inside the same
1021 // window next to the tab being duplicated.
1022 int index = browser->tab_strip_model()->GetIndexOfTabContents(contents);
1023 int add_types = TabStripModel::ADD_ACTIVE |
1024 TabStripModel::ADD_INHERIT_GROUP;
[email protected]976702b2012-11-26 20:08:411025 browser->tab_strip_model()->InsertWebContentsAt(
1026 index + 1,
1027 view_source_contents->web_contents(),
1028 add_types);
[email protected]2cd4fde2012-06-26 03:10:261029 } else {
[email protected]a4fe67012012-07-25 20:14:291030 Browser* b = new Browser(
[email protected]2cd4fde2012-06-26 03:10:261031 Browser::CreateParams(Browser::TYPE_TABBED, browser->profile()));
1032
1033 // Preserve the size of the original window. The new window has already
1034 // been given an offset by the OS, so we shouldn't copy the old bounds.
1035 BrowserWindow* new_window = b->window();
1036 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
1037 browser->window()->GetRestoredBounds().size()));
1038
1039 // We need to show the browser now. Otherwise ContainerWin assumes the
1040 // WebContents is invisible and won't size it.
1041 b->window()->Show();
1042
1043 // The page transition below is only for the purpose of inserting the tab.
[email protected]0d56fa7212012-11-15 23:34:021044 b->tab_strip_model()->AddTabContents(view_source_contents, -1,
1045 content::PAGE_TRANSITION_LINK,
1046 TabStripModel::ADD_ACTIVE);
[email protected]2cd4fde2012-06-26 03:10:261047 }
1048
1049 SessionService* session_service =
1050 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
1051 if (session_service)
[email protected]b624ddc2012-11-15 18:04:131052 session_service->TabRestored(view_source_contents->web_contents(), false);
[email protected]2cd4fde2012-06-26 03:10:261053}
1054
1055void ViewSelectedSource(Browser* browser) {
[email protected]59253a652012-11-20 00:17:261056 ViewSource(browser, browser->tab_strip_model()->GetActiveTabContents());
[email protected]2cd4fde2012-06-26 03:10:261057}
1058
[email protected]5d98294912012-06-27 22:57:401059bool CanViewSource(const Browser* browser) {
[email protected]855370052012-07-10 19:30:321060 return GetActiveWebContents(browser)->GetController().CanViewSource();
[email protected]5d98294912012-06-27 22:57:401061}
1062
[email protected]619f86182012-07-03 21:30:181063void CreateApplicationShortcuts(Browser* browser) {
1064 content::RecordAction(UserMetricsAction("CreateShortcut"));
[email protected]7381d9f2012-09-12 20:26:221065 extensions::TabHelper::FromWebContents(GetActiveWebContents(browser))->
[email protected]619f86182012-07-03 21:30:181066 CreateApplicationShortcuts();
1067}
1068
[email protected]5d98294912012-06-27 22:57:401069bool CanCreateApplicationShortcuts(const Browser* browser) {
[email protected]7381d9f2012-09-12 20:26:221070 return extensions::TabHelper::FromWebContents(GetActiveWebContents(browser))->
[email protected]619f86182012-07-03 21:30:181071 CanCreateApplicationShortcuts();
[email protected]5d98294912012-06-27 22:57:401072}
1073
[email protected]40df6f52012-06-28 17:08:521074void ConvertTabToAppWindow(Browser* browser,
1075 content::WebContents* contents) {
1076 const GURL& url = contents->GetController().GetActiveEntry()->GetURL();
1077 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
1078
1079 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1080 if (index >= 0)
1081 browser->tab_strip_model()->DetachTabContentsAt(index);
1082
[email protected]a4fe67012012-07-25 20:14:291083 Browser* app_browser = new Browser(
[email protected]40df6f52012-06-28 17:08:521084 Browser::CreateParams::CreateForApp(
1085 Browser::TYPE_POPUP, app_name, gfx::Rect(), browser->profile()));
[email protected]ea01ff22012-11-27 20:35:151086 app_browser->tab_strip_model()->AppendWebContents(contents, true);
[email protected]40df6f52012-06-28 17:08:521087
1088 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
1089 contents->GetRenderViewHost()->SyncRendererPrefs();
1090 app_browser->window()->Show();
1091}
1092
[email protected]a37d4b02012-06-25 21:56:101093} // namespace chrome