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

Side by Side Diff: content/browser/frame_host/navigation_controller_impl.cc

Issue 2810173002: NavigationController: Fix several broken class invariants. (Closed)
Patch Set: Addressed comments @creis Created 3 years, 7 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
OLDNEW
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 /* 5 /*
6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
9 * (http://www.torchmobile.com/) 9 * (http://www.torchmobile.com/)
10 * 10 *
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 } 272 }
273 273
274 void NavigationControllerImpl::Restore( 274 void NavigationControllerImpl::Restore(
275 int selected_navigation, 275 int selected_navigation,
276 RestoreType type, 276 RestoreType type,
277 std::vector<std::unique_ptr<NavigationEntry>>* entries) { 277 std::vector<std::unique_ptr<NavigationEntry>>* entries) {
278 // Verify that this controller is unused and that the input is valid. 278 // Verify that this controller is unused and that the input is valid.
279 DCHECK(GetEntryCount() == 0 && !GetPendingEntry()); 279 DCHECK(GetEntryCount() == 0 && !GetPendingEntry());
280 DCHECK(selected_navigation >= 0 && 280 DCHECK(selected_navigation >= 0 &&
281 selected_navigation < static_cast<int>(entries->size())); 281 selected_navigation < static_cast<int>(entries->size()));
282 DCHECK_EQ(-1, pending_entry_index_);
282 283
283 needs_reload_ = true; 284 needs_reload_ = true;
284 entries_.reserve(entries->size()); 285 entries_.reserve(entries->size());
285 for (auto& entry : *entries) 286 for (auto& entry : *entries)
286 entries_.push_back( 287 entries_.push_back(
287 NavigationEntryImpl::FromNavigationEntry(std::move(entry))); 288 NavigationEntryImpl::FromNavigationEntry(std::move(entry)));
288 289
289 // At this point, the |entries| is full of empty scoped_ptrs, so it can be 290 // At this point, the |entries| is full of empty scoped_ptrs, so it can be
290 // cleared out safely. 291 // cleared out safely.
291 entries->clear(); 292 entries->clear();
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 NavigationEntryImpl* 441 NavigationEntryImpl*
441 NavigationControllerImpl::GetEntryWithUniqueID(int nav_entry_id) const { 442 NavigationControllerImpl::GetEntryWithUniqueID(int nav_entry_id) const {
442 int index = GetEntryIndexWithUniqueID(nav_entry_id); 443 int index = GetEntryIndexWithUniqueID(nav_entry_id);
443 return (index != -1) ? entries_[index].get() : nullptr; 444 return (index != -1) ? entries_[index].get() : nullptr;
444 } 445 }
445 446
446 void NavigationControllerImpl::LoadEntry( 447 void NavigationControllerImpl::LoadEntry(
447 std::unique_ptr<NavigationEntryImpl> entry) { 448 std::unique_ptr<NavigationEntryImpl> entry) {
448 // Remember the last pending entry for which we haven't received a response 449 // Remember the last pending entry for which we haven't received a response
449 // yet. This will be deleted in the NavigateToPendingEntry() function. 450 // yet. This will be deleted in the NavigateToPendingEntry() function.
451 DCHECK_EQ(nullptr, last_pending_entry_);
452 DCHECK_EQ(-1, last_pending_entry_index_);
450 last_pending_entry_ = pending_entry_; 453 last_pending_entry_ = pending_entry_;
451 last_pending_entry_index_ = pending_entry_index_; 454 last_pending_entry_index_ = pending_entry_index_;
452 last_transient_entry_index_ = transient_entry_index_; 455 last_transient_entry_index_ = transient_entry_index_;
456
453 pending_entry_ = nullptr; 457 pending_entry_ = nullptr;
458 pending_entry_index_ = -1;
454 // When navigating to a new page, we don't know for sure if we will actually 459 // When navigating to a new page, we don't know for sure if we will actually
455 // end up leaving the current page. The new page load could for example 460 // end up leaving the current page. The new page load could for example
456 // result in a download or a 'no content' response (e.g., a mailto: URL). 461 // result in a download or a 'no content' response (e.g., a mailto: URL).
457 SetPendingEntry(std::move(entry)); 462 SetPendingEntry(std::move(entry));
458 NavigateToPendingEntry(ReloadType::NONE); 463 NavigateToPendingEntry(ReloadType::NONE);
459 } 464 }
460 465
461 void NavigationControllerImpl::SetPendingEntry( 466 void NavigationControllerImpl::SetPendingEntry(
462 std::unique_ptr<NavigationEntryImpl> entry) { 467 std::unique_ptr<NavigationEntryImpl> entry) {
463 DiscardNonCommittedEntriesInternal(); 468 DiscardNonCommittedEntriesInternal();
464 pending_entry_ = entry.release(); 469 pending_entry_ = entry.release();
470 DCHECK_EQ(-1, pending_entry_index_);
465 NotificationService::current()->Notify( 471 NotificationService::current()->Notify(
466 NOTIFICATION_NAV_ENTRY_PENDING, 472 NOTIFICATION_NAV_ENTRY_PENDING,
467 Source<NavigationController>(this), 473 Source<NavigationController>(this),
468 Details<NavigationEntry>(pending_entry_)); 474 Details<NavigationEntry>(pending_entry_));
469 } 475 }
470 476
471 NavigationEntryImpl* NavigationControllerImpl::GetActiveEntry() const { 477 NavigationEntryImpl* NavigationControllerImpl::GetActiveEntry() const {
472 if (transient_entry_index_ != -1) 478 if (transient_entry_index_ != -1)
473 return entries_[transient_entry_index_].get(); 479 return entries_[transient_entry_index_].get();
474 if (pending_entry_) 480 if (pending_entry_)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 const std::string& mime_type = delegate_->GetContentsMimeType(); 533 const std::string& mime_type = delegate_->GetContentsMimeType();
528 bool is_viewable_mime_type = 534 bool is_viewable_mime_type =
529 mime_util::IsSupportedNonImageMimeType(mime_type) && 535 mime_util::IsSupportedNonImageMimeType(mime_type) &&
530 !media::IsSupportedMediaMimeType(mime_type); 536 !media::IsSupportedMediaMimeType(mime_type);
531 NavigationEntry* visible_entry = GetVisibleEntry(); 537 NavigationEntry* visible_entry = GetVisibleEntry();
532 return visible_entry && !visible_entry->IsViewSourceMode() && 538 return visible_entry && !visible_entry->IsViewSourceMode() &&
533 is_viewable_mime_type && !delegate_->GetInterstitialPage(); 539 is_viewable_mime_type && !delegate_->GetInterstitialPage();
534 } 540 }
535 541
536 int NavigationControllerImpl::GetLastCommittedEntryIndex() const { 542 int NavigationControllerImpl::GetLastCommittedEntryIndex() const {
543 // The last committed entry index must always be less than the number of
544 // entries. If there is no entries, it must be -1. On the other side, when
Charlie Reis 2017/04/24 17:34:55 nit: s/is/are/
arthursonzogni 2017/04/26 12:13:48 Done.
545 // is is -1, it doesn't always mean that there is no entries. A transient
546 // entry can be inserted before any navigation.
Charlie Reis 2017/04/24 17:34:55 Thanks for clarifying. Let's shorten these last t
arthursonzogni 2017/04/26 12:13:48 Done.
547 DCHECK_LT(last_committed_entry_index_, GetEntryCount());
548 DCHECK(GetEntryCount() || last_committed_entry_index_ == -1);
537 return last_committed_entry_index_; 549 return last_committed_entry_index_;
538 } 550 }
539 551
540 int NavigationControllerImpl::GetEntryCount() const { 552 int NavigationControllerImpl::GetEntryCount() const {
541 DCHECK(entries_.size() <= max_entry_count()); 553 DCHECK_LE(entries_.size(), max_entry_count());
542 return static_cast<int>(entries_.size()); 554 return static_cast<int>(entries_.size());
543 } 555 }
544 556
545 NavigationEntryImpl* NavigationControllerImpl::GetEntryAtIndex( 557 NavigationEntryImpl* NavigationControllerImpl::GetEntryAtIndex(
546 int index) const { 558 int index) const {
547 if (index < 0 || index >= GetEntryCount()) 559 if (index < 0 || index >= GetEntryCount())
548 return nullptr; 560 return nullptr;
549 561
550 return entries_[index].get(); 562 return entries_[index].get();
551 } 563 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 return; 620 return;
609 } 621 }
610 if (index > transient_entry_index_) { 622 if (index > transient_entry_index_) {
611 // Removing the transient is goint to shift all entries by 1. 623 // Removing the transient is goint to shift all entries by 1.
612 index--; 624 index--;
613 } 625 }
614 } 626 }
615 627
616 DiscardNonCommittedEntries(); 628 DiscardNonCommittedEntries();
617 629
630 DCHECK_EQ(nullptr, pending_entry_);
631 DCHECK_EQ(-1, pending_entry_index_);
632 pending_entry_ = entries_[index].get();
618 pending_entry_index_ = index; 633 pending_entry_index_ = index;
619 entries_[pending_entry_index_]->SetTransitionType( 634 pending_entry_->SetTransitionType(ui::PageTransitionFromInt(
620 ui::PageTransitionFromInt( 635 pending_entry_->GetTransitionType() | ui::PAGE_TRANSITION_FORWARD_BACK));
621 entries_[pending_entry_index_]->GetTransitionType() |
622 ui::PAGE_TRANSITION_FORWARD_BACK));
623 NavigateToPendingEntry(ReloadType::NONE); 636 NavigateToPendingEntry(ReloadType::NONE);
624 } 637 }
625 638
626 void NavigationControllerImpl::GoToOffset(int offset) { 639 void NavigationControllerImpl::GoToOffset(int offset) {
627 // Note: This is actually reached in unit tests. 640 // Note: This is actually reached in unit tests.
628 if (!CanGoToOffset(offset)) 641 if (!CanGoToOffset(offset))
629 return; 642 return;
630 643
631 GoToIndex(GetIndexForOffset(offset)); 644 GoToIndex(GetIndexForOffset(offset));
632 } 645 }
(...skipping 1086 matching lines...) Expand 10 before | Expand all | Expand 10 after
1719 DiscardNonCommittedEntriesInternal(); 1732 DiscardNonCommittedEntriesInternal();
1720 1733
1721 // If there was a transient entry, invalidate everything so the new active 1734 // If there was a transient entry, invalidate everything so the new active
1722 // entry state is shown. 1735 // entry state is shown.
1723 if (transient) { 1736 if (transient) {
1724 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL); 1737 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL);
1725 } 1738 }
1726 } 1739 }
1727 1740
1728 NavigationEntryImpl* NavigationControllerImpl::GetPendingEntry() const { 1741 NavigationEntryImpl* NavigationControllerImpl::GetPendingEntry() const {
1742 // If there is no pending_entry_, there should be no pending_entry_index_.
1743 DCHECK(pending_entry_ || pending_entry_index_ == -1);
1744
1745 // If there is a pending_entry_index_, then pending_entry_ must be the entry
1746 // at that index.
1747 DCHECK(pending_entry_index_ == -1 ||
1748 pending_entry_ == GetEntryAtIndex(pending_entry_index_));
1749
1729 return pending_entry_; 1750 return pending_entry_;
1730 } 1751 }
1731 1752
1732 int NavigationControllerImpl::GetPendingEntryIndex() const { 1753 int NavigationControllerImpl::GetPendingEntryIndex() const {
1754 // The pending entry index must always be less than the number of entries.
1755 // If there are no entries, it must be exactly -1.
1756 DCHECK_LT(pending_entry_index_, GetEntryCount());
1757 DCHECK(GetEntryCount() != 0 || pending_entry_index_ == -1);
1733 return pending_entry_index_; 1758 return pending_entry_index_;
1734 } 1759 }
1735 1760
1736 void NavigationControllerImpl::InsertOrReplaceEntry( 1761 void NavigationControllerImpl::InsertOrReplaceEntry(
1737 std::unique_ptr<NavigationEntryImpl> entry, 1762 std::unique_ptr<NavigationEntryImpl> entry,
1738 bool replace) { 1763 bool replace) {
1739 DCHECK(!ui::PageTransitionCoreTypeIs(entry->GetTransitionType(), 1764 DCHECK(!ui::PageTransitionCoreTypeIs(entry->GetTransitionType(),
1740 ui::PAGE_TRANSITION_AUTO_SUBFRAME)); 1765 ui::PAGE_TRANSITION_AUTO_SUBFRAME));
1741 1766
1742 // If the pending_entry_index_ is -1, the navigation was to a new page, and we 1767 // If the pending_entry_index_ is -1, the navigation was to a new page, and we
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1784 void NavigationControllerImpl::PruneOldestEntryIfFull() { 1809 void NavigationControllerImpl::PruneOldestEntryIfFull() {
1785 if (entries_.size() >= max_entry_count()) { 1810 if (entries_.size() >= max_entry_count()) {
1786 DCHECK_EQ(max_entry_count(), entries_.size()); 1811 DCHECK_EQ(max_entry_count(), entries_.size());
1787 DCHECK_GT(last_committed_entry_index_, 0); 1812 DCHECK_GT(last_committed_entry_index_, 0);
1788 RemoveEntryAtIndex(0); 1813 RemoveEntryAtIndex(0);
1789 NotifyPrunedEntries(this, true, 1); 1814 NotifyPrunedEntries(this, true, 1);
1790 } 1815 }
1791 } 1816 }
1792 1817
1793 void NavigationControllerImpl::NavigateToPendingEntry(ReloadType reload_type) { 1818 void NavigationControllerImpl::NavigateToPendingEntry(ReloadType reload_type) {
1819 DCHECK(pending_entry_);
1794 needs_reload_ = false; 1820 needs_reload_ = false;
1795 1821
1796 // If we were navigating to a slow-to-commit page, and the user performs 1822 // If we were navigating to a slow-to-commit page, and the user performs
1797 // a session history navigation to the last committed page, RenderViewHost 1823 // a session history navigation to the last committed page, RenderViewHost
1798 // will force the throbber to start, but WebKit will essentially ignore the 1824 // will force the throbber to start, but WebKit will essentially ignore the
1799 // navigation, and won't send a message to stop the throbber. To prevent this 1825 // navigation, and won't send a message to stop the throbber. To prevent this
1800 // from happening, we drop the navigation here and stop the slow-to-commit 1826 // from happening, we drop the navigation here and stop the slow-to-commit
1801 // page from loading (which would normally happen during the navigation). 1827 // page from loading (which would normally happen during the navigation).
1802 if (pending_entry_index_ != -1 && 1828 if (pending_entry_index_ != -1 &&
1803 pending_entry_index_ == last_committed_entry_index_ && 1829 pending_entry_index_ == last_committed_entry_index_ &&
1804 (entries_[pending_entry_index_]->restore_type() == RestoreType::NONE) && 1830 pending_entry_->restore_type() == RestoreType::NONE &&
1805 (entries_[pending_entry_index_]->GetTransitionType() & 1831 pending_entry_->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK) {
1806 ui::PAGE_TRANSITION_FORWARD_BACK)) {
1807 delegate_->Stop(); 1832 delegate_->Stop();
1808 1833
1809 // If an interstitial page is showing, we want to close it to get back 1834 // If an interstitial page is showing, we want to close it to get back
1810 // to what was showing before. 1835 // to what was showing before.
1811 if (delegate_->GetInterstitialPage()) 1836 if (delegate_->GetInterstitialPage())
1812 delegate_->GetInterstitialPage()->DontProceed(); 1837 delegate_->GetInterstitialPage()->DontProceed();
1813 1838
1814 DiscardNonCommittedEntries(); 1839 DiscardNonCommittedEntries();
1815 return; 1840 return;
1816 } 1841 }
1817 1842
1818 // If an interstitial page is showing, the previous renderer is blocked and 1843 // If an interstitial page is showing, the previous renderer is blocked and
1819 // cannot make new requests. Unblock (and disable) it to allow this 1844 // cannot make new requests. Unblock (and disable) it to allow this
1820 // navigation to succeed. The interstitial will stay visible until the 1845 // navigation to succeed. The interstitial will stay visible until the
1821 // resulting DidNavigate. 1846 // resulting DidNavigate.
1822 if (delegate_->GetInterstitialPage()) { 1847 if (delegate_->GetInterstitialPage()) {
1823 static_cast<InterstitialPageImpl*>(delegate_->GetInterstitialPage()) 1848 static_cast<InterstitialPageImpl*>(delegate_->GetInterstitialPage())
1824 ->CancelForNavigation(); 1849 ->CancelForNavigation();
1825 } 1850 }
1826 1851
1827 // The last navigation is the last pending navigation which hasn't been 1852 // The last navigation is the last pending navigation which hasn't been
1828 // committed yet, or the last committed navigation. 1853 // committed yet, or the last committed navigation.
1829 NavigationEntryImpl* last_navigation = 1854 NavigationEntryImpl* last_navigation =
1830 last_pending_entry_ ? last_pending_entry_ : GetLastCommittedEntry(); 1855 last_pending_entry_ ? last_pending_entry_ : GetLastCommittedEntry();
1831 1856
1832 // Convert Enter-in-omnibox to a reload. This is what Blink does in 1857 // Convert Enter-in-omnibox to a reload. This is what Blink does in
1833 // FrameLoader, but we want to handle it here so that if the navigation is 1858 // FrameLoader, but we want to handle it here so that if the navigation is
1834 // redirected or handled purely on the browser side in PlzNavigate we have the 1859 // redirected or handled purely on the browser side in PlzNavigate we have the
1835 // same behaviour as Blink would. Note that we don't want to convert to a 1860 // same behaviour as Blink would.
1836 // reload for history navigations, so this must be above the retrieval of the 1861 if (reload_type == ReloadType::NONE && last_navigation &&
1837 // pending_entry_ below when pending_entry_index_ is used. 1862 // When pending_entry is different from -1, it means this is an history
1838 if (reload_type == ReloadType::NONE && last_navigation && pending_entry_ && 1863 // navigation. History navigation mustn't be converted to a reload.
1864 pending_entry_index_ == -1 &&
1839 // Please refer to the ShouldTreatNavigationAsReload() function for info 1865 // Please refer to the ShouldTreatNavigationAsReload() function for info
1840 // on which navigations are treated as reloads. In general navigating to 1866 // on which navigations are treated as reloads. In general navigating to
1841 // the last committed or pending entry via the address bar, clicking on 1867 // the last committed or pending entry via the address bar, clicking on
1842 // a link, etc would be treated as reloads. 1868 // a link, etc would be treated as reloads.
1843 ShouldTreatNavigationAsReload(pending_entry_) && 1869 ShouldTreatNavigationAsReload(pending_entry_) &&
1844 // Skip entries with SSL errors. 1870 // Skip entries with SSL errors.
1845 !last_navigation->ssl_error() && 1871 !last_navigation->ssl_error() &&
1846 // Ignore interstitial pages 1872 // Ignore interstitial pages
1847 last_transient_entry_index_ == -1 && 1873 last_transient_entry_index_ == -1 &&
1848 pending_entry_->frame_tree_node_id() == -1 && 1874 pending_entry_->frame_tree_node_id() == -1 &&
(...skipping 14 matching lines...) Expand all
1863 reload_type = ReloadType::NORMAL; 1889 reload_type = ReloadType::NORMAL;
1864 } 1890 }
1865 1891
1866 if (last_pending_entry_index_ == -1 && last_pending_entry_) 1892 if (last_pending_entry_index_ == -1 && last_pending_entry_)
1867 delete last_pending_entry_; 1893 delete last_pending_entry_;
1868 1894
1869 last_transient_entry_index_ = -1; 1895 last_transient_entry_index_ = -1;
1870 last_pending_entry_ = nullptr; 1896 last_pending_entry_ = nullptr;
1871 last_pending_entry_index_ = -1; 1897 last_pending_entry_index_ = -1;
1872 1898
1873 // For session history navigations only the pending_entry_index_ is set.
1874 if (!pending_entry_) {
1875 CHECK_NE(pending_entry_index_, -1);
1876 pending_entry_ = entries_[pending_entry_index_].get();
1877 }
1878
1879 // Any renderer-side debug URLs or javascript: URLs should be ignored if the 1899 // Any renderer-side debug URLs or javascript: URLs should be ignored if the
1880 // renderer process is not live, unless it is the initial navigation of the 1900 // renderer process is not live, unless it is the initial navigation of the
1881 // tab. 1901 // tab.
1882 if (IsRendererDebugURL(pending_entry_->GetURL())) { 1902 if (IsRendererDebugURL(pending_entry_->GetURL())) {
1883 // TODO(creis): Find the RVH for the correct frame. 1903 // TODO(creis): Find the RVH for the correct frame.
1884 if (!delegate_->GetRenderViewHost()->IsRenderViewLive() && 1904 if (!delegate_->GetRenderViewHost()->IsRenderViewLive() &&
1885 !IsInitialNavigation()) { 1905 !IsInitialNavigation()) {
1886 DiscardNonCommittedEntries(); 1906 DiscardNonCommittedEntries();
1887 return; 1907 return;
1888 } 1908 }
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2037 void NavigationControllerImpl::LoadIfNecessary() { 2057 void NavigationControllerImpl::LoadIfNecessary() {
2038 if (!needs_reload_) 2058 if (!needs_reload_)
2039 return; 2059 return;
2040 2060
2041 // Calling Reload() results in ignoring state, and not loading. 2061 // Calling Reload() results in ignoring state, and not loading.
2042 // Explicitly use NavigateToPendingEntry so that the renderer uses the 2062 // Explicitly use NavigateToPendingEntry so that the renderer uses the
2043 // cached state. 2063 // cached state.
2044 if (pending_entry_) { 2064 if (pending_entry_) {
2045 NavigateToPendingEntry(ReloadType::NONE); 2065 NavigateToPendingEntry(ReloadType::NONE);
2046 } else if (last_committed_entry_index_ != -1) { 2066 } else if (last_committed_entry_index_ != -1) {
2067 pending_entry_ = entries_[last_committed_entry_index_].get();
2047 pending_entry_index_ = last_committed_entry_index_; 2068 pending_entry_index_ = last_committed_entry_index_;
2048 NavigateToPendingEntry(ReloadType::NONE); 2069 NavigateToPendingEntry(ReloadType::NONE);
2049 } else { 2070 } else {
2050 // If there is something to reload, the successful reload will clear the 2071 // If there is something to reload, the successful reload will clear the
2051 // |needs_reload_| flag. Otherwise, just do it here. 2072 // |needs_reload_| flag. Otherwise, just do it here.
2052 needs_reload_ = false; 2073 needs_reload_ = false;
2053 } 2074 }
2054 } 2075 }
2055 2076
2056 void NavigationControllerImpl::NotifyEntryChanged( 2077 void NavigationControllerImpl::NotifyEntryChanged(
(...skipping 27 matching lines...) Expand all
2084 // when the tab is being destroyed for shutdown, since it won't return to 2105 // when the tab is being destroyed for shutdown, since it won't return to
2085 // NavigateToEntry in that case.) http://crbug.com/347742. 2106 // NavigateToEntry in that case.) http://crbug.com/347742.
2086 CHECK(!in_navigate_to_pending_entry_ || delegate_->IsBeingDestroyed()); 2107 CHECK(!in_navigate_to_pending_entry_ || delegate_->IsBeingDestroyed());
2087 2108
2088 if (was_failure && pending_entry_) { 2109 if (was_failure && pending_entry_) {
2089 failed_pending_entry_id_ = pending_entry_->GetUniqueID(); 2110 failed_pending_entry_id_ = pending_entry_->GetUniqueID();
2090 } else { 2111 } else {
2091 failed_pending_entry_id_ = 0; 2112 failed_pending_entry_id_ = 0;
2092 } 2113 }
2093 2114
2094 if (pending_entry_index_ == -1) 2115 if (pending_entry_) {
2095 delete pending_entry_; 2116 if (pending_entry_index_ == -1)
2096 pending_entry_ = NULL; 2117 delete pending_entry_;
2097 pending_entry_index_ = -1; 2118 pending_entry_index_ = -1;
2119 pending_entry_ = nullptr;
2120 }
2098 } 2121 }
2099 2122
2100 void NavigationControllerImpl::SetPendingNavigationSSLError(bool error) { 2123 void NavigationControllerImpl::SetPendingNavigationSSLError(bool error) {
2101 if (pending_entry_) 2124 if (pending_entry_)
2102 pending_entry_->set_ssl_error(error); 2125 pending_entry_->set_ssl_error(error);
2103 } 2126 }
2104 2127
2105 void NavigationControllerImpl::DiscardTransientEntry() { 2128 void NavigationControllerImpl::DiscardTransientEntry() {
2106 if (transient_entry_index_ == -1) 2129 if (transient_entry_index_ == -1)
2107 return; 2130 return;
2108 entries_.erase(entries_.begin() + transient_entry_index_); 2131 entries_.erase(entries_.begin() + transient_entry_index_);
2109 if (last_committed_entry_index_ > transient_entry_index_) 2132 if (last_committed_entry_index_ > transient_entry_index_)
2110 last_committed_entry_index_--; 2133 last_committed_entry_index_--;
2134 if (pending_entry_index_ > transient_entry_index_)
2135 pending_entry_index_--;
2111 transient_entry_index_ = -1; 2136 transient_entry_index_ = -1;
2112 } 2137 }
2113 2138
2114 int NavigationControllerImpl::GetEntryIndexWithUniqueID( 2139 int NavigationControllerImpl::GetEntryIndexWithUniqueID(
2115 int nav_entry_id) const { 2140 int nav_entry_id) const {
2116 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) { 2141 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) {
2117 if (entries_[i]->GetUniqueID() == nav_entry_id) 2142 if (entries_[i]->GetUniqueID() == nav_entry_id)
2118 return i; 2143 return i;
2119 } 2144 }
2120 return -1; 2145 return -1;
2121 } 2146 }
2122 2147
2123 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const { 2148 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const {
2124 if (transient_entry_index_ == -1) 2149 if (transient_entry_index_ == -1)
2125 return NULL; 2150 return NULL;
2126 return entries_[transient_entry_index_].get(); 2151 return entries_[transient_entry_index_].get();
2127 } 2152 }
2128 2153
2129 void NavigationControllerImpl::SetTransientEntry( 2154 void NavigationControllerImpl::SetTransientEntry(
2130 std::unique_ptr<NavigationEntry> entry) { 2155 std::unique_ptr<NavigationEntry> entry) {
2131 // Discard any current transient entry, we can only have one at a time. 2156 // Discard any current transient entry, we can only have one at a time.
2132 int index = 0; 2157 int index = 0;
2133 if (last_committed_entry_index_ != -1) 2158 if (last_committed_entry_index_ != -1)
2134 index = last_committed_entry_index_ + 1; 2159 index = last_committed_entry_index_ + 1;
2135 DiscardTransientEntry(); 2160 DiscardTransientEntry();
2136 entries_.insert(entries_.begin() + index, 2161 entries_.insert(entries_.begin() + index,
2137 NavigationEntryImpl::FromNavigationEntry(std::move(entry))); 2162 NavigationEntryImpl::FromNavigationEntry(std::move(entry)));
2163 if (pending_entry_index_ >= index)
2164 pending_entry_index_++;
2138 transient_entry_index_ = index; 2165 transient_entry_index_ = index;
2139 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL); 2166 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL);
2140 } 2167 }
2141 2168
2142 void NavigationControllerImpl::InsertEntriesFrom( 2169 void NavigationControllerImpl::InsertEntriesFrom(
2143 const NavigationControllerImpl& source, 2170 const NavigationControllerImpl& source,
2144 int max_index) { 2171 int max_index) {
2145 DCHECK_LE(max_index, source.GetEntryCount()); 2172 DCHECK_LE(max_index, source.GetEntryCount());
2146 size_t insert_index = 0; 2173 size_t insert_index = 0;
2147 for (int i = 0; i < max_index; i++) { 2174 for (int i = 0; i < max_index; i++) {
2148 // When cloning a tab, copy all entries except interstitial pages. 2175 // When cloning a tab, copy all entries except interstitial pages.
2149 if (source.entries_[i]->GetPageType() != PAGE_TYPE_INTERSTITIAL) { 2176 if (source.entries_[i]->GetPageType() != PAGE_TYPE_INTERSTITIAL) {
2150 // TODO(creis): Once we start sharing FrameNavigationEntries between 2177 // TODO(creis): Once we start sharing FrameNavigationEntries between
2151 // NavigationEntries, it will not be safe to share them with another tab. 2178 // NavigationEntries, it will not be safe to share them with another tab.
2152 // Must have a version of Clone that recreates them. 2179 // Must have a version of Clone that recreates them.
2153 entries_.insert(entries_.begin() + insert_index++, 2180 entries_.insert(entries_.begin() + insert_index++,
2154 source.entries_[i]->Clone()); 2181 source.entries_[i]->Clone());
2155 } 2182 }
2156 } 2183 }
2184 DCHECK(pending_entry_index_ == -1 ||
2185 pending_entry_ == GetEntryAtIndex(pending_entry_index_));
2157 } 2186 }
2158 2187
2159 void NavigationControllerImpl::SetGetTimestampCallbackForTest( 2188 void NavigationControllerImpl::SetGetTimestampCallbackForTest(
2160 const base::Callback<base::Time()>& get_timestamp_callback) { 2189 const base::Callback<base::Time()>& get_timestamp_callback) {
2161 get_timestamp_callback_ = get_timestamp_callback; 2190 get_timestamp_callback_ = get_timestamp_callback;
2162 } 2191 }
2163 2192
2164 } // namespace content 2193 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/public/browser/navigation_controller.h » ('j') | content/public/browser/navigation_controller.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698