OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/frame_host/navigator_impl.h" | 5 #include "content/browser/frame_host/navigator_impl.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "content/browser/frame_host/frame_tree.h" | 10 #include "content/browser/frame_host/frame_tree.h" |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 render_frame_host, url, error_code, | 248 render_frame_host, url, error_code, |
249 error_description, was_ignored_by_handler); | 249 error_description, was_ignored_by_handler); |
250 } | 250 } |
251 } | 251 } |
252 | 252 |
253 bool NavigatorImpl::NavigateToEntry( | 253 bool NavigatorImpl::NavigateToEntry( |
254 FrameTreeNode* frame_tree_node, | 254 FrameTreeNode* frame_tree_node, |
255 const FrameNavigationEntry& frame_entry, | 255 const FrameNavigationEntry& frame_entry, |
256 const NavigationEntryImpl& entry, | 256 const NavigationEntryImpl& entry, |
257 NavigationController::ReloadType reload_type, | 257 NavigationController::ReloadType reload_type, |
258 bool is_same_document_history_load) { | 258 bool is_same_document_history_load, |
259 bool is_pending_entry) { | |
259 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); | 260 TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry"); |
260 | 261 |
261 GURL dest_url = frame_entry.url(); | 262 GURL dest_url = frame_entry.url(); |
262 Referrer dest_referrer = frame_entry.referrer(); | 263 Referrer dest_referrer = frame_entry.referrer(); |
263 if (reload_type == | 264 if (reload_type == |
264 NavigationController::ReloadType::RELOAD_ORIGINAL_REQUEST_URL && | 265 NavigationController::ReloadType::RELOAD_ORIGINAL_REQUEST_URL && |
265 entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { | 266 entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) { |
266 // We may have been redirected when navigating to the current URL. | 267 // We may have been redirected when navigating to the current URL. |
267 // Use the URL the user originally intended to visit, if it's valid and if a | 268 // Use the URL the user originally intended to visit, if it's valid and if a |
268 // POST wasn't involved; the latter case avoids issues with sending data to | 269 // POST wasn't involved; the latter case avoids issues with sending data to |
(...skipping 27 matching lines...) Expand all Loading... | |
296 | 297 |
297 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. | 298 // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. |
298 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 299 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
299 switches::kEnableBrowserSideNavigation)) { | 300 switches::kEnableBrowserSideNavigation)) { |
300 navigation_data_.reset(new NavigationMetricsData(navigation_start, dest_url, | 301 navigation_data_.reset(new NavigationMetricsData(navigation_start, dest_url, |
301 entry.restore_type())); | 302 entry.restore_type())); |
302 RequestNavigation(frame_tree_node, dest_url, dest_referrer, frame_entry, | 303 RequestNavigation(frame_tree_node, dest_url, dest_referrer, frame_entry, |
303 entry, reload_type, is_same_document_history_load, | 304 entry, reload_type, is_same_document_history_load, |
304 navigation_start); | 305 navigation_start); |
305 | 306 |
306 // Notify observers about navigation. | 307 // Notify observers about navigation if this is for the pending entry. |
307 if (delegate_) | 308 if (delegate_ && is_pending_entry) |
308 delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type); | 309 delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type); |
309 | 310 |
310 return true; | 311 return true; |
311 } | 312 } |
312 | 313 |
313 RenderFrameHostImpl* dest_render_frame_host = | 314 RenderFrameHostImpl* dest_render_frame_host = |
314 manager->Navigate(dest_url, frame_entry, entry); | 315 manager->Navigate(dest_url, frame_entry, entry); |
315 if (!dest_render_frame_host) | 316 if (!dest_render_frame_host) |
316 return false; // Unable to create the desired RenderFrameHost. | 317 return false; // Unable to create the desired RenderFrameHost. |
317 | 318 |
318 // Make sure no code called via RFHM::Navigate clears the pending entry. | 319 // Make sure no code called via RFHM::Navigate clears the pending entry. |
319 CHECK_EQ(controller_->GetPendingEntry(), &entry); | 320 if (is_pending_entry) |
321 CHECK_EQ(controller_->GetPendingEntry(), &entry); | |
320 | 322 |
321 // For security, we should never send non-Web-UI URLs to a Web UI renderer. | 323 // For security, we should never send non-Web-UI URLs to a Web UI renderer. |
322 // Double check that here. | 324 // Double check that here. |
323 CheckWebUIRendererDoesNotDisplayNormalURL(dest_render_frame_host, dest_url); | 325 CheckWebUIRendererDoesNotDisplayNormalURL(dest_render_frame_host, dest_url); |
324 | 326 |
325 // Navigate in the desired RenderFrameHost. | 327 // Navigate in the desired RenderFrameHost. |
326 // We can skip this step in the rare case that this is a transfer navigation | 328 // We can skip this step in the rare case that this is a transfer navigation |
327 // which began in the chosen RenderFrameHost, since the request has already | 329 // which began in the chosen RenderFrameHost, since the request has already |
328 // been issued. In that case, simply resume the response. | 330 // been issued. In that case, simply resume the response. |
329 bool is_transfer_to_same = | 331 bool is_transfer_to_same = |
(...skipping 23 matching lines...) Expand all Loading... | |
353 controller_->GetIndexOfEntry(&entry), | 355 controller_->GetIndexOfEntry(&entry), |
354 controller_->GetLastCommittedEntryIndex(), | 356 controller_->GetLastCommittedEntryIndex(), |
355 controller_->GetEntryCount())); | 357 controller_->GetEntryCount())); |
356 } else { | 358 } else { |
357 // No need to navigate again. Just resume the deferred request. | 359 // No need to navigate again. Just resume the deferred request. |
358 dest_render_frame_host->GetProcess()->ResumeDeferredNavigation( | 360 dest_render_frame_host->GetProcess()->ResumeDeferredNavigation( |
359 entry.transferred_global_request_id()); | 361 entry.transferred_global_request_id()); |
360 } | 362 } |
361 | 363 |
362 // Make sure no code called via RFH::Navigate clears the pending entry. | 364 // Make sure no code called via RFH::Navigate clears the pending entry. |
363 CHECK_EQ(controller_->GetPendingEntry(), &entry); | 365 if (is_pending_entry) |
366 CHECK_EQ(controller_->GetPendingEntry(), &entry); | |
364 | 367 |
365 if (controller_->GetPendingEntryIndex() == -1 && | 368 if (controller_->GetPendingEntryIndex() == -1 && |
366 dest_url.SchemeIs(url::kJavaScriptScheme)) { | 369 dest_url.SchemeIs(url::kJavaScriptScheme)) { |
367 // If the pending entry index is -1 (which means a new navigation rather | 370 // If the pending entry index is -1 (which means a new navigation rather |
368 // than a history one), and the user typed in a javascript: URL, don't add | 371 // than a history one), and the user typed in a javascript: URL, don't add |
369 // it to the session history. | 372 // it to the session history. |
370 // | 373 // |
371 // This is a hack. What we really want is to avoid adding to the history any | 374 // This is a hack. What we really want is to avoid adding to the history any |
372 // URL that doesn't generate content, and what would be great would be if we | 375 // URL that doesn't generate content, and what would be great would be if we |
373 // had a message from the renderer telling us that a new page was not | 376 // had a message from the renderer telling us that a new page was not |
374 // created. The same message could be used for mailto: URLs and the like. | 377 // created. The same message could be used for mailto: URLs and the like. |
375 return false; | 378 return false; |
376 } | 379 } |
377 | 380 |
378 // Notify observers about navigation. | 381 // Notify observers about navigation. |
379 if (delegate_) { | 382 if (delegate_ && is_pending_entry) |
380 delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type); | 383 delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type); |
381 } | |
382 | 384 |
383 return true; | 385 return true; |
384 } | 386 } |
385 | 387 |
386 bool NavigatorImpl::NavigateToPendingEntry( | 388 bool NavigatorImpl::NavigateToPendingEntry( |
387 FrameTreeNode* frame_tree_node, | 389 FrameTreeNode* frame_tree_node, |
388 const FrameNavigationEntry& frame_entry, | 390 const FrameNavigationEntry& frame_entry, |
389 NavigationController::ReloadType reload_type, | 391 NavigationController::ReloadType reload_type, |
390 bool is_same_document_history_load) { | 392 bool is_same_document_history_load) { |
391 return NavigateToEntry(frame_tree_node, frame_entry, | 393 return NavigateToEntry(frame_tree_node, frame_entry, |
392 *controller_->GetPendingEntry(), reload_type, | 394 *controller_->GetPendingEntry(), reload_type, |
393 is_same_document_history_load); | 395 is_same_document_history_load, true); |
396 } | |
397 | |
398 void NavigatorImpl::NavigateNewChildFrame( | |
399 RenderFrameHostImpl* render_frame_host, | |
400 const std::string& unique_name) { | |
401 // TODO(creis): Handle the fallback case where frame_entry isn't found, or | |
402 // where NavigateToEntry returns false. | |
403 NavigationEntryImpl* entry = | |
404 controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id()); | |
Avi (use Gerrit)
2015/11/24 22:09:47
Boy, this "last commit" nav entry id is coming in
Charlie Reis
2015/11/24 23:05:54
Right. The renderer sends this IPC when it knows
| |
405 if (!entry) | |
406 return; | |
407 | |
408 FrameNavigationEntry* frame_entry = | |
409 entry->GetFrameEntryByUniqueName(unique_name); | |
410 if (!frame_entry) | |
411 return; | |
412 | |
413 // Update the FNE's FTN ID, since the frame will have a new one. | |
Avi (use Gerrit)
2015/11/24 22:09:47
I didn't understand this comment the first time I
Charlie Reis
2015/11/24 23:05:54
Done.
| |
414 frame_entry->set_frame_tree_node_id( | |
415 render_frame_host->frame_tree_node()->frame_tree_node_id()); | |
416 | |
417 NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry, *entry, | |
418 NavigationControllerImpl::NO_RELOAD, false, false); | |
394 } | 419 } |
395 | 420 |
396 void NavigatorImpl::DidNavigate( | 421 void NavigatorImpl::DidNavigate( |
397 RenderFrameHostImpl* render_frame_host, | 422 RenderFrameHostImpl* render_frame_host, |
398 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 423 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
399 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); | 424 FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); |
400 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); | 425 bool oopifs_possible = SiteIsolationPolicy::AreCrossProcessFramesPossible(); |
401 | 426 |
402 bool is_navigation_within_page = controller_->IsURLInPageNavigation( | 427 bool is_navigation_within_page = controller_->IsURLInPageNavigation( |
403 params.url, params.was_within_same_page, render_frame_host); | 428 params.url, params.was_within_same_page, render_frame_host); |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
954 entry->set_should_replace_entry(pending_entry->should_replace_entry()); | 979 entry->set_should_replace_entry(pending_entry->should_replace_entry()); |
955 entry->SetRedirectChain(pending_entry->GetRedirectChain()); | 980 entry->SetRedirectChain(pending_entry->GetRedirectChain()); |
956 } | 981 } |
957 controller_->SetPendingEntry(entry.Pass()); | 982 controller_->SetPendingEntry(entry.Pass()); |
958 if (delegate_) | 983 if (delegate_) |
959 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); | 984 delegate_->NotifyChangedNavigationState(content::INVALIDATE_TYPE_URL); |
960 } | 985 } |
961 } | 986 } |
962 | 987 |
963 } // namespace content | 988 } // namespace content |
OLD | NEW |