diff options
Diffstat (limited to 'chrome/browser/ui/browser_navigator.cc')
-rw-r--r-- | chrome/browser/ui/browser_navigator.cc | 108 |
1 files changed, 82 insertions, 26 deletions
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc index 54edd14..7143bdf 100644 --- a/chrome/browser/ui/browser_navigator.cc +++ b/chrome/browser/ui/browser_navigator.cc @@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/browser_navigator.h" +#include "chrome/browser/ui/browser_navigator.h" #include "base/command_line.h" -#include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_url_handler.h" #include "chrome/browser/browser_window.h" @@ -15,7 +14,9 @@ #include "chrome/browser/status_bubble.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/url_constants.h" namespace { @@ -52,20 +53,17 @@ Browser* GetOrCreateBrowser(Profile* profile) { return browser ? browser : Browser::Create(profile); } -// Returns true if two URLs are equal ignoring their ref (hash fragment). -bool CompareURLsIgnoreRef(const GURL& url, const GURL& other) { +// Returns true if two URLs are equal after taking |replacements| into account. +bool CompareURLsWithReplacements( + const GURL& url, + const GURL& other, + const url_canon::Replacements<char>& replacements) { if (url == other) return true; - // If neither has a ref than there is no point in stripping the refs and - // the URLs are different since the comparison failed in the previous if - // statement. - if (!url.has_ref() && !other.has_ref()) - return false; - url_canon::Replacements<char> replacements; - replacements.ClearRef(); - GURL url_no_ref = url.ReplaceComponents(replacements); - GURL other_no_ref = other.ReplaceComponents(replacements); - return url_no_ref == other_no_ref; + + GURL url_replaced = url.ReplaceComponents(replacements); + GURL other_replaced = other.ReplaceComponents(replacements); + return url_replaced == other_replaced; } // Returns the index of an existing singleton tab in |params->browser| matching @@ -85,15 +83,45 @@ int GetIndexOfSingletonTab(browser::NavigateParams* params) { for (int i = 0; i < params->browser->tab_count(); ++i) { TabContents* tab = params->browser->GetTabContentsAt(i); - if (CompareURLsIgnoreRef(tab->GetURL(), params->url) || - CompareURLsIgnoreRef(tab->GetURL(), rewritten_url)) { + + url_canon::Replacements<char> replacements; + replacements.ClearRef(); + if (params->ignore_path) + replacements.ClearPath(); + + if (CompareURLsWithReplacements(tab->GetURL(), params->url, replacements) || + CompareURLsWithReplacements(tab->GetURL(), rewritten_url, + replacements)) { params->target_contents = tab; return i; } } + return -1; } +// Change some of the navigation parameters based on the particular URL. +// Currently this applies to chrome://settings and the bookmark manager, +// which we always want to open in a normal (not incognito) window. +void AdjustNavigateParamsForURL(browser::NavigateParams* params) { + if (!params->target_contents && + params->url.scheme() == chrome::kChromeUIScheme && + (params->url.host() == chrome::kChromeUISettingsHost || + params->url.host() == chrome::kChromeUIBookmarksHost)) { + Profile* profile = + params->browser ? params->browser->profile() : params->profile; + + if (profile->IsOffTheRecord()) { + profile = profile->GetOriginalProfile(); + + params->disposition = SINGLETON_TAB; + params->profile = profile; + params->browser = Browser::GetOrCreateTabbedBrowser(profile); + params->show_window = true; + } + } +} + // Returns a Browser that can host the navigation or tab addition specified in // |params|. This might just return the same Browser specified in |params|, or // some other if that Browser is deemed incompatible. @@ -180,17 +208,27 @@ void NormalizeDisposition(browser::NavigateParams* params) { params->disposition = NEW_FOREGROUND_TAB; } - // Disposition trumps add types. ADD_SELECTED is a default, so we need to - // remove it if disposition implies the tab is going to open in the - // background. - if (params->disposition == NEW_BACKGROUND_TAB) - params->tabstrip_add_types &= ~TabStripModel::ADD_SELECTED; + switch (params->disposition) { + case NEW_BACKGROUND_TAB: + // Disposition trumps add types. ADD_SELECTED is a default, so we need to + // remove it if disposition implies the tab is going to open in the + // background. + params->tabstrip_add_types &= ~TabStripModel::ADD_SELECTED; + break; - // Code that wants to open a new window typically expects it to be shown - // automatically. - if (params->disposition == NEW_WINDOW || params->disposition == NEW_POPUP) { - params->show_window = true; - params->tabstrip_add_types |= TabStripModel::ADD_SELECTED; + case NEW_WINDOW: + case NEW_POPUP: + // Code that wants to open a new window typically expects it to be shown + // automatically. + params->show_window = true; + // Fall-through. + case NEW_FOREGROUND_TAB: + case SINGLETON_TAB: + params->tabstrip_add_types |= TabStripModel::ADD_SELECTED; + break; + + default: + break; } } @@ -281,11 +319,20 @@ NavigateParams::~NavigateParams() { } void Navigate(NavigateParams* params) { + Browser* browser = params->browser; + AdjustNavigateParamsForURL(params); + params->browser = GetBrowserForDisposition(params); if (!params->browser) return; // Navigate() must not return early after this point. + if (browser != params->browser && + params->browser->tabstrip_model()->empty()) { + // A new window has been created. So it needs to be displayed. + params->show_window = true; + } + // Make sure the Browser is shown if params call for it. ScopedBrowserDisplayer displayer(params); @@ -358,6 +405,15 @@ void Navigate(NavigateParams* params) { // The navigation occurred in some other tab. int singleton_index = GetIndexOfSingletonTab(params); if (params->disposition == SINGLETON_TAB && singleton_index >= 0) { + TabContents* target = params->browser->GetTabContentsAt(singleton_index); + + // Load the URL if the target contents URL doesn't match. This can happen + // if the URL path is ignored when locating the singleton tab. + if (target->GetURL() != params->url) { + target->controller().LoadURL( + params->url, params->referrer, params->transition); + } + // The navigation should re-select an existing tab in the target Browser. params->browser->SelectTabContentsAt(singleton_index, user_initiated); } else { |