summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-29 04:41:37 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-29 04:41:37 +0000
commitf381dfa196a8da9382ff6c4b109216b5d166c148 (patch)
treedc19827a840a509c5b539fdfe2507c54a9078647 /chrome
parent3dfc679fda6844272230056dddef10626abf068c (diff)
downloadchromium_src-f381dfa196a8da9382ff6c4b109216b5d166c148.zip
chromium_src-f381dfa196a8da9382ff6c4b109216b5d166c148.tar.gz
chromium_src-f381dfa196a8da9382ff6c4b109216b5d166c148.tar.bz2
Re-land 45894. http://codereview.chromium.org/1732015
TBR=erikkay@chromium.org Review URL: http://codereview.chromium.org/1705012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45914 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.cc80
-rw-r--r--chrome/browser/browser.h15
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.