diff options
Diffstat (limited to 'chrome/browser/browser_navigator.cc')
-rw-r--r-- | chrome/browser/browser_navigator.cc | 84 |
1 files changed, 66 insertions, 18 deletions
diff --git a/chrome/browser/browser_navigator.cc b/chrome/browser/browser_navigator.cc index e34bcba..2950d1f 100644 --- a/chrome/browser/browser_navigator.cc +++ b/chrome/browser/browser_navigator.cc @@ -7,6 +7,7 @@ #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" #include "chrome/browser/location_bar.h" #include "chrome/browser/profile.h" @@ -48,6 +49,48 @@ 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) { + 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; +} + +// Returns the index of an existing singleton tab in |params->browser| matching +// the URL specified in |params|. +int GetIndexOfSingletonTab(browser::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; + BrowserURLHandler::RewriteURLIfNecessary(&rewritten_url, + params->browser->profile(), + &reverse_on_redirect); + + 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)) { + params->target_contents = tab; + return i; + } + } + return -1; +} + // 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. @@ -207,8 +250,7 @@ NavigateParams::NavigateParams(Browser* a_browser, NavigateParams::~NavigateParams() { } -void Navigate(NavigateParams* params, NavigatorDelegate* delegate) { - DCHECK(delegate); +void Navigate(NavigateParams* params) { params->browser = GetBrowserForDisposition(params); if (!params->browser) return; @@ -266,27 +308,33 @@ void Navigate(NavigateParams* params, NavigatorDelegate* delegate) { } // Perform the actual navigation. - GURL url = params->url.is_empty() ? delegate->GetHomePage() : params->url; + GURL url = params->url.is_empty() ? params->browser->GetHomePage() + : params->url; params->target_contents->controller().LoadURL(url, params->referrer, params->transition); - // Update the UI for the navigation. if (params->source_contents == params->target_contents) { - // The navigation occurred in the source tab. - delegate->UpdateUIForNavigationInTab(params->target_contents, - params->transition, - user_initiated); + // The navigation occurred in the source tab, so update the UI. + params->browser->UpdateUIForNavigationInTab(params->target_contents, + params->transition, + user_initiated); } else { - // The navigation occurred in some other tab yet to be added to the - // tabstrip. Add it now. - params->browser->tabstrip_model()->AddTabContents( - params->target_contents, - params->tabstrip_index, - params->transition, - params->tabstrip_add_types); - // Now that the |params->target_contents| is safely owned by the target - // Browser's TabStripModel, we can release ownership. - target_contents_owner.ReleaseOwnership(); + // The navigation occurred in some other tab. + int singleton_index = GetIndexOfSingletonTab(params); + if (params->disposition == SINGLETON_TAB && singleton_index >= 0) { + // The navigation should re-select an existing tab in the target Browser. + params->browser->SelectTabContentsAt(singleton_index, user_initiated); + } else { + // The navigation should insert a new tab into the target Browser. + params->browser->tabstrip_model()->AddTabContents( + params->target_contents, + params->tabstrip_index, + params->transition, + params->tabstrip_add_types); + // Now that the |params->target_contents| is safely owned by the target + // Browser's TabStripModel, we can release ownership. + target_contents_owner.ReleaseOwnership(); + } } } |