1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/browser_url_handler.h"
#include "content/public/browser/web_contents.h"
namespace chrome {
namespace {
// Returns true if two URLs are equal after taking |replacements| into account.
bool CompareURLsWithReplacements(const GURL& url,
const GURL& other,
const url::Replacements<char>& replacements) {
if (url == other)
return true;
GURL url_replaced = url.ReplaceComponents(replacements);
GURL other_replaced = other.ReplaceComponents(replacements);
return url_replaced == other_replaced;
}
} // namespace
void ShowSingletonTab(Browser* browser, const GURL& url) {
NavigateParams params(GetSingletonTabNavigateParams(browser, url));
Navigate(¶ms);
}
void ShowSingletonTabRespectRef(Browser* browser, const GURL& url) {
NavigateParams params(GetSingletonTabNavigateParams(browser, url));
params.ref_behavior = NavigateParams::RESPECT_REF;
Navigate(¶ms);
}
void ShowSingletonTabOverwritingNTP(Browser* browser,
const NavigateParams& params) {
DCHECK(browser);
NavigateParams local_params(params);
content::WebContents* contents =
browser->tab_strip_model()->GetActiveWebContents();
if (contents) {
const GURL& contents_url = contents->GetURL();
if ((contents_url == GURL(kChromeUINewTabURL) || IsInstantNTP(contents) ||
contents_url == GURL(url::kAboutBlankURL)) &&
GetIndexOfSingletonTab(&local_params) < 0) {
local_params.disposition = CURRENT_TAB;
}
}
Navigate(&local_params);
}
NavigateParams GetSingletonTabNavigateParams(Browser* browser,
const GURL& url) {
NavigateParams params(browser, url, ui::PAGE_TRANSITION_AUTO_BOOKMARK);
params.disposition = SINGLETON_TAB;
params.window_action = NavigateParams::SHOW_WINDOW;
params.user_gesture = true;
params.tabstrip_add_types |= TabStripModel::ADD_INHERIT_OPENER;
return params;
}
// Returns the index of an existing singleton tab in |params->browser| matching
// the URL specified in |params|.
int GetIndexOfSingletonTab(NavigateParams* params) {
if (params->disposition != SINGLETON_TAB)
return -1;
// In case the URL was rewritten by the BrowserURLHandler we need to ensure
// that we do not open another URL that will get redirected to the rewritten
// URL.
GURL rewritten_url(params->url);
bool reverse_on_redirect = false;
content::BrowserURLHandler::GetInstance()->RewriteURLIfNecessary(
&rewritten_url,
params->browser->profile(),
&reverse_on_redirect);
// If there are several matches: prefer the active tab by starting there.
int start_index =
std::max(0, params->browser->tab_strip_model()->active_index());
int tab_count = params->browser->tab_strip_model()->count();
for (int i = 0; i < tab_count; ++i) {
int tab_index = (start_index + i) % tab_count;
content::WebContents* tab =
params->browser->tab_strip_model()->GetWebContentsAt(tab_index);
GURL tab_url = tab->GetURL();
// Skip view-source tabs. This is needed because RewriteURLIfNecessary
// removes the "view-source:" scheme which leads to incorrect matching.
if (tab_url.SchemeIs(content::kViewSourceScheme))
continue;
GURL rewritten_tab_url = tab_url;
content::BrowserURLHandler::GetInstance()->RewriteURLIfNecessary(
&rewritten_tab_url,
params->browser->profile(),
&reverse_on_redirect);
url::Replacements<char> replacements;
if (params->ref_behavior == NavigateParams::IGNORE_REF)
replacements.ClearRef();
if (params->path_behavior == NavigateParams::IGNORE_AND_NAVIGATE ||
params->path_behavior == NavigateParams::IGNORE_AND_STAY_PUT) {
replacements.ClearPath();
replacements.ClearQuery();
}
if (CompareURLsWithReplacements(tab_url, params->url, replacements) ||
CompareURLsWithReplacements(rewritten_tab_url,
rewritten_url,
replacements)) {
params->target_contents = tab;
return tab_index;
}
}
return -1;
}
} // namespace chrome
|