Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: chrome/browser/tab_contents/navigation_controller.cc

Issue 115919: Consider an immediate redirect as machine-initiated and slow one as... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/tab_contents/navigation_controller.h" 5 #include "chrome/browser/tab_contents/navigation_controller.h"
6 6
7 #include "app/resource_bundle.h" 7 #include "app/resource_bundle.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 bool AreURLsInPageNavigation(const GURL& existing_url, const GURL& new_url) { 83 bool AreURLsInPageNavigation(const GURL& existing_url, const GURL& new_url) {
84 if (existing_url == new_url || !new_url.has_ref()) 84 if (existing_url == new_url || !new_url.has_ref())
85 return false; 85 return false;
86 86
87 url_canon::Replacements<char> replacements; 87 url_canon::Replacements<char> replacements;
88 replacements.ClearRef(); 88 replacements.ClearRef();
89 return existing_url.ReplaceComponents(replacements) == 89 return existing_url.ReplaceComponents(replacements) ==
90 new_url.ReplaceComponents(replacements); 90 new_url.ReplaceComponents(replacements);
91 } 91 }
92 92
93 // Navigation within this limit since the last document load is considered to
94 // be automatic (i.e., machine-initiated) rather than user-initiated unless
95 // a user gesture has been observed.
96 const base::TimeDelta kMaxAutoNavigationTimeDelta =
97 base::TimeDelta::FromSeconds(5);
98
93 } // namespace 99 } // namespace
94 100
95 // NavigationController --------------------------------------------------- 101 // NavigationController ---------------------------------------------------
96 102
97 // static 103 // static
98 size_t NavigationController::max_entry_count_ = 50; 104 size_t NavigationController::max_entry_count_ = 50;
99 105
100 // static 106 // static
101 bool NavigationController::check_for_repost_ = true; 107 bool NavigationController::check_for_repost_ = true;
102 108
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 423
418 const SkBitmap& NavigationController::GetLazyFavIcon() const { 424 const SkBitmap& NavigationController::GetLazyFavIcon() const {
419 if (pending_entry_) { 425 if (pending_entry_) {
420 return pending_entry_->favicon().bitmap(); 426 return pending_entry_->favicon().bitmap();
421 } else { 427 } else {
422 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); 428 ResourceBundle &rb = ResourceBundle::GetSharedInstance();
423 return *rb.GetBitmapNamed(IDR_DEFAULT_FAVICON); 429 return *rb.GetBitmapNamed(IDR_DEFAULT_FAVICON);
424 } 430 }
425 } 431 }
426 432
433 void NavigationController::DocumentLoadedInFrame() {
434 last_document_loaded_ = base::TimeTicks::Now();
435 }
436
437 void NavigationController::OnUserGesture() {
438 user_gesture_observed_ = true;
439 }
440
427 bool NavigationController::RendererDidNavigate( 441 bool NavigationController::RendererDidNavigate(
428 const ViewHostMsg_FrameNavigate_Params& params, 442 const ViewHostMsg_FrameNavigate_Params& params,
429 LoadCommittedDetails* details) { 443 LoadCommittedDetails* details) {
430 // Save the previous state before we clobber it. 444 // Save the previous state before we clobber it.
431 if (GetLastCommittedEntry()) { 445 if (GetLastCommittedEntry()) {
432 details->previous_url = GetLastCommittedEntry()->url(); 446 details->previous_url = GetLastCommittedEntry()->url();
433 details->previous_entry_index = last_committed_entry_index(); 447 details->previous_entry_index = last_committed_entry_index();
434 } else { 448 } else {
435 details->previous_url = GURL(); 449 details->previous_url = GURL();
436 details->previous_entry_index = -1; 450 details->previous_entry_index = -1;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 512
499 // Now prep the rest of the details for the notification and broadcast. 513 // Now prep the rest of the details for the notification and broadcast.
500 details->entry = GetActiveEntry(); 514 details->entry = GetActiveEntry();
501 details->is_in_page = IsURLInPageNavigation(params.url); 515 details->is_in_page = IsURLInPageNavigation(params.url);
502 details->is_main_frame = PageTransition::IsMainFrame(params.transition); 516 details->is_main_frame = PageTransition::IsMainFrame(params.transition);
503 details->serialized_security_info = params.security_info; 517 details->serialized_security_info = params.security_info;
504 details->is_content_filtered = params.is_content_filtered; 518 details->is_content_filtered = params.is_content_filtered;
505 details->http_status_code = params.http_status_code; 519 details->http_status_code = params.http_status_code;
506 NotifyNavigationEntryCommitted(details); 520 NotifyNavigationEntryCommitted(details);
507 521
522 user_gesture_observed_ = false;
523
508 return true; 524 return true;
509 } 525 }
510 526
511 NavigationType::Type NavigationController::ClassifyNavigation( 527 NavigationType::Type NavigationController::ClassifyNavigation(
512 const ViewHostMsg_FrameNavigate_Params& params) const { 528 const ViewHostMsg_FrameNavigate_Params& params) const {
513 // If a page makes a popup navigated to about blank, and then writes stuff 529 // If a page makes a popup navigated to about blank, and then writes stuff
514 // like a subframe navigated to a real site, we'll get a notification with an 530 // like a subframe navigated to a real site, we'll get a notification with an
515 // invalid page ID. There's nothing we can do with these, so just ignore them. 531 // invalid page ID. There's nothing we can do with these, so just ignore them.
516 if (params.page_id == -1) { 532 if (params.page_id == -1) {
517 DCHECK(!GetActiveEntry()) << "Got an invalid page ID but we seem to be " 533 DCHECK(!GetActiveEntry()) << "Got an invalid page ID but we seem to be "
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 // navigations that don't actually navigate, but it can happen when there is 594 // navigations that don't actually navigate, but it can happen when there is
579 // an encoding override (it always sends a navigation request). 595 // an encoding override (it always sends a navigation request).
580 if (AreURLsInPageNavigation(existing_entry->url(), params.url)) 596 if (AreURLsInPageNavigation(existing_entry->url(), params.url))
581 return NavigationType::IN_PAGE; 597 return NavigationType::IN_PAGE;
582 598
583 // Since we weeded out "new" navigations above, we know this is an existing 599 // Since we weeded out "new" navigations above, we know this is an existing
584 // (back/forward) navigation. 600 // (back/forward) navigation.
585 return NavigationType::EXISTING_PAGE; 601 return NavigationType::EXISTING_PAGE;
586 } 602 }
587 603
604 bool NavigationController::IsRedirect(
605 const ViewHostMsg_FrameNavigate_Params& params) {
606 // For main frame transition, we judge by params.transition.
607 // Otherwise, by params.redirects.
608 if (PageTransition::IsMainFrame(params.transition)) {
609 return PageTransition::IsRedirect(params.transition);
610 }
611 return params.redirects.size() > 1;
612 }
613
614 bool NavigationController::IsLikelyAutoNavigation(base::TimeTicks now) {
615 return !user_gesture_observed_ &&
616 (now - last_document_loaded_) < kMaxAutoNavigationTimeDelta;
617 }
618
588 void NavigationController::RendererDidNavigateToNewPage( 619 void NavigationController::RendererDidNavigateToNewPage(
589 const ViewHostMsg_FrameNavigate_Params& params) { 620 const ViewHostMsg_FrameNavigate_Params& params) {
590 NavigationEntry* new_entry; 621 NavigationEntry* new_entry;
591 if (pending_entry_) { 622 if (pending_entry_) {
592 // TODO(brettw) this assumes that the pending entry is appropriate for the 623 // TODO(brettw) this assumes that the pending entry is appropriate for the
593 // new page that was just loaded. I don't think this is necessarily the 624 // new page that was just loaded. I don't think this is necessarily the
594 // case! We should have some more tracking to know for sure. This goes along 625 // case! We should have some more tracking to know for sure. This goes along
595 // with a similar TODO at the top of RendererDidNavigate where we blindly 626 // with a similar TODO at the top of RendererDidNavigate where we blindly
596 // set the site instance on the pending entry. 627 // set the site instance on the pending entry.
597 new_entry = new NavigationEntry(*pending_entry_); 628 new_entry = new NavigationEntry(*pending_entry_);
598 629
599 // Don't use the page type from the pending entry. Some interstitial page 630 // Don't use the page type from the pending entry. Some interstitial page
600 // may have set the type to interstitial. Once we commit, however, the page 631 // may have set the type to interstitial. Once we commit, however, the page
601 // type must always be normal. 632 // type must always be normal.
602 new_entry->set_page_type(NavigationEntry::NORMAL_PAGE); 633 new_entry->set_page_type(NavigationEntry::NORMAL_PAGE);
603 } else { 634 } else {
604 new_entry = new NavigationEntry; 635 new_entry = new NavigationEntry;
605 } 636 }
606 637
607 new_entry->set_url(params.url); 638 new_entry->set_url(params.url);
608 new_entry->set_referrer(params.referrer); 639 new_entry->set_referrer(params.referrer);
609 new_entry->set_page_id(params.page_id); 640 new_entry->set_page_id(params.page_id);
610 new_entry->set_transition_type(params.transition); 641 new_entry->set_transition_type(params.transition);
611 new_entry->set_site_instance(tab_contents_->GetSiteInstance()); 642 new_entry->set_site_instance(tab_contents_->GetSiteInstance());
612 new_entry->set_has_post_data(params.is_post); 643 new_entry->set_has_post_data(params.is_post);
613 644
614 // If the current entry is a redirection source, it needs to be replaced with 645 // If the current entry is a redirection source and the redirection has
615 // the new entry to avoid unwanted redirections in navigating backward / 646 // occurred within kMaxAutoNavigationTimeDelta since the last document load,
616 // forward. Otherwise, just insert the new entry. 647 // this is likely to be machine-initiated redirect and the entry needs to be
648 // replaced with the new entry to avoid unwanted redirections in navigating
649 // backward/forward.
650 // Otherwise, just insert the new entry.
617 InsertOrReplaceEntry(new_entry, 651 InsertOrReplaceEntry(new_entry,
618 PageTransition::IsRedirect(new_entry->transition_type())); 652 IsRedirect(params) && IsLikelyAutoNavigation(base::TimeTicks::Now()));
619 } 653 }
620 654
621 void NavigationController::RendererDidNavigateToExistingPage( 655 void NavigationController::RendererDidNavigateToExistingPage(
622 const ViewHostMsg_FrameNavigate_Params& params) { 656 const ViewHostMsg_FrameNavigate_Params& params) {
623 // We should only get here for main frame navigations. 657 // We should only get here for main frame navigations.
624 DCHECK(PageTransition::IsMainFrame(params.transition)); 658 DCHECK(PageTransition::IsMainFrame(params.transition));
625 659
626 // This is a back/forward navigation. The existing page for the ID is 660 // This is a back/forward navigation. The existing page for the ID is
627 // guaranteed to exist by ClassifyNavigation, and we just need to update it 661 // guaranteed to exist by ClassifyNavigation, and we just need to update it
628 // with new information from the renderer. 662 // with new information from the renderer.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 NavigationEntry* existing_entry = GetEntryWithPageID( 714 NavigationEntry* existing_entry = GetEntryWithPageID(
681 tab_contents_->GetSiteInstance(), 715 tab_contents_->GetSiteInstance(),
682 params.page_id); 716 params.page_id);
683 717
684 // Reference fragment navigation. We're guaranteed to have the last_committed 718 // Reference fragment navigation. We're guaranteed to have the last_committed
685 // entry and it will be the same page as the new navigation (minus the 719 // entry and it will be the same page as the new navigation (minus the
686 // reference fragments, of course). 720 // reference fragments, of course).
687 NavigationEntry* new_entry = new NavigationEntry(*existing_entry); 721 NavigationEntry* new_entry = new NavigationEntry(*existing_entry);
688 new_entry->set_page_id(params.page_id); 722 new_entry->set_page_id(params.page_id);
689 new_entry->set_url(params.url); 723 new_entry->set_url(params.url);
690 InsertOrReplaceEntry(new_entry, false); 724 InsertOrReplaceEntry(new_entry,
725 IsRedirect(params) && IsLikelyAutoNavigation(base::TimeTicks::Now()));
691 } 726 }
692 727
693 void NavigationController::RendererDidNavigateNewSubframe( 728 void NavigationController::RendererDidNavigateNewSubframe(
694 const ViewHostMsg_FrameNavigate_Params& params) { 729 const ViewHostMsg_FrameNavigate_Params& params) {
730 if (PageTransition::StripQualifier(params.transition) ==
731 PageTransition::AUTO_SUBFRAME) {
732 // This is not user-initiated. Ignore.
733 return;
734 }
735 if (IsRedirect(params)) {
736 // This is redirect. Ignore.
737 return;
738 }
739
695 // Manual subframe navigations just get the current entry cloned so the user 740 // Manual subframe navigations just get the current entry cloned so the user
696 // can go back or forward to it. The actual subframe information will be 741 // can go back or forward to it. The actual subframe information will be
697 // stored in the page state for each of those entries. This happens out of 742 // stored in the page state for each of those entries. This happens out of
698 // band with the actual navigations. 743 // band with the actual navigations.
699 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " 744 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee "
700 << "that a last committed entry exists."; 745 << "that a last committed entry exists.";
701 NavigationEntry* new_entry = new NavigationEntry(*GetLastCommittedEntry()); 746 NavigationEntry* new_entry = new NavigationEntry(*GetLastCommittedEntry());
702 new_entry->set_page_id(params.page_id); 747 new_entry->set_page_id(params.page_id);
703 InsertOrReplaceEntry(new_entry, false); 748 InsertOrReplaceEntry(new_entry, false);
704 } 749 }
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 return i; 1019 return i;
975 } 1020 }
976 return -1; 1021 return -1;
977 } 1022 }
978 1023
979 NavigationEntry* NavigationController::GetTransientEntry() const { 1024 NavigationEntry* NavigationController::GetTransientEntry() const {
980 if (transient_entry_index_ == -1) 1025 if (transient_entry_index_ == -1)
981 return NULL; 1026 return NULL;
982 return entries_[transient_entry_index_].get(); 1027 return entries_[transient_entry_index_].get();
983 } 1028 }
OLDNEW
« no previous file with comments | « chrome/browser/tab_contents/navigation_controller.h ('k') | chrome/browser/tab_contents/tab_contents.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698