diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser.cc | 80 | ||||
-rw-r--r-- | chrome/browser/browser.h | 15 |
2 files changed, 91 insertions, 4 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 0dd870c..11c0c83 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -448,7 +448,17 @@ TabContents* Browser::OpenApplicationWindow( Profile* profile, Extension* extension, Extension::LaunchContainer container, - const GURL& url) { + const GURL& url_input) { + GURL url; + if (!url_input.is_empty()) { + if (extension) + DCHECK(extension->web_extent().ContainsURL(url_input)); + url = url_input; + } else { + DCHECK(extension); + url = extension->GetFullLaunchURL(); + } + // TODO(erikkay) this can't be correct for extensions std::wstring app_name = web_app::GenerateApplicationNameFromURL(url); RegisterAppPrefs(app_name); @@ -456,9 +466,8 @@ TabContents* Browser::OpenApplicationWindow( bool as_panel = extension && (container == Extension::LAUNCH_PANEL); Browser* browser = Browser::CreateForApp(app_name, extension, profile, as_panel); - browser->AddTabWithURL(extension ? extension->GetFullLaunchURL() : url, - GURL(), PageTransition::START_PAGE, - -1, Browser::ADD_SELECTED, NULL, std::string()); + browser->AddTabWithURL(url, GURL(), PageTransition::START_PAGE, true, -1, + false, NULL); TabContents* tab_contents = browser->GetSelectedTabContents(); tab_contents->GetMutableRendererPrefs()->can_accept_load_drops = false; @@ -3371,6 +3380,58 @@ Browser* Browser::GetOrCreateTabbedBrowser(Profile* profile) { return browser; } +bool Browser::HandleCrossAppNavigation(TabContents* source, + const GURL& url, + const GURL& referrer, + WindowOpenDisposition disposition, + PageTransition::Type transition) { + // Can be null in unit tests. + ExtensionsService* service = profile_->GetExtensionsService(); + if (!service) + return false; + + // Get the destination URL's extension, if any. + Extension* extension = service->GetExtensionByURL(url); + if (!extension) + extension = service->GetExtensionByWebExtent(url); + + if (extension) { + // If we're navigating to the same extension, do nothing. + if (extension == extension_app_) + return false; + + // If there's already a window for the destination extension, open the URL + // there. + for (BrowserList::const_iterator iter = BrowserList::begin(); + iter != BrowserList::end(); ++iter) { + if (extension == (*iter)->extension_app()) { + (*iter)->OpenURL(url, referrer, NEW_FOREGROUND_TAB, transition); + return true; + } + } + + // If the extension wants to be opened in a window, but there is no + // existing window, create one, then open the URL there. + if (extension->launch_container() == Extension::LAUNCH_WINDOW) { + Browser::OpenApplicationWindow(profile_, extension, + Extension::LAUNCH_WINDOW, url); + return true; + } + } + + // If the current browser is for an extension, then the destination URL must + // not be for that extension (otherwise, we would have caught it above). So + // find a normal browser and open the URL there. + if (extension_app_) { + Browser* browser = GetOrCreateTabbedBrowser(profile_); + browser->OpenURL(url, referrer, NEW_FOREGROUND_TAB, transition); + browser->window()->Show(); + return true; + } + + return false; +} + void Browser::OpenURLAtIndex(TabContents* source, const GURL& url, const GURL& referrer, @@ -3398,6 +3459,17 @@ void Browser::OpenURLAtIndex(TabContents* source, delegate->OnUserGesture(); } + if (HandleCrossAppNavigation(current_tab, url, referrer, disposition, + transition)) { + // If the source tab was brand new, we can be left with an empty tab which + // looks ugly. Close it. It is still kinda ugly to have a tab flash visible + // for a second, then disappear. But I think it is better than having a + // dead tab just hang around. + if (source->controller().entry_count() == 0) + CloseTabContents(source); + return; + } + // If the URL is part of the same web site, then load it in the same // SiteInstance (and thus the same process). This is an optimization to // reduce process overhead; it is not necessary for compatibility. (That is, diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 3b1eaf4..65eb214 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -801,6 +801,21 @@ class Browser : public TabStripModelDelegate, // Assorted utility functions /////////////////////////////////////////////// + // Checks whether |source| is about to navigate across extension extents, and + // if so, navigates in the correct window. For example if this is a normal + // browser and we're about to navigate into an extent, this method will + // navigate the app's window instead. If we're in an app window and + // navigating out of the app, this method will find and navigate a normal + // browser instead. + // + // Returns true if the navigation was handled, eg, it was opened in some other + // browser. Returns false if it was not handled. + bool HandleCrossAppNavigation(TabContents* source, + const GURL& url, + const GURL& referrer, + WindowOpenDisposition disposition, + PageTransition::Type transition); + // The low-level function that other OpenURL...() functions call. This // determines the appropriate SiteInstance to pass to AddTabWithURL(), focuses // the newly created tab as needed, and does other miscellaneous housekeeping. |