| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/browser_navigator.h" | 5 #include "chrome/browser/browser_navigator.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "chrome/browser/browser.h" | 8 #include "chrome/browser/browser.h" |
| 9 #include "chrome/browser/browser_list.h" | 9 #include "chrome/browser/browser_list.h" |
| 10 #include "chrome/browser/browser_url_handler.h" | 10 #include "chrome/browser/browser_url_handler.h" |
| 11 #include "chrome/browser/browser_window.h" | 11 #include "chrome/browser/browser_window.h" |
| 12 #include "chrome/browser/location_bar.h" | 12 #include "chrome/browser/location_bar.h" |
| 13 #include "chrome/browser/profile.h" | 13 #include "chrome/browser/profile.h" |
| 14 #include "chrome/browser/renderer_host/site_instance.h" | 14 #include "chrome/browser/renderer_host/site_instance.h" |
| 15 #include "chrome/browser/status_bubble.h" | 15 #include "chrome/browser/status_bubble.h" |
| 16 #include "chrome/browser/tabs/tab_strip_model.h" | 16 #include "chrome/browser/tabs/tab_strip_model.h" |
| 17 #include "chrome/browser/tab_contents/tab_contents.h" | 17 #include "chrome/browser/tab_contents/tab_contents.h" |
| 18 #include "chrome/common/chrome_switches.h" | 18 #include "chrome/common/chrome_switches.h" |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 // Returns the SiteInstance for |source_contents| if it represents the same | 22 // Returns the SiteInstance for |source_contents| if it represents the same |
| 23 // website as |url|, or NULL otherwise. |source_contents| cannot be NULL. | 23 // website as |url|, or NULL otherwise. |source_contents| cannot be NULL. |
| 24 SiteInstance* GetSiteInstance(TabContents* source_contents, const GURL& url) { | 24 SiteInstance* GetSiteInstance(TabContents* source_contents, const GURL& url) { |
| 25 if (!source_contents) |
| 26 return NULL; |
| 27 |
| 25 // Don't use this logic when "--process-per-tab" is specified. | 28 // Don't use this logic when "--process-per-tab" is specified. |
| 26 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab) && | 29 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab) && |
| 27 SiteInstance::IsSameWebSite(source_contents->profile(), | 30 SiteInstance::IsSameWebSite(source_contents->profile(), |
| 28 source_contents->GetURL(), | 31 source_contents->GetURL(), |
| 29 url)) { | 32 url)) { |
| 30 return source_contents->GetSiteInstance(); | 33 return source_contents->GetSiteInstance(); |
| 31 } | 34 } |
| 32 return NULL; | 35 return NULL; |
| 33 } | 36 } |
| 34 | 37 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 NOTREACHED(); | 145 NOTREACHED(); |
| 143 } | 146 } |
| 144 return NULL; | 147 return NULL; |
| 145 } | 148 } |
| 146 | 149 |
| 147 // Fix disposition and other parameter values depending on prevailing | 150 // Fix disposition and other parameter values depending on prevailing |
| 148 // conditions. | 151 // conditions. |
| 149 void NormalizeDisposition(browser::NavigateParams* params) { | 152 void NormalizeDisposition(browser::NavigateParams* params) { |
| 150 // Calculate the WindowOpenDisposition if necessary. | 153 // Calculate the WindowOpenDisposition if necessary. |
| 151 if (params->browser->tabstrip_model()->empty() && | 154 if (params->browser->tabstrip_model()->empty() && |
| 152 params->disposition == NEW_BACKGROUND_TAB) { | 155 (params->disposition == NEW_BACKGROUND_TAB || |
| 156 params->disposition == CURRENT_TAB)) { |
| 153 params->disposition = NEW_FOREGROUND_TAB; | 157 params->disposition = NEW_FOREGROUND_TAB; |
| 154 } | 158 } |
| 155 if (params->browser->profile()->IsOffTheRecord() && | 159 if (params->browser->profile()->IsOffTheRecord() && |
| 156 params->disposition == OFF_THE_RECORD) { | 160 params->disposition == OFF_THE_RECORD) { |
| 157 params->disposition = NEW_FOREGROUND_TAB; | 161 params->disposition = NEW_FOREGROUND_TAB; |
| 158 } | 162 } |
| 159 | 163 |
| 160 // Disposition trumps add types. ADD_SELECTED is a default, so we need to | 164 // Disposition trumps add types. ADD_SELECTED is a default, so we need to |
| 161 // remove it if disposition implies the tab is going to open in the | 165 // remove it if disposition implies the tab is going to open in the |
| 162 // background. | 166 // background. |
| 163 if (params->disposition == NEW_BACKGROUND_TAB) | 167 if (params->disposition == NEW_BACKGROUND_TAB) |
| 164 params->tabstrip_add_types &= ~TabStripModel::ADD_SELECTED; | 168 params->tabstrip_add_types &= ~TabStripModel::ADD_SELECTED; |
| 169 |
| 170 // Code that wants to open a new window typically expects it to be shown |
| 171 // automatically. |
| 172 if (params->disposition == NEW_WINDOW || params->disposition == NEW_POPUP) { |
| 173 params->show_window = true; |
| 174 params->tabstrip_add_types |= TabStripModel::ADD_SELECTED; |
| 175 } |
| 165 } | 176 } |
| 166 | 177 |
| 167 // This class makes sure the Browser object held in |params| is made visible | 178 // This class makes sure the Browser object held in |params| is made visible |
| 168 // by the time it goes out of scope, provided |params| wants it to be shown. | 179 // by the time it goes out of scope, provided |params| wants it to be shown. |
| 169 class ScopedBrowserDisplayer { | 180 class ScopedBrowserDisplayer { |
| 170 public: | 181 public: |
| 171 explicit ScopedBrowserDisplayer(browser::NavigateParams* params) | 182 explicit ScopedBrowserDisplayer(browser::NavigateParams* params) |
| 172 : params_(params) { | 183 : params_(params) { |
| 173 } | 184 } |
| 174 ~ScopedBrowserDisplayer() { | 185 ~ScopedBrowserDisplayer() { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 // Make sure the Browser is shown if params call for it. | 270 // Make sure the Browser is shown if params call for it. |
| 260 ScopedBrowserDisplayer displayer(params); | 271 ScopedBrowserDisplayer displayer(params); |
| 261 | 272 |
| 262 // Makes sure any TabContents created by this function is destroyed if | 273 // Makes sure any TabContents created by this function is destroyed if |
| 263 // not properly added to a tab strip. | 274 // not properly added to a tab strip. |
| 264 ScopedTargetContentsOwner target_contents_owner(params); | 275 ScopedTargetContentsOwner target_contents_owner(params); |
| 265 | 276 |
| 266 // Some dispositions need coercion to base types. | 277 // Some dispositions need coercion to base types. |
| 267 NormalizeDisposition(params); | 278 NormalizeDisposition(params); |
| 268 | 279 |
| 280 // Determine if the navigation was user initiated. If it was, we need to |
| 281 // inform the target TabContents, and we may need to update the UI. |
| 282 PageTransition::Type base_transition = |
| 283 PageTransition::StripQualifier(params->transition); |
| 284 bool user_initiated = base_transition == PageTransition::TYPED || |
| 285 base_transition == PageTransition::AUTO_BOOKMARK; |
| 286 |
| 269 // If no target TabContents was specified, we need to construct one if we are | 287 // If no target TabContents was specified, we need to construct one if we are |
| 270 // supposed to target a new tab. | 288 // supposed to target a new tab. |
| 271 if (!params->target_contents) { | 289 if (!params->target_contents) { |
| 272 if (params->disposition != CURRENT_TAB) { | 290 if (params->disposition != CURRENT_TAB) { |
| 273 params->target_contents = | 291 params->target_contents = |
| 274 new TabContents(params->browser->profile(), | 292 new TabContents(params->browser->profile(), |
| 275 GetSiteInstance(params->source_contents, params->url), | 293 GetSiteInstance(params->source_contents, params->url), |
| 276 MSG_ROUTING_NONE, | 294 MSG_ROUTING_NONE, |
| 277 params->source_contents, | 295 params->source_contents, |
| 278 NULL); | 296 NULL); |
| 279 // This function takes ownership of |params->target_contents| until it | 297 // This function takes ownership of |params->target_contents| until it |
| 280 // is added to a TabStripModel. | 298 // is added to a TabStripModel. |
| 281 target_contents_owner.TakeOwnership(); | 299 target_contents_owner.TakeOwnership(); |
| 282 params->target_contents->SetExtensionAppById(params->extension_app_id); | 300 params->target_contents->SetExtensionAppById(params->extension_app_id); |
| 283 // TODO(sky): figure out why this is needed. Without it we seem to get | 301 // TODO(sky): figure out why this is needed. Without it we seem to get |
| 284 // failures in startup tests. | 302 // failures in startup tests. |
| 285 // By default, content believes it is not hidden. When adding contents | 303 // By default, content believes it is not hidden. When adding contents |
| 286 // in the background, tell it that it's hidden. | 304 // in the background, tell it that it's hidden. |
| 287 if ((params->tabstrip_add_types & TabStripModel::ADD_SELECTED) == 0) { | 305 if ((params->tabstrip_add_types & TabStripModel::ADD_SELECTED) == 0) { |
| 288 // TabStripModel::AddTabContents invokes HideContents if not foreground. | 306 // TabStripModel::AddTabContents invokes HideContents if not foreground. |
| 289 params->target_contents->WasHidden(); | 307 params->target_contents->WasHidden(); |
| 290 } | 308 } |
| 291 } else { | 309 } else { |
| 292 // ... otherwise if we're loading in the current tab, the target is the | 310 // ... otherwise if we're loading in the current tab, the target is the |
| 293 // same as the source. | 311 // same as the source. |
| 294 params->target_contents = params->source_contents; | 312 params->target_contents = params->source_contents; |
| 295 } | 313 } |
| 314 |
| 315 if (user_initiated) { |
| 316 RenderViewHostDelegate::BrowserIntegration* integration = |
| 317 params->target_contents; |
| 318 integration->OnUserGesture(); |
| 319 } |
| 320 |
| 321 // Perform the actual navigation. |
| 322 GURL url = params->url.is_empty() ? params->browser->GetHomePage() |
| 323 : params->url; |
| 324 params->target_contents->controller().LoadURL(url, params->referrer, |
| 325 params->transition); |
| 326 } else { |
| 327 // |target_contents| was specified non-NULL, and so we assume it has already |
| 328 // been navigated appropriately. We need to do nothing more other than |
| 329 // add it to the appropriate tabstrip. |
| 296 } | 330 } |
| 297 | 331 |
| 298 // Determine if the navigation was user initiated. If it was, we need to | |
| 299 // inform the target TabContents, and we may need to update the UI. | |
| 300 PageTransition::Type base_transition = | |
| 301 PageTransition::StripQualifier(params->transition); | |
| 302 bool user_initiated = base_transition == PageTransition::TYPED || | |
| 303 base_transition == PageTransition::AUTO_BOOKMARK; | |
| 304 if (user_initiated) { | |
| 305 RenderViewHostDelegate::BrowserIntegration* integration = | |
| 306 params->target_contents; | |
| 307 integration->OnUserGesture(); | |
| 308 } | |
| 309 | |
| 310 // Perform the actual navigation. | |
| 311 GURL url = params->url.is_empty() ? params->browser->GetHomePage() | |
| 312 : params->url; | |
| 313 params->target_contents->controller().LoadURL(url, params->referrer, | |
| 314 params->transition); | |
| 315 | |
| 316 if (params->source_contents == params->target_contents) { | 332 if (params->source_contents == params->target_contents) { |
| 317 // The navigation occurred in the source tab, so update the UI. | 333 // The navigation occurred in the source tab, so update the UI. |
| 318 params->browser->UpdateUIForNavigationInTab(params->target_contents, | 334 params->browser->UpdateUIForNavigationInTab(params->target_contents, |
| 319 params->transition, | 335 params->transition, |
| 320 user_initiated); | 336 user_initiated); |
| 321 } else { | 337 } else { |
| 322 // The navigation occurred in some other tab. | 338 // The navigation occurred in some other tab. |
| 323 int singleton_index = GetIndexOfSingletonTab(params); | 339 int singleton_index = GetIndexOfSingletonTab(params); |
| 324 if (params->disposition == SINGLETON_TAB && singleton_index >= 0) { | 340 if (params->disposition == SINGLETON_TAB && singleton_index >= 0) { |
| 325 // The navigation should re-select an existing tab in the target Browser. | 341 // The navigation should re-select an existing tab in the target Browser. |
| 326 params->browser->SelectTabContentsAt(singleton_index, user_initiated); | 342 params->browser->SelectTabContentsAt(singleton_index, user_initiated); |
| 327 } else { | 343 } else { |
| 344 // If some non-default value is set for the index, we should tell the |
| 345 // TabStripModel to respect it. |
| 346 if (params->tabstrip_index != -1) |
| 347 params->tabstrip_add_types |= TabStripModel::ADD_FORCE_INDEX; |
| 348 |
| 328 // The navigation should insert a new tab into the target Browser. | 349 // The navigation should insert a new tab into the target Browser. |
| 329 params->browser->tabstrip_model()->AddTabContents( | 350 params->browser->tabstrip_model()->AddTabContents( |
| 330 params->target_contents, | 351 params->target_contents, |
| 331 params->tabstrip_index, | 352 params->tabstrip_index, |
| 332 params->transition, | 353 params->transition, |
| 333 params->tabstrip_add_types); | 354 params->tabstrip_add_types); |
| 334 // Now that the |params->target_contents| is safely owned by the target | 355 // Now that the |params->target_contents| is safely owned by the target |
| 335 // Browser's TabStripModel, we can release ownership. | 356 // Browser's TabStripModel, we can release ownership. |
| 336 target_contents_owner.ReleaseOwnership(); | 357 target_contents_owner.ReleaseOwnership(); |
| 337 } | 358 } |
| 338 } | 359 } |
| 339 } | 360 } |
| 340 | 361 |
| 341 } // namespace browser | 362 } // namespace browser |
| 342 | 363 |
| OLD | NEW |