blob: fef09f5406e14a71f77e17272b133a28ccb6e7db [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"
[email protected]70019152012-12-19 11:44:1917#include "chrome/browser/devtools/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]d8ce31e2012-12-19 05:09:2127#include "chrome/browser/printing/print_preview_dialog_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]a37d4b02012-06-25 21:56:1045#include "chrome/browser/ui/find_bar/find_bar_controller.h"
46#include "chrome/browser/ui/find_bar/find_tab_helper.h"
[email protected]3f32b9b2012-07-09 16:59:2847#include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
[email protected]a37d4b02012-06-25 21:56:1048#include "chrome/browser/ui/omnibox/location_bar.h"
[email protected]43aafff2012-06-29 21:20:4949#include "chrome/browser/ui/search/search.h"
50#include "chrome/browser/ui/search/search_model.h"
[email protected]a37d4b02012-06-25 21:56:1051#include "chrome/browser/ui/status_bubble.h"
[email protected]a37d4b02012-06-25 21:56:1052#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]d2b16572013-01-03 00:41:5853#include "chrome/browser/ui/web_contents_modal_dialog_manager.h"
[email protected]a37d4b02012-06-25 21:56:1054#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
[email protected]5d98294912012-06-27 22:57:4055#include "chrome/browser/web_applications/web_app.h"
[email protected]a37d4b02012-06-25 21:56:1056#include "chrome/common/chrome_switches.h"
[email protected]a37d4b02012-06-25 21:56:1057#include "chrome/common/pref_names.h"
[email protected]98f66112012-12-25 12:59:3658#include "content/public/browser/devtools_agent_host.h"
[email protected]a37d4b02012-06-25 21:56:1059#include "content/public/browser/navigation_controller.h"
60#include "content/public/browser/navigation_entry.h"
61#include "content/public/browser/page_navigator.h"
62#include "content/public/browser/render_view_host.h"
63#include "content/public/browser/user_metrics.h"
64#include "content/public/browser/web_contents.h"
65#include "content/public/browser/web_contents_view.h"
[email protected]6c2d6eb2012-09-01 00:06:3166#include "content/public/browser/web_intents_dispatcher.h"
[email protected]9b7ab882012-09-10 23:46:3667#include "content/public/common/content_client.h"
[email protected]78e2edc2012-07-01 23:32:2868#include "content/public/common/content_restriction.h"
69#include "content/public/common/renderer_preferences.h"
[email protected]2cd4fde2012-06-26 03:10:2670#include "content/public/common/url_constants.h"
[email protected]a37d4b02012-06-25 21:56:1071#include "net/base/escape.h"
[email protected]bb0e79472012-10-23 04:36:3472#include "webkit/glue/glue_serialize.h"
[email protected]6c2d6eb2012-09-01 00:06:3173#include "webkit/glue/web_intent_data.h"
[email protected]9b7ab882012-09-10 23:46:3674#include "webkit/user_agent/user_agent_util.h"
[email protected]a37d4b02012-06-25 21:56:1075
76#if defined(OS_MACOSX)
77#include "ui/base/cocoa/find_pasteboard.h"
78#endif
79
80#if defined(OS_WIN)
[email protected]b0bcd9be2012-10-24 22:51:5681#include "chrome/browser/ui/metro_pin_tab_helper_win.h"
[email protected]bd04f2492012-12-06 00:40:3182#include "win8/util/win8_util.h"
[email protected]a37d4b02012-06-25 21:56:1083#endif
84
[email protected]9b7ab882012-09-10 23:46:3685namespace {
86const char kOsOverrideForTabletSite[] = "Linux; Android 4.0.3";
87}
88
[email protected]a37d4b02012-06-25 21:56:1089using content::NavigationController;
90using content::NavigationEntry;
91using content::OpenURLParams;
92using content::Referrer;
93using content::SSLStatus;
94using content::UserMetricsAction;
95using content::WebContents;
96
97namespace chrome {
98namespace {
99
[email protected]195c99c2012-10-31 06:24:51100void BookmarkCurrentPageInternal(Browser* browser, bool from_star) {
101 content::RecordAction(UserMetricsAction("Star"));
102
103 BookmarkModel* model =
104 BookmarkModelFactory::GetForProfile(browser->profile());
105 if (!model || !model->IsLoaded())
106 return; // Ignore requests until bookmarks are loaded.
107
108 GURL url;
109 string16 title;
110 WebContents* web_contents = GetActiveWebContents(browser);
111 GetURLAndTitleToBookmark(web_contents, &url, &title);
112 bool was_bookmarked = model->IsBookmarked(url);
113 if (!was_bookmarked && web_contents->GetBrowserContext()->IsOffTheRecord()) {
114 // If we're incognito the favicon may not have been saved. Save it now
115 // so that bookmarks have an icon for the page.
116 FaviconTabHelper::FromWebContents(web_contents)->SaveFavicon();
117 }
118 bookmark_utils::AddIfNotBookmarked(model, url, title);
119 if (from_star && !was_bookmarked)
120 BookmarkPromptController::AddedBookmark(browser, url);
121 // Make sure the model actually added a bookmark before showing the star. A
122 // bookmark isn't created if the url is invalid.
123 if (browser->window()->IsActive() && model->IsBookmarked(url)) {
124 // Only show the bubble if the window is active, otherwise we may get into
125 // weird situations where the bubble is deleted as soon as it is shown.
126 browser->window()->ShowBookmarkBubble(url, was_bookmarked);
127 }
128}
129
[email protected]a37d4b02012-06-25 21:56:10130WebContents* GetOrCloneTabForDisposition(Browser* browser,
131 WindowOpenDisposition disposition) {
[email protected]ee9b0cb2012-11-29 20:56:17132 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
[email protected]a37d4b02012-06-25 21:56:10133 switch (disposition) {
134 case NEW_FOREGROUND_TAB:
135 case NEW_BACKGROUND_TAB: {
[email protected]ee9b0cb2012-11-29 20:56:17136 current_tab = current_tab->Clone();
137 browser->tab_strip_model()->AddWebContents(
[email protected]a37d4b02012-06-25 21:56:10138 current_tab, -1, content::PAGE_TRANSITION_LINK,
139 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
140 TabStripModel::ADD_NONE);
141 break;
142 }
143 case NEW_WINDOW: {
[email protected]ee9b0cb2012-11-29 20:56:17144 current_tab = current_tab->Clone();
[email protected]435d43e02012-12-09 09:13:55145 Browser* b = new Browser(Browser::CreateParams(
146 browser->profile(), browser->host_desktop_type()));
[email protected]ee9b0cb2012-11-29 20:56:17147 b->tab_strip_model()->AddWebContents(
[email protected]a37d4b02012-06-25 21:56:10148 current_tab, -1, content::PAGE_TRANSITION_LINK,
149 TabStripModel::ADD_ACTIVE);
150 b->window()->Show();
151 break;
152 }
153 default:
154 break;
155 }
[email protected]ee9b0cb2012-11-29 20:56:17156 return current_tab;
[email protected]a37d4b02012-06-25 21:56:10157}
158
159void ReloadInternal(Browser* browser,
160 WindowOpenDisposition disposition,
161 bool ignore_cache) {
[email protected]a37d4b02012-06-25 21:56:10162 // As this is caused by a user action, give the focus to the page.
163 //
164 // Also notify RenderViewHostDelegate of the user gesture; this is
165 // normally done in Browser::Navigate, but a reload bypasses Navigate.
166 WebContents* web_contents = GetOrCloneTabForDisposition(browser, disposition);
167 web_contents->UserGestureDone();
168 if (!web_contents->FocusLocationBarByDefault())
169 web_contents->Focus();
170 if (ignore_cache)
171 web_contents->GetController().ReloadIgnoringCache(true);
172 else
173 web_contents->GetController().Reload(true);
174}
175
[email protected]5d98294912012-06-27 22:57:40176bool HasConstrainedWindow(const Browser* browser) {
[email protected]c6464ad2012-10-03 00:27:28177 WebContents* web_contents = GetActiveWebContents(browser);
178 if (!web_contents)
179 return false;
180
[email protected]d2b16572013-01-03 00:41:58181 WebContentsModalDialogManager* web_contents_dialog_manager =
182 WebContentsModalDialogManager::FromWebContents(web_contents);
183 return web_contents_dialog_manager->dialog_count() > 0;
[email protected]5d98294912012-06-27 22:57:40184}
185
186bool PrintPreviewShowing(const Browser* browser) {
[email protected]a7ed0ca2012-12-06 19:30:06187 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
[email protected]d8ce31e2012-12-19 05:09:21188 printing::PrintPreviewDialogController* controller =
189 printing::PrintPreviewDialogController::GetInstance();
[email protected]5d98294912012-06-27 22:57:40190 return controller && (controller->GetPrintPreviewForTab(contents) ||
191 controller->is_creating_print_preview_tab());
192}
193
[email protected]db9747252012-07-02 19:28:00194bool IsNTPModeForInstantExtendedAPI(const Browser* browser) {
195 return browser->search_model() &&
[email protected]855370052012-07-10 19:30:32196 search::IsInstantExtendedAPIEnabled(browser->profile()) &&
197 browser->search_model()->mode().is_ntp();
[email protected]db9747252012-07-02 19:28:00198}
199
[email protected]a37d4b02012-06-25 21:56:10200} // namespace
201
[email protected]5d98294912012-06-27 22:57:40202bool IsCommandEnabled(Browser* browser, int command) {
203 return browser->command_controller()->command_updater()->IsCommandEnabled(
204 command);
205}
206
207bool SupportsCommand(Browser* browser, int command) {
208 return browser->command_controller()->command_updater()->SupportsCommand(
209 command);
210}
211
212bool ExecuteCommand(Browser* browser, int command) {
213 return browser->command_controller()->command_updater()->ExecuteCommand(
214 command);
215}
216
217bool ExecuteCommandWithDisposition(Browser* browser,
218 int command,
219 WindowOpenDisposition disposition) {
220 return browser->command_controller()->command_updater()->
221 ExecuteCommandWithDisposition(command, disposition);
222}
223
224void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
225 browser->command_controller()->command_updater()->UpdateCommandEnabled(
226 command, enabled);
227}
228
229void AddCommandObserver(Browser* browser,
230 int command,
231 CommandObserver* observer) {
232 browser->command_controller()->command_updater()->AddCommandObserver(
233 command, observer);
234}
235
236void RemoveCommandObserver(Browser* browser,
237 int command,
238 CommandObserver* observer) {
239 browser->command_controller()->command_updater()->RemoveCommandObserver(
240 command, observer);
241}
242
243int GetContentRestrictions(const Browser* browser) {
244 int content_restrictions = 0;
[email protected]52877dbc62012-06-29 22:22:03245 WebContents* current_tab = GetActiveWebContents(browser);
[email protected]5d98294912012-06-27 22:57:40246 if (current_tab) {
247 content_restrictions = current_tab->GetContentRestrictions();
248 NavigationEntry* active_entry =
249 current_tab->GetController().GetActiveEntry();
250 // See comment in UpdateCommandsForTabState about why we call url().
251 if (!download_util::IsSavableURL(
252 active_entry ? active_entry->GetURL() : GURL()) ||
253 current_tab->ShowingInterstitialPage())
254 content_restrictions |= content::CONTENT_RESTRICTION_SAVE;
255 if (current_tab->ShowingInterstitialPage())
256 content_restrictions |= content::CONTENT_RESTRICTION_PRINT;
257 }
258 return content_restrictions;
259}
260
[email protected]5fdb45b2012-10-23 20:26:28261void NewEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
[email protected]a37d4b02012-06-25 21:56:10262 bool incognito = profile->IsOffTheRecord();
263 PrefService* prefs = profile->GetPrefs();
264 if (incognito) {
265 if (IncognitoModePrefs::GetAvailability(prefs) ==
266 IncognitoModePrefs::DISABLED) {
267 incognito = false;
268 }
269 } else {
270 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
271 IncognitoModePrefs::ShouldLaunchIncognito(
272 *CommandLine::ForCurrentProcess(), prefs)) {
273 incognito = true;
274 }
275 }
276
277 if (incognito) {
278 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
[email protected]5fdb45b2012-10-23 20:26:28279 OpenEmptyWindow(profile->GetOffTheRecordProfile(), desktop_type);
[email protected]a37d4b02012-06-25 21:56:10280 } else {
281 content::RecordAction(UserMetricsAction("NewWindow"));
282 SessionService* session_service =
283 SessionServiceFactory::GetForProfile(profile->GetOriginalProfile());
284 if (!session_service ||
285 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
[email protected]5fdb45b2012-10-23 20:26:28286 OpenEmptyWindow(profile->GetOriginalProfile(), desktop_type);
[email protected]a37d4b02012-06-25 21:56:10287 }
288 }
289}
290
[email protected]5fdb45b2012-10-23 20:26:28291void NewEmptyWindow(Profile* profile) {
292 NewEmptyWindow(profile, HOST_DESKTOP_TYPE_NATIVE);
293}
294
295Browser* OpenEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
[email protected]d8f10042012-11-14 01:10:46296 // TODO(scottmg): http://crbug.com/128578
297 // This is necessary because WebContentsViewAura doesn't have enough context
298 // to get the right StackingClient (and therefore parent window) otherwise.
299 ScopedForceDesktopType force_desktop_type(desktop_type);
[email protected]5fdb45b2012-10-23 20:26:28300 Browser* browser = new Browser(
301 Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
[email protected]686221c2012-11-08 07:30:10302 AddBlankTabAt(browser, -1, true);
[email protected]a37d4b02012-06-25 21:56:10303 browser->window()->Show();
304 return browser;
305}
306
[email protected]5fdb45b2012-10-23 20:26:28307Browser* OpenEmptyWindow(Profile* profile) {
308 return OpenEmptyWindow(profile, HOST_DESKTOP_TYPE_NATIVE);
309}
310
[email protected]a37d4b02012-06-25 21:56:10311void OpenWindowWithRestoredTabs(Profile* profile) {
312 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
313 if (service)
314 service->RestoreMostRecentEntry(NULL);
315}
316
[email protected]3b14b7f22012-10-04 01:29:09317void OpenURLOffTheRecord(Profile* profile,
318 const GURL& url,
319 chrome::HostDesktopType desktop_type) {
[email protected]7b0957f2012-12-26 22:23:08320 Browser* browser = chrome::FindOrCreateTabbedBrowser(
[email protected]3b14b7f22012-10-04 01:29:09321 profile->GetOffTheRecordProfile(), desktop_type);
[email protected]52877dbc62012-06-29 22:22:03322 AddSelectedTabWithURL(browser, url, content::PAGE_TRANSITION_LINK);
[email protected]a37d4b02012-06-25 21:56:10323 browser->window()->Show();
324}
325
[email protected]5d98294912012-06-27 22:57:40326bool CanGoBack(const Browser* browser) {
[email protected]52877dbc62012-06-29 22:22:03327 return GetActiveWebContents(browser)->GetController().CanGoBack();
[email protected]a37d4b02012-06-25 21:56:10328}
329
330void GoBack(Browser* browser, WindowOpenDisposition disposition) {
331 content::RecordAction(UserMetricsAction("Back"));
332
[email protected]1f2469a2012-12-13 21:19:55333 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
[email protected]a37d4b02012-06-25 21:56:10334 if (CanGoBack(browser)) {
335 WebContents* new_tab = GetOrCloneTabForDisposition(browser, disposition);
336 // If we are on an interstitial page and clone the tab, it won't be copied
337 // to the new tab, so we don't need to go back.
[email protected]1f2469a2012-12-13 21:19:55338 if (current_tab->ShowingInterstitialPage() && new_tab != current_tab)
[email protected]a37d4b02012-06-25 21:56:10339 return;
340 new_tab->GetController().GoBack();
341 }
342}
343
[email protected]5d98294912012-06-27 22:57:40344bool CanGoForward(const Browser* browser) {
[email protected]52877dbc62012-06-29 22:22:03345 return GetActiveWebContents(browser)->GetController().CanGoForward();
[email protected]a37d4b02012-06-25 21:56:10346}
347
348void GoForward(Browser* browser, WindowOpenDisposition disposition) {
349 content::RecordAction(UserMetricsAction("Forward"));
350 if (CanGoForward(browser)) {
351 GetOrCloneTabForDisposition(browser, disposition)->
352 GetController().GoForward();
353 }
354}
355
356bool NavigateToIndexWithDisposition(Browser* browser,
357 int index,
358 WindowOpenDisposition disp) {
359 NavigationController& controller =
360 GetOrCloneTabForDisposition(browser, disp)->GetController();
361 if (index < 0 || index >= controller.GetEntryCount())
362 return false;
363 controller.GoToIndex(index);
364 return true;
365}
366
367void Reload(Browser* browser, WindowOpenDisposition disposition) {
368 content::RecordAction(UserMetricsAction("Reload"));
369 ReloadInternal(browser, disposition, false);
370}
371
372void ReloadIgnoringCache(Browser* browser, WindowOpenDisposition disposition) {
373 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
374 ReloadInternal(browser, disposition, true);
375}
376
[email protected]5d98294912012-06-27 22:57:40377bool CanReload(const Browser* browser) {
[email protected]db9747252012-07-02 19:28:00378 return !browser->is_devtools() && !IsNTPModeForInstantExtendedAPI(browser);
[email protected]5d98294912012-06-27 22:57:40379}
380
[email protected]a37d4b02012-06-25 21:56:10381void Home(Browser* browser, WindowOpenDisposition disposition) {
382 content::RecordAction(UserMetricsAction("Home"));
[email protected]72ea827d2012-09-28 01:30:55383
384 std::string extra_headers;
385#if defined(ENABLE_RLZ)
386 // If the home page is a Google home page, add the RLZ header to the request.
387 PrefService* pref_service = browser->profile()->GetPrefs();
388 if (pref_service) {
389 std::string home_page = pref_service->GetString(prefs::kHomePage);
390 if (google_util::IsGoogleHomePageUrl(home_page)) {
391 extra_headers = RLZTracker::GetAccessPointHttpHeader(
[email protected]7e6f4ed5c2012-10-31 21:10:34392 RLZTracker::CHROME_HOME_PAGE);
[email protected]72ea827d2012-09-28 01:30:55393 }
394 }
395#endif
396
397 OpenURLParams params(
[email protected]a37d4b02012-06-25 21:56:10398 browser->profile()->GetHomePage(), Referrer(), disposition,
399 content::PageTransitionFromInt(
400 content::PAGE_TRANSITION_AUTO_BOOKMARK |
401 content::PAGE_TRANSITION_HOME_PAGE),
[email protected]72ea827d2012-09-28 01:30:55402 false);
403 params.extra_headers = extra_headers;
404 browser->OpenURL(params);
[email protected]a37d4b02012-06-25 21:56:10405}
406
407void OpenCurrentURL(Browser* browser) {
408 content::RecordAction(UserMetricsAction("LoadURL"));
409 LocationBar* location_bar = browser->window()->GetLocationBar();
410 if (!location_bar)
411 return;
412
413 WindowOpenDisposition open_disposition =
414 location_bar->GetWindowOpenDisposition();
[email protected]e41982a72012-11-20 07:16:51415 if (browser->instant_controller() &&
416 browser->instant_controller()->OpenInstant(open_disposition))
[email protected]a37d4b02012-06-25 21:56:10417 return;
418
419 GURL url(location_bar->GetInputString());
420
[email protected]855370052012-07-10 19:30:32421 NavigateParams params(browser, url, location_bar->GetPageTransition());
[email protected]a37d4b02012-06-25 21:56:10422 params.disposition = open_disposition;
423 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
424 // inherit the opener. In some cases the tabstrip will determine the group
425 // should be inherited, in which case the group is inherited instead of the
426 // opener.
427 params.tabstrip_add_types =
428 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
[email protected]855370052012-07-10 19:30:32429 Navigate(&params);
[email protected]a37d4b02012-06-25 21:56:10430
431 DCHECK(browser->profile()->GetExtensionService());
432 if (browser->profile()->GetExtensionService()->IsInstalledApp(url)) {
433 AppLauncherHandler::RecordAppLaunchType(
434 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION);
435 }
436}
437
438void Stop(Browser* browser) {
439 content::RecordAction(UserMetricsAction("Stop"));
[email protected]52877dbc62012-06-29 22:22:03440 GetActiveWebContents(browser)->Stop();
[email protected]a37d4b02012-06-25 21:56:10441}
442
443#if !defined(OS_WIN)
444void NewWindow(Browser* browser) {
445 NewEmptyWindow(browser->profile()->GetOriginalProfile());
446}
447
448void NewIncognitoWindow(Browser* browser) {
449 NewEmptyWindow(browser->profile()->GetOffTheRecordProfile());
450}
451#endif // OS_WIN
452
453void CloseWindow(Browser* browser) {
454 content::RecordAction(UserMetricsAction("CloseWindow"));
455 browser->window()->Close();
456}
457
458void NewTab(Browser* browser) {
459 content::RecordAction(UserMetricsAction("NewTab"));
460 // TODO(asvitkine): This is invoked programmatically from several places.
461 // Audit the code and change it so that the histogram only gets collected for
462 // user-initiated commands.
463 UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", TabStripModel::NEW_TAB_COMMAND,
464 TabStripModel::NEW_TAB_ENUM_COUNT);
465
466 if (browser->is_type_tabbed()) {
[email protected]686221c2012-11-08 07:30:10467 AddBlankTabAt(browser, -1, true);
[email protected]52877dbc62012-06-29 22:22:03468 GetActiveWebContents(browser)->GetView()->RestoreFocus();
[email protected]a37d4b02012-06-25 21:56:10469 } else {
[email protected]3b14b7f22012-10-04 01:29:09470 Browser* b =
[email protected]7b0957f2012-12-26 22:23:08471 chrome::FindOrCreateTabbedBrowser(browser->profile(),
472 browser->host_desktop_type());
[email protected]686221c2012-11-08 07:30:10473 AddBlankTabAt(b, -1, true);
[email protected]a37d4b02012-06-25 21:56:10474 b->window()->Show();
[email protected]686221c2012-11-08 07:30:10475 // The call to AddBlankTabAt above did not set the focus to the tab as its
[email protected]a37d4b02012-06-25 21:56:10476 // window was not active, so we have to do it explicitly.
477 // See http://crbug.com/6380.
[email protected]855370052012-07-10 19:30:32478 GetActiveWebContents(b)->GetView()->RestoreFocus();
[email protected]a37d4b02012-06-25 21:56:10479 }
480}
481
482void CloseTab(Browser* browser) {
483 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
484 browser->tab_strip_model()->CloseSelectedTabs();
485}
486
[email protected]5d98294912012-06-27 22:57:40487void RestoreTab(Browser* browser) {
488 content::RecordAction(UserMetricsAction("RestoreTab"));
489 TabRestoreService* service =
490 TabRestoreServiceFactory::GetForProfile(browser->profile());
491 if (service)
492 service->RestoreMostRecentEntry(browser->tab_restore_service_delegate());
493}
494
495bool CanRestoreTab(const Browser* browser) {
496 TabRestoreService* service =
497 TabRestoreServiceFactory::GetForProfile(browser->profile());
498 return service && !service->entries().empty();
499}
500
[email protected]a37d4b02012-06-25 21:56:10501void SelectNextTab(Browser* browser) {
502 content::RecordAction(UserMetricsAction("SelectNextTab"));
503 browser->tab_strip_model()->SelectNextTab();
504}
505
506void SelectPreviousTab(Browser* browser) {
507 content::RecordAction(UserMetricsAction("SelectPrevTab"));
508 browser->tab_strip_model()->SelectPreviousTab();
509}
510
511void OpenTabpose(Browser* browser) {
512#if defined(OS_MACOSX)
513 if (!CommandLine::ForCurrentProcess()->HasSwitch(
514 switches::kEnableExposeForTabs)) {
515 return;
516 }
517
518 content::RecordAction(UserMetricsAction("OpenTabpose"));
519 browser->window()->OpenTabpose();
520#else
521 NOTREACHED();
522#endif
523}
524
525void MoveTabNext(Browser* browser) {
526 content::RecordAction(UserMetricsAction("MoveTabNext"));
527 browser->tab_strip_model()->MoveTabNext();
528}
529
530void MoveTabPrevious(Browser* browser) {
531 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
532 browser->tab_strip_model()->MoveTabPrevious();
533}
534
535void SelectNumberedTab(Browser* browser, int index) {
536 if (index < browser->tab_count()) {
537 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
[email protected]57892182012-12-03 19:15:39538 browser->tab_strip_model()->ActivateTabAt(index, true);
[email protected]a37d4b02012-06-25 21:56:10539 }
540}
541
542void SelectLastTab(Browser* browser) {
543 content::RecordAction(UserMetricsAction("SelectLastTab"));
544 browser->tab_strip_model()->SelectLastTab();
545}
546
547void DuplicateTab(Browser* browser) {
548 content::RecordAction(UserMetricsAction("Duplicate"));
[email protected]855370052012-07-10 19:30:32549 DuplicateTabAt(browser, browser->active_index());
[email protected]a37d4b02012-06-25 21:56:10550}
551
[email protected]5d98294912012-06-27 22:57:40552bool CanDuplicateTab(const Browser* browser) {
[email protected]52877dbc62012-06-29 22:22:03553 WebContents* contents = GetActiveWebContents(browser);
[email protected]5d98294912012-06-27 22:57:40554 return contents && contents->GetController().GetLastCommittedEntry();
555}
556
[email protected]ab93b6372012-11-28 05:20:22557WebContents* DuplicateTabAt(Browser* browser, int index) {
[email protected]cd6a46022012-11-28 01:18:10558 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(index);
[email protected]855370052012-07-10 19:30:32559 CHECK(contents);
[email protected]ee9b0cb2012-11-29 20:56:17560 WebContents* contents_dupe = contents->Clone();
[email protected]855370052012-07-10 19:30:32561
562 bool pinned = false;
563 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
564 // If this is a tabbed browser, just create a duplicate tab inside the same
565 // window next to the tab being duplicated.
[email protected]cd6a46022012-11-28 01:18:10566 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
[email protected]855370052012-07-10 19:30:32567 pinned = browser->tab_strip_model()->IsTabPinned(index);
568 int add_types = TabStripModel::ADD_ACTIVE |
569 TabStripModel::ADD_INHERIT_GROUP |
570 (pinned ? TabStripModel::ADD_PINNED : 0);
[email protected]976702b2012-11-26 20:08:41571 browser->tab_strip_model()->InsertWebContentsAt(
[email protected]ee9b0cb2012-11-29 20:56:17572 index + 1, contents_dupe, add_types);
[email protected]855370052012-07-10 19:30:32573 } else {
574 Browser* browser = NULL;
575 if (browser->is_app()) {
576 CHECK(!browser->is_type_popup());
577 CHECK(!browser->is_type_panel());
[email protected]a4fe67012012-07-25 20:14:29578 browser = new Browser(
[email protected]855370052012-07-10 19:30:32579 Browser::CreateParams::CreateForApp(Browser::TYPE_POPUP,
580 browser->app_name(),
581 gfx::Rect(),
582 browser->profile()));
583 } else if (browser->is_type_popup()) {
[email protected]a4fe67012012-07-25 20:14:29584 browser = new Browser(
[email protected]435d43e02012-12-09 09:13:55585 Browser::CreateParams(Browser::TYPE_POPUP, browser->profile(),
586 browser->host_desktop_type()));
[email protected]855370052012-07-10 19:30:32587 }
588
589 // Preserve the size of the original window. The new window has already
590 // been given an offset by the OS, so we shouldn't copy the old bounds.
591 BrowserWindow* new_window = browser->window();
592 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
593 browser->window()->GetRestoredBounds().size()));
594
595 // We need to show the browser now. Otherwise ContainerWin assumes the
596 // WebContents is invisible and won't size it.
597 browser->window()->Show();
598
599 // The page transition below is only for the purpose of inserting the tab.
[email protected]ee9b0cb2012-11-29 20:56:17600 browser->tab_strip_model()->AddWebContents(contents_dupe, -1,
[email protected]0d56fa7212012-11-15 23:34:02601 content::PAGE_TRANSITION_LINK,
602 TabStripModel::ADD_ACTIVE);
[email protected]855370052012-07-10 19:30:32603 }
604
605 SessionService* session_service =
606 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
607 if (session_service)
[email protected]ee9b0cb2012-11-29 20:56:17608 session_service->TabRestored(contents_dupe, pinned);
609 return contents_dupe;
[email protected]855370052012-07-10 19:30:32610}
611
612bool CanDuplicateTabAt(Browser* browser, int index) {
613 content::NavigationController& nc =
614 GetWebContentsAt(browser, index)->GetController();
615 return nc.GetWebContents() && nc.GetLastCommittedEntry();
616}
617
[email protected]a37d4b02012-06-25 21:56:10618void ConvertPopupToTabbedBrowser(Browser* browser) {
619 content::RecordAction(UserMetricsAction("ShowAsTab"));
[email protected]f397f6e2012-12-05 22:44:57620 WebContents* contents =
621 browser->tab_strip_model()->DetachWebContentsAt(browser->active_index());
[email protected]435d43e02012-12-09 09:13:55622 Browser* b = new Browser(Browser::CreateParams(browser->profile(),
623 browser->host_desktop_type()));
[email protected]f397f6e2012-12-05 22:44:57624 b->tab_strip_model()->AppendWebContents(contents, true);
[email protected]a37d4b02012-06-25 21:56:10625 b->window()->Show();
626}
627
628void Exit() {
629 content::RecordAction(UserMetricsAction("Exit"));
630 browser::AttemptUserExit();
631}
632
633void BookmarkCurrentPage(Browser* browser) {
[email protected]195c99c2012-10-31 06:24:51634 BookmarkCurrentPageInternal(browser, false);
635}
[email protected]a37d4b02012-06-25 21:56:10636
[email protected]195c99c2012-10-31 06:24:51637void BookmarkCurrentPageFromStar(Browser* browser) {
638 BookmarkCurrentPageInternal(browser, true);
[email protected]a37d4b02012-06-25 21:56:10639}
640
[email protected]5d98294912012-06-27 22:57:40641bool CanBookmarkCurrentPage(const Browser* browser) {
[email protected]4f7490ef2012-07-31 08:49:03642 BookmarkModel* model =
643 BookmarkModelFactory::GetForProfile(browser->profile());
[email protected]5d98294912012-06-27 22:57:40644 return browser_defaults::bookmarks_enabled &&
645 browser->profile()->GetPrefs()->GetBoolean(
646 prefs::kEditBookmarksEnabled) &&
647 model && model->IsLoaded() && browser->is_type_tabbed();
648}
649
650void BookmarkAllTabs(Browser* browser) {
[email protected]345d7d32012-10-03 23:10:18651 chrome::ShowBookmarkAllTabsDialog(browser);
[email protected]5d98294912012-06-27 22:57:40652}
653
654bool CanBookmarkAllTabs(const Browser* browser) {
655 return browser->tab_count() > 1 && CanBookmarkCurrentPage(browser);
656}
657
[email protected]ffe6de62012-07-19 00:02:35658void TogglePagePinnedToStartScreen(Browser* browser) {
[email protected]b0bcd9be2012-10-24 22:51:56659#if defined(OS_WIN)
[email protected]5ab8d622012-09-07 18:00:48660 MetroPinTabHelper::FromWebContents(GetActiveWebContents(browser))->
[email protected]ffe6de62012-07-19 00:02:35661 TogglePinnedToStartScreen();
[email protected]b0bcd9be2012-10-24 22:51:56662#endif
[email protected]a37d4b02012-06-25 21:56:10663}
[email protected]a37d4b02012-06-25 21:56:10664
665void SavePage(Browser* browser) {
666 content::RecordAction(UserMetricsAction("SavePage"));
[email protected]52877dbc62012-06-29 22:22:03667 WebContents* current_tab = GetActiveWebContents(browser);
[email protected]a37d4b02012-06-25 21:56:10668 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
669 content::RecordAction(UserMetricsAction("PDF.SavePage"));
670 current_tab->OnSavePage();
671}
672
[email protected]5d98294912012-06-27 22:57:40673bool CanSavePage(const Browser* browser) {
674 // LocalState can be NULL in tests.
675 if (g_browser_process->local_state() &&
676 !g_browser_process->local_state()->GetBoolean(
677 prefs::kAllowFileSelectionDialogs)) {
678 return false;
679 }
680 return !browser->is_devtools() &&
681 !(GetContentRestrictions(browser) & content::CONTENT_RESTRICTION_SAVE);
682}
683
[email protected]a37d4b02012-06-25 21:56:10684void ShowFindBar(Browser* browser) {
685 browser->GetFindBarController()->Show();
686}
687
688void ShowPageInfo(Browser* browser,
689 content::WebContents* web_contents,
690 const GURL& url,
691 const SSLStatus& ssl,
692 bool show_history) {
693 Profile* profile = Profile::FromBrowserContext(
694 web_contents->GetBrowserContext());
[email protected]a37d4b02012-06-25 21:56:10695 if (CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]9a8e9352012-08-24 00:45:17696 switches::kDisableWebsiteSettings)) {
697 browser->window()->ShowPageInfo(web_contents, url, ssl, show_history);
698 } else {
[email protected]a37d4b02012-06-25 21:56:10699 browser->window()->ShowWebsiteSettings(
[email protected]36ad4aa82012-11-21 19:20:48700 profile, web_contents, url, ssl, show_history);
[email protected]a37d4b02012-06-25 21:56:10701 }
702}
703
704void ShowChromeToMobileBubble(Browser* browser) {
705 // Only show the bubble if the window is active, otherwise we may get into
706 // weird situations where the bubble is deleted as soon as it is shown.
707 if (browser->window()->IsActive())
708 browser->window()->ShowChromeToMobileBubble();
709}
710
711void Print(Browser* browser) {
[email protected]e3a7e6f2012-09-18 22:44:31712 printing::PrintViewManager* print_view_manager =
713 printing::PrintViewManager::FromWebContents(
714 GetActiveWebContents(browser));
[email protected]0045b0f42012-07-26 11:52:08715 if (browser->profile()->GetPrefs()->GetBoolean(
[email protected]e3a7e6f2012-09-18 22:44:31716 prefs::kPrintPreviewDisabled))
717 print_view_manager->PrintNow();
718 else
719 print_view_manager->PrintPreviewNow();
[email protected]a37d4b02012-06-25 21:56:10720}
721
[email protected]5d98294912012-06-27 22:57:40722bool CanPrint(const Browser* browser) {
[email protected]0045b0f42012-07-26 11:52:08723 // Do not print when printing is disabled via pref or policy.
[email protected]5d98294912012-06-27 22:57:40724 // Do not print when a constrained window is showing. It's confusing.
[email protected]db9747252012-07-02 19:28:00725 // Do not print if instant extended API is enabled and mode is NTP.
[email protected]0045b0f42012-07-26 11:52:08726 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
727 !(HasConstrainedWindow(browser) ||
[email protected]db9747252012-07-02 19:28:00728 GetContentRestrictions(browser) & content::CONTENT_RESTRICTION_PRINT ||
729 IsNTPModeForInstantExtendedAPI(browser));
[email protected]5d98294912012-06-27 22:57:40730}
731
[email protected]a37d4b02012-06-25 21:56:10732void AdvancedPrint(Browser* browser) {
[email protected]e3a7e6f2012-09-18 22:44:31733 printing::PrintViewManager* print_view_manager =
734 printing::PrintViewManager::FromWebContents(
735 GetActiveWebContents(browser));
736 print_view_manager->AdvancedPrintNow();
[email protected]a37d4b02012-06-25 21:56:10737}
738
[email protected]5d98294912012-06-27 22:57:40739bool CanAdvancedPrint(const Browser* browser) {
[email protected]0045b0f42012-07-26 11:52:08740 // If printing is not disabled via pref or policy, it is always possible to
741 // advanced print when the print preview is visible.
742 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
743 (PrintPreviewShowing(browser) || CanPrint(browser));
[email protected]5d98294912012-06-27 22:57:40744}
745
[email protected]d53e4032012-06-29 18:58:34746void PrintToDestination(Browser* browser) {
[email protected]e3a7e6f2012-09-18 22:44:31747 printing::PrintViewManager* print_view_manager =
748 printing::PrintViewManager::FromWebContents(
749 GetActiveWebContents(browser));
750 print_view_manager->PrintToDestination();
[email protected]d53e4032012-06-29 18:58:34751}
752
[email protected]a37d4b02012-06-25 21:56:10753void EmailPageLocation(Browser* browser) {
754 content::RecordAction(UserMetricsAction("EmailPageLocation"));
[email protected]52877dbc62012-06-29 22:22:03755 WebContents* wc = GetActiveWebContents(browser);
[email protected]a37d4b02012-06-25 21:56:10756 DCHECK(wc);
757
758 std::string title = net::EscapeQueryParamValue(
759 UTF16ToUTF8(wc->GetTitle()), false);
760 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
761 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
762 title + "&body=%0A%0A" + page_url;
763 platform_util::OpenExternal(GURL(mailto));
764}
765
[email protected]5d98294912012-06-27 22:57:40766bool CanEmailPageLocation(const Browser* browser) {
767 return browser->toolbar_model()->ShouldDisplayURL() &&
[email protected]52877dbc62012-06-29 22:22:03768 GetActiveWebContents(browser)->GetURL().is_valid();
[email protected]5d98294912012-06-27 22:57:40769}
770
[email protected]a37d4b02012-06-25 21:56:10771void Cut(Browser* browser) {
772 content::RecordAction(UserMetricsAction("Cut"));
773 browser->window()->Cut();
774}
775
776void Copy(Browser* browser) {
777 content::RecordAction(UserMetricsAction("Copy"));
778 browser->window()->Copy();
779}
780
781void Paste(Browser* browser) {
782 content::RecordAction(UserMetricsAction("Paste"));
783 browser->window()->Paste();
784}
785
786void Find(Browser* browser) {
787 content::RecordAction(UserMetricsAction("Find"));
788 FindInPage(browser, false, false);
789}
790
791void FindNext(Browser* browser) {
792 content::RecordAction(UserMetricsAction("FindNext"));
793 FindInPage(browser, true, true);
794}
795
796void FindPrevious(Browser* browser) {
797 content::RecordAction(UserMetricsAction("FindPrevious"));
798 FindInPage(browser, true, false);
799}
800
801void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
802 ShowFindBar(browser);
803 if (find_next) {
804 string16 find_text;
805#if defined(OS_MACOSX)
806 // We always want to search for the contents of the find pasteboard on OS X.
807 find_text = GetFindPboardText();
808#endif
[email protected]bc852c932012-09-29 21:38:34809 FindTabHelper::FromWebContents(GetActiveWebContents(browser))->
810 StartFinding(find_text,
811 forward_direction,
812 false); // Not case sensitive.
[email protected]a37d4b02012-06-25 21:56:10813 }
814}
815
816void Zoom(Browser* browser, content::PageZoom zoom) {
817 if (browser->is_devtools())
818 return;
819
[email protected]8233cbc2012-07-13 16:14:52820 chrome_page_zoom::Zoom(GetActiveWebContents(browser), zoom);
[email protected]a37d4b02012-06-25 21:56:10821}
822
823void FocusToolbar(Browser* browser) {
824 content::RecordAction(UserMetricsAction("FocusToolbar"));
825 browser->window()->FocusToolbar();
826}
827
828void FocusLocationBar(Browser* browser) {
829 content::RecordAction(UserMetricsAction("FocusLocation"));
830 browser->window()->SetFocusToLocationBar(true);
831}
832
833void FocusSearch(Browser* browser) {
834 // TODO(beng): replace this with FocusLocationBar
835 content::RecordAction(UserMetricsAction("FocusSearch"));
836 browser->window()->GetLocationBar()->FocusSearch();
837}
838
839void FocusAppMenu(Browser* browser) {
840 content::RecordAction(UserMetricsAction("FocusAppMenu"));
841 browser->window()->FocusAppMenu();
842}
843
844void FocusBookmarksToolbar(Browser* browser) {
845 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
846 browser->window()->FocusBookmarksToolbar();
847}
848
849void FocusNextPane(Browser* browser) {
850 content::RecordAction(UserMetricsAction("FocusNextPane"));
851 browser->window()->RotatePaneFocus(true);
852}
853
854void FocusPreviousPane(Browser* browser) {
855 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
856 browser->window()->RotatePaneFocus(false);
857}
858
859void ToggleDevToolsWindow(Browser* browser, DevToolsToggleAction action) {
860 if (action == DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE)
861 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
862 else
863 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
[email protected]d16657c2012-09-03 14:25:10864 DevToolsWindow::ToggleDevToolsWindow(browser, action);
[email protected]a37d4b02012-06-25 21:56:10865}
866
867bool CanOpenTaskManager() {
868#if defined(OS_WIN)
869 // In metro we can't display the task manager, as it is a native window.
[email protected]bd04f2492012-12-06 00:40:31870 return !win8::IsSingleWindowMetroMode();
[email protected]a37d4b02012-06-25 21:56:10871#else
872 return true;
873#endif
874}
875
876void OpenTaskManager(Browser* browser, bool highlight_background_resources) {
877 content::RecordAction(UserMetricsAction("TaskManager"));
878 if (highlight_background_resources)
[email protected]ddeb0e8432012-12-21 07:27:54879 browser->window()->ShowBackgroundPages(browser->host_desktop_type());
[email protected]a37d4b02012-06-25 21:56:10880 else
[email protected]ddeb0e8432012-12-21 07:27:54881 browser->window()->ShowTaskManager(browser->host_desktop_type());
[email protected]a37d4b02012-06-25 21:56:10882}
883
884void OpenFeedbackDialog(Browser* browser) {
885 content::RecordAction(UserMetricsAction("Feedback"));
[email protected]7a19ea22012-08-02 14:39:39886 chrome::ShowFeedbackPage(browser, std::string(), std::string());
[email protected]a37d4b02012-06-25 21:56:10887}
888
889void ToggleBookmarkBar(Browser* browser) {
890 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
891 browser->window()->ToggleBookmarkBar();
892}
893
894void ShowAppMenu(Browser* browser) {
895 // We record the user metric for this event in WrenchMenu::RunMenu.
896 browser->window()->ShowAppMenu();
897}
898
899void ShowAvatarMenu(Browser* browser) {
900 browser->window()->ShowAvatarBubbleFromAvatarButton();
901}
902
903void OpenUpdateChromeDialog(Browser* browser) {
904 content::RecordAction(UserMetricsAction("UpdateChrome"));
905 browser->window()->ShowUpdateChromeDialog();
906}
907
908void ToggleSpeechInput(Browser* browser) {
[email protected]52877dbc62012-06-29 22:22:03909 GetActiveWebContents(browser)->GetRenderViewHost()->ToggleSpeechInput();
[email protected]a37d4b02012-06-25 21:56:10910}
911
[email protected]9b7ab882012-09-10 23:46:36912bool CanRequestTabletSite(WebContents* current_tab) {
913 if (!current_tab)
914 return false;
915 return current_tab->GetController().GetActiveEntry() != NULL;
916}
917
918bool IsRequestingTabletSite(Browser* browser) {
919 WebContents* current_tab = chrome::GetActiveWebContents(browser);
920 if (!current_tab)
921 return false;
922 content::NavigationEntry* entry =
923 current_tab->GetController().GetActiveEntry();
924 if (!entry)
925 return false;
926 return entry->GetIsOverridingUserAgent();
927}
928
929void ToggleRequestTabletSite(Browser* browser) {
930 WebContents* current_tab = GetActiveWebContents(browser);
931 if (!current_tab)
932 return;
933 NavigationController& controller = current_tab->GetController();
934 NavigationEntry* entry = controller.GetActiveEntry();
935 if (!entry)
936 return;
937 if (entry->GetIsOverridingUserAgent()) {
938 entry->SetIsOverridingUserAgent(false);
939 } else {
940 entry->SetIsOverridingUserAgent(true);
941 current_tab->SetUserAgentOverride(
942 webkit_glue::BuildUserAgentFromOSAndProduct(
943 kOsOverrideForTabletSite,
944 content::GetContentClient()->GetProduct()));
945 }
946 controller.ReloadOriginalRequestURL(true);
947}
948
[email protected]3f32b9b2012-07-09 16:59:28949void ToggleFullscreenMode(Browser* browser) {
950 browser->fullscreen_controller()->ToggleFullscreenMode();
951}
952
[email protected]d3446bda2012-07-12 14:24:39953void ClearCache(Browser* browser) {
[email protected]38b892b42012-09-04 13:25:47954 BrowsingDataRemover* remover =
955 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
[email protected]d3446bda2012-07-12 14:24:39956 remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
957 BrowsingDataHelper::UNPROTECTED_WEB);
958 // BrowsingDataRemover takes care of deleting itself when done.
959}
960
961bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
962 WebContents* contents = chrome::GetActiveWebContents(browser);
963 return contents ?
[email protected]98f66112012-12-25 12:59:36964 content::DevToolsAgentHost::IsDebuggerAttached(contents) : false;
[email protected]d3446bda2012-07-12 14:24:39965}
966
[email protected]ab93b6372012-11-28 05:20:22967void ViewSource(Browser* browser, WebContents* contents) {
[email protected]2cd4fde2012-06-26 03:10:26968 DCHECK(contents);
969
[email protected]8fcc7bf2012-08-14 18:14:50970 // Use the last committed entry, since the pending entry hasn't loaded yet and
971 // won't be copied into the cloned tab.
[email protected]ab93b6372012-11-28 05:20:22972 NavigationEntry* entry = contents->GetController().GetLastCommittedEntry();
[email protected]8fcc7bf2012-08-14 18:14:50973 if (!entry)
[email protected]2cd4fde2012-06-26 03:10:26974 return;
975
[email protected]8fcc7bf2012-08-14 18:14:50976 ViewSource(browser, contents, entry->GetURL(), entry->GetContentState());
[email protected]2cd4fde2012-06-26 03:10:26977}
978
979void ViewSource(Browser* browser,
[email protected]ab93b6372012-11-28 05:20:22980 WebContents* contents,
[email protected]2cd4fde2012-06-26 03:10:26981 const GURL& url,
982 const std::string& content_state) {
983 content::RecordAction(UserMetricsAction("ViewSource"));
984 DCHECK(contents);
985
[email protected]8fcc7bf2012-08-14 18:14:50986 // Note that Clone does not copy the pending or transient entries, so the
987 // active entry in view_source_contents will be the last committed entry.
[email protected]ee9b0cb2012-11-29 20:56:17988 WebContents* view_source_contents = contents->Clone();
989 view_source_contents->GetController().PruneAllButActive();
[email protected]2cd4fde2012-06-26 03:10:26990 NavigationEntry* active_entry =
[email protected]ee9b0cb2012-11-29 20:56:17991 view_source_contents->GetController().GetActiveEntry();
[email protected]2cd4fde2012-06-26 03:10:26992 if (!active_entry)
993 return;
994
[email protected]52877dbc62012-06-29 22:22:03995 GURL view_source_url = GURL(kViewSourceScheme + std::string(":") +
[email protected]2cd4fde2012-06-26 03:10:26996 url.spec());
997 active_entry->SetVirtualURL(view_source_url);
998
999 // Do not restore scroller position.
1000 active_entry->SetContentState(
1001 webkit_glue::RemoveScrollOffsetFromHistoryState(content_state));
1002
1003 // Do not restore title, derive it from the url.
1004 active_entry->SetTitle(string16());
1005
1006 // Now show view-source entry.
1007 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
1008 // If this is a tabbed browser, just create a duplicate tab inside the same
1009 // window next to the tab being duplicated.
[email protected]ab93b6372012-11-28 05:20:221010 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
[email protected]2cd4fde2012-06-26 03:10:261011 int add_types = TabStripModel::ADD_ACTIVE |
1012 TabStripModel::ADD_INHERIT_GROUP;
[email protected]976702b2012-11-26 20:08:411013 browser->tab_strip_model()->InsertWebContentsAt(
1014 index + 1,
[email protected]ee9b0cb2012-11-29 20:56:171015 view_source_contents,
[email protected]976702b2012-11-26 20:08:411016 add_types);
[email protected]2cd4fde2012-06-26 03:10:261017 } else {
[email protected]a4fe67012012-07-25 20:14:291018 Browser* b = new Browser(
[email protected]435d43e02012-12-09 09:13:551019 Browser::CreateParams(Browser::TYPE_TABBED, browser->profile(),
1020 browser->host_desktop_type()));
[email protected]2cd4fde2012-06-26 03:10:261021
1022 // Preserve the size of the original window. The new window has already
1023 // been given an offset by the OS, so we shouldn't copy the old bounds.
1024 BrowserWindow* new_window = b->window();
1025 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
1026 browser->window()->GetRestoredBounds().size()));
1027
1028 // We need to show the browser now. Otherwise ContainerWin assumes the
1029 // WebContents is invisible and won't size it.
1030 b->window()->Show();
1031
1032 // The page transition below is only for the purpose of inserting the tab.
[email protected]ee9b0cb2012-11-29 20:56:171033 b->tab_strip_model()->AddWebContents(view_source_contents, -1,
[email protected]0d56fa7212012-11-15 23:34:021034 content::PAGE_TRANSITION_LINK,
1035 TabStripModel::ADD_ACTIVE);
[email protected]2cd4fde2012-06-26 03:10:261036 }
1037
1038 SessionService* session_service =
1039 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
1040 if (session_service)
[email protected]ee9b0cb2012-11-29 20:56:171041 session_service->TabRestored(view_source_contents, false);
[email protected]2cd4fde2012-06-26 03:10:261042}
1043
1044void ViewSelectedSource(Browser* browser) {
[email protected]ab93b6372012-11-28 05:20:221045 ViewSource(browser, browser->tab_strip_model()->GetActiveWebContents());
[email protected]2cd4fde2012-06-26 03:10:261046}
1047
[email protected]5d98294912012-06-27 22:57:401048bool CanViewSource(const Browser* browser) {
[email protected]ab93b6372012-11-28 05:20:221049 return browser->tab_strip_model()->GetActiveWebContents()->
1050 GetController().CanViewSource();
[email protected]5d98294912012-06-27 22:57:401051}
1052
[email protected]619f86182012-07-03 21:30:181053void CreateApplicationShortcuts(Browser* browser) {
1054 content::RecordAction(UserMetricsAction("CreateShortcut"));
[email protected]7381d9f2012-09-12 20:26:221055 extensions::TabHelper::FromWebContents(GetActiveWebContents(browser))->
[email protected]619f86182012-07-03 21:30:181056 CreateApplicationShortcuts();
1057}
1058
[email protected]5d98294912012-06-27 22:57:401059bool CanCreateApplicationShortcuts(const Browser* browser) {
[email protected]7381d9f2012-09-12 20:26:221060 return extensions::TabHelper::FromWebContents(GetActiveWebContents(browser))->
[email protected]619f86182012-07-03 21:30:181061 CanCreateApplicationShortcuts();
[email protected]5d98294912012-06-27 22:57:401062}
1063
[email protected]40df6f52012-06-28 17:08:521064void ConvertTabToAppWindow(Browser* browser,
1065 content::WebContents* contents) {
1066 const GURL& url = contents->GetController().GetActiveEntry()->GetURL();
1067 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
1068
1069 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1070 if (index >= 0)
[email protected]f397f6e2012-12-05 22:44:571071 browser->tab_strip_model()->DetachWebContentsAt(index);
[email protected]40df6f52012-06-28 17:08:521072
[email protected]a4fe67012012-07-25 20:14:291073 Browser* app_browser = new Browser(
[email protected]40df6f52012-06-28 17:08:521074 Browser::CreateParams::CreateForApp(
1075 Browser::TYPE_POPUP, app_name, gfx::Rect(), browser->profile()));
[email protected]ea01ff22012-11-27 20:35:151076 app_browser->tab_strip_model()->AppendWebContents(contents, true);
[email protected]40df6f52012-06-28 17:08:521077
1078 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
1079 contents->GetRenderViewHost()->SyncRendererPrefs();
1080 app_browser->window()->Show();
1081}
1082
[email protected]a37d4b02012-06-25 21:56:101083} // namespace chrome