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 |